Skip to content

Commit b801f06

Browse files
Improved dragging of widgets into AutoHideArea
1 parent f6ccaba commit b801f06

File tree

7 files changed

+127
-38
lines changed

7 files changed

+127
-38
lines changed

demo/MainWindow.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -437,8 +437,8 @@ void MainWindowPrivate::createContent()
437437

438438
// For this Special Dock Area we want to avoid dropping on the center of it (i.e. we don't want this widget to be ever tabbified):
439439
{
440-
SpecialDockArea->setAllowedAreas(ads::OuterDockAreas);
441-
//SpecialDockArea->setAllowedAreas({ads::LeftDockWidgetArea, ads::RightDockWidgetArea}); // just for testing
440+
//SpecialDockArea->setAllowedAreas(ads::OuterDockAreas);
441+
SpecialDockArea->setAllowedAreas({ads::LeftDockWidgetArea, ads::RightDockWidgetArea, ads::TopDockWidgetArea}); // just for testing
442442
}
443443

444444
DockWidget = createLongTextLabelDockWidget();
@@ -506,7 +506,9 @@ void MainWindowPrivate::createContent()
506506

507507
// Test dock area docking
508508
auto RighDockArea = DockManager->addDockWidget(ads::RightDockWidgetArea, createLongTextLabelDockWidget(), TopDockArea);
509-
DockManager->addDockWidget(ads::TopDockWidgetArea, createLongTextLabelDockWidget(), RighDockArea);
509+
DockWidget = createLongTextLabelDockWidget();
510+
DockWidget->setFeature(ads::CDockWidget::DockWidgetPinnable, false);
511+
DockManager->addDockWidget(ads::TopDockWidgetArea, DockWidget, RighDockArea);
510512
auto BottomDockArea = DockManager->addDockWidget(ads::BottomDockWidgetArea, createLongTextLabelDockWidget(), RighDockArea);
511513
DockManager->addDockWidget(ads::CenterDockWidgetArea, createLongTextLabelDockWidget(), RighDockArea);
512514
auto LabelDockWidget = createLongTextLabelDockWidget();

src/DockContainerWidget.cpp

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,12 @@ class DockContainerWidgetPrivate
186186
*/
187187
void dropIntoAutoHideSideBar(CFloatingDockContainer* FloatingWidget, DockWidgetArea area);
188188

189+
/**
190+
* Creates a new tab for a widget dropped into the center of a section
191+
*/
192+
void dropIntoCenterOfSection(CFloatingDockContainer* FloatingWidget,
193+
CDockAreaWidget* TargetArea);
194+
189195
/**
190196
* Drop floating widget into dock area
191197
*/
@@ -207,13 +213,13 @@ class DockContainerWidgetPrivate
207213
/**
208214
* Creates a new tab for a widget dropped into the center of a section
209215
*/
210-
void dropIntoCenterOfSection(CFloatingDockContainer* FloatingWidget,
211-
CDockAreaWidget* TargetArea);
216+
void moveIntoCenterOfSection(QWidget* Widget, CDockAreaWidget* TargetArea);
212217

213218
/**
214-
* Creates a new tab for a widget dropped into the center of a section
219+
* Moves the dock widget or dock area given in Widget parameter to
220+
* a auto hide sidebar area
215221
*/
216-
void moveIntoCenterOfSection(QWidget* Widget, CDockAreaWidget* TargetArea);
222+
void moveToAutoHideSideBar(QWidget* Widget, DockWidgetArea area);
217223

218224

