1 | /*************************************************************************** |
2 | * Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com> * |
3 | * * |
4 | * Based on the Itemviews NG project from Trolltech Labs: * |
5 | * http://qt.gitorious.org/qt-labs/itemviews-ng * |
6 | * * |
7 | * This program is free software; you can redistribute it and/or modify * |
8 | * it under the terms of the GNU General Public License as published by * |
9 | * the Free Software Foundation; either version 2 of the License, or * |
10 | * (at your option) any later version. * |
11 | * * |
12 | * This program is distributed in the hope that it will be useful, * |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * |
15 | * GNU General Public License for more details. * |
16 | * * |
17 | * You should have received a copy of the GNU General Public License * |
18 | * along with this program; if not, write to the * |
19 | * Free Software Foundation, Inc., * |
20 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * |
21 | ***************************************************************************/ |
22 | |
23 | #ifndef KITEMLISTWIDGET_H |
24 | #define KITEMLISTWIDGET_H |
25 | |
26 | #include <libdolphin_export.h> |
27 | |
28 | #include <kitemviews/kitemliststyleoption.h> |
29 | |
30 | #include <QBitArray> |
31 | #include <QGraphicsWidget> |
32 | #include <QStyle> |
33 | |
34 | class KItemListSelectionToggle; |
35 | class KItemListView; |
36 | class QPropertyAnimation; |
37 | |
38 | /** |
39 | * @brief Provides information for creating an instance of KItemListWidget. |
40 | * |
41 | * KItemListView only creates KItemListWidget instances for the visible |
42 | * area. For calculating the required size of all items the expected |
43 | * size for the invisible items must be accessible. KItemListWidgetInformant |
44 | * provides this information. |
45 | */ |
46 | class LIBDOLPHINPRIVATE_EXPORT KItemListWidgetInformant |
47 | { |
48 | public: |
49 | KItemListWidgetInformant(); |
50 | virtual ~KItemListWidgetInformant(); |
51 | |
52 | virtual void calculateItemSizeHints(QVector<qreal>& logicalHeightHints, qreal& logicalWidthHint, const KItemListView* view) const = 0; |
53 | |
54 | virtual qreal preferredRoleColumnWidth(const QByteArray& role, |
55 | int index, |
56 | const KItemListView* view) const = 0; |
57 | }; |
58 | |
59 | /** |
60 | * @brief Widget that shows a visible item from the model. |
61 | * |
62 | * For showing an item from a custom model it is required to at least overwrite KItemListWidget::paint(). |
63 | * All properties are set by KItemListView, for each property there is a corresponding |
64 | * virtual protected method that allows to react on property changes. |
65 | */ |
66 | class LIBDOLPHINPRIVATE_EXPORT KItemListWidget : public QGraphicsWidget |
67 | { |
68 | Q_OBJECT |
69 | |
70 | public: |
71 | KItemListWidget(KItemListWidgetInformant* informant, QGraphicsItem* parent); |
72 | virtual ~KItemListWidget(); |
73 | |
74 | void setIndex(int index); |
75 | int index() const; |
76 | |
77 | void setData(const QHash<QByteArray, QVariant>& data, const QSet<QByteArray>& roles = QSet<QByteArray>()); |
78 | QHash<QByteArray, QVariant> data() const; |
79 | |
80 | /** |
81 | * Draws the hover-rectangle if the item is hovered. Overwrite this method |
82 | * to show the data of the custom model provided by KItemListWidget::data(). |
83 | * @reimp |
84 | */ |
85 | virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0); |
86 | |
87 | void setVisibleRoles(const QList<QByteArray>& roles); |
88 | QList<QByteArray> visibleRoles() const; |
89 | |
90 | /** |
91 | * Sets the width of a role that should be used if the alignment of the content |
92 | * should be done in columns. |
93 | */ |
94 | void setColumnWidth(const QByteArray& role, qreal width); |
95 | qreal columnWidth(const QByteArray& role) const; |
96 | |
97 | void setStyleOption(const KItemListStyleOption& option); |
98 | const KItemListStyleOption& styleOption() const; |
99 | |
100 | // TODO: Hides QGraphicsItem::setSelected()/isSelected(). Replace |
101 | // this by using the default mechanism. |
102 | void setSelected(bool selected); |
103 | bool isSelected() const; |
104 | |
105 | void setCurrent(bool current); |
106 | bool isCurrent() const; |
107 | |
108 | void setHovered(bool hovered); |
109 | bool isHovered() const; |
110 | |
111 | void setHoverPosition(const QPointF& pos); |
112 | |
113 | void setAlternateBackground(bool enable); |
114 | bool alternateBackground() const; |
115 | |
116 | void setEnabledSelectionToggle(bool enabled); |
117 | bool enabledSelectionToggle() const; |
118 | |
119 | /** |
120 | * Sets the sibling information for the item and all of its parents. |
121 | * The sibling information of the upper most parent is represented by |
122 | * the first bit, the sibling information of the item by the last bit. |
123 | * The sibling information is useful for drawing the branches in |
124 | * tree views. |
125 | */ |
126 | void setSiblingsInformation(const QBitArray& siblings); |
127 | QBitArray siblingsInformation() const; |
128 | |
129 | /** |
130 | * Allows the user to edit the role \a role. The signals |
131 | * roleEditingCanceled() or roleEditingFinished() will be |
132 | * emitted after editing. An ongoing editing gets canceled if |
133 | * the role is empty. Derived classes must implement |
134 | * editedRoleChanged(). |
135 | */ |
136 | void setEditedRole(const QByteArray& role); |
137 | QByteArray editedRole() const; |
138 | |
139 | /** |
140 | * @return True if \a point is inside KItemListWidget::hoverRect(), |
141 | * KItemListWidget::textRect(), KItemListWidget::selectionToggleRect() |
142 | * or KItemListWidget::expansionToggleRect(). |
143 | * @reimp |
144 | */ |
145 | virtual bool contains(const QPointF& point) const; |
146 | |
147 | /** |
148 | * @return Rectangle for the area that shows the icon. |
149 | */ |
150 | virtual QRectF iconRect() const = 0; |
151 | |
152 | /** |
153 | * @return Rectangle for the area that contains the text-properties. |
154 | */ |
155 | virtual QRectF textRect() const = 0; |
156 | |
157 | /** |
158 | * @return Focus rectangle for indicating the current item. Per default |
159 | * textRect() will be returned. Overwrite this method if textRect() |
160 | * provides a larger rectangle than the actual text (e.g. to |
161 | * be aligned with the iconRect()). The textFocusRect() may not be |
162 | * outside the boundaries of textRect(). |
163 | */ |
164 | virtual QRectF textFocusRect() const; |
165 | |
166 | /** |
167 | * @return Rectangle around which a selection box should be drawn if the item is selected. |
168 | */ |
169 | virtual QRectF selectionRect() const = 0; |
170 | |
171 | /** |
172 | * @return Rectangle for the selection-toggle that is used to select or deselect an item. |
173 | * Per default an empty rectangle is returned which means that no selection-toggle |
174 | * is available. |
175 | */ |
176 | virtual QRectF selectionToggleRect() const; |
177 | |
178 | /** |
179 | * @return Rectangle for the expansion-toggle that is used to open a sub-tree of the model. |
180 | * Per default an empty rectangle is returned which means that no opening of sub-trees |
181 | * is supported. |
182 | */ |
183 | virtual QRectF expansionToggleRect() const; |
184 | |
185 | /** |
186 | * @return Pixmap that is used when dragging an item. Per default the current state of the |
187 | * widget is returned as pixmap. |
188 | */ |
189 | virtual QPixmap createDragPixmap(const QStyleOptionGraphicsItem* option, QWidget* widget = 0); |
190 | |
191 | signals: |
192 | void roleEditingCanceled(int index, const QByteArray& role, const QVariant& value); |
193 | void roleEditingFinished(int index, const QByteArray& role, const QVariant& value); |
194 | |
195 | protected: |
196 | virtual void dataChanged(const QHash<QByteArray, QVariant>& current, const QSet<QByteArray>& roles = QSet<QByteArray>()); |
197 | virtual void visibleRolesChanged(const QList<QByteArray>& current, const QList<QByteArray>& previous); |
198 | virtual void columnWidthChanged(const QByteArray& role, qreal current, qreal previous); |
199 | virtual void styleOptionChanged(const KItemListStyleOption& current, const KItemListStyleOption& previous); |
200 | virtual void currentChanged(bool current); |
201 | virtual void selectedChanged(bool selected); |
202 | virtual void hoveredChanged(bool hovered); |
203 | virtual void alternateBackgroundChanged(bool enabled); |
204 | virtual void siblingsInformationChanged(const QBitArray& current, const QBitArray& previous); |
205 | virtual void editedRoleChanged(const QByteArray& current, const QByteArray& previous); |
206 | virtual void resizeEvent(QGraphicsSceneResizeEvent* event); |
207 | |
208 | /** |
209 | * @return The current opacity of the hover-animation. When implementing a custom painting-code for a hover-state |
210 | * this opacity value should be respected. |
211 | */ |
212 | qreal hoverOpacity() const; |
213 | |
214 | const KItemListWidgetInformant* informant() const; |
215 | |
216 | private slots: |
217 | void slotHoverAnimationFinished(); |
218 | |
219 | private: |
220 | void initializeSelectionToggle(); |
221 | void setHoverOpacity(qreal opacity); |
222 | void clearHoverCache(); |
223 | void drawItemStyleOption(QPainter* painter, QWidget* widget, QStyle::State styleState); |
224 | |
225 | private: |
226 | Q_PROPERTY(qreal hoverOpacity READ hoverOpacity WRITE setHoverOpacity) |
227 | |
228 | KItemListWidgetInformant* m_informant; |
229 | int m_index; |
230 | bool m_selected; |
231 | bool m_current; |
232 | bool m_hovered; |
233 | bool m_alternateBackground; |
234 | bool m_enabledSelectionToggle; |
235 | QHash<QByteArray, QVariant> m_data; |
236 | QList<QByteArray> m_visibleRoles; |
237 | QHash<QByteArray, qreal> m_columnWidths; |
238 | KItemListStyleOption m_styleOption; |
239 | QBitArray m_siblingsInfo; |
240 | |
241 | qreal m_hoverOpacity; |
242 | mutable QPixmap* m_hoverCache; |
243 | QPropertyAnimation* m_hoverAnimation; |
244 | |
245 | KItemListSelectionToggle* m_selectionToggle; |
246 | |
247 | QByteArray m_editedRole; |
248 | }; |
249 | |
250 | inline const KItemListWidgetInformant* KItemListWidget::informant() const |
251 | { |
252 | return m_informant; |
253 | } |
254 | |
255 | #endif |
256 | |
257 | |
258 | |