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
qquickstyleitem.h
Go to the documentation of this file.
1// Copyright (C) 2020 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#ifndef QQUICKSTYLEITEM_H
5#define QQUICKSTYLEITEM_H
6
7#include <QtCore/qdebug.h>
8#include <QtQml/qqml.h>
9#include <QtQml/qqmlinfo.h>
10#include <QtQuick/private/qquickitem_p.h>
11#include <QtQuickTemplates2/private/qquickcontrol_p.h>
12
13#include "qquicknativestyle.h"
14#include "qquickstyle.h"
15#include "qquickstyleoption.h"
16
17#include <QtCore/qpointer.h>
18
19// Work-around for now, to avoid creator getting confused
20// about missing macros. Should eventually be defined
21// in qt declarative somewhere I assume.
22#ifndef QML_NAMED_ELEMENT
23#define QML_NAMED_ELEMENT(NAME)
24#define QML_UNCREATABLE(NAME)
25#endif
26
27#ifdef QT_DEBUG
28#define qqc2Debug() if (m_debugFlags.testFlag(Debug)) qDebug() << __FUNCTION__ << ":"
29#define qqc2Info() if (m_debugFlags.testFlag(Info)) qDebug() << __FUNCTION__ << ":"
30#define qqc2InfoHeading(HEADING) if (m_debugFlags.testFlag(Info)) qDebug() << "--------" << HEADING << "--------"
31#else
32#define qqc2Debug() if (false) qDebug()
33#define qqc2Info() if (false) qDebug()
34#define qqc2InfoHeading(HEADING) if (false) qDebug()
35#endif
36
38
39using namespace QQC2;
40
42{
44
45 Q_PROPERTY(int left READ left())
46 Q_PROPERTY(int top READ top())
49
50 QML_NAMED_ELEMENT(stylemargins)
52
53public:
56 QQuickStyleMargins(const QMargins &margins) : m_margins(margins) {}
57 QQuickStyleMargins(const QRect &outer, const QRect &inner)
58 {
59 const int left = inner.left() - outer.left();
60 const int top = inner.top() - outer.top();
61 const int right = outer.right() - inner.right();
62 const int bottom = outer.bottom() - inner.bottom();
64 }
65
66 inline void operator=(const QQuickStyleMargins &other) { m_margins = other.m_margins; }
67 inline bool operator==(const QQuickStyleMargins &other) const { return other.m_margins == m_margins; }
68 inline bool operator!=(const QQuickStyleMargins &other) const { return other.m_margins != m_margins; }
69
70 inline int left() const { return m_margins.left(); }
71 inline int right() const { return m_margins.right(); }
72 inline int top() const { return m_margins.top(); }
73 inline int bottom() const { return m_margins.bottom(); }
74
76};
77
79
81{
82 /*
83 A QQuickStyleItem is responsible for drawing a control, or a part of it.
84
85 'minimumSize' should be the minimum possible size that the item can
86 have _without_ taking content size into consideration (and still render
87 correctly). This will also be the size of the image that the item is drawn
88 to, unless QQuickStyleItem::useNinePatchImage is set to false. In that
89 case, the size of the image will be set to the size of the item instead
90 (which is set from QML, and will typically be the same as the size of the control).
91 The default way to calculate minimumSize is to call style()->sizeFromContents()
92 with an empty content size. This is not always well supported by the legacy QStyle
93 implementation, which means that you might e.g get an empty size in return.
94 For those cases, the correct solution is to go into the specific platform style
95 and change it so that it returns a valid size also for this special case.
96
97 'implicitSize' should reflect the preferred size of the item, taking the
98 given content size (as set from QML) into account. But not all controls
99 have contents (slider), and for many controls, the content/label is instead
100 placed outside the item/background image (radiobutton). In both cases, the
101 size of the item will not include the content size, and implicitSize can
102 usually be set equal to minimumSize instead.
103
104 'contentRect' should be the free space where the contents can be placed. Note that
105 this rect doesn't need to have the same size as the contentSize provided as input
106 to the style item. Instead, QStyle can typically calculate a rect that is bigger, to
107 e.g center the contents inside the control.
108
109 'layoutRect' can be set to shift the position of the whole control so
110 that aligns correctly with the other controls. This is important for
111 controls that draws e.g shadows or focus rings. Such adornments should
112 be painted, but not be included when aligning the controls.
113 */
114
118 QRect layoutRect; // If invalid, there are no layout margins!
121};
122
124
126{
128
129 // Input
130 Q_PROPERTY(QQuickItem *control MEMBER m_control NOTIFY controlChanged)
133 Q_PROPERTY(bool useNinePatchImage MEMBER m_useNinePatchImage)
135
136 // Output
140 Q_PROPERTY(int transitionDuration MEMBER m_transitionDuration CONSTANT)
141
142 QML_NAMED_ELEMENT(StyleItem)
143 QML_UNCREATABLE("StyleItem is an abstract base class.")
144
145public:
152 Q_DECLARE_FLAGS(DirtyFlags, DirtyFlag)
153
161
162
163#ifdef QT_DEBUG
164 enum DebugFlag {
165 NoDebug = 0x000,
166 Debug = 0x001,
167 Info = 0x002,
168 ImageRect = 0x004,
169 ContentRect = 0x008,
170 LayoutRect = 0x010,
171 Unscaled = 0x020,
172 InputContentSize = 0x040,
173 DontUseNinePatchImage = 0x080,
174 NinePatchMargins = 0x100,
175 SaveImage = 0x200,
176 };
177 Q_DECLARE_FLAGS(DebugFlags, DebugFlag)
178 Q_FLAG(DebugFlags)
179#endif
180
181 explicit QQuickStyleItem(QQuickItem *parent = nullptr);
182 ~QQuickStyleItem() override;
183
188
191 QSize minimumSize() const;
192 QSize imageSize() const;
193 qreal focusFrameRadius() const;
194
196
197 void markGeometryDirty();
198 void markImageDirty();
199
206
207protected:
208 void componentComplete() override;
209 QSGNode *updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *updatePaintNodeData) override;
210 void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
211 void itemChange(ItemChange change, const ItemChangeData &data) override;
212 void updatePolish() override;
213
214 virtual void connectToControl() const;
215 virtual void paintEvent(QPainter *painter) const = 0;
217
218 static QStyle::State controlSize(QQuickItem *item);
219 void initStyleOptionBase(QStyleOption &styleOption) const;
220
221 inline QSize contentSize() const { return QSize(qCeil(m_contentSize.width()), qCeil(m_contentSize.height())); }
222 inline static QStyle *style() { return QQuickNativeStyle::style(); }
223
224 template <class T> inline const T* control() const {
225#ifdef QT_DEBUG
226 if (!dynamic_cast<T *>(m_control.data())) {
227 qmlWarning(this) << "control property is not of correct type";
228 Q_UNREACHABLE();
229 }
230#endif
231 return static_cast<T *>(m_control.data());
232 }
233
234#ifdef QT_DEBUG
235 DebugFlags m_debugFlags = NoDebug;
236#endif
238
239private:
240 bool event(QEvent *event) override;
241 inline void updateGeometry();
242 inline void paintControlToImage();
243
244 int dprAlignedSize(const int size) const;
245
246#ifdef QT_DEBUG
247 void addDebugInfo();
248#endif
249
250private:
251 QPointer<QQuickItem> m_control;
252 QImage m_paintedImage;
253 StyleItemGeometry m_styleItemGeometry;
254 QSizeF m_contentSize;
255
256 DirtyFlags m_dirty = Everything;
257 bool m_useNinePatchImage = true;
258 bool m_polishing = false;
259 mutable QQuickWindow *m_connectedWindow = nullptr;
260
261#ifdef Q_OS_MACOS
262 int m_transitionDuration = 150;
263#else
264 int m_transitionDuration = 400;
265#endif
266
267private:
269};
270
271Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickStyleItem::DirtyFlags)
272
273#ifdef QT_DEBUG
274Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickStyleItem::DebugFlags)
275#endif
276
278
279#endif // QQUICKSTYLEITEM_H
\inmodule QtCore
\inmodule QtCore
Definition qcoreevent.h:45
\reentrant
Definition qfont.h:22
\inmodule QtGui
Definition qimage.h:37
\inmodule QtCore
Definition qmargins.h:24
constexpr int bottom() const noexcept
Returns the bottom margin.
Definition qmargins.h:115
constexpr int left() const noexcept
Returns the left margin.
Definition qmargins.h:106
constexpr int right() const noexcept
Returns the right margin.
Definition qmargins.h:112
constexpr int top() const noexcept
Returns the top margin.
Definition qmargins.h:109
The QPainter class performs low-level painting on widgets and other paint devices.
Definition qpainter.h:46
T * data() const noexcept
Definition qpointer.h:73
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
Definition qquickitem.h:63
QQuickItem * parent
\qmlproperty Item QtQuick::Item::parent This property holds the visual parent of the item.
Definition qquickitem.h:67
ItemChange
Used in conjunction with QQuickItem::itemChange() to notify the item about certain types of changes.
Definition qquickitem.h:144
virtual void connectToControl() const
void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override
void layoutMarginsChanged()
QQuickStyleMargins contentPadding
qreal focusFrameRadius() const
virtual StyleItemGeometry calculateGeometry()=0
OverrideState m_overrideState
virtual void paintEvent(QPainter *painter) const =0
QSize imageSize() const
void itemChange(ItemChange change, const ItemChangeData &data) override
Called when change occurs for this item.
const T * control() const
void minimumSizeChanged()
virtual Q_INVOKABLE QFont styleFont(QQuickItem *control) const
OverrideState overrideState
qreal contentWidth()
minimumSizeChangedint transitionDuration
layoutMarginsChangedQSize minimumSize
QSize contentSize() const
void updatePolish() override
This function should perform any layout as required for this item.
void setContentHeight(qreal contentHeight)
~QQuickStyleItem() override
void contentPaddingChanged()
static QStyle::State controlSize(QQuickItem *item)
contentPaddingChangedQQuickStyleMargins layoutMargins
void setContentWidth(qreal contentWidth)
qreal contentHeight()
void controlChanged()
void initStyleOptionBase(QStyleOption &styleOption) const
QQuickItem * control
QQuickStyleItem(QQuickItem *parent=nullptr)
static QStyle * style()
QSGNode * updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *updatePaintNodeData) override
Called on the render thread when it is time to sync the state of the item with the scene graph.
void componentComplete() override
\reimp Derived classes should call the base class method before adding their own actions to perform a...
QQuickStyleMargins(const QMargins &margins)
bool operator!=(const QQuickStyleMargins &other) const
void operator=(const QQuickStyleMargins &other)
QQuickStyleMargins(const QQuickStyleMargins &other)
bool operator==(const QQuickStyleMargins &other) const
QQuickStyleMargins(const QRect &outer, const QRect &inner)
\qmltype Window \instantiates QQuickWindow \inqmlmodule QtQuick
\inmodule QtCore\reentrant
Definition qrect.h:484
\inmodule QtCore\reentrant
Definition qrect.h:30
\group qtquick-scenegraph-nodes \title Qt Quick Scene Graph Node classes
Definition qsgnode.h:37
\inmodule QtCore
Definition qsize.h:208
constexpr qreal width() const noexcept
Returns the width.
Definition qsize.h:332
constexpr qreal height() const noexcept
Returns the height.
Definition qsize.h:335
\inmodule QtCore
Definition qsize.h:25
Combined button and popup list for selecting options.
#define Q_DECLARE_FLAGS(Flags, Enum)
Definition qflags.h:174
#define Q_DECLARE_OPERATORS_FOR_FLAGS(Flags)
Definition qflags.h:194
int qCeil(T v)
Definition qmath.h:36
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLdouble GLdouble GLdouble GLdouble top
GLdouble GLdouble right
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLint left
GLint GLint bottom
struct _cl_event * event
Q_QML_EXPORT QQmlInfo qmlWarning(const QObject *me)
#define QML_UNCREATABLE(NAME)
QDebug operator<<(QDebug debug, const QQuickStyleMargins &padding)
#define QML_NAMED_ELEMENT(NAME)
#define Q_ENUM(x)
#define Q_PROPERTY(...)
#define Q_OBJECT
#define Q_FLAG(x)
#define Q_INVOKABLE
#define Q_GADGET
#define Q_SIGNALS
double qreal
Definition qtypes.h:187
static const uint base
Definition qurlidna.cpp:20
QSharedPointer< T > other(t)
[5]
QGraphicsItem * item
QPainter painter(this)
[7]
\inmodule QtQuick
Definition qquickitem.h:159