• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

Plasma

toolbutton.cpp

Go to the documentation of this file.
00001 /*
00002  *   Copyright 2008 Marco Martin <notmart@gmail.com>
00003  *
00004  *   This program is free software; you can redistribute it and/or modify
00005  *   it under the terms of the GNU Library General Public License as
00006  *   published by the Free Software Foundation; either version 2, or
00007  *   (at your option) any later version.
00008  *
00009  *   This program is distributed in the hope that it will be useful,
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *   GNU General Public License for more details
00013  *
00014  *   You should have received a copy of the GNU Library General Public
00015  *   License along with this program; if not, write to the
00016  *   Free Software Foundation, Inc.,
00017  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00018  */
00019 
00020 #include "toolbutton.h"
00021 
00022 #include <QStyleOptionGraphicsItem>
00023 #include <QPainter>
00024 #include <QDir>
00025 #include <QToolButton>
00026 #include <QApplication>
00027 
00028 #include <kicon.h>
00029 #include <kiconeffect.h>
00030 #include <kmimetype.h>
00031 #include <kcolorutils.h>
00032 
00033 #include "theme.h"
00034 #include "svg.h"
00035 #include "framesvg.h"
00036 #include "animator.h"
00037 #include "paintutils.h"
00038 
00039 namespace Plasma
00040 {
00041 
00042 class ToolButtonPrivate
00043 {
00044 public:
00045     ToolButtonPrivate(ToolButton *toolButton)
00046         : q(toolButton),
00047           background(0),
00048           animId(0),
00049           fadeIn(false),
00050           svg(0)
00051     {
00052     }
00053 
00054     ~ToolButtonPrivate()
00055     {
00056         delete svg;
00057     }
00058 
00059     void setPixmap(ToolButton *q)
00060     {
00061         if (imagePath.isEmpty()) {
00062             return;
00063         }
00064 
00065         KMimeType::Ptr mime = KMimeType::findByPath(absImagePath);
00066         QPixmap pm(q->size().toSize());
00067 
00068         if (mime->is("image/svg+xml")) {
00069             svg = new Svg();
00070             QPainter p(&pm);
00071             svg->paint(&p, pm.rect());
00072         } else {
00073             pm = QPixmap(absImagePath);
00074         }
00075 
00076         static_cast<QToolButton*>(q->widget())->setIcon(KIcon(pm));
00077     }
00078 
00079     void syncActiveRect();
00080     void syncBorders();
00081     void animationUpdate(qreal progress);
00082 
00083     ToolButton *q;
00084 
00085     FrameSvg *background;
00086     int animId;
00087     bool fadeIn;
00088     qreal opacity;
00089     QRectF activeRect;
00090 
00091     QString imagePath;
00092     QString absImagePath;
00093     Svg *svg;
00094 };
00095 
00096 void ToolButtonPrivate::syncActiveRect()
00097 {
00098     background->setElementPrefix("normal");
00099 
00100     qreal left, top, right, bottom;
00101     background->getMargins(left, top, right, bottom);
00102 
00103     background->setElementPrefix("active");
00104     qreal activeLeft, activeTop, activeRight, activeBottom;
00105     background->getMargins(activeLeft, activeTop, activeRight, activeBottom);
00106 
00107     activeRect = QRectF(QPointF(0, 0), q->size());
00108     activeRect.adjust(left - activeLeft, top - activeTop,
00109                       -(right - activeRight), -(bottom - activeBottom));
00110 
00111     background->setElementPrefix("normal");
00112 }
00113 
00114 void ToolButtonPrivate::syncBorders()
00115 {
00116     //set margins from the normal element
00117     qreal left, top, right, bottom;
00118 
00119     background->setElementPrefix("normal");
00120     background->getMargins(left, top, right, bottom);
00121     q->setContentsMargins(left, top, right, bottom);
00122 
00123     //calc the rect for the over effect
00124     syncActiveRect();
00125 }
00126 
00127 void ToolButtonPrivate::animationUpdate(qreal progress)
00128 {
00129     if (progress == 1) {
00130         animId = 0;
00131         fadeIn = true;
00132     }
00133 
00134     opacity = fadeIn ? progress : 1 - progress;
00135 
00136     // explicit update
00137     q->update();
00138 }
00139 
00140 ToolButton::ToolButton(QGraphicsWidget *parent)
00141     : QGraphicsProxyWidget(parent),
00142       d(new ToolButtonPrivate(this))
00143 {
00144     QToolButton *native = new QToolButton;
00145     connect(native, SIGNAL(clicked()), this, SIGNAL(clicked()));
00146     setWidget(native);
00147     native->setAttribute(Qt::WA_NoSystemBackground);
00148     native->setAutoRaise(true);
00149 
00150     d->background = new FrameSvg(this);
00151     d->background->setImagePath("widgets/button");
00152     d->background->setCacheAllRenderedFrames(true);
00153     d->background->setElementPrefix("normal");
00154     d->syncBorders();
00155     setAcceptHoverEvents(true);
00156     connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), SLOT(syncBorders()));
00157 }
00158 
00159 ToolButton::~ToolButton()
00160 {
00161     delete d;
00162 }
00163 
00164 void ToolButton::setAutoRaise(bool raise)
00165 {
00166     nativeWidget()->setAutoRaise(raise);
00167 }
00168 
00169 bool ToolButton::autoRaise() const
00170 {
00171     return nativeWidget()->autoRaise();
00172 }
00173 
00174 void ToolButton::setText(const QString &text)
00175 {
00176     static_cast<QToolButton*>(widget())->setText(text);
00177 }
00178 
00179 QString ToolButton::text() const
00180 {
00181     return static_cast<QToolButton*>(widget())->text();
00182 }
00183 
00184 void ToolButton::setImage(const QString &path)
00185 {
00186     if (d->imagePath == path) {
00187         return;
00188     }
00189 
00190     delete d->svg;
00191     d->svg = 0;
00192     d->imagePath = path;
00193 
00194     bool absolutePath = !path.isEmpty() &&
00195                         #ifdef Q_WS_WIN
00196                             !QDir::isRelativePath(path)
00197                         #else
00198                             (path[0] == '/' || path.startsWith(":/"))
00199                         #endif
00200         ;
00201 
00202     if (absolutePath) {
00203         d->absImagePath = path;
00204     } else {
00205         //TODO: package support
00206         d->absImagePath = Theme::defaultTheme()->imagePath(path);
00207     }
00208 
00209     d->setPixmap(this);
00210 }
00211 
00212 QString ToolButton::image() const
00213 {
00214     return d->imagePath;
00215 }
00216 
00217 void ToolButton::setStyleSheet(const QString &stylesheet)
00218 {
00219     widget()->setStyleSheet(stylesheet);
00220 }
00221 
00222 QString ToolButton::styleSheet()
00223 {
00224     return widget()->styleSheet();
00225 }
00226 
00227 QToolButton *ToolButton::nativeWidget() const
00228 {
00229     return static_cast<QToolButton*>(widget());
00230 }
00231 
00232 void ToolButton::resizeEvent(QGraphicsSceneResizeEvent *event)
00233 {
00234     d->setPixmap(this);
00235 
00236    if (d->background) {
00237         //resize all four panels
00238         d->background->setElementPrefix("pressed");
00239         d->background->resizeFrame(size());
00240         d->background->setElementPrefix("focus");
00241         d->background->resizeFrame(size());
00242 
00243         d->syncActiveRect();
00244 
00245         d->background->setElementPrefix("active");
00246         d->background->resizeFrame(d->activeRect.size());
00247 
00248         d->background->setElementPrefix("normal");
00249         d->background->resizeFrame(size());
00250    }
00251 
00252    QGraphicsProxyWidget::resizeEvent(event);
00253 }
00254 
00255 void ToolButton::paint(QPainter *painter,
00256                        const QStyleOptionGraphicsItem *option,
00257                        QWidget *widget)
00258 {
00259     if (!styleSheet().isNull()) {
00260         QGraphicsProxyWidget::paint(painter, option, widget);
00261         return;
00262     }
00263 
00264     QToolButton *button = nativeWidget();
00265 
00266     QStyleOptionToolButton buttonOpt;
00267     buttonOpt.initFrom(button);
00268     buttonOpt.icon = button->icon();
00269     buttonOpt.text = button->text();
00270     buttonOpt.iconSize = button->iconSize();
00271     buttonOpt.toolButtonStyle = button->toolButtonStyle();
00272 
00273 
00274     if (d->animId || !button->autoRaise() || (buttonOpt.state & QStyle::State_MouseOver) || (buttonOpt.state & QStyle::State_On)) {
00275         if (button->isDown() || (buttonOpt.state & QStyle::State_On)) {
00276             d->background->setElementPrefix("pressed");
00277         } else {
00278             d->background->setElementPrefix("normal");
00279         }
00280         d->background->resizeFrame(size());
00281 
00282         if (d->animId) {
00283             QPixmap buffer = d->background->framePixmap();
00284 
00285             QPainter bufferPainter(&buffer);
00286             bufferPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
00287             QColor alphaColor(Qt::black);
00288             alphaColor.setAlphaF(qMin(qreal(0.95), d->opacity));
00289             bufferPainter.fillRect(buffer.rect(), alphaColor);
00290             bufferPainter.end();
00291 
00292             painter->drawPixmap(QPoint(0,0), buffer);
00293 
00294             buttonOpt.palette.setColor(QPalette::ButtonText, KColorUtils::mix(Plasma::Theme::defaultTheme()->color(Plasma::Theme::ButtonTextColor), Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor), 1-d->opacity));
00295         } else {
00296             d->background->paintFrame(painter);
00297             buttonOpt.palette.setColor(QPalette::ButtonText, Plasma::Theme::defaultTheme()->color(Plasma::Theme::ButtonTextColor));
00298         }
00299 
00300     } else {
00301         buttonOpt.palette.setColor(QPalette::ButtonText, Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor));
00302     }
00303 
00304     painter->setFont(Plasma::Theme::defaultTheme()->font(Plasma::Theme::DefaultFont));
00305 
00306     button->style()->drawControl(QStyle::CE_ToolButtonLabel, &buttonOpt, painter, button);
00307 }
00308 
00309 void ToolButton::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
00310 {
00311     if (nativeWidget()->isDown() || !nativeWidget()->autoRaise()) {
00312         return;
00313     }
00314 
00315     const int FadeInDuration = 75;
00316 
00317     if (d->animId) {
00318         Plasma::Animator::self()->stopCustomAnimation(d->animId);
00319     }
00320     d->animId = Plasma::Animator::self()->customAnimation(
00321         40 / (1000 / FadeInDuration), FadeInDuration,
00322         Plasma::Animator::LinearCurve, this, "animationUpdate");
00323 
00324     d->background->setElementPrefix("active");
00325 
00326     QGraphicsProxyWidget::hoverEnterEvent(event);
00327 }
00328 
00329 void ToolButton::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
00330 {
00331     if (nativeWidget()->isDown() || !nativeWidget()->autoRaise()) {
00332         return;
00333     }
00334 
00335     const int FadeOutDuration = 150;
00336 
00337     if (d->animId) {
00338         Plasma::Animator::self()->stopCustomAnimation(d->animId);
00339     }
00340 
00341     d->fadeIn = false;
00342     d->animId = Plasma::Animator::self()->customAnimation(
00343         40 / (1000 / FadeOutDuration), FadeOutDuration,
00344         Plasma::Animator::LinearCurve, this, "animationUpdate");
00345 
00346     d->background->setElementPrefix("active");
00347 
00348     QGraphicsProxyWidget::hoverLeaveEvent(event);
00349 }
00350 
00351 } // namespace Plasma
00352 
00353 #include <toolbutton.moc>
00354 

Plasma

Skip menu "Plasma"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.7
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal