Skip to content

Commit f4fc0da

Browse files
Added support for dropping dock widget to a certain tab postion of a dock area
1 parent 39bc7f1 commit f4fc0da

File tree

7 files changed

+94
-22
lines changed

7 files changed

+94
-22
lines changed

src/DockAreaTabBar.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,31 @@ QSize CDockAreaTabBar::sizeHint() const
504504
return d->TabsContainerWidget->sizeHint();
505505
}
506506

507+
508+
//===========================================================================
509+
int CDockAreaTabBar::tabAt(const QPoint& Pos) const
510+
{
511+
if (!isVisible())
512+
{
513+
return -2;
514+
}
515+
516+
if (Pos.x() < tab(0)->geometry().x())
517+
{
518+
return -1;
519+
}
520+
521+
for (int i = 0; i < count(); ++i)
522+
{
523+
if (tab(i)->geometry().contains(Pos))
524+
{
525+
return i;
526+
}
527+
}
528+
529+
return count();
530+
}
531+
507532
} // namespace ads
508533

509534

src/DockAreaTabBar.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,14 @@ private Q_SLOTS:
113113
*/
114114
CDockWidgetTab* tab(int Index) const;
115115

116+
/**
117+
* Returns the tab at the given position.
118+
* Returns -1 if the position is left of the first tab and count() if the
119+
* position is right of the last tab. Returns -2 to indicate an invalid
120+
* value.
121+
*/
122+
int tabAt(const QPoint& Pos) const;
123+
116124
/**
117125
* Filters the tab widget events
118126
*/

src/DockContainerWidget.cpp

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -190,19 +190,20 @@ class DockContainerWidgetPrivate
190190
* Creates a new tab for a widget dropped into the center of a section
191191
*/
192192
void dropIntoCenterOfSection(CFloatingDockContainer* FloatingWidget,
193-
CDockAreaWidget* TargetArea);
193+
CDockAreaWidget* TargetArea, int TabIndex = -2);
194194

195195
/**
196196
* Drop floating widget into dock area
197197
*/
198198
void dropIntoSection(CFloatingDockContainer* FloatingWidget,
199-
CDockAreaWidget* TargetArea, DockWidgetArea area);
199+
CDockAreaWidget* TargetArea, DockWidgetArea area, int TabIndex = -2);
200200

201201
/**
202202
* Moves the dock widget or dock area given in Widget parameter to a
203203
* new dock widget area
204204
*/
205-
void moveToNewSection(QWidget* Widget, CDockAreaWidget* TargetArea, DockWidgetArea area);
205+
void moveToNewSection(QWidget* Widget, CDockAreaWidget* TargetArea, DockWidgetArea area,
206+
int TabIndex = -2);
206207

207208
/**
208209
* Moves the dock widget or dock area given in Widget parameter to a
@@ -213,7 +214,7 @@ class DockContainerWidgetPrivate
213214
/**
214215
* Creates a new tab for a widget dropped into the center of a section
215216
*/
216-
void moveIntoCenterOfSection(QWidget* Widget, CDockAreaWidget* TargetArea);
217+
void moveIntoCenterOfSection(QWidget* Widget, CDockAreaWidget* TargetArea, int TabIndex = -2);
217218

