diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/DoubleSpinBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/DoubleSpinBox.qml index 10e21ec3f16..2455a277b51 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/DoubleSpinBox.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/DoubleSpinBox.qml @@ -38,6 +38,8 @@ Item { property alias sliderIndicatorVisible: spinBox.sliderIndicatorVisible property alias hover: spinBox.hover + property alias pixelsPerUnit: spinBox.pixelsPerUnit + signal valueModified signal dragStarted signal indicatorPressed @@ -50,6 +52,8 @@ Item { StudioControls.RealSpinBox { id: spinBox + __devicePixelRatio: devicePixelRatio() + onDragStarted: { hideCursor() wrapper.dragStarted() diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/SpinBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/SpinBox.qml index cd22b7e7f26..853357200bf 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/SpinBox.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/SpinBox.qml @@ -41,6 +41,7 @@ Item { property alias sliderIndicatorVisible: spinBox.sliderIndicatorVisible property alias realDragRange: spinBox.realDragRange + property alias pixelsPerUnit: spinBox.pixelsPerUnit width: 96 implicitHeight: spinBox.height @@ -64,6 +65,8 @@ Item { StudioControls.RealSpinBox { id: spinBox + __devicePixelRatio: devicePixelRatio() + onDragStarted: { hideCursor() transaction.start() @@ -74,11 +77,12 @@ Item { transaction.end() } + // Needs to be held in place due to screen size limits potentially being hit while dragging onDragging: holdCursorInPlace() onRealValueModified: { if (transaction.active()) - commitValue() + spinBox.commitValue() } function commitValue() { @@ -105,13 +109,13 @@ Item { id: colorLogic backendValue: spinBox.backendValue onValueFromBackendChanged: { - if (valueFromBackend !== undefined) - spinBox.realValue = valueFromBackend + if (colorLogic.valueFromBackend !== undefined) + spinBox.realValue = colorLogic.valueFromBackend } } labelColor: spinBox.edit ? StudioTheme.Values.themeTextColor : colorLogic.textColor - onCompressedRealValueModified: commitValue() + onCompressedRealValueModified: spinBox.commitValue() } } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSpinBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSpinBox.qml index dd2fe2357f1..6cf763f3ab5 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSpinBox.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSpinBox.qml @@ -74,6 +74,9 @@ T.SpinBox { property real __sliderIndicatorWidth: StudioTheme.Values.sliderIndicatorWidth property real __sliderIndicatorHeight: StudioTheme.Values.sliderIndicatorHeight + property alias __devicePixelRatio: spinBoxInput.devicePixelRatio + property alias pixelsPerUnit: spinBoxInput.pixelsPerUnit + property alias compressedValueTimer: myTimer signal realValueModified diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSpinBoxInput.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSpinBoxInput.qml index abc8568a2d7..53829682bfe 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSpinBoxInput.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSpinBoxInput.qml @@ -36,6 +36,9 @@ TextInput { property bool drag: false property bool hover: mouseArea.containsMouse && textInput.enabled + property int devicePixelRatio: 1 + property int pixelsPerUnit: 10 + z: 2 font: myControl.font color: StudioTheme.Values.themeTextColor @@ -77,18 +80,21 @@ TextInput { if (event.modifiers & Qt.ControlModifier) { mouseArea.stepSize = myControl.minStepSize - mouseArea.calcValue(myControl.realValueModified) + mouseArea.calcValue() + myControl.realValueModified() } if (event.modifiers & Qt.ShiftModifier) { mouseArea.stepSize = myControl.maxStepSize - mouseArea.calcValue(myControl.realValueModified) + mouseArea.calcValue() + myControl.realValueModified() } } Keys.onReleased: function(event) { event.accepted = true mouseArea.stepSize = myControl.realStepSize - mouseArea.calcValue(myControl.realValueModified) + mouseArea.calcValue() + myControl.realValueModified() } } @@ -102,34 +108,42 @@ TextInput { property real stepSize: myControl.realStepSize + // Properties to store the state of a drag operation property bool dragging: false - property bool wasDragging: false + property bool hasDragged: false property bool potentialDragStart: false - property real initialValue: myControl.realValue + property real initialValue: myControl.realValue // value on drag operation starts property real pressStartX: 0.0 property real dragStartX: 0.0 property real translationX: 0.0 + property real dragDirection: 0.0 + property real totalUnits: 0.0 // total number of units dragged + property real units: 0.0 + + property real __pixelsPerUnit: textInput.devicePixelRatio * textInput.pixelsPerUnit + anchors.fill: parent enabled: true hoverEnabled: true propagateComposedEvents: true acceptedButtons: Qt.LeftButton cursorShape: Qt.PointingHandCursor + preventStealing: true onPositionChanged: function(mouse) { if (!mouseArea.dragging && !myControl.edit && Math.abs(mouseArea.pressStartX - mouse.x) > StudioTheme.Values.dragThreshold - && mouse.buttons === 1 + && mouse.buttons === Qt.LeftButton && mouseArea.potentialDragStart) { mouseArea.dragging = true mouseArea.potentialDragStart = false mouseArea.initialValue = myControl.realValue mouseArea.cursorShape = Qt.ClosedHandCursor - mouseArea.dragStartX = mouseArea.mouseX + mouseArea.dragStartX = mouse.x myControl.drag = true myControl.dragStarted() @@ -143,18 +157,32 @@ TextInput { mouse.accepted = true - mouseArea.translationX += (mouseArea.mouseX - mouseArea.dragStartX) - mouseArea.calcValue(myControl.realValueModified) - } + var translationX = mouse.x - mouseArea.dragStartX - onCanceled: mouseArea.endDrag() + // Early return if mouse didn't move along x-axis + if (translationX === 0.0) + return + + var currentDragDirection = Math.sign(translationX) + + // Has drag direction changed + if (currentDragDirection !== mouseArea.dragDirection) { + mouseArea.translationX = 0.0 + mouseArea.dragDirection = currentDragDirection + mouseArea.totalUnits = mouseArea.units + } + + mouseArea.translationX += translationX + mouseArea.calcValue() + myControl.realValueModified() + } onClicked: function(mouse) { if (textInput.edit) mouse.accepted = false - if (mouseArea.wasDragging) { - mouseArea.wasDragging = false + if (mouseArea.hasDragged) { + mouseArea.hasDragged = false return } @@ -167,7 +195,7 @@ TextInput { mouse.accepted = false mouseArea.potentialDragStart = true - mouseArea.pressStartX = mouseArea.mouseX + mouseArea.pressStartX = mouse.x } onReleased: function(mouse) { @@ -182,11 +210,12 @@ TextInput { return mouseArea.dragging = false - mouseArea.wasDragging = true + mouseArea.hasDragged = true if (myControl.compressedValueTimer.running) { myControl.compressedValueTimer.stop() - mouseArea.calcValue(myControl.compressedRealValueModified) + mouseArea.calcValue() + myControl.compressedRealValueModified() } mouseArea.cursorShape = Qt.PointingHandCursor myControl.drag = false @@ -196,21 +225,21 @@ TextInput { textInput.focus = false myControl.focus = false - mouseArea.translationX = 0 + mouseArea.translationX = 0.0 + mouseArea.units = 0.0 + mouseArea.totalUnits = 0.0 } - function calcValue(callback) { - var minTranslation = (myControl.realFrom - mouseArea.initialValue) / mouseArea.stepSize - var maxTranslation = (myControl.realTo - mouseArea.initialValue) / mouseArea.stepSize + function calcValue() { + var minUnit = (myControl.realFrom - mouseArea.initialValue) / mouseArea.stepSize + var maxUnit = (myControl.realTo - mouseArea.initialValue) / mouseArea.stepSize - mouseArea.translationX = Math.min(Math.max(mouseArea.translationX, minTranslation), maxTranslation) - - myControl.setRealValue(mouseArea.initialValue + (mouseArea.translationX * mouseArea.stepSize)) + var units = Math.trunc(mouseArea.translationX / mouseArea.__pixelsPerUnit) + mouseArea.units = Math.min(Math.max(mouseArea.totalUnits + units, minUnit), maxUnit) + myControl.setRealValue(mouseArea.initialValue + (mouseArea.units * mouseArea.stepSize)) if (mouseArea.dragging) myControl.dragging() - - callback() } onWheel: function(wheel) { diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp index f72439c6748..bdfa8fb2026 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp @@ -541,6 +541,14 @@ void PropertyEditorContextObject::holdCursorInPlace() QCursor::setPos(w->screen(), m_lastPos); } +int PropertyEditorContextObject::devicePixelRatio() +{ + if (QWidget *w = QApplication::activeWindow()) + return w->devicePixelRatio(); + + return 1; +} + QStringList PropertyEditorContextObject::styleNamesForFamily(const QString &family) { const QFontDatabase dataBase; diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.h b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.h index 0fff1129357..262e9191ccb 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.h +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.h @@ -96,6 +96,8 @@ public: Q_INVOKABLE void restoreCursor(); Q_INVOKABLE void holdCursorInPlace(); + Q_INVOKABLE int devicePixelRatio(); + Q_INVOKABLE QStringList styleNamesForFamily(const QString &family); Q_INVOKABLE QStringList allStatesForId(const QString &id);