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