FloatingDragPreview.cpp
Go to the documentation of this file.
1 //============================================================================
6 //============================================================================
7 
8 //============================================================================
9 // INCLUDES
10 //============================================================================
11 #include "FloatingDragPreview.h"
12 #include <iostream>
13 
14 #include <QEvent>
15 #include <QApplication>
16 #include <QPainter>
17 #include <QKeyEvent>
18 
19 #include "DockWidget.h"
20 #include "DockAreaWidget.h"
21 #include "DockManager.h"
22 #include "DockContainerWidget.h"
23 #include "DockOverlay.h"
24 
25 namespace ads
26 {
27 
32 {
34  QWidget* Content;
40  bool Hidden = false;
42  bool Canceled = false;
43 
44 
49  void updateDropOverlays(const QPoint &GlobalPos);
50 
51  void setHidden(bool Value)
52  {
53  Hidden = Value;
54  _this->update();
55  }
56 
61  {
62  Canceled = true;
63  emit _this->draggingCanceled();
64  DockManager->containerOverlay()->hideOverlay();
65  DockManager->dockAreaOverlay()->hideOverlay();
66  _this->close();
67  }
68 
73  void createFloatingWidget();
74 };
75 // struct LedArrayPanelPrivate
76 
77 
78 //============================================================================
80 {
81  if (!_this->isVisible() || !DockManager)
82  {
83  return;
84  }
85 
86  auto Containers = DockManager->dockContainers();
87  CDockContainerWidget *TopContainer = nullptr;
88  for (auto ContainerWidget : Containers)
89  {
90  if (!ContainerWidget->isVisible())
91  {
92  continue;
93  }
94 
95  QPoint MappedPos = ContainerWidget->mapFromGlobal(GlobalPos);
96  if (ContainerWidget->rect().contains(MappedPos))
97  {
98  if (!TopContainer || ContainerWidget->isInFrontOf(TopContainer))
99  {
100  TopContainer = ContainerWidget;
101  }
102  }
103  }
104 
105  DropContainer = TopContainer;
106  auto ContainerOverlay = DockManager->containerOverlay();
107  auto DockAreaOverlay = DockManager->dockAreaOverlay();
108  auto DockDropArea = DockAreaOverlay->dropAreaUnderCursor();
109  auto ContainerDropArea = ContainerOverlay->dropAreaUnderCursor();
110 
111  if (!TopContainer)
112  {
113  ContainerOverlay->hideOverlay();
114  DockAreaOverlay->hideOverlay();
116  {
117  setHidden(false);
118  }
119  return;
120  }
121 
122  int VisibleDockAreas = TopContainer->visibleDockAreaCount();
123  ContainerOverlay->setAllowedAreas(
124  VisibleDockAreas > 1 ? OuterDockAreas : AllDockAreas);
125  auto DockArea = TopContainer->dockAreaAt(GlobalPos);
126  if (DockArea && DockArea->isVisible() && VisibleDockAreas >= 0 && DockArea != ContentSourceArea)
127  {
128  DockAreaOverlay->enableDropPreview(true);
129  DockAreaOverlay->setAllowedAreas(
130  (VisibleDockAreas == 1) ? NoDockWidgetArea : DockArea->allowedAreas());
131  DockWidgetArea Area = DockAreaOverlay->showOverlay(DockArea);
132 
133  // A CenterDockWidgetArea for the dockAreaOverlay() indicates that
134  // the mouse is in the title bar. If the ContainerArea is valid
135  // then we ignore the dock area of the dockAreaOverlay() and disable
136  // the drop preview
137  if ((Area == CenterDockWidgetArea) && (ContainerDropArea != InvalidDockWidgetArea))
138  {
139  DockAreaOverlay->enableDropPreview(false);
140  ContainerOverlay->enableDropPreview(true);
141  }
142  else
143  {
144  ContainerOverlay->enableDropPreview(InvalidDockWidgetArea == Area);
145  }
146  ContainerOverlay->showOverlay(TopContainer);
147  }
148  else
149  {
150  DockAreaOverlay->hideOverlay();
151  // If there is only one single visible dock area in a container, then
152  // it does not make sense to show a dock overlay because the dock area
153  // would be removed and inserted at the same position
154  if (VisibleDockAreas == 1)
155  {
156  ContainerOverlay->hideOverlay();
157  }
158  else
159  {
160  ContainerOverlay->showOverlay(TopContainer);
161  }
162 
163 
164  if (DockArea == ContentSourceArea && InvalidDockWidgetArea == ContainerDropArea)
165  {
166  DropContainer = nullptr;
167  }
168  }
169 
171  {
172  setHidden(DockDropArea != InvalidDockWidgetArea || ContainerDropArea != InvalidDockWidgetArea);
173  }
174 }
175 
176 
177 //============================================================================
179  _this(_public)
180 {
181 
182 }
183 
184 
185 //============================================================================
187 {
188  CDockWidget* DockWidget = qobject_cast<CDockWidget*>(Content);
189  CDockAreaWidget* DockArea = qobject_cast<CDockAreaWidget*>(Content);
190 
191  CFloatingDockContainer* FloatingWidget = nullptr;
192 
193  if (DockWidget && DockWidget->features().testFlag(CDockWidget::DockWidgetFloatable))
194  {
195  FloatingWidget = new CFloatingDockContainer(DockWidget);
196  }
197  else if (DockArea && DockArea->features().testFlag(CDockWidget::DockWidgetFloatable))
198  {
199  FloatingWidget = new CFloatingDockContainer(DockArea);
200  }
201 
202  if (FloatingWidget)
203  {
204  FloatingWidget->setGeometry(_this->geometry());
205  FloatingWidget->show();
207  {
208  QApplication::processEvents();
209  int FrameHeight = FloatingWidget->frameGeometry().height() - FloatingWidget->geometry().height();
210  QRect FixedGeometry = _this->geometry();
211  FixedGeometry.adjust(0, FrameHeight, 0, 0);
212  FloatingWidget->setGeometry(FixedGeometry);
213  }
214  }
215 }
216 
217 
218 //============================================================================
220  QWidget(parent),
221  d(new FloatingDragPreviewPrivate(this))
222 {
223  d->Content = Content;
224  setAttribute(Qt::WA_DeleteOnClose);
226  {
227  setWindowFlags(
228  Qt::Window | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint);
229  }
230  else
231  {
232  setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
233  setAttribute(Qt::WA_NoSystemBackground);
234  setAttribute(Qt::WA_TranslucentBackground);
235  }
236 
237 #ifdef Q_OS_LINUX
238  auto Flags = windowFlags();
239  Flags |= Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint;
240  setWindowFlags(Flags);
241 #endif
242 
243  setWindowOpacity(0.6);
244 
245  // Create a static image of the widget that should get undocked
246  // This is like some kind preview image like it is uses in drag and drop
247  // operations
249  {
250  d->ContentPreviewPixmap = QPixmap(Content->size());
251  Content->render(&d->ContentPreviewPixmap);
252  }
253 
254  connect(qApp, SIGNAL(applicationStateChanged(Qt::ApplicationState)),
255  SLOT(onApplicationStateChanged(Qt::ApplicationState)));
256 
257  // The only safe way to receive escape key presses is to install an event
258  // filter for the application object
259  qApp->installEventFilter(this);
260 }
261 
262 
263 //============================================================================
265  : CFloatingDragPreview((QWidget*)Content, Content->dockManager())
266 {
267  d->DockManager = Content->dockManager();
268  if (Content->dockAreaWidget()->openDockWidgetsCount() == 1)
269  {
270  d->ContentSourceArea = Content->dockAreaWidget();
271  }
272  setWindowTitle(Content->windowTitle());
273 }
274 
275 
276 //============================================================================
278  : CFloatingDragPreview((QWidget*)Content, Content->dockManager())
279 {
280  d->DockManager = Content->dockManager();
281  d->ContentSourceArea = Content;
282  setWindowTitle(Content->currentDockWidget()->windowTitle());
283 }
284 
285 
286 //============================================================================
288 {
289  delete d;
290 }
291 
292 
293 //============================================================================
295 {
296  int BorderSize = (frameSize().width() - size().width()) / 2;
297  const QPoint moveToPos = QCursor::pos() - d->DragStartMousePosition
298  - QPoint(BorderSize, 0);
299  move(moveToPos);
300  d->updateDropOverlays(QCursor::pos());
301 }
302 
303 
304 //============================================================================
305 void CFloatingDragPreview::startFloating(const QPoint &DragStartMousePos,
306  const QSize &Size, eDragState DragState, QWidget *MouseEventHandler)
307 {
308  Q_UNUSED(MouseEventHandler)
309  Q_UNUSED(DragState)
310  resize(Size);
311  d->DragStartMousePosition = DragStartMousePos;
312  moveFloating();
313  show();
314 
315 }
316 
317 
318 //============================================================================
320 {
321  ADS_PRINT("CFloatingDragPreview::finishDragging");
322  auto DockDropArea = d->DockManager->dockAreaOverlay()->visibleDropAreaUnderCursor();
323  auto ContainerDropArea = d->DockManager->containerOverlay()->visibleDropAreaUnderCursor();
324  if (!d->DropContainer)
325  {
327  }
328  else if (DockDropArea != InvalidDockWidgetArea)
329  {
330  d->DropContainer->dropWidget(d->Content, DockDropArea, d->DropContainer->dockAreaAt(QCursor::pos()));
331  }
332  else if (ContainerDropArea != InvalidDockWidgetArea)
333  {
334  // If there is only one single dock area, and we drop into the center
335  // then we tabify the dropped widget into the only visible dock area
336  if (d->DropContainer->visibleDockAreaCount() <= 1 && CenterDockWidgetArea == ContainerDropArea)
337  {
338  d->DropContainer->dropWidget(d->Content, ContainerDropArea, d->DropContainer->dockAreaAt(QCursor::pos()));
339  }
340  else
341  {
342  d->DropContainer->dropWidget(d->Content, ContainerDropArea, nullptr);
343  }
344  }
345  else
346  {
348  }
349 
350  this->close();
351  d->DockManager->containerOverlay()->hideOverlay();
352  d->DockManager->dockAreaOverlay()->hideOverlay();
353 }
354 
355 
356 //============================================================================
357 void CFloatingDragPreview::paintEvent(QPaintEvent* event)
358 {
359  Q_UNUSED(event);
360  if (d->Hidden)
361  {
362  return;
363  }
364 
365  QPainter painter(this);
367  {
368  painter.drawPixmap(QPoint(0, 0), d->ContentPreviewPixmap);
369  }
370 
371  // If we do not have a window frame then we paint a QRubberBand like
372  // frameless window
374  {
375  QColor Color = palette().color(QPalette::Active, QPalette::Highlight);
376  QPen Pen = painter.pen();
377  Pen.setColor(Color.darker(120));
378  Pen.setStyle(Qt::SolidLine);
379  Pen.setWidth(1);
380  Pen.setCosmetic(true);
381  painter.setPen(Pen);
382  Color = Color.lighter(130);
383  Color.setAlpha(64);
384  painter.setBrush(Color);
385  painter.drawRect(rect().adjusted(0, 0, -1, -1));
386  }
387 }
388 
389 //============================================================================
391 {
392  if (state != Qt::ApplicationActive)
393  {
394  disconnect(qApp, SIGNAL(applicationStateChanged(Qt::ApplicationState)),
395  this, SLOT(onApplicationStateChanged(Qt::ApplicationState)));
396  d->cancelDragging();
397  }
398 }
399 
400 
401 //============================================================================
402 bool CFloatingDragPreview::eventFilter(QObject *watched, QEvent *event)
403 {
404  Q_UNUSED(watched);
405  if (!d->Canceled && event->type() == QEvent::KeyPress)
406  {
407  QKeyEvent* e = static_cast<QKeyEvent*>(event);
408  if (e->key() == Qt::Key_Escape)
409  {
410  watched->removeEventFilter(this);
411  d->cancelDragging();
412  }
413  }
414 
415  return false;
416 }
417 
418 
419 
420 } // namespace ads
421 
422 //---------------------------------------------------------------------------
423 // EOF FloatingDragPreview.cpp
static bool testConfigFlag(eConfigFlag Flag)
CDockWidget * currentDockWidget() const
static heap_info state
Definition: Heap.c:58
CDockContainerWidget * DropContainer
DockWidgetArea
Definition: ads_globals.h:73
MQTTClient d
Definition: test10.c:1656
virtual void paintEvent(QPaintEvent *e) override
CDockAreaWidget * dockAreaAt(const QPoint &GlobalPos) const
void onApplicationStateChanged(Qt::ApplicationState state)
Definition: lobject.h:47
void dropWidget(QWidget *Widget, DockWidgetArea DropArea, CDockAreaWidget *TargetAreaWidget)
dock widget can be dragged into a floating window
Definition: DockWidget.h:152
bool isInFrontOf(CDockContainerWidget *Other) const
virtual void finishDragging() override
Declaration of CFloatingDragPreview.
void setAllowedAreas(DockWidgetAreas areas)
FloatingDragPreviewPrivate * d
#define ADS_PRINT(s)
Definition: ads_globals.h:60
const QList< CDockContainerWidget * > dockContainers() const
CFloatingDragPreview(QWidget *Content, QWidget *parent)
void updateDropOverlays(const QPoint &GlobalPos)
If opaque undocking is disabled, then this flag configures if the drag preview is frameless or looks ...
Definition: DockManager.h:171
Declaration of CDockContainerWidget class.
CDockManager * dockManager() const
Definition: DockWidget.cpp:366
const T & move(const T &v)
Definition: backward.hpp:394
DockWidgetFeatures features() const
Definition: DockWidget.cpp:359
Declaration of CDockAreaWidget class.
CDockManager * dockManager() const
CDockOverlay * containerOverlay() const
FloatingDragPreviewPrivate(CFloatingDragPreview *_public)
virtual bool eventFilter(QObject *watched, QEvent *event) override
Declaration of CDockWidget class.
virtual void startFloating(const QPoint &DragStartMousePos, const QSize &Size, eDragState DragState, QWidget *MouseEventHandler) override
Declaration of CDockManager class.
If opaque undocking is disabled, this flag defines the behavior of the drag preview window...
Definition: DockManager.h:169
CDockOverlay * dockAreaOverlay() const
virtual void moveFloating() override
CDockAreaWidget * dockAreaWidget() const
Definition: DockWidget.cpp:394
int openDockWidgetsCount() const
union Value Value
eDragState
Definition: ads_globals.h:99
If opaque undocking is disabled, the created drag preview window shows a copy of the content of the d...
Definition: DockManager.h:170


plotjuggler
Author(s): Davide Faconti
autogenerated on Sun Dec 6 2020 03:47:34