[vlc-commits] [Git][videolan/vlc][master] 14 commits: qt: introduce DoubleClickIgnoringItem

Steve Lhomme (@robUx4) gitlab at videolan.org
Tue Jul 2 04:53:30 UTC 2024



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
42b8d2cd by Fatih Uzunoglu at 2024-07-02T04:40:32+00:00
qt: introduce DoubleClickIgnoringItem

MOC is not necessary, we are not using
meta-object features in this file.

- - - - -
6847be9f by Fatih Uzunoglu at 2024-07-02T04:40:32+00:00
qt: register new type DoubleClickIgnoringItem

- - - - -
a45e30a4 by Fatih Uzunoglu at 2024-07-02T04:40:32+00:00
qml: get rid of the mouse area in MusicArtistDelegate

- - - - -
9054f043 by Fatih Uzunoglu at 2024-07-02T04:40:32+00:00
qml: use TapHandler instead of MouseArea in ControlBar

- - - - -
c10a33db by Fatih Uzunoglu at 2024-07-02T04:40:32+00:00
qml: use handlers instead of MouseArea in PlaylistDelegate

- - - - -
1900fd71 by Fatih Uzunoglu at 2024-07-02T04:40:32+00:00
qml: use handlers instead of MouseArea in TableViewDelegate

- - - - -
4e6707b1 by Fatih Uzunoglu at 2024-07-02T04:40:32+00:00
qml: use handlers instead of MouseArea in PlayCover

- - - - -
ac129671 by Fatih Uzunoglu at 2024-07-02T04:40:32+00:00
qml: use TapHandler instead of MouseArea for KeyNavigableTableView column

- - - - -
a3d71fbe by Fatih Uzunoglu at 2024-07-02T04:40:32+00:00
qml: use TapHandler instead of MouseArea in KeyNavigableListView

- - - - -
cbc63a0a by Fatih Uzunoglu at 2024-07-02T04:40:32+00:00
qml: use handlers instead of MouseArea in GridItem

- - - - -
acbbc2f3 by Fatih Uzunoglu at 2024-07-02T04:40:32+00:00
qml: set preventStealing in HorizontalResizeHandle

- - - - -
05b5e208 by Fatih Uzunoglu at 2024-07-02T04:40:32+00:00
qml: use TapHandler instead of MouseArea for ExpandGridView flickable

- - - - -
a261c7c5 by Fatih Uzunoglu at 2024-07-02T04:40:32+00:00
qml: use WheelHandler and TapHandler in PlaybackSpeedButton

- - - - -
14dfdfa0 by Fatih Uzunoglu at 2024-07-02T04:40:32+00:00
qml: adjust seek bar handler permissions and policy

- - - - -


18 changed files:

- modules/gui/qt/Makefile.am
- modules/gui/qt/maininterface/mainui.cpp
- modules/gui/qt/medialibrary/qml/MusicArtistDelegate.qml
- modules/gui/qt/meson.build
- modules/gui/qt/network/qml/NetworkThumbnailItem.qml
- modules/gui/qt/player/qml/ControlBar.qml
- modules/gui/qt/player/qml/SliderBar.qml
- modules/gui/qt/player/qml/controlbarcontrols/PlaybackSpeedButton.qml
- modules/gui/qt/playlist/qml/PlaylistDelegate.qml
- + modules/gui/qt/widgets/native/doubleclickignoringitem.hpp
- modules/gui/qt/widgets/qml/ExpandGridView.qml
- modules/gui/qt/widgets/qml/GridItem.qml
- modules/gui/qt/widgets/qml/HorizontalResizeHandle.qml
- modules/gui/qt/widgets/qml/KeyNavigableListView.qml
- modules/gui/qt/widgets/qml/KeyNavigableTableView.qml
- modules/gui/qt/widgets/qml/MediaCover.qml
- modules/gui/qt/widgets/qml/PlayCover.qml
- modules/gui/qt/widgets/qml/TableViewDelegate.qml


Changes:

=====================================
modules/gui/qt/Makefile.am
=====================================
@@ -339,7 +339,8 @@ libqt_plugin_la_SOURCES = \
 	widgets/native/qvlcframe.hpp \
 	widgets/native/roundimage.cpp widgets/native/roundimage.hpp widgets/native/roundimage_p.hpp \
 	widgets/native/searchlineedit.cpp widgets/native/searchlineedit.hpp \
-	widgets/native/viewblockingrectangle.cpp widgets/native/viewblockingrectangle.hpp
+	widgets/native/viewblockingrectangle.cpp widgets/native/viewblockingrectangle.hpp \
+	widgets/native/doubleclickignoringitem.hpp
 
 # Meta-object compilation
 


=====================================
modules/gui/qt/maininterface/mainui.cpp
=====================================
@@ -62,6 +62,13 @@
 #include "widgets/native/roundimage.hpp"
 #include "widgets/native/navigation_attached.hpp"
 #include "widgets/native/viewblockingrectangle.hpp"
+#if QT_VERSION < QT_VERSION_CHECK(6, 4, 0)
+#include "widgets/native/doubleclickignoringitem.hpp"
+#else
+// QQuickItem already ignores double click, starting
+// with Qt 6.4.0:
+#define DoubleClickIgnoringItem QQuickItem
+#endif
 
 #include "videosurface.hpp"
 #include "mainctx.hpp"
@@ -307,6 +314,8 @@ void MainUI::registerQMLTypes()
 
         qmlRegisterType<ListSelectionModel>( uri, versionMajor, versionMinor, "ListSelectionModel" );
 
+        qmlRegisterType<DoubleClickIgnoringItem>( uri, versionMajor, versionMinor, "DoubleClickIgnoringItem" );
+
         qmlProtectModule(uri, versionMajor);
     }
 


