* use Backend term in place of Package as it suits better
[plasma-media-center:mainline.git] / applets / mediabrowser / gridview.cpp
1 /***************************************************************************
2  *   Copyright 2009 by Alessandro Diaferia <alediaferia@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 #include "gridview.h"
20 #include "viewitem.h"
21
22 #include <QScrollBar>
23 #include <QTimer>
24 #include <QKeyEvent>
25
26 #include <KDebug>
27
28 #include <Plasma/Animator>
29 #include <Plasma/ScrollBar>
30
31 GridView::GridView(QGraphicsItem *parent) : AbstractMediaItemView(parent),
32 m_itemRows(0),
33 m_timer(new QTimer(this)),
34 m_lastHoveredItem(0),
35 m_highlighting(false)
36 {
37     setupOptions();
38     m_timer->setInterval(2000);
39
40 //    connect (m_timer, SIGNAL(timeout()), this, SLOT(highlightHoveredItem()));
41 //    connect (Plasma::Animator::self(), SIGNAL(animationFinished(QGraphicsItem*,Plasma::Animator::Animation)),
42 //             this, SLOT(slotAnimationFinished(QGraphicsItem*,Plasma::Animator::Animation)));
43 }
44
45 GridView::~GridView()
46 {}
47
48 void GridView::setupOptions()
49 {
50     AbstractMediaItemView::setupOptions();
51     m_option.decorationPosition = QStyleOptionViewItem::Top;
52     m_option.decorationAlignment = Qt::AlignCenter;
53     m_option.displayAlignment = Qt::AlignHCenter | Qt::AlignBottom;
54 }
55
56 void GridView::layoutItems()
57 {
58     int x = contentsArea().x();
59     int y = contentsArea().y();
60     const int width = contentsArea().width();
61     m_itemRows = 0;
62
63     for (int i = 0; i < m_items.count(); i++) {
64         if (i == 0) {
65             y -= m_scrollMode == AbstractMediaItemView::PerItem ? (verticalScrollBar()->value() * m_items[i]->size().height())
66                                   : verticalScrollBar()->value();
67         }
68         m_items[i]->setPos(x, y);
69         m_items[i]->resize(m_items[i]->itemSizeHint());
70
71         if ((x + m_items[i]->size().width() * 2) > contentsArea().width()) {
72            y += m_items[i]->size().height();
73            x = 0;
74            ++m_itemRows;
75          } else {
76            x += m_items[i]->size().width();
77          }
78     }
79
80     if (m_hoveredItem) {
81         m_hoverIndicator->resize(m_hoveredItem->size());
82     }
83 }
84
85 void GridView::generateItems(const QModelIndex &parent, int start, int end)
86 {
87     if (parent != m_rootIndex) {
88         return;
89     }
90
91     for (int i = start; i <= end; i++) {
92         ViewItem *item = new ViewItem(m_option, this);
93         item->setModelIndex(m_model->index(i, 0, m_rootIndex));
94         item->setDrawBlurredText(m_blurred);
95         m_items.insert(i, item);
96     }
97     layoutItems();
98     updateScrollBar();
99 }
100
101 void GridView::updateScrollBar()
102 {
103     if (m_items.isEmpty()) {
104         return;
105     }
106     if (m_scrollMode == PerItem) {
107         verticalScrollBar()->setRange(0, m_itemRows);
108         verticalScrollBar()->setSingleStep(1);
109     } else {
110         verticalScrollBar()->setRange(0, m_itemRows * m_items[0]->size().height() - rect().height());
111         verticalScrollBar()->setSingleStep(1);
112         verticalScrollBar()->setPageStep(iconSize() * 2);
113     }
114 }
115
116 void GridView::resizeEvent(QGraphicsSceneResizeEvent *event)
117 {
118     AbstractMediaItemView::resizeEvent(event);
119
120     if (m_model) {
121         updateScrollBar();
122     }
123 }
124
125 void GridView::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
126 {
127     AbstractMediaItemView::hoverEnterEvent(event);
128 //
129 //    if (m_hoveredItem) {
130 //        m_lastHoveredItem = m_hoveredItem;
131 //        m_timer->start();
132 //    }
133 }
134
135 void GridView::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
136 {
137     AbstractMediaItemView::hoverMoveEvent(event);
138
139 //    if (m_hoveredItem && m_hoveredItem != m_lastHoveredItem) {
140 //        m_lastHoveredItem = m_hoveredItem;
141 //        m_timer->stop();
142 //        if (m_highlighting) {
143 //            layoutItems();
144 //            restoreItems();
145 //            m_highlighting = false;
146 //        }
147 //        m_timer->start();
148 //    }
149 }
150
151 void GridView::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
152 {
153     AbstractMediaItemView::hoverLeaveEvent(event);
154
155 //    if (m_timer->isActive()) {
156 //        m_timer->stop();
157 //        m_highlighting = false;
158 //    }
159 //    m_lastHoveredItem = 0;
160 }
161
162 void GridView::highlightHoveredItem()
163 {
164     fadeOutItems(m_hoveredItem);
165     Plasma::Animator::self()->customAnimation(100, 250, Plasma::Animator::EaseInCurve, this, "highlightAnimation");
166     m_hoveredItem->setZValue(1000);
167     m_timer->stop();
168 }
169
170 void GridView::highlightAnimation(qreal value)
171 {
172     m_highlighting = true;
173     m_hoveredItem->resize( (m_hoveredItem->itemSizeHint().width() * 2) * value, (m_hoveredItem->itemSizeHint().height() * 2) * value);
174     m_hoverIndicator->resize(m_hoveredItem->size());
175 }
176
177 void GridView::fadeOutItems(ViewItem *exception)
178 {
179     for (int i = 0; i < m_items.count(); i++) {
180         if (m_items[i] != exception) {
181             m_items[i]->setOpacity(0.3);
182         }
183     }
184 }
185
186 void GridView::restoreItems()
187 {
188     for (int i = 0; i < m_items.count(); i++) {
189         m_items[i]->setOpacity(1);
190     }
191 }
192
193 void GridView::keyPressEvent(QKeyEvent *event)
194 {
195     if (m_items.isEmpty()) {
196         return;
197     }
198
199     if (event->key() == Qt::Key_Left || event->key() == Qt::Key_Right) {
200         if (!m_hoveredItem) {
201             updateHoveredItem(m_items.first());
202         } else {
203             int index = m_items.indexOf(m_hoveredItem);
204             if (index == -1) {
205                 // We should not be here
206                 return;
207             }
208             if (event->key() == Qt::Key_Left) {
209                 --index;
210             } else { // Qt::Key_Right
211                 ++index;
212             }
213
214             if (index < 0 || index >= m_items.count()) {
215                 return;
216             }
217             updateHoveredItem(m_items.at(index));
218         }
219     } else if (event->key() == Qt::Key_Up || event->key() == Qt::Key_Down) {
220         if (!m_hoveredItem) {
221             updateHoveredItem(m_items.first());
222         } else {
223             QPointF currentPoint = m_hoveredItem->pos() + QPointF(1, 1);
224             event->key() == Qt::Key_Up ? currentPoint.setY(currentPoint.y() - m_hoveredItem->size().height()) :
225                                         currentPoint.setY(currentPoint.y() + m_hoveredItem->size().height());
226             ViewItem *newItem = itemFromPos(currentPoint);
227             if (newItem) {
228                 updateHoveredItem(newItem);
229             } else {
230                 updateHoveredItem(m_items.last());
231             }
232         }
233     }
234 }