Index: sources/gui/qml/components/RangeSlider.qml =================================================================== diff -u -rb07e8c91cabe64f9bc29b3653d27083b5cf96cb5 -r2ef03b2ce51b4dc507f66e9671953a8e0824bde9 --- sources/gui/qml/components/RangeSlider.qml (.../RangeSlider.qml) (revision b07e8c91cabe64f9bc29b3653d27083b5cf96cb5) +++ sources/gui/qml/components/RangeSlider.qml (.../RangeSlider.qml) (revision 2ef03b2ce51b4dc507f66e9671953a8e0824bde9) @@ -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 RangeSlider.qml * \author (last) Behrouz NematiPour - * \date (last) 14-Mar-2023 + * \date (last) 31-Mar-2023 * \author (original) Behrouz NematiPour * \date (original) 17-Sep-2020 * @@ -51,6 +51,8 @@ property real maxValueLowerBound : 0 property real maxValueUpperBound : 0 + property bool lowerBoundValid : true + property bool upperBoundValid : true property int curHandler : RangeSlider.HandlerOption.None ///< current active slider handler property int diameter : Variables.progressbarHandler ///< handlers diameter @@ -67,12 +69,15 @@ property bool maxAdjusted : false ///< first time user adjustment happens property bool hasAdjust : false ///< if set to true then component is grayed out until both min and max are adjusted - property bool showTickmarks : true ///< Indicate whether tickMarks should be shown - property bool isTickMarksRound : true ///< Indicate whether the tickmakrs are round + property bool showTickmarks : true ///< Indicate whether tickMarks should be shown + property bool isTickMarksRound : true ///< Indicate whether the tickmarks are round + property bool isTickMarksCentered : false ///< Indicate whether the tickmarks are centered in the slider body + property int tickMarkYDisplacement : (-diameter + Variables.progressbarHandlerBorderWidth*2) ///< The amount of y displacement if the TickMarks are not centered property bool isRoundedEnds : true property bool hasBorder : true - property color borderColor : Colors.borderDisableButton + property color disabledBorderColor : Colors.borderDisableButton + property color enabledBorderColor : Colors.borderButton onHasAdjustChanged : { setAdjusted() @@ -95,27 +100,44 @@ radius : _root.isRoundedEnds ? (height/2) : Variables.rangeRectRadius border.width: _root.hasBorder ? Variables.rangeRectBorderWidth : 0 - border.color: (_root.minAdjusted && _root.maxAdjusted) ? Colors.borderButton : Colors.borderDisableButton + border.color: (_root.minAdjusted && _root.maxAdjusted) ? enabledBorderColor : disabledBorderColor minimum : 0 maximum : 0 - /// Lable of the minimum of range + /// The label under the rangeSlider for minimum value minText { visible : true anchors.topMargin: Variables.sliderTextMargin font.pixelSize : Fonts.fontPixelSliderMarker font.bold : false } - ///< Lable of the maximum of range + /// The label under the rangeSlider for maximum value maxText { visible : true anchors.topMargin: Variables.sliderTextMargin font.pixelSize : Fonts.fontPixelSliderMarker font.bold : false } + function incrementMax(vInStepSegments) { + if ( ! maxAdjusted ) { setMaxValue(_root.maxValueUpperBound )} + else { updateMaxValue(vInStepSegments, true )} + } + function decrementMax(vInStepSegments) { + if ( ! maxAdjusted ) { setMaxValue(_root.maxValueUpperBound )} + else { updateMaxValue(vInStepSegments, false)} + } + + function incrementMin(vInStepSegments) { + if ( ! minAdjusted ) { setMinValue(_root.minValueLowerBound )} + else { updateMinValue(vInStepSegments, true )} + } + function decrementMin(vInStepSegments) { + if ( ! minAdjusted ) { setMinValue(_root.minValueLowerBound )} + else { updateMinValue(vInStepSegments, false)} + } /// /// \brief grays out the rangebar and handler if not adjusted and hasAdjust set to true /// @@ -216,7 +238,7 @@ function checkLimitsMinValueBounds ( vValue ) { if ( vValue < minValueLowerBound ) { minValue = minValueLowerBound; return } if ( vValue > minValueUpperBound ) { minValue = minValueUpperBound; return } - setMinvalue(vValue) + setMinValue(vValue) } function checkLimitsMaxValueBounds ( vValue ) { @@ -225,16 +247,88 @@ setMaxValue(vValue) } - function setMinvalue(vValue) { - minAdjusted = true - minValue = vValue + function setMinValue(vValue) { + // added an if block in case for the first time (not adjusted yet) the value is not changed (still on def value), to force the valueChanged emit. + if ( ! minAdjusted ) { + minAdjusted = true + if ( vValue == minValue ) + minValueChanged(vValue) + else + minValue = vValue + } + else { + minValue = vValue + } } function setMaxValue(vValue) { - maxAdjusted = true - maxValue = vValue + // added an if block in case for the first time (not adjusted yet) the value is not changed (still on def value), to force the valueChanged emit. + if ( ! maxAdjusted ) { + maxAdjusted = true + if ( vValue == maxValue ) + maxValueChanged(vValue) + else + maxValue = vValue + } + else { + maxValue = vValue + } } + // This is a helper function that will calculate and return a new value + // that was either incremented or decremented by 1 or step amount + function determineNewValue(vOldValue, vInStepSegments, vIsIncrementing) { + let amountChanged = 1 + if (vInStepSegments) { + amountChanged = step + } + + let newValue = Number.NaN + if(vIsIncrementing) { + newValue = vOldValue + amountChanged + } else { + newValue = vOldValue - amountChanged + } + + // Capping values based on min/max threshold + if ( newValue < minimum ) newValue = minimum + if ( newValue > maximum ) newValue = maximum + + return newValue.toFixed(decimal) + } + + function updateMaxValue(vInStepSegments, vIsIncrementing) { + // Set the "focused" handle to be the maxium handle + curHandler = RangeSlider.HandlerOption.Max + + // In order to use pre-existing rules for handling min/max ranges, need to calculate X of new value + let newMaxValue = determineNewValue(_root.maxValue, vInStepSegments, vIsIncrementing) + let newX = ((newMaxValue - _root.minimum)*_root.width) / (_root.maximum - _root.minimum) + + // Update the boundary + setBound(newX) + } + + function updateMinValue(vInStepSegments, vIsIncrementing) { + // Set the "focused" handle to be the minium handle + curHandler = RangeSlider.HandlerOption.Min + + // In order to use pre-existing rules for handling min/max ranges, need to calculate X of new value + let newMinValue = determineNewValue(_root.minValue, vInStepSegments, vIsIncrementing) + let newX = ((newMinValue - _root.minimum)*_root.width) / (_root.maximum - _root.minimum) + + // Update the boundary + setBound(newX) + } + + function getColor(vIsActive, vIsValid) { + let color = Colors.textMain + if ( ! vIsValid ) { color = Colors.createTreatmentInvalidParam ; return color } + if ( ! vIsActive ) { color = Colors.textDisableButton ; return color } + return color + } + + /// The main range rectangle bar - This is the "highlighted" area of the slider RangeRect { id: _rangeRect property alias lowerBound : _rangeRect.minimum @@ -248,17 +342,19 @@ radius : _root.isRoundedEnds ? (height/2) : Variables.rangeRectRadius border.width: _root.hasBorder ? Variables.rangeRectBorderWidth : 0 - border.color: (_root.minAdjusted && _root.maxAdjusted) ? Colors.borderButton : Colors.borderDisableButton + border.color: (_root.minAdjusted && _root.maxAdjusted) ? Colors.sliderProgressBorderActive : Colors.borderDisableButton decimal : _root.decimal - minText { - visible: false - anchors.topMargin: -40 + minText { // The minimum value label above the handle + visible : false + anchors.topMargin: -60 + color : _root.getColor((_root.minAdjusted && _root.maxAdjusted), lowerBoundValid) } - maxText { - visible: false - anchors.topMargin: -40 + maxText { // the maximum value label above the handle + visible : false + anchors.topMargin: -60 + color : _root.getColor((_root.minAdjusted && _root.maxAdjusted), upperBoundValid) } // propagation is not working on drag ! @@ -297,8 +393,14 @@ textColor : _root.color lineTickMarkHeight: _rangeRect.height isTickMarkRound : _root.isTickMarksRound - yDisplacement : _root.border.width/2 - 1 // had to subtract 1 to center on the _rangeRect - showEndMarks : false + yDisplacement : { + if ( _root.isTickMarksCentered ) { + return (_root.border.width/2 - 1) // had to subtract 1 to center on the _rangeRect + } else { + return _root.tickMarkYDisplacement + } + } + showEndMarks : true color: _root.isActive ? Colors.borderButton : Colors.borderDisableButton } } @@ -336,7 +438,7 @@ /// Left most handler Rectangle { id: _handlerLeft - property real diameter : _root.diameter + property real diameter : _root.diameter anchors.verticalCenter : parent.verticalCenter anchors.horizontalCenter: _rangeRect.left @@ -346,7 +448,7 @@ radius : diameter color : Colors.highlightProgressBar border { - width : 4 + width : Variables.progressbarHandlerBorderWidth color : Colors.textMain } MouseArea { id: _leftHandleMouseArea @@ -376,7 +478,7 @@ radius : diameter color : Colors.highlightProgressBar border { - width : 4 + width : Variables.progressbarHandlerBorderWidth color : Colors.textMain } MouseArea { id: _rightHandlerMouseArea