diff --git a/src/controls/Slider.qml b/src/controls/Slider.qml index 7723496e8f7640ed3d6d83bf573af7a73b382245..95cda60f6d3645024dcd6344bab81cf6e0ae0997 100644 --- a/src/controls/Slider.qml +++ b/src/controls/Slider.qml @@ -166,6 +166,9 @@ Control { /*! \internal */ property bool __horizontal: orientation === Qt.Horizontal + /*! \internal */ + property real __handlePos: range.valueForPosition(__horizontal ? fakeHandle.x : fakeHandle.y) + activeFocusOnTab: true Accessible.role: Accessible.Slider @@ -198,10 +201,16 @@ Control { inverted: __horizontal ? false : true positionAtMinimum: 0 - positionAtMaximum: __horizontal ? slider.width : slider.height + positionAtMaximum: __horizontal ? slider.width - fakeHandle.width : slider.height - fakeHandle.height } - Item { id: fakeHandle } + Item { + id: fakeHandle + anchors.verticalCenter: __horizontal ? parent.verticalCenter : undefined + anchors.horizontalCenter: !__horizontal ? parent.horizontalCenter : undefined + width: __panel.handleWidth + height: __panel.handleHeight + } MouseArea { id: mouseArea @@ -212,22 +221,27 @@ Control { width: parent.width height: parent.height - drag.target: fakeHandle - drag.axis: __horizontal ? Drag.XAxis : Drag.YAxis - drag.minimumX: range.positionAtMinimum - drag.maximumX: range.positionAtMaximum + function clamp ( val ) { + return Math.max(range.positionAtMinimum, Math.min(range.positionAtMaximum, val)) + } + + onMouseXChanged: { + if (pressed && __horizontal) { + var pos = clamp (mouse.x - fakeHandle.width/2) + fakeHandle.x = pos + } + } + + onMouseYChanged: { + if (pressed && !__horizontal) { + var pos = clamp (mouse.y - fakeHandle.height/2) + fakeHandle.y = pos + } + } onPressed: { if (slider.activeFocusOnPress) slider.forceActiveFocus(); - - // Clamp the value - var current = __horizontal ? mouse.x : mouse.y - var minimum = __horizontal ? drag.minimumX : drag.minimumY - var maximum = __horizontal ? drag.maximumX : drag.maximumY - var newVal = Math.max(current, minimum); - newVal = Math.min(newVal, maximum); - range.position = newVal; } onReleased: { @@ -238,13 +252,10 @@ Control { } } - - - // Range position normally follow fakeHandle, except when - // 'updateValueWhileDragging' is false. In this case it will only follow - // if the user is not pressing the handle. + // Range position normally follows handle, except when + // 'updateValueWhileDragging' is false. Binding { - when: updateValueWhileDragging || !mouseArea.pressed + when: updateValueWhileDragging && !mouseArea.drag.active target: range property: "position" value: __horizontal ? fakeHandle.x : fakeHandle.y diff --git a/src/private/qquickstyleitem.cpp b/src/private/qquickstyleitem.cpp index bde25409e70fb93bae99421dfcca1b4385edbd2b..036f1f043c9da8702af8fca805a51a31f7a61649 100644 --- a/src/private/qquickstyleitem.cpp +++ b/src/private/qquickstyleitem.cpp @@ -543,7 +543,7 @@ void QQuickStyleItem::initStyleOption() if (opt->tickPosition != QSlider::NoTicks) opt->subControls |= QStyle::SC_SliderTickmarks; - opt->activeSubControls = QStyle::SC_None; + opt->activeSubControls = QStyle::SC_SliderHandle; } break; case ProgressBar: { diff --git a/src/styles/Desktop/SliderStyle.qml b/src/styles/Desktop/SliderStyle.qml index af6ad12ef7787321f99ffd8d5c18b5814fa46c75..d84c21efc164ce662828a0cf46874aa6f7c43c8a 100644 --- a/src/styles/Desktop/SliderStyle.qml +++ b/src/styles/Desktop/SliderStyle.qml @@ -51,11 +51,14 @@ Style { maximum: control.maximumValue*100 minimum: control.minimumValue*100 step: control.stepSize*100 - value: control.value*100 + value: control.__handlePos*100 horizontal: control.orientation === Qt.Horizontal enabled: control.enabled hasFocus: control.activeFocus hints: control.styleHints activeControl: control.tickmarksEnabled ? "ticks" : "" + property int handleWidth: 15 + property int handleHeight: 15 } + property Margins padding: Margins { top: 0 ; left: 0 ; right: 0 ; bottom: 0 } } diff --git a/src/styles/SliderStyle.qml b/src/styles/SliderStyle.qml index 02ad173fdaa8d7db38dde5d8a8092b45cea77995..0e244b62ed3677cfd32e5da9ec65091a7f651d90 100644 --- a/src/styles/SliderStyle.qml +++ b/src/styles/SliderStyle.qml @@ -139,6 +139,9 @@ Style { */ property Component panel: Item { id: root + property int handleWidth: handleLoader.width + property int handleHeight: handleLoader.height + property bool horizontal : control.orientation === Qt.Horizontal property int horizontalSize: grooveLoader.implicitWidth + padding.left + padding.right property int verticalSize: Math.max(handleLoader.implicitHeight, grooveLoader.implicitHeight) + padding.top + padding.bottom @@ -166,7 +169,7 @@ Style { id: handleLoader sourceComponent: handle anchors.verticalCenter: grooveLoader.verticalCenter - x: Math.round(control.value / control.maximumValue * ((horizontal ? root.width : root.height)- item.width)) + x: Math.round(control.__handlePos / control.maximumValue * ((horizontal ? root.width : root.height) - item.width)) } } } diff --git a/tests/auto/controls/data/tst_slider.qml b/tests/auto/controls/data/tst_slider.qml index 7c07ba4cb848ba4d7ee292e0f69a02186c76e286..f414e5189412ef74d75118a8af58e43123c41dd8 100644 --- a/tests/auto/controls/data/tst_slider.qml +++ b/tests/auto/controls/data/tst_slider.qml @@ -127,7 +127,7 @@ Item { var ratio = mouseRatio / sliderDeltaRatio mouseWheel(slider, 5, 5, 20 * ratio, 0) - compare(slider.value, 20) + compare(slider.value, 22) slider.maximumValue = 30 slider.minimumValue = 0 @@ -238,7 +238,15 @@ Item { } function test_updateValueWhileDragging() { - var control = Qt.createQmlObject('import QtQuick.Controls 1.0; Slider {x: 0; y: 0; width: 200; height: 50}', container, '') + var controlString = + 'import QtQuick 2.1 ; \ + import QtQuick.Controls 1.0 ; \ + import QtQuick.Controls.Styles 1.0; \ + Slider { \ + width: 200 ; \ + height : 50; \ + style: SliderStyle{ handle: Item{ } }}' + var control = Qt.createQmlObject(controlString, container, '') control.maximumValue = 200 control.minimumValue = 0 control.stepSize = 0.1 @@ -249,14 +257,15 @@ Item { spy.signalName = "valueChanged" control.updateValueWhileDragging = false - mouseDrag(control, 0,1, 100 + util.dragThreshold + 1 , 0, Qt.LeftButton) + mouseDrag(control, 0,1, 100 , 0, Qt.LeftButton) compare(control.value, 100) compare(spy.count, 1) control.updateValueWhileDragging = true - mouseDrag(control, 100,1, 80 + util.dragThreshold + 1 , 0, Qt.LeftButton) + + mouseDrag(control, 100,1, 80 , 0, Qt.LeftButton) compare(control.value, 180) - compare(spy.count, 4) + compare(spy.count, 5) control.destroy() } }