1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtQuick module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#ifndef QQUICKANCHORS_P_P_H
41#define QQUICKANCHORS_P_P_H
42
43//
44// W A R N I N G
45// -------------
46//
47// This file is not part of the Qt API. It exists purely as an
48// implementation detail. This header file may change from version to
49// version without notice, or even be removed.
50//
51// We mean it.
52//
53
54#include "qquickanchors_p.h"
55#include "qquickitemchangelistener_p.h"
56#include <private/qobject_p.h>
57
58QT_BEGIN_NAMESPACE
59
60class QQuickAnchorLine
61{
62public:
63 QQuickAnchorLine() {}
64 QQuickAnchorLine(QQuickItem *i, QQuickAnchors::Anchor l) : item(i), anchorLine(l) {}
65 QQuickAnchorLine(QQuickItem *i, uint l)
66 : item(i)
67 , anchorLine(static_cast<QQuickAnchors::Anchor>(l))
68 { Q_ASSERT(l < ((QQuickAnchors::BaselineAnchor << 1) - 1)); }
69
70 QQuickItem *item = nullptr;
71 QQuickAnchors::Anchor anchorLine = QQuickAnchors::InvalidAnchor;
72};
73
74inline bool operator==(const QQuickAnchorLine& a, const QQuickAnchorLine& b)
75{
76 return a.item == b.item && a.anchorLine == b.anchorLine;
77}
78
79class QQuickAnchorsPrivate : public QObjectPrivate, public QQuickItemChangeListener
80{
81 Q_DECLARE_PUBLIC(QQuickAnchors)
82public:
83 QQuickAnchorsPrivate(QQuickItem *i)
84 : leftMargin(0)
85 , rightMargin(0)
86 , topMargin(0)
87 , bottomMargin(0)
88 , margins(0)
89 , vCenterOffset(0)
90 , hCenterOffset(0)
91 , baselineOffset(0)
92 , item(i)
93 , fill(nullptr)
94 , centerIn(nullptr)
95 , leftAnchorItem(nullptr)
96 , rightAnchorItem(nullptr)
97 , topAnchorItem(nullptr)
98 , bottomAnchorItem(nullptr)
99 , vCenterAnchorItem(nullptr)
100 , hCenterAnchorItem(nullptr)
101 , baselineAnchorItem(nullptr)
102 , leftAnchorLine(QQuickAnchors::InvalidAnchor)
103 , leftMarginExplicit(false)
104 , rightAnchorLine(QQuickAnchors::InvalidAnchor)
105 , rightMarginExplicit(false)
106 , topAnchorLine(QQuickAnchors::InvalidAnchor)
107 , topMarginExplicit(false)
108 , bottomAnchorLine(QQuickAnchors::InvalidAnchor)
109 , bottomMarginExplicit(false)
110 , vCenterAnchorLine(QQuickAnchors::InvalidAnchor)
111 , updatingMe(false)
112 , hCenterAnchorLine(QQuickAnchors::InvalidAnchor)
113 , inDestructor(false)
114 , baselineAnchorLine(QQuickAnchors::InvalidAnchor)
115 , centerAligned(true)
116 , usedAnchors(QQuickAnchors::InvalidAnchor)
117 , componentComplete(true)
118 , updatingFill(0)
119 , updatingCenterIn(0)
120 , updatingHorizontalAnchor(0)
121 , updatingVerticalAnchor(0)
122 {
123 }
124
125 void clearItem(QQuickItem *);
126
127 QQuickGeometryChange calculateDependency(QQuickItem *) const;
128 void addDepend(QQuickItem *);
129 void remDepend(QQuickItem *);
130 bool isItemComplete() const;
131
132 void setItemHeight(qreal);
133 void setItemWidth(qreal);
134 void setItemX(qreal);
135 void setItemY(qreal);
136 void setItemPos(const QPointF &);
137 void setItemSize(const QSizeF &);
138
139 void update();
140 void updateOnComplete();
141 void updateMe();
142
143 // QQuickItemGeometryListener interface
144 void itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &) override;
145 QQuickAnchorsPrivate *anchorPrivate() override { return this; }
146
147 bool checkHValid() const;
148 bool checkVValid() const;
149 bool checkHAnchorValid(QQuickAnchorLine anchor) const;
150 bool checkVAnchorValid(QQuickAnchorLine anchor) const;
151 bool calcStretch(QQuickItem *edge1Item, QQuickAnchors::Anchor edge1Line,
152 QQuickItem *edge2Item, QQuickAnchors::Anchor edge2Line,
153 qreal offset1, qreal offset2, QQuickAnchors::Anchor line, qreal &stretch) const;
154
155 bool isMirrored() const;
156 void updateHorizontalAnchors();
157 void updateVerticalAnchors();
158 void fillChanged();
159 void centerInChanged();
160
161 qreal leftMargin;
162 qreal rightMargin;
163 qreal topMargin;
164 qreal bottomMargin;
165 qreal margins;
166 qreal vCenterOffset;
167 qreal hCenterOffset;
168 qreal baselineOffset;
169
170 QQuickItem *item;
171
172 QQuickItem *fill;
173 QQuickItem *centerIn;
174
175 QQuickItem *leftAnchorItem;
176 QQuickItem *rightAnchorItem;
177 QQuickItem *topAnchorItem;
178 QQuickItem *bottomAnchorItem;
179 QQuickItem *vCenterAnchorItem;
180 QQuickItem *hCenterAnchorItem;
181 QQuickItem *baselineAnchorItem;
182
183 // The bit fields below are carefully laid out in chunks of 1 byte, so the compiler doesn't
184 // need to generate 2 loads (and combining shifts/ors) to create a single field.
185
186 QQuickAnchors::Anchor leftAnchorLine : 7;
187 uint leftMarginExplicit : 1;
188 QQuickAnchors::Anchor rightAnchorLine : 7;
189 uint rightMarginExplicit : 1;
190 QQuickAnchors::Anchor topAnchorLine : 7;
191 uint topMarginExplicit : 1;
192 QQuickAnchors::Anchor bottomAnchorLine : 7;
193 uint bottomMarginExplicit : 1;
194
195 QQuickAnchors::Anchor vCenterAnchorLine : 7;
196 uint updatingMe : 1;
197 QQuickAnchors::Anchor hCenterAnchorLine : 7;
198 uint inDestructor : 1;
199 QQuickAnchors::Anchor baselineAnchorLine : 7;
200 uint centerAligned : 1;
201 uint usedAnchors : 7; // QQuickAnchors::Anchors
202 uint componentComplete : 1;
203
204 // Instead of using a mostly empty bit field, we can stretch the following fields up to be full
205 // bytes. The advantage is that incrementing/decrementing does not need any combining ands/ors.
206 qint8 updatingFill;
207 qint8 updatingCenterIn;
208 qint8 updatingHorizontalAnchor;
209 qint8 updatingVerticalAnchor;
210
211
212 static inline QQuickAnchorsPrivate *get(QQuickAnchors *o) {
213 return static_cast<QQuickAnchorsPrivate *>(QObjectPrivate::get(o));
214 }
215};
216
217QT_END_NAMESPACE
218
219Q_DECLARE_METATYPE(QQuickAnchorLine)
220
221#endif
222