~ubuntu-branches/ubuntu/utopic/kde-workspace/utopic-proposed

« back to all changes in this revision

Viewing changes to libs/plasmagenericshell/abstracticon.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michał Zając
  • Date: 2011-07-09 08:31:15 UTC
  • Revision ID: james.westby@ubuntu.com-20110709083115-ohyxn6z93mily9fc
Tags: upstream-4.6.90
Import upstream version 4.6.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *   Copyright (C) 2009 by Ana Cecília Martins <anaceciliamb@gmail.com>
 
3
 *   Copyright (C) 2010 by Chani Armitage <chani@kde.org>
 
4
 *   Copyright (C) 2010 by Ivan Cukic <ivan.cukic@kde.org>
 
5
 *
 
6
 *   This program is free software; you can redistribute it and/or modify
 
7
 *   it under the terms of the GNU Library/Lesser General Public License
 
8
 *   version 2, or (at your option) any later version, as published by the
 
9
 *   Free Software Foundation
 
10
 *
 
11
 *   This program is distributed in the hope that it will be useful,
 
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 *   GNU General Public License for more details
 
15
 *
 
16
 *   You should have received a copy of the GNU Library/Lesser General Public
 
17
 *   License along with this program; if not, write to the
 
18
 *   Free Software Foundation, Inc.,
 
19
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
20
 */
 
21
 
 
22
#include "abstracticon.h"
 
23
 
 
24
#include <QApplication>
 
25
#include <QCursor>
 
26
#include <QDebug>
 
27
#include <QFontMetrics>
 
28
#include <QGraphicsSceneMouseEvent>
 
29
#include <QPropertyAnimation>
 
30
#include <QStyleOptionGraphicsItem>
 
31
#include <QPainter>
 
32
 
 
33
#include <KIconLoader>
 
34
#include <KIcon>
 
35
#include <KGlobalSettings>
 
36
 
 
37
#include <Plasma/FrameSvg>
 
38
#include <Plasma/Theme>
 
39
#include <Plasma/PaintUtils>
 
40
#include <QWidget>
 
41
 
 
42
namespace Plasma
 
