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 "kitemlistselectiontoggle_p.h"
26 #include "kitemlistview.h"
27 #include "kitemmodelbase.h"
31 #include <QApplication>
33 #include <QPropertyAnimation>
35 #include <QStyleOption>
37 KItemListWidget::KItemListWidget(QGraphicsItem
* parent
) :
38 QGraphicsWidget(parent
, 0),
43 m_alternatingBackgroundColors(false),
44 m_enabledSelectionToggle(false),
47 m_visibleRolesSizes(),
56 KItemListWidget::~KItemListWidget()
61 void KItemListWidget::setIndex(int index
)
63 if (m_index
!= index
) {
64 delete m_selectionToggle
;
65 m_selectionToggle
= 0;
67 if (m_hoverAnimation
) {
68 m_hoverAnimation
->stop();
77 int KItemListWidget::index() const
82 void KItemListWidget::setData(const QHash
<QByteArray
, QVariant
>& data
,
83 const QSet
<QByteArray
>& roles
)
86 if (roles
.isEmpty()) {
90 foreach (const QByteArray
& role
, roles
) {
91 m_data
[role
] = data
[role
];
93 dataChanged(m_data
, roles
);
97 QHash
<QByteArray
, QVariant
> KItemListWidget::data() const
102 void KItemListWidget::paint(QPainter
* painter
, const QStyleOptionGraphicsItem
* option
, QWidget
* widget
)
106 painter
->setRenderHint(QPainter::Antialiasing
);
108 if (m_alternatingBackgroundColors
&& (m_index
& 0x1)) {
109 const QColor backgroundColor
= m_styleOption
.palette
.color(QPalette::AlternateBase
);
110 const QRectF
backgroundRect(0, 0, size().width(), size().height());
111 painter
->fillRect(backgroundRect
, backgroundColor
);
114 const QRect iconBounds
= iconRect().toRect();
116 QStyleOptionViewItemV4 viewItemOption
;
117 viewItemOption
.initFrom(widget
);
118 viewItemOption
.rect
= iconBounds
;
119 viewItemOption
.state
= QStyle::State_Enabled
| QStyle::State_Selected
| QStyle::State_Item
;
120 viewItemOption
.viewItemPosition
= QStyleOptionViewItemV4::OnlyOne
;
121 widget
->style()->drawPrimitive(QStyle::PE_PanelItemViewItem
, &viewItemOption
, painter
, widget
);
123 drawTextBackground(painter
);
127 QStyleOptionViewItemV4 viewItemOption
;
128 viewItemOption
.initFrom(widget
);
129 viewItemOption
.rect
= textRect().toRect();
130 viewItemOption
.state
= QStyle::State_Enabled
| QStyle::State_Item
;
131 viewItemOption
.viewItemPosition
= QStyleOptionViewItemV4::OnlyOne
;
132 style()->drawPrimitive(QStyle::PE_FrameFocusRect
, &viewItemOption
, painter
, widget
);
135 if (m_hoverOpacity
<= 0.0) {
140 // Initialize the m_hoverCache pixmap to improve the drawing performance
141 // when fading the hover background
142 m_hoverCache
= new QPixmap(iconBounds
.size());
143 m_hoverCache
->fill(Qt::transparent
);
145 QPainter
pixmapPainter(m_hoverCache
);
147 QStyleOptionViewItemV4 viewItemOption
;
148 viewItemOption
.initFrom(widget
);
149 viewItemOption
.rect
= QRect(0, 0, iconBounds
.width(), iconBounds
.height());
150 viewItemOption
.state
= QStyle::State_Enabled
| QStyle::State_MouseOver
| QStyle::State_Item
;
151 viewItemOption
.viewItemPosition
= QStyleOptionViewItemV4::OnlyOne
;
153 widget
->style()->drawPrimitive(QStyle::PE_PanelItemViewItem
, &viewItemOption
, &pixmapPainter
, widget
);
156 const qreal opacity
= painter
->opacity();
157 painter
->setOpacity(m_hoverOpacity
* opacity
);
158 painter
->drawPixmap(iconBounds
.topLeft(), *m_hoverCache
);
159 drawTextBackground(painter
);
160 painter
->setOpacity(opacity
);
163 void KItemListWidget::setVisibleRoles(const QList
<QByteArray
>& roles
)
165 const QList
<QByteArray
> previousRoles
= m_visibleRoles
;
166 m_visibleRoles
= roles
;
167 visibleRolesChanged(roles
, previousRoles
);
170 QList
<QByteArray
> KItemListWidget::visibleRoles() const
172 return m_visibleRoles
;
175 void KItemListWidget::setVisibleRolesSizes(const QHash
<QByteArray
, QSizeF
> rolesSizes
)
177 const QHash
<QByteArray
, QSizeF
> previousRolesSizes
= m_visibleRolesSizes
;
178 m_visibleRolesSizes
= rolesSizes
;
179 visibleRolesSizesChanged(rolesSizes
, previousRolesSizes
);
182 QHash
<QByteArray
, QSizeF
> KItemListWidget::visibleRolesSizes() const
184 return m_visibleRolesSizes
;
187 void KItemListWidget::setStyleOption(const KItemListStyleOption
& option
)
189 const KItemListStyleOption previous
= m_styleOption
;
191 m_styleOption
= option
;
193 styleOptionChanged(option
, previous
);
196 const KItemListStyleOption
& KItemListWidget::styleOption() const
198 return m_styleOption
;
201 void KItemListWidget::setSelected(bool selected
)
203 if (m_selected
!= selected
) {
204 m_selected
= selected
;
205 if (m_selectionToggle
) {
206 m_selectionToggle
->setChecked(selected
);
209 selectedChanged(selected
);
214 bool KItemListWidget::isSelected() const
219 void KItemListWidget::setCurrent(bool current
)
221 if (m_current
!= current
) {
224 currentChanged(current
);
229 bool KItemListWidget::isCurrent() const
234 void KItemListWidget::setHovered(bool hovered
)
236 if (hovered
== m_hovered
) {
242 if (!m_hoverAnimation
) {
243 m_hoverAnimation
= new QPropertyAnimation(this, "hoverOpacity", this);
244 m_hoverAnimation
->setDuration(200);
245 connect(m_hoverAnimation
, SIGNAL(finished()), this, SLOT(slotHoverAnimationFinished()));
247 m_hoverAnimation
->stop();
250 m_hoverAnimation
->setEndValue(1.0);
251 if (m_enabledSelectionToggle
&& !(QApplication::mouseButtons() & Qt::LeftButton
)) {
252 initializeSelectionToggle();
255 m_hoverAnimation
->setEndValue(0.0);
258 m_hoverAnimation
->start();
260 hoveredChanged(hovered
);
265 bool KItemListWidget::isHovered() const
270 void KItemListWidget::setAlternatingBackgroundColors(bool enable
)
272 if (m_alternatingBackgroundColors
!= enable
) {
273 m_alternatingBackgroundColors
= enable
;
274 alternatingBackgroundColorsChanged(enable
);
279 bool KItemListWidget::alternatingBackgroundColors() const
281 return m_alternatingBackgroundColors
;
284 void KItemListWidget::setEnabledSelectionToggle(bool enable
)
286 if (m_enabledSelectionToggle
!= enable
) {
287 m_enabledSelectionToggle
= enable
;
292 bool KItemListWidget::enabledSelectionToggle() const
294 return m_enabledSelectionToggle
;
297 bool KItemListWidget::contains(const QPointF
& point
) const
299 if (!QGraphicsWidget::contains(point
)) {
303 return iconRect().contains(point
) ||
304 textRect().contains(point
) ||
305 expansionToggleRect().contains(point
) ||
306 selectionToggleRect().contains(point
);
309 QRectF
KItemListWidget::selectionToggleRect() const
314 QRectF
KItemListWidget::expansionToggleRect() const
319 void KItemListWidget::dataChanged(const QHash
<QByteArray
, QVariant
>& current
,
320 const QSet
<QByteArray
>& roles
)
327 void KItemListWidget::visibleRolesChanged(const QList
<QByteArray
>& current
,
328 const QList
<QByteArray
>& previous
)
335 void KItemListWidget::visibleRolesSizesChanged(const QHash
<QByteArray
, QSizeF
>& current
,
336 const QHash
<QByteArray
, QSizeF
>& previous
)
343 void KItemListWidget::styleOptionChanged(const KItemListStyleOption
& current
,
344 const KItemListStyleOption
& previous
)
351 void KItemListWidget::currentChanged(bool current
)
356 void KItemListWidget::selectedChanged(bool selected
)
361 void KItemListWidget::hoveredChanged(bool hovered
)
366 void KItemListWidget::alternatingBackgroundColorsChanged(bool enabled
)
371 void KItemListWidget::resizeEvent(QGraphicsSceneResizeEvent
* event
)
373 QGraphicsWidget::resizeEvent(event
);
377 qreal
KItemListWidget::hoverOpacity() const
379 return m_hoverOpacity
;
382 void KItemListWidget::slotHoverAnimationFinished()
385 delete m_selectionToggle
;
386 m_selectionToggle
= 0;
390 void KItemListWidget::initializeSelectionToggle()
392 Q_ASSERT(m_enabledSelectionToggle
);
394 if (!m_selectionToggle
) {
395 m_selectionToggle
= new KItemListSelectionToggle(this);
398 const QRectF toggleRect
= selectionToggleRect();
399 m_selectionToggle
->setPos(toggleRect
.topLeft());
400 m_selectionToggle
->resize(toggleRect
.size());
402 m_selectionToggle
->setChecked(isSelected());
405 void KItemListWidget::setHoverOpacity(qreal opacity
)
407 m_hoverOpacity
= opacity
;
408 if (m_selectionToggle
) {
409 m_selectionToggle
->setOpacity(opacity
);
414 void KItemListWidget::clearHoverCache()
420 void KItemListWidget::drawTextBackground(QPainter
* painter
)
422 const qreal opacity
= painter
->opacity();
424 QRectF textBounds
= textRect();
425 const qreal marginDiff
= m_styleOption
.margin
/ 2;
426 textBounds
.adjust(marginDiff
, marginDiff
, -marginDiff
, -marginDiff
);
427 painter
->setOpacity(opacity
* 0.1);
428 painter
->setPen(Qt::NoPen
);
429 painter
->setBrush(m_styleOption
.palette
.text());
430 painter
->drawRoundedRect(textBounds
, 4, 4);
432 painter
->setOpacity(opacity
);
435 #include "kitemlistwidget.moc"