218219
/**
219220
* Moves the dock widget or dock area given in Widget parameter to
@@ -535,12 +536,13 @@ void DockContainerWidgetPrivate::dropIntoAutoHideSideBar(CFloatingDockContainer*
535536

536537
//============================================================================
537538
void DockContainerWidgetPrivate::dropIntoCenterOfSection(
538-
CFloatingDockContainer* FloatingWidget, CDockAreaWidget* TargetArea)
539+
CFloatingDockContainer* FloatingWidget, CDockAreaWidget* TargetArea, int TabIndex)
539540
{
540541
CDockContainerWidget* FloatingContainer = FloatingWidget->dockContainer();
541542
auto NewDockWidgets = FloatingContainer->dockWidgets();
542543
auto TopLevelDockArea = FloatingContainer->topLevelDockArea();
543544
int NewCurrentIndex = -1;
545+
TabIndex = (TabIndex < 0) ? 0 : TabIndex;
544546

545547
// If the floating widget contains only one single dock are, then the
546548
// current dock widget of the dock area will also be the future current
@@ -553,7 +555,7 @@ void DockContainerWidgetPrivate::dropIntoCenterOfSection(
553555
for (int i = 0; i < NewDockWidgets.count(); ++i)
554556
{
555557
CDockWidget* DockWidget = NewDockWidgets[i];
556-
TargetArea->insertDockWidget(i, DockWidget, false);
558+
TargetArea->insertDockWidget(TabIndex + i, DockWidget, false);
557559
// If the floating widget contains multiple visible dock areas, then we
558560
// simply pick the first visible open dock widget and make it
559561
// the current one.
@@ -562,21 +564,22 @@ void DockContainerWidgetPrivate::dropIntoCenterOfSection(
562564
NewCurrentIndex = i;
563565
}
564566
}
565-
TargetArea->setCurrentIndex(NewCurrentIndex);
567+
TargetArea->setCurrentIndex(NewCurrentIndex + TabIndex);
566568
TargetArea->updateTitleBarVisibility();
567569
return;
568570
}
569571

570572

571573
//============================================================================
572574
void DockContainerWidgetPrivate::dropIntoSection(CFloatingDockContainer* FloatingWidget,
573-
CDockAreaWidget* TargetArea, DockWidgetArea area)
575+
CDockAreaWidget* TargetArea, DockWidgetArea area, int TabIndex)
574576
{
577+
qDebug() << "DockContainerWidgetPrivate::dropIntoSection TabIndex: " << TabIndex;
575578
// Dropping into center means all dock widgets in the dropped floating
576579
// widget will become tabs of the drop area
577580
if (CenterDockWidgetArea == area)
578581
{
579-
dropIntoCenterOfSection(FloatingWidget, TargetArea);
582+
dropIntoCenterOfSection(FloatingWidget, TargetArea, TabIndex);
580583
return;
581584
}
582585

@@ -666,11 +669,15 @@ void DockContainerWidgetPrivate::dropIntoSection(CFloatingDockContainer* Floatin
666669

667670

668671
//============================================================================
669-
void DockContainerWidgetPrivate::moveIntoCenterOfSection(QWidget* Widget, CDockAreaWidget* TargetArea)
672+
void DockContainerWidgetPrivate::moveIntoCenterOfSection(QWidget* Widget, CDockAreaWidget* TargetArea,
673+
int TabIndex)
670674
{
675+
qDebug() << "DockContainerWidgetPrivate::moveIntoCenterOfSection TabIndex: "
676+
<< TabIndex;
671677
auto DroppedDockWidget = qobject_cast<CDockWidget*>(Widget);
672678
auto DroppedArea = qobject_cast<CDockAreaWidget*>(Widget);
673679

680+
TabIndex = (TabIndex < 0) ? 0 : TabIndex;
674681
if (DroppedDockWidget)
675682
{
676683
CDockAreaWidget* OldDockArea = DroppedDockWidget->dockAreaWidget();
@@ -683,7 +690,7 @@ void DockContainerWidgetPrivate::moveIntoCenterOfSection(QWidget* Widget, CDockA
683690
{
684691
OldDockArea->removeDockWidget(DroppedDockWidget);
685692
}
686-
TargetArea->insertDockWidget(0, DroppedDockWidget, true);
693+
TargetArea->insertDockWidget(TabIndex, DroppedDockWidget, true);
687694
}
688695
else
689696
{
@@ -692,9 +699,9 @@ void DockContainerWidgetPrivate::moveIntoCenterOfSection(QWidget* Widget, CDockA
692699
for (int i = 0; i < NewDockWidgets.count(); ++i)
693700
{
694701
CDockWidget* DockWidget = NewDockWidgets[i];
695-
TargetArea->insertDockWidget(i, DockWidget, false);
702+
TargetArea->insertDockWidget(TabIndex + i, DockWidget, false);
696703
}
697-
TargetArea->setCurrentIndex(NewCurrentIndex);
704+
TargetArea->setCurrentIndex(TabIndex + NewCurrentIndex);
698705
DroppedArea->dockContainer()->removeDockArea(DroppedArea);
699706
DroppedArea->deleteLater();
700707
}
@@ -705,13 +712,16 @@ void DockContainerWidgetPrivate::moveIntoCenterOfSection(QWidget* Widget, CDockA
705712

706713

707714
//============================================================================
708-
void DockContainerWidgetPrivate::moveToNewSection(QWidget* Widget, CDockAreaWidget* TargetArea, DockWidgetArea area)
715+
void DockContainerWidgetPrivate::moveToNewSection(QWidget* Widget, CDockAreaWidget* TargetArea, DockWidgetArea area,
716+
int TabIndex)
709717
{
718+
qDebug() << "DockContainerWidgetPrivate::moveToNewSection TabIndex: "
719+
<< TabIndex;
710720
// Dropping into center means all dock widgets in the dropped floating
711721
// widget will become tabs of the drop area
712722
if (CenterDockWidgetArea == area)
713723
{
714-
moveIntoCenterOfSection(Widget, TargetArea);
724+
moveIntoCenterOfSection(Widget, TargetArea, TabIndex);
715725
return;
716726
}
717727

@@ -1705,7 +1715,6 @@ void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWi
17051715
bool Dropped = false;
17061716

17071717
CDockAreaWidget* DockArea = dockAreaAt(TargetPos);
1708-
std::cout << "DockArea: " << DockArea << " dropArea: " << dropArea << std::endl;
17091718
if (DockArea)
17101719
{
17111720
auto dropOverlay = d->DockManager->dockAreaOverlay();
@@ -1720,7 +1729,8 @@ void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWi
17201729
if (dropArea != InvalidDockWidgetArea)
17211730
{
17221731
ADS_PRINT("Dock Area Drop Content: " << dropArea);
1723-
d->dropIntoSection(FloatingWidget, DockArea, dropArea);
1732+
int TabIndex = d->DockManager->dockAreaOverlay()->tabIndexUnderCursor();
1733+
d->dropIntoSection(FloatingWidget, DockArea, dropArea, TabIndex);
17241734
Dropped = true;
17251735
}
17261736
}
@@ -1773,12 +1783,14 @@ void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWi
17731783

17741784

17751785
//============================================================================
1776-
void CDockContainerWidget::dropWidget(QWidget* Widget, DockWidgetArea DropArea, CDockAreaWidget* TargetAreaWidget)
1786+
void CDockContainerWidget::dropWidget(QWidget* Widget, DockWidgetArea DropArea, CDockAreaWidget* TargetAreaWidget,
1787+
int TabIndex)
17771788
{
1789+
qDebug() << "CDockContainerWidget::dropWidget TabIndex: " << TabIndex;
17781790
CDockWidget* SingleDockWidget = topLevelDockWidget();
17791791
if (TargetAreaWidget)
17801792
{
1781-
d->moveToNewSection(Widget, TargetAreaWidget, DropArea);
1793+
d->moveToNewSection(Widget, TargetAreaWidget, DropArea, TabIndex);
17821794
}
17831795
else if (internal::isSideBarArea(DropArea))
17841796
{

src/DockContainerWidget.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,8 @@ class ADS_EXPORT CDockContainerWidget : public QFrame
132132
* a nullptr, then the DropArea indicates the drop area in the given
133133
* TargetAreaWidget
134134
*/
135-
void dropWidget(QWidget* Widget, DockWidgetArea DropArea, CDockAreaWidget* TargetAreaWidget);
135+
void dropWidget(QWidget* Widget, DockWidgetArea DropArea, CDockAreaWidget* TargetAreaWidget,
136+
int TabIndex = -2);
136137

