KDDockWidgets API Documentation 1.7
Loading...
Searching...
No Matches
FocusScope.cpp
Go to the documentation of this file.
1/*
2 This file is part of KDDockWidgets.
3
4 SPDX-FileCopyrightText: 2019-2023 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
5 Author: SĂ©rgio Martins <sergio.martins@kdab.com>
6
7 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
8
9 Contact KDAB at <info@kdab.com> for commercial licensing options.
10*/
11
19#include "FocusScope.h"
20#include "DockWidgetBase.h"
21
22#include "private/TitleBar_p.h"
23#include "private/Frame_p.h"
24#include "private/DockRegistry_p.h"
25
26#include <QObject>
27#include <QGuiApplication>
28#include <QPointer>
29
30using namespace KDDockWidgets;
31
32// Our Private inherits from QObject since FocusScope can't (Since Frame is already QObject)
33class FocusScope::Private : public QObject // clazy:exclude=missing-qobject-macro (breaks unity build with earlier cmake due to including .moc here.)
34{
35public:
36 Private(FocusScope *qq, QWidgetAdapter *thisWidget)
37 : q(qq)
38 , m_thisWidget(thisWidget)
39 {
41 this, &Private::onFocusObjectChanged);
42
43 onFocusObjectChanged(qApp->focusObject());
44 m_inCtor = false;
45 }
46
48 bool lastFocusedIsTabWidget() const
49 {
50 if (!m_lastFocusedInScope)
51 return false;
52
53 if (auto metaObj = m_lastFocusedInScope->metaObject()) {
54 const auto className = QLatin1String(metaObj->className());
55
56 return className == QLatin1String("KDDockWidgets::TabBarWidget")
57 || className == QLatin1String("KDDockWidgets::TabBarQuick");
58 }
59
60 return false;
61 }
62
63 ~Private() override;
64
65 void setIsFocused(bool);
66 void onFocusObjectChanged(QObject *);
67 bool isInFocusScope(WidgetType *) const;
68
69 FocusScope *const q;
70 QWidgetAdapter *const m_thisWidget;
71 bool m_isFocused = false;
72 bool m_inCtor = true;
73 QPointer<WidgetType> m_lastFocusedInScope;
74};
75
76FocusScope::Private::~Private()
77{
78}
79
80FocusScope::FocusScope(QWidgetAdapter *thisWidget)
81 : d(new Private(this, thisWidget))
82{
83}
84
86{
87 delete d;
88}
89
91{
92 return d->m_isFocused;
93}
94
96{
97 return d->m_lastFocusedInScope;
98}
99
101{
102 if (d->m_lastFocusedInScope && !d->lastFocusedIsTabWidget()) {
103 // When we focus the FocusScope, we give focus to the last focused widget, but let's
104 // do better than focusing a tab widget. The tab widget itself being focused isn't
105 // very useful.
106 d->m_lastFocusedInScope->setFocus(reason);
107 } else {
108 if (auto frame = qobject_cast<Frame *>(d->m_thisWidget)) {
109 if (DockWidgetBase *dw = frame->currentDockWidget()) {
110 if (auto guest = dw->widget()) {
111 if (guest->focusPolicy() != Qt::NoFocus)
112 guest->setFocus(reason);
113 }
114 }
115 } else {
116 // Not a use case right now
117 d->m_thisWidget->setFocus(reason);
118 }
119 }
120}
121
122void FocusScope::Private::setIsFocused(bool is)
123{
124 if (is != m_isFocused) {
125 m_isFocused = is;
126
127 if (!m_inCtor) // Hack so we don't call pure-virtual
128 /* Q_EMIT */ q->isFocusedChangedCallback();
129 }
130}
131
132void FocusScope::Private::onFocusObjectChanged(QObject *obj)
133{
134 auto widget = qobject_cast<WidgetType *>(obj);
135 if (!widget) {
136 setIsFocused(false);
137 return;
138 }
139
140 const bool is = isInFocusScope(widget);
141 if (is && m_lastFocusedInScope != widget && !qobject_cast<TitleBar *>(obj)) {
142 m_lastFocusedInScope = widget;
143 setIsFocused(is);
144 /* Q_EMIT */ q->focusedWidgetChangedCallback();
145 } else {
146 setIsFocused(is);
147 }
148}
149
150bool FocusScope::Private::isInFocusScope(WidgetType *widget) const
151{
152 WidgetType *p = widget;
153 while (p) {
154 if (p == m_thisWidget)
155 return true;
156
157 p = KDDockWidgets::Private::parentWidget(p);
158 }
159
160 return false;
161}
The DockWidget base-class that's shared between QtWidgets and QtQuick stack.
FocusScope.
The DockWidget base-class. DockWidget and DockWidgetBase are only split in two so we can share some c...
Allows to implement a similar functionality to QtQuick's FocusScope item, in QtWidgets.
Definition FocusScope.h:28
bool isFocused() const
Returns true if this FocusScope is focused. This is similar to the QWidget::hasFocus(),...
void focus(Qt::FocusReason=Qt::OtherFocusReason)
Sets focus on this scope.
WidgetType * focusedWidget() const
Returns the widget that's focused in this scope The widget itself might not have focus as in QWidget:...
FocusScope(QWidgetAdapter *thisWidget)
constructor
void focusObjectChanged(QObject *focusObject)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
T qobject_cast(QObject *object)
FocusReason

© 2019-2023 Klarälvdalens Datakonsult AB (KDAB)
"The Qt, C++ and OpenGL Experts"
https://www.kdab.com/
KDDockWidgets
Advanced Dock Widget Framework for Qt
https://www.kdab.com/development-resources/qt-tools/kddockwidgets/
Generated on Wed Nov 1 2023 00:02:31 for KDDockWidgets API Documentation by doxygen 1.9.8