2
Library for Aurorae window decoration themes.
3
Copyright (C) 2009, 2010 Martin Gräßlin <kde@martin-graesslin.com>
5
This program is free software; you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation; either version 2 of the License, or
8
(at your option) any later version.
10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
GNU General Public License for more details.
15
You should have received a copy of the GNU General Public License along
16
with this program; if not, write to the Free Software Foundation, Inc.,
17
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21
#include "auroraebutton.h"
22
#include "auroraescene.h"
23
#include "auroraetheme.h"
24
#include "themeconfig.h"
26
#include <QtCore/QEasingCurve>
27
#include <QtCore/QPropertyAnimation>
28
#include <QtCore/QTimer>
29
#include <QtGui/QGraphicsSceneEvent>
30
#include <QtGui/QPainter>
33
#include <KDE/KIconLoader>
34
#include <KDE/KIconEffect>
35
#include <KDE/Plasma/FrameSvg>
36
#include <KDE/Plasma/PaintUtils>
40
AuroraeButtonGroup::AuroraeButtonGroup(AuroraeTheme *theme, AuroraeButtonGroup::ButtonGroup group)
47
void AuroraeButtonGroup::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
51
Plasma::FrameSvg *decoration = m_theme->decoration();
54
AuroraeScene *s = static_cast<AuroraeScene*>(scene());
57
basePrefix = "buttongroup-left";
60
basePrefix = "buttongroup-right";
63
if (!decoration->hasElementPrefix(basePrefix)) {
66
if (!s->isActive() && decoration->hasElementPrefix(basePrefix + "-inactive")) {
67
prefix = basePrefix + "-inactive";
71
decoration->setElementPrefix(prefix);
72
decoration->setEnabledBorders(Plasma::FrameSvg::AllBorders);
73
decoration->resizeFrame(size());
74
if (s->isAnimating() && decoration->hasElementPrefix(basePrefix + "-inactive")) {
75
QPixmap target = decoration->framePixmap();
76
decoration->setElementPrefix(basePrefix + "-inactive");
78
decoration->setElementPrefix(basePrefix);
80
decoration->resizeFrame(size());
81
QPixmap result = Plasma::PaintUtils::transition(decoration->framePixmap(),
82
target, s->animationProgress());
83
painter->drawPixmap(0, 0, result);
85
decoration->paintFrame(painter);
89
AuroraeButton::AuroraeButton(AuroraeTheme* theme, AuroraeButtonType type)
95
, m_animationProgress(0.0)
96
, m_animation(new QPropertyAnimation(this, "animation", this))
100
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
101
setAcceptHoverEvents(true);
102
setAcceptedMouseButtons(Qt::LeftButton);
103
connect(m_theme, SIGNAL(buttonSizesChanged()), SLOT(buttonSizesChanged()));
106
AuroraeButton::~AuroraeButton()
110
void AuroraeButton::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
114
if (m_theme->hasButton(m_type)) {
116
if (static_cast<AuroraeScene*>(scene())->isActive()) {
125
if (isCheckable() && isChecked()) {
128
paintButton(painter, m_theme->button(currentType()), state);
132
AuroraeButtonType AuroraeButton::currentType() const
137
QSizeF AuroraeButton::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
141
const qreal factor = m_theme->buttonSizeFactor();
142
qreal width = m_theme->themeConfig().buttonWidth()*factor;
143
qreal height = m_theme->themeConfig().buttonHeight()*factor;
146
width = m_theme->themeConfig().buttonWidthMinimize()*factor;
150
width = m_theme->themeConfig().buttonWidthMaximizeRestore()*factor;
153
width = m_theme->themeConfig().buttonWidthClose()*factor;
155
case AllDesktopsButton:
156
width = m_theme->themeConfig().buttonWidthAllDesktops()*factor;
158
case KeepAboveButton:
159
width = m_theme->themeConfig().buttonWidthKeepAbove()*factor;
161
case KeepBelowButton:
162
width = m_theme->themeConfig().buttonWidthKeepBelow()*factor;
165
width = m_theme->themeConfig().buttonWidthShade()*factor;
168
width = m_theme->themeConfig().buttonWidthHelp()*factor;
173
if (m_theme->themeConfig().decorationPosition() == DecorationLeft ||
174
m_theme->themeConfig().decorationPosition() == DecorationRight) {
175
qSwap(width, height);
177
return QSizeF(width, height);
179
void AuroraeButton::mousePressEvent(QGraphicsSceneMouseEvent* event)
186
void AuroraeButton::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
194
QGraphicsItem::mouseReleaseEvent(event);
197
void AuroraeButton::hoverEnterEvent(QGraphicsSceneHoverEvent* event)
204
m_animationProgress = 0.0;
205
int time = m_theme->themeConfig().animationTime();
207
m_animation->setDuration(time);
208
m_animation->setEasingCurve(QEasingCurve::InQuad);
209
m_animation->setStartValue(0.0);
210
m_animation->setEndValue(1.0);
211
m_animation->start();
216
void AuroraeButton::hoverLeaveEvent(QGraphicsSceneHoverEvent* event)
223
m_animationProgress = 0.0;
224
int time = m_theme->themeConfig().animationTime();
226
m_animation->setDuration(time);
227
m_animation->setEasingCurve(QEasingCurve::OutQuad);
228
m_animation->setStartValue(0.0);
229
m_animation->setEndValue(1.0);
230
m_animation->start();
235
void AuroraeButton::paintButton(QPainter *painter, Plasma::FrameSvg *frame, ButtonStates states)
237
QString prefix = "active";
238
QString animationPrefix = "active";
239
bool hasInactive = false;
240
// check for inactive prefix
241
if (!states.testFlag(Active) && frame->hasElementPrefix("inactive")) {
242
// we have inactive, so we use it
245
animationPrefix = "inactive";
248
if (states.testFlag(Hover)) {
249
if (states.testFlag(Active)) {
250
if (frame->hasElementPrefix("hover")) {
255
if (frame->hasElementPrefix("hover-inactive")) {
256
prefix = "hover-inactive";
259
if (frame->hasElementPrefix("hover")) {
265
if (states.testFlag(Pressed)) {
266
if (states.testFlag(Active)) {
267
if (frame->hasElementPrefix("pressed")) {
272
if (frame->hasElementPrefix("pressed-inactive")) {
273
prefix = "pressed-inactive";
276
if (frame->hasElementPrefix("pressed")) {
282
if (states.testFlag(Deactivated)) {
283
if (states.testFlag(Active)) {
284
if (frame->hasElementPrefix("deactivated")) {
285
prefix = "deactivated";
289
if (frame->hasElementPrefix("deactivated-inactive")) {
290
prefix = "deactivated-inactive";
293
if (frame->hasElementPrefix("deactivated")) {
294
prefix = "deactivated";
299
frame->setElementPrefix(prefix);
300
frame->resizeFrame(size());
302
// there is an animation so we have to use it
303
// the animation is definately a hover animation as currently nothing else is supported
304
if (!states.testFlag(Hover)) {
305
// only have to set for not hover state as animationPrefix is set to (in)active by default
306
if (states.testFlag(Active)) {
307
if (frame->hasElementPrefix("hover")) {
308
animationPrefix = "hover";
312
if (frame->hasElementPrefix("hover-inactive")) {
313
animationPrefix = "hover-inactive";
316
if (frame->hasElementPrefix("hover")) {
317
animationPrefix = "hover";
322
QPixmap target = frame->framePixmap();
323
frame->setElementPrefix(animationPrefix);
324
frame->resizeFrame(size());
325
QPixmap result = Plasma::PaintUtils::transition(frame->framePixmap(),
326
target, m_animationProgress);
327
painter->drawPixmap(QRect(QPoint(0, 0), size().toSize()), result);
329
bool animation = false;
330
AuroraeScene *s = static_cast<AuroraeScene*>(scene());
331
if (s->isAnimating()) {
332
animationPrefix = prefix;
333
if (prefix.endsWith(QLatin1String("-inactive"))) {
334
animationPrefix.remove("-inactive");
336
animationPrefix = animationPrefix + "-inactive";
338
if (frame->hasElementPrefix(animationPrefix)) {
340
QPixmap target = frame->framePixmap();
341
frame->setElementPrefix(animationPrefix);
342
frame->resizeFrame(size());
343
QPixmap result = Plasma::PaintUtils::transition(frame->framePixmap(),
344
target, s->animationProgress());
345
painter->drawPixmap(0, 0, result);
349
frame->paintFrame(painter);
354
bool AuroraeButton::isAnimating() const
356
return (m_animation->state() == QAbstractAnimation::Running);
359
qreal AuroraeButton::animationProgress() const
361
return m_animationProgress;
364
void AuroraeButton::setAnimationProgress(qreal progress)
366
m_animationProgress = progress;
370
void AuroraeButton::buttonSizesChanged()
373
static_cast<AuroraeScene*>(scene())->updateLayout();
376
/***********************************************
377
* AuroraeMaximizeButton
378
***********************************************/
379
AuroraeMaximizeButton::AuroraeMaximizeButton(AuroraeTheme* theme)
380
: AuroraeButton(theme, MaximizeButton)
381
, m_maximizeMode(KDecorationDefines::MaximizeRestore)
383
setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton|Qt::MidButton);
386
void AuroraeMaximizeButton::mousePressEvent(QGraphicsSceneMouseEvent* event)
388
AuroraeButton::mousePressEvent(event);
389
m_pressedButton = event->button();
392
void AuroraeMaximizeButton::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
394
if (isPressed() && m_pressedButton == event->button()) {
395
emit clicked(m_pressedButton);
399
QGraphicsItem::mouseReleaseEvent(event);
402
AuroraeButtonType AuroraeMaximizeButton::currentType() const
404
if (m_maximizeMode == KDecorationDefines::MaximizeFull &&
405
theme()->hasButton(RestoreButton)) {
406
return RestoreButton;
408
return MaximizeButton;
412
void AuroraeMaximizeButton::setMaximizeMode(KDecorationDefines::MaximizeMode mode)
414
m_maximizeMode = mode;
418
/************************************************
420
************************************************/
421
AuroraeMenuButton::AuroraeMenuButton(AuroraeTheme* theme)
422
: AuroraeButton(theme, MenuButton)
424
m_timer = new QTimer(this);
425
m_timer->setSingleShot(true);
426
m_timer->setInterval(QApplication::doubleClickInterval());
427
connect(m_timer, SIGNAL(timeout()), SIGNAL(clicked()));
430
void AuroraeMenuButton::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
434
if (m_icon.isNull()) {
437
QPixmap iconPix = m_icon;
438
KIconEffect *effect = KIconLoader::global()->iconEffect();
439
AuroraeScene *s = static_cast<AuroraeScene*>(scene());
442
iconPix = effect->apply(iconPix, KIconLoader::Desktop, KIconLoader::ActiveState);
445
iconPix = effect->apply(iconPix, KIconLoader::Desktop, KIconLoader::DisabledState);
447
if (s->isAnimating()) {
449
QPixmap oldPix = m_icon;
450
if (!s->isActive()) {
452
oldPix = effect->apply(iconPix, KIconLoader::Desktop, KIconLoader::ActiveState);
455
oldPix = effect->apply(iconPix, KIconLoader::Desktop, KIconLoader::DisabledState);
457
iconPix = Plasma::PaintUtils::transition(oldPix, iconPix, s->animationProgress());
459
painter->drawPixmap(0, 0, iconPix);
462
void AuroraeMenuButton::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event)
465
emit doubleClicked();
468
void AuroraeMenuButton::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
472
if (m_timer->isActive()) {
480
QGraphicsItem::mouseReleaseEvent(event);
483
void AuroraeMenuButton::setIcon(const QPixmap& icon)
489
/************************************************
491
************************************************/
492
AuroraeSpacer::AuroraeSpacer(AuroraeTheme *theme)
498
QSizeF AuroraeSpacer::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
502
return QSizeF(m_theme->themeConfig().explicitButtonSpacer(),
503
m_theme->themeConfig().buttonHeight());