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);
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<CDockWidgetTab*>(sender());
if (!Tab)
if (Index >= count())
{
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;
}
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<CDockWidgetTab*>(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);*/
}

View File

@ -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
//-----------------------------------------------------------------------------

View File

@ -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());
}

View File

@ -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
*/

View File

@ -45,6 +45,8 @@
#include "DockOverlay.h"
#include "DockManager.h"
#include <iostream>
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)
{

View File

@ -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