DockFocusController.cpp
Go to the documentation of this file.
1 //============================================================================
6 //============================================================================
7 
8 //============================================================================
9 // INCLUDES
10 //============================================================================
11 #include "DockFocusController.h"
12 
13 #include <algorithm>
14 #include <iostream>
15 
16 #include <QPointer>
17 #include <QApplication>
18 #include <QAbstractButton>
19 
20 #include "DockWidget.h"
21 #include "DockAreaWidget.h"
22 #include "DockWidgetTab.h"
23 #include "DockContainerWidget.h"
24 #include "FloatingDockContainer.h"
25 #include "DockManager.h"
26 #include "DockAreaTitleBar.h"
27 
28 #ifdef Q_OS_LINUX
30 #endif
31 
32 namespace ads
33 {
38 {
40  QPointer<CDockWidget> FocusedDockWidget = nullptr;
41  QPointer<CDockAreaWidget> FocusedArea = nullptr;
43 #ifdef Q_OS_LINUX
44  QPointer<CFloatingDockContainer> FloatingWidget = nullptr;
45 #endif
48 
53 
59 };
60 // struct DockFocusControllerPrivate
61 
62 
63 //===========================================================================
65 {
66  DockWidget->setProperty("focused", Focused);
67  DockWidget->tabWidget()->setProperty("focused", Focused);
68  DockWidget->tabWidget()->updateStyle();
69  internal::repolishStyle(DockWidget);
70 }
71 
72 
73 //===========================================================================
74 static void updateDockAreaFocusStyle(CDockAreaWidget* DockArea, bool Focused)
75 {
76  DockArea->setProperty("focused", Focused);
77  internal::repolishStyle(DockArea);
78  internal::repolishStyle(DockArea->titleBar());
79 }
80 
81 
82 //===========================================================================
83 #ifdef Q_OS_LINUX
84 static void updateFloatingWidgetFocusStyle(CFloatingDockContainer* FloatingWidget, bool Focused)
85 {
86  if (FloatingWidget->hasNativeTitleBar())
87  {
88  return;
89  }
90  auto TitleBar = qobject_cast<CFloatingWidgetTitleBar*>(FloatingWidget->titleBarWidget());
91  if (!TitleBar)
92  {
93  return;
94  }
95  TitleBar->setProperty("focused", Focused);
96  TitleBar->updateStyle();
97 }
98 #endif
99 
100 
101 //============================================================================
103  CDockFocusController *_public) :
104  _this(_public)
105 {
106 
107 }
108 
109 
110 //============================================================================
112 {
113  if (!DockWidget->features().testFlag(CDockWidget::DockWidgetFocusable))
114  {
115  return;
116  }
117 
118  CDockAreaWidget* NewFocusedDockArea = nullptr;
119  if (FocusedDockWidget)
120  {
122  }
123 
125  FocusedDockWidget = DockWidget;
127  NewFocusedDockArea = FocusedDockWidget->dockAreaWidget();
128  if (NewFocusedDockArea && (FocusedArea != NewFocusedDockArea))
129  {
130  if (FocusedArea)
131  {
132  QObject::disconnect(FocusedArea, SIGNAL(viewToggled(bool)), _this, SLOT(onFocusedDockAreaViewToggled(bool)));
134  }
135 
136  FocusedArea = NewFocusedDockArea;
138  QObject::connect(FocusedArea, SIGNAL(viewToggled(bool)), _this, SLOT(onFocusedDockAreaViewToggled(bool)));
139  }
140 
141 
142  auto NewFloatingWidget = FocusedDockWidget->dockContainer()->floatingWidget();
143  if (NewFloatingWidget)
144  {
145  NewFloatingWidget->setProperty("FocusedDockWidget", QVariant::fromValue(DockWidget));
146  }
147 
148 
149 #ifdef Q_OS_LINUX
150  // This code is required for styling the floating widget titlebar for linux
151  // depending on the current focus state
152  if (FloatingWidget == NewFloatingWidget)
153  {
154  return;
155  }
156 
157  if (FloatingWidget)
158  {
159  updateFloatingWidgetFocusStyle(FloatingWidget, false);
160  }
161  FloatingWidget = NewFloatingWidget;
162 
163  if (FloatingWidget)
164  {
165  updateFloatingWidgetFocusStyle(FloatingWidget, true);
166  }
167 #endif
168 
169  if (old == DockWidget && !ForceFocusChangedSignal)
170  {
171  return;
172  }
173 
174  ForceFocusChangedSignal = false;
175  if (DockWidget->isVisible())
176  {
177  emit DockManager->focusedDockWidgetChanged(old, DockWidget);
178  }
179  else
180  {
181  OldFocusedDockWidget = old;
182  QObject::connect(DockWidget, SIGNAL(visibilityChanged(bool)), _this, SLOT(onDockWidgetVisibilityChanged(bool)));
183  }
184 }
185 
186 
187 
188 //============================================================================
190 {
191  auto Sender = sender();
192  auto DockWidget = qobject_cast<ads::CDockWidget*>(Sender);
193  disconnect(Sender, SIGNAL(visibilityChanged(bool)), this, SLOT(onDockWidgetVisibilityChanged(bool)));
194  if (DockWidget && Visible)
195  {
196  emit d->DockManager->focusedDockWidgetChanged(d->OldFocusedDockWidget, DockWidget);
197  }
198 }
199 
200 
201 //============================================================================
203  Super(DockManager),
204  d(new DockFocusControllerPrivate(this))
205 {
206  d->DockManager = DockManager;
207  connect(QApplication::instance(), SIGNAL(focusChanged(QWidget*, QWidget*)),
208  this, SLOT(onApplicationFocusChanged(QWidget*, QWidget*)));
209  connect(d->DockManager, SIGNAL(stateRestored()), SLOT(onStateRestored()));
210 }
211 
212 //============================================================================
214 {
215  delete d;
216 }
217 
218 
219 //===========================================================================
220 void CDockFocusController::onApplicationFocusChanged(QWidget* focusedOld, QWidget* focusedNow)
221 {
223  {
224  return;
225  }
226 
227  ADS_PRINT("CDockFocusController::onApplicationFocusChanged "
228  << " old: " << focusedOld << " new: " << focusedNow);
229  if (!focusedNow)
230  {
231  return;
232  }
233 
234  // If the close button in another tab steals the focus from the current
235  // active dock widget content, i.e. if the user clicks its close button,
236  // then we immediately give the focus back to the previous focused widget
237  // focusedOld
239  {
240  auto OtherDockWidgetTab = internal::findParent<CDockWidgetTab*>(focusedNow);
241  if (OtherDockWidgetTab && focusedOld)
242  {
243  auto OldFocusedDockWidget = internal::findParent<CDockWidget*>(focusedOld);
244  if (OldFocusedDockWidget)
245  {
246  focusedOld->setFocus();
247  }
248  return;
249  }
250  }
251 
252  CDockWidget* DockWidget = nullptr;
253  auto DockWidgetTab = qobject_cast<CDockWidgetTab*>(focusedNow);
254  if (DockWidgetTab)
255  {
256  DockWidget = DockWidgetTab->dockWidget();
257  // If the DockWidgetTab "steals" the focus from a widget in the same
258  // DockWidget, then we immediately give the focus back to the previous
259  // focused widget focusedOld
260  if (focusedOld)
261  {
262  auto OldFocusedDockWidget = internal::findParent<CDockWidget*>(focusedOld);
263  if (OldFocusedDockWidget && OldFocusedDockWidget == DockWidget)
264  {
265  focusedOld->setFocus();
266  }
267  }
268  }
269 
270  if (!DockWidget)
271  {
272  DockWidget = qobject_cast<CDockWidget*>(focusedNow);
273  }
274 
275  if (!DockWidget)
276  {
277  DockWidget = internal::findParent<CDockWidget*>(focusedNow);
278  }
279 
280 #ifdef Q_OS_LINUX
281  if (!DockWidget)
282  {
283  return;
284  }
285 #else
286  if (!DockWidget || DockWidget->tabWidget()->isHidden())
287  {
288  return;
289  }
290 #endif
291 
292  d->updateDockWidgetFocus(DockWidget);
293 }
294 
295 
296 //===========================================================================
298 {
299  d->updateDockWidgetFocus(focusedNow);
300 }
301 
302 
303 //===========================================================================
305 {
307  {
308  return;
309  }
310 
311  CDockAreaWidget* DockArea = qobject_cast<CDockAreaWidget*>(sender());
312  if (!DockArea || Open)
313  {
314  return;
315  }
316  auto Container = DockArea->dockContainer();
317  auto OpenedDockAreas = Container->openedDockAreas();
318  if (OpenedDockAreas.isEmpty())
319  {
320  return;
321  }
322 
323  CDockManager::setWidgetFocus(OpenedDockAreas[0]->currentDockWidget()->tabWidget());
324 }
325 
326 
327 //===========================================================================
329 {
331  {
332  return;
333  }
334 
335  CDockWidget* DockWidget = qobject_cast<CDockWidget*>(DroppedWidget);
336  if (!DockWidget)
337  {
338  CDockAreaWidget* DockArea = qobject_cast<CDockAreaWidget*>(DroppedWidget);
339  if (DockArea)
340  {
341  DockWidget = DockArea->currentDockWidget();
342  }
343  }
344 
345  if (!DockWidget)
346  {
347  return;
348  }
349 
350  d->ForceFocusChangedSignal = true;
352 }
353 
354 
355 //===========================================================================
357 {
358  if (!FloatingWidget || d->DockManager->isRestoringState())
359  {
360  return;
361  }
362 
363  auto vDockWidget = FloatingWidget->property("FocusedDockWidget");
364  if (!vDockWidget.isValid())
365  {
366  return;
367  }
368 
369  auto DockWidget = vDockWidget.value<CDockWidget*>();
370  if (DockWidget)
371  {
372  d->FocusedDockWidget = nullptr;
375  }
376 }
377 
378 
379 //==========================================================================
381 {
382  if (d->FocusedDockWidget)
383  {
385  }
386 }
387 
388 
389 //==========================================================================
391 {
392  return d->FocusedDockWidget.data();
393 }
394 
395 } // namespace ads
396 
397 //---------------------------------------------------------------------------
398 // EOF DockFocusController.cpp
static bool testConfigFlag(eConfigFlag Flag)
Declaration of CDockWidgetTab class.
bool isRestoringState() const
CDockWidget * currentDockWidget() const
void updateDockWidgetFocus(CDockWidget *DockWidget)
CDockAreaTitleBar * titleBar() const
MQTTClient d
Definition: test10.c:1656
Declaration of CDockFocusController class.
void onFocusedDockAreaViewToggled(bool Open)
Declaration of CFloatingDockContainer class.
void notifyFloatingWidgetDrop(CFloatingDockContainer *FloatingWidget)
QList< CDockAreaWidget * > openedDockAreas() const
CDockContainerWidget * dockContainer() const
void setCurrentDockWidget(CDockWidget *DockWidget)
void repolishStyle(QWidget *w, eRepolishChildOptions Options=RepolishIgnoreChildren)
if this is enabled, a dock widget can get focus highlighting
Definition: DockWidget.h:155
static void updateDockWidgetFocusStyle(CDockWidget *DockWidget, bool Focused)
If enabled the tab close buttons will be QToolButtons instead of QPushButtons - disabled by default...
Definition: DockManager.h:166
static void setWidgetFocus(QWidgetPtr widget)
Definition: DockManager.h:468
#define ADS_PRINT(s)
Definition: ads_globals.h:60
void setDockWidgetFocused(CDockWidget *focusedNow)
CDockWidget * focusedDockWidget() const
CDockFocusController(CDockManager *DockManager)
Declaration of CDockContainerWidget class.
QPointer< CDockAreaWidget > FocusedArea
DockFocusControllerPrivate * d
private data (pimpl)
void onApplicationFocusChanged(QWidget *old, QWidget *now)
CDockWidgetTab * tabWidget() const
Definition: DockWidget.cpp:328
DockWidgetFeatures features() const
Definition: DockWidget.cpp:359
Declaration of CFloatingWidgetTitleBar class.
Declaration of CDockAreaWidget class.
static void updateDockAreaFocusStyle(CDockAreaWidget *DockArea, bool Focused)
QPointer< CDockWidget > FocusedDockWidget
Declaration of CDockWidget class.
Declaration of CDockManager class.
CDockAreaWidget * dockAreaWidget() const
Definition: DockWidget.cpp:394
void focusedDockWidgetChanged(ads::CDockWidget *old, ads::CDockWidget *now)
Declaration of CDockAreaTitleBar class.
void onDockWidgetVisibilityChanged(bool Visible)
void notifyWidgetOrAreaRelocation(QWidget *RelocatedWidget)
DockFocusControllerPrivate(CDockFocusController *_public)


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