File indexing completed on 2024-05-12 05:47:31
0001 /* 0002 * SPDX-FileCopyrightText: 2011 Peter Penz <peter.penz19@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef KITEMLISTVIEWLAYOUTER_H 0008 #define KITEMLISTVIEWLAYOUTER_H 0009 0010 #include "dolphin_export.h" 0011 0012 #include <QObject> 0013 #include <QRectF> 0014 #include <QSet> 0015 #include <QSizeF> 0016 #include <QVector> 0017 0018 class KItemModelBase; 0019 class KItemListSizeHintResolver; 0020 0021 /** 0022 * @brief Internal helper class for KItemListView to layout the items. 0023 * 0024 * The layouter is capable to align the items within a grid. If the 0025 * scroll-direction is horizontal the column-width of the grid can be 0026 * variable. If the scroll-direction is vertical the row-height of 0027 * the grid can be variable. 0028 * 0029 * The layouter is implemented in a way that it postpones the expensive 0030 * layout operation until a property is read the first time after 0031 * marking the layouter as dirty (see markAsDirty()). This means that 0032 * changing properties of the layouter is not expensive, only the 0033 * first read of a property can get expensive. 0034 */ 0035 class DOLPHIN_EXPORT KItemListViewLayouter : public QObject 0036 { 0037 Q_OBJECT 0038 0039 public: 0040 explicit KItemListViewLayouter(KItemListSizeHintResolver *sizeHintResolver, QObject *parent = nullptr); 0041 ~KItemListViewLayouter() override; 0042 0043 void setScrollOrientation(Qt::Orientation orientation); 0044 Qt::Orientation scrollOrientation() const; 0045 0046 void setSize(const QSizeF &size); 0047 QSizeF size() const; 0048 0049 void setItemSize(const QSizeF &size); 0050 QSizeF itemSize() const; 0051 0052 /** 0053 * Margin between the rows and columns of items. 0054 */ 0055 void setItemMargin(const QSizeF &margin); 0056 QSizeF itemMargin() const; 0057 0058 /** 0059 * Sets the height of the header that is always aligned 0060 * at the top. A height of <= 0.0 means that no header is 0061 * used. 0062 */ 0063 void setHeaderHeight(qreal height); 0064 qreal headerHeight() const; 0065 0066 /** 0067 * Sets the height of the group header that is used 0068 * to indicate a new item group. 0069 */ 0070 void setGroupHeaderHeight(qreal height); 0071 qreal groupHeaderHeight() const; 0072 0073 /** 0074 * Sets the margin between the last items of the group n and 0075 * the group header for the group n + 1. 0076 */ 0077 void setGroupHeaderMargin(qreal margin); 0078 qreal groupHeaderMargin() const; 0079 0080 void setScrollOffset(qreal scrollOffset); 0081 qreal scrollOffset() const; 0082 0083 qreal maximumScrollOffset() const; 0084 0085 void setItemOffset(qreal scrollOffset); 0086 qreal itemOffset() const; 0087 0088 qreal maximumItemOffset() const; 0089 0090 void setModel(const KItemModelBase *model); 0091 const KItemModelBase *model() const; 0092 0093 /** 0094 * @return The first (at least partly) visible index. -1 is returned 0095 * if the item count is 0. 0096 */ 0097 int firstVisibleIndex() const; 0098 0099 /** 0100 * @return The last (at least partly) visible index. -1 is returned 0101 * if the item count is 0. 0102 */ 0103 int lastVisibleIndex() const; 0104 0105 /** 0106 * @return Rectangle of the item with the index \a index. 0107 * The top/left of the bounding rectangle is related to 0108 * the top/left of the KItemListView. An empty rectangle 0109 * is returned if an invalid index is given. 0110 */ 0111 QRectF itemRect(int index) const; 0112 0113 /** 0114 * @return Rectangle of the group header for the item with the 0115 * index \a index. Note that the layouter does not check 0116 * whether the item really has a header: Usually only 0117 * the first item of a group gets a header (see 0118 * isFirstGroupItem()). 0119 */ 0120 QRectF groupHeaderRect(int index) const; 0121 0122 /** 0123 * @return Column of the item with the index \a index. 0124 * -1 is returned if an invalid index is given. 0125 */ 0126 int itemColumn(int index) const; 0127 0128 /** 0129 * @return Row of the item with the index \a index. 0130 * -1 is returned if an invalid index is given. 0131 */ 0132 int itemRow(int index) const; 0133 0134 /** 0135 * @return Maximum number of (at least partly) visible items for 0136 * the given size. 0137 */ 0138 int maximumVisibleItems() const; 0139 0140 /** 0141 * @return True if the item with the index \p itemIndex 0142 * is the first item within a group. 0143 */ 0144 bool isFirstGroupItem(int itemIndex) const; 0145 0146 /** 0147 * Marks the layouter as dirty. This means as soon as a property of 0148 * the layouter gets read, an expensive relayout will be done. 0149 */ 0150 void markAsDirty(); 0151 0152 inline int columnCount() const 0153 { 0154 return m_columnCount; 0155 } 0156 0157 #ifndef QT_NO_DEBUG 0158 /** 0159 * @return True if the layouter has been marked as dirty and hence has 0160 * not called yet doLayout(). Is enabled only in the debugging 0161 * mode, as it is not useful to check the dirty state otherwise. 0162 */ 0163 bool isDirty(); 0164 #endif 0165 0166 private: 0167 void doLayout(); 0168 void updateVisibleIndexes(); 0169 bool createGroupHeaders(); 0170 0171 /** 0172 * @return Minimum width of group headers when grouping is enabled in the horizontal 0173 * alignment mode. The header alignment is done like this: 0174 * Header-1 Header-2 Header-3 0175 * Item 1 Item 4 Item 7 0176 * Item 2 Item 5 Item 8 0177 * Item 3 Item 6 Item 9 0178 */ 0179 qreal minimumGroupHeaderWidth() const; 0180 0181 private: 0182 bool m_dirty; 0183 bool m_visibleIndexesDirty; 0184 0185 Qt::Orientation m_scrollOrientation; 0186 QSizeF m_size; 0187 0188 QSizeF m_itemSize; 0189 QSizeF m_itemMargin; 0190 qreal m_headerHeight; 0191 const KItemModelBase *m_model; 0192 KItemListSizeHintResolver *m_sizeHintResolver; 0193 0194 qreal m_scrollOffset; 0195 qreal m_maximumScrollOffset; 0196 0197 qreal m_itemOffset; 0198 qreal m_maximumItemOffset; 0199 0200 int m_firstVisibleIndex; 0201 int m_lastVisibleIndex; 0202 0203 qreal m_columnWidth; 0204 qreal m_xPosInc; 0205 int m_columnCount; 0206 0207 QVector<qreal> m_rowOffsets; 0208 QVector<qreal> m_columnOffsets; 0209 0210 // Stores all item indexes that are the first item of a group. 0211 // Assures fast access for KItemListViewLayouter::isFirstGroupItem(). 0212 QSet<int> m_groupItemIndexes; 0213 qreal m_groupHeaderHeight; 0214 qreal m_groupHeaderMargin; 0215 0216 struct ItemInfo { 0217 int column; 0218 int row; 0219 }; 0220 QVector<ItemInfo> m_itemInfos; 0221 0222 friend class KItemListControllerTest; 0223 }; 0224 0225 #endif