19#include <QApplication>
24static const char *
const s_focusedDockWidgetProperty =
"FocusedDockWidget";
26static void updateDockWidgetFocusStyle(DockWidget *widget,
bool focused)
28 widget->setProperty(
"focused", focused);
29 widget->tab()->setProperty(
"focused", focused);
30 widget->tab()->updateStyle();
31 internal::repolishStyle(widget);
34static void updateDockPanelFocusStyle(DockPanel *panel,
bool focused)
36 panel->setProperty(
"focused", focused);
37 internal::repolishStyle(panel);
38 internal::repolishStyle(panel->titleBar());
42static void updateFloatingWidgetFocusStyle(DockFloatingContainer *floatingWidget,
bool focused)
44 if (floatingWidget->hasNativeTitleBar()) {
47 auto titleBar = qobject_cast<DockFloatingTitleBar *>(floatingWidget->titleBarWidget());
51 titleBar->setProperty(
"focused", focused);
52 titleBar->updateStyle();
56class DockFocusControllerPrivate
61 DockFocusControllerPrivate();
62 void updateDockWidgetFocus(DockWidget *dockWidget);
65 QPointer<DockWidget> m_focusedDockWidget =
nullptr;
66 QPointer<DockWidget> m_oldFocusedDockWidget =
nullptr;
67 QPointer<DockPanel> m_focusedPanel =
nullptr;
69 QPointer<DockFloatingContainer> m_floatingWidget =
nullptr;
71 bool m_tabPressed =
false;
72 bool m_forceFocusChangedSignal =
false;
75DockFocusControllerPrivate::DockFocusControllerPrivate()
83void DockFocusControllerPrivate::updateDockWidgetFocus(DockWidget *dockWidget)
87 if (!dockWidget->features().testFlag(DockWidget::DockWidgetFocusable)) {
90 Q_Q(DockFocusController);
93 auto DockContainer = dockWidget->dockContainer();
95 window = DockContainer->window()->windowHandle();
99 window->setProperty(s_focusedDockWidgetProperty, QVariant::fromValue(QPointer<DockWidget>(dockWidget)));
101 DockPanel *newFocusedPanel =
nullptr;
102 if (m_focusedDockWidget) {
103 updateDockWidgetFocusStyle(m_focusedDockWidget,
false);
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);
116 m_focusedPanel = newFocusedPanel;
117 updateDockPanelFocusStyle(m_focusedPanel,
true);
118 QObject::connect(m_focusedPanel, SIGNAL(viewToggled(
bool)), q, SLOT(onFocusedDockAreaViewToggled(
bool)));
121 DockFloatingContainer *newFloatingWidget =
nullptr;
122 DockContainer = m_focusedDockWidget->dockContainer();
124 newFloatingWidget = DockContainer->floatingWidget();
127 if (newFloatingWidget) {
128 newFloatingWidget->setProperty(s_focusedDockWidgetProperty,
129 QVariant::fromValue(QPointer<DockWidget>(dockWidget)));
135 if (m_floatingWidget != newFloatingWidget) {
136 if (m_floatingWidget) {
137 updateFloatingWidgetFocusStyle(m_floatingWidget,
false);
139 m_floatingWidget = newFloatingWidget;
141 if (m_floatingWidget) {
142 updateFloatingWidgetFocusStyle(m_floatingWidget,
true);
147 if (old == dockWidget && !m_forceFocusChangedSignal) {
151 m_forceFocusChangedSignal =
false;
152 if (dockWidget->isVisible()) {
153 Q_EMIT m_window->focusedDockWidgetChanged(old, dockWidget);
155 m_oldFocusedDockWidget = old;
156 QObject::connect(dockWidget, SIGNAL(visibilityChanged(
bool)), q, SLOT(onDockWidgetVisibilityChanged(
bool)));
167 connect(QApplication::instance(), SIGNAL(focusChanged(QWidget *, QWidget *)),
this,
169 connect(QApplication::instance(), SIGNAL(focusWindowChanged(QWindow *)),
this,
171 connect(d->m_window, SIGNAL(stateRestored()), SLOT(
onStateRestored()));
187 if (d->m_window->isRestoringState()) {
191 DockWidget *dockWidget = qobject_cast<DockWidget *>(droppedWidget);
193 DockPanel *panel = qobject_cast<DockPanel *>(droppedWidget);
203 d->m_forceFocusChangedSignal =
true;
216 if (!floatingWidget || d->m_window->isRestoringState()) {
220 auto vDockWidget = floatingWidget->property(s_focusedDockWidgetProperty);
221 if (!vDockWidget.isValid()) {
225 auto dockWidget = vDockWidget.value<QPointer<DockWidget>>();
227 dockWidget->dockPanel()->setCurrentDockWidget(dockWidget);
241 d->updateDockWidgetFocus(dockWidget);
251 d->m_tabPressed = Value;
257 updateDockWidgetFocusStyle(w,
false);
267 return d->m_focusedDockWidget.data();
276 d->updateDockWidgetFocus(focusedNow);
281 Q_UNUSED(focusedOld);
284 if (d->m_window->isRestoringState() || d->m_tabPressed) {
292 DockWidget *dockWidget = qobject_cast<DockWidget *>(focusedNow);
294 dockWidget = internal::findParent<DockWidget *>(focusedNow);
301 if (!dockWidget || dockWidget->
tab()->isHidden()) {
306 d->updateDockWidgetFocus(dockWidget);
316 auto vDockWidget = focusWindow->property(s_focusedDockWidgetProperty);
317 if (!vDockWidget.isValid()) {
321 auto dockWidget = vDockWidget.value<QPointer<DockWidget>>();
326 d->updateDockWidgetFocus(dockWidget);
333 if (d->m_window->isRestoringState()) {
337 DockPanel *panel = qobject_cast<DockPanel *>(sender());
338 if (!panel || open) {
343 if (openedDockPanels.isEmpty()) {
347 d->updateDockWidgetFocus(openedDockPanels[0]->currentDockWidget());
353 auto sender = this->sender();
354 auto dockWidget = qobject_cast<DockWidget *>(sender);
356 if (dockWidget && visible) {
357 Q_EMIT d->m_window->focusedDockWidgetChanged(d->m_oldFocusedDockWidget, dockWidget);
364 if (d->m_focusedDockWidget) {
365 updateDockWidgetFocusStyle(d->m_focusedDockWidget,
false);
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 onFocusedDockAreaViewToggled(bool open)
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
virtual ~DockFocusController()
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.
DockContainer * dockContainer() const
DockWidget * currentDockWidget() const
DockWidget * dockWidget() const
The central dock window that maintains the complete docking system.
#define QX_INIT_PRIVATE(Class)
#define QX_DECLARE_PUBLIC(Class)
#define QX_FINI_PRIVATE()
#define QX_DOCK_END_NAMESPACE
#define QX_DOCK_BEGIN_NAMESPACE