137138
/**
138139
* Adds the given dock area to this container widget

src/DockOverlay.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,15 @@
4141
#include "DockContainerWidget.h"
4242
#include "AutoHideSideBar.h"
4343
#include "DockManager.h"
44+
#include "DockAreaTabBar.h"
4445

4546
#include <iostream>
4647

4748
namespace ads
4849
{
4950
static const int AutoHideAreaWidth = 32;
5051
static const int AutoHideAreaMouseZone = 8;
52+
static const int InvalidTabIndex = -2;
5153

5254
/**
5355
* Private data class of CDockOverlay
@@ -62,6 +64,7 @@ struct DockOverlayPrivate
6264
bool DropPreviewEnabled = true;
6365
CDockOverlay::eMode Mode = CDockOverlay::ModeDockAreaOverlay;
6466
QRect DropAreaRect;
67+
int TabIndex = InvalidTabIndex;
6568

6669
/**
6770
* Private data constructor
@@ -456,6 +459,7 @@ DockWidgetAreas CDockOverlay::allowedAreas() const
456459
//============================================================================
457460
DockWidgetArea CDockOverlay::dropAreaUnderCursor() const
458461
{
462+
d->TabIndex = InvalidTabIndex;
459463
if (!d->TargetWidget)
460464
{
461465
return InvalidDockWidgetArea;
@@ -503,17 +507,27 @@ DockWidgetArea CDockOverlay::dropAreaUnderCursor() const
503507
return Result;
504508
}
505509

510+
auto CursorPos = QCursor::pos();
506511
if (DockArea->allowedAreas().testFlag(CenterDockWidgetArea)
507512
&& !DockArea->titleBar()->isHidden()
508-
&& DockArea->titleBarGeometry().contains(DockArea->mapFromGlobal(QCursor::pos())))
513+
&& DockArea->titleBarGeometry().contains(DockArea->mapFromGlobal(CursorPos)))
509514
{
515+
auto TabBar = DockArea->titleBar()->tabBar();
516+
d->TabIndex = TabBar->tabAt(TabBar->mapFromGlobal(CursorPos));
510517
return CenterDockWidgetArea;
511518
}
512519

513520
return Result;
514521
}
515522

516523

524+
//============================================================================
525+
int CDockOverlay::tabIndexUnderCursor() const
526+
{
527+
return d->TabIndex;
528+
}
529+
530+
517531
//============================================================================
518532
DockWidgetArea CDockOverlay::visibleDropAreaUnderCursor() const
519533
{

src/DockOverlay.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,17 @@ class ADS_EXPORT CDockOverlay : public QFrame
8787
*/
8888
DockWidgetArea dropAreaUnderCursor() const;
8989

