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)
Q_PROPERTY(bool isFirstItem READ isFirstItem NOTIFY isFirstItemChanged)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 
isFirstItem()84     bool isFirstItem() const { return m_isFirstItem; }
85     void setIsFirstItem(bool isFirstItem);
86 
isLastItem()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 
rows()295     int rows() const { return m_rows; }
296     void setRows(const int rows);
297 
columns()298     int columns() const { return m_columns; }
299     void setColumns(const int columns);
300 
rowSpacing()301     qreal rowSpacing() const { return m_rowSpacing; }
302     void setRowSpacing(qreal);
resetRowSpacing()303     void resetRowSpacing() { m_useRowSpacing = false; }
304 
columnSpacing()305     qreal columnSpacing() const { return m_columnSpacing; }
306     void setColumnSpacing(qreal);
resetColumnSpacing()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