QmlDesigner: Fix SpinBox dragging

* Add PPU (pixels per unit) property
* Include device pixel ratio

Task-number: QDS-3081
Task-number: QDS-4798
Change-Id: I23cd26662d719888eca685e54d0706f5da09c4cd
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Henning Gruendl
2021-09-17 20:33:20 +02:00
committed by Henning Gründl
parent 72d932a44e
commit 64e48988ed
6 changed files with 79 additions and 29 deletions

View File

@@ -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()

View File

@@ -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()
}
}

View File

@@ -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

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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);