Skip to content

Commit 1c6d86e

Browse files
Added support for make auto hide widget floating via double click or context menu
1 parent 0b3c3f0 commit 1c6d86e

10 files changed

+149
-28
lines changed

src/AutoHideDockContainer.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ CAutoHideDockContainer::CAutoHideDockContainer(CDockWidget* DockWidget, SideBarL
230230
//============================================================================
231231
void CAutoHideDockContainer::updateSize()
232232
{
233-
std::cout << "CAutoHideDockContainer::updateSize()" << std::endl;
233+
qDebug() << "CAutoHideDockContainer::updateSize()";
234234
auto dockContainerParent = dockContainer();
235235
if (!dockContainerParent)
236236
{
@@ -239,6 +239,10 @@ void CAutoHideDockContainer::updateSize()
239239

240240
auto rect = dockContainerParent->contentRect();
241241
qDebug() << "dockContainerParent->contentRect() " << rect;
242+
qDebug() << "dockWidget()->rect()" << dockWidget()->rect();
243+
qDebug() << "dockAreaWidget()->rect(): " << dockAreaWidget()->rect();
244+
qDebug() << "CAutoHideDockContainer::isVisible " << this->isVisible();
245+
qDebug() << "CAutoHideDockContainer::rect " << this->rect();
242246

243247
switch (sideBarLocation())
244248
{
@@ -273,6 +277,9 @@ void CAutoHideDockContainer::updateSize()
273277
default:
274278
break;
275279
}
280+
281+
qDebug() << "CAutoHideDockContainer::rect (after): " << this->rect();
282+
qDebug() << "dockAreaWidget()->rect(): " << dockAreaWidget()->rect();
276283
}
277284

278285
//============================================================================
@@ -326,6 +333,7 @@ CDockWidget* CAutoHideDockContainer::dockWidget() const
326333
//============================================================================
327334
void CAutoHideDockContainer::addDockWidget(CDockWidget* DockWidget)
328335
{
336+
std::cout << "CAutoHideDockContainer::addDockWidget " << std::endl;
329337
if (d->DockWidget)
330338
{
331339
// Remove the old dock widget at this area
@@ -346,6 +354,10 @@ void CAutoHideDockContainer::addDockWidget(CDockWidget* DockWidget)
346354
}
347355
d->DockArea->addDockWidget(DockWidget);
348356
updateSize();
357+
// The dock area is not visible and will not update the size when updateSize()
358+
// is called for this auto hide container. Therefore we explicitely resize
359+
// it here. As soon as it will become visible, it will get the right size
360+
d->DockArea->resize(size());
349361
}
350362

351363

src/AutoHideTab.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include <QBoxLayout>
3333
#include <QApplication>
3434
#include <QElapsedTimer>
35+
#include <QMenu>
3536

3637
#include "AutoHideDockContainer.h"
3738
#include "AutoHideSideBar.h"
@@ -272,10 +273,65 @@ bool CAutoHideTab::event(QEvent* event)
272273
return Super::event(event);
273274
}
274275

276+
275277
//============================================================================
276278
bool CAutoHideTab::iconOnly() const
277279
{
278280
return CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideSideBarsIconOnly) && !icon().isNull();
279281
}
280282

