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>
34 #include <QStyleOption>
36 KItemListWidget::KItemListWidget(QGraphicsItem
* parent
) :
37 QGraphicsWidget(parent
, 0),
42 m_alternatingBackgroundColors(false),
43 m_enabledSelectionToggle(false),
46 m_visibleRolesSizes(),
55 KItemListWidget::~KItemListWidget()
60 void KItemListWidget::setIndex(int index
)
62 if (m_index
!= index
) {
63 delete m_selectionToggle
;
64 m_selectionToggle
= 0;
66 if (m_hoverAnimation
) {
67 m_hoverAnimation
->stop();
76 int KItemListWidget::index() const
81 void KItemListWidget::setData(const QHash
<QByteArray
, QVariant
>& data
,
82 const QSet
<QByteArray
>& roles
)
85 if (roles
.isEmpty()) {
89 foreach (const QByteArray
& role
, roles
) {
90 m_data
[role
] = data
[role
];
92 dataChanged(m_data
, roles
);
96 QHash
<QByteArray
, QVariant
> KItemListWidget::data() const
101 void KItemListWidget::paint(QPainter
* painter
, const QStyleOptionGraphicsItem
* option
, QWidget
* widget
)
105 painter
->setRenderHint(QPainter::Antialiasing
);
107 if (m_alternatingBackgroundColors
&& (m_index
& 0x1)) {
108 const QColor backgroundColor
= m_styleOption
.palette
.color(QPalette::AlternateBase
);
109 const QRectF
backgroundRect(0, 0, size().width(), size().height());
110 painter
->fillRect(backgroundRect
, backgroundColor
);
114 const QStyle::State
activeState(isActiveWindow() ? QStyle::State_Active
: 0);
115 drawItemStyleOption(painter
, widget
, activeState
|
116 QStyle::State_Enabled
|
117 QStyle::State_Selected
|
122 QStyleOptionViewItemV4 viewItemOption
;
123 viewItemOption
.initFrom(widget
);
125 const QRect iconBounds
= iconRect().toRect();
126 const QRect textBounds
= textRect().toRect();
127 if (iconBounds
.bottom() > textBounds
.top()) {
128 viewItemOption
.rect
= textBounds
;
130 // See KItemListWidget::drawItemStyleOption(): The selection rectangle
132 viewItemOption
.rect
= textBounds
.adjusted(1, 1, -1, -1);
135 viewItemOption
.state
= QStyle::State_Enabled
| QStyle::State_Item
;
137 viewItemOption
.state
|= QStyle::State_Selected
;
140 viewItemOption
.viewItemPosition
= QStyleOptionViewItemV4::OnlyOne
;
141 style()->drawPrimitive(QStyle::PE_FrameFocusRect
, &viewItemOption
, painter
, widget
);
144 if (m_hoverOpacity
> 0.0) {
146 // Initialize the m_hoverCache pixmap to improve the drawing performance
147 // when fading the hover background
148 m_hoverCache
= new QPixmap(size().toSize());
149 m_hoverCache
->fill(Qt::transparent
);
151 QPainter
pixmapPainter(m_hoverCache
);
152 const QStyle::State
activeState(isActiveWindow() ? QStyle::State_Active
: 0);
153 drawItemStyleOption(&pixmapPainter
, widget
, activeState
|
154 QStyle::State_Enabled
|
155 QStyle::State_MouseOver
|
159 const qreal opacity
= painter
->opacity();
160 painter
->setOpacity(m_hoverOpacity
* opacity
);
161 painter
->drawPixmap(0, 0, *m_hoverCache
);
162 painter
->setOpacity(opacity
);
166 void KItemListWidget::setVisibleRoles(const QList
<QByteArray
>& roles
)
168 const QList
<QByteArray
> previousRoles
= m_visibleRoles
;
169 m_visibleRoles
= roles
;
170 visibleRolesChanged(roles
, previousRoles
);
173 QList
<QByteArray
> KItemListWidget::visibleRoles() const
175 return m_visibleRoles
;
178 void KItemListWidget::setVisibleRolesSizes(const QHash
<QByteArray
, QSizeF
> rolesSizes
)
180 const QHash
<QByteArray
, QSizeF
> previousRolesSizes
= m_visibleRolesSizes
;
181 m_visibleRolesSizes
= rolesSizes
;
182 visibleRolesSizesChanged(rolesSizes
, previousRolesSizes
);
185 QHash
<QByteArray
, QSizeF
> KItemListWidget::visibleRolesSizes() const
187 return m_visibleRolesSizes
;
190 void KItemListWidget::setStyleOption(const KItemListStyleOption
& option
)
192 const KItemListStyleOption previous
= m_styleOption
;
194 m_styleOption
= option
;
196 styleOptionChanged(option
, previous
);
199 const KItemListStyleOption
& KItemListWidget::styleOption() const
201 return m_styleOption
;
204 void KItemListWidget::setSelected(bool selected
)
206 if (m_selected
!= selected
) {
207 m_selected
= selected
;
208 if (m_selectionToggle
) {
209 m_selectionToggle
->setChecked(selected
);
212 selectedChanged(selected
);
217 bool KItemListWidget::isSelected() const
222 void KItemListWidget::setCurrent(bool current
)
224 if (m_current
!= current
) {
227 currentChanged(current
);
232 bool KItemListWidget::isCurrent() const
237 void KItemListWidget::setHovered(bool hovered
)
239 if (hovered
== m_hovered
) {
245 if (!m_hoverAnimation
) {
246 m_hoverAnimation
= new QPropertyAnimation(this, "hoverOpacity", this);
247 m_hoverAnimation
->setDuration(200);
248 connect(m_hoverAnimation
, SIGNAL(finished()), this, SLOT(slotHoverAnimationFinished()));
250 m_hoverAnimation
->stop();
253 const qreal startValue
= qMax(hoverOpacity(), qreal(0.1));
254 m_hoverAnimation
->setStartValue(startValue
);
255 m_hoverAnimation
->setEndValue(1.0);
256 if (m_enabledSelectionToggle
&& !(QApplication::mouseButtons() & Qt::LeftButton
)) {
257 initializeSelectionToggle();
260 m_hoverAnimation
->setStartValue(hoverOpacity());
261 m_hoverAnimation
->setEndValue(0.0);
264 m_hoverAnimation
->start();
266 hoveredChanged(hovered
);
271 bool KItemListWidget::isHovered() const
276 void KItemListWidget::setAlternatingBackgroundColors(bool enable
)
278 if (m_alternatingBackgroundColors
!= enable
) {
279 m_alternatingBackgroundColors
= enable
;
280 alternatingBackgroundColorsChanged(enable
);
285 bool KItemListWidget::alternatingBackgroundColors() const
287 return m_alternatingBackgroundColors
;
290 void KItemListWidget::setEnabledSelectionToggle(bool enable
)
292 if (m_enabledSelectionToggle
!= enable
) {
293 m_enabledSelectionToggle
= enable
;
298 bool KItemListWidget::enabledSelectionToggle() const
300 return m_enabledSelectionToggle
;
303 bool KItemListWidget::contains(const QPointF
& point
) const
305 if (!QGraphicsWidget::contains(point
)) {
309 return iconRect().contains(point
) ||
310 textRect().contains(point
) ||
311 expansionToggleRect().contains(point
) ||
312 selectionToggleRect().contains(point
);
315 QRectF
KItemListWidget::selectionToggleRect() const
320 QRectF
KItemListWidget::expansionToggleRect() const
325 void KItemListWidget::dataChanged(const QHash
<QByteArray
, QVariant
>& current
,
326 const QSet
<QByteArray
>& roles
)
333 void KItemListWidget::visibleRolesChanged(const QList
<QByteArray
>& current
,
334 const QList
<QByteArray
>& previous
)
341 void KItemListWidget::visibleRolesSizesChanged(const QHash
<QByteArray
, QSizeF
>& current
,
342 const QHash
<QByteArray
, QSizeF
>& previous
)
349 void KItemListWidget::styleOptionChanged(const KItemListStyleOption
& current
,
350 const KItemListStyleOption
& previous
)
357 void KItemListWidget::currentChanged(bool current
)
362 void KItemListWidget::selectedChanged(bool selected
)
367 void KItemListWidget::hoveredChanged(bool hovered
)
372 void KItemListWidget::alternatingBackgroundColorsChanged(bool enabled
)
377 void KItemListWidget::resizeEvent(QGraphicsSceneResizeEvent
* event
)
379 QGraphicsWidget::resizeEvent(event
);
383 qreal
KItemListWidget::hoverOpacity() const
385 return m_hoverOpacity
;
388 void KItemListWidget::slotHoverAnimationFinished()
391 delete m_selectionToggle
;
392 m_selectionToggle
= 0;
396 void KItemListWidget::initializeSelectionToggle()
398 Q_ASSERT(m_enabledSelectionToggle
);
400 if (!m_selectionToggle
) {
401 m_selectionToggle
= new KItemListSelectionToggle(this);
404 const QRectF toggleRect
= selectionToggleRect();
405 m_selectionToggle
->setPos(toggleRect
.topLeft());
406 m_selectionToggle
->resize(toggleRect
.size());
408 m_selectionToggle
->setChecked(isSelected());
411 void KItemListWidget::setHoverOpacity(qreal opacity
)
413 m_hoverOpacity
= opacity
;
414 if (m_selectionToggle
) {
415 m_selectionToggle
->setOpacity(opacity
);
418 if (m_hoverOpacity
<= 0.0) {
426 void KItemListWidget::clearHoverCache()
432 void KItemListWidget::drawItemStyleOption(QPainter
* painter
, QWidget
* widget
, QStyle::State styleState
)
434 const QRect iconBounds
= iconRect().toRect();
435 const QRect textBounds
= textRect().toRect();
437 QStyleOptionViewItemV4 viewItemOption
;
438 viewItemOption
.initFrom(widget
);
439 viewItemOption
.state
= styleState
;
440 viewItemOption
.viewItemPosition
= QStyleOptionViewItemV4::OnlyOne
;
442 if (iconBounds
.bottom() > textBounds
.top()) {
443 viewItemOption
.rect
= iconBounds
| textBounds
;
444 widget
->style()->drawPrimitive(QStyle::PE_PanelItemViewItem
, &viewItemOption
, painter
, widget
);
446 viewItemOption
.rect
= iconBounds
;
447 widget
->style()->drawPrimitive(QStyle::PE_PanelItemViewItem
, &viewItemOption
, painter
, widget
);
449 viewItemOption
.rect
= textBounds
.adjusted(1, 1, -1, -1);
450 widget
->style()->drawPrimitive(QStyle::PE_PanelItemViewItem
, &viewItemOption
, painter
, widget
);
454 #include "kitemlistwidget.moc"