3939#include " DockAreaWidget.h"
4040#include " DockManager.h"
4141#include " DockWidget.h"
42+ #include " FloatingDragPreview.h"
43+ #include " DockOverlay.h"
4244
4345namespace ads
4446{
@@ -54,6 +56,11 @@ struct AutoHideTabPrivate
5456 CAutoHideSideBar* SideBar = nullptr ;
5557 Qt::Orientation Orientation{Qt::Vertical};
5658 QElapsedTimer TimeSinceHoverMousePress;
59+ bool MousePressed = false ;
60+ eDragState DragState = DraggingInactive;
61+ QPoint GlobalDragStartMousePosition;
62+ QPoint DragStartMousePosition;
63+ IFloatingWidget* FloatingWidget = nullptr ;
5764
5865 /* *
5966 * Private data constructor
@@ -99,6 +106,41 @@ struct AutoHideTabPrivate
99106 Action->setEnabled (Location != _this->sideBarLocation ());
100107 return Action;
101108 }
109+
110+ /* *
111+ * Test function for current drag state
112+ */
113+ bool isDraggingState (eDragState dragState) const
114+ {
115+ return this ->DragState == dragState;
116+ }
117+
118+ /* *
119+ * Saves the drag start position in global and local coordinates
120+ */
121+ void saveDragStartMousePosition (const QPoint& GlobalPos)
122+ {
123+ GlobalDragStartMousePosition = GlobalPos;
124+ DragStartMousePosition = _this->mapFromGlobal (GlobalPos);
125+ }
126+
127+ /* *
128+ * Starts floating of the dock widget that belongs to this title bar
129+ * Returns true, if floating has been started and false if floating
130+ * is not possible for any reason
131+ */
132+ bool startFloating (eDragState DraggingState = DraggingFloatingWidget);
133+
134+ template <typename T>
135+ IFloatingWidget* createFloatingWidget (T* Widget)
136+ {
137+ auto w = new CFloatingDragPreview (Widget);
138+ _this->connect (w, &CFloatingDragPreview::draggingCanceled, [=]()
139+ {
140+ DragState = DraggingInactive;
141+ });
142+ return w;
143+ }
102144}; // struct DockWidgetTabPrivate
103145
104146
@@ -127,6 +169,52 @@ void AutoHideTabPrivate::updateOrientation()
127169}
128170
129171
172+ // ============================================================================
173+ bool AutoHideTabPrivate::startFloating (eDragState DraggingState)
174+ {
175+ auto DockArea = DockWidget->dockAreaWidget ();
176+ ADS_PRINT (" isFloating " << dockContainer->isFloating ());
177+
178+ ADS_PRINT (" startFloating" );
179+ DragState = DraggingState;
180+ IFloatingWidget* FloatingWidget = nullptr ;
181+ FloatingWidget = createFloatingWidget (DockArea);
182+ auto Size = DockArea->size ();
183+ auto StartPos = DragStartMousePosition;
184+ auto AutoHideContainer = DockWidget->autoHideDockContainer ();
185+ switch (SideBar->sideBarLocation ())
186+ {
187+ case SideBarLeft:
188+ StartPos.rx () = AutoHideContainer->rect ().left () + 10 ;
189+ break ;
190+
191+ case SideBarRight:
192+ StartPos.rx () = AutoHideContainer->rect ().right () - 10 ;
193+ break ;
194+
195+ case SideBarTop:
196+ StartPos.ry () = AutoHideContainer->rect ().top () + 10 ;
197+ break ;
198+
199+ case SideBarBottom:
200+ StartPos.ry () = AutoHideContainer->rect ().bottom () - 10 ;
201+ break ;
202+
203+ case SideBarNone:
204+ return false ;
205+ }
206+ FloatingWidget->startFloating (StartPos, Size, DraggingFloatingWidget, _this);
207+ auto DockManager = DockWidget->dockManager ();
208+ auto Overlay = DockManager->containerOverlay ();
209+ Overlay->setAllowedAreas (OuterDockAreas);
210+ this ->FloatingWidget = FloatingWidget;
211+ qApp->postEvent (DockWidget, new QEvent ((QEvent::Type)internal::DockedWidgetDragStartEvent));
212+
213+ return true ;
214+ }
215+
216+
217+
130218// ============================================================================
131219void CAutoHideTab::setSideBar (CAutoHideSideBar* SideTabBar)
132220{
@@ -267,22 +355,6 @@ bool CAutoHideTab::event(QEvent* event)
267355 d->forwardEventToDockContainer (event);
268356 break ;
269357
270- case QEvent::MouseButtonPress:
271- // If AutoHideShowOnMouseOver is active, then the showing is triggered
272- // by a MousePressEvent sent to this tab. To prevent accidental hiding
273- // of the tab by a mouse click, we wait at least 500 ms before we accept
274- // the mouse click
275- if (!event->spontaneous ())
276- {
277- d->TimeSinceHoverMousePress .restart ();
278- d->forwardEventToDockContainer (event);
279- }
280- else if (d->TimeSinceHoverMousePress .hasExpired (500 ))
281- {
282- d->forwardEventToDockContainer (event);
283- }
284- break ;
285-
286358 default :
287359 break ;
288360 }
@@ -360,4 +432,139 @@ void CAutoHideTab::onAutoHideToActionClicked()
360432}
361433
362434
435+ // ============================================================================
436+ void CAutoHideTab::mousePressEvent (QMouseEvent* ev)
437+ {
438+ // If AutoHideShowOnMouseOver is active, then the showing is triggered
439+ // by a MousePressEvent sent to this tab. To prevent accidental hiding
440+ // of the tab by a mouse click, we wait at least 500 ms before we accept
441+ // the mouse click
442+ if (!ev->spontaneous ())
443+ {
444+ d->TimeSinceHoverMousePress .restart ();
445+ d->forwardEventToDockContainer (ev);
446+ }
447+ else if (d->TimeSinceHoverMousePress .hasExpired (500 ))
448+ {
449+ d->forwardEventToDockContainer (ev);
450+ }
451+
452+ if (ev->button () == Qt::LeftButton)
453+ {
454+ ev->accept ();
455+ d->MousePressed = true ;
456+ d->saveDragStartMousePosition (internal::globalPositionOf (ev));
457+ d->DragState = DraggingMousePressed;
458+ }
459+ Super::mousePressEvent (ev);
460+ }
461+
462+
463+
464+ // ============================================================================
465+ void CAutoHideTab::mouseReleaseEvent (QMouseEvent* ev)
466+ {
467+ if (ev->button () == Qt::LeftButton)
468+ {
469+ d->MousePressed = false ;
470+ auto CurrentDragState = d->DragState ;
471+ d->GlobalDragStartMousePosition = QPoint ();
472+ d->DragStartMousePosition = QPoint ();
473+ d->DragState = DraggingInactive;
474+
475+ switch (CurrentDragState)
476+ {
477+ case DraggingTab:
478+ // End of tab moving, emit signal
479+ /* if (d->DockArea)
480+ {
481+ ev->accept();
482+ Q_EMIT moved(internal::globalPositionOf(ev));
483+ }*/
484+ break ;
485+
486+ case DraggingFloatingWidget:
487+ ev->accept ();
488+ d->FloatingWidget ->finishDragging ();
489+ break ;
490+
491+ default :
492+ /* if (CDockManager::testConfigFlag(CDockManager::FocusHighlighting))
493+ {
494+ d->focusController()->setDockWidgetTabPressed(false);
495+ }*/
496+ break ; // do nothing
497+ }
498+ }
499+
500+ Super::mouseReleaseEvent (ev);
501+ }
502+
503+
504+ // ============================================================================
505+ void CAutoHideTab::mouseMoveEvent (QMouseEvent* ev)
506+ {
507+ std::cout << " CAutoHideTab::mouseMoveEvent" << std::endl;
508+ if (!(ev->buttons () & Qt::LeftButton) || d->isDraggingState (DraggingInactive))
509+ {
510+ d->DragState = DraggingInactive;
511+ Super::mouseMoveEvent (ev);
512+ return ;
513+ }
514+
515+ // move floating window
516+ if (d->isDraggingState (DraggingFloatingWidget))
517+ {
518+ d->FloatingWidget ->moveFloating ();
519+ Super::mouseMoveEvent (ev);
520+ return ;
521+ }
522+
523+ // move tab
524+ if (d->isDraggingState (DraggingTab))
525+ {
526+ // Moving the tab is always allowed because it does not mean moving the
527+ // dock widget around
528+ // d->moveTab(ev);
529+ }
530+
531+ auto MappedPos = mapToParent (ev->pos ());
532+ bool MouseOutsideBar = (MappedPos.x () < 0 ) || (MappedPos.x () > parentWidget ()->rect ().right ());
533+ // Maybe a fixed drag distance is better here ?
534+ int DragDistanceY = qAbs (d->GlobalDragStartMousePosition .y () - internal::globalPositionOf (ev).y ());
535+ std::cout << " DragDistanceY " << DragDistanceY << " MouseOutsideBar " << MouseOutsideBar << std::endl;
536+ if (DragDistanceY >= CDockManager::startDragDistance () || MouseOutsideBar)
537+ {
538+ // Floating is only allowed for widgets that are floatable
539+ // We can create the drag preview if the widget is movable.
540+ auto Features = d->DockWidget ->features ();
541+ if (Features.testFlag (CDockWidget::DockWidgetFloatable) || (Features.testFlag (CDockWidget::DockWidgetMovable)))
542+ {
543+ // If we undock, we need to restore the initial position of this
544+ // tab because it looks strange if it remains on its dragged position
545+ /* if (d->isDraggingState(DraggingTab))
546+ {
547+ parentWidget()->layout()->update();
548+ }*/
549+ d->startFloating ();
550+ }
551+ return ;
552+ }
553+ /* else if (d->DockArea->openDockWidgetsCount() > 1
554+ && (internal::globalPositionOf(ev) - d->GlobalDragStartMousePosition).manhattanLength() >= QApplication::startDragDistance()) // Wait a few pixels before start moving
555+ {
556+ // If we start dragging the tab, we save its inital position to
557+ // restore it later
558+ if (DraggingTab != d->DragState)
559+ {
560+ d->TabDragStartPosition = this->pos();
561+ }
562+ d->DragState = DraggingTab;
563+ return;
564+ }*/
565+
566+ Super::mouseMoveEvent (ev);
567+ }
568+
569+
363570}
0 commit comments