QtCanpool 3.3.0
载入中...
搜索中...
未找到
dockfocuscontroller.cpp
浏览该文件的文档.
1
6#include "dockwindow.h"
7#include "dockwidget.h"
8#include "dockpanel.h"
9#include "dockutils.h"
10#include "docktab.h"
12#include "docktitlebar.h"
13#include "dockmanager.h"
14
15#if QX_DOCK_X11
17#endif
18
19#include <QApplication>
20#include <QPointer>
21
23
24static const char *const s_focusedDockWidgetProperty = "FocusedDockWidget";
25
26static void updateDockWidgetFocusStyle(DockWidget *widget, bool focused)
27{
28 widget->setProperty("focused", focused);
29 widget->tab()->setProperty("focused", focused);
30 widget->tab()->updateStyle();
31 internal::repolishStyle(widget);
32}
33
34static void updateDockPanelFocusStyle(DockPanel *panel, bool focused)
35{
36 panel->setProperty("focused", focused);
37 internal::repolishStyle(panel);
38 internal::repolishStyle(panel->titleBar());
39}
40
41#if QX_DOCK_X11
42static void updateFloatingWidgetFocusStyle(DockFloatingContainer *floatingWidget, bool focused)
43{
44 if (floatingWidget->hasNativeTitleBar()) {
45 return;
46 }
47 auto titleBar = qobject_cast<DockFloatingTitleBar *>(floatingWidget->titleBarWidget());
48 if (!titleBar) {
49 return;
50 }
51 titleBar->setProperty("focused", focused);
52 titleBar->updateStyle();
53}
54#endif
55
56class DockFocusControllerPrivate
57{
58public:
59 QX_DECLARE_PUBLIC(DockFocusController)
60public:
61 DockFocusControllerPrivate();
62 void updateDockWidgetFocus(DockWidget *dockWidget);
63public:
64 DockWindow *m_window;
65 QPointer<DockWidget> m_focusedDockWidget = nullptr;
66 QPointer<DockWidget> m_oldFocusedDockWidget = nullptr;
67 QPointer<DockPanel> m_focusedPanel = nullptr;
68#if QX_DOCK_X11
69 QPointer<DockFloatingContainer> m_floatingWidget = nullptr;
70#endif
71 bool m_tabPressed = false;
72 bool m_forceFocusChangedSignal = false;
73};
74
75DockFocusControllerPrivate::DockFocusControllerPrivate()
76{
77}
78
83void DockFocusControllerPrivate::updateDockWidgetFocus(DockWidget *dockWidget)
84{
85 if (!dockWidget)
86 return;
87 if (!dockWidget->features().testFlag(DockWidget::DockWidgetFocusable)) {
88 return;
89 }
90 Q_Q(DockFocusController);
91
92 QWindow *window = nullptr;
93 auto DockContainer = dockWidget->dockContainer();
94 if (DockContainer) {
95 window = DockContainer->window()->windowHandle();
96 }
97
98 if (window) {
99 window->setProperty(s_focusedDockWidgetProperty, QVariant::fromValue(QPointer<DockWidget>(dockWidget)));
100 }
101 DockPanel *newFocusedPanel = nullptr;
102 if (m_focusedDockWidget) {
103 updateDockWidgetFocusStyle(m_focusedDockWidget, false);
104 }
105
106 DockWidget *old = m_focusedDockWidget;
107 m_focusedDockWidget = dockWidget;
108 updateDockWidgetFocusStyle(m_focusedDockWidget, true);
109 newFocusedPanel = m_focusedDockWidget->dockPanel();
110 if (newFocusedPanel && (m_focusedPanel != newFocusedPanel)) {
111 if (m_focusedPanel) {
112 QObject::disconnect(m_focusedPanel, SIGNAL(viewToggled(bool)), q, SLOT(onFocusedDockAreaViewToggled(bool)));
113 updateDockPanelFocusStyle(m_focusedPanel, false);
114 }
115
116 m_focusedPanel = newFocusedPanel;
117 updateDockPanelFocusStyle(m_focusedPanel, true);
118 QObject::connect(m_focusedPanel, SIGNAL(viewToggled(bool)), q, SLOT(onFocusedDockAreaViewToggled(bool)));
119 }
120
121 DockFloatingContainer *newFloatingWidget = nullptr;
122 DockContainer = m_focusedDockWidget->dockContainer();
123 if (DockContainer) {
124 newFloatingWidget = DockContainer->floatingWidget();
125 }
126
127 if (newFloatingWidget) {
128 newFloatingWidget->setProperty(s_focusedDockWidgetProperty,
129 QVariant::fromValue(QPointer<DockWidget>(dockWidget)));
130 }
131
132#if QX_DOCK_X11
133 // This code is required for styling the floating widget titlebar for linux
134 // depending on the current focus state
135 if (m_floatingWidget != newFloatingWidget) {
136 if (m_floatingWidget) {
137 updateFloatingWidgetFocusStyle(m_floatingWidget, false);
138 }
139 m_floatingWidget = newFloatingWidget;
140
141 if (m_floatingWidget) {
142 updateFloatingWidgetFocusStyle(m_floatingWidget, true);
143 }
144 }
145#endif
146
147 if (old == dockWidget && !m_forceFocusChangedSignal) {
148 return;
149 }
150
151 m_forceFocusChangedSignal = false;
152 if (dockWidget->isVisible()) {
153 Q_EMIT m_window->focusedDockWidgetChanged(old, dockWidget);
154 } else {
155 m_oldFocusedDockWidget = old;
156 QObject::connect(dockWidget, SIGNAL(visibilityChanged(bool)), q, SLOT(onDockWidgetVisibilityChanged(bool)));
157 }
158}
159
160DockFocusController::DockFocusController(DockWindow *window)
161 : QObject(window)
162{
165 d->m_window = window;
166
167 connect(QApplication::instance(), SIGNAL(focusChanged(QWidget *, QWidget *)), this,
168 SLOT(onApplicationFocusChanged(QWidget *, QWidget *)));
169 connect(QApplication::instance(), SIGNAL(focusWindowChanged(QWindow *)), this,
170 SLOT(onFocusWindowChanged(QWindow *)));
171 connect(d->m_window, SIGNAL(stateRestored()), SLOT(onStateRestored()));
172}
173
178
184{
186
187 if (d->m_window->isRestoringState()) {
188 return;
189 }
190
191 DockWidget *dockWidget = qobject_cast<DockWidget *>(droppedWidget);
192 if (!dockWidget) {
193 DockPanel *panel = qobject_cast<DockPanel *>(droppedWidget);
194 if (panel) {
195 dockWidget = panel->currentDockWidget();
196 }
197 }
198
199 if (!dockWidget) {
200 return;
201 }
202
203 d->m_forceFocusChangedSignal = true;
204 DockManager::setWidgetFocus(dockWidget);
205}
206
214{
216 if (!floatingWidget || d->m_window->isRestoringState()) {
217 return;
218 }
219
220 auto vDockWidget = floatingWidget->property(s_focusedDockWidgetProperty);
221 if (!vDockWidget.isValid()) {
222 return;
223 }
224
225 auto dockWidget = vDockWidget.value<QPointer<DockWidget>>();
226 if (dockWidget) {
227 dockWidget->dockPanel()->setCurrentDockWidget(dockWidget);
228 DockManager::setWidgetFocus(dockWidget);
229 }
230}
231
237{
239 auto dockWidget = tab->dockWidget();
240 if (dockWidget) {
241 d->updateDockWidgetFocus(dockWidget);
242 }
243}
244
249{
251 d->m_tabPressed = Value;
252}
253
255{
256 w->clearFocus();
257 updateDockWidgetFocusStyle(w, false);
258}
259
265{
266 Q_D(const DockFocusController);
267 return d->m_focusedDockWidget.data();
268}
269
274{
276 d->updateDockWidgetFocus(focusedNow);
277}
278
279void DockFocusController::onApplicationFocusChanged(QWidget *focusedOld, QWidget *focusedNow)
280{
281 Q_UNUSED(focusedOld);
283
284 if (d->m_window->isRestoringState() || d->m_tabPressed) {
285 return;
286 }
287
288 if (!focusedNow) {
289 return;
290 }
291
292 DockWidget *dockWidget = qobject_cast<DockWidget *>(focusedNow);
293 if (!dockWidget) {
294 dockWidget = internal::findParent<DockWidget *>(focusedNow);
295 }
296#if QX_DOCK_X11
297 if (!dockWidget) {
298 return;
299 }
300#else
301 if (!dockWidget || dockWidget->tab()->isHidden()) {
302 return;
303 }
304#endif
305
306 d->updateDockWidgetFocus(dockWidget);
307}
308
310{
312 if (!focusWindow) {
313 return;
314 }
315
316 auto vDockWidget = focusWindow->property(s_focusedDockWidgetProperty);
317 if (!vDockWidget.isValid()) {
318 return;
319 }
320
321 auto dockWidget = vDockWidget.value<QPointer<DockWidget>>();
322 if (!dockWidget) {
323 return;
324 }
325
326 d->updateDockWidgetFocus(dockWidget);
327}
328
330{
332
333 if (d->m_window->isRestoringState()) {
334 return;
335 }
336
337 DockPanel *panel = qobject_cast<DockPanel *>(sender());
338 if (!panel || open) {
339 return;
340 }
341 auto container = panel->dockContainer();
342 auto openedDockPanels = container->openedDockPanels();
343 if (openedDockPanels.isEmpty()) {
344 return;
345 }
346
347 d->updateDockWidgetFocus(openedDockPanels[0]->currentDockWidget());
348}
349
351{
353 auto sender = this->sender();
354 auto dockWidget = qobject_cast<DockWidget *>(sender);
355 disconnect(sender, SIGNAL(visibilityChanged(bool)), this, SLOT(onDockWidgetVisibilityChanged(bool)));
356 if (dockWidget && visible) {
357 Q_EMIT d->m_window->focusedDockWidgetChanged(d->m_oldFocusedDockWidget, dockWidget);
358 }
359}
360
362{
364 if (d->m_focusedDockWidget) {
365 updateDockWidgetFocusStyle(d->m_focusedDockWidget, false);
366 }
367}
368
QList< DockPanel * > openedDockPanels() const
Returns the list of dock panels that are not closed If all dock widgets in a dock panel are closed,...
This implements a floating widget that is a dock container that accepts docking of dock widgets like ...
Manages focus styling of dock widgets and handling of focus changes
void onApplicationFocusChanged(QWidget *focusedOld, QWidget *focusedNow)
void setDockWidgetTabFocused(DockTab *tab)
Request focus highlighting for the given dock widget assigned to the tab given in tab parameter
void onDockWidgetVisibilityChanged(bool visible)
void setDockWidgetFocused(DockWidget *focusedNow)
Request a focus change to the given dock widget
void clearDockWidgetFocus(DockWidget *w)
void notifyDockAreaRelocation(QWidget *droppedWidget)
A container needs to call this function if a widget has been dropped into it
void setDockWidgetTabPressed(bool Value)
Notifies the dock focus controller, that a the mouse is pressed or released
DockWidget * focusedDockWidget() const
Returns the dock widget that has focus style in the ui or a nullptr if not dock widget is painted foc...
void onFocusWindowChanged(QWindow *focusWindow)
void notifyFloatingWidgetDrop(DockFloatingContainer *floatingWidget)
This function is called, if a floating widget has been dropped into an new position.
static void setWidgetFocus(QWidgetPtr widget)
DockPanel manages multiple instances of DockWidgets.
Definition dockpanel.h:31
DockContainer * dockContainer() const
DockWidget * currentDockWidget() const
DockWidget * dockWidget() const
Definition docktab.cpp:360
The DockWidget class provides a widget that can be docked inside a DockWindow or floated as a top-lev...
Definition dockwidget.h:31
DockTab * tab() const
Returns the tab widget of this dock widget that is shown in the dock title bar
The central dock window that maintains the complete docking system.
Definition dockwindow.h:36
#define QX_INIT_PRIVATE(Class)
#define QX_DECLARE_PUBLIC(Class)
#define QX_FINI_PRIVATE()
#define QX_DOCK_END_NAMESPACE
#define QX_DOCK_BEGIN_NAMESPACE
QColor window