From 616c462c5c86167cd9412c8f7f7c50c310e6d482 Mon Sep 17 00:00:00 2001 From: Roman Pudashkin Date: Wed, 23 Mar 2022 16:43:50 +0200 Subject: [PATCH] fix #10477: introduced a new way to determine if panels can be combined into tabs --- .../qml/NotationPage/NotationPage.qml | 19 ++++-- src/appshell/view/dockwindow/dockpageview.cpp | 61 +++---------------- src/appshell/view/dockwindow/dockpageview.h | 3 +- .../view/dockwindow/dockpanelview.cpp | 41 +++++++++++-- src/appshell/view/dockwindow/dockpanelview.h | 13 ++-- src/appshell/view/dockwindow/dockwindow.cpp | 8 +-- .../dockwindow/internal/dropcontroller.cpp | 12 ++-- .../view/dockwindow/internal/dropcontroller.h | 2 +- 8 files changed, 73 insertions(+), 86 deletions(-) diff --git a/src/appshell/qml/NotationPage/NotationPage.qml b/src/appshell/qml/NotationPage/NotationPage.qml index fb7e63a2deec..4af6ad489ab2 100644 --- a/src/appshell/qml/NotationPage/NotationPage.qml +++ b/src/appshell/qml/NotationPage/NotationPage.qml @@ -95,6 +95,9 @@ DockPage { readonly property int horizontalPanelMinHeight: 100 readonly property int horizontalPanelMaxHeight: 520 + readonly property string verticalPanelsGroup: "VERTICAL_PANELS" + readonly property string horizontalPanelsGroup: "HORIZONTAL_PANELS" + readonly property var verticalPanelDropDestinations: [ { "dock": root.centralDock, "dropLocation": Location.Left, "dropDistance": root.verticalPanelDefaultWidth }, { "dock": root.centralDock, "dropLocation": Location.Right, "dropDistance": root.verticalPanelDefaultWidth } @@ -213,7 +216,7 @@ DockPage { minimumWidth: root.verticalPanelDefaultWidth maximumWidth: root.verticalPanelDefaultWidth - tabifyPanel: instrumentsPanel + groupName: root.verticalPanelsGroup dropDestinations: root.verticalPanelDropDestinations @@ -238,7 +241,7 @@ DockPage { minimumWidth: root.verticalPanelDefaultWidth maximumWidth: root.verticalPanelDefaultWidth - tabifyPanel: inspectorPanel + groupName: root.verticalPanelsGroup dropDestinations: root.verticalPanelDropDestinations @@ -262,8 +265,8 @@ DockPage { width: root.verticalPanelDefaultWidth minimumWidth: root.verticalPanelDefaultWidth maximumWidth: root.verticalPanelDefaultWidth - - tabifyPanel: selectionFilterPanel + + groupName: root.verticalPanelsGroup dropDestinations: root.verticalPanelDropDestinations @@ -284,6 +287,8 @@ DockPage { minimumWidth: root.verticalPanelDefaultWidth maximumWidth: root.verticalPanelDefaultWidth + groupName: root.verticalPanelsGroup + //! NOTE: hidden by default visible: false @@ -308,7 +313,7 @@ DockPage { minimumHeight: root.horizontalPanelMinHeight maximumHeight: root.horizontalPanelMaxHeight - tabifyPanel: pianoKeyboardPanel + groupName: root.horizontalPanelsGroup //! NOTE: hidden by default visible: false @@ -342,7 +347,7 @@ DockPage { minimumHeight: root.horizontalPanelMinHeight maximumHeight: root.horizontalPanelMaxHeight - tabifyPanel: timelinePanel + groupName: root.horizontalPanelsGroup //! NOTE: hidden by default visible: false @@ -368,6 +373,8 @@ DockPage { minimumHeight: root.horizontalPanelMinHeight maximumHeight: root.horizontalPanelMaxHeight + groupName: root.horizontalPanelsGroup + //! NOTE: hidden by default visible: false diff --git a/src/appshell/view/dockwindow/dockpageview.cpp b/src/appshell/view/dockwindow/dockpageview.cpp index f24989898f32..c3d078452c26 100644 --- a/src/appshell/view/dockwindow/dockpageview.cpp +++ b/src/appshell/view/dockwindow/dockpageview.cpp @@ -155,51 +155,17 @@ DockingHolderView* DockPageView::holder(DockType type, Location location) const return nullptr; } -QList DockPageView::possibleTabs(const DockPanelView* panel) const +QList DockPageView::possiblePanelsForTab(const DockPanelView* tab) const { - QList tabs; + QList result; - auto isPanelAllowedAsTab = [panel](const DockPanelView* p) { - if (!p || p == panel) { - return false; - } - - return p->isOpen() && !p->floating(); - }; - - DockPanelView* rootPanel = findRootPanel(panel); - DockPanelView* nextPanel = rootPanel ? rootPanel->tabifyPanel() : nullptr; - - while (nextPanel) { - if (isPanelAllowedAsTab(nextPanel)) { - tabs << nextPanel; - } - - nextPanel = nextPanel->tabifyPanel(); - } - - if (!tabs.contains(rootPanel) && isPanelAllowedAsTab(rootPanel)) { - tabs.prepend(rootPanel); - } - - return tabs; -} - -DockPanelView* DockPageView::findRootPanel(const DockPanelView* panel) const -{ - for (DockPanelView* panel_ : panels()) { - DockPanelView* tabifyPanel = panel_->tabifyPanel(); - - while (tabifyPanel) { - if (tabifyPanel == panel) { - return panel_; - } - - tabifyPanel = tabifyPanel->tabifyPanel(); + for (DockPanelView* panel : panels()) { + if (panel->isTabAllowed(tab)) { + result << panel; } } - return const_cast(panel); + return result; } bool DockPageView::isDockOpen(const QString& dockName) const @@ -241,19 +207,8 @@ void DockPageView::setDockOpen(const QString& dockName, bool open) DockPanelView* DockPageView::findPanelForTab(const DockPanelView* tab) const { - for (DockPanelView* panel : panels()) { - if (panel->tabifyPanel() != tab) { - continue; - } - - if (panel->isOpen() && !panel->floating()) { - return panel; - } - - return findPanelForTab(panel); - } - - return nullptr; + QList panels = possiblePanelsForTab(tab); + return !panels.isEmpty() ? panels.first() : nullptr; } bool DockPageView::isDockFloating(const QString& dockName) const diff --git a/src/appshell/view/dockwindow/dockpageview.h b/src/appshell/view/dockwindow/dockpageview.h index 08cf7b172596..20af0438d473 100644 --- a/src/appshell/view/dockwindow/dockpageview.h +++ b/src/appshell/view/dockwindow/dockpageview.h @@ -75,7 +75,7 @@ class DockPageView : public QQuickItem DockBase* dockByName(const QString& dockName) const; DockingHolderView* holder(DockType type, Location location) const; - QList possibleTabs(const DockPanelView* panel) const; + QList possiblePanelsForTab(const DockPanelView* tab) const; bool isDockOpen(const QString& dockName) const; void toggleDock(const QString& dockName); @@ -100,7 +100,6 @@ public slots: void componentComplete() override; DockPanelView* findPanelForTab(const DockPanelView* tab) const; - DockPanelView* findRootPanel(const DockPanelView* panel) const; QString m_uri; uicomponents::QmlListProperty m_mainToolBars; diff --git a/src/appshell/view/dockwindow/dockpanelview.cpp b/src/appshell/view/dockwindow/dockpanelview.cpp index c66653611874..2412dc504116 100644 --- a/src/appshell/view/dockwindow/dockpanelview.cpp +++ b/src/appshell/view/dockwindow/dockpanelview.cpp @@ -164,19 +164,19 @@ DockPanelView::~DockPanelView() dockWidget->setProperty(CONTEXT_MENU_MODEL_PROPERTY, QVariant::fromValue(nullptr)); } -DockPanelView* DockPanelView::tabifyPanel() const +QString DockPanelView::groupName() const { - return m_tabifyPanel; + return m_groupName; } -void DockPanelView::setTabifyPanel(DockPanelView* panel) +void DockPanelView::setGroupName(const QString& name) { - if (panel == m_tabifyPanel) { + if (m_groupName == name) { return; } - m_tabifyPanel = panel; - emit tabifyPanelChanged(panel); + m_groupName = name; + emit groupNameChanged(); } DockType DockPanelView::type() const @@ -236,12 +236,41 @@ void DockPanelView::setContextMenuModel(AbstractMenuModel* model) emit contextMenuModelChanged(); } +bool DockPanelView::isTabAllowed(const DockPanelView* tab) const +{ + IF_ASSERT_FAILED(tab) { + return false; + } + + if (tab == this) { + return false; + } + + if (!isOpen()) { + return false; + } + + if (floating()) { + return false; + } + + if (m_groupName.isEmpty() || tab->m_groupName.isEmpty()) { + return false; + } + + return m_groupName == tab->m_groupName; +} + void DockPanelView::addPanelAsTab(DockPanelView* tab) { IF_ASSERT_FAILED(tab && dockWidget()) { return; } + if (!isTabAllowed(tab)) { + return; + } + dockWidget()->addDockWidgetAsTab(tab->dockWidget()); tab->setVisible(true); } diff --git a/src/appshell/view/dockwindow/dockpanelview.h b/src/appshell/view/dockwindow/dockpanelview.h index 4765ba6026e9..b891dc9feb8a 100644 --- a/src/appshell/view/dockwindow/dockpanelview.h +++ b/src/appshell/view/dockwindow/dockpanelview.h @@ -38,7 +38,7 @@ class DockPanelView : public DockBase { Q_OBJECT - Q_PROPERTY(DockPanelView * tabifyPanel READ tabifyPanel WRITE setTabifyPanel NOTIFY tabifyPanelChanged) + Q_PROPERTY(QString groupName READ groupName WRITE setGroupName NOTIFY groupNameChanged) Q_PROPERTY(QObject * navigationSection READ navigationSection WRITE setNavigationSection NOTIFY navigationSectionChanged) Q_PROPERTY( mu::uicomponents::AbstractMenuModel @@ -46,22 +46,23 @@ class DockPanelView : public DockBase public: explicit DockPanelView(QQuickItem* parent = nullptr); - ~DockPanelView(); + ~DockPanelView() override; - DockPanelView* tabifyPanel() const; + QString groupName() const; QObject* navigationSection() const; uicomponents::AbstractMenuModel* contextMenuModel() const; + bool isTabAllowed(const DockPanelView* tab) const; void addPanelAsTab(DockPanelView* tab); void setCurrentTabIndex(int index); public slots: - void setTabifyPanel(DockPanelView* panel); + void setGroupName(const QString& name); void setNavigationSection(QObject* newNavigation); void setContextMenuModel(uicomponents::AbstractMenuModel* model); signals: - void tabifyPanelChanged(DockPanelView* panel); + void groupNameChanged(); void navigationSectionChanged(); void contextMenuModelChanged(); @@ -69,7 +70,7 @@ public slots: DockType type() const override; void componentComplete() override; - DockPanelView* m_tabifyPanel = nullptr; + QString m_groupName; QObject* m_navigationSection = nullptr; class DockPanelMenuModel; diff --git a/src/appshell/view/dockwindow/dockwindow.cpp b/src/appshell/view/dockwindow/dockwindow.cpp index 281b1f16a179..8eecaaf815fe 100644 --- a/src/appshell/view/dockwindow/dockwindow.cpp +++ b/src/appshell/view/dockwindow/dockwindow.cpp @@ -349,13 +349,9 @@ void DockWindow::loadPanels(const DockPageView* page) { TRACEFUNC; - auto canAddAsTab = [](const DockPanelView* panel, const DockPanelView* destination) { - return panel->isVisible() && destination->isOpen() && destination->tabifyPanel() == panel; - }; - - auto addPanel = [this, page, canAddAsTab](DockPanelView* panel, Location location) { + auto addPanel = [this, page](DockPanelView* panel, Location location) { for (DockPanelView* destinationPanel : page->panels()) { - if (canAddAsTab(panel, destinationPanel)) { + if (destinationPanel->isTabAllowed(panel)) { registerDock(panel); destinationPanel->addPanelAsTab(panel); diff --git a/src/appshell/view/dockwindow/internal/dropcontroller.cpp b/src/appshell/view/dockwindow/internal/dropcontroller.cpp index 23883c6b9fb0..8f2f490ef3bf 100644 --- a/src/appshell/view/dockwindow/internal/dropcontroller.cpp +++ b/src/appshell/view/dockwindow/internal/dropcontroller.cpp @@ -252,7 +252,7 @@ DropDestination DropController::resolveDropDestination(const DockBase* draggedDo if (draggedDock->type() == DockType::Panel) { DropDestination destination; - destination.dock = resolveTabifyPanel(dynamic_cast(draggedDock), localPos); + destination.dock = resolvePanelForDrop(dynamic_cast(draggedDock), localPos); destination.dropLocation = resolveDropLocation(destination.dock, localPos); if (destination.isValid()) { @@ -304,13 +304,13 @@ DockingHolderView* DropController::resolveDockingHolder(DockType draggedDockType return nullptr; } -DockPanelView* DropController::resolveTabifyPanel(const DockPanelView* panel, const QPoint& localPos) const +DockPanelView* DropController::resolvePanelForDrop(const DockPanelView* panel, const QPoint& localPos) const { - QList tabs = currentPage()->possibleTabs(panel); + QList panels = currentPage()->possiblePanelsForTab(panel); - for (DockPanelView* tab : tabs) { - if (isMouseOverDock(localPos, tab)) { - return tab; + for (DockPanelView* p : panels) { + if (isMouseOverDock(localPos, p)) { + return p; } } diff --git a/src/appshell/view/dockwindow/internal/dropcontroller.h b/src/appshell/view/dockwindow/internal/dropcontroller.h index 538275058fe2..f9a0eccf4282 100644 --- a/src/appshell/view/dockwindow/internal/dropcontroller.h +++ b/src/appshell/view/dockwindow/internal/dropcontroller.h @@ -56,7 +56,7 @@ class DropController : public KDDockWidgets::DropIndicatorOverlayInterface DropDestination resolveDropDestination(const DockBase* draggedDock, const QPoint& localPos) const; DockingHolderView* resolveDockingHolder(DockType draggedDockType, const QPoint& localPos) const; - DockPanelView* resolveTabifyPanel(const DockPanelView* panel, const QPoint& localPos) const; + DockPanelView* resolvePanelForDrop(const DockPanelView* panel, const QPoint& localPos) const; Location resolveDropLocation(const DockBase* hoveredDock, const QPoint& localPos) const; QRect resolveHighlightingRect(const DockBase* draggedDock, const DropDestination& destination) const;