Skip to content

Commit e833257

Browse files
Improved tab dragging, added support for undocking if mouse leaves tabbar during tb dragging
1 parent 3f09d5c commit e833257

File tree

3 files changed

+28
-26
lines changed

3 files changed

+28
-26
lines changed

demo/MainWindow.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,7 @@ CMainWindow::CMainWindow(QWidget *parent) :
488488

489489
// uncomment the following line if you want to use opaque undocking and
490490
// opaque splitter resizing
491-
// CDockManager::setConfigFlags(CDockManager::DefaultOpaqueConfig);
491+
//CDockManager::setConfigFlags(CDockManager::DefaultOpaqueConfig);
492492

493493
// uncomment the following line if you want a fixed tab width that does
494494
// not change if the visibility of the close button changes

src/DockAreaTabBar.cpp

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include <QDebug>
3636
#include <QBoxLayout>
3737
#include <QApplication>
38+
#include <QtGlobal>
3839

3940
#include "FloatingDockContainer.h"
4041
#include "DockAreaWidget.h"
@@ -69,6 +70,16 @@ struct DockAreaTabBarPrivate
6970
* The function reassigns the stylesheet to update the tabs
7071
*/
7172
void updateTabs();
73+
74+
/**
75+
* Convenience function to access first tab
76+
*/
77+
CDockWidgetTab* firstTab() const {return _this->tab(0);}
78+
79+
/**
80+
* Convenience function to access last tab
81+
*/
82+
CDockWidgetTab* lastTab() const {return _this->tab(_this->count() - 1);}
7283
};
7384
// struct DockAreaTabBarPrivate
7485

@@ -366,6 +377,8 @@ void CDockAreaTabBar::onTabWidgetMoved(const QPoint& GlobalPos)
366377

367378
int fromIndex = d->TabsLayout->indexOf(MovingTab);
368379
auto MousePos = mapFromGlobal(GlobalPos);
380+
MousePos.rx() = qMax(d->firstTab()->geometry().left(), MousePos.x());
381+
MousePos.rx() = qMin(d->lastTab()->geometry().right(), MousePos.x());
369382
int toIndex = -1;
370383
// Find tab under mouse
371384
for (int i = 0; i < count(); ++i)
@@ -381,38 +394,23 @@ void CDockAreaTabBar::onTabWidgetMoved(const QPoint& GlobalPos)
381394
if (toIndex == fromIndex)
382395
{
383396
toIndex = -1;
384-
continue;
385-
}
386-
387-
if (toIndex < 0)
388-
{
389-
toIndex = 0;
390397
}
391398
break;
392399
}
393400

394-
// Now check if the mouse is behind the last tab
395-
if (toIndex < 0)
396-
{
397-
if (MousePos.x() > tab(count() - 1)->geometry().right())
398-
{
399-
ADS_PRINT("after all tabs");
400-
toIndex = count() - 1;
401-
}
402-
else
403-
{
404-
toIndex = fromIndex;
405-
}
406-
}
407-
408-
d->TabsLayout->removeWidget(MovingTab);
409-
d->TabsLayout->insertWidget(toIndex, MovingTab);
410-
if (toIndex >= 0)
401+
if (toIndex > -1)
411402
{
403+
d->TabsLayout->removeWidget(MovingTab);
404+
d->TabsLayout->insertWidget(toIndex, MovingTab);
412405
ADS_PRINT("tabMoved from " << fromIndex << " to " << toIndex);
413406
emit tabMoved(fromIndex, toIndex);
414407
setCurrentIndex(toIndex);
415408
}
409+
else
410+
{
411+
// Ensure that the moved tab is reset to its start position
412+
d->TabsLayout->update();
413+
}
416414
}
417415

418416
//===========================================================================

src/DockWidgetTab.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,8 @@ void DockWidgetTabPrivate::moveTab(QMouseEvent* ev)
215215
QPoint Distance = ev->globalPos() - GlobalDragStartMousePosition;
216216
Distance.setY(0);
217217
auto TargetPos = Distance + TabDragStartPosition;
218+
TargetPos.rx() = qMax(TargetPos.x(), 0);
219+
TargetPos.rx() = qMin(_this->parentWidget()->rect().right() - _this->width() + 1, TargetPos.rx());
218220
_this->move(TargetPos);
219221
_this->raise();
220222
}
@@ -364,9 +366,11 @@ void CDockWidgetTab::mouseMoveEvent(QMouseEvent* ev)
364366
d->moveTab(ev);
365367
}
366368

369+
auto MappedPos = mapToParent(ev->pos());
370+
bool MouseOutsideBar = (MappedPos.x() < 0) || (MappedPos.x() > parentWidget()->rect().right());
367371
// Maybe a fixed drag distance is better here ?
368372
int DragDistanceY = qAbs(d->GlobalDragStartMousePosition.y() - ev->globalPos().y());
369-
if (DragDistanceY >= CDockManager::startDragDistance())
373+
if (DragDistanceY >= CDockManager::startDragDistance() || MouseOutsideBar)
370374
{
371375
// If this is the last dock area in a dock container with only
372376
// one single dock widget it does not make sense to move it to a new
@@ -390,7 +394,7 @@ void CDockWidgetTab::mouseMoveEvent(QMouseEvent* ev)
390394
// tab because it looks strange if it remains on its dragged position
391395
if (d->isDraggingState(DraggingTab) && !CDockManager::configFlags().testFlag(CDockManager::OpaqueUndocking))
392396
{
393-
this->move(d->TabDragStartPosition);
397+
parentWidget()->layout()->update();
394398
}
395399
d->startFloating();
396400
}

0 commit comments

Comments
 (0)