Properly implemented tab moving

This commit is contained in:
Uwe Kindler 2018-10-12 09:17:14 +02:00
parent 7c67d71f68
commit 75288af88c
6 changed files with 90 additions and 76 deletions

View File

@ -258,7 +258,7 @@ void CDockAreaTabBar::insertTab(int Index, CDockWidgetTab* Tab)
{ {
d->TabsLayout->insertWidget(Index, Tab); d->TabsLayout->insertWidget(Index, Tab);
connect(Tab, SIGNAL(clicked()), this, SLOT(onTabClicked())); 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; d->MenuOutdated = true;
if (Index <= d->CurrentIndex) if (Index <= d->CurrentIndex)
{ {
@ -272,8 +272,7 @@ void CDockAreaTabBar::removeTab(CDockWidgetTab* Tab)
{ {
std::cout << "CDockAreaTabBar::removeTab " << std::endl; std::cout << "CDockAreaTabBar::removeTab " << std::endl;
d->TabsLayout->removeWidget(Tab); d->TabsLayout->removeWidget(Tab);
disconnect(Tab, SIGNAL(clicked()), this, SLOT(onTabClicked())); Tab->disconnect(this);
disconnect(Tab, SIGNAL(moved()), this, SLOT(onTabMoved()));
d->MenuOutdated = true; d->MenuOutdated = true;
} }
@ -313,51 +312,75 @@ void CDockAreaTabBar::onTabClicked()
//=========================================================================== //===========================================================================
void CDockAreaTabBar::onTabMoved() CDockWidgetTab* CDockAreaTabBar::tab(int Index) const
{ {
CDockWidgetTab* Tab = qobject_cast<CDockWidgetTab*>(sender()); if (Index >= count())
if (!Tab) {
return 0;
}
return qobject_cast<CDockWidgetTab*>(d->TabsLayout->itemAt(Index)->widget());
}
//===========================================================================
void CDockAreaTabBar::onTabWidgetMoved(const QPoint& GlobalPos)
{
CDockWidgetTab* MovingTab = qobject_cast<CDockWidgetTab*>(sender());
if (!MovingTab)
{ {
return; return;
} }
int fromIndex = d->TabsLayout->indexOf(MovingTab);
auto MousePos = mapFromGlobal(GlobalPos);
int toIndex = -1;
// Find tab under mouse // 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) for (int i = 0; i < count(); ++i)
{ {
CDockWidgetTab* Tab2 = qobject_cast<CDockWidgetTab*>(d->TabsLayout->itemAt(i)->widget()); CDockWidgetTab* DropTab = tab(i);
if (Tab2 == Tab || !Tab) if (DropTab == MovingTab || !DropTab->isVisibleTo(this)
|| !DropTab->geometry().contains(MousePos))
{ {
continue; continue;
} }
std::cout << "Tab.left " << Tab->pos().x() << " Tab2.left " << Tab2->pos().x()
<< std::endl;
}
toIndex = d->TabsLayout->indexOf(DropTab);
/* if (toIndex == fromIndex)
* for (int i = 0; i < d->ContentsLayout->count(); ++i)
{ {
auto TabWidget = d->tabWidgetAt(i); toIndex = -1;
if (TabWidget->isVisible() && TabWidget->geometry().contains(p) && (!exclude || TabWidget != exclude)) continue;
{
return i;
} }
}
*/
std::cout << "CDockAreaTabBar::onTabMoved from " << fromIndex << std::endl; if (toIndex < 0)
/*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; toIndex = 0;
}
break;
}
// Now check if the mouse is behind the last tab
if (toIndex < 0)
{
if (MousePos.x() > tab(count() - 1)->geometry().right())
{
qDebug() << "after all tabs";
toIndex = count() - 1;
}
else
{
toIndex = fromIndex;
}
}
d->TabsLayout->removeWidget(MovingTab);
d->TabsLayout->insertWidget(toIndex, MovingTab);
if (toIndex >= 0)
{
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);*/
} }

View File

@ -32,7 +32,7 @@ private:
private slots: private slots:
void onTabClicked(); void onTabClicked();
void onTabMoved(); void onTabWidgetMoved(const QPoint& GlobalPos);
protected: protected:
virtual void wheelEvent(QWheelEvent* Event) override; virtual void wheelEvent(QWheelEvent* Event) override;
@ -100,6 +100,11 @@ public:
*/ */
CDockWidgetTab* currentTab() const; CDockWidgetTab* currentTab() const;
/**
* Returns the tab with the given index
*/
CDockWidgetTab* tab(int Index) const;
public slots: public slots:
/** /**
* This property sets the index of the tab bar's visible tab * 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. * The index is the index that should be closed.
*/ */
void tabCloseRequested(int index); 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 }; // class CDockAreaTabBar
} // namespace ads } // namespace ads
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -380,6 +380,7 @@ void DockAreaWidgetPrivate::createTabBar()
TabBar = new CDockAreaTabBar(_this); TabBar = new CDockAreaTabBar(_this);
TopLayout->addWidget(TabBar, 1); TopLayout->addWidget(TabBar, 1);
_this->connect(TabBar, SIGNAL(tabBarClicked(int)), SLOT(setCurrentIndex(int))); _this->connect(TabBar, SIGNAL(tabBarClicked(int)), SLOT(setCurrentIndex(int)));
_this->connect(TabBar, SIGNAL(tabMoved(int, int)), SLOT(reorderDockWidget(int, int)));
TabsMenuButton = new QPushButton(); TabsMenuButton = new QPushButton();
TabsMenuButton->setObjectName("tabsMenuButton"); TabsMenuButton->setObjectName("tabsMenuButton");
@ -768,35 +769,13 @@ void CDockAreaWidget::reorderDockWidget(int fromIndex, int toIndex)
|| toIndex >= d->ContentsLayout->count() || toIndex < 0 || fromIndex == toIndex) || toIndex >= d->ContentsLayout->count() || toIndex < 0 || fromIndex == toIndex)
{ {
qDebug() << "Invalid index for tab movement" << fromIndex << toIndex; qDebug() << "Invalid index for tab movement" << fromIndex << toIndex;
//d->TabsLayout->update();
return; 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); auto Widget = d->ContentsLayout->widget(fromIndex);
d->ContentsLayout->removeWidget(Widget); d->ContentsLayout->removeWidget(Widget);
d->ContentsLayout->insertWidget(toIndex, Widget); d->ContentsLayout->insertWidget(toIndex, Widget);
//delete liFrom; setCurrentIndex(d->TabBar->currentIndex());
} }