219225
/**
@@ -760,6 +766,33 @@ void DockContainerWidgetPrivate::moveToNewSection(QWidget* Widget, CDockAreaWidg
760766
}
761767

762768

769+
//============================================================================
770+
void DockContainerWidgetPrivate::moveToAutoHideSideBar(QWidget* Widget, DockWidgetArea area)
771+
{
772+
std::cout << "DockContainerWidgetPrivate::moveToAutoHideSideBar " << area << std::endl;
773+
CDockWidget* DroppedDockWidget = qobject_cast<CDockWidget*>(Widget);
774+
CDockAreaWidget* DroppedDockArea = qobject_cast<CDockAreaWidget*>(Widget);
775+
auto SideBarLocation = internal::toSideBarLocation(area);
776+
777+
if (DroppedDockWidget)
778+
{
779+
_this->createAndSetupAutoHideContainer(SideBarLocation, DroppedDockWidget);
780+
}
781+
else
782+
{
783+
for (const auto DockWidget : DroppedDockArea->openedDockWidgets())
784+
{
785+
if (!DockWidget->features().testFlag(CDockWidget::DockWidgetPinnable))
786+
{
787+
continue;
788+
}
789+
790+
_this->createAndSetupAutoHideContainer(SideBarLocation, DockWidget);
791+
}
792+
}
793+
}
794+
795+
763796
//============================================================================
764797
void DockContainerWidgetPrivate::updateSplitterHandles( QSplitter* splitter )
765798
{
@@ -1724,24 +1757,6 @@ void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWi
17241757
d->DockManager->notifyFloatingWidgetDrop(FloatingWidget);
17251758
}
17261759

1727-
/*
1728-
* else if (internal::isSideBarArea(ContainerDropArea))
1729-
{
1730-
// Drop into AutoHideArea
1731-
auto DockWidget = qobject_cast<CDockWidget*>(d->Content);
1732-
auto DockArea = qobject_cast<CDockAreaWidget*>(d->Content);
1733-
auto SideBarLocation = internal::toSideBarLocation(ContainerDropArea);
1734-
if (DockWidget)
1735-
{
1736-
DockWidget->toggleAutoHide(SideBarLocation);
1737-
}
1738-
else if (DockArea)
1739-
{
1740-
DockArea->toggleAutoHide(SideBarLocation);
1741-
}
1742-
}
1743-
*/
1744-
17451760

