diff --git a/src/DockAreaTabBar.cpp b/src/DockAreaTabBar.cpp index 6d1d3dd..75478a9 100644 --- a/src/DockAreaTabBar.cpp +++ b/src/DockAreaTabBar.cpp @@ -258,7 +258,7 @@ void CDockAreaTabBar::insertTab(int Index, CDockWidgetTab* Tab) { d->TabsLayout->insertWidget(Index, Tab); connect(Tab, SIGNAL(clicked()), this, SLOT(onTabClicked())); - connect(Tab, SIGNAL(moved()), this, SLOT(onTabMoved())); + connect(Tab, SIGNAL(moved(const QPoint&)), this, SLOT(onTabWidgetMoved(const QPoint&))); d->MenuOutdated = true; if (Index <= d->CurrentIndex) { @@ -272,8 +272,7 @@ void CDockAreaTabBar::removeTab(CDockWidgetTab* Tab) { std::cout << "CDockAreaTabBar::removeTab " << std::endl; d->TabsLayout->removeWidget(Tab); - disconnect(Tab, SIGNAL(clicked()), this, SLOT(onTabClicked())); - disconnect(Tab, SIGNAL(moved()), this, SLOT(onTabMoved())); + Tab->disconnect(this); d->MenuOutdated = true; } @@ -313,51 +312,75 @@ void CDockAreaTabBar::onTabClicked() //=========================================================================== -void CDockAreaTabBar::onTabMoved() +CDockWidgetTab* CDockAreaTabBar::tab(int Index) const { - CDockWidgetTab* Tab = qobject_cast(sender()); - if (!Tab) + if (Index >= count()) + { + return 0; + } + return qobject_cast(d->TabsLayout->itemAt(Index)->widget()); +} + + +//=========================================================================== +void CDockAreaTabBar::onTabWidgetMoved(const QPoint& GlobalPos) +{ + CDockWidgetTab* MovingTab = qobject_cast(sender()); + if (!MovingTab) { return; } + int fromIndex = d->TabsLayout->indexOf(MovingTab); + auto MousePos = mapFromGlobal(GlobalPos); + int toIndex = -1; // Find tab under mouse - int fromIndex = d->TabsLayout->indexOf(Tab); - std::cout << "d->TabsLayout->count() " << count() << std::endl; for (int i = 0; i < count(); ++i) { - CDockWidgetTab* Tab2 = qobject_cast(d->TabsLayout->itemAt(i)->widget()); - if (Tab2 == Tab || !Tab) + CDockWidgetTab* DropTab = tab(i); + if (DropTab == MovingTab || !DropTab->isVisibleTo(this) + || !DropTab->geometry().contains(MousePos)) { continue; } - std::cout << "Tab.left " << Tab->pos().x() << " Tab2.left " << Tab2->pos().x() - << std::endl; + + toIndex = d->TabsLayout->indexOf(DropTab); + if (toIndex == fromIndex) + { + toIndex = -1; + continue; + } + + if (toIndex < 0) + { + toIndex = 0; + } + break; } - -/* - * for (int i = 0; i < d->ContentsLayout->count(); ++i) + // Now check if the mouse is behind the last tab + if (toIndex < 0) { - auto TabWidget = d->tabWidgetAt(i); - if (TabWidget->isVisible() && TabWidget->geometry().contains(p) && (!exclude || TabWidget != exclude)) + if (MousePos.x() > tab(count() - 1)->geometry().right()) { - return i; + qDebug() << "after all tabs"; + toIndex = count() - 1; + } + else + { + toIndex = fromIndex; } } - */ - std::cout << "CDockAreaTabBar::onTabMoved from " << fromIndex << std::endl; - - /*QPoint pos = d->DockArea->mapFromGlobal(ev->globalPos()); - int fromIndex = d->DockArea->index(d->DockWidget); - int toIndex = d->DockArea->indexOfContentByTitlePos(pos, this); - if (-1 == toIndex) + d->TabsLayout->removeWidget(MovingTab); + d->TabsLayout->insertWidget(toIndex, MovingTab); + if (toIndex >= 0) { - toIndex = d->DockArea->dockWidgetsCount() - 1; + qDebug() << "tabMoved from " << fromIndex << " to " << toIndex; + d->CurrentIndex = toIndex; + emit tabMoved(fromIndex, toIndex); + emit currentChanged(toIndex); } - qDebug() << "Move tab from " << fromIndex << " to " << toIndex; - d->DockArea->reorderDockWidget(fromIndex, toIndex);*/ } diff --git a/src/DockAreaTabBar.h b/src/DockAreaTabBar.h index cb6dfa8..6d09fca 100644 --- a/src/DockAreaTabBar.h +++ b/src/DockAreaTabBar.h @@ -32,7 +32,7 @@ private: private slots: void onTabClicked(); - void onTabMoved(); + void onTabWidgetMoved(const QPoint& GlobalPos); protected: virtual void wheelEvent(QWheelEvent* Event) override; @@ -100,6 +100,11 @@ public: */ CDockWidgetTab* currentTab() const; + /** + * Returns the tab with the given index + */ + CDockWidgetTab* tab(int Index) const; + public slots: /** * This property sets the index of the tab bar's visible tab @@ -135,6 +140,12 @@ signals: * The index is the index that should be closed. */ void tabCloseRequested(int index); + + /** + * This signal is emitted when the tab has moved the tab at index position + * from to index position to. + */ + void tabMoved(int from, int to); }; // class CDockAreaTabBar } // namespace ads //----------------------------------------------------------------------------- diff --git a/src/DockAreaWidget.cpp b/src/DockAreaWidget.cpp index ebc6601..9815126 100644 --- a/src/DockAreaWidget.cpp +++ b/src/DockAreaWidget.cpp @@ -380,6 +380,7 @@ void DockAreaWidgetPrivate::createTabBar() TabBar = new CDockAreaTabBar(_this); TopLayout->addWidget(TabBar, 1); _this->connect(TabBar, SIGNAL(tabBarClicked(int)), SLOT(setCurrentIndex(int))); + _this->connect(TabBar, SIGNAL(tabMoved(int, int)), SLOT(reorderDockWidget(int, int))); TabsMenuButton = new QPushButton(); TabsMenuButton->setObjectName("tabsMenuButton"); @@ -768,35 +769,13 @@ void CDockAreaWidget::reorderDockWidget(int fromIndex, int toIndex) || toIndex >= d->ContentsLayout->count() || toIndex < 0 || fromIndex == toIndex) { qDebug() << "Invalid index for tab movement" << fromIndex << toIndex; - //d->TabsLayout->update(); return; } - CDockWidget* DockWidget = dockWidget(fromIndex); - - // reorder tabs menu action to match new order of contents - auto Menu = d->TabsMenuButton->menu(); - auto TabsAction = d->dockWidgetTabAction(DockWidget); - Menu->removeAction(TabsAction); - if (toIndex >= Menu->actions().count()) - { - Menu->addAction(TabsAction); - } - else - { - Menu->insertAction(Menu->actions().at(toIndex), TabsAction); - } - - // now reorder contents and title bars - QLayoutItem* liFrom = nullptr; - /*liFrom = d->TabsLayout->takeAt(fromIndex); - d->TabsLayout->insertItem(toIndex, liFrom);*/ - //liFrom = d->ContentsLayout->takeAt(fromIndex); - //d->ContentsLayout->insertWidget(toIndex, liFrom->widget()); auto Widget = d->ContentsLayout->widget(fromIndex); d->ContentsLayout->removeWidget(Widget); d->ContentsLayout->insertWidget(toIndex, Widget); - //delete liFrom; + setCurrentIndex(d->TabBar->currentIndex()); } diff --git a/src/DockAreaWidget.h b/src/DockAreaWidget.h index 0c41caf..666425c 100644 --- a/src/DockAreaWidget.h +++ b/src/DockAreaWidget.h @@ -67,6 +67,12 @@ private slots: void onCloseButtonClicked(); void onTabsMenuAboutToShow(); + /** + * Reorder the index position of DockWidget at fromIndx to toIndex + * if a tab in the tabbar is dragged from one index to another one + */ + void reorderDockWidget(int fromIndex, int toIndex); + protected: /** * Inserts a dock widget into dock area. @@ -94,11 +100,6 @@ protected: */ int indexOfContentByTitlePos(const QPoint& pos, QWidget* exclude = nullptr) const; - /** - * Reorder the index position of DockWidget at fromIndx to toIndex. - */ - void reorderDockWidget(int fromIndex, int toIndex); - /** * Called from dock widget if it is opened or closed */ diff --git a/src/DockWidgetTab.cpp b/src/DockWidgetTab.cpp index 4ddc211..f6f526b 100644 --- a/src/DockWidgetTab.cpp +++ b/src/DockWidgetTab.cpp @@ -45,6 +45,8 @@ #include "DockOverlay.h" #include "DockManager.h" +#include + namespace ads { /** @@ -229,6 +231,7 @@ void CDockWidgetTab::mousePressEvent(QMouseEvent* ev) ev->accept(); d->DragStartMousePosition = ev->pos(); d->DragState = DraggingMousePressed; + emit clicked(); return; } QFrame::mousePressEvent(ev); @@ -240,27 +243,12 @@ void CDockWidgetTab::mousePressEvent(QMouseEvent* ev) void CDockWidgetTab::mouseReleaseEvent(QMouseEvent* ev) { qDebug() << "CDockWidgetTab::mouseReleaseEvent"; - // End of tab moving, change order now + // End of tab moving, emit signal if (d->isDraggingState(DraggingTab) && d->DockArea) { - // Find tab under mouse - /*QPoint pos = d->DockArea->mapFromGlobal(ev->globalPos()); - int fromIndex = d->DockArea->index(d->DockWidget); - int toIndex = d->DockArea->indexOfContentByTitlePos(pos, this); - if (-1 == toIndex) - { - toIndex = d->DockArea->dockWidgetsCount() - 1; - } - qDebug() << "Move tab from " << fromIndex << " to " << toIndex; - d->DockArea->reorderDockWidget(fromIndex, toIndex);*/ - emit moved(); + emit moved(ev->globalPos()); } - if (!d->DragStartMousePosition.isNull()) - { - emit clicked(); - } - d->DragStartMousePosition = QPoint(); d->DragState = DraggingInactive; QFrame::mouseReleaseEvent(ev); @@ -277,7 +265,7 @@ void CDockWidgetTab::mouseMoveEvent(QMouseEvent* ev) return; } - // move floating winwdow + // move floating window if (d->isDraggingState(DraggingFloatingWidget)) { d->FloatingWidget->moveFloating(); @@ -387,6 +375,13 @@ const QIcon& CDockWidgetTab::icon() const } +//============================================================================ +QString CDockWidgetTab::text() const +{ + return d->TitleLabel->text(); +} + + //============================================================================ void CDockWidgetTab::mouseDoubleClickEvent(QMouseEvent *event) { diff --git a/src/DockWidgetTab.h b/src/DockWidgetTab.h index a257b17..67b0801 100644 --- a/src/DockWidgetTab.h +++ b/src/DockWidgetTab.h @@ -116,13 +116,18 @@ public: */ const QIcon& icon() const; + /** + * Returns the tab text + */ + QString text() const; + public slots: virtual void setVisible(bool visible); signals: void activeTabChanged(); void clicked(); - void moved(); + void moved(const QPoint& GlobalPos); }; // class DockWidgetTab } // namespace ads