Kirigami2

columnview.h
1 /*
2  * SPDX-FileCopyrightText: 2019 Marco Martin <[email protected]>
3  *
4  * SPDX-License-Identifier: LGPL-2.0-or-later
5  */
6 
7 #pragma once
8 
9 #include <QPointer>
10 #include <QQuickItem>
11 #include <QVariant>
12 
13 class ContentItem;
14 class ColumnView;
15 
16 class ScrollIntentionEvent : public QObject
17 {
18  Q_OBJECT
19  Q_PROPERTY(QPointF delta MEMBER delta CONSTANT)
20  Q_PROPERTY(bool accepted MEMBER accepted)
21 public:
22  ScrollIntentionEvent()
23  {
24  }
25  ~ScrollIntentionEvent() override
26  {
27  }
28 
29  QPointF delta;
30  bool accepted = false;
31 };
32 
33 /**
34  * This is an attached property to every item that is inserted in the ColumnView,
35  * used to access the view and page information such as the position and information for layouting, such as fillWidth
36  * @since 2.7
37  */
39 {
40  Q_OBJECT
41 
42  /**
43  * The index position of the column in the view, starting from 0
44  */
45  Q_PROPERTY(int index READ index WRITE setIndex NOTIFY indexChanged)
46 
47  /**
48  * If true, the column will expand to take the whole viewport space minus reservedSpace
49  */
50  Q_PROPERTY(bool fillWidth READ fillWidth WRITE setFillWidth NOTIFY fillWidthChanged)
51 
52  /**
53  * When a column is fillWidth, it will keep reservedSpace amount of pixels from going to fill the full viewport width
54  */
55  Q_PROPERTY(qreal reservedSpace READ reservedSpace WRITE setReservedSpace NOTIFY reservedSpaceChanged)
56 
57  /**
58  * Like the same property of MouseArea, when this is true, the column view won't
59  * try to manage events by itself when filtering from a child, not
60  * disturbing user interaction
61  */
62  Q_PROPERTY(bool preventStealing READ preventStealing WRITE setPreventStealing NOTIFY preventStealingChanged)
63 
64  /**
65  * If true the page will never go out of view, but will stay either
66  * at the right or left side of the ColumnView
67  */
68  Q_PROPERTY(bool pinned READ isPinned WRITE setPinned NOTIFY pinnedChanged)
69 
70  /**
71  * The view this column belongs to
72  */
73  Q_PROPERTY(ColumnView *view READ view NOTIFY viewChanged)
74 
75  /**
76  * True if this column is at least partly visible in the ColumnView's viewport.
77  * @since 5.77
78  */
79  Q_PROPERTY(bool inViewport READ inViewport NOTIFY inViewportChanged)
80 
81 public:
82  ColumnViewAttached(QObject *parent = nullptr);
83  ~ColumnViewAttached() override;
84 
85  void setIndex(int index);
86  int index() const;
87 
88  void setFillWidth(bool fill);
89  bool fillWidth() const;
90 
91  qreal reservedSpace() const;
92  void setReservedSpace(qreal space);
93 
94  ColumnView *view();
95  void setView(ColumnView *view);
96 
97  // Private API, not for QML use
98  QQuickItem *originalParent() const;
99  void setOriginalParent(QQuickItem *parent);
100 
101  bool shouldDeleteOnRemove() const;
102  void setShouldDeleteOnRemove(bool del);
103 
104  bool preventStealing() const;
105  void setPreventStealing(bool prevent);
106 
107  bool isPinned() const;
108  void setPinned(bool pinned);
109 
110  bool inViewport() const;
111  void setInViewport(bool inViewport);
112 
113 Q_SIGNALS:
114  void indexChanged();
115  void fillWidthChanged();
116  void reservedSpaceChanged();
117  void viewChanged();
118  void preventStealingChanged();
119  void pinnedChanged();
120  void scrollIntention(ScrollIntentionEvent *event);
121  void inViewportChanged();
122 
123 private:
124  int m_index = -1;
125  bool m_fillWidth = false;
126  qreal m_reservedSpace = 0;
127  QPointer<ColumnView> m_view;
128  QPointer<QQuickItem> m_originalParent;
129  bool m_customFillWidth = false;
130  bool m_customReservedSpace = false;
131  bool m_shouldDeleteOnRemove = true;
132  bool m_preventStealing = false;
133  bool m_pinned = false;
134  bool m_inViewport = false;
135 };
136 
137 /**
138  * ColumnView is a container that lays out items horizontally in a row,
139  * when not all items fit in the ColumnView, it will behave like a Flickable and will be a scrollable view which shows only a determined number of columns.
140  * The columns can either all have the same fixed size (recommended),
141  * size themselves with implicitWidth, or automatically expand to take all the available width: by default the last column will always be the expanding one.
142  * Items inside the ColumnView can access info of the view and set layouting hints via the ColumnView attached property.
143  *
144  * This is the base for the implementation of PageRow
145  * @since 2.7
146  */
147 class ColumnView : public QQuickItem
148 {
149  Q_OBJECT
150 
151  /**
152  * The strategy to follow while automatically resizing the columns,
153  * the enum can have the following values:
154  * * FixedColumns: every column is fixed at the same width of the columnWidth property
155  * * DynamicColumns: columns take their width from their implicitWidth
156  * * SingleColumn: only one column at a time is shown, as wide as the viewport, eventual reservedSpace on the column's attached property is ignored
157  */
158  Q_PROPERTY(ColumnResizeMode columnResizeMode READ columnResizeMode WRITE setColumnResizeMode NOTIFY columnResizeModeChanged)
159 
160  /**
161  * The width of all columns when columnResizeMode is FixedColumns
162  */
163  Q_PROPERTY(qreal columnWidth READ columnWidth WRITE setColumnWidth NOTIFY columnWidthChanged)
164 
165  /**
166  * How many columns this view containsItem*/
167  Q_PROPERTY(int count READ count NOTIFY countChanged)
168 
169  /**
170  * The position of the currently active column. The current column will also have keyboard focus
171  */
172  Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged)
173 
174  /**
175  * The currently active column. The current column will also have keyboard focus
176  */
177  Q_PROPERTY(QQuickItem *currentItem READ currentItem NOTIFY currentItemChanged)
178 
179  /**
180  * The main content item of this view: it's the parent of the column items
181  */
182  Q_PROPERTY(QQuickItem *contentItem READ contentItem CONSTANT)
183 
184  /**
185  * The value of the horizontal scroll of the view, in pixels
186  */
187  Q_PROPERTY(qreal contentX READ contentX WRITE setContentX NOTIFY contentXChanged)
188 
189  /**
190  * The compound width of all columns in the view
191  */
192  Q_PROPERTY(qreal contentWidth READ contentWidth NOTIFY contentWidthChanged)
193 
194  /**
195  * The padding this will have at the top
196  */
197  Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding NOTIFY topPaddingChanged)
198 
199  /**
200  * The padding this will have at the bottom
201  */
202  Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding NOTIFY bottomPaddingChanged)
203 
204  /**
205  * The duration for scrolling animations
206  */
207  Q_PROPERTY(int scrollDuration READ scrollDuration WRITE setScrollDuration NOTIFY scrollDurationChanged)
208 
209  /**
210  * True if columns should be visually separated by a separator line
211  */
212  Q_PROPERTY(bool separatorVisible READ separatorVisible WRITE setSeparatorVisible NOTIFY separatorVisibleChanged)
213 
214  /**
215  * The list of all visible column items that are at least partially in the viewport at any given moment
216  */
217  Q_PROPERTY(QList<QObject *> visibleItems READ visibleItems NOTIFY visibleItemsChanged)
218 
219  /**
220  * The first of visibleItems provided from convenience
221  */
222  Q_PROPERTY(QQuickItem *firstVisibleItem READ firstVisibleItem NOTIFY firstVisibleItemChanged)
223 
224  /**
225  * The last of visibleItems provided from convenience
226  */
227  Q_PROPERTY(QQuickItem *lastVisibleItem READ lastVisibleItem NOTIFY lastVisibleItemChanged)
228 
229  // Properties to make it similar to Flickable
230  /**
231  * True when the user is dragging around with touch gestures the view contents
232  */
233  Q_PROPERTY(bool dragging READ dragging NOTIFY draggingChanged)
234 
235  /**
236  * True both when the user is dragging around with touch gestures the view contents or the view is animating
237  */
238  Q_PROPERTY(bool moving READ moving NOTIFY movingChanged)
239 
240  /**
241  * True if it supports moving the contents by dragging
242  */
243  Q_PROPERTY(bool interactive READ interactive WRITE setInteractive NOTIFY interactiveChanged)
244 
245  /**
246  * True if the contents can be dragged also with mouse besides touch
247  */
248  Q_PROPERTY(bool acceptsMouse READ acceptsMouse WRITE setAcceptsMouse NOTIFY acceptsMouseChanged)
249 
250  // Default properties
251  /**
252  * Every column item the view contains
253  */
254  Q_PROPERTY(QQmlListProperty<QQuickItem> contentChildren READ contentChildren NOTIFY contentChildrenChanged FINAL)
255  /**
256  * every item declared inside the view, both visual and non-visual items
257  */
258  Q_PROPERTY(QQmlListProperty<QObject> contentData READ contentData FINAL)
259  Q_CLASSINFO("DefaultProperty", "contentData")
260 
261 public:
262  enum ColumnResizeMode {
263  FixedColumns = 0,
264  DynamicColumns,
265  SingleColumn,
266  };
267  Q_ENUM(ColumnResizeMode)
268 
269  ColumnView(QQuickItem *parent = nullptr);
270  ~ColumnView() override;
271 
272  // QML property accessors
273  ColumnResizeMode columnResizeMode() const;
274  void setColumnResizeMode(ColumnResizeMode mode);
275 
276  qreal columnWidth() const;
277  void setColumnWidth(qreal width);
278 
279  int currentIndex() const;
280  void setCurrentIndex(int index);
281 
282  int scrollDuration() const;
283  void setScrollDuration(int duration);
284 
285  bool separatorVisible() const;
286  void setSeparatorVisible(bool visible);
287 
288  int count() const;
289 
290  qreal topPadding() const;
291  void setTopPadding(qreal padding);
292 
293  qreal bottomPadding() const;
294  void setBottomPadding(qreal padding);
295 
296  QQuickItem *currentItem();
297 
298  // NOTE: It's a QList<QObject *> as QML can't correctly build an Array out of QList<QQuickItem*>
299  QList<QObject *> visibleItems() const;
300  QQuickItem *firstVisibleItem() const;
301  QQuickItem *lastVisibleItem() const;
302 
303  QQuickItem *contentItem() const;
304 
305  QQmlListProperty<QQuickItem> contentChildren();
306  QQmlListProperty<QObject> contentData();
307 
308  bool dragging() const;
309  bool moving() const;
310  qreal contentWidth() const;
311 
312  qreal contentX() const;
313  void setContentX(qreal x) const;
314 
315  bool interactive() const;
316  void setInteractive(bool interactive);
317 
318  bool acceptsMouse() const;
319  void setAcceptsMouse(bool accepts);
320 
321  // Api not intended for QML use
322  // can't do overloads in QML
323  QQuickItem *removeItem(QQuickItem *item);
324  QQuickItem *removeItem(int item);
325 
326  // QML attached property
327  static ColumnViewAttached *qmlAttachedProperties(QObject *object);
328 
329 public Q_SLOTS:
330  /**
331  * Pushes a new item at the end of the view
332  * @param item the new item which will be reparented and managed
333  */
334  void addItem(QQuickItem *item);
335 
336  /**
337  * Inserts a new item in the view at a given position.
338  * The current Item will not be changed, currentIndex will be adjusted
339  * accordingly if needed to keep the same current item.
340  * @param pos the position we want the new item to be inserted in
341  * @param item the new item which will be reparented and managed
342  */
343  void insertItem(int pos, QQuickItem *item);
344 
345  /**
346  * Replaces an item in the view at a given position with a new item.
347  * The current Item and currentIndex will not be changed.
348  * @param pos the position we want the new item to be placed in
349  * @param item the new item which will be reparented and managed
350  */
351  void replaceItem(int pos, QQuickItem *item);
352 
353  /**
354  * Move an item inside the view.
355  * The currentIndex property may be changed in order to keep currentItem the same.
356  * @param from the old position
357  * @param to the new position
358  */
359  void moveItem(int from, int to);
360 
361  /**
362  * Removes an item from the view.
363  * Items will be reparented to their old parent.
364  * If they have JavaScript ownership and they didn't have an old parent, they will be destroyed.
365  * CurrentIndex may be changed in order to keep the same currentItem
366  * @param item it can either be a pointer of an item or an integer specifying the position to remove
367  * @returns the item that has just been removed
368  */
369  QQuickItem *removeItem(const QVariant &item);
370 
371  /**
372  * Removes all the items after item. Starting from the last column, every column will be removed until item is found, which will be left in place.
373  * Items will be reparented to their old parent.
374  * If they have JavaScript ownership and they didn't have an old parent, they will be destroyed
375  * @param item the item which will be the new last one of the row.
376  * @returns the last item that has been removed
377  */
378  QQuickItem *pop(QQuickItem *item);
379 
380  /**
381  * Removes every item in the view.
382  * Items will be reparented to their old parent.
383  * If they have JavaScript ownership and they didn't have an old parent, they will be destroyed
384  */
385  void clear();
386 
387  /**
388  * @returns true if the view contains the given item
389  */
390  bool containsItem(QQuickItem *item);
391 
392  /**
393  * Returns the visible item containing the point x, y in content coordinates.
394  * If there is no item at the point specified, or the item is not visible null is returned.
395  */
396  QQuickItem *itemAt(qreal x, qreal y);
397 
398 protected:
399  void classBegin() override;
400  void componentComplete() override;
401  void updatePolish() override;
402  void itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value) override;
403 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
404  void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
405 #else
406  void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
407 #endif
408  bool childMouseEventFilter(QQuickItem *item, QEvent *event) override;
409  void mousePressEvent(QMouseEvent *event) override;
410  void mouseMoveEvent(QMouseEvent *event) override;
411  void mouseReleaseEvent(QMouseEvent *event) override;
412  void mouseUngrabEvent() override;
413 
414 Q_SIGNALS:
415  /**
416  * A new item has been inserted
417  * @param position where the page has been inserted
418  * @param item a pointer to the new item
419  */
420  void itemInserted(int position, QQuickItem *item);
421 
422  /**
423  * An item has just been removed from the view
424  * @param item a pointer to the item that has just been removed
425  */
426  void itemRemoved(QQuickItem *item);
427 
428  // Property notifiers
429  void contentChildrenChanged();
430  void columnResizeModeChanged();
431  void columnWidthChanged();
432  void currentIndexChanged();
433  void currentItemChanged();
434  void visibleItemsChanged();
435  void countChanged();
436  void draggingChanged();
437  void movingChanged();
438  void contentXChanged();
439  void contentWidthChanged();
440  void interactiveChanged();
441  void acceptsMouseChanged();
442  void scrollDurationChanged();
443  void separatorVisibleChanged();
444  void firstVisibleItemChanged();
445  void lastVisibleItemChanged();
446  void topPaddingChanged();
447  void bottomPaddingChanged();
448 
449 private:
450  static void contentChildren_append(QQmlListProperty<QQuickItem> *prop, QQuickItem *object);
451 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
452  static int contentChildren_count(QQmlListProperty<QQuickItem> *prop);
453  static QQuickItem *contentChildren_at(QQmlListProperty<QQuickItem> *prop, int index);
454 #else
455  static qsizetype contentChildren_count(QQmlListProperty<QQuickItem> *prop);
456  static QQuickItem *contentChildren_at(QQmlListProperty<QQuickItem> *prop, qsizetype index);
457 #endif
458  static void contentChildren_clear(QQmlListProperty<QQuickItem> *prop);
459 
460  static void contentData_append(QQmlListProperty<QObject> *prop, QObject *object);
461 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
462  static int contentData_count(QQmlListProperty<QObject> *prop);
463  static QObject *contentData_at(QQmlListProperty<QObject> *prop, int index);
464 #else
465  static qsizetype contentData_count(QQmlListProperty<QObject> *prop);
466  static QObject *contentData_at(QQmlListProperty<QObject> *prop, qsizetype index);
467 #endif
468  static void contentData_clear(QQmlListProperty<QObject> *prop);
469 
470  QList<QObject *> m_contentData;
471 
472  ContentItem *m_contentItem;
473  QPointer<QQuickItem> m_currentItem;
474 
475  qreal m_oldMouseX = -1.0;
476  qreal m_startMouseX = -1.0;
477  qreal m_oldMouseY = -1.0;
478  qreal m_startMouseY = -1.0;
479  int m_currentIndex = -1;
480  qreal m_topPadding = 0;
481  qreal m_bottomPadding = 0;
482 
483  bool m_mouseDown = false;
484  bool m_interactive = true;
485  bool m_dragging = false;
486  bool m_moving = false;
487  bool m_separatorVisible = true;
488  bool m_complete = false;
489  bool m_acceptsMouse = false;
490 };
491 
492 QML_DECLARE_TYPEINFO(ColumnView, QML_HAS_ATTACHED_PROPERTIES)
Q_OBJECTQ_OBJECT
Q_PROPERTY(...)
Q_ENUM(...)
Q_SLOTSQ_SLOTS
Q_CLASSINFO(Name, Value)
bool pinned
If true the page will never go out of view, but will stay either at the right or left side of the Col...
Definition: columnview.h:68
ColumnView is a container that lays out items horizontally in a row, when not all items fit in the Co...
Definition: columnview.h:147
virtual bool event(QEvent *e)
qreal reservedSpace
When a column is fillWidth, it will keep reservedSpace amount of pixels from going to fill the full v...
Definition: columnview.h:55
ColumnView view
The view this column belongs to.
Definition: columnview.h:73
Q_SIGNALSQ_SIGNALS
bool inViewport
True if this column is at least partly visible in the ColumnView's viewport.
Definition: columnview.h:79
int index
The index position of the column in the view, starting from 0.
Definition: columnview.h:45
QObject * parent() const const
bool preventStealing
Like the same property of MouseArea, when this is true, the column view won't try to manage events by...
Definition: columnview.h:62
This is an attached property to every item that is inserted in the ColumnView, used to access the vie...
Definition: columnview.h:38
bool fillWidth
If true, the column will expand to take the whole viewport space minus reservedSpace.
Definition: columnview.h:50
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Tue Feb 7 2023 04:14:23 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.