=====================================
modules/gui/qt/medialibrary/qml/MusicArtistDelegate.qml
=====================================
@@ -64,6 +64,8 @@ T.ItemDelegate {
     verticalPadding: VLCStyle.margin_xsmall
     horizontalPadding: VLCStyle.margin_normal
 
+    hoverEnabled: true
+
     Accessible.onPressAction: root.itemClicked()
 
     // Childs
@@ -77,62 +79,77 @@ T.ItemDelegate {
         enabled: root.enabled
     }
 
-    background: Widgets.AnimatedBackground {
-        enabled: theme.initialized
-        color: (root.isCurrent || root.selected) ? theme.bg.highlight : theme.bg.primary
-        border.color: visualFocus ? theme.visualFocus : "transparent"
+    // TODO: Qt bug 6.2: QTBUG-103604
+    DoubleClickIgnoringItem {
+        anchors.fill: parent
 
-        Widgets.CurrentIndicator {
-            anchors {
-                left: parent.left
-                leftMargin: VLCStyle.margin_xxxsmall
-                verticalCenter: parent.verticalCenter
+        TapHandler {
+            gesturePolicy: TapHandler.ReleaseWithinBounds // TODO: Qt 6.2 bug: Use TapHandler.DragThreshold
+
+            grabPermissions: TapHandler.CanTakeOverFromHandlersOfDifferentType | TapHandler.ApprovesTakeOverByAnything
+
+            // We need this for extra information such as modifiers
+            Component.onCompleted: {
+                canceled.connect(initialAction) // DragHandler stole the event
             }
 
-            implicitHeight: parent.height * 3 / 4
+            onSingleTapped: (eventPoint, button) => {
+                initialAction()
 
-            visible: isCurrent
+                if (!(root.selected && button === Qt.RightButton)) {
+                    view.selectionModel.updateSelection(point.modifiers, view.currentIndex, index)
+                    view.currentIndex = index
+                }
+            }
+
+            onDoubleTapped: (eventPoint, button) => {
+                if (button !== Qt.RightButton)
+                    MediaLib.addAndPlay(model.id);
+            }
+
+            function initialAction() {
+                root.forceActiveFocus(Qt.MouseFocusReason)
+            }
         }
-    }
 
-    MouseArea {
-        anchors.fill: parent
+        DragHandler {
+            target: null
 
-        drag.axis: Drag.XAndYAxis
-        drag.smoothed: false
+            grabPermissions: PointerHandler.CanTakeOverFromHandlersOfDifferentType | PointerHandler.ApprovesTakeOverByAnything
 
-        drag.target: root.dragTarget
+            onActiveChanged: {
+                const target = root.dragTarget
+                if (target) {
+                    if (active) {
+                        if (!selected) {
+                            view.selectionModel.select(index, ItemSelectionModel.ClearAndSelect)
+                            view.currentIndex = index
+                        }
 
-        drag.onActiveChanged: {
-            if (drag.target) {
-                const target = drag.target
-                if (drag.active) {
-                    if (!selected) {
-                        view.selectionModel.select(index, ItemSelectionModel.ClearAndSelect)
-                        view.currentIndex = index
+                        target.Drag.active = true
+                    } else {
+                        target.Drag.drop()
                     }
-
-                    target.Drag.active = true
-                } else {
-                    target.Drag.drop()
                 }
             }
         }
+    }
+
+    background: Widgets.AnimatedBackground {
+        enabled: theme.initialized
+        color: (root.isCurrent || root.selected) ? theme.bg.highlight : theme.bg.primary
+        border.color: visualFocus ? theme.visualFocus : "transparent"
 
-        onClicked: (mouse) => {
-            if (!(root.selected && mouse.button === Qt.RightButton)) {
-                view.selectionModel.updateSelection(mouse.modifiers, view.currentIndex, index)
-                view.currentIndex = index
+        Widgets.CurrentIndicator {
+            anchors {
+                left: parent.left
+                leftMargin: VLCStyle.margin_xxxsmall
+                verticalCenter: parent.verticalCenter
             }
-        }
 
-        onDoubleClicked: (mouse) => {
-            if (mouse.button !== Qt.RightButton)
-                MediaLib.addAndPlay(model.id);
-        }
+            implicitHeight: parent.height * 3 / 4
 
-        onPressed: (mouse) => {
-            root.forceActiveFocus(Qt.MouseFocusReason)
+            visible: isCurrent
         }
     }
 


=====================================
modules/gui/qt/meson.build
=====================================
@@ -497,6 +497,7 @@ some_sources = files(
     'widgets/native/searchlineedit.hpp',
     'widgets/native/viewblockingrectangle.cpp',
     'widgets/native/viewblockingrectangle.hpp',
+    'widgets/native/doubleclickignoringitem.hpp',
 )
 
 if host_system == 'windows'


=====================================
modules/gui/qt/network/qml/NetworkThumbnailItem.qml
=====================================
@@ -115,7 +115,7 @@ Widgets.TableRowDelegate {
 
                     visible: root._showPlayCover
 
-                    onClicked: playClicked(root.index)
+                    onTapped: playClicked(root.index)
                 }
             }
         }


=====================================
modules/gui/qt/player/qml/ControlBar.qml
=====================================
@@ -136,9 +136,10 @@ T.Pane {
                 anchors.right: (parent === pseudoRow) ? parent.right : undefined
                 anchors.verticalCenter: (parent === pseudoRow) ? parent.verticalCenter : undefined
 
-                MouseArea {
-                    anchors.fill: parent
-                    onClicked: MainCtx.showRemainingTime = !MainCtx.showRemainingTime
+                TapHandler {
+                    onTapped: (eventPoint, button) => {
+                        MainCtx.showRemainingTime = !MainCtx.showRemainingTime
+                    }
                 }
             },
             SliderBar {


=====================================
modules/gui/qt/player/qml/SliderBar.qml
=====================================
@@ -229,6 +229,10 @@ T.ProgressBar {
         TapHandler {
             acceptedButtons: Qt.LeftButton
 
+            grabPermissions: TapHandler.CanTakeOverFromAnything
+
+            gesturePolicy: TapHandler.WithinBounds
+
             //clicked but not dragged
             onTapped: (point, button) => {
                 fsm.pressControl(point.position.x / control.width, point.modifiers === Qt.ShiftModifier)
@@ -242,6 +246,7 @@ T.ProgressBar {
 
             target: null
             dragThreshold: 0
+            grabPermissions: PointerHandler.CanTakeOverFromAnything
 
             function moveControl() {
                 fsm.moveControl(dragHandler.centroid.position.x / control.width,


=====================================
modules/gui/qt/player/qml/controlbarcontrols/PlaybackSpeedButton.qml
=====================================
@@ -55,54 +55,56 @@ PopupIconToolButton {
         color: root.color
     }
 
-    // TODO: Qt 5.15 Use WheelHandler & TapHandler
-    MouseArea {
+    // TODO: Qt bug 6.2: QTBUG-103604
+    DoubleClickIgnoringItem {
         anchors.fill: parent
 
-        acceptedButtons: Qt.RightButton
+        z: -1
 
-        onWheel: function(wheel) {
-            if (!root.popup.contentItem || !root.popup.contentItem.slider) {
-                wheel.accepted = false
-                return
-            }
+        WheelHandler {
+            onWheel: (event) => {
+                if (!root.popup.contentItem || !root.popup.contentItem.slider) {
+                    event.accepted = false
+                    return
+                }
 
-            let delta = 0
+                let delta = 0
 
-            if (wheel.angleDelta.x)
-                delta = wheel.angleDelta.x
-            else if (wheel.angleDelta.y)
-                delta = wheel.angleDelta.y
-            else {
-                wheel.accepted = false
-                return
-            }
+                if (event.angleDelta.x)
+                    delta = event.angleDelta.x
+                else if (event.angleDelta.y)
+                    delta = event.angleDelta.y
+                else {
+                    event.accepted = false
+                    return
+                }
 
-            if (wheel.inverted)
-                delta = -delta
+                if (event.inverted)
+                    delta = -delta
 
-            wheel.accepted = true
+                event.accepted = true
 
-            delta = delta / 8 / 15
+                delta = delta / 8 / 15
 
-            let func
-            if (delta > 0)
-                func = root.popup.contentItem.slider.increase
-            else
-                func = root.popup.contentItem.slider.decrease
+                let func
+                if (delta > 0)
+                    func = root.popup.contentItem.slider.increase
+                else
+                    func = root.popup.contentItem.slider.decrease
 
-            for (let i = 0; i < Math.ceil(Math.abs(delta)); ++i)
-                func()
+                for (let i = 0; i < Math.ceil(Math.abs(delta)); ++i)
+                    func()
+            }
         }
 
-        onClicked: function(mouse) {
-            if (!root.popup.contentItem || !root.popup.contentItem.slider) {
-                mouse.accepted = false
-                return
-            }
+        TapHandler {
+            acceptedButtons: Qt.RightButton
+
+            enabled: root.popup.contentItem && root.popup.contentItem.slider
 
-            mouse.accepted = true
-            root.popup.contentItem.slider.value = 0
+            onTapped: (eventPoint, button) => {
+                root.popup.contentItem.slider.value = 0
+            }
         }
     }
 }


=====================================
modules/gui/qt/playlist/qml/PlaylistDelegate.qml
=====================================
@@ -27,7 +27,7 @@ import org.videolan.vlc 0.1
 import "qrc:///widgets/" as Widgets
 import "qrc:///style/"
 
-T.ItemDelegate {
+T.Control {
     id: delegate
 
     // Properties
@@ -68,6 +68,8 @@ T.ItemDelegate {
 
     // Settings
 
+    hoverEnabled: true
+
     verticalPadding: VLCStyle.playlistDelegate_verticalPadding
 
     leftPadding: VLCStyle.margin_normal
@@ -79,7 +81,7 @@ T.ItemDelegate {
     implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
                              implicitContentHeight + topPadding + bottomPadding)
 
-    ListView.delayRemove: mouseArea.drag.active
+    ListView.delayRemove: dragHandler.active
 
     T.ToolTip.visible: ( visible && (visualFocus || hovered) &&
                          (textInfoColumn.implicitWidth > textInfoColumn.width) )
@@ -236,60 +238,76 @@ T.ItemDelegate {
         }
     }
 
-    MouseArea {
-        id: mouseArea
-
+    // TODO: Qt bug 6.2: QTBUG-103604
+    DoubleClickIgnoringItem {
         anchors.fill: parent
 
-        hoverEnabled: true
+        TapHandler {
+            acceptedDevices: PointerDevice.AllDevices & ~(PointerDevice.TouchScreen)
+
+            acceptedButtons: Qt.LeftButton | Qt.RightButton
+
+            gesturePolicy: TapHandler.ReleaseWithinBounds // TODO: Qt 6.2 bug: Use TapHandler.DragThreshold
 
-        acceptedButtons: Qt.LeftButton | Qt.RightButton
+            grabPermissions: TapHandler.CanTakeOverFromHandlersOfDifferentType | TapHandler.ApprovesTakeOverByAnything
 
-        onClicked: (mouse) => {
-            /* to receive keys events */
-            if (!(delegate.selected && mouse.button === Qt.RightButton)) {
-                view.selectionModel.updateSelection(mouse.modifiers, view.currentIndex, index)
-                view.currentIndex = index
+            onSingleTapped: (eventPoint, button) => {
+                initialAction()
+
+                if (!(delegate.selected && button === Qt.RightButton)) {
+                    view.selectionModel.updateSelection(point.modifiers, view.currentIndex, index)
+                    view.currentIndex = index
+                }
+
+                if (contextMenu && button === Qt.RightButton)
+                    contextMenu.popup(index, parent.mapToGlobal(eventPoint.position.x, eventPoint.position.y))
             }
 
-            if (contextMenu && mouse.button === Qt.RightButton)
-                contextMenu.popup(index, mapToGlobal(mouse.x, mouse.y))
-        }
+            onDoubleTapped: (eventPoint, button) => {
+                if (button !== Qt.RightButton)
+                    MainPlaylistController.goTo(index, true)
+            }
 
-        onDoubleClicked: (mouse) => {
-            if (mouse.button !== Qt.RightButton)
-                MainPlaylistController.goTo(index, true)
-        }
+            Component.onCompleted: {
+                canceled.connect(initialAction)
+            }
 
-        onPressed: (mouse) => {
-            delegate.forceActiveFocus(Qt.MouseFocusReason)
+            function initialAction() {
+                delegate.forceActiveFocus(Qt.MouseFocusReason)
+            }
         }
 
-        drag.target: dragItem
+        DragHandler {
+            id: dragHandler
 
-        drag.smoothed: false
+            target: null
 
-        drag.onActiveChanged: {
-            if (dragItem) {
-                if (drag.active) {
-                    if (!selected) {
-                        /* the dragged item is not in the selection, replace the selection */
-                        view.selectionModel.select(index, ItemSelectionModel.ClearAndSelect)
-                    }
+            grabPermissions: PointerHandler.CanTakeOverFromHandlersOfDifferentType | PointerHandler.ApprovesTakeOverByAnything
 
-                    dragItem.indexes = view.selectionModel.selectedIndexesFlat
-                    dragItem.indexesFlat = true
-                    dragItem.Drag.active = true
-                } else {
-                    dragItem.Drag.drop()
+            onActiveChanged: {
+                if (dragItem) {
+                    if (active) {
+                        if (!selected) {
+                            /* the dragged item is not in the selection, replace the selection */
+                            view.selectionModel.select(index, ItemSelectionModel.ClearAndSelect)
+                        }
+
+                        dragItem.indexes = view.selectionModel.selectedIndexesFlat
+                        dragItem.indexesFlat = true
+                        dragItem.Drag.active = true
+                    } else {
+                        dragItem.Drag.drop()
+                    }
                 }
             }
         }
 
         TapHandler {
             acceptedDevices: PointerDevice.TouchScreen
-            
-            onTapped: {
+
+            grabPermissions: TapHandler.CanTakeOverFromHandlersOfDifferentType | TapHandler.ApprovesTakeOverByAnything
+
+            onTapped: (eventPoint, button) => {
                 MainPlaylistController.goTo(index, true)
             }
 


=====================================
modules/gui/qt/widgets/native/doubleclickignoringitem.hpp
=====================================
@@ -0,0 +1,39 @@
+/*****************************************************************************
+ * Copyright (C) 2024 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * ( at your option ) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+#ifndef DOUBLECLICKIGNORINGITEM_HPP
+#define DOUBLECLICKIGNORINGITEM_HPP
+
+#include <QQuickItem>
+
+// TODO: Remove Qt >= 6.4
+//       413522: QQuickItem: ignore double-clicks by default; remove allowDoubleClick
+class DoubleClickIgnoringItem : public QQuickItem
+{
+    // Q_OBJECT
+
+public:
+    DoubleClickIgnoringItem(QQuickItem *parent = nullptr) : QQuickItem(parent) { }
+
+protected:
+    void mouseDoubleClickEvent(QMouseEvent *ev) override
+    {
+        ev->ignore();
+    }
+};
+
+#endif // DOUBLECLICKIGNORINGITEM_HPP


=====================================
modules/gui/qt/widgets/qml/ExpandGridView.qml
=====================================
@@ -735,25 +735,33 @@ FocusScope {
             id: flickableScrollBar
         }
 
-        MouseArea {
-            anchors.fill: parent
-            z: -1
+        TapHandler {
+            acceptedDevices: PointerDevice.Mouse
 
-            preventStealing: true
             acceptedButtons: Qt.LeftButton | Qt.RightButton
 
-            onPressed: (mouse) => {
-                Helpers.enforceFocus(flickable, Qt.MouseFocusReason)
+            grabPermissions: PointerHandler.TakeOverForbidden
+
+            gesturePolicy: TapHandler.ReleaseWithinBounds
 
-                if (!(mouse.modifiers & (Qt.ShiftModifier | Qt.ControlModifier))) {
-                    if (selectionModel)
-                        selectionModel.clearSelection()
+            onTapped: (eventPoint, button) => {
+                initialAction()
+
+                if (button === Qt.RightButton) {
+                    root.showContextMenu(parent.mapToGlobal(eventPoint.position.x, eventPoint.position.y))
                 }
             }
 
-            onReleased: (mouse) => {
-                if (mouse.button & Qt.RightButton) {
-                    root.showContextMenu(mapToGlobal(mouse.x, mouse.y))
+            Component.onCompleted: {
+                canceled.connect(initialAction)
+            }
+
+            function initialAction() {
+                Helpers.enforceFocus(flickable, Qt.MouseFocusReason)
+
+                if (!(point.modifiers & (Qt.ShiftModifier | Qt.ControlModifier))) {
+                    if (root.selectionModel)
+                        root.selectionModel.clearSelection()
                 }
             }
         }


=====================================
modules/gui/qt/widgets/qml/GridItem.qml
=====================================
@@ -78,7 +78,7 @@ T.ItemDelegate {
     implicitWidth: layout.implicitWidth
     implicitHeight: layout.implicitHeight
 
-    highlighted: (mouseHoverHandler.hovered || visualFocus)
+    highlighted: (hovered || visualFocus)
 
     Accessible.role: Accessible.Cell
     Accessible.name: title
@@ -162,187 +162,206 @@ T.ItemDelegate {
         hovered: root.hovered
     }
 
-    background: AnimatedBackground {
-        width: root.width + (selectedBorderWidth * 2)
-        height: root.height + (selectedBorderWidth * 2)
+    // TODO: Qt bug 6.2: QTBUG-103604
+    DoubleClickIgnoringItem {
+        anchors.fill: parent
 
-        x: - selectedBorderWidth
-        y: - selectedBorderWidth
+        DragHandler {
+            id: dragHandler
 
-        enabled: theme.initialized
+            target: null
 
-        //don't show the backgroud unless selected
-        color: root.selected ?  theme.bg.highlight : theme.bg.primary
-        border.color: visualFocus ? theme.visualFocus : "transparent"
-    }
+            grabPermissions: PointerHandler.CanTakeOverFromHandlersOfDifferentType | PointerHandler.ApprovesTakeOverByAnything
 
-    contentItem: MouseArea {
-        implicitWidth: layout.implicitWidth
-        implicitHeight: layout.implicitHeight
+            onActiveChanged: {
+                if (dragItem) {
+                    if (active && !selected) {
+                        root.itemClicked(root._modifiersOnLastPress)
+                    }
 
-        acceptedButtons: Qt.RightButton | Qt.LeftButton
+                    if (active)
+                        dragItem.Drag.active = true
+                    else
+                        dragItem.Drag.drop()
+                }
+            }
+        }
 
-        drag.target: root.dragItem
+        TapHandler {
+            acceptedDevices: PointerDevice.AllDevices & ~(PointerDevice.TouchScreen)
 
-        drag.axis: Drag.XAndYAxis
+            acceptedButtons: Qt.RightButton | Qt.LeftButton
 
-        drag.smoothed: false
+            grabPermissions: TapHandler.CanTakeOverFromHandlersOfDifferentType | TapHandler.ApprovesTakeOverByAnything
 
-        onClicked: (mouse) => {
-            if (mouse.button === Qt.RightButton)
-                contextMenuButtonClicked(picture, root.mapToGlobal(mouse.x,mouse.y));
-            else if (mouse.button === Qt.LeftButton) {
-                root.itemClicked(mouse.modifiers);
+            gesturePolicy: TapHandler.ReleaseWithinBounds // TODO: Qt 6.2 bug: Use TapHandler.DragThreshold
+
+            onSingleTapped: (eventPoint, button) => {
+                initialAction()
+
+                // FIXME: The signals are messed up in this item.
+                //        Right click does not fire itemClicked?
+                if (button === Qt.RightButton)
+                    contextMenuButtonClicked(picture, parent.mapToGlobal(eventPoint.position.x, eventPoint.position.y));
+                else
+                    root.itemClicked(point.modifiers);
             }
-        }
 
-        onDoubleClicked: (mouse) => {
-            if (mouse.button === Qt.LeftButton)
-                root.itemDoubleClicked(mouse.modifiers)
-        }
+            onDoubleTapped: (eventPoint, button) => {
+                if (button === Qt.LeftButton)
+                    root.itemDoubleClicked(point.modifiers)
+            }
 
-        onPressed: (mouse) => {
-            _modifiersOnLastPress = mouse.modifiers
-        }
+            Component.onCompleted: {
+                canceled.connect(initialAction)
+            }
 
-        drag.onActiveChanged: {
-            // perform the "click" action because the click action is only executed on mouse release (we are in the pressed state)
-            // but we will need the updated list on drop
-            if (drag.active && !selected) {
-                root.itemClicked(root._modifiersOnLastPress)
-            } else if (root.dragItem) {
-                root.dragItem.Drag.drop()
+            function initialAction() {
+                _modifiersOnLastPress = point.modifiers
+
+                root.forceActiveFocus(Qt.MouseFocusReason)
             }
-            root.dragItem.Drag.active = drag.active
         }
 
         TapHandler {
             acceptedDevices: PointerDevice.TouchScreen
 
+            grabPermissions: TapHandler.CanTakeOverFromHandlersOfDifferentType | TapHandler.ApprovesTakeOverByAnything
+
             onTapped: (eventPoint, button) => {
                 root.itemClicked(Qt.NoModifier)
                 root.itemDoubleClicked(Qt.NoModifier)
             }
 
             onLongPressed: {
-                contextMenuButtonClicked(picture, point.scenePosition);
+                contextMenuButtonClicked(picture, parent.mapToGlobal(point.position.x, point.position.y));
             }
         }
+    }
 
-        HoverHandler {
-            id: mouseHoverHandler
-            acceptedDevices: PointerDevice.Mouse
-        }
-
-        ColumnLayout {
-            id: layout
+    background: AnimatedBackground {
+        width: root.width + (selectedBorderWidth * 2)
+        height: root.height + (selectedBorderWidth * 2)
 
-            anchors.top: parent.top
-            anchors.horizontalCenter: parent.horizontalCenter
-            spacing: 0
+        x: - selectedBorderWidth
+        y: - selectedBorderWidth
 
-            Widgets.MediaCover {
-                id: picture
+        enabled: theme.initialized
 
-                playCoverVisible: false
-                playCoverOpacity: 0
-                radius: VLCStyle.gridCover_radius
-                color: theme.bg.secondary
+        //don't show the backgroud unless selected
+        color: root.selected ?  theme.bg.highlight : theme.bg.primary
+        border.color: visualFocus ? theme.visualFocus : "transparent"
+    }
 
-                Layout.preferredWidth: pictureWidth
-                Layout.preferredHeight: pictureHeight
+    contentItem: ColumnLayout {
+        id: layout
 
-                onPlayIconClicked: (mouse) => {
-                    // emulate a mouse click before delivering the play signal as to select the item
-                    // this helps in updating the selection and restore of initial index in the parent views
-                    root.itemClicked(mouse.modifiers)
-                    root.playClicked()
-                }
+        z: 1
 
-                DefaultShadow {
-                    id: unselectedShadow
+        spacing: 0
 
-                    anchors.centerIn: parent
+        Widgets.MediaCover {
+            id: picture
 
-                    visible: opacity > 0
+            playCoverVisible: false
+            playCoverOpacity: 0
+            radius: VLCStyle.gridCover_radius
+            color: theme.bg.secondary
 
-                    sourceItem: parent
+            Layout.preferredWidth: pictureWidth
+            Layout.preferredHeight: pictureHeight
+            Layout.alignment: Qt.AlignCenter
 
-                    width: viewportWidth
-                    height: viewportHeight
-                    sourceSize: Qt.size(128, 128)
-                }
+            onPlayIconClicked: (point) => {
+                // emulate a mouse click before delivering the play signal as to select the item
+                // this helps in updating the selection and restore of initial index in the parent views
+                root.itemClicked(point.modifiers)
+                root.playClicked()
+            }
 
-                DoubleShadow {
-                    id: selectedShadow
+            DefaultShadow {
+                id: unselectedShadow
 
-                    anchors.centerIn: parent
+                anchors.centerIn: parent
 
-                    visible: opacity > 0
-                    opacity: 0
+                visible: opacity > 0
 
-                    sourceItem: parent
+                sourceItem: parent
 
-                    width: viewportWidth
-                    height: viewportHeight
+                width: viewportWidth
+                height: viewportHeight
+                sourceSize: Qt.size(128, 128)
+            }
 
-                    sourceSize: Qt.size(128, 128)
+            DoubleShadow {
+                id: selectedShadow
 
-                    primaryVerticalOffset: VLCStyle.dp(6, VLCStyle.scale)
-                    primaryBlurRadius: VLCStyle.dp(18, VLCStyle.scale)
+                anchors.centerIn: parent
 
-                    secondaryVerticalOffset: VLCStyle.dp(32, VLCStyle.scale)
-                    secondaryBlurRadius: VLCStyle.dp(72, VLCStyle.scale)
-                }
-            }
+                visible: opacity > 0
+                opacity: 0
 
-            Widgets.TextAutoScroller {
-                id: titleTextRect
+                sourceItem: parent
 
-                label: titleLabel
-                forceScroll: highlighted
-                visible: root.title !== ""
-                clip: scrolling
+                width: viewportWidth
+                height: viewportHeight
 
-                Layout.preferredWidth: Math.min(titleLabel.implicitWidth, pictureWidth)
-                Layout.preferredHeight: titleLabel.height
-                Layout.topMargin: root.titleMargin
-                Layout.alignment: root.textAlignHCenter ? Qt.AlignCenter : Qt.AlignLeft
+                sourceSize: Qt.size(128, 128)
 
-                Widgets.ListLabel {
-                    id: titleLabel
+                primaryVerticalOffset: VLCStyle.dp(6, VLCStyle.scale)
+                primaryBlurRadius: VLCStyle.dp(18, VLCStyle.scale)
 
-                    height: implicitHeight
-                    color: root.selected
-                        ? theme.fg.highlight
-                        : theme.fg.primary
-                    textFormat: Text.PlainText
-                }
+                secondaryVerticalOffset: VLCStyle.dp(32, VLCStyle.scale)
+                secondaryBlurRadius: VLCStyle.dp(72, VLCStyle.scale)
             }
+        }
+
+        Widgets.TextAutoScroller {
+            id: titleTextRect
+
+            label: titleLabel
+            forceScroll: highlighted
+            visible: root.title !== ""
+            clip: scrolling
 
-            Widgets.MenuCaption {
-                id: subtitleTxt
+            Layout.preferredWidth: Math.min(titleLabel.implicitWidth, pictureWidth)
+            Layout.preferredHeight: titleLabel.height
+            Layout.topMargin: root.titleMargin
+            Layout.alignment: root.textAlignHCenter ? Qt.AlignCenter : Qt.AlignLeft
 
-                visible: text !== ""
-                text: root.subtitle
-                elide: Text.ElideRight
+            Widgets.ListLabel {
+                id: titleLabel
+
+                height: implicitHeight
                 color: root.selected
                     ? theme.fg.highlight
-                    : theme.fg.secondary
+                    : theme.fg.primary
                 textFormat: Text.PlainText
+            }
+        }
 
-                Layout.preferredWidth: Math.min(pictureWidth, implicitWidth)
-                Layout.alignment: root.textAlignHCenter ? Qt.AlignCenter : Qt.AlignLeft
-                Layout.topMargin: VLCStyle.margin_xsmall
+        Widgets.MenuCaption {
+            id: subtitleTxt
 
-                ToolTip.delay: VLCStyle.delayToolTipAppear
-                ToolTip.text: subtitleTxt.text
-                ToolTip.visible: subtitleTxtMouseHandler.hovered
+            visible: text !== ""
+            text: root.subtitle
+            elide: Text.ElideRight
+            color: root.selected
+                ? theme.fg.highlight
+                : theme.fg.secondary
+            textFormat: Text.PlainText
 
-                HoverHandler {
-                    id: subtitleTxtMouseHandler
-                    acceptedDevices: PointerDevice.Mouse
-                }
+            Layout.preferredWidth: Math.min(pictureWidth, implicitWidth)
+            Layout.alignment: root.textAlignHCenter ? Qt.AlignCenter : Qt.AlignLeft
+            Layout.topMargin: VLCStyle.margin_xsmall
+
+            ToolTip.delay: VLCStyle.delayToolTipAppear
+            ToolTip.text: subtitleTxt.text
+            ToolTip.visible: subtitleTxtMouseHandler.hovered
+
+            HoverHandler {
+                id: subtitleTxtMouseHandler
+                acceptedDevices: PointerDevice.Mouse
             }
         }
     }


=====================================
modules/gui/qt/widgets/qml/HorizontalResizeHandle.qml
=====================================
@@ -41,6 +41,7 @@ MouseArea {
     cursorShape: Qt.SplitHCursor
     width: VLCStyle.resizeHandleWidth
     acceptedButtons: Qt.LeftButton
+    preventStealing: true
 
     onPressed: (mouse) => {
         MainCtx.setCursor(cursorShape)


=====================================
modules/gui/qt/widgets/qml/KeyNavigableListView.qml
=====================================
@@ -298,30 +298,35 @@ ListView {
         }
     }
 
-    MouseArea {
-        anchors.fill: parent
+    TapHandler {
+        acceptedDevices: PointerDevice.Mouse
 
-        z: -1
+        acceptedButtons: Qt.LeftButton | Qt.RightButton
 
-        preventStealing: true
+        grabPermissions: PointerHandler.TakeOverForbidden
 
-        acceptedButtons: Qt.LeftButton | Qt.RightButton
+        gesturePolicy: TapHandler.ReleaseWithinBounds
 
-        onPressed: (mouse) => {
-            focus = true // Grab the focus from delegate
-            root.forceActiveFocus(Qt.MouseFocusReason) // Re-focus the list
+        onTapped: (eventPoint, button) => {
+            initialAction()
 
-            if (!(mouse.modifiers & (Qt.ShiftModifier | Qt.ControlModifier))) {
-                if (selectionModel)
-                    selectionModel.clearSelection()
+            if (button === Qt.RightButton) {
+                root.showContextMenu(parent.mapToGlobal(eventPoint.position.x, eventPoint.position.y))
             }
+        }
 
-            mouse.accepted = true
+        Component.onCompleted: {
+            canceled.connect(initialAction)
         }
 
-        onReleased: (mouse) => {
-            if (mouse.button & Qt.RightButton) {
-                root.showContextMenu(mapToGlobal(mouse.x, mouse.y))
+        function initialAction() {
+            if (root.currentItem)
+                root.currentItem.focus = false // Grab the focus from delegate
+            root.forceActiveFocus(Qt.MouseFocusReason) // Re-focus the list
+
+            if (!(point.modifiers & (Qt.ShiftModifier | Qt.ControlModifier))) {
+                if (selectionModel)
+                    selectionModel.clearSelection()
             }
         }
     }


=====================================
modules/gui/qt/widgets/qml/KeyNavigableTableView.qml
=====================================
@@ -301,7 +301,7 @@ FocusScope {
 
                     Repeater {
                         model: sortModel
-                        MouseArea {
+                        Item {
                             id: headerCell
 
                             required property var modelData
@@ -338,13 +338,16 @@ FocusScope {
                                     rightMargin: VLCStyle.margin_xsmall
                                 }
                             }
-                            onClicked: {
-                                if (!(modelData.model.isSortable ?? true))
-                                    return
-                                else if (root.model.sortCriteria !== modelData.model.criteria)
-                                    root.model.sortCriteria = modelData.model.criteria
-                                else
-                                    root.model.sortOrder = (root.model.sortOrder === Qt.AscendingOrder) ? Qt.DescendingOrder : Qt.AscendingOrder
+
+                            TapHandler {
+                                onTapped: (eventPoint, button) => {
+                                    if (!(modelData.model.isSortable ?? true))
+                                        return
+                                    else if (root.model.sortCriteria !== modelData.model.criteria)
+                                        root.model.sortCriteria = modelData.model.criteria
+                                    else
+                                        root.model.sortOrder = (root.model.sortOrder === Qt.AscendingOrder) ? Qt.DescendingOrder : Qt.AscendingOrder
+                                }
                             }
                         }
                     }


=====================================
modules/gui/qt/widgets/qml/MediaCover.qml
=====================================
@@ -57,7 +57,7 @@ Rectangle {
 
     // Signals
 
-    signal playIconClicked(var /* MouseEvent */ mouse)
+    signal playIconClicked(var point)
 
     // Settings
 
@@ -113,7 +113,9 @@ Rectangle {
         sourceComponent: Widgets.PlayCover {
             width: playIconSize
 
-            onClicked: (mouse) => playIconClicked(mouse)
+            Component.onCompleted: {
+                tapped.connect(root.playIconClicked)
+            }
         }
 
         asynchronous: true


=====================================
modules/gui/qt/widgets/qml/PlayCover.qml
=====================================
@@ -19,13 +19,14 @@
  *****************************************************************************/
 
 import QtQuick
-import QtQuick.Controls
 
 import org.videolan.vlc 0.1
 import "qrc:///style/"
 import "qrc:///widgets/" as Widgets
 
-MouseArea {
+Item {
+    id: root
+
     // Settings
 
     width: VLCStyle.play_cover_normal
@@ -33,11 +34,13 @@ MouseArea {
 
     // NOTE: This is the same scaling than the PlayButton, except we make it bigger.
     //       Maybe we could crank this to 1.1.
-    scale: (containsMouse && pressed === false) ? 1.05 : 1.0
+    scale: (hoverHandler.hovered && !tapHandler.pressed) ? 1.05 : 1.0
 
     opacity: (visible) ? 1.0 : 0.0
 
-    hoverEnabled: true
+    activeFocusOnTab: false
+
+    signal tapped(var point)
 
     readonly property ColorContext colorContext: ColorContext {
         id: theme
@@ -48,7 +51,7 @@ MouseArea {
 
     Behavior on scale {
         // NOTE: We disable the animation while pressing to make it more impactful.
-        enabled: (pressed === false)
+        enabled: (!tapHandler.pressed)
 
         NumberAnimation {
             duration: VLCStyle.duration_short
@@ -67,6 +70,22 @@ MouseArea {
 
     // Children
 
+    TapHandler {
+        id: tapHandler
+
+        grabPermissions: TapHandler.CanTakeOverFromHandlersOfDifferentType | TapHandler.ApprovesTakeOverByAnything
+
+        onSingleTapped: (eventPoint, button) => {
+            root.tapped(point)
+        }
+    }
+
+    HoverHandler {
+        id: hoverHandler
+
+        grabPermissions: PointerHandler.CanTakeOverFromHandlersOfDifferentType | PointerHandler.ApprovesTakeOverByAnything
+    }
+
     ScaledImage {
         anchors.centerIn: parent
 
@@ -92,8 +111,7 @@ MouseArea {
 
         text: VLCIcons.play_filled
 
-        color: (containsMouse) ? theme.accent
-                               : "black"
+        color: (root.hovered) ? theme.accent : "black"
 
         font.pixelSize: Math.round(parent.width / 2)
     }


=====================================
modules/gui/qt/widgets/qml/TableViewDelegate.qml
=====================================
@@ -36,7 +36,7 @@ T.Control {
     required property Widgets.DragItem dragItem
     required property bool acceptDrop
 
-    readonly property bool dragActive: hoverArea.drag.active
+    readonly property bool dragActive: dragHandler.active
 
     property int _modifiersOnLastPress: Qt.NoModifier
 
@@ -93,76 +93,85 @@ T.Control {
         hovered: delegate.hovered
     }
 
-    background: AnimatedBackground {
-        animationDuration: VLCStyle.duration_short
-        enabled: theme.initialized
-        color: delegate.selected ? theme.bg.highlight : theme.bg.primary
-        border.color: visualFocus ? theme.visualFocus : "transparent"
-
-        MouseArea {
-            id: hoverArea
+    // TODO: Qt bug 6.2: QTBUG-103604
+    DoubleClickIgnoringItem {
+        anchors.fill: parent
 
-            // Settings
+        z: -1
 
-            anchors.fill: parent
+        DragHandler {
+            id: dragHandler
 
-            hoverEnabled: false
+            target: null
 
-            acceptedButtons: Qt.RightButton | Qt.LeftButton
+            grabPermissions: PointerHandler.CanTakeOverFromHandlersOfDifferentType | PointerHandler.ApprovesTakeOverByAnything
 
-            drag.target: delegate.dragItem
+            onActiveChanged: {
+                if (dragItem) {
+                    if (active) {
+                        dragItem.Drag.active = true
+                    } else {
+                        dragItem.Drag.drop()
+                    }
+                }
+            }
+        }
 
-            drag.axis: Drag.XAndYAxis
+        TapHandler {
+            acceptedDevices: PointerDevice.AllDevices & ~(PointerDevice.TouchScreen)
 
-            drag.smoothed: false
+            acceptedButtons: Qt.LeftButton | Qt.RightButton
 
-            // Events
+            gesturePolicy: TapHandler.ReleaseWithinBounds // TODO: Qt 6.2 bug: Use TapHandler.DragThreshold
 
-            onPressed: (mouse) => {
-                _modifiersOnLastPress = mouse.modifiers
-            }
+            grabPermissions: TapHandler.CanTakeOverFromHandlersOfDifferentType | TapHandler.ApprovesTakeOverByAnything
 
-            onClicked: (mouse) => {
-                if ((mouse.button === Qt.LeftButton) || !delegate.selected) {
-                    delegate.selectAndFocus(mouse.modifiers, Qt.MouseFocusReason)
-                }
+            onSingleTapped: (point, button) => {
+                initialAction()
 
-                if (mouse.button === Qt.RightButton)
-                    delegate.rightClick(delegate, delegate.rowModel, hoverArea.mapToGlobal(mouse.x, mouse.y))
+                if (button === Qt.RightButton)
+                    delegate.rightClick(delegate, delegate.rowModel, parent.mapToGlobal(point.position.x, point.position.y))
             }
 
-            onDoubleClicked: (mouse) => {
-                if (mouse.button === Qt.LeftButton)
+            onDoubleTapped: (point, button) => {
+                if (button === Qt.LeftButton)
                     delegate.itemDoubleClicked(delegate.index, delegate.rowModel)
             }
 
-            drag.onActiveChanged: {
-                // NOTE: Perform the "click" action because the click action is only executed on mouse
-                //       release (we are in the pressed state) but we will need the updated list on drop.
-                if (drag.active && !delegate.selected) {
-                    delegate.selectAndFocus(_modifiersOnLastPress, index)
-                } else if (delegate.dragItem) {
-                    delegate.dragItem.Drag.drop()
-                }
+            Component.onCompleted: {
+                canceled.connect(initialAction)
+            }
 
-                delegate.dragItem.Drag.active = drag.active
+            function initialAction() {
+                if ((point.pressedButtons === Qt.LeftButton) || !delegate.selected) {
+                    delegate.selectAndFocus(point.modifiers, Qt.MouseFocusReason)
+                }
             }
+        }
 
-            TapHandler {
-                acceptedDevices: PointerDevice.TouchScreen
+        TapHandler {
+            acceptedDevices: PointerDevice.TouchScreen
 
-                onTapped: {
-                    delegate.selectAndFocus(Qt.NoModifier, Qt.MouseFocusReason)
-                    delegate.itemDoubleClicked(delegate.index, delegate.rowModel)
-                }
+            grabPermissions: TapHandler.CanTakeOverFromHandlersOfDifferentType | TapHandler.ApprovesTakeOverByAnything
 
-                onLongPressed: {
-                    delegate.rightClick(delegate, delegate.rowModel, point.scenePosition)
-                }
+            onTapped: (eventPoint, button) => {
+                delegate.selectAndFocus(Qt.NoModifier, Qt.MouseFocusReason)
+                delegate.itemDoubleClicked(delegate.index, delegate.rowModel)
+            }
+
+            onLongPressed: {
+                delegate.rightClick(delegate, delegate.rowModel, parent.mapToGlobal(point.position.x, point.position.y))
             }
         }
     }
 
+    background: AnimatedBackground {
+        animationDuration: VLCStyle.duration_short
+        enabled: theme.initialized
+        color: delegate.selected ? theme.bg.highlight : theme.bg.primary
+        border.color: visualFocus ? theme.visualFocus : "transparent"
+    }
+
     contentItem: Row {
         leftPadding: VLCStyle.margin_xxxsmall
         rightPadding: VLCStyle.margin_xxxsmall
@@ -190,7 +199,7 @@ T.Control {
                             index: Qt.binding(() => delegate.index),
                             currentlyFocused: Qt.binding(() => delegate.visualFocus),
                             selected: Qt.binding(() => delegate.selected),
-                            containsMouse: Qt.binding(() => hoverArea.containsMouse),
+                            containsMouse: Qt.binding(() => delegate.hovered),
                             colorContext: Qt.binding(() => theme),
                         }
                     )



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/e51fdd5c36e94afea6e571811514c2ef916d9abd...14dfdfa01e5bff7814c31867eb8f59261d69d38b

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/e51fdd5c36e94afea6e571811514c2ef916d9abd...14dfdfa01e5bff7814c31867eb8f59261d69d38b
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list