File indexing completed on 2024-04-21 03:55:58
0001 /* 0002 * SPDX-FileCopyrightText: 2019 Marco Martin <mart@kde.org> 0003 * 0004 * SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #pragma once 0008 0009 #include <QPointer> 0010 #include <QQuickItem> 0011 #include <QVariant> 0012 0013 class ContentItem; 0014 class ColumnView; 0015 0016 class ScrollIntentionEvent : public QObject 0017 { 0018 Q_OBJECT 0019 Q_PROPERTY(QPointF delta MEMBER delta CONSTANT FINAL) 0020 Q_PROPERTY(bool accepted MEMBER accepted FINAL) 0021 public: 0022 ScrollIntentionEvent() 0023 { 0024 } 0025 ~ScrollIntentionEvent() override 0026 { 0027 } 0028 0029 QPointF delta; 0030 bool accepted = false; 0031 }; 0032 0033 /** 0034 * This is an attached property to every item that is inserted in the ColumnView, 0035 * used to access the view and page information such as the position and information for layouting, such as fillWidth 0036 * @since 2.7 0037 */ 0038 class ColumnViewAttached : public QObject 0039 { 0040 Q_OBJECT 0041 0042 /** 0043 * The index position of the column in the view, starting from 0 0044 */ 0045 Q_PROPERTY(int index READ index WRITE setIndex NOTIFY indexChanged FINAL) 0046 0047 /** 0048 * If true, the column will expand to take the whole viewport space minus reservedSpace 0049 */ 0050 Q_PROPERTY(bool fillWidth READ fillWidth WRITE setFillWidth NOTIFY fillWidthChanged FINAL) 0051 0052 /** 0053 * When a column is fillWidth, it will keep reservedSpace amount of pixels from going to fill the full viewport width 0054 */ 0055 Q_PROPERTY(qreal reservedSpace READ reservedSpace WRITE setReservedSpace NOTIFY reservedSpaceChanged FINAL) 0056 0057 /** 0058 * Like the same property of MouseArea, when this is true, the column view won't 0059 * try to manage events by itself when filtering from a child, not 0060 * disturbing user interaction 0061 */ 0062 Q_PROPERTY(bool preventStealing READ preventStealing WRITE setPreventStealing NOTIFY preventStealingChanged FINAL) 0063 0064 /** 0065 * If true the page will never go out of view, but will stay either 0066 * at the right or left side of the ColumnView 0067 */ 0068 Q_PROPERTY(bool pinned READ isPinned WRITE setPinned NOTIFY pinnedChanged FINAL) 0069 0070 /** 0071 * The view this column belongs to 0072 */ 0073 Q_PROPERTY(ColumnView *view READ view NOTIFY viewChanged FINAL) 0074 0075 /** 0076 * True if this column is at least partly visible in the ColumnView's viewport. 0077 * @since 5.77 0078 */ 0079 Q_PROPERTY(bool inViewport READ inViewport NOTIFY inViewportChanged FINAL) 0080 0081 Q_PROPERTY(QQuickItem *globalHeader READ globalHeader WRITE setGlobalHeader NOTIFY globalHeaderChanged FINAL) 0082 Q_PROPERTY(QQuickItem *globalFooter READ globalFooter WRITE setGlobalFooter NOTIFY globalFooterChanged FINAL) 0083 0084 public: 0085 ColumnViewAttached(QObject *parent = nullptr); 0086 ~ColumnViewAttached() override; 0087 0088 void setIndex(int index); 0089 int index() const; 0090 0091 void setFillWidth(bool fill); 0092 bool fillWidth() const; 0093 0094 qreal reservedSpace() const; 0095 void setReservedSpace(qreal space); 0096 0097 ColumnView *view(); 0098 void setView(ColumnView *view); 0099 0100 // Private API, not for QML use 0101 QQuickItem *originalParent() const; 0102 void setOriginalParent(QQuickItem *parent); 0103 0104 bool shouldDeleteOnRemove() const; 0105 void setShouldDeleteOnRemove(bool del); 0106 0107 bool preventStealing() const; 0108 void setPreventStealing(bool prevent); 0109 0110 bool isPinned() const; 0111 void setPinned(bool pinned); 0112 0113 bool inViewport() const; 0114 void setInViewport(bool inViewport); 0115 0116 QQuickItem *globalHeader() const; 0117 void setGlobalHeader(QQuickItem *header); 0118 0119 QQuickItem *globalFooter() const; 0120 void setGlobalFooter(QQuickItem *footer); 0121 0122 Q_SIGNALS: 0123 void indexChanged(); 0124 void fillWidthChanged(); 0125 void reservedSpaceChanged(); 0126 void viewChanged(); 0127 void preventStealingChanged(); 0128 void pinnedChanged(); 0129 void scrollIntention(ScrollIntentionEvent *event); 0130 void inViewportChanged(); 0131 void globalHeaderChanged(QQuickItem *oldHeader, QQuickItem *newHeader); 0132 void globalFooterChanged(QQuickItem *oldFooter, QQuickItem *newFooter); 0133 0134 private: 0135 int m_index = -1; 0136 bool m_fillWidth = false; 0137 qreal m_reservedSpace = 0; 0138 QPointer<ColumnView> m_view; 0139 QPointer<QQuickItem> m_originalParent; 0140 bool m_customFillWidth = false; 0141 bool m_customReservedSpace = false; 0142 bool m_shouldDeleteOnRemove = true; 0143 bool m_preventStealing = false; 0144 bool m_pinned = false; 0145 bool m_inViewport = false; 0146 QPointer<QQuickItem> m_globalHeader; 0147 QPointer<QQuickItem> m_globalFooter; 0148 }; 0149 0150 /** 0151 * ColumnView is a container that lays out items horizontally in a row, 0152 * 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. 0153 * The columns can either all have the same fixed size (recommended), 0154 * size themselves with implicitWidth, or automatically expand to take all the available width: by default the last column will always be the expanding one. 0155 * Items inside the ColumnView can access info of the view and set layouting hints via the ColumnView attached property. 0156 * 0157 * This is the base for the implementation of PageRow 0158 * @since 2.7 0159 */ 0160 class ColumnView : public QQuickItem 0161 { 0162 Q_OBJECT 0163 QML_ELEMENT 0164 QML_ATTACHED(ColumnViewAttached) 0165 0166 /** 0167 * The strategy to follow while automatically resizing the columns, 0168 * the enum can have the following values: 0169 * * FixedColumns: every column is fixed at the same width of the columnWidth property 0170 * * DynamicColumns: columns take their width from their implicitWidth 0171 * * SingleColumn: only one column at a time is shown, as wide as the viewport, eventual reservedSpace on the column's attached property is ignored 0172 */ 0173 Q_PROPERTY(ColumnResizeMode columnResizeMode READ columnResizeMode WRITE setColumnResizeMode NOTIFY columnResizeModeChanged FINAL) 0174 0175 /** 0176 * The width of all columns when columnResizeMode is FixedColumns 0177 */ 0178 Q_PROPERTY(qreal columnWidth READ columnWidth WRITE setColumnWidth NOTIFY columnWidthChanged FINAL) 0179 0180 /** 0181 * How many columns this view containsItem*/ 0182 Q_PROPERTY(int count READ count NOTIFY countChanged FINAL) 0183 0184 /** 0185 * The position of the currently active column. The current column will also have keyboard focus 0186 */ 0187 Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged FINAL) 0188 0189 /** 0190 * The currently active column. The current column will also have keyboard focus 0191 */ 0192 Q_PROPERTY(QQuickItem *currentItem READ currentItem NOTIFY currentItemChanged FINAL) 0193 0194 /** 0195 * The main content item of this view: it's the parent of the column items 0196 */ 0197 Q_PROPERTY(QQuickItem *contentItem READ contentItem CONSTANT FINAL) 0198 0199 /** 0200 * The value of the horizontal scroll of the view, in pixels 0201 */ 0202 Q_PROPERTY(qreal contentX READ contentX WRITE setContentX NOTIFY contentXChanged FINAL) 0203 0204 /** 0205 * The compound width of all columns in the view 0206 */ 0207 Q_PROPERTY(qreal contentWidth READ contentWidth NOTIFY contentWidthChanged FINAL) 0208 0209 /** 0210 * The padding this will have at the top 0211 */ 0212 Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding NOTIFY topPaddingChanged FINAL) 0213 0214 /** 0215 * The padding this will have at the bottom 0216 */ 0217 Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding NOTIFY bottomPaddingChanged FINAL) 0218 0219 /** 0220 * The duration for scrolling animations 0221 */ 0222 Q_PROPERTY(int scrollDuration READ scrollDuration WRITE setScrollDuration NOTIFY scrollDurationChanged FINAL) 0223 0224 /** 0225 * True if columns should be visually separated by a separator line 0226 */ 0227 Q_PROPERTY(bool separatorVisible READ separatorVisible WRITE setSeparatorVisible NOTIFY separatorVisibleChanged FINAL) 0228 0229 /** 0230 * The list of all visible column items that are at least partially in the viewport at any given moment 0231 */ 0232 Q_PROPERTY(QList<QObject *> visibleItems READ visibleItems NOTIFY visibleItemsChanged FINAL) 0233 0234 /** 0235 * The first of visibleItems provided from convenience 0236 */ 0237 Q_PROPERTY(QQuickItem *leadingVisibleItem READ leadingVisibleItem NOTIFY leadingVisibleItemChanged FINAL) 0238 0239 /** 0240 * The last of visibleItems provided from convenience 0241 */ 0242 Q_PROPERTY(QQuickItem *trailingVisibleItem READ trailingVisibleItem NOTIFY trailingVisibleItemChanged FINAL) 0243 0244 // Properties to make it similar to Flickable 0245 /** 0246 * True when the user is dragging around with touch gestures the view contents 0247 */ 0248 Q_PROPERTY(bool dragging READ dragging NOTIFY draggingChanged FINAL) 0249 0250 /** 0251 * True both when the user is dragging around with touch gestures the view contents or the view is animating 0252 */ 0253 Q_PROPERTY(bool moving READ moving NOTIFY movingChanged FINAL) 0254 0255 /** 0256 * True if it supports moving the contents by dragging 0257 */ 0258 Q_PROPERTY(bool interactive READ interactive WRITE setInteractive NOTIFY interactiveChanged FINAL) 0259 0260 /** 0261 * True if the contents can be dragged also with mouse besides touch 0262 */ 0263 Q_PROPERTY(bool acceptsMouse READ acceptsMouse WRITE setAcceptsMouse NOTIFY acceptsMouseChanged FINAL) 0264 0265 // Default properties 0266 /** 0267 * Every column item the view contains 0268 */ 0269 Q_PROPERTY(QQmlListProperty<QQuickItem> contentChildren READ contentChildren NOTIFY contentChildrenChanged FINAL) 0270 /** 0271 * every item declared inside the view, both visual and non-visual items 0272 */ 0273 Q_PROPERTY(QQmlListProperty<QObject> contentData READ contentData FINAL) 0274 Q_CLASSINFO("DefaultProperty", "contentData") 0275 0276 public: 0277 enum ColumnResizeMode { 0278 FixedColumns = 0, 0279 DynamicColumns, 0280 SingleColumn, 0281 }; 0282 Q_ENUM(ColumnResizeMode) 0283 0284 ColumnView(QQuickItem *parent = nullptr); 0285 ~ColumnView() override; 0286 0287 // QML property accessors 0288 ColumnResizeMode columnResizeMode() const; 0289 void setColumnResizeMode(ColumnResizeMode mode); 0290 0291 qreal columnWidth() const; 0292 void setColumnWidth(qreal width); 0293 0294 int currentIndex() const; 0295 void setCurrentIndex(int index); 0296 0297 int scrollDuration() const; 0298 void setScrollDuration(int duration); 0299 0300 bool separatorVisible() const; 0301 void setSeparatorVisible(bool visible); 0302 0303 int count() const; 0304 0305 qreal topPadding() const; 0306 void setTopPadding(qreal padding); 0307 0308 qreal bottomPadding() const; 0309 void setBottomPadding(qreal padding); 0310 0311 QQuickItem *currentItem(); 0312 0313 // NOTE: It's a QList<QObject *> as QML can't correctly build an Array out of QList<QQuickItem*> 0314 QList<QObject *> visibleItems() const; 0315 QQuickItem *leadingVisibleItem() const; 0316 QQuickItem *trailingVisibleItem() const; 0317 0318 QQuickItem *contentItem() const; 0319 0320 QQmlListProperty<QQuickItem> contentChildren(); 0321 QQmlListProperty<QObject> contentData(); 0322 0323 bool dragging() const; 0324 bool moving() const; 0325 qreal contentWidth() const; 0326 0327 qreal contentX() const; 0328 void setContentX(qreal x) const; 0329 0330 bool interactive() const; 0331 void setInteractive(bool interactive); 0332 0333 bool acceptsMouse() const; 0334 void setAcceptsMouse(bool accepts); 0335 0336 /** 0337 * @brief This method removes all the items after the specified item or 0338 * index from the view and returns the last item that was removed. 0339 * 0340 * Note that if the passed value is neither of the values said below, it 0341 * will return a nullptr. 0342 * 0343 * @param item the item to remove. It can be an item, index or not defined 0344 * in which case it will pop the last item. 0345 */ 0346 Q_INVOKABLE QQuickItem *pop(const QVariant &item); 0347 0348 /** 0349 * @brief This method removes all the items after the specified item from 0350 * the view and returns the last item that was removed. 0351 * 0352 * @see ::removeItem() 0353 * 0354 * @param the item where the iteration should stop at 0355 * @returns the last item that has been removed 0356 */ 0357 QQuickItem *pop(QQuickItem *item); 0358 0359 /** 0360 * @brief This method removes all the items after the specified position 0361 * from the view and returns the last item that was removed. 0362 * 0363 * It starts iterating from the last item to the first item calling 0364 * removeItem() for each of them until it reaches the specified position. 0365 * 0366 * @see ::removeItem() 0367 * 0368 * @param the position where the iteration should stop at 0369 * @returns the last item that has been removed 0370 */ 0371 QQuickItem *pop(int index); 0372 0373 /** 0374 * @brief This method removes the last item from the view and returns it. 0375 * 0376 * This method calls removeItem() on the last item. 0377 * 0378 * @see ::removeItem() 0379 * 0380 * @return the removed item 0381 */ 0382 Q_INVOKABLE QQuickItem *pop(); 0383 0384 /** 0385 * @brief This method removes the specified item from the view. 0386 * 0387 * Items will be reparented to their old parent. If they have JavaScript 0388 * ownership and they didn't have an old parent, they will be destroyed. 0389 * CurrentIndex may be changed in order to keep the same currentItem 0390 * 0391 * @param item pointer to the item to remove 0392 * @returns the removed item 0393 */ 0394 QQuickItem *removeItem(QQuickItem *item); 0395 0396 /** 0397 * @brief This method removes an item at a given index from the view. 0398 * 0399 * This method calls removeItem(QQuickItem *item) to remove the item at 0400 * the specified index. 0401 * 0402 * @see ::removeItem(QQuickItem *item) 0403 * 0404 * @param index the index of the item which should be removed 0405 * @return the removed item 0406 */ 0407 QQuickItem *removeItem(int index); 0408 0409 // QML attached property 0410 static ColumnViewAttached *qmlAttachedProperties(QObject *object); 0411 0412 public Q_SLOTS: 0413 /** 0414 * Pushes a new item at the end of the view 0415 * @param item the new item which will be reparented and managed 0416 */ 0417 void addItem(QQuickItem *item); 0418 0419 /** 0420 * @brief This method removes an item from the view. 0421 * 0422 * If the argument is a number, this method dispatches to removeItem(int index) 0423 * to remove an item by its index. Otherwise the argument should be the item 0424 * itself to be removed itself, and this method will dispatch to removeItem(QQuickItem *item). 0425 * 0426 * @see ::removeItem(QQuickItem *item) 0427 * 0428 * @param index the index of the item which should be removed, or the item itself 0429 * @return the removed item 0430 */ 0431 Q_INVOKABLE QQuickItem *removeItem(const QVariant &item); 0432 0433 /** 0434 * Inserts a new item in the view at a given position. 0435 * The current Item will not be changed, currentIndex will be adjusted 0436 * accordingly if needed to keep the same current item. 0437 * @param pos the position we want the new item to be inserted in 0438 * @param item the new item which will be reparented and managed 0439 */ 0440 void insertItem(int pos, QQuickItem *item); 0441 0442 /** 0443 * Replaces an item in the view at a given position with a new item. 0444 * The current Item and currentIndex will not be changed. 0445 * @param pos the position we want the new item to be placed in 0446 * @param item the new item which will be reparented and managed 0447 */ 0448 void replaceItem(int pos, QQuickItem *item); 0449 0450 /** 0451 * Move an item inside the view. 0452 * The currentIndex property may be changed in order to keep currentItem the same. 0453 * @param from the old position 0454 * @param to the new position 0455 */ 0456 void moveItem(int from, int to); 0457 0458 /** 0459 * Removes every item in the view. 0460 * Items will be reparented to their old parent. 0461 * If they have JavaScript ownership and they didn't have an old parent, they will be destroyed 0462 */ 0463 void clear(); 0464 0465 /** 0466 * @returns true if the view contains the given item 0467 */ 0468 bool containsItem(QQuickItem *item); 0469 0470 /** 0471 * Returns the visible item containing the point x, y in content coordinates. 0472 * If there is no item at the point specified, or the item is not visible null is returned. 0473 */ 0474 QQuickItem *itemAt(qreal x, qreal y); 0475 0476 protected: 0477 void classBegin() override; 0478 void componentComplete() override; 0479 void updatePolish() override; 0480 void itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value) override; 0481 void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override; 0482 bool childMouseEventFilter(QQuickItem *item, QEvent *event) override; 0483 void mousePressEvent(QMouseEvent *event) override; 0484 void mouseMoveEvent(QMouseEvent *event) override; 0485 void mouseReleaseEvent(QMouseEvent *event) override; 0486 void mouseUngrabEvent() override; 0487 0488 Q_SIGNALS: 0489 /** 0490 * A new item has been inserted 0491 * @param position where the page has been inserted 0492 * @param item a pointer to the new item 0493 */ 0494 void itemInserted(int position, QQuickItem *item); 0495 0496 /** 0497 * An item has just been removed from the view 0498 * @param item a pointer to the item that has just been removed 0499 */ 0500 void itemRemoved(QQuickItem *item); 0501 0502 // Property notifiers 0503 void contentChildrenChanged(); 0504 void columnResizeModeChanged(); 0505 void columnWidthChanged(); 0506 void currentIndexChanged(); 0507 void currentItemChanged(); 0508 void visibleItemsChanged(); 0509 void countChanged(); 0510 void draggingChanged(); 0511 void movingChanged(); 0512 void contentXChanged(); 0513 void contentWidthChanged(); 0514 void interactiveChanged(); 0515 void acceptsMouseChanged(); 0516 void scrollDurationChanged(); 0517 void separatorVisibleChanged(); 0518 void leadingVisibleItemChanged(); 0519 void trailingVisibleItemChanged(); 0520 void topPaddingChanged(); 0521 void bottomPaddingChanged(); 0522 0523 private: 0524 static void contentChildren_append(QQmlListProperty<QQuickItem> *prop, QQuickItem *object); 0525 static qsizetype contentChildren_count(QQmlListProperty<QQuickItem> *prop); 0526 static QQuickItem *contentChildren_at(QQmlListProperty<QQuickItem> *prop, qsizetype index); 0527 static void contentChildren_clear(QQmlListProperty<QQuickItem> *prop); 0528 0529 static void contentData_append(QQmlListProperty<QObject> *prop, QObject *object); 0530 static qsizetype contentData_count(QQmlListProperty<QObject> *prop); 0531 static QObject *contentData_at(QQmlListProperty<QObject> *prop, qsizetype index); 0532 static void contentData_clear(QQmlListProperty<QObject> *prop); 0533 0534 QList<QObject *> m_contentData; 0535 0536 ContentItem *m_contentItem; 0537 QPointer<QQuickItem> m_currentItem; 0538 0539 qreal m_oldMouseX = -1.0; 0540 qreal m_startMouseX = -1.0; 0541 qreal m_oldMouseY = -1.0; 0542 qreal m_startMouseY = -1.0; 0543 int m_currentIndex = -1; 0544 qreal m_topPadding = 0; 0545 qreal m_bottomPadding = 0; 0546 0547 bool m_mouseDown = false; 0548 bool m_interactive = true; 0549 bool m_dragging = false; 0550 bool m_moving = false; 0551 bool m_separatorVisible = true; 0552 bool m_complete = false; 0553 bool m_acceptsMouse = false; 0554 }; 0555 0556 QML_DECLARE_TYPEINFO(ColumnView, QML_HAS_ATTACHED_PROPERTIES)