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 58 QT_BEGIN_NAMESPACE 59 60 class QQuickAnchorLine 61 { 62 public: QQuickAnchorLine()63 QQuickAnchorLine() {} QQuickAnchorLine(QQuickItem * i,QQuickAnchors::Anchor l)64 QQuickAnchorLine(QQuickItem *i, QQuickAnchors::Anchor l) : item(i), anchorLine(l) {} QQuickAnchorLine(QQuickItem * i,uint 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 74 inline bool operator==(const QQuickAnchorLine& a, const QQuickAnchorLine& b) 75 { 76 return a.item == b.item && a.anchorLine == b.anchorLine; 77 } 78 79 class QQuickAnchorsPrivate : public QObjectPrivate, public QQuickItemChangeListener 80 { Q_DECLARE_PUBLIC(QQuickAnchors)81 Q_DECLARE_PUBLIC(QQuickAnchors) 82 public: 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; anchorPrivate()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 get(QQuickAnchors * o)212 static inline QQuickAnchorsPrivate *get(QQuickAnchors *o) { 213 return static_cast<QQuickAnchorsPrivate *>(QObjectPrivate::get(o)); 214 } 215 }; 216 217 QT_END_NAMESPACE 218 219 Q_DECLARE_METATYPE(QQuickAnchorLine) 220 221 #endif 222