]> cloud.milkyroute.net Git - dolphin.git/blob - src/kitemviews/private/kitemlistviewlayouter.h
Merge remote-tracking branch 'origin/KDE/4.11' into KDE/4.12
[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(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 void setSizeHintResolver(const KItemListSizeHintResolver* sizeHintResolver);
107 const KItemListSizeHintResolver* sizeHintResolver() const;
108
109 /**
110 * @return The first (at least partly) visible index. -1 is returned
111 * if the item count is 0.
112 */
113 int firstVisibleIndex() const;
114
115 /**
116 * @return The last (at least partly) visible index. -1 is returned
117 * if the item count is 0.
118 */
119 int lastVisibleIndex() const;
120
121 /**
122 * @return Rectangle of the item with the index \a index.
123 * The top/left of the bounding rectangle is related to
124 * the top/left of the KItemListView. An empty rectangle
125 * is returned if an invalid index is given.
126 */
127 QRectF itemRect(int index) const;
128
129 /**
130 * @return Rectangle of the group header for the item with the
131 * index \a index. Note that the layouter does not check
132 * whether the item really has a header: Usually only
133 * the first item of a group gets a header (see
134 * isFirstGroupItem()).
135 */
136 QRectF groupHeaderRect(int index) const;
137
138 /**
139 * @return Column of the item with the index \a index.
140 * -1 is returned if an invalid index is given.
141 */
142 int itemColumn(int index) const;
143
144 /**
145 * @return Row of the item with the index \a index.
146 * -1 is returned if an invalid index is given.
147 */
148 int itemRow(int index) const;
149
150 /**
151 * @return Maximum number of (at least partly) visible items for
152 * the given size.
153 */
154 int maximumVisibleItems() const;
155
156 /**
157 * @return True if the item with the index \p itemIndex
158 * is the first item within a group.
159 */
160 bool isFirstGroupItem(int itemIndex) const;
161
162 /**
163 * Marks the layouter as dirty. This means as soon as a property of
164 * the layouter gets read, an expensive relayout will be done.
165 */
166 void markAsDirty();
167
168 inline int columnCount() const
169 {
170 return m_columnCount;
171 }
172
173 #ifndef QT_NO_DEBUG
174 /**
175 * @return True if the layouter has been marked as dirty and hence has
176 * not called yet doLayout(). Is enabled only in the debugging
177 * mode, as it is not useful to check the dirty state otherwise.
178 */
179 bool isDirty();
180 #endif
181
182 private:
183 void doLayout();
184 void updateVisibleIndexes();
185 bool createGroupHeaders();
186
187 /**
188 * @return Minimum width of group headers when grouping is enabled in the horizontal
189 * alignment mode. The header alignment is done like this:
190 * Header-1 Header-2 Header-3
191 * Item 1 Item 4 Item 7
192 * Item 2 Item 5 Item 8
193 * Item 3 Item 6 Item 9
194 */
195 qreal minimumGroupHeaderWidth() const;
196
197 private:
198 bool m_dirty;
199 bool m_visibleIndexesDirty;
200
201 Qt::Orientation m_scrollOrientation;
202 QSizeF m_size;
203
204 QSizeF m_itemSize;
205 QSizeF m_itemMargin;
206 qreal m_headerHeight;
207 const KItemModelBase* m_model;
208 const KItemListSizeHintResolver* m_sizeHintResolver;
209
210 qreal m_scrollOffset;
211 qreal m_maximumScrollOffset;
212
213 qreal m_itemOffset;
214 qreal m_maximumItemOffset;
215
216 int m_firstVisibleIndex;
217 int m_lastVisibleIndex;
218
219 qreal m_columnWidth;
220 qreal m_xPosInc;
221 int m_columnCount;
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 QPointF pos;
231 int column;
232 int row;
233 };
234 QVector<ItemInfo> m_itemInfos;
235
236 friend class KItemListControllerTest;
237 };
238
239 #endif
240
241