Index: sources/gui/qml/components/Slider.qml =================================================================== diff -u -r3b20d3a8a2e0b3e3282313cd68f2aadee1c45869 -r0f28ae04f739c859dc850a9baa430c62251629d6 --- sources/gui/qml/components/Slider.qml (.../Slider.qml) (revision 3b20d3a8a2e0b3e3282313cd68f2aadee1c45869) +++ sources/gui/qml/components/Slider.qml (.../Slider.qml) (revision 0f28ae04f739c859dc850a9baa430c62251629d6) @@ -76,6 +76,11 @@ activeChanged() } + onValueChanged: { + // update the displayed value to the attentive snapped value + _root.displayedValue = (Math.round(_root.value / step) * step).toFixed(decimal) + } + height : Variables.progressbarHeight touchMargin : 25 leftRightTouchMargin: _handler.width/2 @@ -114,22 +119,18 @@ _root.value = vValue } - function setValue(x, isSnappingToTicks) { + function calculateValue(x, isSnappingToTicks) { let mMinimum = Number(_root.minimum.toFixed(decimal)) let mMaximum = Number(_root.maximum.toFixed(decimal)) if(x < _handler.width) { // The outside of the slider, lower bound case - update(mMinimum) - _root.displayedValue = mMinimum - return + return mMinimum } - if(x > (_root.width - _handler.width/2)) { + if(x > _root.width ) { // The outside of the slider, upper bound case - update(mMaximum) - _root.displayedValue = mMaximum - return + return mMaximum } // Calculate the in-between : @@ -145,43 +146,29 @@ if ( stepWidth < _handler.width ) { let valueStepCount = parseInt(mValue / step) mValue = valueStepCount * step - update(mValue.toFixed(decimal)); - return; + return mValue.toFixed(decimal) } if ( isSnappingToTicks ) { mValue = Math.round((mValue - start) / step) * step + start + let additionalDecimalResolution = 3 + mValue = mValue.toFixed(decimal + additionalDecimalResolution) + } // For sliders with decimal min, max, values, we need to add refinement to // the value to achieve slider handle movement close to those of the whole number sliders if ( decimal > 0 ) { - let additionalDecimalResolution = 3 - mValue = mValue.toFixed(decimal + additionalDecimalResolution) } - if ( mValue < mMinimum ) { mValue = mMinimum; update(mValue); return; } - if ( mValue > mMaximum ) { mValue = mMaximum; update(mValue); return; } - update(mValue); return; + if ( mValue < mMinimum ) { return mMinimum; } + if ( mValue > mMaximum ) { return mMaximum; } + return mValue; } - function updateSliderVisuals(isSnapped) { - // Correct the handle location when dragging to assure centering of - // the handle on the cursor / touchpoint - // if isSnapped is true, indicates handler is to snap to a tick, remove displacement - // to assure centering on the edge of ProgressRect - if(!isSnapped && (_progressRect.width >= _handler.width/2)) { - _handler.anchors.horizontalCenterOffset = -_progressRect.leftRightTouchMargin - } else { - _handler.anchors.horizontalCenterOffset = 0 - } - - // update the displayed value to the attentive snapped value - _root.displayedValue = (Math.round(_root.value / step) * step).toFixed(decimal) - } - ProgressRect { id: _progressRect - color : Colors.highlightProgressBar + property real previousSliderValue: _progressRect.value + color : Colors.highlightProgressBar decimal : _root.decimal minimum : _root.minimum maximum : _root.maximum @@ -194,10 +181,6 @@ _root.dragged(vMouseEvent) progressRectDragged() } - onClicked: { - _root.clicked(vMouseEvent) - progressRectClicked() - } onPressed: { _root.pressed(vMouseEvent) } @@ -223,18 +206,43 @@ } onDragged: { - setValue(vMouseEvent.x, !stepSnapOnRelease) - updateSliderVisuals(false) + // On position change / dragging, the value is updated based on value calculated + // Need to account for the extended touch areas + let adjustedXPosition = vMouseEvent.x - _progressRect.leftRightTouchMargin + let newCurrentValue = calculateValue(adjustedXPosition, !stepSnapOnRelease) + update(newCurrentValue) } - onClicked: { - setValue(vMouseEvent.x, true) + + onPressed : { + // On a pressed state, calculate and store the value of current x position + // Need to account for the extended touch areas + let adjustedXPosition = vMouseEvent.x - _progressRect.leftRightTouchMargin + + // Passing false for snapping to get exact value in respect to x + let newCurrentValue = calculateValue(adjustedXPosition, false) + _progressRect.previousSliderValue = newCurrentValue } - onPressed: { - setValue(vMouseEvent.x, !stepSnapOnRelease) - } + onReleased: { - setValue(vMouseEvent.x, true) - updateSliderVisuals(true) + // Check the cursor's current value to determine if the cursor had moved + // Need to account for the extended touch areas + let adjustedXPosition = vMouseEvent.x - _progressRect.leftRightTouchMargin + + // Passing false for snapping to get exact value in respect to x + let newCurrentValue = calculateValue(adjustedXPosition, false) + + // Do not avoid type coercion, it will produce undesired results + if(newCurrentValue != _progressRect.previousSliderValue) { + // The cursor did move + if(stepSnapOnRelease) { + // check for snapping state to save an iteration of recalculation if snap is off + newCurrentValue = calculateValue(vMouseEvent.x - _progressRect.leftRightTouchMargin, stepSnapOnRelease) + } + + // Update the slider's value since the cursor did move + update(newCurrentValue) + } + } Rectangle { id: _handler @@ -243,7 +251,6 @@ anchors.verticalCenter : parent.verticalCenter anchors.horizontalCenter: _progressRect.right - opacity: 0.5 width : diameter height : diameter radius : diameter