39
39
#include " DockAreaWidget.h"
40
40
#include " DockManager.h"
41
41
#include " DockWidget.h"
42
+ #include " FloatingDragPreview.h"
43
+ #include " DockOverlay.h"
42
44
43
45
namespace ads
44
46
{
@@ -54,6 +56,11 @@ struct AutoHideTabPrivate
54
56
CAutoHideSideBar* SideBar = nullptr ;
55
57
Qt::Orientation Orientation{Qt::Vertical};
56
58
QElapsedTimer TimeSinceHoverMousePress;
59
+ bool MousePressed = false ;
60
+ eDragState DragState = DraggingInactive;
61
+ QPoint GlobalDragStartMousePosition;
62
+ QPoint DragStartMousePosition;
63
+ IFloatingWidget* FloatingWidget = nullptr ;
57
64
58
65
/* *
59
66
* Private data constructor
@@ -99,6 +106,41 @@ struct AutoHideTabPrivate
99
106
Action->setEnabled (Location != _this->sideBarLocation ());
100
107
return Action;
101
108
}
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
+ }
102
144
}; // struct DockWidgetTabPrivate
103
145
104
146
@@ -127,6 +169,52 @@ void AutoHideTabPrivate::updateOrientation()
127
169
}
128
170
129
171
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
+
130
218
// ============================================================================
131
219
void CAutoHideTab::setSideBar (CAutoHideSideBar* SideTabBar)
132
220
{
@@ -267,22 +355,6 @@ bool CAutoHideTab::event(QEvent* event)
267
355
d->forwardEventToDockContainer (event);
268
356
break ;
269
357
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
-
286
358
default :
287
359
break ;
288
360
}
@@ -360,4 +432,139 @@ void CAutoHideTab::onAutoHideToActionClicked()
360
432
}
361
433
362
434
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
+
363
570
}
0 commit comments