283+
284+
//============================================================================
285+
void CAutoHideTab::contextMenuEvent(QContextMenuEvent* ev)
286+
{
287+
ev->accept();
288+
//d->saveDragStartMousePosition(ev->globalPos());
289+
290+
const bool isFloatable = d->DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable);
291+
QAction* Action;
292+
QMenu Menu(this);
293+
294+
295+
Action = Menu.addAction(tr("Detach"), this, SLOT(setDockWidgetFloating()));
296+
Action->setEnabled(isFloatable);
297+
auto IsPinnable = d->DockWidget->features().testFlag(CDockWidget::DockWidgetPinnable);
298+
Action->setEnabled(IsPinnable);
299+
300+
auto menu = Menu.addMenu(tr("Pin To..."));
301+
menu->setEnabled(IsPinnable);
302+
//d->createAutoHideToAction(tr("Top"), SideBarTop, menu);
303+
//d->createAutoHideToAction(tr("Left"), SideBarLeft, menu);
304+
//d->createAutoHideToAction(tr("Right"), SideBarRight, menu);
305+
//d->createAutoHideToAction(tr("Bottom"), SideBarBottom, menu);
306+
307+
/*Menu.addSeparator();
308+
Action = Menu.addAction(tr("Close"), this, SIGNAL(closeRequested()));
309+
Action->setEnabled(isClosable());
310+
if (d->DockArea->openDockWidgetsCount() > 1)
311+
{
312+
Action = Menu.addAction(tr("Close Others"), this, SIGNAL(closeOtherTabsRequested()));
313+
}*/
314+
Menu.exec(ev->globalPos());
315+
}
316+
317+
318+
//============================================================================
319+
void CAutoHideTab::mouseDoubleClickEvent(QMouseEvent *event)
320+
{
321+
if (event->button() == Qt::LeftButton)
322+
{
323+
setDockWidgetFloating();
324+
}
325+
326+
Super::mouseDoubleClickEvent(event);
327+
}
328+
329+
330+
//============================================================================
331+
void CAutoHideTab::setDockWidgetFloating()
332+
{
333+
dockWidget()->setFloating();
334+
}
335+
336+
281337
}

src/AutoHideTab.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,12 @@ class ADS_EXPORT CAutoHideTab : public CPushButton
6565
friend class CDockContainerWidget;
6666
friend DockContainerWidgetPrivate;
6767

68-
6968
protected:
7069
void setSideBar(CAutoHideSideBar *SideTabBar);
7170
void removeFromSideBar();
7271
virtual bool event(QEvent* event) override;
72+
virtual void contextMenuEvent(QContextMenuEvent* ev) override;
73+
virtual void mouseDoubleClickEvent(QMouseEvent *event) override;
7374

7475
public:
7576
using Super = CPushButton;
@@ -133,6 +134,12 @@ class ADS_EXPORT CAutoHideTab : public CPushButton
133134
* not in a side bar
134135
*/
135136
CAutoHideSideBar* sideBar() const;
137+
138+
public Q_SLOTS:
139+
/**
140+
* Set the dock widget floating, if it is floatable
141+
*/
142+
void setDockWidgetFloating();
136143
}; // class AutoHideTab
137144
}
138145
// namespace ads

