Index: sources/gui/qml/components/Slider.qml =================================================================== diff -u -rc65859e54930664100dfdff13afa019e05ae23b6 -rcb9c48c7c307690dcafcfd16ef412fe660291692 --- sources/gui/qml/components/Slider.qml (.../Slider.qml) (revision c65859e54930664100dfdff13afa019e05ae23b6) +++ sources/gui/qml/components/Slider.qml (.../Slider.qml) (revision cb9c48c7c307690dcafcfd16ef412fe660291692) @@ -25,6 +25,7 @@ */ RangeRect { id: _root property real value : _progressRect.value + property real minStop : _root.minimum property real defaultValue : _root.minimum property real step : 1 @@ -54,7 +55,13 @@ property bool isRoundedEnds : true property bool hasBorder : true property bool showMinMaxText : true - property color borderColor : Colors.borderDisableButton + property color borderColor : Colors.borderDisableButton + property color highlightActiveColor : Colors.sliderHighlightColor + property color highlightInactiveColor : Colors.createTreatmentInactive + property color progressBorderActiveColor : Colors.sliderProgressBorderActive + property color progressBorderInactiveColor : Colors.borderDisableButton + property color handlerActiveColor : Colors.createTreatmentActive + property color handlerInactiveColor : Colors.createTreatmentInactive signal activeChanged() signal handleSelected() @@ -86,14 +93,16 @@ let newValue = Number.NaN if(vIsIncrement) { - newValue = _progressRect.value + amountChanged + newValue = calculateRoundedValue(_progressRect.value + amountChanged) } else { - newValue = _progressRect.value - amountChanged + newValue = calculateRoundedValue(_progressRect.value - amountChanged) } // Capping values based on min/max threshold - if ( newValue < minimum ) newValue = minimum - if ( newValue > maximum ) newValue = maximum + let min = calculateMinimum() + let max = calculateMaximum() + if ( newValue < min ) newValue = min + if ( newValue > max ) newValue = max // Update the slider's visual value _progressRect.previousSliderValue = newValue // for comparison purposes @@ -105,11 +114,11 @@ function setActiveVisuals(active) { if (active) { - color = Colors.sliderHighlightColor - handlerColor = Colors.createTreatmentActive + color = _root.highlightActiveColor + handlerColor = _root.handlerActiveColor } else { - color = Colors.createTreatmentInactive - handlerColor = Colors.createTreatmentInactive + color = _root.highlightInactiveColor + handlerColor = _root.handlerInactiveColor } } @@ -179,6 +188,12 @@ return (Math.round(vValue / step) * step).toFixed(decimal) } + // round the value based on the given precision (not step) + function calculatePrecisionRoundedValue(value) { + let multiplier = Math.pow(10, decimal) + return Math.round(value * multiplier) / multiplier + } + function getValueOfX(x) { return ( x * ( maximum - minimum ) ) / width + minimum } @@ -188,8 +203,8 @@ } function calculateValue(x, isSnappingToTicks) { - let mMinimum = Number(_root.minimum.toFixed(decimal)) - let mMaximum = Number(_root.maximum.toFixed(decimal)) + let mMinimum = calculateMinimum() + let mMaximum = calculateMaximum() // 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. @@ -216,8 +231,10 @@ let stepWidth = width / ((mMaximum - mMinimum) / step) if ( stepWidth < _handler.width ) { let valueStepCount = parseInt(mValue / step) - mValue = valueStepCount * step - return mValue.toFixed(decimal) + mValue = calculateRoundedValue((valueStepCount * step)) + if ( mValue < mMinimum ) { return mMinimum } + if ( mValue > mMaximum ) { return mMaximum } + return mValue } // For sliders with decimal min, max, values, we need to add refinement to @@ -237,6 +254,44 @@ return mValue; } + /*! + * \brief Calculate the minimum value for the slider based on the current minimum, + * minStop, and stepSnap values. + * \return If minimum is greater than or equal to minStop, then just return minimum. + * If minStop is greater than minimum and stepSnap is false, then return minStop. + * If minStop is greater than minimum and stepSnap is true, then return minStep if + * it falls on a step, otherwise return the step above minStop. + */ + function calculateMinimum() { + let result = calculateRoundedValue(_root.minimum) + let rdMinStop = calculatePrecisionRoundedValue(_root.minStop) + if (rdMinStop > result) { + if (stepSnap) { + // if slider is set to snap and minimum stop is not on a step, then + // adjust it to one step above + let rdStep = calculatePrecisionRoundedValue(step) + result = Math.ceil(rdMinStop/rdStep) * rdStep + } + else { + result = rdMinStop + } + } + return result + } + + /*! + * \brief Calculate the maximum value for the slider based on the current maximum + * and stepSnap values. + * \return If stepSnap is false, then maximum. + * If stepSnap is true and maximum does not fall on a step, then one step below maximum, + * otherwise maximum. + */ + function calculateMaximum() { + let result = calculatePrecisionRoundedValue(_root.maximum) + return stepSnap ? Math.min(result, parseInt(result/step) * step) + : result + } + // used loader for performance since it may not always be required. // and can be a heavy Component Loader { id: _ticksLoader @@ -260,7 +315,7 @@ ProgressRect { id: _progressRect property real previousSliderValue: Number.NaN value : minimum - color : Colors.sliderHighlightColor + color : _root.highlightActiveColor decimal : _root.decimal minimum : _root.minimum @@ -270,7 +325,7 @@ radius : _root.isRoundedEnds ? (height/2) : Variables.rangeRectRadius border.width: _root.hasBorder ? Variables.rangeRectBorderWidth : 0 - border.color: _root.isActive ? Colors.sliderProgressBorderActive : Colors.borderDisableButton + border.color: _root.isActive ? _root.progressBorderActiveColor : _root.progressBorderInactiveColor // propagation is not working on drag ! onDragged: { @@ -340,7 +395,7 @@ width : diameter height : diameter radius : diameter - color : Colors.highlightProgressBar + color : _root.handlerActiveColor border { width: Variables.progressbarHandlerBorderWidth color: _root.handleBorderColor