43
{
 
44
 
 
45
AbstractIcon::AbstractIcon(QGraphicsItem *parent)
 
46
    : QGraphicsWidget(parent),
 
47
      m_background(new Plasma::FrameSvg(this)),
 
48
      m_backgroundFadeAnim(0),
 
49
      m_backgroundPrefix("normal"),
 
50
      m_iconHeight(DEFAULT_ICON_SIZE),
 
51
      m_maxSize(maximumSize()),
 
52
      m_backgroundAlpha(1),
 
53
      m_selected(false),
 
54
      m_hovered(false)
 
55
{
 
56
    setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
 
57
    setCacheMode(DeviceCoordinateCache);
 
58
    setAcceptHoverEvents(true);
 
59
    m_background->setCacheAllRenderedFrames(true);
 
60
    m_background->setImagePath("widgets/tasks");
 
61
    connect(m_background, SIGNAL(repaintNeeded()), this, SLOT(syncTheme()));
 
62
    syncTheme();
 
63
}
 
64
 
 
65
AbstractIcon::~AbstractIcon()
 
66
{
 
67
}
 
68
 
 
69
void AbstractIcon::syncTheme()
 
70
{
 
71
    m_background->setElementPrefix("normal");
 
72
    m_background->resizeFrame(size());
 
73
    qreal ml, mt, mr, mb;
 
74
    m_background->getMargins(ml, mt, mr, mb);
 
75
 
 
76
    setContentsMargins(ml, mt, mr, mb);
 
77
    updateGeometry();
 
78
    update();
 
79
}
 
80
 
 
81
void AbstractIcon::resizeEvent(QGraphicsSceneResizeEvent *event)
 
82
{
 
83
    m_background->resizeFrame(event->newSize());
 
84
}
 
85
 
 
86
QSizeF AbstractIcon::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
 
87
{
 
88
    if (which == Qt::MinimumSize || which == Qt::PreferredSize) {
 
89
        qreal l, t, r, b;
 
90
        getContentsMargins(&l, &t, &r, &b);
 
91
        QFontMetrics fm(font());
 
92
        const int minHeight = m_iconHeight + 2 + fm.height();
 
93
        QSizeF s(qMax(m_iconHeight, fm.width(m_name)) + l + r, minHeight + t + b);
 
94
        return s;
 
95
    }
 
96
 
 
97
    return QGraphicsWidget::sizeHint(which, constraint);
 
98
}
 
99
 
 
100
void AbstractIcon::setIconSize(int height)
 
101
{
 
102
    m_iconHeight = height;
 
103
    updateGeometry();
 
104
    update();
 
105
}
 
106
 
 
107
int AbstractIcon::iconSize() const
 
108
{
 
109
    return m_iconHeight;
 
110
}
 
111
 
 
112
void AbstractIcon::setName(const QString &name)
 
113
{
 
114
    m_name = name;
 
115
    updateGeometry();
 
116
    update();
 
117
}
 
118
 
 
119
QString AbstractIcon::name() const
 
120
{
 
121
    return m_name;
 
122
}
 
123
 
 
124
void AbstractIcon::collapse()
 
125
{
 
126
    if (isVisible()) {
 
127
        setVisible(false);
 
128
        m_maxSize = maximumSize();
 
129
        //kDebug() << m_maxSize;
 
130
        setMaximumSize(0, 0);
 
131
    }
 
132
}
 
133
 
 
134
void AbstractIcon::expand()
 
135
{
 
136
    if (!isVisible()) {
 
137
        setVisible(true);
 
138
        setMaximumSize(m_maxSize);
 
139
    }
 
140
}
 
141
 
 
142
void AbstractIcon::hoverEnterEvent(QGraphicsSceneHoverEvent *)
 
143
{
 
144
    m_hovered = true;
 
145
 
 
146
    m_backgroundPrefix = "hover";
 
147
    m_oldBackgroundPrefix = m_selected ? "focus" : "normal";
 
148
    m_background->setElementPrefix(m_backgroundPrefix);
 
149
    m_background->resizeFrame(size());
 
150
 
 
151
    emit hoverEnter(this);
 
152
 
 
153
    fadeBackground(150);
 
154
}
 
155
 
 
156
void AbstractIcon::hoverLeaveEvent(QGraphicsSceneHoverEvent *)
 
157
{
 
158
    m_hovered = false;
 
159
    emit hoverLeave(this);
 
160
 
 
161
    m_backgroundPrefix = m_selected ? "focus" : "normal";
 
162
    m_oldBackgroundPrefix = "hover";
 
163
    m_background->setElementPrefix(m_backgroundPrefix);
 
164
    m_background->resizeFrame(size());
 
165
 
 
166
    fadeBackground(250);
 
167
}
 
168
 
 
169
void AbstractIcon::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
 
170
{
 
171
    if (event->button() != Qt::LeftButton &&
 
172
        (event->pos() - event->buttonDownPos(Qt::LeftButton)).toPoint().manhattanLength() > QApplication::startDragDistance()) {
 
173
        event->accept();
 
174
        setCursor(Qt::OpenHandCursor);
 
175
        QMimeData *data = mimeData();
 
176
        if (data && !data->formats().isEmpty()) {
 
177
            qDebug() << "Start Dragging";
 
178
            emit dragging(this);
 
179
            QDrag *drag = new QDrag(event->widget());
 
180
            QPixmap p = pixmap(QSize(KIconLoader::SizeLarge, KIconLoader::SizeLarge));
 
181
            drag->setPixmap(p);
 
182
 
 
183
            drag->setMimeData(mimeData());
 
184
            drag->exec();
 
185
        } else {
 
186
            delete data;
 
187
        }
 
188
    }
 
189
}
 
190
 
 
191
void AbstractIcon::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
 
192
{
 
193
    QGraphicsWidget::mouseReleaseEvent(event);
 
194
    if (isDraggable()) {
 
195
        setCursor(Qt::OpenHandCursor);
 
196
    }
 
197
 
 
198
    if (boundingRect().contains(event->pos())) {
 
199
        emit(clicked(this));
 
200
    }
 
201
}
 
202
 
 
203
void AbstractIcon::mousePressEvent(QGraphicsSceneMouseEvent *event)
 
204
{
 
205
    Q_UNUSED(event)
 
206
    if (isDraggable()) {
 
207
        setCursor(Qt::ClosedHandCursor);
 
208
    }
 
209
}
 
210
 
 
211
void AbstractIcon::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
 
212
{
 
213
    Q_UNUSED(event)
 
214
    emit doubleClicked(this);
 
215
}
 
216
 
 
217
void AbstractIcon::setSelected(bool selected)
 
218
{
 
219
    if (m_selected != selected) {
 
220
        m_selected = selected;
 
221
 
 
222
        if (m_selected) {
 
223
            m_backgroundPrefix = "focus";
 
224
            m_oldBackgroundPrefix = m_hovered ? "hover" : "normal";
 
225
        } else {
 
226
            m_backgroundPrefix = m_hovered ? "hover" : "normal";
 
227
            m_oldBackgroundPrefix = "focus";
 
228
        }
 
229
 
 
230
        fadeBackground(150);
 
231
    }
 
232
}
 
233
 
 
234
bool AbstractIcon::isSelected() const
 
235
{
 
236
    return m_selected;
 
237
}
 
238
 
 
239
bool AbstractIcon::isDraggable() const
 
240
{
 
241
    return cursor().shape() == Qt::OpenHandCursor ||
 
242
           cursor().shape() == Qt::ClosedHandCursor;
 
243
}
 
244
 
 
245
void AbstractIcon::setDraggable(bool draggable)
 
246
{
 
247
    if (draggable) {
 
248
        setCursor(Qt::OpenHandCursor);
 
249
    } else {
 
250
        unsetCursor();
 
251
    }
 
252
}
 
253
 
 
254
void AbstractIcon::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
 
255
{
 
256
    paintBackground(painter, option, widget);
 
257
    paintForeground(painter, option, widget);
 
258
}
 
259
 
 
260
void AbstractIcon::paintBackground(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
 
261
{
 
262
    if (!option->rect.isValid()) {
 
263
        return;
 
264
    }
 
265
 
 
266
    if (!m_backgroundFadeAnim || m_backgroundFadeAnim->state() != QAbstractAnimation::Running) {
 
267
        m_background->setElementPrefix(m_backgroundPrefix);
 
268
        m_background->paintFrame(painter);
 
269
        return;
 
270
    }
 
271
 
 
272
    m_background->setElementPrefix(m_oldBackgroundPrefix);
 
273
    QPixmap bg = m_background->framePixmap();
 
274
 
 
275
    m_background->setElementPrefix(m_backgroundPrefix);
 
276
    bg = Plasma::PaintUtils::transition(bg, m_background->framePixmap(), m_backgroundAlpha);
 
277
    painter->drawPixmap(option->exposedRect, bg, option->exposedRect);
 
278
}
 
279
 
 
280
void AbstractIcon::paintForeground(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
 
281
{
 
282
    const QRectF rect = contentsRect();
 
283
    const int width = rect.width();
 
284
    const int height = rect.height();
 
285
 
 
286
    QRectF textRect(rect.x(), rect.y(), width, height - m_iconHeight - 2);
 
287
    QRect iconRect(rect.x() + qMax(0, (width / 2) - (m_iconHeight / 2)), textRect.bottom() + 2, m_iconHeight, m_iconHeight);
 
288
 
 
289
    painter->setPen(Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor));
 
290
    painter->setFont(font());
 
291
 
 
292
    int flags = Qt::AlignTop;// | Qt::TextWordWrap;
 
293
    QFontMetrics fm(font());
 
294
    if (fm.width(m_name) < textRect.width()) {
 
295
        flags |= Qt::AlignCenter;
 
296
    }
 
297
 
 
298
    if (!m_name.isEmpty() && qGray(painter->pen().color().rgb()) < 192) {
 
299
        const QRectF haloRect = fm.boundingRect(textRect.toAlignedRect(), flags, m_name);
 
300
        PaintUtils::drawHalo(painter, haloRect);
 
301
    }
 
302
 
 
303
    painter->drawPixmap(iconRect, pixmap(QSize(m_iconHeight, m_iconHeight)));
 
304
    painter->drawText(textRect, flags, m_name);
 
305
}
 
306
 
 
307
qreal AbstractIcon::backgroundFadeAlpha() const
 
308
{
 
309
    return m_backgroundAlpha;
 
310
}
 
311
 
 
312
void AbstractIcon::setBackgroundFadeAlpha(qreal progress)
 
313
{
 
314
    m_backgroundAlpha = progress;
 
315
    update();
 
316
}
 
317
 
 
318
void AbstractIcon::fadeBackground(int duration)
 
319
{
 
320
    if (m_oldBackgroundPrefix.isEmpty()) {
 
321
        update();
 
322
    } else {
 
323
        if (!m_backgroundFadeAnim) {
 
324
            m_backgroundFadeAnim = new QPropertyAnimation(this);
 
325
            m_backgroundFadeAnim->setEasingCurve(QEasingCurve::InQuad);
 
326
            m_backgroundFadeAnim->setPropertyName("backgroundFadeAlpha");
 
327
            m_backgroundFadeAnim->setTargetObject(this);
 
328
            m_backgroundFadeAnim->setStartValue(0);
 
329
            m_backgroundFadeAnim->setEndValue(1);
 
330
        }
 
331
 
 
332
        m_backgroundFadeAnim->setDuration(duration);
 
333
        m_backgroundFadeAnim->start();
 
334
    }
 
335
}
 
336
 
 
337
} // namespace Plasma
 
338
 
 
339