]> cloud.milkyroute.net Git - dolphin.git/blob - src/kitemviews/private/kitemlistviewlayouter.h
d5dc6dae1cbe45e6b5a86fbed8e66919b40a1a0b
[dolphin.git] / src / kitemviews / private / kitemlistviewlayouter.h
1 /*
2 * SPDX-FileCopyrightText: 2011 Peter Penz <peter.penz19@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7 #ifndef KITEMLISTVIEWLAYOUTER_H
8 #define KITEMLISTVIEWLAYOUTER_H
9
10 #include "dolphin_export.h"
11
12 #include <QObject>
13 #include <QRectF>
14 #include <QSet>
15 #include <QSizeF>
16 #include <QVector>
17
18 class KItemModelBase;
19 class KItemListSizeHintResolver;
20
21 /**
22 * @brief Internal helper class for KItemListView to layout the items.
23 *
24 * The layouter is capable to align the items within a grid. If the
25 * scroll-direction is horizontal the column-width of the grid can be
26 * variable. If the scroll-direction is vertical the row-height of
27 * the grid can be variable.
28 *
29 * The layouter is implemented in a way that it postpones the expensive
30 * layout operation until a property is read the first time after
31 * marking the layouter as dirty (see markAsDirty()). This means that
32 * changing properties of the layouter is not expensive, only the
33 * first read of a property can get expensive.
34 */
35 class DOLPHIN_EXPORT KItemListViewLayouter : public QObject
36 {
37 Q_OBJECT
38
39 public:
40 explicit KItemListViewLayouter(KItemListSizeHintResolver* sizeHintResolver, QObject* parent = nullptr);
41 ~KItemListViewLayouter() override;
42
43 void setScrollOrientation(Qt::Orientation orientation);
44 Qt::Orientation scrollOrientation() const;
45
46 void setSize(const QSizeF& size);
47 QSizeF size() const;
48
49 void setItemSize(const QSizeF& size);
50 QSizeF itemSize() const;
51
52 /**
53 * Margin between the rows and columns of items.
54 */
55 void setItemMargin(const QSizeF& margin);
56 QSizeF itemMargin() const;
57
58 /**
59 * Sets the height of the header that is always aligned
60 * at the top. A height of <= 0.0 means that no header is
61 * used.
62 */
63 void setHeaderHeight(qreal height);
64 qreal headerHeight() const;
65
66 /**
67 * Sets the height of the group header that is used
68 * to indicate a new item group.
69 */
70 void setGroupHeaderHeight(qreal height);
71 qreal groupHeaderHeight() const;
72
73 /**
74 * Sets the margin between the last items of the group n and
75 * the group header for the group n + 1.
76 */
77 void setGroupHeaderMargin(qreal margin);
78 qreal groupHeaderMargin() const;
79
80 void setScrollOffset(qreal scrollOffset);
81 qreal scrollOffset() const;
82
83 qreal maximumScrollOffset() const;
84
85 void setItemOffset(qreal scrollOffset);
86 qreal itemOffset() const;
87
88 qreal maximumItemOffset() const;
89
90 void setModel(const KItemModelBase* model);
91 const KItemModelBase* model() const;
92
93 /**
94 * @return The first (at least partly) visible index. -1 is returned
95 * if the item count is 0.
96 */
97 int firstVisibleIndex() const;
98
99 /**
100 * @return The last (at least partly) visible index. -1 is returned
101 * if the item count is 0.
102 */
103 int lastVisibleIndex() const;
104
105 /**
106 * @return Rectangle of the item with the index \a index.
107 * The top/left of the bounding rectangle is related to
108 * the top/left of the KItemListView. An empty rectangle
109 * is returned if an invalid index is given.
110 */
111 QRectF itemRect(int index) const;
112
113 /**
114 * @return Rectangle of the group header for the item with the
115 * index \a index. Note that the layouter does not check
116 * whether the item really has a header: Usually only
117 * the first item of a group gets a header (see
118 * isFirstGroupItem()).
119 */
120 QRectF groupHeaderRect(int index) const;
121
122 /**
123 * @return Column of the item with the index \a index.
124 * -1 is returned if an invalid index is given.
125 */
126 int itemColumn(int index) const;
127
128 /**
129 * @return Row of the item with the index \a index.
130 * -1 is returned if an invalid index is given.
131 */
132 int itemRow(int index) const;
133
134 /**
135 * @return Maximum number of (at least partly) visible items for
136 * the given size.
137 */
138 int maximumVisibleItems() const;
139
140 /**
141 * @return True if the item with the index \p itemIndex
142 * is the first item within a group.
143 */
144 bool isFirstGroupItem(int itemIndex) const;
145
146 /**
147 * Marks the layouter as dirty. This means as soon as a property of
148 * the layouter gets read, an expensive relayout will be done.
149 */
150 void markAsDirty();
151
152 inline int columnCount() const
153 {
154 return m_columnCount;
155 }
156
157 #ifndef QT_NO_DEBUG
158 /**
159 * @return True if the layouter has been marked as dirty and hence has
160 * not called yet doLayout(). Is enabled only in the debugging
161 * mode, as it is not useful to check the dirty state otherwise.
162 */
163 bool isDirty();
164 #endif
165
166 private:
167 void doLayout();
168 void updateVisibleIndexes();
169 bool createGroupHeaders();
170
171 /**
172 * @return Minimum width of group headers when grouping is enabled in the horizontal
173 * alignment mode. The header alignment is done like this:
174 * Header-1 Header-2 Header-3
175 * Item 1 Item 4 Item 7
176 * Item 2 Item 5 Item 8
177 * Item 3 Item 6 Item 9
178 */
179 qreal minimumGroupHeaderWidth() const;
180
181 private:
182 bool m_dirty;
183 bool m_visibleIndexesDirty;
184
185 Qt::Orientation m_scrollOrientation;
186 QSizeF m_size;
187
188 QSizeF m_itemSize;
189 QSizeF m_itemMargin;
190 qreal m_headerHeight;
191 const KItemModelBase* m_model;
192 KItemListSizeHintResolver* m_sizeHintResolver;
193
194 qreal m_scrollOffset;
195 qreal m_maximumScrollOffset;
196
197 qreal m_itemOffset;
198 qreal m_maximumItemOffset;
199
200 int m_firstVisibleIndex;
201 int m_lastVisibleIndex;
202
203 qreal m_columnWidth;
204 qreal m_xPosInc;
205 int m_columnCount;
206
207 QVector<qreal> m_rowOffsets;
208 QVector<qreal> m_columnOffsets;
209
210 // Stores all item indexes that are the first item of a group.
211 // Assures fast access for KItemListViewLayouter::isFirstGroupItem().
212 QSet<int> m_groupItemIndexes;
213 qreal m_groupHeaderHeight;
214 qreal m_groupHeaderMargin;
215
216 struct ItemInfo {
217 int column;
218 int row;
219 };
220 QVector<ItemInfo> m_itemInfos;
221
222 friend class KItemListControllerTest;
223 };
224
225 #endif
226
227