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 | #ifndef QQUICKANCHORS_P_P_H |
5 | #define QQUICKANCHORS_P_P_H |
6 | |
7 | // |
8 | // W A R N I N G |
9 | // ------------- |
10 | // |
11 | // This file is not part of the Qt API. It exists purely as an |
12 | // implementation detail. This header file may change from version to |
13 | // version without notice, or even be removed. |
14 | // |
15 | // We mean it. |
16 | // |
17 | |
18 | #include "qquickanchors_p.h" |
19 | #include "qquickitemchangelistener_p.h" |
20 | #include <private/qobject_p.h> |
21 | |
22 | QT_BEGIN_NAMESPACE |
23 | |
24 | class Q_QUICK_PRIVATE_EXPORT QQuickAnchorLine |
25 | { |
26 | Q_GADGET |
27 | QML_ANONYMOUS |
28 | QML_ADDED_IN_VERSION(2, 0) |
29 | public: |
30 | QQuickAnchorLine() {} |
31 | QQuickAnchorLine(QQuickItem *i, QQuickAnchors::Anchor l) : item(i), anchorLine(l) {} |
32 | QQuickAnchorLine(QQuickItem *i, uint l) |
33 | : item(i) |
34 | , anchorLine(static_cast<QQuickAnchors::Anchor>(l)) |
35 | { Q_ASSERT(l < ((QQuickAnchors::BaselineAnchor << 1) - 1)); } |
36 | |
37 | QQuickItem *item = nullptr; |
38 | QQuickAnchors::Anchor anchorLine = QQuickAnchors::InvalidAnchor; |
39 | }; |
40 | |
41 | inline bool operator==(const QQuickAnchorLine& a, const QQuickAnchorLine& b) |
42 | { |
43 | return a.item == b.item && a.anchorLine == b.anchorLine; |
44 | } |
45 | |
46 | class QQuickAnchorsPrivate : public QObjectPrivate, public QQuickItemChangeListener |
47 | { |
48 | Q_DECLARE_PUBLIC(QQuickAnchors) |
49 | public: |
50 | QQuickAnchorsPrivate(QQuickItem *i) |
51 | : leftMargin(0) |
52 | , rightMargin(0) |
53 | , topMargin(0) |
54 | , bottomMargin(0) |
55 | , margins(0) |
56 | , vCenterOffset(0) |
57 | , hCenterOffset(0) |
58 | , baselineOffset(0) |
59 | , item(i) |
60 | , fill(nullptr) |
61 | , centerIn(nullptr) |
62 | , leftAnchorItem(nullptr) |
63 | , rightAnchorItem(nullptr) |
64 | , topAnchorItem(nullptr) |
65 | , bottomAnchorItem(nullptr) |
66 | , vCenterAnchorItem(nullptr) |
67 | , hCenterAnchorItem(nullptr) |
68 | , baselineAnchorItem(nullptr) |
69 | , leftAnchorLine(QQuickAnchors::InvalidAnchor) |
70 | , leftMarginExplicit(false) |
71 | , rightAnchorLine(QQuickAnchors::InvalidAnchor) |
72 | , rightMarginExplicit(false) |
73 | , topAnchorLine(QQuickAnchors::InvalidAnchor) |
74 | , topMarginExplicit(false) |
75 | , bottomAnchorLine(QQuickAnchors::InvalidAnchor) |
76 | , bottomMarginExplicit(false) |
77 | , vCenterAnchorLine(QQuickAnchors::InvalidAnchor) |
78 | , updatingMe(false) |
79 | , hCenterAnchorLine(QQuickAnchors::InvalidAnchor) |
80 | , inDestructor(false) |
81 | , baselineAnchorLine(QQuickAnchors::InvalidAnchor) |
82 | , centerAligned(true) |
83 | , usedAnchors(QQuickAnchors::InvalidAnchor) |
84 | , componentComplete(true) |
85 | , updatingFill(0) |
86 | , updatingCenterIn(0) |
87 | , updatingHorizontalAnchor(0) |
88 | , updatingVerticalAnchor(0) |
89 | { |
90 | } |
91 | |
92 | void clearItem(QQuickItem *); |
93 | |
94 | QQuickGeometryChange calculateDependency(QQuickItem *) const; |
95 | void addDepend(QQuickItem *); |
96 | void remDepend(QQuickItem *); |
97 | bool isItemComplete() const; |
98 | |
99 | void setItemHeight(qreal); |
100 | void setItemWidth(qreal); |
101 | void setItemX(qreal); |
102 | void setItemY(qreal); |
103 | void setItemPos(const QPointF &); |
104 | void setItemSize(const QSizeF &); |
105 | |
106 | void update(); |
107 | void updateOnComplete(); |
108 | void updateMe(); |
109 | |
110 | // QQuickItemGeometryListener interface |
111 | void itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &) override; |
112 | QQuickAnchorsPrivate *anchorPrivate() override { return this; } |
113 | |
114 | bool checkHValid() const; |
115 | bool checkVValid() const; |
116 | bool checkHAnchorValid(QQuickAnchorLine anchor) const; |
117 | bool checkVAnchorValid(QQuickAnchorLine anchor) const; |
118 | bool calcStretch(QQuickItem *edge1Item, QQuickAnchors::Anchor edge1Line, |
119 | QQuickItem *edge2Item, QQuickAnchors::Anchor edge2Line, |
120 | qreal offset1, qreal offset2, QQuickAnchors::Anchor line, qreal &stretch) const; |
121 | |
122 | bool isMirrored() const; |
123 | void updateHorizontalAnchors(); |
124 | void updateVerticalAnchors(); |
125 | void fillChanged(); |
126 | void centerInChanged(); |
127 | |
128 | qreal leftMargin; |
129 | qreal rightMargin; |
130 | qreal topMargin; |
131 | qreal bottomMargin; |
132 | qreal margins; |
133 | qreal vCenterOffset; |
134 | qreal hCenterOffset; |
135 | qreal baselineOffset; |
136 | |
137 | QQuickItem *item; |
138 | |
139 | QQuickItem *fill; |
140 | QQuickItem *centerIn; |
141 | |
142 | QQuickItem *leftAnchorItem; |
143 | QQuickItem *rightAnchorItem; |
144 | QQuickItem *topAnchorItem; |
145 | QQuickItem *bottomAnchorItem; |
146 | QQuickItem *vCenterAnchorItem; |
147 | QQuickItem *hCenterAnchorItem; |
148 | QQuickItem *baselineAnchorItem; |
149 | |
150 | // The bit fields below are carefully laid out in chunks of 1 byte, so the compiler doesn't |
151 | // need to generate 2 loads (and combining shifts/ors) to create a single field. |
152 | |
153 | QQuickAnchors::Anchor leftAnchorLine : 7; |
154 | uint leftMarginExplicit : 1; |
155 | QQuickAnchors::Anchor rightAnchorLine : 7; |
156 | uint rightMarginExplicit : 1; |
157 | QQuickAnchors::Anchor topAnchorLine : 7; |
158 | uint topMarginExplicit : 1; |
159 | QQuickAnchors::Anchor bottomAnchorLine : 7; |
160 | uint bottomMarginExplicit : 1; |
161 | |
162 | QQuickAnchors::Anchor vCenterAnchorLine : 7; |
163 | uint updatingMe : 1; |
164 | QQuickAnchors::Anchor hCenterAnchorLine : 7; |
165 | uint inDestructor : 1; |
166 | QQuickAnchors::Anchor baselineAnchorLine : 7; |
167 | uint centerAligned : 1; |
168 | uint usedAnchors : 7; // QQuickAnchors::Anchors |
169 | uint componentComplete : 1; |
170 | |
171 | // Instead of using a mostly empty bit field, we can stretch the following fields up to be full |
172 | // bytes. The advantage is that incrementing/decrementing does not need any combining ands/ors. |
173 | qint8 updatingFill; |
174 | qint8 updatingCenterIn; |
175 | qint8 updatingHorizontalAnchor; |
176 | qint8 updatingVerticalAnchor; |
177 | |
178 | |
179 | static inline QQuickAnchorsPrivate *get(QQuickAnchors *o) { |
180 | return static_cast<QQuickAnchorsPrivate *>(QObjectPrivate::get(o)); |
181 | } |
182 | }; |
183 | |
184 | QT_END_NAMESPACE |
185 | |
186 | Q_DECLARE_METATYPE(QQuickAnchorLine) |
187 | |
188 | #endif |
189 | |