90+
/**
91+
* If the drop area is the CenterDockWidgetArea or a sidebar area,
92+
* then this function returns the index of the tab under cursor.
93+
* Call this function after call to dropAreaUnderCursor() because this
94+
* function updates the tab index.
95+
* A value of -1 indicates a position before the first tab and a value of
96+
* tabCount() indicates a position behind the last tab.
97+
* A value of -2 indicates an valid value
98+
*/
99+
int tabIndexUnderCursor() const;
100+
90101
/**
91102
* This function returns the same like dropAreaUnderCursor() if this
92103
* overlay is not hidden and if drop preview is enabled and returns

src/FloatingDragPreview.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,8 @@ void CFloatingDragPreview::finishDragging()
396396
}
397397
else if (DockDropArea != InvalidDockWidgetArea)
398398
{
399-
d->DropContainer->dropWidget(d->Content, DockDropArea, d->DropContainer->dockAreaAt(QCursor::pos()));
399+
d->DropContainer->dropWidget(d->Content, DockDropArea, d->DropContainer->dockAreaAt(QCursor::pos()),
400+
d->DockManager->dockAreaOverlay()->tabIndexUnderCursor());
400401
}
401402
else if (ContainerDropArea != InvalidDockWidgetArea)
402403
{

0 commit comments

Comments
 (0)