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
22QT_BEGIN_NAMESPACE
23
24class Q_QUICK_PRIVATE_EXPORT QQuickAnchorLine
25{
26 Q_GADGET
27 QML_ANONYMOUS
28 QML_ADDED_IN_VERSION(2, 0)
29public:
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
41inline bool operator==(const QQuickAnchorLine& a, const QQuickAnchorLine& b)
42{
43 return a.item == b.item && a.anchorLine == b.anchorLine;
44}
45
46class QQuickAnchorsPrivate : public QObjectPrivate, public QQuickItemChangeListener
47{
48 Q_DECLARE_PUBLIC(QQuickAnchors)
49public:
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
184QT_END_NAMESPACE
185
186Q_DECLARE_METATYPE(QQuickAnchorLine)
187
188#endif
189

source code of qtdeclarative/src/quick/items/qquickanchors_p_p.h