17461761
//============================================================================
17471762
void CDockContainerWidget::dropWidget(QWidget* Widget, DockWidgetArea DropArea, CDockAreaWidget* TargetAreaWidget)
@@ -1752,6 +1767,10 @@ void CDockContainerWidget::dropWidget(QWidget* Widget, DockWidgetArea DropArea,
17521767
{
17531768
d->moveToNewSection(Widget, TargetAreaWidget, DropArea);
17541769
}
1770+
else if (internal::isSideBarArea(DropArea))
1771+
{
1772+
d->moveToAutoHideSideBar(Widget, DropArea);
1773+
}
17551774
else
17561775
{
17571776
d->moveToContainer(Widget, DropArea);

src/DockContainerWidget.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,13 @@ class ADS_EXPORT CDockContainerWidget : public QFrame
103103
*/
104104
CAutoHideDockContainer* createAndSetupAutoHideContainer(SideBarLocation area, CDockWidget* DockWidget);
105105

106+
/**
107+
* The funtion does the same like createAndSetupAutoHideContainer() but checks
108+
* if the given DockWidget is pinnable. If it is not pinnable, the
109+
* function returns a nullptr.
110+
*/
111+
CAutoHideDockContainer* createAutoHideContainerIfPinnable(SideBarLocation area, CDockWidget* DockWidget);
112+
106113
/**
107114
* Helper function for creation of the root splitter
108115
*/

src/DockOverlay.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,11 @@ struct DockOverlayCrossPrivate
209209
CDockOverlay::eMode Mode)
210210
{
211211
QColor borderColor = iconColor(CDockOverlayCross::FrameColor);
212+
// TODO: remove, this is just for debugging
213+
if (Mode == CDockOverlay::ModeContainerOverlay)
214+
{
215+
borderColor = Qt::red;
216+
}
212217
QColor backgroundColor = iconColor(CDockOverlayCross::WindowBackgroundColor);
213218
QColor overlayColor = iconColor(CDockOverlayCross::OverlayColor);
214219
if (overlayColor.alpha() == 255)
@@ -426,12 +431,26 @@ CDockOverlay::~CDockOverlay()
426431
void CDockOverlay::setAllowedAreas(DockWidgetAreas areas)
427432
{
428433
if (areas == d->AllowedAreas)
434+
{
429435
return;
436+
}
430437
d->AllowedAreas = areas;
431438
d->Cross->reset();
432439
}
433440

434441

442+
//============================================================================
443+
void CDockOverlay::setAllowedArea(DockWidgetArea area, bool Enable)
444+
{
445+
auto AreasOld = d->AllowedAreas;
446+
d->AllowedAreas.setFlag(area, Enable);
447+
if (AreasOld != d->AllowedAreas)
448+
{
449+
d->Cross->reset();
450+
}
451+
}
452+
453+
435454
//============================================================================
436455
DockWidgetAreas CDockOverlay::allowedAreas() const
437456
{
@@ -456,6 +475,7 @@ DockWidgetArea CDockOverlay::dropAreaUnderCursor() const
456475
auto DockArea = qobject_cast<CDockAreaWidget*>(d->TargetWidget.data());
457476
if (!DockArea && CDockManager::autoHideConfigFlags().testFlag(CDockManager::AutoHideFeatureEnabled))
458477
{
478+
std::cout << d->Mode << " Find out side bar area " << std::endl;
459479
auto Rect = rect();
460480
const QPoint pos = mapFromGlobal(QCursor::pos());
461481
if (pos.x() < d->sideBarMouseZone(SideBarLeft))
@@ -468,6 +488,7 @@ DockWidgetArea CDockOverlay::dropAreaUnderCursor() const
468488
}
469489
else if (pos.y() < d->sideBarMouseZone(SideBarTop))
470490
{
491+
std::cout << d->Mode << " TopAutoHideArea " << std::endl;
471492
return TopAutoHideArea;
472493
}
473494
else if (pos.y() > (Rect.height() - d->sideBarMouseZone(SideBarBottom)))
@@ -513,12 +534,14 @@ DockWidgetArea CDockOverlay::visibleDropAreaUnderCursor() const
513534
//============================================================================
514535
DockWidgetArea CDockOverlay::showOverlay(QWidget* target)
515536
{
537+
std::cout << d->Mode << " CDockOverlay::showOverlay()" << target << " " << target->objectName().toStdString() << std::endl;
516538
if (d->TargetWidget == target)
517539
{
518540
// Hint: We could update geometry of overlay here.
519541
DockWidgetArea da = dropAreaUnderCursor();
520542
if (da != d->LastLocation)
521543
{
544+
std::cout << d->Mode << " repaint()" << std::endl;
522545
repaint();
523546
d->LastLocation = da;
524547
}
@@ -543,6 +566,7 @@ DockWidgetArea CDockOverlay::showOverlay(QWidget* target)
543566
//============================================================================
544567
void CDockOverlay::hideOverlay()
545568
{
569+
std::cout << d->Mode << " CDockOverlay::hideOverlay()" << std::endl;
546570
hide();
547571
d->TargetWidget.clear();
548572
d->LastLocation = InvalidDockWidgetArea;
@@ -554,6 +578,7 @@ void CDockOverlay::hideOverlay()
554578
void CDockOverlay::enableDropPreview(bool Enable)
555579
{
556580
d->DropPreviewEnabled = Enable;
581+
std::cout << d->Mode << " update() " << Enable << std::endl;
557582
update();
558583
}
559584

@@ -581,6 +606,7 @@ void CDockOverlay::paintEvent(QPaintEvent* event)
581606
double Factor = (CDockOverlay::ModeContainerOverlay == d->Mode) ?
582607
3 : 2;
583608

609+
std::cout << "CDockOverlay::paintEvent da: " << da << std::endl;
584610
switch (da)
585611
{
586612
case TopDockWidgetArea: r.setHeight(r.height() / Factor); break;
@@ -596,6 +622,11 @@ void CDockOverlay::paintEvent(QPaintEvent* event)
596622
}
597623
QPainter painter(this);
598624
QColor Color = palette().color(QPalette::Active, QPalette::Highlight);
625+
// TODO: This is just for debugging - remove later
626+
if (d->Mode == CDockOverlay::ModeContainerOverlay)
627+
{
628+
Color = Qt::red;
629+
}
599630
QPen Pen = painter.pen();
600631
Pen.setColor(Color.darker(120));
601632
Pen.setStyle(Qt::SolidLine);

src/DockOverlay.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@ class ADS_EXPORT CDockOverlay : public QFrame
7272
*/
7373
void setAllowedAreas(DockWidgetAreas areas);
7474

75+
/**
76+
* Enable / disable a certain area
77+
*/
78+
void setAllowedArea(DockWidgetArea area, bool Enable);
79+
7580
/**
7681
* Returns flags with all allowed drop areas
7782
*/

src/FloatingDockContainer.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -585,11 +585,19 @@ void FloatingDockContainerPrivate::updateDropOverlays(const QPoint &GlobalPos)
585585
}
586586

587587
int VisibleDockAreas = TopContainer->visibleDockAreaCount();
588-
ContainerOverlay->setAllowedAreas(
589-
VisibleDockAreas > 1 ? OuterDockAreas : AllDockAreas);
588+
DockWidgetAreas AllowedAreas = (VisibleDockAreas > 1) ? OuterDockAreas : AllDockAreas;
589+
auto DockArea = TopContainer->dockAreaAt(GlobalPos);
590+
// If the dock container contains only one single DockArea, then we need
591+
// to respect the allowed areas - only the center area is relevant here because
592+
// all other allowed areas are from the container
593+
if (VisibleDockAreas == 1 && DockArea)
594+
{
595+
AllowedAreas.setFlag(CenterDockWidgetArea, DockArea->allowedAreas().testFlag(CenterDockWidgetArea));
596+
}
597+
ContainerOverlay->setAllowedAreas(AllowedAreas);
598+
590599
DockWidgetArea ContainerArea = ContainerOverlay->showOverlay(TopContainer);
591600
ContainerOverlay->enableDropPreview(ContainerArea != InvalidDockWidgetArea);
592-
auto DockArea = TopContainer->dockAreaAt(GlobalPos);
593601
if (DockArea && DockArea->isVisible() && VisibleDockAreas > 0)
594602
{
595603
DockAreaOverlay->enableDropPreview(true);

src/FloatingDragPreview.cpp

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ void FloatingDragPreviewPrivate::updateDropOverlays(const QPoint &GlobalPos)
101101
{
102102
if (!_this->isVisible() || !DockManager)
103103
{
104+
std::cout << "return 1" << std::endl;
104105
return;
105106
}
106107

@@ -126,20 +127,24 @@ void FloatingDragPreviewPrivate::updateDropOverlays(const QPoint &GlobalPos)
126127
DropContainer = TopContainer;
127128
auto ContainerOverlay = DockManager->containerOverlay();
128129
auto DockAreaOverlay = DockManager->dockAreaOverlay();
129-
auto DockDropArea = DockAreaOverlay->dropAreaUnderCursor();
130-
auto ContainerDropArea = ContainerOverlay->dropAreaUnderCursor();
131130

132131
if (!TopContainer)
133132
{
133+
std::cout << "ContainerOverlay->hideOverlay() 1" << std::endl;
134134
ContainerOverlay->hideOverlay();
135+
std::cout << "DockAreaOverlay->hideOverlay() 1" << std::endl;
135136
DockAreaOverlay->hideOverlay();
136137
if (CDockManager::testConfigFlag(CDockManager::DragPreviewIsDynamic))
137138
{
139+
std::cout << "return 2" << std::endl;
138140
setHidden(false);
139141
}
140142
return;
141143
}
142144

145+
auto DockDropArea = DockAreaOverlay->dropAreaUnderCursor();
146+
auto ContainerDropArea = ContainerOverlay->dropAreaUnderCursor();
147+
143148
int VisibleDockAreas = TopContainer->visibleDockAreaCount();
144149

145150
// Include the overlay widget we're dragging as a visible widget
@@ -148,15 +153,25 @@ void FloatingDragPreviewPrivate::updateDropOverlays(const QPoint &GlobalPos)
148153
{
149154
VisibleDockAreas++;
150155
}
156+
std::cout << "VisibleDockAreas " << VisibleDockAreas << std::endl;
151157

152-
ContainerOverlay->setAllowedAreas( VisibleDockAreas > 1 ? OuterDockAreas : AllDockAreas);
158+
DockWidgetAreas AllowedAreas = (VisibleDockAreas > 1) ? OuterDockAreas : AllDockAreas;
159+
//ContainerOverlay->enableDropPreview(ContainerDropArea != InvalidDockWidgetArea);
153160
auto DockArea = TopContainer->dockAreaAt(GlobalPos);
161+
// If the dock container contains only one single DockArea, then we need
162+
// to respect the allowed areas - only the center area is relevant here because
163+
// all other allowed areas are from the container
164+
if (VisibleDockAreas == 1 && DockArea)
165+
{
166+
AllowedAreas.setFlag(CenterDockWidgetArea, DockArea->allowedAreas().testFlag(CenterDockWidgetArea));
167+
}
168+
ContainerOverlay->setAllowedAreas(AllowedAreas);
154169
if (DockArea && DockArea->isVisible() && VisibleDockAreas >= 0 && DockArea != ContentSourceArea)
155170
{
156171
DockAreaOverlay->enableDropPreview(true);
157172
DockAreaOverlay->setAllowedAreas( (VisibleDockAreas == 1) ? NoDockWidgetArea : DockArea->allowedAreas());
158-
159173
DockWidgetArea Area = DockAreaOverlay->showOverlay(DockArea);
174+
std::cout << "DockWidgetArea " << Area << std::endl;
160175

161176
// A CenterDockWidgetArea for the dockAreaOverlay() indicates that
162177
// the mouse is in the title bar. If the ContainerArea is valid
@@ -165,28 +180,30 @@ void FloatingDragPreviewPrivate::updateDropOverlays(const QPoint &GlobalPos)
165180
if ((Area == CenterDockWidgetArea) && (ContainerDropArea != InvalidDockWidgetArea))
166181
{
167182
DockAreaOverlay->enableDropPreview(false);
183+
184+
std::cout << "ContainerOverlay->enableDropPreview(true) 1" << std::endl;
168185
ContainerOverlay->enableDropPreview(true);
169186
}
170187
else
171188
{
189+
std::cout << "ContainerOverlay->enableDropPreview 2" << std::endl;
172190
ContainerOverlay->enableDropPreview(InvalidDockWidgetArea == Area);
173191
}
174192
ContainerOverlay->showOverlay(TopContainer);
175193
}
176194
else
177195
{
196+
std::cout << "DockAreaOverlay->hideOverlay() 2" << std::endl;
178197
DockAreaOverlay->hideOverlay();
179198
// If there is only one single visible dock area in a container, then
180199
// it does not make sense to show a dock overlay because the dock area
181-
// would be removed and inserted at the same position
200+
// would be removed and inserted at the same position. Only auto hide
201+
// area is allowed
182202
if (VisibleDockAreas == 1)
183203
{
184-
ContainerOverlay->hideOverlay();
185-
}
186-
else
187-
{
188-
ContainerOverlay->showOverlay(TopContainer);
204+
ContainerOverlay->setAllowedAreas(AutoHideDockAreas);
189205
}
206+
ContainerOverlay->showOverlay(TopContainer);
190207

191208

192209
if (DockArea == ContentSourceArea && InvalidDockWidgetArea == ContainerDropArea)

0 commit comments

Comments
 (0)