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 QQUICKPOSITIONERS_P_H |
41 | #define QQUICKPOSITIONERS_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 <QtQuick/private/qtquickglobal_p.h> |
55 | |
56 | QT_REQUIRE_CONFIG(quick_positioners); |
57 | |
58 | #include "qquickimplicitsizeitem_p.h" |
59 | #include "qquickitemviewtransition_p.h" |
60 | |
61 | #include <private/qpodvector_p.h> |
62 | |
63 | #include <QtCore/qobject.h> |
64 | #include <QtCore/qstring.h> |
65 | |
66 | QT_BEGIN_NAMESPACE |
67 | |
68 | class QQuickBasePositionerPrivate; |
69 | |
70 | class QQuickPositionerAttached : public QObject |
71 | { |
72 | Q_OBJECT |
73 | |
74 | public: |
75 | QQuickPositionerAttached(QObject *parent); |
76 | |
77 | Q_PROPERTY(int index READ index NOTIFY indexChanged) |
78 | Q_PROPERTY(bool isFirstItem READ isFirstItem NOTIFY isFirstItemChanged) |
79 | Q_PROPERTY(bool isLastItem READ isLastItem NOTIFY isLastItemChanged) |
80 | |
81 | int index() const { return m_index; } |
82 | void setIndex(int index); |
83 | |
84 | bool isFirstItem() const { return m_isFirstItem; } |
85 | void setIsFirstItem(bool isFirstItem); |
86 | |
87 | bool isLastItem() const { return m_isLastItem; } |
88 | void setIsLastItem(bool isLastItem); |
89 | |
90 | Q_SIGNALS: |
91 | void indexChanged(); |
92 | void isFirstItemChanged(); |
93 | void isLastItemChanged(); |
94 | |
95 | private: |
96 | int m_index; |
97 | bool m_isFirstItem; |
98 | bool m_isLastItem; |
99 | }; |
100 | |
101 | class Q_QUICK_PRIVATE_EXPORT QQuickBasePositioner : public QQuickImplicitSizeItem |
102 | { |
103 | Q_OBJECT |
104 | |
105 | Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing NOTIFY spacingChanged) |
106 | Q_PROPERTY(QQuickTransition *populate READ populate WRITE setPopulate NOTIFY populateChanged) |
107 | Q_PROPERTY(QQuickTransition *move READ move WRITE setMove NOTIFY moveChanged) |
108 | Q_PROPERTY(QQuickTransition *add READ add WRITE setAdd NOTIFY addChanged) |
109 | |
110 | Q_PROPERTY(qreal padding READ padding WRITE setPadding RESET resetPadding NOTIFY paddingChanged REVISION 6) |
111 | Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding RESET resetTopPadding NOTIFY topPaddingChanged REVISION 6) |
112 | Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding NOTIFY leftPaddingChanged REVISION 6) |
113 | Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged REVISION 6) |
114 | Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged REVISION 6) |
115 | |
116 | QML_NAMED_ELEMENT(Positioner) |
117 | QML_UNCREATABLE("Positioner is an abstract type that is only available as an attached property." ) |
118 | QML_ATTACHED(QQuickPositionerAttached) |
119 | |
120 | public: |
121 | enum PositionerType { None = 0x0, Horizontal = 0x1, Vertical = 0x2, Both = 0x3 }; |
122 | |
123 | QQuickBasePositioner(PositionerType, QQuickItem *parent); |
124 | ~QQuickBasePositioner(); |
125 | |
126 | qreal spacing() const; |
127 | void setSpacing(qreal); |
128 | |
129 | QQuickTransition *populate() const; |
130 | void setPopulate(QQuickTransition *); |
131 | |
132 | QQuickTransition *move() const; |
133 | void setMove(QQuickTransition *); |
134 | |
135 | QQuickTransition *add() const; |
136 | void setAdd(QQuickTransition *); |
137 | |
138 | static QQuickPositionerAttached *qmlAttachedProperties(QObject *obj); |
139 | |
140 | void updateAttachedProperties(QQuickPositionerAttached *specificProperty = nullptr, QQuickItem *specificPropertyOwner = nullptr) const; |
141 | |
142 | qreal padding() const; |
143 | void setPadding(qreal padding); |
144 | void resetPadding(); |
145 | |
146 | qreal topPadding() const; |
147 | void setTopPadding(qreal padding); |
148 | void resetTopPadding(); |
149 | |
150 | qreal leftPadding() const; |
151 | void setLeftPadding(qreal padding); |
152 | void resetLeftPadding(); |
153 | |
154 | qreal rightPadding() const; |
155 | void setRightPadding(qreal padding); |
156 | void resetRightPadding(); |
157 | |
158 | qreal bottomPadding() const; |
159 | void setBottomPadding(qreal padding); |
160 | void resetBottomPadding(); |
161 | |
162 | Q_REVISION(9) Q_INVOKABLE void forceLayout(); |
163 | |
164 | protected: |
165 | QQuickBasePositioner(QQuickBasePositionerPrivate &dd, PositionerType at, QQuickItem *parent); |
166 | void componentComplete() override; |
167 | void itemChange(ItemChange, const ItemChangeData &) override; |
168 | |
169 | void updatePolish() override; |
170 | |
171 | Q_SIGNALS: |
172 | void spacingChanged(); |
173 | void populateChanged(); |
174 | void moveChanged(); |
175 | void addChanged(); |
176 | Q_REVISION(6) void paddingChanged(); |
177 | Q_REVISION(6) void topPaddingChanged(); |
178 | Q_REVISION(6) void leftPaddingChanged(); |
179 | Q_REVISION(6) void rightPaddingChanged(); |
180 | Q_REVISION(6) void bottomPaddingChanged(); |
181 | Q_REVISION(9) void positioningComplete(); |
182 | |
183 | protected Q_SLOTS: |
184 | void prePositioning(); |
185 | |
186 | protected: |
187 | virtual void doPositioning(QSizeF *contentSize)=0; |
188 | virtual void reportConflictingAnchors()=0; |
189 | |
190 | class PositionedItem |
191 | { |
192 | public : |
193 | PositionedItem(QQuickItem *i); |
194 | ~PositionedItem(); |
195 | bool operator==(const PositionedItem &other) const { return other.item == item; } |
196 | |
197 | qreal itemX() const; |
198 | qreal itemY() const; |
199 | |
200 | void moveTo(const QPointF &pos); |
201 | |
202 | void transitionNextReposition(QQuickItemViewTransitioner *transitioner, QQuickItemViewTransitioner::TransitionType type, bool asTarget); |
203 | bool prepareTransition(QQuickItemViewTransitioner *transitioner, const QRectF &viewBounds); |
204 | void startTransition(QQuickItemViewTransitioner *transitioner); |
205 | |
206 | void updatePadding(qreal lp, qreal tp, qreal rp, qreal bp); |
207 | |
208 | QQuickItem *item; |
209 | QQuickItemViewTransitionableItem *transitionableItem; |
210 | int index; |
211 | bool isNew; |
212 | bool isVisible; |
213 | |
214 | qreal topPadding; |
215 | qreal leftPadding; |
216 | qreal rightPadding; |
217 | qreal bottomPadding; |
218 | }; |
219 | |
220 | QPODVector<PositionedItem,8> positionedItems; |
221 | QPODVector<PositionedItem,8> unpositionedItems;//Still 'in' the positioner, just not positioned |
222 | |
223 | void positionItem(qreal x, qreal y, PositionedItem *target); |
224 | void positionItemX(qreal, PositionedItem *target); |
225 | void positionItemY(qreal, PositionedItem *target); |
226 | |
227 | void removePositionedItem(QPODVector<PositionedItem,8> *items, int index); |
228 | void clearPositionedItems(QPODVector<PositionedItem,8> *items); |
229 | |
230 | private: |
231 | Q_DISABLE_COPY(QQuickBasePositioner) |
232 | Q_DECLARE_PRIVATE(QQuickBasePositioner) |
233 | }; |
234 | |
235 | class Q_AUTOTEST_EXPORT QQuickColumn : public QQuickBasePositioner |
236 | { |
237 | Q_OBJECT |
238 | QML_NAMED_ELEMENT(Column) |
239 | public: |
240 | QQuickColumn(QQuickItem *parent=nullptr); |
241 | |
242 | protected: |
243 | void doPositioning(QSizeF *contentSize) override; |
244 | void reportConflictingAnchors() override; |
245 | private: |
246 | Q_DISABLE_COPY(QQuickColumn) |
247 | }; |
248 | |
249 | class QQuickRowPrivate; |
250 | class Q_AUTOTEST_EXPORT QQuickRow: public QQuickBasePositioner |
251 | { |
252 | Q_OBJECT |
253 | Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged) |
254 | Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged) |
255 | QML_NAMED_ELEMENT(Row) |
256 | |
257 | public: |
258 | QQuickRow(QQuickItem *parent=nullptr); |
259 | |
260 | Qt::LayoutDirection layoutDirection() const; |
261 | void setLayoutDirection (Qt::LayoutDirection); |
262 | Qt::LayoutDirection effectiveLayoutDirection() const; |
263 | |
264 | Q_SIGNALS: |
265 | void layoutDirectionChanged(); |
266 | void effectiveLayoutDirectionChanged(); |
267 | |
268 | protected: |
269 | void doPositioning(QSizeF *contentSize) override; |
270 | void reportConflictingAnchors() override; |
271 | private: |
272 | Q_DISABLE_COPY(QQuickRow) |
273 | Q_DECLARE_PRIVATE(QQuickRow) |
274 | }; |
275 | |
276 | class QQuickGridPrivate; |
277 | class Q_AUTOTEST_EXPORT QQuickGrid : public QQuickBasePositioner |
278 | { |
279 | Q_OBJECT |
280 | Q_PROPERTY(int rows READ rows WRITE setRows NOTIFY rowsChanged) |
281 | Q_PROPERTY(int columns READ columns WRITE setColumns NOTIFY columnsChanged) |
282 | Q_PROPERTY(qreal rowSpacing READ rowSpacing WRITE setRowSpacing NOTIFY rowSpacingChanged RESET resetRowSpacing) |
283 | Q_PROPERTY(qreal columnSpacing READ columnSpacing WRITE setColumnSpacing NOTIFY columnSpacingChanged RESET resetColumnSpacing) |
284 | Q_PROPERTY(Flow flow READ flow WRITE setFlow NOTIFY flowChanged) |
285 | Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged) |
286 | Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged) |
287 | Q_PROPERTY(HAlignment horizontalItemAlignment READ hItemAlign WRITE setHItemAlign NOTIFY horizontalAlignmentChanged REVISION 1) |
288 | Q_PROPERTY(HAlignment effectiveHorizontalItemAlignment READ effectiveHAlign NOTIFY effectiveHorizontalAlignmentChanged REVISION 1) |
289 | Q_PROPERTY(VAlignment verticalItemAlignment READ vItemAlign WRITE setVItemAlign NOTIFY verticalAlignmentChanged REVISION 1) |
290 | QML_NAMED_ELEMENT(Grid) |
291 | |
292 | public: |
293 | QQuickGrid(QQuickItem *parent=nullptr); |
294 | |
295 | int rows() const { return m_rows; } |
296 | void setRows(const int rows); |
297 | |
298 | int columns() const { return m_columns; } |
299 | void setColumns(const int columns); |
300 | |
301 | qreal rowSpacing() const { return m_rowSpacing; } |
302 | void setRowSpacing(qreal); |
303 | void resetRowSpacing() { m_useRowSpacing = false; } |
304 | |
305 | qreal columnSpacing() const { return m_columnSpacing; } |
306 | void setColumnSpacing(qreal); |
307 | void resetColumnSpacing() { m_useColumnSpacing = false; } |
308 | |
309 | enum Flow { LeftToRight, TopToBottom }; |
310 | Q_ENUM(Flow) |
311 | Flow flow() const; |
312 | void setFlow(Flow); |
313 | |
314 | Qt::LayoutDirection layoutDirection() const; |
315 | void setLayoutDirection (Qt::LayoutDirection); |
316 | Qt::LayoutDirection effectiveLayoutDirection() const; |
317 | |
318 | enum HAlignment { AlignLeft = Qt::AlignLeft, |
319 | AlignRight = Qt::AlignRight, |
320 | AlignHCenter = Qt::AlignHCenter}; |
321 | Q_ENUM(HAlignment) |
322 | enum VAlignment { AlignTop = Qt::AlignTop, |
323 | AlignBottom = Qt::AlignBottom, |
324 | AlignVCenter = Qt::AlignVCenter }; |
325 | Q_ENUM(VAlignment) |
326 | |
327 | HAlignment hItemAlign() const; |
328 | void setHItemAlign(HAlignment align); |
329 | HAlignment effectiveHAlign() const; |
330 | |
331 | VAlignment vItemAlign() const; |
332 | void setVItemAlign(VAlignment align); |
333 | |
334 | Q_SIGNALS: |
335 | void rowsChanged(); |
336 | void columnsChanged(); |
337 | void flowChanged(); |
338 | void layoutDirectionChanged(); |
339 | void effectiveLayoutDirectionChanged(); |
340 | void rowSpacingChanged(); |
341 | void columnSpacingChanged(); |
342 | Q_REVISION(1) void horizontalAlignmentChanged(HAlignment alignment); |
343 | Q_REVISION(1) void effectiveHorizontalAlignmentChanged(HAlignment alignment); |
344 | Q_REVISION(1) void verticalAlignmentChanged(VAlignment alignment); |
345 | |
346 | protected: |
347 | void doPositioning(QSizeF *contentSize) override; |
348 | void reportConflictingAnchors() override; |
349 | |
350 | private: |
351 | int m_rows; |
352 | int m_columns; |
353 | qreal m_rowSpacing; |
354 | qreal m_columnSpacing; |
355 | bool m_useRowSpacing; |
356 | bool m_useColumnSpacing; |
357 | Flow m_flow; |
358 | HAlignment m_hItemAlign; |
359 | VAlignment m_vItemAlign; |
360 | Q_DISABLE_COPY(QQuickGrid) |
361 | Q_DECLARE_PRIVATE(QQuickGrid) |
362 | }; |
363 | |
364 | class QQuickFlowPrivate; |
365 | class Q_AUTOTEST_EXPORT QQuickFlow: public QQuickBasePositioner |
366 | { |
367 | Q_OBJECT |
368 | Q_PROPERTY(Flow flow READ flow WRITE setFlow NOTIFY flowChanged) |
369 | Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged) |
370 | Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged) |
371 | QML_NAMED_ELEMENT(Flow) |
372 | public: |
373 | QQuickFlow(QQuickItem *parent=nullptr); |
374 | |
375 | enum Flow { LeftToRight, TopToBottom }; |
376 | Q_ENUM(Flow) |
377 | Flow flow() const; |
378 | void setFlow(Flow); |
379 | |
380 | Qt::LayoutDirection layoutDirection() const; |
381 | void setLayoutDirection (Qt::LayoutDirection); |
382 | Qt::LayoutDirection effectiveLayoutDirection() const; |
383 | |
384 | Q_SIGNALS: |
385 | void flowChanged(); |
386 | void layoutDirectionChanged(); |
387 | void effectiveLayoutDirectionChanged(); |
388 | |
389 | protected: |
390 | void doPositioning(QSizeF *contentSize) override; |
391 | void reportConflictingAnchors() override; |
392 | protected: |
393 | QQuickFlow(QQuickFlowPrivate &dd, QQuickItem *parent); |
394 | private: |
395 | Q_DISABLE_COPY(QQuickFlow) |
396 | Q_DECLARE_PRIVATE(QQuickFlow) |
397 | }; |
398 | |
399 | |
400 | QT_END_NAMESPACE |
401 | |
402 | QML_DECLARE_TYPE(QQuickColumn) |
403 | QML_DECLARE_TYPE(QQuickRow) |
404 | QML_DECLARE_TYPE(QQuickGrid) |
405 | QML_DECLARE_TYPE(QQuickFlow) |
406 | |
407 | QML_DECLARE_TYPE(QQuickBasePositioner) |
408 | |
409 | #endif // QQUICKPOSITIONERS_P_H |
410 | |