[vlc-commits] [Git][videolan/vlc][master] 3 commits: qt: update qml_menu_wrapper(s)

Steve Lhomme (@robUx4) gitlab at videolan.org
Sun Feb 23 13:51:29 UTC 2025



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
e718a113 by Prince Gupta at 2025-02-23T13:36:13+00:00
qt: update qml_menu_wrapper(s)

Have a common class in all menu wrappers that implement
some basic functionality - visibility and memory management

implement tableView_popup function for Network context menu

- - - - -
fc42c7f5 by Prince Gupta at 2025-02-23T13:36:13+00:00
qml: update implementation of MLContextMenu

useful for changes following this commit

- - - - -
62dc35f6 by Prince Gupta at 2025-02-23T13:36:13+00:00
qml: keep context menu button visible when menu is shown

- - - - -


17 changed files:

- modules/gui/qt/medialibrary/qml/MusicAlbums.qml
- modules/gui/qt/medialibrary/qml/MusicAllArtists.qml
- modules/gui/qt/medialibrary/qml/MusicArtist.qml
- modules/gui/qt/medialibrary/qml/MusicGenres.qml
- modules/gui/qt/medialibrary/qml/MusicTrackListDisplay.qml
- modules/gui/qt/medialibrary/qml/PlaylistMediaDisplay.qml
- modules/gui/qt/medialibrary/qml/PlaylistMediaList.qml
- modules/gui/qt/medialibrary/qml/UrlListDisplay.qml
- modules/gui/qt/medialibrary/qml/VideoAll.qml
- modules/gui/qt/menus/qml_menu_wrapper.cpp
- modules/gui/qt/menus/qml_menu_wrapper.hpp
- modules/gui/qt/network/qml/BrowseDeviceView.qml
- modules/gui/qt/network/qml/BrowseTreeDisplay.qml
- modules/gui/qt/util/qml/MLContextMenu.qml
- modules/gui/qt/util/qml/NativeMenu.qml
- modules/gui/qt/widgets/qml/TableViewDelegate.qml
- modules/gui/qt/widgets/qml/TableViewExt.qml


Changes:

