From 2f3284267ab86e295bf8624c3845b8023135834b Mon Sep 17 00:00:00 2001 From: ronso0 Date: Fri, 8 Oct 2021 13:38:10 +0200 Subject: [PATCH 1/2] librarycontrol: allow to focus the library widget directly... without the indirection via sidebar, and without assuming the library is next/after the sidebar. --- src/library/autodj/dlgautodj.cpp | 4 ++++ src/library/autodj/dlgautodj.h | 1 + src/library/dlganalysis.cpp | 4 ++++ src/library/dlganalysis.h | 1 + src/library/dlghidden.cpp | 4 ++++ src/library/dlghidden.h | 1 + src/library/dlgmissing.cpp | 4 ++++ src/library/dlgmissing.h | 1 + src/library/librarycontrol.cpp | 17 ++--------------- src/library/libraryview.h | 2 ++ src/library/recording/dlgrecording.cpp | 4 ++++ src/library/recording/dlgrecording.h | 1 + src/widget/wlibrary.cpp | 2 +- src/widget/wlibrarytextbrowser.cpp | 4 ++++ src/widget/wlibrarytextbrowser.h | 1 + src/widget/wtracktableview.cpp | 4 ++++ src/widget/wtracktableview.h | 1 + 17 files changed, 40 insertions(+), 16 deletions(-) diff --git a/src/library/autodj/dlgautodj.cpp b/src/library/autodj/dlgautodj.cpp index 94ff6780ac9f..4104dc72c1c6 100644 --- a/src/library/autodj/dlgautodj.cpp +++ b/src/library/autodj/dlgautodj.cpp @@ -388,3 +388,7 @@ void DlgAutoDJ::shiftTabKeypress() { QKeyEvent{QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier}; QApplication::sendEvent(this, &backwardFocusKeyEvent); } + +void DlgAutoDJ::setFocus() { + m_pTrackTableView->setFocus(); +} diff --git a/src/library/autodj/dlgautodj.h b/src/library/autodj/dlgautodj.h index 1857928b657b..cbe92c099dd1 100644 --- a/src/library/autodj/dlgautodj.h +++ b/src/library/autodj/dlgautodj.h @@ -29,6 +29,7 @@ class DlgAutoDJ : public QWidget, public Ui::DlgAutoDJ, public LibraryView { void onShow() override; bool hasFocus() const override; + void setFocus() override; void onSearch(const QString& text) override; void loadSelectedTrack() override; void loadSelectedTrackToGroup(const QString& group, bool play) override; diff --git a/src/library/dlganalysis.cpp b/src/library/dlganalysis.cpp index 4c34f81ba865..c5ef8e3681f3 100644 --- a/src/library/dlganalysis.cpp +++ b/src/library/dlganalysis.cpp @@ -111,6 +111,10 @@ bool DlgAnalysis::hasFocus() const { return m_pAnalysisLibraryTableView->hasFocus(); } +void DlgAnalysis::setFocus() { + m_pAnalysisLibraryTableView->setFocus(); +} + void DlgAnalysis::onSearch(const QString& text) { m_pAnalysisLibraryTableModel->search(text); } diff --git a/src/library/dlganalysis.h b/src/library/dlganalysis.h index e279fcfc8a99..b75beede9237 100644 --- a/src/library/dlganalysis.h +++ b/src/library/dlganalysis.h @@ -25,6 +25,7 @@ class DlgAnalysis : public QWidget, public Ui::DlgAnalysis, public virtual Libra void onSearch(const QString& text) override; void onShow() override; bool hasFocus() const override; + void setFocus() override; void loadSelectedTrack() override; void loadSelectedTrackToGroup(const QString& group, bool play) override; void slotAddToAutoDJBottom() override; diff --git a/src/library/dlghidden.cpp b/src/library/dlghidden.cpp index 266c2c01444e..d4f9fd674f5f 100644 --- a/src/library/dlghidden.cpp +++ b/src/library/dlghidden.cpp @@ -123,3 +123,7 @@ void DlgHidden::selectionChanged(const QItemSelection &selected, bool DlgHidden::hasFocus() const { return m_pTrackTableView->hasFocus(); } + +void DlgHidden::setFocus() { + m_pTrackTableView->setFocus(); +} diff --git a/src/library/dlghidden.h b/src/library/dlghidden.h index 9e83163997f1..cd1f04cd520c 100644 --- a/src/library/dlghidden.h +++ b/src/library/dlghidden.h @@ -23,6 +23,7 @@ class DlgHidden : public QWidget, public Ui::DlgHidden, public LibraryView { void onShow() override; bool hasFocus() const override; + void setFocus() override; void onSearch(const QString& text) override; QString currentSearch(); diff --git a/src/library/dlgmissing.cpp b/src/library/dlgmissing.cpp index 5cdf14b0392e..70340594b289 100644 --- a/src/library/dlgmissing.cpp +++ b/src/library/dlgmissing.cpp @@ -92,3 +92,7 @@ void DlgMissing::selectionChanged(const QItemSelection &selected, bool DlgMissing::hasFocus() const { return m_pTrackTableView->hasFocus(); } + +void DlgMissing::setFocus() { + m_pTrackTableView->setFocus(); +} diff --git a/src/library/dlgmissing.h b/src/library/dlgmissing.h index 9fd5985eec30..882848bfb4eb 100644 --- a/src/library/dlgmissing.h +++ b/src/library/dlgmissing.h @@ -23,6 +23,7 @@ class DlgMissing : public QWidget, public Ui::DlgMissing, public LibraryView { void onShow() override; bool hasFocus() const override; + void setFocus() override; void onSearch(const QString& text) override; QString currentSearch(); diff --git a/src/library/librarycontrol.cpp b/src/library/librarycontrol.cpp index 630fe34d9ed7..09d106544abc 100644 --- a/src/library/librarycontrol.cpp +++ b/src/library/librarycontrol.cpp @@ -629,23 +629,10 @@ void LibraryControl::emitKeyEvent(QKeyEvent&& event) { } void LibraryControl::setLibraryFocus() { - // TODO: Set the focus of the library panel directly instead of sending tab from sidebar - VERIFY_OR_DEBUG_ASSERT(m_pSidebarWidget) { - return; - } - // Try to focus the sidebar. - m_pSidebarWidget->setFocus(); - - // This may have failed, for example when a Cover window still has focus, - // so make sure the sidebar is focused or we'll crash. - if (!m_pSidebarWidget->hasFocus()) { + VERIFY_OR_DEBUG_ASSERT(m_pLibraryWidget) { return; } - // Send Tab to move focus to the Tracks table. - // Obviously only works as desired if the skin widgets are arranged - // accordingly. - QKeyEvent event(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier); - QApplication::sendEvent(m_pSidebarWidget, &event); + m_pLibraryWidget->getActiveView()->setFocus(); } void LibraryControl::slotSelectSidebarItem(double v) { diff --git a/src/library/libraryview.h b/src/library/libraryview.h index 112c294ca2a1..1c4498fd0d87 100644 --- a/src/library/libraryview.h +++ b/src/library/libraryview.h @@ -16,6 +16,8 @@ class LibraryView { virtual void onShow() = 0; virtual bool hasFocus() const = 0; + virtual void setFocus() { + } /// Reimplement if LibraryView should be able to search virtual void onSearch(const QString& text) {Q_UNUSED(text);} diff --git a/src/library/recording/dlgrecording.cpp b/src/library/recording/dlgrecording.cpp index c66373aff93e..c5befa11422f 100644 --- a/src/library/recording/dlgrecording.cpp +++ b/src/library/recording/dlgrecording.cpp @@ -112,6 +112,10 @@ bool DlgRecording::hasFocus() const { return m_pTrackTableView->hasFocus(); } +void DlgRecording::setFocus() { + m_pTrackTableView->setFocus(); +} + void DlgRecording::refreshBrowseModel() { m_browseModel.setPath(mixxx::FileAccess(mixxx::FileInfo(m_recordingDir))); } diff --git a/src/library/recording/dlgrecording.h b/src/library/recording/dlgrecording.h index 226d977c23da..306548b86202 100644 --- a/src/library/recording/dlgrecording.h +++ b/src/library/recording/dlgrecording.h @@ -26,6 +26,7 @@ class DlgRecording : public QWidget, public Ui::DlgRecording, public virtual Lib void onSearch(const QString& text) override; void onShow() override; bool hasFocus() const override; + void setFocus() override; void loadSelectedTrack() override; void slotAddToAutoDJBottom() override; void slotAddToAutoDJTop() override; diff --git a/src/widget/wlibrary.cpp b/src/widget/wlibrary.cpp index 15608e3ac549..dca7388b63c0 100644 --- a/src/widget/wlibrary.cpp +++ b/src/widget/wlibrary.cpp @@ -77,7 +77,7 @@ void WLibrary::switchToView(const QString& name) { WTrackTableView* ttWidgetView = qobject_cast( widget); - if (ttWidgetView != nullptr){ + if (ttWidgetView != nullptr) { qDebug("trying to restore position"); ttWidgetView->restoreCurrentVScrollBarPos(); } diff --git a/src/widget/wlibrarytextbrowser.cpp b/src/widget/wlibrarytextbrowser.cpp index 64b7139ef8a2..82d35ed6e5b9 100644 --- a/src/widget/wlibrarytextbrowser.cpp +++ b/src/widget/wlibrarytextbrowser.cpp @@ -9,3 +9,7 @@ WLibraryTextBrowser::WLibraryTextBrowser(QWidget* parent) bool WLibraryTextBrowser::hasFocus() const { return QWidget::hasFocus(); } + +void WLibraryTextBrowser::setFocus() { + QWidget::setFocus(); +} diff --git a/src/widget/wlibrarytextbrowser.h b/src/widget/wlibrarytextbrowser.h index b1e952301f88..206664f0693f 100644 --- a/src/widget/wlibrarytextbrowser.h +++ b/src/widget/wlibrarytextbrowser.h @@ -10,4 +10,5 @@ class WLibraryTextBrowser : public QTextBrowser, public LibraryView { explicit WLibraryTextBrowser(QWidget* parent = nullptr); void onShow() override {} bool hasFocus() const override; + void setFocus() override; }; diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index d145808822be..756ff8e491b0 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -1028,6 +1028,10 @@ bool WTrackTableView::hasFocus() const { return QWidget::hasFocus(); } +void WTrackTableView::setFocus() { + QWidget::setFocus(); +} + void WTrackTableView::saveCurrentVScrollBarPos() { saveVScrollBarPos(getTrackModel()); } diff --git a/src/widget/wtracktableview.h b/src/widget/wtracktableview.h index 9db21a36d23b..46291e59f0a7 100644 --- a/src/widget/wtracktableview.h +++ b/src/widget/wtracktableview.h @@ -32,6 +32,7 @@ class WTrackTableView : public WLibraryTableView { void onSearch(const QString& text) override; void onShow() override; bool hasFocus() const override; + void setFocus() override; void keyPressEvent(QKeyEvent* event) override; void loadSelectedTrack() override; void loadSelectedTrackToGroup(const QString& group, bool play) override; From 94f324bd2b6fcac896f4e6adba11ed2dfef5e732 Mon Sep 17 00:00:00 2001 From: ronso0 Date: Thu, 14 Oct 2021 16:21:15 +0200 Subject: [PATCH 2/2] library: add CO to read and set the currently focused library widget --- src/library/browse/browsefeature.cpp | 1 + src/library/library.cpp | 21 ++++++ src/library/library.h | 2 + src/library/library_decl.h | 9 +++ src/library/librarycontrol.cpp | 73 +++++++++++++++++--- src/library/librarycontrol.h | 6 +- src/library/rekordbox/rekordboxfeature.cpp | 1 + src/library/serato/seratofeature.cpp | 1 + src/library/trackset/baseplaylistfeature.cpp | 1 + src/library/trackset/crate/cratefeature.cpp | 1 + src/widget/wlibrarysidebar.cpp | 12 +++- src/widget/wlibrarysidebar.h | 6 +- src/widget/wlibrarytextbrowser.cpp | 11 +++ src/widget/wlibrarytextbrowser.h | 8 +++ src/widget/wsearchlineedit.cpp | 3 + src/widget/wsearchlineedit.h | 2 + src/widget/wtracktableview.cpp | 11 +++ src/widget/wtracktableview.h | 8 +++ 18 files changed, 162 insertions(+), 15 deletions(-) diff --git a/src/library/browse/browsefeature.cpp b/src/library/browse/browsefeature.cpp index 6512b27be014..97653ef41d05 100644 --- a/src/library/browse/browsefeature.cpp +++ b/src/library/browse/browsefeature.cpp @@ -222,6 +222,7 @@ void BrowseFeature::bindLibraryWidget(WLibrary* libraryWidget, WLibraryTextBrowser* edit = new WLibraryTextBrowser(libraryWidget); edit->setHtml(getRootViewHtml()); libraryWidget->registerView("BROWSEHOME", edit); + m_pLibrary->bindFeatureRootView(edit); } void BrowseFeature::bindSidebarWidget(WLibrarySidebar* pSidebarWidget) { diff --git a/src/library/library.cpp b/src/library/library.cpp index bf48d9a33f27..a3f5d4209c7f 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -43,6 +43,7 @@ #include "util/sandbox.h" #include "widget/wlibrary.h" #include "widget/wlibrarysidebar.h" +#include "widget/wlibrarytextbrowser.h" #include "widget/wsearchlineedit.h" #include "widget/wtracktableview.h" @@ -288,6 +289,10 @@ void Library::bindSearchboxWidget(WSearchLineEdit* pSearchboxWidget) { &WSearchLineEdit::slotSetFont); emit setTrackTableFont(m_trackTableFont); m_pLibraryControl->bindSearchboxWidget(pSearchboxWidget); + connect(pSearchboxWidget, + &WSearchLineEdit::searchbarFocusChange, + m_pLibraryControl, + &LibraryControl::setLibraryFocus); } void Library::bindSidebarWidget(WLibrarySidebar* pSidebarWidget) { @@ -318,6 +323,11 @@ void Library::bindSidebarWidget(WLibrarySidebar* pSidebarWidget) { m_pSidebarModel, &SidebarModel::rightClicked); + connect(pSidebarWidget, + &WLibrarySidebar::sidebarFocusChange, + m_pLibraryControl, + &LibraryControl::setLibraryFocus); + pSidebarWidget->slotSetFont(m_trackTableFont); connect(this, &Library::setTrackTableFont, @@ -375,6 +385,10 @@ void Library::bindLibraryWidget( &WTrackTableView::setSelectedClick); m_pLibraryControl->bindLibraryWidget(pLibraryWidget, pKeyboard); + connect(pTrackTableView, + &WTrackTableView::trackTableFocusChange, + m_pLibraryControl, + &LibraryControl::setLibraryFocus); for (const auto& feature : qAsConst(m_features)) { feature->bindLibraryWidget(pLibraryWidget, pKeyboard); @@ -387,6 +401,13 @@ void Library::bindLibraryWidget( emit setSelectedClick(m_editMetadataSelectedClick); } +void Library::bindFeatureRootView(WLibraryTextBrowser* pTextBrowser) { + connect(pTextBrowser, + &WLibraryTextBrowser::textBrowserFocusChange, + m_pLibraryControl, + &LibraryControl::setLibraryFocus); +} + void Library::addFeature(LibraryFeature* feature) { VERIFY_OR_DEBUG_ASSERT(feature) { return; diff --git a/src/library/library.h b/src/library/library.h index 83dda1bb1cff..6ad97f4a5220 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -36,6 +36,7 @@ class TrackModel; class WSearchLineEdit; class WLibrarySidebar; class WLibrary; +class WLibraryTextBrowser; #ifdef __ENGINEPRIME__ namespace mixxx { @@ -69,6 +70,7 @@ class Library: public QObject { void bindSidebarWidget(WLibrarySidebar* sidebarWidget); void bindLibraryWidget(WLibrary* libraryWidget, KeyboardEventFilter* pKeyboard); + void bindFeatureRootView(WLibraryTextBrowser* pTextBrowser); void addFeature(LibraryFeature* feature); diff --git a/src/library/library_decl.h b/src/library/library_decl.h index 64fbc2452c58..9b278f9adbaa 100644 --- a/src/library/library_decl.h +++ b/src/library/library_decl.h @@ -7,3 +7,12 @@ enum class LibraryRemovalType { HideTracks, PurgeTracks }; + +enum class FocusWidget { + None, + Searchbar, + Sidebar, + TracksTable, // or a feature root view (WLibraryTextBrowser) + Count // used for setting the number of PushButton states of + // m_pLibraryFocusedWidgetCO in librarycontrol.cpp +}; diff --git a/src/library/librarycontrol.cpp b/src/library/librarycontrol.cpp index 09d106544abc..b548a5f537b7 100644 --- a/src/library/librarycontrol.cpp +++ b/src/library/librarycontrol.cpp @@ -62,6 +62,7 @@ LibraryControl::LibraryControl(Library* pLibrary) m_numDecks("[Master]", "num_decks", this), m_numSamplers("[Master]", "num_samplers", this), m_numPreviewDecks("[Master]", "num_preview_decks", this) { + qRegisterMetaType("FocusWidget"); slotNumDecksChanged(m_numDecks.get()); slotNumSamplersChanged(m_numSamplers.get()); @@ -121,7 +122,8 @@ LibraryControl::LibraryControl(Library* pLibrary) this, &LibraryControl::slotMoveHorizontal); - // Control to navigate between widgets (tab/shit+tab button) + // Controls to navigate between widgets + // Relative focus controls (tab/shift+tab button) m_pMoveFocusForward = std::make_unique(ConfigKey("[Library]", "MoveFocusForward")); m_pMoveFocusBackward = std::make_unique(ConfigKey("[Library]", "MoveFocusBackward")); m_pMoveFocus = std::make_unique(ConfigKey("[Library]", "MoveFocus"), false); @@ -137,6 +139,25 @@ LibraryControl::LibraryControl(Library* pLibrary) &ControlEncoder::valueChanged, this, &LibraryControl::slotMoveFocus); + // Direct focus control, read/write + m_pLibraryFocusedWidgetCO = std::make_unique( + ConfigKey("[Library]", "focused_widget")); + m_pLibraryFocusedWidgetCO->setStates(static_cast(FocusWidget::Count)); + m_pLibraryFocusedWidgetCO->connectValueChangeRequest( + this, + [this](double value) { + // Focus can not be removed from a widget just moved to another one. + // Thus, to keep the CO and QApplication::focusWidget() in sync we + // have to prevent scripts or GUI buttons setting the CO to 'None'. + // It's only set to 'None' internally when one of the library widgets + // receives a FocusOutEvent(), e.g. when the focus is moved to another + // widget, or when the main window loses focus. + const int valueInt = static_cast(value); + if (valueInt != static_cast(FocusWidget::None) && + valueInt < static_cast(FocusWidget::Count)) { + setLibraryFocus(static_cast(valueInt)); + } + }); // Control to "goto" the currently selected item in focused widget (context dependent) m_pGoToItem = std::make_unique(ConfigKey("[Library]", "GoToItem")); @@ -355,7 +376,6 @@ void LibraryControl::slotNumSamplersChanged(double v) { } } - void LibraryControl::slotNumPreviewDecksChanged(double v) { int iNumPreviewDecks = static_cast(v); @@ -406,8 +426,6 @@ void LibraryControl::bindSearchboxWidget(WSearchLineEdit* pSearchbox) { &LibraryControl::searchboxWidgetDeleted); } - - void LibraryControl::libraryWidgetDeleted() { m_pLibraryWidget = nullptr; } @@ -612,11 +630,11 @@ void LibraryControl::emitKeyEvent(QKeyEvent&& event) { if (!keyIsTab && !m_pSidebarWidget->hasFocus() && !m_pLibraryWidget->getActiveView()->hasFocus()) { if (keyIsUpDown && !m_pSearchbox->hasFocus()) { - setLibraryFocus(); + setLibraryFocus(FocusWidget::TracksTable); } } if (keyIsTab && !QApplication::focusWidget()){ - setLibraryFocus(); + setLibraryFocus(FocusWidget::TracksTable); } // Send the event pointer to the currently focused widget @@ -628,11 +646,44 @@ void LibraryControl::emitKeyEvent(QKeyEvent&& event) { } } -void LibraryControl::setLibraryFocus() { - VERIFY_OR_DEBUG_ASSERT(m_pLibraryWidget) { +void LibraryControl::setLibraryFocus(FocusWidget newFocusWidget) { + // ignore no-op + if (static_cast(newFocusWidget) == m_pLibraryFocusedWidgetCO->get()) { return; } - m_pLibraryWidget->getActiveView()->setFocus(); + bool confirmed = false; + switch (newFocusWidget) { + case FocusWidget::Searchbar: + VERIFY_OR_DEBUG_ASSERT(m_pSearchbox) { + return; + } + m_pSearchbox->setFocus(); + confirmed = m_pSearchbox->hasFocus(); + break; + case FocusWidget::Sidebar: + VERIFY_OR_DEBUG_ASSERT(m_pSidebarWidget) { + return; + } + m_pSidebarWidget->setFocus(); + confirmed = m_pSidebarWidget->hasFocus(); + break; + case FocusWidget::TracksTable: + VERIFY_OR_DEBUG_ASSERT(m_pLibraryWidget) { + return; + } + m_pLibraryWidget->getActiveView()->setFocus(); + confirmed = m_pLibraryWidget->getActiveView()->hasFocus(); + break; + case FocusWidget::None: + confirmed = true; + break; + default: + DEBUG_ASSERT(!"Invalid focus widget change request"); + break; + } + if (confirmed) { + m_pLibraryFocusedWidgetCO->setAndConfirm(static_cast(newFocusWidget)); + } } void LibraryControl::slotSelectSidebarItem(double v) { @@ -694,7 +745,7 @@ void LibraryControl::slotGoToItem(double v) { // expanding those root items via controllers is considered dispensable // because the subfeatures' actions can't be accessed by controllers anyway. if (m_pSidebarWidget->isLeafNodeSelected()) { - setLibraryFocus(); + setLibraryFocus(FocusWidget::TracksTable); return; } else { // Otherwise toggle the sidebar item expanded state @@ -711,7 +762,7 @@ void LibraryControl::slotGoToItem(double v) { // If searchbox has focus jump to the tracks table if (m_pSearchbox->hasFocus()) { - return setLibraryFocus(); + return setLibraryFocus(FocusWidget::TracksTable); } // Clear the search if the searchbox has focus diff --git a/src/library/librarycontrol.h b/src/library/librarycontrol.h index 396f841d47ff..32204fa4f589 100644 --- a/src/library/librarycontrol.h +++ b/src/library/librarycontrol.h @@ -4,6 +4,7 @@ #include "control/controlencoder.h" #include "control/controlproxy.h" +#include "library/library_decl.h" #include "util/memory.h" class ControlObject; @@ -43,6 +44,8 @@ class LibraryControl : public QObject { void bindLibraryWidget(WLibrary* pLibrary, KeyboardEventFilter* pKeyboard); void bindSidebarWidget(WLibrarySidebar* pLibrarySidebar); void bindSearchboxWidget(WSearchLineEdit* pSearchbox); + // Give the keyboard focus to one of the library widgets + void setLibraryFocus(FocusWidget newFocusWidget); signals: void clearSearchIfClearButtonHasFocus(); @@ -103,8 +106,6 @@ class LibraryControl : public QObject { // Simulate pressing a key on the keyboard void emitKeyEvent(QKeyEvent&& event); - // Give the keyboard focus to the main library pane - void setLibraryFocus(); // Controls to navigate vertically within currently focused widget (up/down buttons) std::unique_ptr m_pMoveUp; @@ -125,6 +126,7 @@ class LibraryControl : public QObject { std::unique_ptr m_pMoveFocusForward; std::unique_ptr m_pMoveFocusBackward; std::unique_ptr m_pMoveFocus; + std::unique_ptr m_pLibraryFocusedWidgetCO; // Control to choose the currently selected item in focused widget (double click) std::unique_ptr m_pGoToItem; diff --git a/src/library/rekordbox/rekordboxfeature.cpp b/src/library/rekordbox/rekordboxfeature.cpp index 12e53f62eb8a..faff4c2d69bd 100644 --- a/src/library/rekordbox/rekordboxfeature.cpp +++ b/src/library/rekordbox/rekordboxfeature.cpp @@ -1421,6 +1421,7 @@ void RekordboxFeature::bindLibraryWidget(WLibrary* libraryWidget, edit->setOpenLinks(false); connect(edit, &WLibraryTextBrowser::anchorClicked, this, &RekordboxFeature::htmlLinkClicked); libraryWidget->registerView("REKORDBOXHOME", edit); + m_pLibrary->bindFeatureRootView(edit); } void RekordboxFeature::htmlLinkClicked(const QUrl& link) { diff --git a/src/library/serato/seratofeature.cpp b/src/library/serato/seratofeature.cpp index f068d9347c0e..078c54a32232 100644 --- a/src/library/serato/seratofeature.cpp +++ b/src/library/serato/seratofeature.cpp @@ -937,6 +937,7 @@ void SeratoFeature::bindLibraryWidget(WLibrary* libraryWidget, edit->setOpenLinks(false); connect(edit, &WLibraryTextBrowser::anchorClicked, this, &SeratoFeature::htmlLinkClicked); libraryWidget->registerView("SERATOHOME", edit); + m_pLibrary->bindFeatureRootView(edit); } void SeratoFeature::htmlLinkClicked(const QUrl& link) { diff --git a/src/library/trackset/baseplaylistfeature.cpp b/src/library/trackset/baseplaylistfeature.cpp index ea98f2cd26ba..1bc39886bfa1 100644 --- a/src/library/trackset/baseplaylistfeature.cpp +++ b/src/library/trackset/baseplaylistfeature.cpp @@ -670,6 +670,7 @@ void BasePlaylistFeature::bindLibraryWidget(WLibrary* libraryWidget, this, &BasePlaylistFeature::htmlLinkClicked); libraryWidget->registerView(m_rootViewName, edit); + m_pLibrary->bindFeatureRootView(edit); } void BasePlaylistFeature::bindSidebarWidget(WLibrarySidebar* pSidebarWidget) { diff --git a/src/library/trackset/crate/cratefeature.cpp b/src/library/trackset/crate/cratefeature.cpp index 3c9b81b897af..d015dae3d5c8 100644 --- a/src/library/trackset/crate/cratefeature.cpp +++ b/src/library/trackset/crate/cratefeature.cpp @@ -270,6 +270,7 @@ void CrateFeature::bindLibraryWidget( this, &CrateFeature::htmlLinkClicked); libraryWidget->registerView(m_rootViewName, edit); + m_pLibrary->bindFeatureRootView(edit); } void CrateFeature::bindSidebarWidget(WLibrarySidebar* pSidebarWidget) { diff --git a/src/widget/wlibrarysidebar.cpp b/src/widget/wlibrarysidebar.cpp index eaeef3abe106..2e392afe6474 100644 --- a/src/widget/wlibrarysidebar.cpp +++ b/src/widget/wlibrarysidebar.cpp @@ -15,6 +15,7 @@ constexpr int expand_time = 250; WLibrarySidebar::WLibrarySidebar(QWidget* parent) : QTreeView(parent), WBaseWidget(this) { + qRegisterMetaType("FocusWidget"); //Set some properties setHeaderHidden(true); setSelectionMode(QAbstractItemView::SingleSelection); @@ -155,7 +156,6 @@ void WLibrarySidebar::dropEvent(QDropEvent * event) { } } - void WLibrarySidebar::toggleSelectedItem() { QModelIndexList selectedIndices = this->selectionModel()->selectedRows(); if (selectedIndices.size() > 0) { @@ -289,6 +289,16 @@ bool WLibrarySidebar::event(QEvent* pEvent) { return QTreeView::event(pEvent); } +void WLibrarySidebar::focusInEvent(QFocusEvent* event) { + QTreeView::focusInEvent(event); + emit sidebarFocusChange(FocusWidget::Sidebar); +} + +void WLibrarySidebar::focusOutEvent(QFocusEvent* event) { + QTreeView::focusOutEvent(event); + emit sidebarFocusChange(FocusWidget::None); +} + void WLibrarySidebar::slotSetFont(const QFont& font) { setFont(font); // Resize the feature icons to be a bit taller than the label's capital diff --git a/src/widget/wlibrarysidebar.h b/src/widget/wlibrarysidebar.h index 3e97e003e123..ea17baf36e07 100644 --- a/src/widget/wlibrarysidebar.h +++ b/src/widget/wlibrarysidebar.h @@ -4,13 +4,14 @@ #include #include #include +#include #include #include #include #include #include -#include +#include "library/library_decl.h" #include "widget/wbasewidget.h" class WLibrarySidebar : public QTreeView, public WBaseWidget { @@ -34,9 +35,12 @@ class WLibrarySidebar : public QTreeView, public WBaseWidget { signals: void rightClicked(const QPoint&, const QModelIndex&); + FocusWidget sidebarFocusChange(FocusWidget newFocus); protected: bool event(QEvent* pEvent) override; + void focusInEvent(QFocusEvent*) override; + void focusOutEvent(QFocusEvent*) override; private: QBasicTimer m_expandTimer; diff --git a/src/widget/wlibrarytextbrowser.cpp b/src/widget/wlibrarytextbrowser.cpp index 82d35ed6e5b9..eac3cf596f16 100644 --- a/src/widget/wlibrarytextbrowser.cpp +++ b/src/widget/wlibrarytextbrowser.cpp @@ -4,6 +4,7 @@ WLibraryTextBrowser::WLibraryTextBrowser(QWidget* parent) : QTextBrowser(parent) { + qRegisterMetaType("FocusWidget"); } bool WLibraryTextBrowser::hasFocus() const { @@ -13,3 +14,13 @@ bool WLibraryTextBrowser::hasFocus() const { void WLibraryTextBrowser::setFocus() { QWidget::setFocus(); } + +void WLibraryTextBrowser::focusInEvent(QFocusEvent* event) { + QWidget::focusInEvent(event); + emit textBrowserFocusChange(FocusWidget::TracksTable); +} + +void WLibraryTextBrowser::focusOutEvent(QFocusEvent* event) { + QWidget::focusOutEvent(event); + emit textBrowserFocusChange(FocusWidget::None); +} diff --git a/src/widget/wlibrarytextbrowser.h b/src/widget/wlibrarytextbrowser.h index 206664f0693f..ad610e7db93f 100644 --- a/src/widget/wlibrarytextbrowser.h +++ b/src/widget/wlibrarytextbrowser.h @@ -2,6 +2,7 @@ #include +#include "library/library_decl.h" #include "library/libraryview.h" class WLibraryTextBrowser : public QTextBrowser, public LibraryView { @@ -11,4 +12,11 @@ class WLibraryTextBrowser : public QTextBrowser, public LibraryView { void onShow() override {} bool hasFocus() const override; void setFocus() override; + + protected: + void focusInEvent(QFocusEvent* event) override; + void focusOutEvent(QFocusEvent* event) override; + + signals: + FocusWidget textBrowserFocusChange(FocusWidget newFocus); }; diff --git a/src/widget/wsearchlineedit.cpp b/src/widget/wsearchlineedit.cpp index d00fdbfb4bd0..82c6486e9140 100644 --- a/src/widget/wsearchlineedit.cpp +++ b/src/widget/wsearchlineedit.cpp @@ -78,6 +78,7 @@ WSearchLineEdit::WSearchLineEdit(QWidget* pParent) : QComboBox(pParent), WBaseWidget(this), m_clearButton(make_parented(this)) { + qRegisterMetaType("FocusWidget"); setAcceptDrops(false); setEditable(true); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); @@ -326,6 +327,7 @@ void WSearchLineEdit::focusInEvent(QFocusEvent* event) { << "focusInEvent"; #endif // ENABLE_TRACE_LOG QComboBox::focusInEvent(event); + emit searchbarFocusChange(FocusWidget::Searchbar); } void WSearchLineEdit::focusOutEvent(QFocusEvent* event) { @@ -334,6 +336,7 @@ void WSearchLineEdit::focusOutEvent(QFocusEvent* event) { << "focusOutEvent"; #endif // ENABLE_TRACE_LOG QComboBox::focusOutEvent(event); + emit searchbarFocusChange(FocusWidget::None); if (m_debouncingTimer.isActive()) { // Trigger a pending search before leaving the edit box. // Otherwise the entered text might be ignored and get lost diff --git a/src/widget/wsearchlineedit.h b/src/widget/wsearchlineedit.h index 9709cc8a579c..1250bc0b591d 100644 --- a/src/widget/wsearchlineedit.h +++ b/src/widget/wsearchlineedit.h @@ -6,6 +6,7 @@ #include #include +#include "library/library_decl.h" #include "util/parented_ptr.h" #include "widget/wbasewidget.h" @@ -39,6 +40,7 @@ class WSearchLineEdit : public QComboBox, public WBaseWidget { signals: void search(const QString& text); + FocusWidget searchbarFocusChange(FocusWidget newFocusWidget); public slots: void slotSetFont(const QFont& font); diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index 756ff8e491b0..a110ec054a08 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -60,6 +60,7 @@ WTrackTableView::WTrackTableView(QWidget* parent, m_sorting(sorting), m_selectionChangedSinceLastGuiTick(true), m_loadCachedOnly(false) { + qRegisterMetaType("FocusWidget"); // Connect slots and signals to make the world go 'round. connect(this, &WTrackTableView::doubleClicked, this, &WTrackTableView::slotMouseDoubleClicked); @@ -1024,6 +1025,16 @@ void WTrackTableView::slotSortingChanged(int headerSection, Qt::SortOrder order) } } +void WTrackTableView::focusInEvent(QFocusEvent* event) { + QWidget::focusInEvent(event); + emit trackTableFocusChange(FocusWidget::TracksTable); +} + +void WTrackTableView::focusOutEvent(QFocusEvent* event) { + QWidget::focusOutEvent(event); + emit trackTableFocusChange(FocusWidget::None); +} + bool WTrackTableView::hasFocus() const { return QWidget::hasFocus(); } diff --git a/src/widget/wtracktableview.h b/src/widget/wtracktableview.h index 46291e59f0a7..bd69533c79aa 100644 --- a/src/widget/wtracktableview.h +++ b/src/widget/wtracktableview.h @@ -5,6 +5,7 @@ #include "control/controlproxy.h" #include "library/dao/playlistdao.h" +#include "library/library_decl.h" #include "library/trackmodel.h" // Can't forward declare enums #include "preferences/usersettings.h" #include "util/duration.h" @@ -53,6 +54,9 @@ class WTrackTableView : public WLibraryTableView { return m_pFocusBorderColor; } + signals: + void trackTableFocusChange(FocusWidget newFocusWidget); + public slots: void loadTrackModel(QAbstractItemModel* model); void slotMouseDoubleClicked(const QModelIndex &); @@ -63,6 +67,10 @@ class WTrackTableView : public WLibraryTableView { void slotAddToAutoDJTop() override; void slotAddToAutoDJReplace() override; + protected: + void focusInEvent(QFocusEvent* event) override; + void focusOutEvent(QFocusEvent* event) override; + private slots: void doSortByColumn(int headerSection, Qt::SortOrder sortOrder); void applySortingIfVisible();