1 /***************************************************************************
2 * Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com> *
4 * Based on the Itemviews NG project from Trolltech Labs: *
5 * http://qt.gitorious.org/qt-labs/itemviews-ng *
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. *
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. *
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 ***************************************************************************/
23 #include "kitemlistwidget.h"
25 #include "kitemlistview.h"
26 #include "kitemmodelbase.h"
31 #include <QPropertyAnimation>
33 #include <QStyleOption>
35 KItemListWidget::KItemListWidget(QGraphicsItem
* parent
) :
36 QGraphicsWidget(parent
, 0),
41 m_alternatingBackgroundColors(false),
44 m_visibleRolesSizes(),
52 KItemListWidget::~KItemListWidget()
57 void KItemListWidget::setIndex(int index
)
59 if (m_index
!= index
) {
60 if (m_hoverAnimation
) {
61 m_hoverAnimation
->stop();
70 int KItemListWidget::index() const
75 void KItemListWidget::setData(const QHash
<QByteArray
, QVariant
>& data
,
76 const QSet
<QByteArray
>& roles
)
79 if (roles
.isEmpty()) {
83 foreach (const QByteArray
& role
, roles
) {
84 m_data
[role
] = data
[role
];
86 dataChanged(m_data
, roles
);
90 QHash
<QByteArray
, QVariant
> KItemListWidget::data() const
95 void KItemListWidget::paint(QPainter
* painter
, const QStyleOptionGraphicsItem
* option
, QWidget
* widget
)
99 painter
->setRenderHint(QPainter::Antialiasing
);
101 if (m_alternatingBackgroundColors
&& (m_index
& 0x1)) {
102 const QColor backgroundColor
= m_styleOption
.palette
.color(QPalette::AlternateBase
);
103 const QRectF
backgroundRect(0, 0, size().width(), size().height());
104 painter
->fillRect(backgroundRect
, backgroundColor
);
107 const QRect iconBounds
= iconBoundingRect().toRect();
109 QStyleOptionViewItemV4 viewItemOption
;
110 viewItemOption
.initFrom(widget
);
111 viewItemOption
.rect
= iconBounds
;
112 viewItemOption
.state
= QStyle::State_Enabled
| QStyle::State_Selected
| QStyle::State_Item
;
113 viewItemOption
.viewItemPosition
= QStyleOptionViewItemV4::OnlyOne
;
114 widget
->style()->drawPrimitive(QStyle::PE_PanelItemViewItem
, &viewItemOption
, painter
, widget
);
116 drawTextBackground(painter
);
120 drawFocusIndicator(painter
);
123 if (m_hoverOpacity
<= 0.0) {
128 // Initialize the m_hoverCache pixmap to improve the drawing performance
129 // when fading the hover background
130 m_hoverCache
= new QPixmap(iconBounds
.size());
131 m_hoverCache
->fill(Qt::transparent
);
133 QPainter
pixmapPainter(m_hoverCache
);
135 QStyleOptionViewItemV4 viewItemOption
;
136 viewItemOption
.initFrom(widget
);
137 viewItemOption
.rect
= QRect(0, 0, iconBounds
.width(), iconBounds
.height());
138 viewItemOption
.state
= QStyle::State_Enabled
| QStyle::State_MouseOver
| QStyle::State_Item
;
139 viewItemOption
.viewItemPosition
= QStyleOptionViewItemV4::OnlyOne
;
141 widget
->style()->drawPrimitive(QStyle::PE_PanelItemViewItem
, &viewItemOption
, &pixmapPainter
, widget
);
144 const qreal opacity
= painter
->opacity();
145 painter
->setOpacity(m_hoverOpacity
* opacity
);
146 painter
->drawPixmap(iconBounds
.topLeft(), *m_hoverCache
);
147 drawTextBackground(painter
);
148 painter
->setOpacity(opacity
);
151 void KItemListWidget::setVisibleRoles(const QList
<QByteArray
>& roles
)
153 const QList
<QByteArray
> previousRoles
= m_visibleRoles
;
154 m_visibleRoles
= roles
;
155 visibleRolesChanged(roles
, previousRoles
);
158 QList
<QByteArray
> KItemListWidget::visibleRoles() const
160 return m_visibleRoles
;
163 void KItemListWidget::setVisibleRolesSizes(const QHash
<QByteArray
, QSizeF
> rolesSizes
)
165 const QHash
<QByteArray
, QSizeF
> previousRolesSizes
= m_visibleRolesSizes
;
166 m_visibleRolesSizes
= rolesSizes
;
167 visibleRolesSizesChanged(rolesSizes
, previousRolesSizes
);
170 QHash
<QByteArray
, QSizeF
> KItemListWidget::visibleRolesSizes() const
172 return m_visibleRolesSizes
;
175 void KItemListWidget::setStyleOption(const KItemListStyleOption
& option
)
177 const KItemListStyleOption previous
= m_styleOption
;
179 m_styleOption
= option
;
181 styleOptionChanged(option
, previous
);
184 const KItemListStyleOption
& KItemListWidget::styleOption() const
186 return m_styleOption
;
189 void KItemListWidget::setSelected(bool selected
)
191 if (m_selected
!= selected
) {
192 m_selected
= selected
;
193 selectedChanged(selected
);
198 bool KItemListWidget::isSelected() const
203 void KItemListWidget::setCurrent(bool current
)
205 if (m_current
!= current
) {
207 currentChanged(current
);
212 bool KItemListWidget::isCurrent() const
217 void KItemListWidget::setHovered(bool hovered
)
219 if (hovered
== m_hovered
) {
225 if (!m_hoverAnimation
) {
226 m_hoverAnimation
= new QPropertyAnimation(this, "hoverOpacity", this);
227 m_hoverAnimation
->setDuration(200);
229 m_hoverAnimation
->stop();
232 m_hoverAnimation
->setEndValue(1.0);
234 m_hoverAnimation
->setEndValue(0.0);
237 m_hoverAnimation
->start();
239 hoveredChanged(hovered
);
244 bool KItemListWidget::isHovered() const
249 void KItemListWidget::setAlternatingBackgroundColors(bool enable
)
251 if (m_alternatingBackgroundColors
!= enable
) {
252 m_alternatingBackgroundColors
= enable
;
253 alternatingBackgroundColorsChanged(enable
);
258 bool KItemListWidget::alternatingBackgroundColors() const
260 return m_alternatingBackgroundColors
;
263 bool KItemListWidget::contains(const QPointF
& point
) const
265 if (!QGraphicsWidget::contains(point
)) {
269 return iconBoundingRect().contains(point
) ||
270 textBoundingRect().contains(point
) ||
271 expansionToggleRect().contains(point
) ||
272 selectionToggleRect().contains(point
);
275 QRectF
KItemListWidget::selectionToggleRect() const
280 QRectF
KItemListWidget::expansionToggleRect() const
285 void KItemListWidget::dataChanged(const QHash
<QByteArray
, QVariant
>& current
,
286 const QSet
<QByteArray
>& roles
)
293 void KItemListWidget::visibleRolesChanged(const QList
<QByteArray
>& current
,
294 const QList
<QByteArray
>& previous
)
301 void KItemListWidget::visibleRolesSizesChanged(const QHash
<QByteArray
, QSizeF
>& current
,
302 const QHash
<QByteArray
, QSizeF
>& previous
)
309 void KItemListWidget::styleOptionChanged(const KItemListStyleOption
& current
,
310 const KItemListStyleOption
& previous
)
317 void KItemListWidget::currentChanged(bool current
)
322 void KItemListWidget::selectedChanged(bool selected
)
327 void KItemListWidget::hoveredChanged(bool hovered
)
332 void KItemListWidget::alternatingBackgroundColorsChanged(bool enabled
)
337 void KItemListWidget::resizeEvent(QGraphicsSceneResizeEvent
* event
)
339 QGraphicsWidget::resizeEvent(event
);
343 qreal
KItemListWidget::hoverOpacity() const
345 return m_hoverOpacity
;
348 void KItemListWidget::setHoverOpacity(qreal opacity
)
350 m_hoverOpacity
= opacity
;
354 void KItemListWidget::clearHoverCache()
360 void KItemListWidget::drawFocusIndicator(QPainter
* painter
)
362 // Ideally style()->drawPrimitive(QStyle::PE_FrameFocusRect...)
363 // should be used, but Oxygen only draws indicators within classes
364 // derived from QAbstractItemView or Q3ListView. As a workaround
365 // the indicator is drawn manually. Code copied from oxygenstyle.cpp
366 // Copyright ( C ) 2009-2010 Hugo Pereira Da Costa <hugo@oxygen-icons.org>
367 // TODO: Clarify with Oxygen maintainers how to proceed with this.
369 const KItemListStyleOption
& option
= styleOption();
370 const QPalette palette
= option
.palette
;
371 const QRect rect
= textBoundingRect().toRect().adjusted(0, 0, 0, -1);
373 QLinearGradient
gradient(rect
.bottomLeft(), rect
.bottomRight());
374 gradient
.setColorAt(0.0, Qt::transparent
);
375 gradient
.setColorAt(1.0, Qt::transparent
);
376 gradient
.setColorAt(0.2, palette
.color(QPalette::Text
));
377 gradient
.setColorAt(0.8, palette
.color(QPalette::Text
));
379 painter
->setRenderHint(QPainter::Antialiasing
, false);
380 painter
->setPen(QPen(gradient
, 1));
381 painter
->drawLine(rect
.bottomLeft(), rect
.bottomRight());
382 painter
->setRenderHint(QPainter::Antialiasing
, true);
385 void KItemListWidget::drawTextBackground(QPainter
* painter
)
387 const qreal opacity
= painter
->opacity();
389 QRectF textBounds
= textBoundingRect();
390 const qreal marginDiff
= m_styleOption
.margin
/ 2;
391 textBounds
.adjust(marginDiff
, marginDiff
, -marginDiff
, -marginDiff
);
392 painter
->setOpacity(opacity
* 0.1);
393 painter
->setPen(Qt::NoPen
);
394 painter
->setBrush(m_styleOption
.palette
.text());
395 painter
->drawRoundedRect(textBounds
, 4, 4);
397 painter
->setOpacity(opacity
);
400 #include "kitemlistwidget.moc"