diff --git a/src/qml/Base/HSelectableLabel.qml b/src/qml/Base/HSelectableLabel.qml index f3c11502..0baf561f 100644 --- a/src/qml/Base/HSelectableLabel.qml +++ b/src/qml/Base/HSelectableLabel.qml @@ -131,6 +131,12 @@ TextEdit { } } + PointHandler { + onActiveChanged: + active ? container.dragStarted() : container.dragStopped() + onPointChanged: container.dragPointChanged(point) + } + MouseArea { anchors.fill: label acceptedButtons: Qt.NoButton diff --git a/src/qml/Base/HSelectableLabelContainer.qml b/src/qml/Base/HSelectableLabelContainer.qml index 37deec87..ae425efb 100644 --- a/src/qml/Base/HSelectableLabelContainer.qml +++ b/src/qml/Base/HSelectableLabelContainer.qml @@ -3,11 +3,13 @@ import "../utils.js" as Utils FocusScope { signal deselectAll() + signal dragStarted() + signal dragStopped() + signal dragPointChanged(var eventPoint) property bool reversed: false - readonly property bool dragging: pointHandler.active || dragHandler.active property bool selecting: false property real selectionStart: -1 property real selectionEnd: -1 @@ -36,8 +38,22 @@ FocusScope { return toCopy.join("").trim() } - readonly property alias dragPoint: dragHandler.centroid - readonly property alias dragPosition: dragHandler.centroid.position + + onDragStarted: { + draggedItem.Drag.active = true + } + onDragStopped: { + draggedItem.Drag.drop() + draggedItem.Drag.active = false + selecting = false + } + onDragPointChanged: { + let pos = mapFromItem( + mainUI, eventPoint.scenePosition.x, eventPoint.scenePosition.y, + ) + draggedItem.x = pos.x + draggedItem.y = pos.y + } function clearSelection() { @@ -50,28 +66,21 @@ FocusScope { } - Item { id: dragCursor } - - DragHandler { - id: dragHandler - target: dragCursor - onActiveChanged: { - if (active) { - target.Drag.active = true - } else { - target.Drag.drop() - target.Drag.active = false - selecting = false - } - } - } + // PointHandler and TapHandler won't activate if the press occurs inside + // a label child, so we need a Point/TapHandler inside them too. PointHandler { + // We don't use a DragHandler because they have an unchangable minimum + // drag distance before they activate. id: pointHandler + onActiveChanged: active ? dragStarted() : dragStopped() + onPointChanged: dragPointChanged(point) } TapHandler { acceptedButtons: Qt.LeftButton onTapped: clearSelection() } + + Item { id: draggedItem } } diff --git a/src/qml/Chat/Timeline/EventList.qml b/src/qml/Chat/Timeline/EventList.qml index 0e29e459..f6349ceb 100644 --- a/src/qml/Chat/Timeline/EventList.qml +++ b/src/qml/Chat/Timeline/EventList.qml @@ -13,23 +13,23 @@ Rectangle { anchors.fill: parent reversed: eventList.verticalLayoutDirection == ListView.BottomToTop - onDragPositionChanged: { - let left = dragPoint.pressedButtons & Qt.LeftButton - let vel = dragPoint.velocity.y + DragHandler { + target: null + onActiveChanged: if (! active) dragFlicker.speed = 0 + onCentroidChanged: { + let left = centroid.pressedButtons & Qt.LeftButton + let vel = centroid.velocity.y + let pos = centroid.position.y + let dist = Math.min(selectableLabelContainer.height / 4, 50) + let boost = 20 * (pos < dist ? -pos : -(height - pos)) - let boost = 20 * ( - dragPosition.y < 50 ? - -dragPosition.y : -(height - dragPosition.y) - ) - - dragFlicker.speed = - dragPosition.x == 0 && dragPosition.y == 0 ? 0 : - left && vel && dragPosition.y < 50 ? 1000 + boost: - left && vel && dragPosition.y > height - 50 ? -1000 + -boost : - 0 + dragFlicker.speed = + left && vel && pos < dist ? 1000 + boost : + left && vel && pos > height - dist ? -1000 + -boost : + 0 + } } - Timer { id: dragFlicker interval: 100