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_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,
47 public QSafeQuickItemChangeListener<QQuickAnchorsPrivate>
48{
49 Q_DECLARE_PUBLIC(QQuickAnchors)
50public:
51 QQuickAnchorsPrivate(QQuickItem *i)
52 : leftMargin(0)
53 , rightMargin(0)
54 , topMargin(0)
55 , bottomMargin(0)
56 , margins(0)
57 , vCenterOffset(0)
58 , hCenterOffset(0)
59 , baselineOffset(0)
60 , item(i)
61 , fill(nullptr)
62 , centerIn(nullptr)
63 , leftAnchorItem(nullptr)
64 , rightAnchorItem(nullptr)
65 , topAnchorItem(nullptr)
66 , bottomAnchorItem(nullptr)
67 , vCenterAnchorItem(nullptr)
68 , hCenterAnchorItem(nullptr)
69 , baselineAnchorItem(nullptr)
70 , leftAnchorLine(QQuickAnchors::InvalidAnchor)
71 , leftMarginExplicit(false)
72 , rightAnchorLine(QQuickAnchors::InvalidAnchor)
73 , rightMarginExplicit(false)
74 , topAnchorLine(QQuickAnchors::InvalidAnchor)
75 , topMarginExplicit(false)
76 , bottomAnchorLine(QQuickAnchors::InvalidAnchor)
77 , bottomMarginExplicit(false)
78 , vCenterAnchorLine(QQuickAnchors::InvalidAnchor)
79 , updatingMe(false)
80 , hCenterAnchorLine(QQuickAnchors::InvalidAnchor)
81 , inDestructor(false)
82 , baselineAnchorLine(QQuickAnchors::InvalidAnchor)
83 , centerAligned(true)
84 , usedAnchors(QQuickAnchors::InvalidAnchor)
85 , componentComplete(true)
86 , updatingFill(0)
87 , updatingCenterIn(0)
88 , updatingHorizontalAnchor(0)
89 , updatingVerticalAnchor(0)
90 {
91 }
92
93 void clearItem(QQuickItem *);
94
95 QQuickGeometryChange calculateDependency(QQuickItem *) const;
96 void addDepend(QQuickItem *);
97 void remDepend(QQuickItem *);
98 bool isItemComplete() const;
99
100 void setItemHeight(qreal);
101 void setItemWidth(qreal);
102 void setItemX(qreal);
103 void setItemY(qreal);
104 void setItemPos(const QPointF &);
105 void setItemSize(const QSizeF &);
106
107 void update();
108 void updateOnComplete();
109 void updateMe();
110
111 // QQuickItemGeometryListener interface
112 void itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &) override;
113 QQuickAnchorsPrivate *anchorPrivate() override { return this; }
114
115 bool checkHValid() const;
116 bool checkVValid() const;
117 bool checkHAnchorValid(QQuickAnchorLine anchor) const;
118 bool checkVAnchorValid(QQuickAnchorLine anchor) const;
119 bool calcStretch(QQuickItem *edge1Item, QQuickAnchors::Anchor edge1Line,
120 QQuickItem *edge2Item, QQuickAnchors::Anchor edge2Line,
121 qreal offset1, qreal offset2, QQuickAnchors::Anchor line, qreal &stretch) const;
122
123 bool isMirrored() const;
124 void updateHorizontalAnchors();
125 void updateVerticalAnchors();
126 void fillChanged();
127 void centerInChanged();
128
129 qreal leftMargin;
130 qreal rightMargin;
131 qreal topMargin;
132 qreal bottomMargin;
133 qreal margins;
134 qreal vCenterOffset;
135 qreal hCenterOffset;
136 qreal baselineOffset;
137
138 QQuickItem *item;
139
140 QQuickItem *fill;
141 QQuickItem *centerIn;
142
143 QQuickItem *leftAnchorItem;
144 QQuickItem *rightAnchorItem;
145 QQuickItem *topAnchorItem;
146 QQuickItem *bottomAnchorItem;
147 QQuickItem *vCenterAnchorItem;
148 QQuickItem *hCenterAnchorItem;
149 QQuickItem *baselineAnchorItem;
150
151 // The bit fields below are carefully laid out in chunks of 1 byte, so the compiler doesn't
152 // need to generate 2 loads (and combining shifts/ors) to create a single field.
153
154 QQuickAnchors::Anchor leftAnchorLine : 7;
155 uint leftMarginExplicit : 1;
156 QQuickAnchors::Anchor rightAnchorLine : 7;
157 uint rightMarginExplicit : 1;
158 QQuickAnchors::Anchor topAnchorLine : 7;
159 uint topMarginExplicit : 1;
160 QQuickAnchors::Anchor bottomAnchorLine : 7;
161 uint bottomMarginExplicit : 1;
162
163 QQuickAnchors::Anchor vCenterAnchorLine : 7;
164 uint updatingMe : 1;
165 QQuickAnchors::Anchor hCenterAnchorLine : 7;
166 uint inDestructor : 1;
167 QQuickAnchors::Anchor baselineAnchorLine : 7;
168 uint centerAligned : 1;
169 uint usedAnchors : 7; // QQuickAnchors::Anchors
170 uint componentComplete : 1;
171
172 // Instead of using a mostly empty bit field, we can stretch the following fields up to be full
173 // bytes. The advantage is that incrementing/decrementing does not need any combining ands/ors.
174 qint8 updatingFill;
175 qint8 updatingCenterIn;
176 qint8 updatingHorizontalAnchor;
177 qint8 updatingVerticalAnchor;
178
179
180 static inline QQuickAnchorsPrivate *get(QQuickAnchors *o) {
181 return static_cast<QQuickAnchorsPrivate *>(QObjectPrivate::get(o));
182 }
183};
184
185QT_END_NAMESPACE
186
187Q_DECLARE_METATYPE(QQuickAnchorLine)
188
189#endif
190

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