src/DockAreaTitleBar.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ void DockAreaTitleBarPrivate::createTabBar()
260260
//============================================================================
261261
IFloatingWidget* DockAreaTitleBarPrivate::makeAreaFloating(const QPoint& Offset, eDragState DragState)
262262
{
263+
qDebug() << "DockAreaTitleBarPrivate::makeAreaFloating " << DockArea->size();
263264
QSize Size = DockArea->size();
264265
this->DragState = DragState;
265266
bool CreateFloatingDockContainer = (DraggingFloatingWidget != DragState);
@@ -660,6 +661,7 @@ void CDockAreaTitleBar::mouseMoveEvent(QMouseEvent* ev)
660661
//============================================================================
661662
void CDockAreaTitleBar::mouseDoubleClickEvent(QMouseEvent *event)
662663
{
664+
std::cout << "CDockAreaTitleBar::mouseDoubleClickEvent" << std::endl;
663665
// If this is the last dock area in a dock container it does not make
664666
// sense to move it to a new floating widget and leave this one
665667
// empty
@@ -677,6 +679,26 @@ void CDockAreaTitleBar::mouseDoubleClickEvent(QMouseEvent *event)
677679
}
678680

679681

682+
//============================================================================
683+
void CDockAreaTitleBar::setAreaFloating()
684+
{
685+
// If this is the last dock area in a dock container it does not make
686+
// sense to move it to a new floating widget and leave this one
687+
// empty
688+
if (d->DockArea->dockContainer()->isFloating() && d->DockArea->dockContainer()->dockAreaCount() == 1)
689+
{
690+
return;
691+
}
692+
693+
if (!d->DockArea->features().testFlag(CDockWidget::DockWidgetFloatable))
694+
{
695+
return;
696+
}
697+
698+
d->makeAreaFloating(mapFromGlobal(QCursor::pos()), DraggingInactive);
699+
}
700+
701+
680702
//============================================================================
681703
void CDockAreaTitleBar::contextMenuEvent(QContextMenuEvent* ev)
682704
{

src/DockAreaTitleBar.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,12 @@ public Q_SLOTS:
163163
*/
164164
QString titleBarButtonToolTip(TitleBarButton Button) const;
165165

166+
/**
167+
* Moves the dock area into its own floating widget if the area
168+
* DockWidgetFloatable flag is true
169+
*/
170+
void setAreaFloating();
171+
166172
Q_SIGNALS:
167173
/**
168174
* This signal is emitted if a tab in the tab bar is clicked by the user

src/DockAreaWidget.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1442,6 +1442,13 @@ bool CDockAreaWidget::isTopLevelArea() const
14421442
}
14431443

14441444

1445+
//============================================================================
1446+
void CDockAreaWidget::setFloating()
1447+
{
1448+
d->TitleBar->setAreaFloating();
1449+
}
1450+
1451+
14451452
#ifdef Q_OS_WIN
14461453
//============================================================================
14471454
bool CDockAreaWidget::event(QEvent *e)

src/DockAreaWidget.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,12 @@ public Q_SLOTS:
414414
*/
415415
void closeOtherAreas();
416416

417+
/**
418+
* Moves the dock area into its own floating widget if the area
419+
* DockWidgetFloatable flag is true
420+
*/
421+
void setFloating();
422+
417423
Q_SIGNALS:
418424
/**
419425
* This signal is emitted when user clicks on a tab at an index.

src/DockOverlay.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,6 @@ DockWidgetArea CDockOverlay::dropAreaUnderCursor() const
475475
auto DockArea = qobject_cast<CDockAreaWidget*>(d->TargetWidget.data());
476476
if (!DockArea && CDockManager::autoHideConfigFlags().testFlag(CDockManager::AutoHideFeatureEnabled))
477477
{
478-
std::cout << d->Mode << " Find out side bar area " << std::endl;
479478
auto Rect = rect();
480479
const QPoint pos = mapFromGlobal(QCursor::pos());
481480
if (pos.x() < d->sideBarMouseZone(SideBarLeft))
@@ -488,7 +487,6 @@ DockWidgetArea CDockOverlay::dropAreaUnderCursor() const
488487
}
489488
else if (pos.y() < d->sideBarMouseZone(SideBarTop))
490489
{
491-
std::cout << d->Mode << " TopAutoHideArea " << std::endl;
492490
return TopAutoHideArea;
493491
}
494492
else if (pos.y() > (Rect.height() - d->sideBarMouseZone(SideBarBottom)))
@@ -534,14 +532,12 @@ DockWidgetArea CDockOverlay::visibleDropAreaUnderCursor() const
534532
//============================================================================
535533
DockWidgetArea CDockOverlay::showOverlay(QWidget* target)
536534
{
537-
std::cout << d->Mode << " CDockOverlay::showOverlay()" << target << " " << target->objectName().toStdString() << std::endl;
538535
if (d->TargetWidget == target)
539536
{
540537
// Hint: We could update geometry of overlay here.
541538
DockWidgetArea da = dropAreaUnderCursor();
542539
if (da != d->LastLocation)
543540
{
544-
std::cout << d->Mode << " repaint()" << std::endl;
545541
repaint();
546542
d->LastLocation = da;
547543
}
@@ -566,7 +562,6 @@ DockWidgetArea CDockOverlay::showOverlay(QWidget* target)
566562
//============================================================================
567563
void CDockOverlay::hideOverlay()
568564
{
569-
std::cout << d->Mode << " CDockOverlay::hideOverlay()" << std::endl;
570565
hide();
571566
d->TargetWidget.clear();
572567
d->LastLocation = InvalidDockWidgetArea;
@@ -578,7 +573,6 @@ void CDockOverlay::hideOverlay()
578573
void CDockOverlay::enableDropPreview(bool Enable)
579574
{
580575
d->DropPreviewEnabled = Enable;
581-
std::cout << d->Mode << " update() " << Enable << std::endl;
582576
update();
583577
}
584578

@@ -606,7 +600,6 @@ void CDockOverlay::paintEvent(QPaintEvent* event)
606600
double Factor = (CDockOverlay::ModeContainerOverlay == d->Mode) ?
607601
3 : 2;
608602

609-
std::cout << "CDockOverlay::paintEvent da: " << da << std::endl;
610603
switch (da)
611604
{
612605
case TopDockWidgetArea: r.setHeight(r.height() / Factor); break;

src/DockWidget.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1021,7 +1021,15 @@ void CDockWidget::setFloating()
10211021
{
10221022
return;
10231023
}
1024-
d->TabWidget->detachDockWidget();
1024+
1025+
if (this->isAutoHide())
1026+
{
1027+
dockAreaWidget()->setFloating();
1028+
}
1029+
else
1030+
{
1031+
d->TabWidget->detachDockWidget();
1032+
}
10251033
}
10261034

10271035

src/FloatingDockContainer.cpp

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -499,32 +499,35 @@ void FloatingDockContainerPrivate::titleMouseReleaseEvent()
499499
return;
500500
}
501501

502-
if (DockManager->dockAreaOverlay()->dropAreaUnderCursor()
503-
!= InvalidDockWidgetArea
504-
|| DockManager->containerOverlay()->dropAreaUnderCursor()
505-
!= InvalidDockWidgetArea)
502+
if (DockManager->dockAreaOverlay()->dropAreaUnderCursor() != InvalidDockWidgetArea
503+
|| DockManager->containerOverlay()->dropAreaUnderCursor() != InvalidDockWidgetArea)
506504
{
507505
CDockOverlay *Overlay = DockManager->containerOverlay();
508506
if (!Overlay->dropOverlayRect().isValid())
509507
{
510508
Overlay = DockManager->dockAreaOverlay();
511509
}
512510

513-
// Resize the floating widget to the size of the highlighted drop area
514-
// rectangle
515-
QRect Rect = Overlay->dropOverlayRect();
516-
int FrameWidth = (_this->frameSize().width() - _this->rect().width())
517-
/ 2;
518-
int TitleBarHeight = _this->frameSize().height()
519-
- _this->rect().height() - FrameWidth;
520-
if (Rect.isValid())
511+
// Do not resize if we drop into an autohide sidebar area to preserve
512+
// the dock area size for the initial size of the auto hide area
513+
if (!ads::internal::isSideBarArea(Overlay->dropAreaUnderCursor()))
521514
{
522-
QPoint TopLeft = Overlay->mapToGlobal(Rect.topLeft());
523-
TopLeft.ry() += TitleBarHeight;
524-
_this->setGeometry(
525-
QRect(TopLeft,
526-
QSize(Rect.width(), Rect.height() - TitleBarHeight)));
527-
QApplication::processEvents();
515+
// Resize the floating widget to the size of the highlighted drop area
516+
// rectangle
517+
QRect Rect = Overlay->dropOverlayRect();
518+
int FrameWidth = (_this->frameSize().width() - _this->rect().width())
519+
/ 2;
520+
int TitleBarHeight = _this->frameSize().height()
521+
- _this->rect().height() - FrameWidth;
522+
if (Rect.isValid())
523+
{
524+
QPoint TopLeft = Overlay->mapToGlobal(Rect.topLeft());
525+
TopLeft.ry() += TitleBarHeight;
526+
_this->setGeometry(
527+
QRect(TopLeft,
528+
QSize(Rect.width(), Rect.height() - TitleBarHeight)));
529+
QApplication::processEvents();
530+
}
528531
}
529532
DropContainer->dropFloatingWidget(_this, QCursor::pos());
530533
}
@@ -533,6 +536,7 @@ void FloatingDockContainerPrivate::titleMouseReleaseEvent()
533536
DockManager->dockAreaOverlay()->hideOverlay();
534537
}
535538

539+
536540
//============================================================================
537541
void FloatingDockContainerPrivate::updateDropOverlays(const QPoint &GlobalPos)
538542
{

0 commit comments

Comments
 (0)