=====================================
modules/gui/qt/medialibrary/qml/MusicAlbums.qml
=====================================
@@ -243,12 +243,11 @@ MainViewLoader {
             dragItem: albumDragItem
             rowHeight: VLCStyle.tableCoverRow_height
 
+            rowContextMenu: contextMenu
+
             sortModel: (availableRowWidth < VLCStyle.colWidth(4)) ? _modelSmall
                                                                   : _modelMedium
 
-            onContextMenuButtonClicked: (_,_,globalMousePos) => {
-                contextMenu.popup(selectionModel.selectedIndexes, globalMousePos)
-            }
             onRightClick: (_,_,globalMousePos) => {
                 contextMenu.popup(selectionModel.selectedIndexes, globalMousePos)
             }


=====================================
modules/gui/qt/medialibrary/qml/MusicAllArtists.qml
=====================================
@@ -203,6 +203,7 @@ MainViewLoader {
             model: artistModel
             focus: true
             dragItem: artistsDragItem
+            rowContextMenu: contextMenu
             rowHeight: VLCStyle.tableCoverRow_height
 
             header: root.header
@@ -221,9 +222,6 @@ MainViewLoader {
                 root.requestArtistAlbumView(Qt.MouseFocusReason, model.id)
             }
 
-            onContextMenuButtonClicked: (_,_, globalMousePos) => {
-                contextMenu.popup(selectionModel.selectedIndexes, globalMousePos)
-            }
             onRightClick: (_,_,globalMousePos) => {
                 contextMenu.popup(selectionModel.selectedIndexes, globalMousePos)
             }


=====================================
modules/gui/qt/medialibrary/qml/MusicArtist.qml
=====================================
@@ -550,6 +550,8 @@ FocusScope {
 
             dragItem: tableDragItem
 
+            rowContextMenu: trackContextMenu
+
             Navigation.parentItem: root
 
             Navigation.upAction: function() {
@@ -559,7 +561,6 @@ FocusScope {
             Navigation.cancelAction: root._onNavigationCancel
 
             onItemDoubleClicked: MediaLib.addAndPlay(model.id)
-            onContextMenuButtonClicked: trackContextMenu.popup(tableView_id.selectionModel.selectedIndexes, globalMousePos)
             onRightClick: trackContextMenu.popup(tableView_id.selectionModel.selectedIndexes, globalMousePos)
 
             onDragItemChanged: console.assert(tableView_id.dragItem === tableDragItem)


=====================================
modules/gui/qt/medialibrary/qml/MusicGenres.qml
=====================================
@@ -266,14 +266,12 @@ MainViewLoader {
 
             header: root.header
 
+            rowContextMenu: contextMenu
+
             onItemDoubleClicked: (index, model) => {
                 root.showAlbumView(model.id, model.name, Qt.MouseFocusReason)
             }
 
-            onContextMenuButtonClicked: (_,_,globalMousePos) => {
-                contextMenu.popup(selectionModel.selectedIndexes, globalMousePos)
-            }
-
             onRightClick: (_,_,globalMousePos) => {
                 contextMenu.popup(selectionModel.selectedIndexes, globalMousePos)
             }


=====================================
modules/gui/qt/medialibrary/qml/MusicTrackListDisplay.qml
=====================================
@@ -180,11 +180,10 @@ Widgets.TableViewExt {
 
     onDragItemChanged: console.assert(root.dragItem === tableDragItem)
 
+    rowContextMenu: contextMenu
+
     onActionForSelection: (selection) => model.addAndPlay(selection)
     onItemDoubleClicked: (index, model) => MediaLib.addAndPlay(model.id)
-    onContextMenuButtonClicked: (_,_, globalMousePos) => {
-        contextMenu.popup(selectionModel.selectedIndexes, globalMousePos)
-    }
     onRightClick: (_,_, globalMousePos) => {
         contextMenu.popup(selectionModel.selectedIndexes, globalMousePos)
     }


=====================================
modules/gui/qt/medialibrary/qml/PlaylistMediaDisplay.qml
=====================================
@@ -184,6 +184,10 @@ FocusScope {
 
         model: root.model
         ctx: MainCtx
+
+        function tableView_popup(index, selectedIndexes, globalPos) {
+            popup(selectedIndexes, globalPos)
+        }
     }
 
     PlaylistMedia
@@ -200,6 +204,8 @@ FocusScope {
 
         dragItem: root.dragItem
 
+        rowContextMenu: contextMenu
+
         isMusic: root.isMusic
 
         header: Widgets.ViewHeader {
@@ -222,10 +228,6 @@ FocusScope {
 
         // Events
 
-        onContextMenuButtonClicked: (_,_,globalMousePos) => {
-            contextMenu.popup(selectionModel.selectedRows(), globalMousePos)
-        }
-
         onRightClick: (_,_,globalMousePos) => {
             contextMenu.popup(selectionModel.selectedRows(), globalMousePos)
         }


=====================================
modules/gui/qt/medialibrary/qml/PlaylistMediaList.qml
=====================================
@@ -238,6 +238,10 @@ MainViewLoader {
         model: root.model
 
         ctx: MainCtx
+
+        function tableView_popup(index, selectedIndexes, globalPos) {
+            popup(selectedIndexes, globalPos)
+        }
     }
 
     // TBD: Refactor this with MusicGenres ?
@@ -414,6 +418,8 @@ MainViewLoader {
 
             header: root.header
 
+            rowContextMenu: contextMenu
+
             listView.isDropAcceptableFunc: function(drag, index) {
                 root._adjustDragAccepted(drag)
                 return drag.accepted
@@ -434,10 +440,6 @@ MainViewLoader {
 
             onItemDoubleClicked: (_, model) => showList(model, Qt.MouseFocusReason)
 
-            onContextMenuButtonClicked: (_, _, globalMousePos) => {
-                contextMenu.popup(selectionModel.selectedRows(), globalMousePos)
-            }
-
             onRightClick: (_, _, globalMousePos) => {
                 contextMenu.popup(selectionModel.selectedRows(), globalMousePos)
             }


=====================================
modules/gui/qt/medialibrary/qml/UrlListDisplay.qml
=====================================
@@ -83,11 +83,11 @@ Widgets.TableViewExt {
 
     rowHeight: VLCStyle.listAlbumCover_height + VLCStyle.margin_xxsmall * 2
 
+    rowContextMenu: contextMenu
+
     onActionForSelection: (selection) => model.addAndPlay( selection )
     onItemDoubleClicked: (index, model) => MediaLib.addAndPlay(model.id)
-    onContextMenuButtonClicked: (_,_,globalMousePos) => {
-        contextMenu.popup(selectionModel.selectedIndexes, globalMousePos)
-    }
+
     onRightClick: (_,_,globalMousePos) => {
         contextMenu.popup(selectionModel.selectedIndexes, globalMousePos)
     }


=====================================
modules/gui/qt/medialibrary/qml/VideoAll.qml
=====================================
@@ -184,6 +184,8 @@ MainViewLoader {
 
             selectionModel: root.selectionModel
 
+            rowContextMenu: root.contextMenu
+
             dragItem: root.dragItem
 
             header: root.header
@@ -210,10 +212,6 @@ MainViewLoader {
 
             onItemDoubleClicked: (index, model) => root.onDoubleClick(model)
 
-            onContextMenuButtonClicked: (_,_,globalMousePos) => {
-                root.contextMenu.popup(selectionModel.selectedIndexes, globalMousePos)
-            }
-
             onRightClick: (_,_,globalMousePos) => {
                 root.contextMenu.popup(selectionModel.selectedIndexes, globalMousePos)
             }


=====================================
modules/gui/qt/menus/qml_menu_wrapper.cpp
=====================================
@@ -71,8 +71,7 @@ namespace
 void StringListMenu::popup(const QPoint &point, const QVariantList &stringList)
 {
     assert(m_ctx);
-    QMenu *m = new VLCMenu(m_ctx->getIntf());
-    m->setAttribute(Qt::WA_DeleteOnClose);
+    QMenu *m = newMenu();
 
     for (int i = 0; i != stringList.size(); ++i)
     {
@@ -86,6 +85,30 @@ void StringListMenu::popup(const QPoint &point, const QVariantList &stringList)
     m->popup(point);
 }
 
+QMenu *BasicMenuContainer::newMenu()
+{
+    QMenu *m = new VLCMenu(m_ctx->getIntf());
+    m->setAttribute(Qt::WA_DeleteOnClose);
+    if (m_prevMenu)
+    {
+        setVisible(false);
+        m_prevMenu->disconnect(this);
+    }
+
+    m_prevMenu = m;
+    connect(m, &QMenu::aboutToShow, this, [this](){ setVisible(true);});
+    connect(m, &QMenu::aboutToHide, this, [this](){ setVisible(false);});
+    return m;
+}
+
+void BasicMenuContainer::setVisible(bool visible)
+{
+    if (m_visible == visible) return;
+
+    m_visible = visible;
+    emit visibleChanged();
+}
+
 // SortMenu
 
 void SortMenu::popup(const QPoint &point, const bool popupAbovePoint, const QVariantList &model)
@@ -771,7 +794,7 @@ void QmlAudioContextMenu::popup(const QPoint & position)
 //=================================================================================================
 
 PlaylistListContextMenu::PlaylistListContextMenu(QObject * parent)
-    : QObject(parent)
+    : BasicMenuContainer(parent)
 {}
 
 
@@ -787,17 +810,17 @@ void PlaylistListContextMenu::popup(const QModelIndexList & selected, QPoint pos
     for (const QModelIndex & modelIndex : selected)
         ids.push_back(m_model->data(modelIndex, MLPlaylistListModel::PLAYLIST_ID));
 
-    m_menu = std::make_unique<VLCMenu>(m_ctx->getIntf());
+    auto menu = newMenu();
 
     MediaLib * ml = m_model->ml();
 
-    QAction * action = m_menu->addAction(qtr("Add and play"));
+    QAction * action = menu->addAction(qtr("Add and play"));
 
     connect(action, &QAction::triggered, [ml, ids]() {
         ml->addAndPlay(ids);
     });
 
-    action = m_menu->addAction(qtr("Enqueue"));
+    action = menu->addAction(qtr("Enqueue"));
 
     connect(action, &QAction::triggered, [ml, ids]() {
         ml->addToPlaylist(ids);
@@ -805,7 +828,7 @@ void PlaylistListContextMenu::popup(const QModelIndexList & selected, QPoint pos
 
     if (ids.count() == 1)
     {
-        action = m_menu->addAction(qtr("Rename"));
+        action = menu->addAction(qtr("Rename"));
 
         QModelIndex index = selected.first();
 
@@ -814,20 +837,19 @@ void PlaylistListContextMenu::popup(const QModelIndexList & selected, QPoint pos
         });
     }
 
-    action = m_menu->addAction(qtr("Delete"));
+    action = menu->addAction(qtr("Delete"));
 
     connect(action, &QAction::triggered, [this, ids]() {
         m_model->deletePlaylists(ids);
     });
 
-    m_menu->popup(pos);
+    menu->popup(pos);
 }
 
 //=================================================================================================
 // PlaylistMediaContextMenu
 //=================================================================================================
 
-PlaylistMediaContextMenu::PlaylistMediaContextMenu(QObject * parent) : QObject(parent) {}
 
 void PlaylistMediaContextMenu::popup(const QModelIndexList & selected, QPoint pos,
                                      QVariantMap options)
@@ -842,38 +864,38 @@ void PlaylistMediaContextMenu::popup(const QModelIndexList & selected, QPoint po
     for (const QModelIndex& modelIndex : selected)
         ids.push_back(m_model->data(modelIndex, MLPlaylistModel::MEDIA_ID));
 
-    m_menu = std::make_unique<VLCMenu>(m_ctx->getIntf());
+    auto menu =newMenu();
 
     MediaLib * ml = m_model->ml();
 
-    QAction * action = m_menu->addAction(qtr("Add and play"));
+    QAction * action = menu->addAction(qtr("Add and play"));
 
     connect(action, &QAction::triggered, [ml, ids]() {
         ml->addAndPlay(ids);
     });
 
-    action = m_menu->addAction(qtr("Enqueue"));
+    action = menu->addAction(qtr("Enqueue"));
 
     connect(action, &QAction::triggered, [ml, ids]() {
         ml->addToPlaylist(ids);
     });
 
-    action = m_menu->addAction(qtr("Add to playlist"));
+    action = menu->addAction(qtr("Add to playlist"));
 
     connect(action, &QAction::triggered, [ids]() {
         DialogsProvider::getInstance()->playlistsDialog(ids);
     });
 
-    action = m_menu->addAction(qtr("Play as audio"));
+    action = menu->addAction(qtr("Play as audio"));
 
     connect(action, &QAction::triggered, [ml, ids]() {
         ml->addAndPlay(ids, {":no-video"});
     });
 
     if (options.contains("information") && options["information"].typeId() == QMetaType::Int) {
-        action = m_menu->addAction(qtr("Information"));
+        action = menu->addAction(qtr("Information"));
 
-        QSignalMapper * mapper = new QSignalMapper(m_menu.get());
+        QSignalMapper * mapper = new QSignalMapper(menu);
 
         connect(action, &QAction::triggered, mapper, QOverload<>::of(&QSignalMapper::map));
 
@@ -882,9 +904,9 @@ void PlaylistMediaContextMenu::popup(const QModelIndexList & selected, QPoint po
                 this, &PlaylistMediaContextMenu::showMediaInformation);
     }
 
-    m_menu->addSeparator();
+    menu->addSeparator();
 
-    action = m_menu->addAction(qtr("Remove Selected"));
+    action = menu->addAction(qtr("Remove Selected"));
 
     action->setIcon(QIcon(":/menu/remove.svg"));
 
@@ -892,15 +914,11 @@ void PlaylistMediaContextMenu::popup(const QModelIndexList & selected, QPoint po
         m_model->remove(selected);
     });
 
-    m_menu->popup(pos);
+    menu->popup(pos);
 }
 
 //=================================================================================================
 
-NetworkMediaContextMenu::NetworkMediaContextMenu(QObject* parent)
-    : QObject(parent)
-{}
-
 void NetworkMediaContextMenu::popup(const QModelIndexList& selected, QPoint pos)
 {
     assert(m_ctx);
@@ -908,15 +926,15 @@ void NetworkMediaContextMenu::popup(const QModelIndexList& selected, QPoint pos)
     if (!m_model)
         return;
 
-    m_menu = std::make_unique<VLCMenu>(m_ctx->getIntf());
+    auto menu = newMenu();
     QAction* action;
 
-    action = m_menu->addAction( qtr("Add and play") );
+    action = menu->addAction( qtr("Add and play") );
     connect(action, &QAction::triggered, [this, selected]( ) {
         m_model->addAndPlay(selected);
     });
 
-    action = m_menu->addAction( qtr("Enqueue") );
+    action = menu->addAction( qtr("Enqueue") );
     connect(action, &QAction::triggered, [this, selected]( ) {
         m_model->addToPlaylist(selected);
     });
@@ -940,7 +958,7 @@ void NetworkMediaContextMenu::popup(const QModelIndexList& selected, QPoint pos)
     if (canBeIndexed)
     {
         bool removeFromML = countIndexed > 0;
-        action = m_menu->addAction(removeFromML
+        action = menu->addAction(removeFromML
             ? qtr("Remove from Media Library")
             : qtr("Add to Media Library"));
 
@@ -951,13 +969,9 @@ void NetworkMediaContextMenu::popup(const QModelIndexList& selected, QPoint pos)
         });
     }
 
-    m_menu->popup(pos);
+    menu->popup(pos);
 }
 
-NetworkDeviceContextMenu::NetworkDeviceContextMenu(QObject* parent)
-    : QObject(parent)
-{}
-
 void NetworkDeviceContextMenu::popup(const QModelIndexList& selected, QPoint pos)
 {
     assert(m_ctx);
@@ -965,20 +979,20 @@ void NetworkDeviceContextMenu::popup(const QModelIndexList& selected, QPoint pos
     if (!m_model)
         return;
 
-    m_menu = std::make_unique<VLCMenu>(m_ctx->getIntf());
+    auto menu = newMenu();
     QAction* action;
 
-    action = m_menu->addAction( qtr("Add and play") );
+    action = menu->addAction( qtr("Add and play") );
     connect(action, &QAction::triggered, [this, selected]( ) {
         m_model->addAndPlay(selected);
     });
 
-    action = m_menu->addAction( qtr("Enqueue") );
+    action = menu->addAction( qtr("Enqueue") );
     connect(action, &QAction::triggered, [this, selected]( ) {
         m_model->addToPlaylist(selected);
     });
 
-    m_menu->popup(pos);
+    menu->popup(pos);
 }
 
 PlaylistContextMenu::PlaylistContextMenu(QObject* parent)


=====================================
modules/gui/qt/menus/qml_menu_wrapper.hpp
=====================================
@@ -57,22 +57,44 @@ class PlaylistListModel;
     type m_##name = defaultValue;
 
 
-class StringListMenu : public QObject
+class BasicMenuContainer : public QObject
 {
     Q_OBJECT
 
     SIMPLE_MENU_PROPERTY(MainCtx *, ctx, nullptr)
+    Q_PROPERTY(bool visible READ visible NOTIFY visibleChanged FINAL)
 
 public:
     using QObject::QObject;
 
+    bool visible() const { return m_visible; }
+
+signals:
+    void visibleChanged();
+
+protected:
+    QMenu *newMenu();
+
+private:
+    void setVisible(bool visible);
+
+    bool m_visible = false;
+    QPointer<QMenu> m_prevMenu;
+};
+
+class StringListMenu : public BasicMenuContainer
+{
+    Q_OBJECT
+
+public:
+    using BasicMenuContainer::BasicMenuContainer;
+
     Q_INVOKABLE void popup(const QPoint &point, const QVariantList &stringList);
 
 signals:
     void selected(int index, const QString &str);
 };
 
-
 class SortMenu : public QObject
 {
     Q_OBJECT
@@ -360,18 +382,15 @@ protected: // QmlTrackMenu implementation
     void beforePopup(QMenu * menu) override;
 };
 
-class PlaylistListContextMenu : public QObject {
+class PlaylistListContextMenu : public BasicMenuContainer {
     Q_OBJECT
 
-    SIMPLE_MENU_PROPERTY(MainCtx *, ctx, nullptr)
     SIMPLE_MENU_PROPERTY(MLPlaylistListModel *, model, nullptr)
 public:
     PlaylistListContextMenu(QObject * parent = nullptr);
 
 public slots:
     void popup(const QModelIndexList & selected, QPoint pos, QVariantMap options = {});
-private:
-    std::unique_ptr<QMenu> m_menu;
 };
 
 class QmlAudioContextMenu : public VLCMenuBar
@@ -389,44 +408,45 @@ private:
     std::unique_ptr<QMenu> m_menu;
 };
 
-class PlaylistMediaContextMenu : public QObject {
+class PlaylistMediaContextMenu : public BasicMenuContainer {
     Q_OBJECT
     SIMPLE_MENU_PROPERTY(MLPlaylistModel *, model, nullptr)
-    SIMPLE_MENU_PROPERTY(MainCtx *, ctx, nullptr)
 public:
-    PlaylistMediaContextMenu(QObject * parent = nullptr);
+    using BasicMenuContainer::BasicMenuContainer;
 
 public slots:
     void popup(const QModelIndexList & selected, QPoint pos, QVariantMap options = {});
 signals:
     void showMediaInformation(int index);
-private:
-    std::unique_ptr<QMenu> m_menu;
 };
 
-class NetworkMediaContextMenu : public QObject {
+class NetworkMediaContextMenu : public BasicMenuContainer {
     Q_OBJECT
     SIMPLE_MENU_PROPERTY(NetworkMediaModel*, model, nullptr)
-    SIMPLE_MENU_PROPERTY(MainCtx *, ctx, nullptr)
 public:
-    NetworkMediaContextMenu(QObject* parent = nullptr);
+        using BasicMenuContainer::BasicMenuContainer;
 
 public slots:
     void popup(const QModelIndexList& selected, QPoint pos );
-private:
-    std::unique_ptr<QMenu> m_menu;
+    void tableView_popup(int /*current*/, const QModelIndexList &selected, QPoint pos)
+    {
+        popup(selected, pos);
+    }
 };
 
-class NetworkDeviceContextMenu : public QObject {
+class NetworkDeviceContextMenu : public BasicMenuContainer {
     Q_OBJECT
     SIMPLE_MENU_PROPERTY(NetworkDeviceModel*, model, nullptr)
-    SIMPLE_MENU_PROPERTY(MainCtx *, ctx, nullptr)
 public:
-    NetworkDeviceContextMenu(QObject* parent = nullptr);
+    using BasicMenuContainer::BasicMenuContainer;
+
 public slots:
     void popup(const QModelIndexList& selected, QPoint pos );
-private:
-    std::unique_ptr<QMenu> m_menu;
+    void tableView_popup(int /*current*/, const QModelIndexList &selected, QPoint pos)
+    {
+        popup(selected, pos);
+    }
+
 };
 
 class PlaylistContextMenu : public QObject {


=====================================
modules/gui/qt/network/qml/BrowseDeviceView.qml
=====================================
@@ -288,6 +288,8 @@ FocusScope {
 
             // Settings
 
+            rowContextMenu: null
+
             rowHeight: VLCStyle.tableCoverRow_height
 
             displayMarginEnd: root.displayMarginEnd


=====================================
modules/gui/qt/network/qml/BrowseTreeDisplay.qml
=====================================
@@ -295,11 +295,11 @@ MainViewLoader {
                 }
             }
 
+            rowContextMenu: contextMenu
+
             onActionForSelection: (selection) => _actionAtIndex(selection[0].row)
             onItemDoubleClicked: (index, model) => _actionAtIndex(index)
-            onContextMenuButtonClicked: (_,_,globalMousePos) => {
-                contextMenu.popup(selectionModel.selectedIndexes, globalMousePos)
-            }
+
             onRightClick: (_,_,globalMousePos) => {
                 contextMenu.popup(selectionModel.selectedIndexes, globalMousePos)
             }


=====================================
modules/gui/qt/util/qml/MLContextMenu.qml
=====================================
@@ -40,6 +40,12 @@ NativeMenu {
 
     signal showMediaInformation(int index)
 
+
+    // required by TableViewExt
+    property var tableView_popup: function (index/* reserved for future */, selectedIndexes, globalPos) {
+        return popup(selectedIndexes, globalPos)
+    }
+
     // Settings
 
     actions: [{


=====================================
modules/gui/qt/util/qml/NativeMenu.qml
=====================================
@@ -43,6 +43,10 @@ QtObject {
 
     property var actions: []
 
+    property alias visible: menu.visible
+
+    readonly property int currentRequest: _currentRequest
+
     signal requestData(var requestID, var indexes)
 
 
@@ -58,7 +62,9 @@ QtObject {
 
     property point _popupPoint
 
-
+    // requests data for '_indexes' and shows popup menu
+    // with 'NativeMenu::actions' based on '_options'
+    // returns unique request id
     function popup(_indexes, point, _options) {
         root._options = _options
         root._indexes = _indexes
@@ -67,6 +73,7 @@ QtObject {
 
         const requestID = ++_currentRequest
         requestData(requestID, _indexes)
+        return requestID
     }
 
     function setData(id, data) {


=====================================
modules/gui/qt/widgets/qml/TableViewDelegate.qml
=====================================
@@ -35,6 +35,8 @@ T.Control {
     required property bool selected
     required property Widgets.DragItem dragItem
 
+    required property var contextMenu
+
     readonly property bool topContainsDrag: dropAreaLayout.higherDropArea.containsDrag
     readonly property bool bottomContainsDrag: dropAreaLayout.lowerDropArea.containsDrag
     readonly property bool containsDrag: (topContainsDrag || bottomContainsDrag)
@@ -46,6 +48,8 @@ T.Control {
                                                       dropAreaLayout.dragPosition.x,
                                                       dropAreaLayout.dragPosition.y)
 
+    readonly property ItemSelectionModel selectionModel: delegate.ListView.view.selectionModel
+
     // Optional, used to show the drop indicator
     property alias isDropAcceptable: dropAreaLayout.isDropAcceptable
 
@@ -54,12 +58,23 @@ T.Control {
 
     property int _modifiersOnLastPress: Qt.NoModifier
 
-    signal contextMenuButtonClicked(Item menuParent, var menuModel, point globalMousePos)
+    readonly property int _defaultContextMenuRequestID: index
+
+    property int _contextMenuRequestID: -1
+
     signal rightClick(Item menuParent, var menuModel, point globalMousePos)
     signal itemDoubleClicked(var index, var model)
 
     signal selectAndFocus(int modifiers, int focusReason)
 
+    Connections {
+        target: contextMenu
+
+        function onVisibleChanged() {
+            if (!contextMenu.visible) _contextMenuRequestID = -1
+        }
+    }
+
     property Component defaultDelegate: TableRowDelegate {
         id: defaultDelId
         Widgets.TextAutoScroller {
@@ -126,7 +141,7 @@ T.Control {
                 if (dragItem) {
                     if (active) {
                         if (!selected) {
-                            delegate.ListView.view.selectionModel.select(index, ItemSelectionModel.ClearAndSelect)
+                            delegate.selectionModel.select(index, ItemSelectionModel.ClearAndSelect)
                         }
 
                         dragItem.Drag.active = true
@@ -151,7 +166,7 @@ T.Control {
 
                 if (!(delegate.selected && button === Qt.RightButton)) {
                     const view = delegate.ListView.view
-                    view.selectionModel.updateSelection(point.modifiers, view.currentIndex, index)
+                    delegate.selectionModel.updateSelection(point.modifiers, view.currentIndex, index)
                     view.currentIndex = index
                 }
 
@@ -248,6 +263,8 @@ T.Control {
 
             height: parent.height
 
+            visible: !!delegate.contextMenu
+
             Widgets.IconToolButton {
                 id: contextButton
 
@@ -263,6 +280,9 @@ T.Control {
                 description: qsTr("Menu")
 
                 visible: delegate.hovered
+                         || ((delegate.contextMenu?.currentRequest ?? delegate._defaultContextMenuRequestID)
+                                    === delegate._contextMenuRequestID
+                                && delegate.contextMenu.visible)
 
                 // NOTE: QTBUG-100543
                 // Hover handling in controls is blocking in Qt 6.2, meaning if this
@@ -284,7 +304,11 @@ T.Control {
                         delegate.selectAndFocus(Qt.NoModifier, Qt.MouseFocusReason)
 
                     const pos = contextButton.mapToGlobal(VLCStyle.margin_xsmall, contextButton.height / 2 + VLCStyle.fontHeight_normal)
-                    delegate.contextMenuButtonClicked(this, delegate.rowModel, pos)
+                    const selectionIndexes = delegate.ListView.view.selectionModel.selectedIndexes
+
+                    delegate._contextMenuRequestID
+                            = delegate.contextMenu.tableView_popup(delegate.index, selectionIndexes, pos)
+                                ?? delegate._defaultContextMenuRequestID
                 }
 
                 activeFocusOnTab: false


=====================================
modules/gui/qt/widgets/qml/TableViewExt.qml
=====================================
@@ -47,6 +47,30 @@ FocusScope {
         }
     }
 
+    /*
+        Expects an object with the following properties:
+
+        // Determines if the menu is visible (optional)
+        bool visible
+
+        // The request ID associated with the currently displayed context menu (optional)
+        int currentRequest
+
+        // Displays the popup menu at the specified position (required)
+        // incase the function doesn't return request id TableViewExt will
+        // try to mimic behavior but it may have some caveats
+        //
+        // Parameters:
+        //    current    - calling row index
+        //    selectedIndexes - current item selection (all)
+        //    globalPos  - the global position where the popup should appear
+        //
+        // Returns:
+        //    int - the generated request ID
+        function tableView_popup(current, selectedIndexes, globalPos) -> int (request ID)
+    */
+    required property var rowContextMenu
+
     // NOTE: We want edge to edge backgrounds in our delegate and header, so we implement our own
     //       margins implementation like in ExpandGridView. The default values should be the same
     //       than ExpandGridView to respect the grid parti pris.
@@ -157,7 +181,6 @@ FocusScope {
 
     //forwarded from subview
     signal actionForSelection( var selection )
-    signal contextMenuButtonClicked(Item menuParent, var menuModel, point globalMousePos)
     signal rightClick(Item menuParent, var menuModel, point globalMousePos)
     signal itemDoubleClicked(var index, var model)
 
@@ -235,7 +258,6 @@ FocusScope {
         id: view
 
         anchors.fill: parent
-
         focus: true
 
         headerPositioning: ListView.OverlayHeader
@@ -402,14 +424,13 @@ FocusScope {
 
             dragItem: root.dragItem
 
+            contextMenu: root.rowContextMenu
+
             rowModel: model
             sortModel: root.sortModel
 
             selected: selectionModel.selectedIndexesFlat.includes(index)
 
-            onContextMenuButtonClicked: (menuParent, menuModel, globalMousePos) => {
-                root.contextMenuButtonClicked(menuParent, menuModel, globalMousePos)
-            }
             onRightClick: (menuParent, menuModel, globalMousePos) => {
                 root.rightClick(menuParent, menuModel, globalMousePos)
             }



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/6ff47780a40332671a0d3b5ba0fad0fb45e03b20...62dc35f62b62637add0b845a8ddbfeb5d885977c

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/6ff47780a40332671a0d3b5ba0fad0fb45e03b20...62dc35f62b62637add0b845a8ddbfeb5d885977c
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