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 "qpaintdevicewindow_p.h"
5
6#include <QtGui/QGuiApplication>
7#include <QtGui/QScreen>
8
9QT_BEGIN_NAMESPACE
10
11QPaintDeviceWindowPrivate::QPaintDeviceWindowPrivate()
12 = default;
13
14QPaintDeviceWindowPrivate::~QPaintDeviceWindowPrivate()
15 = default;
16
17/*!
18 \class QPaintDeviceWindow
19 \inmodule QtGui
20 \since 5.4
21 \brief Convenience subclass of QWindow that is also a QPaintDevice.
22
23 QPaintDeviceWindow is like a regular QWindow, with the added functionality
24 of being a paint device too. Whenever the content needs to be updated,
25 the virtual paintEvent() function is called. Subclasses, that reimplement
26 this function, can then simply open a QPainter on the window.
27
28 \note This class cannot directly be used in applications. It rather serves
29 as a base for subclasses like QOpenGLWindow.
30
31 \sa QOpenGLWindow
32*/
33
34/*!
35 Marks the entire window as dirty and schedules a repaint.
36
37 \note Subsequent calls to this function before the next paint
38 event will get ignored.
39
40 \note For non-exposed windows the update is deferred until the
41 window becomes exposed again.
42*/
43void QPaintDeviceWindow::update()
44{
45 update(rect: QRect(QPoint(0,0), size()));
46}
47
48/*!
49 Marks the \a rect of the window as dirty and schedules a repaint.
50
51 \note Subsequent calls to this function before the next paint
52 event will get ignored, but \a rect is added to the region to update.
53
54 \note For non-exposed windows the update is deferred until the
55 window becomes exposed again.
56*/
57void QPaintDeviceWindow::update(const QRect &rect)
58{
59 Q_D(QPaintDeviceWindow);
60 d->dirtyRegion += rect;
61 if (isExposed())
62 requestUpdate();
63}
64
65/*!
66 Marks the \a region of the window as dirty and schedules a repaint.
67
68 \note Subsequent calls to this function before the next paint
69 event will get ignored, but \a region is added to the region to update.
70
71 \note For non-exposed windows the update is deferred until the
72 window becomes exposed again.
73*/
74void QPaintDeviceWindow::update(const QRegion &region)
75{
76 Q_D(QPaintDeviceWindow);
77 d->dirtyRegion += region;
78 if (isExposed())
79 requestUpdate();
80}
81
82/*!
83 Handles paint events passed in the \a event parameter.
84
85 The default implementation does nothing. Reimplement this function to
86 perform painting. If necessary, the dirty area is retrievable from
87 the \a event.
88*/
89void QPaintDeviceWindow::paintEvent(QPaintEvent *event)
90{
91 Q_UNUSED(event);
92 // Do nothing
93}
94
95/*!
96 \internal
97 */
98int QPaintDeviceWindow::metric(PaintDeviceMetric metric) const
99{
100 QScreen *screen = this->screen();
101 if (!screen && QGuiApplication::primaryScreen())
102 screen = QGuiApplication::primaryScreen();
103
104 switch (metric) {
105 case PdmWidth:
106 return width();
107 case PdmWidthMM:
108 if (screen)
109 return width() * screen->physicalSize().width() / screen->geometry().width();
110 break;
111 case PdmHeight:
112 return height();
113 case PdmHeightMM:
114 if (screen)
115 return height() * screen->physicalSize().height() / screen->geometry().height();
116 break;
117 case PdmDpiX:
118 if (screen)
119 return qRound(d: screen->logicalDotsPerInchX());
120 break;
121 case PdmDpiY:
122 if (screen)
123 return qRound(d: screen->logicalDotsPerInchY());
124 break;
125 case PdmPhysicalDpiX:
126 if (screen)
127 return qRound(d: screen->physicalDotsPerInchX());
128 break;
129 case PdmPhysicalDpiY:
130 if (screen)
131 return qRound(d: screen->physicalDotsPerInchY());
132 break;
133 case PdmDevicePixelRatio:
134 return int(QWindow::devicePixelRatio());
135 break;
136 case PdmDevicePixelRatioScaled:
137 return int(QWindow::devicePixelRatio() * devicePixelRatioFScale());
138 break;
139 case PdmDevicePixelRatioF_EncodedA:
140 Q_FALLTHROUGH();
141 case PdmDevicePixelRatioF_EncodedB:
142 return QPaintDevice::encodeMetricF(metric, value: QWindow::devicePixelRatio());
143 break;
144 default:
145 break;
146 }
147
148 return QPaintDevice::metric(metric);
149}
150
151/*!
152 \internal
153 */
154void QPaintDeviceWindow::exposeEvent(QExposeEvent *exposeEvent)
155{
156 QWindow::exposeEvent(exposeEvent);
157}
158
159/*!
160 \internal
161 */
162bool QPaintDeviceWindow::event(QEvent *event)
163{
164 Q_D(QPaintDeviceWindow);
165
166 if (event->type() == QEvent::UpdateRequest) {
167 if (handle()) // platform window may be gone when the window is closed during app exit
168 d->handleUpdateEvent();
169 return true;
170 } else if (event->type() == QEvent::Paint) {
171 d->markWindowAsDirty();
172 // Do not rely on exposeEvent->region() as it has some issues for the
173 // time being, namely that it is sometimes in local coordinates,
174 // sometimes relative to the parent, depending on the platform plugin.
175 // We require local coords here.
176 auto region = QRect(QPoint(0, 0), size());
177 d->doFlush(region); // Will end up calling paintEvent
178 return true;
179 } else if (event->type() == QEvent::Resize) {
180 d->handleResizeEvent();
181 }
182
183 return QWindow::event(event);
184}
185
186/*!
187 \internal
188 */
189QPaintDeviceWindow::QPaintDeviceWindow(QPaintDeviceWindowPrivate &dd, QWindow *parent)
190 : QWindow(dd, parent)
191{
192}
193
194/*!
195 \internal
196 */
197QPaintEngine *QPaintDeviceWindow::paintEngine() const
198{
199 return nullptr;
200}
201
202QT_END_NAMESPACE
203
204#include "moc_qpaintdevicewindow.cpp"
205

Provided by KDAB

Privacy Policy
Start learning QML with our Intro Training
Find out more

source code of qtbase/src/gui/kernel/qpaintdevicewindow.cpp