Kirigami2

columnview.h
1 /*
2  * SPDX-FileCopyrightText: 2019 Marco Martin <mart@kde.org>
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 FINAL)
20  Q_PROPERTY(bool accepted MEMBER accepted FINAL)
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 FINAL)
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 FINAL)
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 FINAL)
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 FINAL)
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 FINAL)
69 
70  /**
71  * The view this column belongs to
72  */
73  Q_PROPERTY(ColumnView *view READ view NOTIFY viewChanged FINAL)
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 FINAL)
80 
81  Q_PROPERTY(QQuickItem *globalHeader READ globalHeader WRITE setGlobalHeader NOTIFY globalHeaderChanged FINAL)
82  Q_PROPERTY(QQuickItem *globalFooter READ globalFooter WRITE setGlobalFooter NOTIFY globalFooterChanged FINAL)
83 
84 public:
85  ColumnViewAttached(QObject *parent = nullptr);
86  ~ColumnViewAttached() override;
87 
88  void setIndex(int index);
89  int index() const;
90 
91  void setFillWidth(bool fill);
92  bool fillWidth() const;
93 
94  qreal reservedSpace() const;
95  void setReservedSpace(qreal space);
96 
97  ColumnView *view();
98  void setView(ColumnView *view);
99 
100  // Private API, not for QML use
101  QQuickItem *originalParent() const;
102  void setOriginalParent(QQuickItem *parent);
103 
104  bool shouldDeleteOnRemove() const;
105  void setShouldDeleteOnRemove(bool del);
106 
107  bool preventStealing() const;
108  void setPreventStealing(bool prevent);
109 
110  bool isPinned() const;
111  void setPinned(bool pinned);
112 
113  bool inViewport() const;
114  void setInViewport(bool inViewport);
115 
116  QQuickItem *globalHeader() const;
117  void setGlobalHeader(QQuickItem *header);
118 
119  QQuickItem *globalFooter() const;
120  void setGlobalFooter(QQuickItem *footer);
121 
122 Q_SIGNALS:
123  void indexChanged();
124  void fillWidthChanged();
125  void reservedSpaceChanged();
126  void viewChanged();
127  void preventStealingChanged();
128  void pinnedChanged();
129  void scrollIntention(ScrollIntentionEvent *event);
130  void inViewportChanged();
131  void globalHeaderChanged(QQuickItem *oldHeader, QQuickItem *newHeader);
132  void globalFooterChanged(QQuickItem *oldFooter, QQuickItem *newFooter);
133 
134 private:
135  int m_index = -1;
136  bool m_fillWidth = false;
137  qreal m_reservedSpace = 0;
138  QPointer<ColumnView> m_view;
139  QPointer<QQuickItem> m_originalParent;
140  bool m_customFillWidth = false;
141  bool m_customReservedSpace = false;
142  bool m_shouldDeleteOnRemove = true;
143  bool m_preventStealing = false;
144  bool m_pinned = false;
145  bool m_inViewport = false;
146  QPointer<QQuickItem> m_globalHeader;
147  QPointer<QQuickItem> m_globalFooter;
148 };
149 
150 /**
151  * ColumnView is a container that lays out items horizontally in a row,
152  * 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.
153  * The columns can either all have the same fixed size (recommended),
154  * size themselves with implicitWidth, or automatically expand to take all the available width: by default the last column will always be the expanding one.
155  * Items inside the ColumnView can access info of the view and set layouting hints via the ColumnView attached property.
156  *
157  * This is the base for the implementation of PageRow
158  * @since 2.7
159  */
160 class ColumnView : public QQuickItem
161 {
162  Q_OBJECT
163  QML_ELEMENT
164  QML_ATTACHED(ColumnViewAttached)
165 
166  /**
167  * The strategy to follow while automatically resizing the columns,
168  * the enum can have the following values:
169  * * FixedColumns: every column is fixed at the same width of the columnWidth property
170  * * DynamicColumns: columns take their width from their implicitWidth
171  * * SingleColumn: only one column at a time is shown, as wide as the viewport, eventual reservedSpace on the column's attached property is ignored
172  */
173  Q_PROPERTY(ColumnResizeMode columnResizeMode READ columnResizeMode WRITE setColumnResizeMode NOTIFY columnResizeModeChanged FINAL)
174 
175  /**
176  * The width of all columns when columnResizeMode is FixedColumns
177  */
178  Q_PROPERTY(qreal columnWidth READ columnWidth WRITE setColumnWidth NOTIFY columnWidthChanged FINAL)
179 
180  /**
181  * How many columns this view containsItem*/
182  Q_PROPERTY(int count READ count NOTIFY countChanged FINAL)
183 
184  /**
185  * The position of the currently active column. The current column will also have keyboard focus
186  */
187  Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged FINAL)
188 
189  /**
190  * The currently active column. The current column will also have keyboard focus
191  */
192  Q_PROPERTY(QQuickItem *currentItem READ currentItem NOTIFY currentItemChanged FINAL)
193 
194  /**
195  * The main content item of this view: it's the parent of the column items
196  */
197  Q_PROPERTY(QQuickItem *contentItem READ contentItem CONSTANT FINAL)
198 
199  /**
200  * The value of the horizontal scroll of the view, in pixels
201  */
202  Q_PROPERTY(qreal contentX READ contentX WRITE setContentX NOTIFY contentXChanged FINAL)
203 
204  /**
205  * The compound width of all columns in the view
206  */
207  Q_PROPERTY(qreal contentWidth READ contentWidth NOTIFY contentWidthChanged FINAL)
208 
209  /**
210  * The padding this will have at the top
211  */
212  Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding NOTIFY topPaddingChanged FINAL)
213 
214  /**
215  * The padding this will have at the bottom
216  */
217  Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding NOTIFY bottomPaddingChanged FINAL)
218 
219  /**
220  * The duration for scrolling animations
221  */
222  Q_PROPERTY(int scrollDuration READ scrollDuration WRITE setScrollDuration NOTIFY scrollDurationChanged FINAL)
223 
224  /**
225  * True if columns should be visually separated by a separator line
226  */
227  Q_PROPERTY(bool separatorVisible READ separatorVisible WRITE setSeparatorVisible NOTIFY separatorVisibleChanged FINAL)
228 
229  /**
230  * The list of all visible column items that are at least partially in the viewport at any given moment
231  */
232  Q_PROPERTY(QList<QObject *> visibleItems READ visibleItems NOTIFY visibleItemsChanged FINAL)
233 
234  /**
235  * The first of visibleItems provided from convenience
236  */
237  Q_PROPERTY(QQuickItem *leadingVisibleItem READ leadingVisibleItem NOTIFY leadingVisibleItemChanged FINAL)
238 
239  /**
240  * The last of visibleItems provided from convenience
241  */
242  Q_PROPERTY(QQuickItem *trailingVisibleItem READ trailingVisibleItem NOTIFY trailingVisibleItemChanged FINAL)
243 
244  // Properties to make it similar to Flickable
245  /**
246  * True when the user is dragging around with touch gestures the view contents
247  */
248  Q_PROPERTY(bool dragging READ dragging NOTIFY draggingChanged FINAL)
249 
250  /**
251  * True both when the user is dragging around with touch gestures the view contents or the view is animating
252  */
253  Q_PROPERTY(bool moving READ moving NOTIFY movingChanged FINAL)
254 
255  /**
256  * True if it supports moving the contents by dragging
257  */
258  Q_PROPERTY(bool interactive READ interactive WRITE setInteractive NOTIFY interactiveChanged FINAL)
259 
260  /**
261  * True if the contents can be dragged also with mouse besides touch
262  */
263  Q_PROPERTY(bool acceptsMouse READ acceptsMouse WRITE setAcceptsMouse NOTIFY acceptsMouseChanged FINAL)
264 
265  // Default properties
266  /**
267  * Every column item the view contains
268  */
269  Q_PROPERTY(QQmlListProperty<QQuickItem> contentChildren READ contentChildren NOTIFY contentChildrenChanged FINAL)
270  /**
271  * every item declared inside the view, both visual and non-visual items
272  */
273  Q_PROPERTY(QQmlListProperty<QObject> contentData READ contentData FINAL)
274  Q_CLASSINFO("DefaultProperty", "contentData")
275 
276 public:
277  enum ColumnResizeMode {
278  FixedColumns = 0,
279  DynamicColumns,
280  SingleColumn,
281  };
282  Q_ENUM(ColumnResizeMode)
283 
284  ColumnView(QQuickItem *parent = nullptr);
285  ~ColumnView() override;
286 
287  // QML property accessors
288  ColumnResizeMode columnResizeMode() const;
289  void setColumnResizeMode(ColumnResizeMode mode);
290 
291  qreal columnWidth() const;
292  void setColumnWidth(qreal width);
293 
294  int currentIndex() const;
295  void setCurrentIndex(int index);
296 
297  int scrollDuration() const;
298  void setScrollDuration(int duration);
299 
300  bool separatorVisible() const;
301  void setSeparatorVisible(bool visible);
302 
303  int count() const;
304 
305  qreal topPadding() const;
306  void setTopPadding(qreal padding);
307 
308  qreal bottomPadding() const;
309  void setBottomPadding(qreal padding);
310 
311  QQuickItem *currentItem();
312 
313  // NOTE: It's a QList<QObject *> as QML can't correctly build an Array out of QList<QQuickItem*>
314  QList<QObject *> visibleItems() const;
315  QQuickItem *leadingVisibleItem() const;
316  QQuickItem *trailingVisibleItem() const;
317 
318  QQuickItem *contentItem() const;
319 
320  QQmlListProperty<QQuickItem> contentChildren();
321  QQmlListProperty<QObject> contentData();
322 
323  bool dragging() const;
324  bool moving() const;
325  qreal contentWidth() const;
326 
327  qreal contentX() const;
328  void setContentX(qreal x) const;
329 
330  bool interactive() const;
331  void setInteractive(bool interactive);
332 
333  bool acceptsMouse() const;
334  void setAcceptsMouse(bool accepts);
335 
336  /**
337  * @brief This method removes all the items after the specified item or
338  * index from the view and returns the last item that was removed.
339  *
340  * Note that if the passed value is neither of the values said below, it
341  * will return a nullptr.
342  *
343  * @param item the item to remove. It can be an item, index or not defined
344  * in which case it will pop the last item.
345  */
346  Q_INVOKABLE QQuickItem *pop(const QVariant &item);
347 
348  /**
349  * @brief This method removes all the items after the specified item from
350  * the view and returns the last item that was removed.
351  *
352  * @see ::removeItem()
353  *
354  * @param the item where the iteration should stop at
355  * @returns the last item that has been removed
356  */
357  QQuickItem *pop(QQuickItem *item);
358 
359  /**
360  * @brief This method removes all the items after the specified position
361  * from the view and returns the last item that was removed.
362  *
363  * It starts iterating from the last item to the first item calling
364  * removeItem() for each of them until it reaches the specified position.
365  *
366  * @see ::removeItem()
367  *
368  * @param the position where the iteration should stop at
369  * @returns the last item that has been removed
370  */
371  QQuickItem *pop(int index);
372 
373  /**
374  * @brief This method removes the last item from the view and returns it.
375  *
376  * This method calls removeItem() on the last item.
377  *
378  * @see ::removeItem()
379  *
380  * @return the removed item
381  */
382  Q_INVOKABLE QQuickItem *pop();
383 
384  /**
385  * @brief This method removes the specified item from the view.
386  *
387  * Items will be reparented to their old parent. If they have JavaScript
388  * ownership and they didn't have an old parent, they will be destroyed.
389  * CurrentIndex may be changed in order to keep the same currentItem
390  *
391  * @param item pointer to the item to remove
392  * @returns the removed item
393  */
394  QQuickItem *removeItem(QQuickItem *item);
395 
396  /**
397  * @brief This method removes an item at a given index from the view.
398  *
399  * This method calls removeItem(QQuickItem *item) to remove the item at
400  * the specified index.
401  *
402  * @see ::removeItem(QQuickItem *item)
403  *
404  * @param index the index of the item which should be removed
405  * @return the removed item
406  */
407  QQuickItem *removeItem(int index);
408 
409  // QML attached property
410  static ColumnViewAttached *qmlAttachedProperties(QObject *object);
411 
412 public Q_SLOTS:
413  /**
414  * Pushes a new item at the end of the view
415  * @param item the new item which will be reparented and managed
416  */
417  void addItem(QQuickItem *item);
418 
419  /**
420  * @brief This method removes an item from the view.
421  *
422  * If the argument is a number, this method dispatches to removeItem(int index)
423  * to remove an item by its index. Otherwise the argument should be the item
424  * itself to be removed itself, and this method will dispatch to removeItem(QQuickItem *item).
425  *
426  * @see ::removeItem(QQuickItem *item)
427  *
428  * @param index the index of the item which should be removed, or the item itself
429  * @return the removed item
430  */
431  Q_INVOKABLE QQuickItem *removeItem(const QVariant &item);
432 
433  /**
434  * Inserts a new item in the view at a given position.
435  * The current Item will not be changed, currentIndex will be adjusted
436  * accordingly if needed to keep the same current item.
437  * @param pos the position we want the new item to be inserted in
438  * @param item the new item which will be reparented and managed
439  */
440  void insertItem(int pos, QQuickItem *item);
441 
442  /**
443  * Replaces an item in the view at a given position with a new item.
444  * The current Item and currentIndex will not be changed.
445  * @param pos the position we want the new item to be placed in
446  * @param item the new item which will be reparented and managed
447  */
448  void replaceItem(int pos, QQuickItem *item);
449 
450  /**
451  * Move an item inside the view.
452  * The currentIndex property may be changed in order to keep currentItem the same.
453  * @param from the old position
454  * @param to the new position
455  */
456  void moveItem(int from, int to);
457 
458  /**
459  * Removes every item in the view.
460  * Items will be reparented to their old parent.
461  * If they have JavaScript ownership and they didn't have an old parent, they will be destroyed
462  */
463  void clear();
464 
465  /**
466  * @returns true if the view contains the given item
467  */
468  bool containsItem(QQuickItem *item);
469 
470  /**
471  * Returns the visible item containing the point x, y in content coordinates.
472  * If there is no item at the point specified, or the item is not visible null is returned.
473  */
474  QQuickItem *itemAt(qreal x, qreal y);
475 
476 protected:
477  void classBegin() override;
478  void componentComplete() override;
479  void updatePolish() override;
480  void itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value) override;
481  void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
482  bool childMouseEventFilter(QQuickItem *item, QEvent *event) override;
483  void mousePressEvent(QMouseEvent *event) override;
484  void mouseMoveEvent(QMouseEvent *event) override;
485  void mouseReleaseEvent(QMouseEvent *event) override;
486  void mouseUngrabEvent() override;
487 
488 Q_SIGNALS:
489  /**
490  * A new item has been inserted
491  * @param position where the page has been inserted
492  * @param item a pointer to the new item
493  */
494  void itemInserted(int position, QQuickItem *item);
495 
496  /**
497  * An item has just been removed from the view
498  * @param item a pointer to the item that has just been removed
499  */
500  void itemRemoved(QQuickItem *item);
501 
502  // Property notifiers
503  void contentChildrenChanged();
504  void columnResizeModeChanged();
505  void columnWidthChanged();
506  void currentIndexChanged();
507  void currentItemChanged();
508  void visibleItemsChanged();
509  void countChanged();
510  void draggingChanged();
511  void movingChanged();
512  void contentXChanged();
513  void contentWidthChanged();
514  void interactiveChanged();
515  void acceptsMouseChanged();
516  void scrollDurationChanged();
517  void separatorVisibleChanged();
518  void leadingVisibleItemChanged();
519  void trailingVisibleItemChanged();
520  void topPaddingChanged();
521  void bottomPaddingChanged();
522 
523 private:
524  static void contentChildren_append(QQmlListProperty<QQuickItem> *prop, QQuickItem *object);
525  static qsizetype contentChildren_count(QQmlListProperty<QQuickItem> *prop);
526  static QQuickItem *contentChildren_at(QQmlListProperty<QQuickItem> *prop, qsizetype index);
527  static void contentChildren_clear(QQmlListProperty<QQuickItem> *prop);
528 
529  static void contentData_append(QQmlListProperty<QObject> *prop, QObject *object);
530  static qsizetype contentData_count(QQmlListProperty<QObject> *prop);
531  static QObject *contentData_at(QQmlListProperty<QObject> *prop, qsizetype index);
532  static void contentData_clear(QQmlListProperty<QObject> *prop);
533 
534  QList<QObject *> m_contentData;
535 
536  ContentItem *m_contentItem;
537  QPointer<QQuickItem> m_currentItem;
538 
539  qreal m_oldMouseX = -1.0;
540  qreal m_startMouseX = -1.0;
541  qreal m_oldMouseY = -1.0;
542  qreal m_startMouseY = -1.0;
543  int m_currentIndex = -1;
544  qreal m_topPadding = 0;
545  qreal m_bottomPadding = 0;
546 
547  bool m_mouseDown = false;
548  bool m_interactive = true;
549  bool m_dragging = false;
550  bool m_moving = false;
551  bool m_separatorVisible = true;
552  bool m_complete = false;
553  bool m_acceptsMouse = false;
554 };
555 
556 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:160
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_INVOKABLEQ_INVOKABLE
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-2024 The KDE developers.
Generated on Thu Feb 15 2024 03:59:21 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.