Qt 6.x
The Qt SDK
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// Work-around for now, to avoid creator getting confused
18// about missing macros. Should eventually be defined
19// in qt declarative somewhere I assume.
20#ifndef QML_NAMED_ELEMENT
21#define QML_NAMED_ELEMENT(NAME)
22#define QML_UNCREATABLE(NAME)
23#endif
24
25#ifdef QT_DEBUG
26#define qqc2Debug() if (m_debugFlags.testFlag(Debug)) qDebug() << __FUNCTION__ << ":"
27#define qqc2Info() if (m_debugFlags.testFlag(Info)) qDebug() << __FUNCTION__ << ":"
28#define qqc2InfoHeading(HEADING) if (m_debugFlags.testFlag(Info)) qDebug() << "--------" << HEADING << "--------"
29#else
30#define qqc2Debug() if (false) qDebug()
31#define qqc2Info() if (false) qDebug()
32#define qqc2InfoHeading(HEADING) if (false) qDebug()
33#endif
34
36
37using namespace QQC2;
38
40{
42
43 Q_PROPERTY(int left READ left())
44 Q_PROPERTY(int top READ top())
45 Q_PROPERTY(int right READ right())
46 Q_PROPERTY(int bottom READ bottom())
47
48 QML_NAMED_ELEMENT(stylemargins)
50
51public:
54 QQuickStyleMargins(const QMargins &margins) : m_margins(margins) {}
55 QQuickStyleMargins(const QRect &outer, const QRect &inner)
56 {
57 const int left = inner.left() - outer.left();
58 const int top = inner.top() - outer.top();
59 const int right = outer.right() - inner.right();
60 const int bottom = outer.bottom() - inner.bottom();
62 }
63
64 inline void operator=(const QQuickStyleMargins &other) { m_margins = other.m_margins; }
65 inline bool operator==(const QQuickStyleMargins &other) const { return other.m_margins == m_margins; }
66 inline bool operator!=(const QQuickStyleMargins &other) const { return other.m_margins != m_margins; }
67
68 inline int left() const { return m_margins.left(); }
69 inline int right() const { return m_margins.right(); }
70 inline int top() const { return m_margins.top(); }
71 inline int bottom() const { return m_margins.bottom(); }
72
74};
75
77
79{
80 /*
81 A QQuickStyleItem is responsible for drawing a control, or a part of it.
82
83 'minimumSize' should be the minimum possible size that the item can
84 have _without_ taking content size into consideration (and still render
85 correctly). This will also be the size of the image that the item is drawn
86 to, unless QQuickStyleItem::useNinePatchImage is set to false. In that
87 case, the size of the image will be set to the size of the item instead
88 (which is set from QML, and will typically be the same as the size of the control).
89 The default way to calculate minimumSize is to call style()->sizeFromContents()
90 with an empty content size. This is not always well supported by the legacy QStyle
91 implementation, which means that you might e.g get an empty size in return.
92 For those cases, the correct solution is to go into the specific platform style
93 and change it so that it returns a valid size also for this special case.
94
95 'implicitSize' should reflect the preferred size of the item, taking the
96 given content size (as set from QML) into account. But not all controls
97 have contents (slider), and for many controls, the content/label is instead
98 placed outside the item/background image (radiobutton). In both cases, the
99 size of the item will not include the content size, and implicitSize can
100 usually be set equal to minimumSize instead.
101
102 'contentRect' should be the free space where the contents can be placed. Note that
103 this rect doesn't need to have the same size as the contentSize provided as input
104 to the style item. Instead, QStyle can typically calculate a rect that is bigger, to
105 e.g center the contents inside the control.
106
107 'layoutRect' can be set to shift the position of the whole control so
108 that aligns correctly with the other controls. This is important for
109 controls that draws e.g shadows or focus rings. Such adornments should
110 be painted, but not be included when aligning the controls.
111 */
112
116 QRect layoutRect; // If invalid, there are no layout margins!
119};
120
122
124{
126
127 // Input
128 Q_PROPERTY(QQuickItem *control MEMBER m_control NOTIFY controlChanged)
131 Q_PROPERTY(bool useNinePatchImage MEMBER m_useNinePatchImage)
133
134 // Output
138 Q_PROPERTY(int transitionDuration MEMBER m_transitionDuration CONSTANT)
139
140 QML_NAMED_ELEMENT(StyleItem)
141 QML_UNCREATABLE("StyleItem is an abstract base class.")
142
143public:
148 Everything = 255
149 };
150 Q_DECLARE_FLAGS(DirtyFlags, DirtyFlag)
151
153 None = 0,
157 };
159
160
161#ifdef QT_DEBUG
162 enum DebugFlag {
163 NoDebug = 0x000,
164 Debug = 0x001,
165 Info = 0x002,
166 ImageRect = 0x004,
167 ContentRect = 0x008,
168 LayoutRect = 0x010,
169 Unscaled = 0x020,
170 InputContentSize = 0x040,
171 DontUseNinePatchImage = 0x080,
172 NinePatchMargins = 0x100,
173 SaveImage = 0x200,
174 };
175 Q_DECLARE_FLAGS(DebugFlags, DebugFlag)
176 Q_FLAG(DebugFlags)
177#endif
178
179 explicit QQuickStyleItem(QQuickItem *parent = nullptr);
180 ~QQuickStyleItem() override;
181
186
189 QSize minimumSize() const;
190 QSize imageSize() const;
191 qreal focusFrameRadius() const;
192
194
195 void markGeometryDirty();
196 void markImageDirty();
197
204
205protected:
206 void componentComplete() override;
207 QSGNode *updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *updatePaintNodeData) override;
208 void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
209 void itemChange(ItemChange change, const ItemChangeData &data) override;
210 void updatePolish() override;
211
212 virtual void connectToControl() const;
213 virtual void paintEvent(QPainter *painter) const = 0;
215
216 static QStyle::State controlSize(QQuickItem *item);
217 void initStyleOptionBase(QStyleOption &styleOption) const;
218
219 inline QSize contentSize() const { return QSize(qCeil(m_contentSize.width()), qCeil(m_contentSize.height())); }
220 inline static QStyle *style() { return QQuickNativeStyle::style(); }
221
222 template <class T> inline const T* control() const {
223#ifdef QT_DEBUG
224 if (!dynamic_cast<T *>(m_control.data())) {
225 qmlWarning(this) << "control property is not of correct type";
226 Q_UNREACHABLE();
227 }
228#endif
229 return static_cast<T *>(m_control.data());
230 }
231
232#ifdef QT_DEBUG
233 DebugFlags m_debugFlags = NoDebug;
234#endif
236
237private:
238 bool event(QEvent *event) override;
239 inline void updateGeometry();
240 inline void paintControlToImage();
241
242 int dprAlignedSize(const int size) const;
243
244#ifdef QT_DEBUG
245 void addDebugInfo();
246#endif
247
248private:
249 QPointer<QQuickItem> m_control;
250 QImage m_paintedImage;
251 StyleItemGeometry m_styleItemGeometry;
252 QSizeF m_contentSize;
253
254 DirtyFlags m_dirty = Everything;
255 bool m_useNinePatchImage = true;
256 bool m_polishing = false;
257 mutable QQuickWindow *m_connectedWindow = nullptr;
258
259#ifdef Q_OS_MACOS
260 int m_transitionDuration = 150;
261#else
262 int m_transitionDuration = 400;
263#endif
264
265private:
267};
268
269Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickStyleItem::DirtyFlags)
270
271#ifdef QT_DEBUG
272Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickStyleItem::DebugFlags)
273#endif
274
276
278
279#endif // QQUICKSTYLEITEM_H
\inmodule QtCore
\inmodule QtCore
Definition qcoreevent.h:45
\reentrant
Definition qfont.h:20
\inmodule QtGui
Definition qimage.h:37
\inmodule QtCore
Definition qmargins.h:23
constexpr int bottom() const noexcept
Returns the bottom margin.
Definition qmargins.h:119
constexpr int left() const noexcept
Returns the left margin.
Definition qmargins.h:110
constexpr int right() const noexcept
Returns the right margin.
Definition qmargins.h:116
constexpr int top() const noexcept
Returns the top margin.
Definition qmargins.h:113
The QPainter class performs low-level painting on widgets and other paint devices.
Definition qpainter.h:46
\inmodule QtCore
Definition qpointer.h:18
T * data() const
Definition qpointer.h:56
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
Definition qquickitem.h:64
QQuickItem * parent
\qmlproperty Item QtQuick::Item::parent This property holds the visual parent of the item.
Definition qquickitem.h:68
ItemChange
Used in conjunction with QQuickItem::itemChange() to notify the item about certain types of changes.
Definition qquickitem.h:143
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
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:483
\inmodule QtCore\reentrant
Definition qrect.h:30
constexpr int bottom() const noexcept
Returns the y-coordinate of the rectangle's bottom edge.
Definition qrect.h:181
constexpr int top() const noexcept
Returns the y-coordinate of the rectangle's top edge.
Definition qrect.h:175
constexpr int left() const noexcept
Returns the x-coordinate of the rectangle's left edge.
Definition qrect.h:172
constexpr int right() const noexcept
Returns the x-coordinate of the rectangle's right edge.
Definition qrect.h:178
\group qtquick-scenegraph-nodes \title Qt Quick Scene Graph Node classes
Definition qsgnode.h:37
\inmodule QtCore
Definition qsize.h:207
constexpr qreal width() const noexcept
Returns the width.
Definition qsize.h:321
constexpr qreal height() const noexcept
Returns the height.
Definition qsize.h:324
\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 left
GLint GLint bottom
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
struct _cl_event * event
#define QML_DECLARE_TYPE(TYPE)
Definition qqml.h:19
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:92
QSharedPointer< T > other(t)
[5]
QGraphicsItem * item
QPainter painter(this)
[7]
\inmodule QtQuick
Definition qquickitem.h:158