View File

@ -67,6 +67,12 @@ private slots:
void onCloseButtonClicked(); void onCloseButtonClicked();
void onTabsMenuAboutToShow(); 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: protected:
/** /**
* Inserts a dock widget into dock area. * Inserts a dock widget into dock area.
@ -94,11 +100,6 @@ protected:
*/ */
int indexOfContentByTitlePos(const QPoint& pos, QWidget* exclude = nullptr) const; 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 * Called from dock widget if it is opened or closed
*/ */

View File

@ -45,6 +45,8 @@
#include "DockOverlay.h" #include "DockOverlay.h"
#include "DockManager.h" #include "DockManager.h"
#include <iostream>
namespace ads namespace ads
{ {
/** /**
@ -229,6 +231,7 @@ void CDockWidgetTab::mousePressEvent(QMouseEvent* ev)
ev->accept(); ev->accept();
d->DragStartMousePosition = ev->pos(); d->DragStartMousePosition = ev->pos();
d->DragState = DraggingMousePressed; d->DragState = DraggingMousePressed;
emit clicked();
return; return;
} }
QFrame::mousePressEvent(ev); QFrame::mousePressEvent(ev);
@ -240,25 +243,10 @@ void CDockWidgetTab::mousePressEvent(QMouseEvent* ev)
void CDockWidgetTab::mouseReleaseEvent(QMouseEvent* ev) void CDockWidgetTab::mouseReleaseEvent(QMouseEvent* ev)
{ {
qDebug() << "CDockWidgetTab::mouseReleaseEvent"; qDebug() << "CDockWidgetTab::mouseReleaseEvent";
// End of tab moving, change order now // End of tab moving, emit signal
if (d->isDraggingState(DraggingTab) && d->DockArea) if (d->isDraggingState(DraggingTab) && d->DockArea)
{ {
// Find tab under mouse emit moved(ev->globalPos());
/*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();
}
if (!d->DragStartMousePosition.isNull())
{
emit clicked();
} }
d->DragStartMousePosition = QPoint(); d->DragStartMousePosition = QPoint();
@ -277,7 +265,7 @@ void CDockWidgetTab::mouseMoveEvent(QMouseEvent* ev)
return; return;
} }
// move floating winwdow // move floating window
if (d->isDraggingState(DraggingFloatingWidget)) if (d->isDraggingState(DraggingFloatingWidget))
{ {
d->FloatingWidget->moveFloating(); 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) void CDockWidgetTab::mouseDoubleClickEvent(QMouseEvent *event)
{ {

View File

@ -116,13 +116,18 @@ public:
*/ */
const QIcon& icon() const; const QIcon& icon() const;
/**
* Returns the tab text
*/
QString text() const;
public slots: public slots:
virtual void setVisible(bool visible); virtual void setVisible(bool visible);
signals: signals:
void activeTabChanged(); void activeTabChanged();
void clicked(); void clicked();
void moved(); void moved(const QPoint& GlobalPos);
}; // class DockWidgetTab }; // class DockWidgetTab
} }
// namespace ads // namespace ads