Index: sources/gui/qml/components/Slider.qml =================================================================== diff -u -rb07e8c91cabe64f9bc29b3653d27083b5cf96cb5 -r83b9d737cd495b34a7b42f5409962a9442f3b8f4 --- sources/gui/qml/components/Slider.qml (.../Slider.qml) (revision b07e8c91cabe64f9bc29b3653d27083b5cf96cb5) +++ sources/gui/qml/components/Slider.qml (.../Slider.qml) (revision 83b9d737cd495b34a7b42f5409962a9442f3b8f4) @@ -1,13 +1,13 @@ /*! * - * Copyright (c) 2020-2023 Diality Inc. - All Rights Reserved. + * Copyright (c) 2020-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 Slider.qml * \author (last) Behrouz NematiPour - * \date (last) 14-Mar-2023 + * \date (last) 26-Jan-2024 * \author (original) Behrouz NematiPour * \date (original) 18-Mar-2020 * @@ -24,9 +24,8 @@ * \brief Denali project ProgressBar */ RangeRect { id: _root - property alias value : _progressRect.value - property real displayedValue : 0 - property real initActiveValue : _root.minimum // the value to assigned upon first activation + property real value : _progressRect.value + property real defaultValue : _root.minimum property real step : 1 property bool stepSnap : false @@ -57,7 +56,18 @@ signal activeChanged() signal handleSelected() + signal sliderSelected() + onDefaultValueChanged: refreshValue() + + // this function shall be used in case that any external value is forced to be set for the slider + // like the OFF switch wants to externally set the slider value and bypass slider controlls and checks. + // same is used in the main treatment Blood,dialyzer sliders to be set to the current value when get in to adjustment screen. + function reset(vValue) { + _root.value = vValue + _progressRect.value = vValue + } + function incrementValue (vInStepSegments) { updateValue(vInStepSegments, true) } @@ -74,17 +84,21 @@ let newValue = Number.NaN if(vIsIncrement) { - newValue = _root.value + amountChanged + newValue = _progressRect.value + amountChanged } else { - newValue = _root.value - amountChanged + newValue = _progressRect.value - amountChanged } // Capping values based on min/max threshold if ( newValue < minimum ) newValue = minimum if ( newValue > maximum ) newValue = maximum - // update new value - update(newValue.toFixed(decimal)) + // Update the slider's visual value + _progressRect.previousSliderValue = newValue // for comparison purposes + _progressRect.value = newValue // visual value + + // update slider value with rounded new value + update(newValue) } function setActiveVisuals(active) { @@ -97,27 +111,30 @@ } } - onIsActiveChanged: { - setActiveVisuals(isActive) - + /* + refreshValue() re-evaluates the _root.value and _progressRect.value based on the + current active state. This function is used when the defaultValue property or + isActive property changes. + */ + function refreshValue() { // value is assigned a different value based on active-ness of the slider // This is to resolve the use of slider with a switch and arrows enabled. // It allows correct behavior when using arrow on a first initialize increment of // the slider when the slider has inActiveZero to true. - if (!isActive) { - value = inActiveZero ? 0 : minimum + if(!isActive) { + _root.value = inActiveZero ? 0 : _root.defaultValue } else { - value = initActiveValue + _root.value = _root.defaultValue } - activeChanged() // emit + // need to set the value of progressRect to reflect handle position + _progressRect.value = _root.defaultValue } - onValueChanged: { - if ( _root.isActive ) { - // update the displayed value to the attentive snapped value - _root.displayedValue = calculateRoundedValue(_root.value) - } + onIsActiveChanged: { + setActiveVisuals(isActive) + refreshValue () // re-evaluate values + activeChanged() // emit } height : Variables.sliderDefaultBodyHeight @@ -134,6 +151,7 @@ // real-time bound change should effect the current set value onMinimumChanged: { + if ( !isActive && inActiveZero ) { value = 0; return } if (value < minimum ) value = minimum } @@ -171,7 +189,9 @@ let mMinimum = Number(_root.minimum.toFixed(decimal)) let mMaximum = Number(_root.maximum.toFixed(decimal)) - if(x < _handler.width) { + // the center of the handler is aligned on the snap point and half width shall be used to set as min not the entire width. + // also half of the hadler is out of slider min position when set on min, which proves the same as above. + if(x < ( _handler.width / 2 ) ) { // The outside of the slider, lower bound case return mMinimum } @@ -231,14 +251,16 @@ lineTickMarkThickness : _root.tickMarksThickness isTickMarkRound : _root.isRoundedEnds yDisplacement : _root.isRoundedEnds ? (-_handler.height/2 - _handler.border.width/2) : 0 - color: _root.isActive ? Colors.borderButton : Colors.borderDisableButton + color : _root.isActive ? Colors.borderButton : Colors.borderDisableButton } } ProgressRect { id: _progressRect property real previousSliderValue: Number.NaN + value : minimum color : Colors.sliderHighlightColor decimal : _root.decimal + minimum : _root.minimum maximum : _root.maximum leftRightTouchMargin: _handler.width/2 @@ -268,15 +290,20 @@ // Check the cursor's current value to determine if the cursor had moved // Do not avoid type coercion, it will produce undesired results if(newCurrentValue != _progressRect.previousSliderValue) { - // The cursor did move + + // The cursor did move if(stepSnapOnRelease) { // check for snapping state to save an iteration of recalculation if snap is off newCurrentValue = calculateValue(vCurrentPositionX, stepSnapOnRelease) } // Update the slider's value since the cursor did move - update(newCurrentValue) - _progressRect.previousSliderValue = newCurrentValue + _progressRect.previousSliderValue = newCurrentValue // for comparison purposes + _progressRect.value = newCurrentValue // visual value + + // update slider value with rounded new value + update(calculateRoundedValue(newCurrentValue)) + } } @@ -285,18 +312,16 @@ // Need to account for the extended touch areas let adjustedXPosition = vMouseEvent.x - _progressRect.leftRightTouchMargin let newCurrentValue = calculateValue(adjustedXPosition, !stepSnapOnRelease) - update(newCurrentValue) + _progressRect.value = newCurrentValue // update visual active slider bar + + update(calculateRoundedValue(newCurrentValue)) // displayed/slider value } + onPressed: { - if(!_root.isActive) { - _root.isActive = true - } + // Indicate that the slider body was selected to provide handling/activation + sliderSelected() // emit - // On initial press without release, the value is updated to reflect the current - // pressed position, effectively moving the handle to the location without snapping - let adjustedXPosition = vMouseEvent.x - _progressRect.leftRightTouchMargin - let newCurrentValue = calculateValue(adjustedXPosition, !stepSnapOnRelease) - update(newCurrentValue) + updateHandleValue(vMouseEvent.x - _progressRect.leftRightTouchMargin) } onReleased: { // Need to account for the extended touch areas @@ -322,11 +347,6 @@ anchors.fill: parent propagateComposedEvents: true onPressed: { - // Handle was inactive and was selected, update the value - if ( !_root.isActive ) { - value = inActiveZero ? 0 : minimum - _root.displayedValue = calculateRoundedValue(value) - } mouse.accepted = false // allow propagtion to the lower mouse areas handleSelected() // emit }