Index: sources/gui/qml/components/Slider.qml =================================================================== diff -u -raf8d98b36b427e2b5f4d6659fcf3b58ee79eab6a -r43ffdd5ca0998f06d28b6adeee231a6eec7e7150 --- sources/gui/qml/components/Slider.qml (.../Slider.qml) (revision af8d98b36b427e2b5f4d6659fcf3b58ee79eab6a) +++ sources/gui/qml/components/Slider.qml (.../Slider.qml) (revision 43ffdd5ca0998f06d28b6adeee231a6eec7e7150) @@ -25,9 +25,11 @@ */ RangeRect { id: _root property alias value : _progressRect.value + property real displayedValue : 0 property real step : 1 property bool stepSnap : false + property bool stepSnapOnRelease : true property bool ticks : false @@ -36,14 +38,14 @@ property alias handler : _handler property alias handlerColor : _handler.color - property alias handlerVisible : _handler.visible + property bool handlerVisible : _handler.visible property alias diameter : _handler.diameter property bool isActive : true property bool inActiveZero : false // if inActiveZero:true, when is not active (inActive or active:false) sets to zero instead of minimum - property alias progressRectMargin : _progressRect.margin + //property alias progressRectMargin : _progressRect.margin property int tickMarksThickness : 2 @@ -74,8 +76,9 @@ activeChanged() } - height : Variables.progressbarHeight - touchMargin : 25 + height : Variables.progressbarHeight + touchMargin : 25 + leftRightTouchMargin: _handler.width/2 minimum : 0 maximum : 0 @@ -111,32 +114,58 @@ _root.value = vValue } - function setValue(x) { - let mValue = 0 + function setValue(x, isSnappingToTicks) { let mMinimum = Number(_root.minimum.toFixed(decimal)) let mMaximum = Number(_root.maximum.toFixed(decimal)) - if ( x < 0 ) { mValue = mMinimum; update(mValue); return; } - if ( x > width ) { mValue = mMaximum; update(mValue); return; } - mValue = getValueOfX(x) + if(x < _handler.width) { + // The outside of the slider, lower bound case + update(mMinimum) + _root.displayedValue = mMinimum + return + } - if ( step === 1 ) { mValue = parseInt(mValue); update(mValue); return; } + if(x > (_root.width - _handler.width/2)) { + // The outside of the slider, upper bound case + update(mMaximum) + _root.displayedValue = mMaximum + return + } + // Calculate the inbetween : + let mValue = 0 let start = 0 + if ( ! stepSnap ) start = mMinimum - mValue = Math.round((mValue - start) / step) * step + start - let decimals = Math.round(-Math.log10(step)) + mValue = getValueOfX(x) + + if(step < _handler.width/2) { + // special handling for the case that the step segments are less than half the handle width + let valueStepCount = parseInt(mValue / step) + + if(valueStepCount <= 1) mValue = step // special case of segment for first tick + + update(mValue); + return; + } + + if(isSnappingToTicks) + mValue = Math.round((mValue - start) / step) * step + start + else + mValue = Math.round(mValue - start + start) + + decimals = Math.round(-Math.log10(step)) if (decimals > 0) { mValue = mValue.toFixed(decimals) } if ( mValue < mMinimum ) { mValue = mMinimum; update(mValue); return; } if ( mValue > mMaximum ) { mValue = mMaximum; update(mValue); return; } - update(mValue); return; } + // Function not used function setHandlerPosition() { if ( _progressRect.width <= 0 ) { _handler.x = 0 - _root.tickMarksThickness @@ -155,21 +184,23 @@ minimum : _root.minimum maximum : _root.maximum height: 5 + + leftRightTouchMargin: _handler.width/2 + // propagation is not working on drag ! onDragged: { - setValue(vMouseEvent.x) + _root.dragged(vMouseEvent) progressRectDragged() } onClicked: { - setValue(vMouseEvent.x) + _root.clicked(vMouseEvent) progressRectClicked() + } onPressed: { - setValue(vMouseEvent.x) _root.pressed(vMouseEvent) } onReleased: { - setValue(vMouseEvent.x) _root.released(vMouseEvent) } onWidthChanged: { @@ -195,16 +226,28 @@ } onDragged: { - setValue(vMouseEvent.x) + setValue(vMouseEvent.x, !stepSnapOnRelease) + + //Correct the handle location when dragging update + if(_progressRect.width >= _handler.width/2) + _handler.anchors.horizontalCenterOffset = -_progressRect.leftRightTouchMargin + else + _handler.anchors.horizontalCenterOffset = 0 + + _root.displayedValue = parseInt(Math.round(_root.value / step) * step) + } onClicked: { - setValue(vMouseEvent.x) + setValue(vMouseEvent.x, true) } onPressed: { - setValue(vMouseEvent.x) + setValue(vMouseEvent.x, !stepSnapOnRelease) } onReleased: { - setValue(vMouseEvent.x) + setValue(vMouseEvent.x, true) + + _handler.anchors.horizontalCenterOffset = 0 + _root.displayedValue = parseInt(Math.round(_root.value / step) * step) } Rectangle { id: _handler @@ -213,6 +256,7 @@ anchors.verticalCenter : parent.verticalCenter anchors.horizontalCenter: _progressRect.right + opacity: 0.5 width : diameter height : diameter radius : diameter