Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qfocusframe.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qfocusframe.h"
5#include "qstyle.h"
6#include "qbitmap.h"
7#include "qstylepainter.h"
8#include "qstyleoption.h"
9#include "qdebug.h"
10#include <private/qwidget_p.h>
11
13
15{
16 Q_DECLARE_PUBLIC(QFocusFrame)
17 QWidget *widget;
18 QWidget *frameParent;
19 bool showFrameAboveWidget;
20public:
22 widget = nullptr;
23 frameParent = nullptr;
24 sendChildEvents = false;
25 showFrameAboveWidget = false;
26 }
27 void updateSize();
28 void update();
29};
30
32{
33 Q_Q(QFocusFrame);
34 q->setParent(frameParent);
35 updateSize();
36 if (q->parentWidget()->rect().intersects(q->geometry())) {
37 if (showFrameAboveWidget)
38 q->raise();
39 else
40 q->stackUnder(widget);
41 q->show();
42 } else {
43 q->hide();
44 }
45}
46
48{
49 Q_Q(QFocusFrame);
50 if (!widget)
51 return;
52
54 q->initStyleOption(&opt);
55 int vmargin = q->style()->pixelMetric(QStyle::PM_FocusFrameVMargin, &opt, q),
56 hmargin = q->style()->pixelMetric(QStyle::PM_FocusFrameHMargin, &opt, q);
57 QPoint pos(widget->x(), widget->y());
58 if (q->parentWidget() != widget->parentWidget())
59 pos = widget->parentWidget()->mapTo(q->parentWidget(), pos);
60 QRect geom(pos.x()-hmargin, pos.y()-vmargin,
61 widget->width()+(hmargin*2), widget->height()+(vmargin*2));
62 if (q->geometry() == geom)
63 return;
64
65 q->setGeometry(geom);
66
67 opt.rect = q->rect();
69 if (q->style()->styleHint(QStyle::SH_FocusFrame_Mask, &opt, q, &mask))
70 q->setMask(mask.region);
71}
72
81{
82 if (!option)
83 return;
84
85 option->initFrom(this);
86}
87
130
138
148void
150{
151 Q_D(QFocusFrame);
152
153 if (style()->styleHint(QStyle::SH_FocusFrame_AboveWidget, nullptr, this))
154 d->showFrameAboveWidget = true;
155 else
156 d->showFrameAboveWidget = false;
157
158 if (widget == d->widget)
159 return;
160 if (d->widget) {
161 // Remove event filters from the widget hierarchy.
162 QWidget *p = d->widget;
163 do {
164 p->removeEventFilter(this);
165 if (!d->showFrameAboveWidget || p == d->frameParent)
166 break;
167 p = p->parentWidget();
168 }while (p);
169 }
171 d->widget = widget;
172 d->widget->installEventFilter(this);
174 QWidget *prev = nullptr;
175 if (d->showFrameAboveWidget) {
176 // Find the right parent for the focus frame.
177 while (p) {
178 // Traverse the hirerarchy of the 'widget' for setting event filter.
179 // During this if come across toolbar or a top level, use that
180 // as the parent for the focus frame. If we find a scroll area
181 // use its viewport as the parent.
182 bool isScrollArea = false;
183 if (p->isWindow() || p->inherits("QToolBar") || (isScrollArea = p->inherits("QAbstractScrollArea"))) {
184 d->frameParent = p;
185 // The previous one in the hierarchy will be the viewport.
186 if (prev && isScrollArea)
187 d->frameParent = prev;
188 break;
189 } else {
190 p->installEventFilter(this);
191 prev = p;
192 p = p->parentWidget();
193 }
194 }
195 } else {
196 d->frameParent = p;
197 }
198 d->update();
199 } else {
200 d->widget = nullptr;
201 hide();
202 }
203}
204
212QWidget *
214{
215 Q_D(const QFocusFrame);
216 return d->widget;
217}
218
219
221void
223{
224 Q_D(QFocusFrame);
225
226 if (!d->widget)
227 return;
228
229 QStylePainter p(this);
232 const int vmargin = style()->pixelMetric(QStyle::PM_FocusFrameVMargin, &option, this);
233 const int hmargin = style()->pixelMetric(QStyle::PM_FocusFrameHMargin, &option, this);
234 QWidgetPrivate *wd = qt_widget_private(d->widget);
235 QRect rect = wd->clipRect().adjusted(0, 0, hmargin*2, vmargin*2);
236 p.setClipRect(rect);
237 p.drawControl(QStyle::CE_FocusFrame, option);
238}
239
240
242bool
244{
245 Q_D(QFocusFrame);
246 if (o == d->widget) {
247 switch(e->type()) {
248 case QEvent::Move:
249 case QEvent::Resize:
250 d->updateSize();
251 break;
252 case QEvent::Hide:
254 hide();
255 break;
257 if (d->showFrameAboveWidget) {
258 QWidget *w = d->widget;
259 setWidget(nullptr);
260 setWidget(w);
261 } else {
262 d->update();
263 }
264 break;
265 case QEvent::Show:
266 d->update();
267 show();
268 break;
270 setPalette(d->widget->palette());
271 break;
273 if (style()->styleHint(QStyle::SH_FocusFrame_AboveWidget, nullptr, this))
274 raise();
275 else
276 stackUnder(d->widget);
277 break;
278 case QEvent::Destroy:
279 setWidget(nullptr);
280 break;
281 default:
282 break;
283 }
284 } else if (d->showFrameAboveWidget) {
285 // Handle changes in the parent widgets we are monitoring.
286 switch(e->type()) {
287 case QEvent::Move:
288 case QEvent::Resize:
289 d->updateSize();
290 break;
292 raise();
293 break;
294 default:
295 break;
296 }
297 }
298 return false;
299}
300
303{
304 Q_D(QFocusFrame);
305
306 switch (e->type()) {
307 case QEvent::Move:
308 case QEvent::Resize:
309 if (d->widget) {
310 // When we're tracking a widget, we don't allow anyone to move the focus frame around.
311 // We do our best with event filters to make it stay on top of the widget, so trying to
312 // move the frame somewhere else will be flaky at best. This can e.g happen for general
313 // purpose code, like QAbstractScrollView, that bulk-moves all children a certain distance.
314 // So we need to call updateSize() when that happens to ensure that the focus frame stays
315 // on top of the widget.
316 d->updateSize();
317 }
318 break;
319 default:
320 return QWidget::event(e);
321 }
322 return true;
323}
324
326
327#include "moc_qfocusframe.cpp"
\inmodule QtCore
Definition qcoreevent.h:45
@ ParentChange
Definition qcoreevent.h:80
@ StyleChange
Definition qcoreevent.h:136
@ ZOrderChange
Definition qcoreevent.h:173
@ PaletteChange
Definition qcoreevent.h:94
@ Destroy
Definition qcoreevent.h:75
Type type() const
Returns the event type.
Definition qcoreevent.h:304
The QFocusFrame widget provides a focus frame which can be outside of a widget's normal paintable are...
Definition qfocusframe.h:17
QFocusFrame(QWidget *parent=nullptr)
Constructs a QFocusFrame.
~QFocusFrame()
Destructor.
QWidget * widget() const
Returns the currently monitored widget for automatically resize and update.
bool event(QEvent *e) override
\reimp
bool eventFilter(QObject *, QEvent *) override
\reimp
void paintEvent(QPaintEvent *) override
\reimp
void setWidget(QWidget *widget)
QFocusFrame will track changes to widget and resize itself automatically.
virtual void initStyleOption(QStyleOption *option) const
Initialize option with the values from this QFocusFrame.
uint sendChildEvents
Definition qobject.h:80
\inmodule QtCore
Definition qobject.h:103
void installEventFilter(QObject *filterObj)
Installs an event filter filterObj on this object.
Definition qobject.cpp:2339
void removeEventFilter(QObject *obj)
Removes an event filter object obj from this object.
Definition qobject.cpp:2370
The QPaintEvent class contains event parameters for paint events.
Definition qevent.h:486
\inmodule QtCore\reentrant
Definition qpoint.h:25
\inmodule QtCore\reentrant
Definition qrect.h:30
constexpr QRect adjusted(int x1, int y1, int x2, int y2) const noexcept
Returns a new rectangle with dx1, dy1, dx2 and dy2 added respectively to the existing coordinates of ...
Definition qrect.h:370
The QStyleHintReturnMask class provides style hints that return a QRegion.
The QStyleOption class stores the parameters used by QStyle functions.
The QStylePainter class is a convenience class for drawing QStyle elements inside a widget.
@ SH_FocusFrame_AboveWidget
Definition qstyle.h:661
@ SH_FocusFrame_Mask
Definition qstyle.h:638
@ CE_FocusFrame
Definition qstyle.h:220
@ PM_FocusFrameVMargin
Definition qstyle.h:498
@ PM_FocusFrameHMargin
Definition qstyle.h:499
virtual int pixelMetric(PixelMetric metric, const QStyleOption *option=nullptr, const QWidget *widget=nullptr) const =0
Returns the value of the given pixel metric.
QRect clipRect() const
Definition qwidget.cpp:1865
The QWidget class is the base class of all user interface objects.
Definition qwidget.h:99
void raise()
Raises this widget to the top of the parent widget's stack.
friend Q_WIDGETS_EXPORT QWidgetPrivate * qt_widget_private(QWidget *widget)
void setPalette(const QPalette &)
Definition qwidget.cpp:4530
int width
the width of the widget excluding any window frame
Definition qwidget.h:114
void hide()
Hides the widget.
Definition qwidget.cpp:8135
int height
the height of the widget excluding any window frame
Definition qwidget.h:115
QRect rect
the internal geometry of the widget excluding any window frame
Definition qwidget.h:116
int y
the y coordinate of the widget relative to its parent and including any window frame
Definition qwidget.h:110
void show()
Shows the widget and its child widgets.
Definition qwidget.cpp:7875
void stackUnder(QWidget *)
Places the widget under w in the parent widget's stack.
int x
the x coordinate of the widget relative to its parent including any window frame
Definition qwidget.h:109
void update()
Updates the widget unless updates are disabled or the widget is hidden.
bool event(QEvent *event) override
This is the main event handler; it handles event event.
Definition qwidget.cpp:8866
QStyle * style() const
Definition qwidget.cpp:2600
QWidget * parentWidget() const
Returns the parent of this widget, or \nullptr if it does not have any parent widget.
Definition qwidget.h:904
QPointF mapTo(const QWidget *, const QPointF &) const
Translates the widget coordinate pos to the coordinate system of parent.
Definition qwidget.cpp:4197
bool isWindow() const
Returns true if the widget is an independent window, otherwise returns false.
Definition qwidget.h:811
Qt::WindowType windowType() const
Returns the window type of this widget.
Definition qwidget.h:801
QOpenGLWidget * widget
[1]
QStyleOptionButton opt
Combined button and popup list for selecting options.
@ WA_TransparentForMouseEvents
Definition qnamespace.h:317
@ WA_NoChildEventsForParent
Definition qnamespace.h:324
@ WA_AcceptDrops
Definition qnamespace.h:346
@ NoFocus
Definition qnamespace.h:107
@ SubWindow
Definition qnamespace.h:216
GLfloat GLfloat GLfloat w
[0]
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLfloat GLfloat p
[1]
GLuint GLenum option
app setAttribute(Qt::AA_DontShowIconsInMenus)