Index: sources/gui/qml/pages/pretreatment/create/PreTreatmentCreate.qml =================================================================== diff -u -re8df7fe7fe6274c416f176369250b9581e07d2a5 -r83b9d737cd495b34a7b42f5409962a9442f3b8f4 --- sources/gui/qml/pages/pretreatment/create/PreTreatmentCreate.qml (.../PreTreatmentCreate.qml) (revision e8df7fe7fe6274c416f176369250b9581e07d2a5) +++ sources/gui/qml/pages/pretreatment/create/PreTreatmentCreate.qml (.../PreTreatmentCreate.qml) (revision 83b9d737cd495b34a7b42f5409962a9442f3b8f4) @@ -1,13 +1,13 @@ /*! * - * Copyright (c) 2021-2022 Diality Inc. - All Rights Reserved. + * Copyright (c) 2021-2024 Diality Inc. - All Rights Reserved. * \copyright * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * * \file PreTreatmentCreate.qml * \author (last) Behrouz NematiPour - * \date (last) 28-Sep-2022 + * \date (last) 08-Feb-2024 * \author (original) Behrouz NematiPour * \date (original) 12-Jan-2021 * @@ -31,30 +31,103 @@ objectName: "_PreTreatmentCreate" // SquishQt testability header.confirmEnabled: - _bloodFlowRate .active && - _dialysateFlowRate .active && - _duration .active && - _heparinDispensingRate .active && - _heparinBolusVolume .active && - _heparinStopTime .active && - _salineBolus .active && - _heparinType .active && - _acidConcentrate .active && - _bicarbonateConcentrate .active && - _dialyzerType .active && - _dialysateTemperature .active && - _arterialPressureLimits .minAdjusted && - _arterialPressureLimits .maxAdjusted && - _venousPressureLimits .minAdjusted && - _venousPressureLimits .maxAdjusted && - _bloodPressureInterval .active && - _rinsebackFlowRate .active + _bloodFlowRate .active && _bloodFlowRate . valid && + _dialysateFlowRate .active && _dialysateFlowRate . valid && + _duration .active && _duration . valid && + _heparinDispensingRate .active && _heparinDispensingRate . valid && + _heparinBolusVolume .active && _heparinBolusVolume . valid && + _heparinStopTime .active && _heparinStopTime . valid && + _salineBolus .active && _salineBolus . valid && + _heparinType._heparinTypeActive && + _acidConcentrate .active && + _bicarbonateConcentrate .active && + _dialyzerType .active && + _dialysateTemperature .active && _dialysateTemperature . valid && + _bloodPressureInterval .active && _bloodPressureInterval . valid + Connections{ target:vTreatmentCreate + // Update flicker location to show the invalid parameter + function onDidValidationFail() { + if ( vTreatmentCreate. bloodFlowRateRejectReason ) { scrollTo( _bloodFlowRate ); return } + if ( vTreatmentCreate. dialysateFlowRateRejectReason ) { scrollTo( _dialysateFlowRate ); return } + if ( vTreatmentCreate. treatmentDurationRejectReason ) { scrollTo( _duration ); return } + if ( vTreatmentCreate. heparinDispensingRateRejectReason ) { scrollTo( _heparinDispensingRate ); return } + if ( vTreatmentCreate. heparinBolusVolumeRejectReason ) { scrollTo( _heparinBolusVolume ); return } + if ( vTreatmentCreate. heparinStopTimeRejectReason ) { scrollTo( _heparinStopTime ); return } + if ( vTreatmentCreate. salineBolusVolumeRejectReason ) { scrollTo( _salineBolus ); return } + if ( vTreatmentCreate. heparinTypeRejectReason ) { scrollTo( _heparinType ); return } + if ( vTreatmentCreate. acidConcentrateRejectReason ) { scrollTo( _acidConcentrate ); return } + if ( vTreatmentCreate. bicarbonateConcentrateRejectReason ) { scrollTo( _bicarbonateConcentrate ); return } + if ( vTreatmentCreate. dialyzerTypeRejectReason ) { scrollTo( _dialyzerType ); return } + + if ( vTreatmentCreate. dialysateTempRejectReason ) { scrollTo( _dialysateTemperature ); return } + if ( vTreatmentCreate.bloodPressureMeasureIntervalRejectReason ) { scrollTo( _bloodPressureInterval ); return } + } + } + function setInteractive(vInteractive) { _flickable.interactive = vInteractive } + function scrollTo(vItem) { + _flickable.contentY = vItem.mapToItem(_flickable.contentItem, 0, 0).y + } + + function clear() { + _flickable.contentY = 0 + _bloodFlowRate .clear() + _dialysateFlowRate .clear() + _duration .clear() + _heparinDispensingRate .clear() + _heparinBolusVolume .clear() + _heparinStopTime .clear() + _salineBolus .clear() + _heparinType .clear() + _acidConcentrate .clear() + _bicarbonateConcentrate .clear() + _dialyzerType .clear() + _dialysateTemperature .clear() + _bloodPressureInterval .clear() + } + + property bool prepopulated: false + function prepopulate() { + // not complete yet and not part of the current DNBUG + // the issue is the On/Off switches whcih has not been stored in the view to restore/prepopulate it, + // which is needed for three sliders to be set properly. + _bloodFlowRate .reset(vTreatmentCreate.bloodFlowRate ) + _dialysateFlowRate .reset(vTreatmentCreate.dialysateFlowRate ) + _duration .reset(vTreatmentCreate.treatmentDuration ) + _heparinDispensingRate .reset(vTreatmentCreate.heparinDispensingRate ) + _heparinBolusVolume .reset(vTreatmentCreate.heparinBolusVolume ) + _heparinStopTime .reset(vTreatmentCreate.heparinStopTime ) + _salineBolus .reset(vTreatmentCreate.salineBolusVolume ) + _heparinType .reset(vTreatmentCreate.heparinType ) + _acidConcentrate .reset(vTreatmentCreate.acidConcentrate ) + _bicarbonateConcentrate .reset(vTreatmentCreate.bicarbonateConcentrate ) + _dialyzerType .reset(vTreatmentCreate.heparinType ) + _dialysateTemperature .reset(vTreatmentCreate.dialysateTemp ) + _bloodPressureInterval .reset(vTreatmentCreate.bloodPressureMeasureInterval ) + } + + ConfirmButton { id : _prepopulateButton + objectName : "_prepopulateButton" + text.text : prepopulated ? qsTr("RESET") : qsTr("PREPOPULATE") + anchors.top : title.top + anchors.topMargin : 0 + visible : false // true // not readu yet and has been hidded. + onClicked : { + if ( prepopulated ) { + clear() + } + else { + prepopulate() + } + prepopulated = ! prepopulated + } + } + ScrollBar { flickable : _flickable anchors.fill: _flickable @@ -97,9 +170,15 @@ minimum : vTreatmentRanges.bloodFlowRateMin maximum : vTreatmentRanges.bloodFlowRateMax step : vTreatmentRanges.bloodFlowRateRes - value : vTreatmentRanges.bloodFlowRateDef - onPressed : vTreatmentCreate.bloodFlowRate = value - onReleased : vTreatmentCreate.bloodFlowRate = value + defaultValue: vTreatmentRanges.bloodFlowRateDef + valid : !vTreatmentCreate.bloodFlowRateRejectReason + onValueChanged : { + // Reset the valid state to allow repositioning to the next invalid parameter + if(!valid) { + vTreatmentCreate.bloodFlowRateRejectReason = Variables.noRejectReason + } + vTreatmentCreate.bloodFlowRate = value + } } SliderCreateTreatment { id: _dialysateFlowRate @@ -110,9 +189,15 @@ minimum : vTreatmentRanges.dialysateFlowRateMin maximum : vTreatmentRanges.dialysateFlowRateMax step : vTreatmentRanges.dialysateFlowRateRes - value : vTreatmentRanges.dialysateFlowRateDef - onPressed : vTreatmentCreate.dialysateFlowRate = value - onReleased : vTreatmentCreate.dialysateFlowRate = value + defaultValue: vTreatmentRanges.dialysateFlowRateDef + valid : !vTreatmentCreate.dialysateFlowRateRejectReason + onValueChanged : { + // Reset the valid state to allow repositioning to the next invalid parameter + if(!valid) { + vTreatmentCreate.dialysateFlowRateRejectReason = Variables.noRejectReason + } + vTreatmentCreate.dialysateFlowRate = value + } } SliderCreateTreatment { id: _duration @@ -123,53 +208,41 @@ minimum : vTreatmentRanges.treatmentDurationMin maximum : vTreatmentRanges.treatmentDurationMax step : vTreatmentRanges.treatmentDurationRes - value : vTreatmentRanges.treatmentDurationDef - onPressed : vTreatmentCreate.treatmentDuration = value - onReleased : vTreatmentCreate.treatmentDuration = value + defaultValue: vTreatmentRanges.treatmentDurationDef + valid : !vTreatmentCreate.treatmentDurationRejectReason + onValueChanged: { + // Reset the valid state to allow repositioning to the next invalid parameter + if(!valid) { + vTreatmentCreate.treatmentDurationRejectReason = Variables.noRejectReason + } + vTreatmentCreate.treatmentDuration = value + } } -// ToDo: create a component for this, -// This is a full implementation of a CheckBox -// Switch { id: _heparinDelivery -// text: qsTr("Heparin Delivery") -// width : Variables.createTreatmentSliderWidth + 25 + Connections { target : _heparinDispensingRateSwitch + function onActiveChanged ( ) { + let mActive = _heparinDispensingRateSwitch.active + let mObject = _heparinStopTime -// anchors.horizontalCenter: parent.horizontalCenter + if ( ! mActive ) { + mObject.enabled = false + mObject.active = false + mObject.adjustable = false + } + } -// indicator: Rectangle { -// implicitWidth : Variables.sliderCircleDiameter * 1.7 -// implicitHeight : Variables.sliderCircleDiameter - ( Variables.progressbarHandlerBorderWidth * 2 ) -// radius : implicitHeight -// x : _heparinDelivery.leftPadding -// y : parent.height / 2 - height / 2 -// color : _heparinDelivery.checked ? Colors.backgroundButtonSelect : Colors.createTreatmentInactive -// border.color : _heparinDelivery.checked ? Colors.borderButton : Colors.createTreatmentInactive -// Rectangle { id: _handler -// property real diameter : Variables.sliderCircleDiameter + function onCheckedChanged ( ) { + let mActive = _heparinDispensingRateSwitch.active + let mChecked = _heparinDispensingRateSwitch.checked + let mObject = _heparinStopTime -// x: _heparinDelivery.checked ? parent.width - width : 0 -// anchors.verticalCenter: parent.verticalCenter -// width : diameter -// height : diameter -// radius : diameter -// color : _heparinDelivery.checked ? Colors.highlightProgressBar : Colors.createTreatmentInactive -// border { -// width: 4 -// color: Colors.textMain -// } -// } -// } + mObject.enabled = mActive && mChecked + mObject.active = mActive && ! mChecked + mObject.adjustable = mChecked -// contentItem: Text { -// enabled: _heparinDelivery.checked -// text: _heparinDelivery.text -// font: _heparinDelivery.font -// opacity: enabled ? 1.0 : 0.3 -// color : Colors.textButton -// verticalAlignment: Text.AlignVCenter -// leftPadding: _heparinDelivery.indicator.width + _heparinDelivery.spacing -// } -// } + if ( ! mChecked ) mObject.reset ( 0 ) + } + } SliderCreateTreatment { id: _heparinDispensingRate objectName : "_heparinDispensingRate" @@ -181,33 +254,46 @@ minimum : vTreatmentRanges.heparinDispensingRateMin maximum : vTreatmentRanges.heparinDispensingRateMax step : vTreatmentRanges.heparinDispensingRateRes - value : vTreatmentRanges.heparinDispensingRateDef - onPressed : vTreatmentCreate.heparinDispensingRate = value - onReleased : vTreatmentCreate.heparinDispensingRate = value - adjustable : _heparinDispensingRateSwitch.checked - inActiveZero: true - + defaultValue: vTreatmentRanges.heparinDispensingRateDef + valid : !vTreatmentCreate.heparinDispensingRateRejectReason + adjustable : _heparinDispensingRateSwitch.checked + inActiveZero : true + enableAdjustButtons: _heparinDispensingRateSwitch.checked + onValueChanged: { + // Reset the valid state to allow repositioning to the next invalid parameter + if(!valid) { + vTreatmentCreate.heparinDispensingRateRejectReason = Variables.noRejectReason + } + vTreatmentCreate.heparinDispensingRate = _heparinDispensingRateSwitch.checked ? value : 0 + } + // ToDo: create a component for Switch, + // ToDo: Consider putting the new CheckBox component into the SliderCreateTreatment component and set via boolean property + // This is a full implementation of a Switch + toggleSwich: _heparinDispensingRateSwitch Switch { id: _heparinDispensingRateSwitch property bool active: false onCheckedChanged: { if ( ! active ) { active = true checked = ! checked } - vTreatmentCreate.heparinDispensingRate = 0 - _heparinDispensingRate.value = 0 - _heparinDispensingRate.active = ! checked + vTreatmentCreate.heparinDispensingRate = 0 + vTreatmentCreate.heparinDispensingRateOff = ! checked + _heparinDispensingRate.reset ( 0 ) + _heparinDispensingRate.active = ! checked } - x : width * -2 - y : parent.height - 13 // (height / 2) - width : indicator.width + x : width * -1.5 + y : Variables.createTreatmentSwitchYDisplacement // these values are set to align the switch with slider + width : 75 // these values are set to align the switch with slider + height : 85 // these values are set to align the switch with slider + // DEBUG: background : Rectangle { color : "white" } + indicator: Rectangle { implicitWidth : Variables.sliderCircleDiameter * 1.7 implicitHeight : Variables.sliderCircleDiameter - ( Variables.progressbarHandlerBorderWidth * 2 ) radius : implicitHeight - x : _heparinDispensingRateSwitch.leftPadding - y : parent.height / 2 - height / 2 + anchors.centerIn: parent color : _heparinDispensingRateSwitch.checked ? Colors.backgroundButtonSelect : Colors.createTreatmentInactive border.color : _heparinDispensingRateSwitch.checked ? Colors.borderButton : Colors.createTreatmentInactive Rectangle { @@ -227,14 +313,12 @@ } contentItem: Text { - width : _heparinDispensingRateSwitch.width text : _heparinDispensingRateSwitch.checked ? qsTr("ON") : qsTr("OFF") font : _heparinDispensingRateSwitch.font color : _heparinDispensingRateSwitch.active ? Colors.textMain : Colors.textDisableButton - verticalAlignment: Text.AlignVCenter + verticalAlignment: Text.AlignTop horizontalAlignment: Text.AlignHCenter - anchors.bottom: _heparinDispensingRateSwitch.top - anchors.bottomMargin: 12 + anchors.centerIn: parent } } } @@ -249,34 +333,47 @@ minimum : vTreatmentRanges.heparinBolusVolumeMin maximum : vTreatmentRanges.heparinBolusVolumeMax step : vTreatmentRanges.heparinBolusVolumeRes - value : vTreatmentRanges.heparinBolusVolumeDef - onPressed : vTreatmentCreate.heparinBolusVolume = value - onReleased : vTreatmentCreate.heparinBolusVolume = value - adjustable : _heparinBolusVolumeSwitch.checked - inActiveZero: true + defaultValue: vTreatmentRanges.heparinBolusVolumeDef + valid : !vTreatmentCreate.heparinBolusVolumeRejectReason + adjustable : _heparinBolusVolumeSwitch.checked + inActiveZero : true + enableAdjustButtons: _heparinBolusVolumeSwitch.checked + onValueChanged : { + // Reset the valid state to allow repositioning to the next invalid parameter + if(!valid) { + vTreatmentCreate.heparinBolusVolumeRejectReason = Variables.noRejectReason + } + vTreatmentCreate.heparinBolusVolume = _heparinBolusVolumeSwitch.checked ? value : 0 + } + // ToDo: create a component for this, + // ToDo: Consider putting the new CheckBox component into the SliderCreateTreatment component and set via boolean property + // This is a full implementation of a CheckBox + toggleSwich: _heparinBolusVolumeSwitch Switch { id: _heparinBolusVolumeSwitch property bool active: false onCheckedChanged: { if ( ! active ) { active = true checked = ! checked } - vTreatmentCreate.heparinBolusVolume = 0 - _heparinBolusVolume.value = 0 - _heparinBolusVolume.active = ! checked - + vTreatmentCreate.heparinBolusVolume = 0 + vTreatmentCreate.heparinBolusVolumeOff = ! checked + _heparinBolusVolume.reset ( 0 ) + _heparinBolusVolume.active = ! checked } - x : width * -2 - y : parent.height - 13 // (height / 2) - width : indicator.width + x : width * -1.5 + y : Variables.createTreatmentSwitchYDisplacement // these values are set to align the switch with slider + width : 75 // these values are set to align the switch with slider + height : 85 // these values are set to align the switch with slider + // DEBUG: background : Rectangle { color : "white" } + indicator: Rectangle { implicitWidth : Variables.sliderCircleDiameter * 1.7 implicitHeight : Variables.sliderCircleDiameter - ( Variables.progressbarHandlerBorderWidth * 2 ) radius : implicitHeight - x : _heparinBolusVolumeSwitch.leftPadding - y : parent.height / 2 - height / 2 + anchors.centerIn: parent color : _heparinBolusVolumeSwitch.checked ? Colors.backgroundButtonSelect : Colors.createTreatmentInactive border.color : _heparinBolusVolumeSwitch.checked ? Colors.borderButton : Colors.createTreatmentInactive Rectangle { @@ -296,14 +393,12 @@ } contentItem: Text { - width : _heparinBolusVolumeSwitch.width text : _heparinBolusVolumeSwitch.checked ? qsTr("ON") : qsTr("OFF") font : _heparinBolusVolumeSwitch.font color : _heparinBolusVolumeSwitch.active ? Colors.textMain : Colors.textDisableButton - verticalAlignment: Text.AlignVCenter + verticalAlignment: Text.AlignTop horizontalAlignment: Text.AlignHCenter - anchors.bottom: _heparinBolusVolumeSwitch.top - anchors.bottomMargin: 12 + anchors.centerIn: parent } } } @@ -316,9 +411,18 @@ minimum : vTreatmentRanges.heparinStopTimeMin maximum : vTreatmentRanges.heparinStopTimeMax step : vTreatmentRanges.heparinStopTimeRes - value : vTreatmentRanges.heparinStopTimeDef - onPressed : vTreatmentCreate.heparinStopTime = value - onReleased : vTreatmentCreate.heparinStopTime = value + defaultValue: vTreatmentRanges.heparinStopTimeDef + valid : !vTreatmentCreate.heparinStopTimeRejectReason + enabled : false // this switch depends on the heparin dispencing + adjustable : false // this switch depends on the heparin dispencing + enableAdjustButtons: _heparinDispensingRateSwitch.checked + onValueChanged: { + // Reset the valid state to allow repositioning to the next invalid parameter + if(!valid) { + vTreatmentCreate.heparinStopTimeRejectReason = Variables.noRejectReason + } + vTreatmentCreate.heparinStopTime = value + } } SliderCreateTreatment { id: _salineBolus @@ -329,9 +433,15 @@ minimum : vTreatmentRanges.salineBolusVolumeMin maximum : vTreatmentRanges.salineBolusVolumeMax step : vTreatmentRanges.salineBolusVolumeRes - value : vTreatmentRanges.salineBolusVolumeDef - onPressed : vTreatmentCreate.salineBolusVolume = value - onReleased : vTreatmentCreate.salineBolusVolume = value + defaultValue: vTreatmentRanges.salineBolusVolumeDef + valid : !vTreatmentCreate.salineBolusVolumeRejectReason + onValueChanged: { + // Reset the valid state to allow repositioning to the next invalid parameter + if(!valid) { + vTreatmentCreate.salineBolusVolumeRejectReason = Variables.noRejectReason + } + vTreatmentCreate.salineBolusVolume = value + } } Text { id: _titleTextOperation @@ -343,31 +453,52 @@ } GridSelection { id : _heparinType + readonly property bool _heparinTypeActive : (enabled && active) || (!enabled) + objectName : "_heparinTypeRect" title : qsTr("Heparin Type") labels : vTreatmentRanges.heparinTypeOptions onClicked :{vTreatmentCreate.heparinType = curIndex ; vTreatmentCreate.heparinTypeSet = true; } + enabled : _heparinDispensingRateSwitch.checked || _heparinBolusVolumeSwitch.checked + onEnabledChanged: { + if ( ! enabled ) { + vTreatmentCreate.heparinTypeSet = false + clear() + } + } + + valid : ! vTreatmentCreate.heparinTypeRejectReason + onCurIndexChanged : vTreatmentCreate.heparinTypeRejectReason = Variables.noRejectReason } GridSelection { id : _acidConcentrate objectName : "_acidConcentrateRect" title : qsTr("Acid Concentrate") labels : vTreatmentRanges.acidConcentrateOptions onClicked :{vTreatmentCreate.acidConcentrate = curIndex ; vTreatmentCreate.acidConcentrateSet = true; } + + valid : ! vTreatmentCreate.acidConcentrateRejectReason + onCurIndexChanged : vTreatmentCreate.acidConcentrateRejectReason = Variables.noRejectReason } GridSelection { id : _bicarbonateConcentrate objectName : "_bicarbonateConcentrateRect" title : qsTr("Bicarbonate Concentrate") labels : vTreatmentRanges.bicarbonateConcentrateOptions onClicked :{vTreatmentCreate.bicarbonateConcentrate = curIndex ; vTreatmentCreate.bicarbonateConcentrateSet = true; } + + valid : ! vTreatmentCreate.bicarbonateConcentrateRejectReason + onCurIndexChanged : vTreatmentCreate.bicarbonateConcentrateRejectReason = Variables.noRejectReason } GridSelection { id : _dialyzerType objectName : "_dialyzerTypeRect" title : qsTr("Dialyzer Type") labels : vTreatmentRanges.dialyzerTypeOptions onClicked :{vTreatmentCreate.dialyzerType = curIndex ; vTreatmentCreate.dialyzerTypeSet = true; } + + valid : ! vTreatmentCreate.dialyzerTypeRejectReason + onCurIndexChanged : vTreatmentCreate.dialyzerTypeRejectReason = Variables.noRejectReason } Item { height: 1; width: 1 /* TODO : there is a design flaw in here, this is a workaround */ } @@ -377,14 +508,24 @@ label : qsTr("Dialysate Temperature") flickable : _flickable unit : Variables.unitTextTemperature + decimal : Variables.dialysateTempPrecision minimum : vTreatmentRanges.dialysateTempMin maximum : vTreatmentRanges.dialysateTempMax step : vTreatmentRanges.dialysateTempRes - value : vTreatmentRanges.dialysateTempDef - onPressed : vTreatmentCreate.dialysateTemp = value - onReleased : vTreatmentCreate.dialysateTemp = value + defaultValue: vTreatmentRanges.dialysateTempDef + valid : !vTreatmentCreate.dialysateTempRejectReason + + onValueChanged: { + // Reset the valid state to allow repositioning to the next invalid parameter + if(!valid) { + vTreatmentCreate.dialysateTempRejectReason = Variables.noRejectReason + } + vTreatmentCreate.dialysateTemp = value + } } +/* [DEN-15359] Arterial and Venous Pressure has been removed, it has been kept here since it supposed to become a component and don't watnt to loose the coce. + // TODO : This has to be a Component Column { id: _arterialColumn spacing: 45 @@ -396,6 +537,11 @@ if ( slider.minAdjusted && slider.maxAdjusted ) { color = Colors.textMain } + + // if it's invalid upper or lower bound, set invalid color + if (!_arterialPressureLimits.lowerBoundValid || !_arterialPressureLimits.upperBoundValid) { + color = Colors.createTreatmentInvalidParam + } return color } width : parent.width @@ -420,9 +566,8 @@ RangeSlider { id: _arterialPressureLimits objectName : "_arterialPressureLimitsSlider" // dimension - height : Variables.progressbarFluidHeight + height : Variables.sliderDefaultBodyHeight width : Variables.createTreatmentSliderWidth - diameter : Variables.sliderCircleDiameter anchors.horizontalCenter: parent.horizontalCenter ticks : true stepSnap : true @@ -432,15 +577,18 @@ lowerText.visible : true lowerText.font.pixelSize : Fonts.fontPixelFluidText lowerText.font.bold : false - lowerText.anchors.topMargin : -50 + lowerText.anchors.topMargin : -60 lowerTextHorizontalCenter : true upperText.visible : true upperText.font.pixelSize : Fonts.fontPixelFluidText upperText.font.bold : false - upperText.anchors.topMargin : -50 + upperText.anchors.topMargin : -60 upperTextHorizontalCenter : true + lowerBoundValid: !vTreatmentCreate.arterialPressureLimitLowRejectReason + upperBoundValid: !vTreatmentCreate.arterialPressureLimitHighRejectReason + minText.visible : true minText.font.bold : false minVerticalEdgeVisible : false @@ -464,10 +612,40 @@ onPressed : { setInteractive(false) } onDragged : { setInteractive(false) } onReleased : { setInteractive(true ) } - onMinValueChanged : { if ( minAdjusted ) vTreatmentCreate.arterialPressureLimitLow = minValue } - onMaxValueChanged : { if ( maxAdjusted ) vTreatmentCreate.arterialPressureLimitHigh = maxValue } - onClicked : { if ( minAdjusted ) vTreatmentCreate.arterialPressureLimitLow = minValue - if ( maxAdjusted ) vTreatmentCreate.arterialPressureLimitHigh = maxValue } + onMinValueChanged : { + if ( minAdjusted ) { + // Reset the valid state to allow repositioning to the next invalid parameter + if(!lowerBoundValid) { + vTreatmentCreate.arterialPressureLimitLowRejectReason = Variables.noRejectReason + } + vTreatmentCreate.arterialPressureLimitLow = minValue + } + } + onMaxValueChanged : { + if ( maxAdjusted ) { + // Reset the valid state to allow repositioning to the next invalid parameter + if(!upperBoundValid) { + vTreatmentCreate.arterialPressureLimitHighRejectReason = Variables.noRejectReason + } + vTreatmentCreate.arterialPressureLimitHigh = maxValue + } + } + + SliderArrows{ id:_arterialPressureLimitsMaxArrows + anchors.verticalCenter : _arterialPressureLimits.verticalCenter + anchors.left : _arterialPressureLimits.right + anchors.leftMargin : Variables.sliderAdjustButtonLeftMargin + onIncrementValue : _arterialPressureLimits.incrementMax(true) + onDecrementValue : _arterialPressureLimits.decrementMax(true) + } + + SliderArrows{ id:_arterialPressureLimitsMinArrows + anchors.verticalCenter : _arterialPressureLimits.verticalCenter + anchors.right : _arterialPressureLimits.left + anchors.rightMargin : Variables.sliderAdjustButtonRightMargin + onIncrementValue : _arterialPressureLimits.incrementMin(true) + onDecrementValue : _arterialPressureLimits.decrementMin(true) + } } } @@ -482,6 +660,11 @@ if ( slider.minAdjusted && slider.maxAdjusted ) { color = Colors.textMain } + + // if it's invalid upper or lower bound, set invalid color + if (!_venousPressureLimits.lowerBoundValid || !_venousPressureLimits.upperBoundValid) { + color = Colors.createTreatmentInvalidParam + } return color } width : parent.width @@ -506,27 +689,34 @@ RangeSlider { id: _venousPressureLimits objectName: "_venousPressureLimitsSlider" // dimension - height : Variables.progressbarFluidHeight + height : Variables.sliderDefaultBodyHeight width : Variables.createTreatmentSliderWidth - diameter : Variables.sliderCircleDiameter anchors.horizontalCenter: parent.horizontalCenter ticks : true stepSnap : true hasAdjust : true + // slider visuals + showTickmarks : true + isRoundedEnds : true + isTickMarksRound: true + // Texts lowerText.visible : true lowerText.font.pixelSize : Fonts.fontPixelFluidText lowerText.font.bold : false - lowerText.anchors.topMargin : -50 + lowerText.anchors.topMargin : -60 lowerTextHorizontalCenter : true upperText.visible : true upperText.font.pixelSize : Fonts.fontPixelFluidText upperText.font.bold : false - upperText.anchors.topMargin : -50 + upperText.anchors.topMargin : -60 upperTextHorizontalCenter : true + lowerBoundValid : !vTreatmentCreate.venousPressureLimitLowRejectReason + upperBoundValid : !vTreatmentCreate.venousPressureLimitHighRejectReason + minText.visible : true minText.font.bold : false minVerticalEdgeVisible : false @@ -550,13 +740,45 @@ onPressed : { setInteractive(false) } onDragged : { setInteractive(false) } onReleased : { setInteractive(true ) } - onMinValueChanged : { if ( minAdjusted ) vTreatmentCreate.venousPressureLimitLow = minValue } - onMaxValueChanged : { if ( maxAdjusted ) vTreatmentCreate.venousPressureLimitHigh = maxValue } - onClicked : { if ( minAdjusted ) vTreatmentCreate.venousPressureLimitLow = minValue - if ( maxAdjusted ) vTreatmentCreate.venousPressureLimitHigh = maxValue } + onMinValueChanged : { + if ( minAdjusted ) { + // Reset the valid state to allow repositioning to the next invalid parameter + if(!lowerBoundValid) { + vTreatmentCreate.venousPressureLimitLowRejectReason = Variables.noRejectReason + } + vTreatmentCreate.venousPressureLimitLow = minValue + } + } + onMaxValueChanged : { + if ( maxAdjusted ) { + // Reset the valid state to allow repositioning to the next invalid parameter + if(!upperBoundValid) { + vTreatmentCreate.venousPressureLimitHighRejectReason = Variables.noRejectReason + } + vTreatmentCreate.venousPressureLimitHigh = maxValue + } + } + + SliderArrows{ id:_venousPressureLimitsMaxArrows + anchors.verticalCenter : _venousPressureLimits.verticalCenter + anchors.left : _venousPressureLimits.right + anchors.leftMargin : Variables.sliderAdjustButtonLeftMargin + onIncrementValue : _venousPressureLimits.incrementMax(true) + onDecrementValue : _venousPressureLimits.decrementMax(true) + } + + SliderArrows{ id:_venousPressureLimitsMinArrows + anchors.verticalCenter : _venousPressureLimits.verticalCenter + anchors.right : _venousPressureLimits.left + anchors.rightMargin : Variables.sliderAdjustButtonRightMargin + onIncrementValue : _venousPressureLimits.incrementMin(true) + onDecrementValue : _venousPressureLimits.decrementMin(true) + } } } +*/ + SliderCreateTreatment { id: _bloodPressureInterval objectName : "_bloodPressureMeasurementInterval" label : qsTr("Blood Pressure Measurement Interval") @@ -566,23 +788,76 @@ minimum : vTreatmentRanges.bloodPressureMeasureIntervalMin maximum : vTreatmentRanges.bloodPressureMeasureIntervalMax step : vTreatmentRanges.bloodPressureMeasureIntervalRes - value : vTreatmentRanges.bloodPressureMeasureIntervalDef - onPressed : vTreatmentCreate.bloodPressureMeasureInterval = value - onReleased : vTreatmentCreate.bloodPressureMeasureInterval = value - } + defaultValue: vTreatmentRanges.bloodPressureMeasureIntervalDef + valid : !vTreatmentCreate.bloodPressureMeasureIntervalRejectReason + adjustable : _bloodPressureIntervalSwitch.checked + inActiveZero: true + enableAdjustButtons: _bloodPressureIntervalSwitch.checked + onValueChanged: { + // Reset the valid state to allow repositioning to the next invalid parameter + if(!valid) { + vTreatmentCreate.bloodPressureMeasureIntervalRejectReason = Variables.noRejectReason + } + vTreatmentCreate.bloodPressureMeasureInterval = _bloodPressureIntervalSwitch.checked ? value : 0 + } - SliderCreateTreatment { id: _rinsebackFlowRate - objectName : "_rinsebackFlowRate" - label : qsTr("Rinseback Flow Rate") - flickable : _flickable - unit : Variables.unitTextFlowRate - minimum : vTreatmentRanges.rinsebackFlowRateMin - maximum : vTreatmentRanges.rinsebackFlowRateMax - step : vTreatmentRanges.rinsebackFlowRateRes - value : vTreatmentRanges.rinsebackFlowRateDef - onPressed : vTreatmentCreate.rinsebackFlowRate = value - onReleased : vTreatmentCreate.rinsebackFlowRate = value + // ToDo: create a component for this, + // ToDo: Consider putting the new CheckBox component into the SliderCreateTreatment component and set via boolean property + // This is a full implementation of a CheckBox + toggleSwich: _bloodPressureIntervalSwitch + Switch { id: _bloodPressureIntervalSwitch + property bool active: false + onCheckedChanged: { + if ( ! active ) { + active = true + checked = ! checked + } + vTreatmentCreate.bloodPressureMeasureInterval = 0 + _bloodPressureInterval.reset ( 0 ) + _bloodPressureInterval.active = ! checked + + } + + x : width * -1.5 + y : Variables.createTreatmentSwitchYDisplacement // these values are set to align the switch with slider + width : 75 // these values are set to align the switch with slider + height : 85 // these values are set to align the switch with slider + // DEBUG: background : Rectangle { color : "white" } + + indicator: Rectangle { + implicitWidth : Variables.sliderCircleDiameter * 1.7 + implicitHeight : Variables.sliderCircleDiameter - ( Variables.progressbarHandlerBorderWidth * 2 ) + radius : implicitHeight + anchors.centerIn: parent + color : _bloodPressureIntervalSwitch.checked ? Colors.backgroundButtonSelect : Colors.createTreatmentInactive + border.color : _bloodPressureIntervalSwitch.checked ? Colors.borderButton : Colors.createTreatmentInactive + Rectangle { + property real diameter : Variables.sliderCircleDiameter + + x: _bloodPressureIntervalSwitch.checked ? parent.width - width : 0 + anchors.verticalCenter: parent.verticalCenter + width : diameter + height : diameter + radius : diameter + color : _bloodPressureIntervalSwitch.active ? Colors.highlightProgressBar : Colors.createTreatmentInactive + border { + width: Variables.progressbarHandlerBorderWidth + color: Colors.textMain + } + } + } + + contentItem: Text { + text : _bloodPressureIntervalSwitch.checked ? qsTr("ON") : qsTr("OFF") + font : _bloodPressureIntervalSwitch.font + color : _bloodPressureIntervalSwitch.active ? Colors.textMain : Colors.textDisableButton + verticalAlignment: Text.AlignTop + horizontalAlignment: Text.AlignHCenter + anchors.centerIn: parent + } + } } + Item { width : 50 height : 50