diff --git a/src/library/library.cpp b/src/library/library.cpp index 0200683586d1..44da525af38b 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -420,6 +420,15 @@ void Library::bindLibraryWidget( m_pLibraryControl->bindLibraryWidget(pLibraryWidget, pKeyboard); + connect(m_pLibraryControl, + &LibraryControl::showHideTrackMenu, + pTrackTableView, + &WTrackTableView::slotShowHideTrackMenu); + connect(pTrackTableView, + &WTrackTableView::trackMenuVisible, + m_pLibraryControl, + &LibraryControl::slotUpdateTrackMenuControl); + for (const auto& feature : qAsConst(m_features)) { feature->bindLibraryWidget(pLibraryWidget, pKeyboard); } diff --git a/src/library/librarycontrol.cpp b/src/library/librarycontrol.cpp index 04229ab2b4fa..5b5afd8abbe6 100644 --- a/src/library/librarycontrol.cpp +++ b/src/library/librarycontrol.cpp @@ -325,7 +325,23 @@ LibraryControl::LibraryControl(Library* pLibrary) } }); - /// Deprecated controls + // Show the track context menu for selected tracks, or hide it + // if it is the current active window + // The control is updated in slotUpdateTrackMenuControl with the actual state + // sent from WTrackMenu via WTrackTableView + m_pShowTrackMenu = std::make_unique( + ConfigKey("[Library]", "show_track_menu")); + m_pShowTrackMenu->setStates(2); + m_pShowTrackMenu->connectValueChangeRequest(this, + [this](double value) { + VERIFY_OR_DEBUG_ASSERT(m_pLibraryWidget) { + return; + } + bool show = static_cast(value); + emit showHideTrackMenu(show); + }); + + // Deprecated controls m_pSelectNextTrack = std::make_unique(ConfigKey("[Playlist]", "SelectNextTrack")); connect(m_pSelectNextTrack.get(), &ControlPushButton::valueChanged, @@ -489,6 +505,10 @@ void LibraryControl::searchboxWidgetDeleted() { m_pSearchbox = nullptr; } +void LibraryControl::slotUpdateTrackMenuControl(bool visible) { + m_pShowTrackMenu->setAndConfirm(visible ? 1.0 : 0.0); +} + void LibraryControl::slotLoadSelectedTrackToGroup(const QString& group, bool play) { if (!m_pLibraryWidget) { return; diff --git a/src/library/librarycontrol.h b/src/library/librarycontrol.h index 69ba138dae60..fe0290df351e 100644 --- a/src/library/librarycontrol.h +++ b/src/library/librarycontrol.h @@ -50,10 +50,12 @@ class LibraryControl : public QObject { signals: void clearSearchIfClearButtonHasFocus(); + void showHideTrackMenu(bool show); public slots: // Deprecated navigation slots void slotLoadSelectedTrackToGroup(const QString& group, bool play); + void slotUpdateTrackMenuControl(bool visible); private slots: void libraryWidgetDeleted(); @@ -151,6 +153,9 @@ class LibraryControl : public QObject { std::unique_ptr m_pTrackColorPrev; std::unique_ptr m_pTrackColorNext; + // Control to show/hide the track menu + std::unique_ptr m_pShowTrackMenu; + // Controls to navigate search history std::unique_ptr m_pSelectHistoryNext; std::unique_ptr m_pSelectHistoryPrev; diff --git a/src/widget/wtrackmenu.cpp b/src/widget/wtrackmenu.cpp index bc4f31bb7a69..7d3e38951030 100644 --- a/src/widget/wtrackmenu.cpp +++ b/src/widget/wtrackmenu.cpp @@ -89,11 +89,19 @@ int WTrackMenu::getTrackCount() const { } } +void WTrackMenu::closeEvent(QCloseEvent* event) { + // Actually the event is accepted by default. doing it explicitly doesn't hurt. + // If it's not accepted the menu remains open and entire GUI will be blocked! + event->accept(); + emit trackMenuVisible(false); +} + void WTrackMenu::popup(const QPoint& pos, QAction* at) { if (isEmpty()) { return; } QMenu::popup(pos, at); + emit trackMenuVisible(true); } void WTrackMenu::createMenus() { diff --git a/src/widget/wtrackmenu.h b/src/widget/wtrackmenu.h index 3280ba6b6d17..2b635993427f 100644 --- a/src/widget/wtrackmenu.h +++ b/src/widget/wtrackmenu.h @@ -83,6 +83,7 @@ class WTrackMenu : public QMenu { signals: void loadTrackToPlayer(TrackPointer pTrack, const QString& group, bool play = false); + void trackMenuVisible(bool visible); private slots: // File @@ -138,6 +139,7 @@ class WTrackMenu : public QMenu { void slotPurge(); private: + void closeEvent(QCloseEvent* event) override; // This getter verifies that m_pTrackModel is set when // invoked. const QModelIndexList& getTrackIndices() const; diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index dc9bc17a4037..4060ca8d0118 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -341,6 +341,13 @@ void WTrackTableView::initTrackMenu() { &WTrackMenu::loadTrackToPlayer, this, &WTrackTableView::loadTrackToPlayer); + + connect(m_pTrackMenu, + &WTrackMenu::trackMenuVisible, + this, + [this](bool visible) { + emit trackMenuVisible(visible); + }); } // slot @@ -461,6 +468,22 @@ void WTrackTableView::slotUnhide() { } } +void WTrackTableView::slotShowHideTrackMenu(bool show) { + VERIFY_OR_DEBUG_ASSERT(m_pTrackMenu.get()) { + return; + } + if (show == m_pTrackMenu->isVisible()) { + emit trackMenuVisible(show); + return; + } + if (show) { + QContextMenuEvent event(QContextMenuEvent::Mouse, QCursor::pos()); + contextMenuEvent(&event); + } else { + m_pTrackMenu->close(); + } +} + void WTrackTableView::contextMenuEvent(QContextMenuEvent* event) { VERIFY_OR_DEBUG_ASSERT(m_pTrackMenu.get()) { initTrackMenu(); @@ -470,7 +493,7 @@ void WTrackTableView::contextMenuEvent(QContextMenuEvent* event) { QModelIndexList indices = selectionModel()->selectedRows(); m_pTrackMenu->loadTrackModelIndices(indices); - //Create the right-click menu + // Create the right-click menu m_pTrackMenu->popup(event->globalPos()); } diff --git a/src/widget/wtracktableview.h b/src/widget/wtracktableview.h index b24d4e7bea48..8001c5d318f9 100644 --- a/src/widget/wtracktableview.h +++ b/src/widget/wtracktableview.h @@ -53,12 +53,16 @@ class WTrackTableView : public WLibraryTableView { return m_pFocusBorderColor; } + signals: + void trackMenuVisible(bool visible); + public slots: void loadTrackModel(QAbstractItemModel* model, bool restoreState = false); void slotMouseDoubleClicked(const QModelIndex &); void slotUnhide(); void slotPurge(); void slotDeleteTracksFromDisk(); + void slotShowHideTrackMenu(bool show); void slotAddToAutoDJBottom() override; void slotAddToAutoDJTop() override;