• Skip to content
  • Skip to link menu
KDE 4.3 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 #include "private/actionwidgetinterface_p.h"
00039 
00040 namespace Plasma
00041 {
00042 
00043 class ToolButtonPrivate : public ActionWidgetInterface<ToolButton>
00044 {
00045 public:
00046     ToolButtonPrivate(ToolButton *toolButton)
00047         : ActionWidgetInterface<ToolButton>(toolButton),
00048           q(toolButton),
00049           background(0),
00050           animId(0),
00051           fadeIn(false),
00052           svg(0)
00053     {
00054     }
00055 
00056     ~ToolButtonPrivate()
00057     {
00058         delete svg;
00059     }
00060 
00061     void setPixmap()
00062     {
00063         if (imagePath.isEmpty()) {
00064             delete svg;
00065             svg = 0;
00066             return;
00067         }
00068 
00069         KMimeType::Ptr mime = KMimeType::findByPath(absImagePath);
00070         QPixmap pm(q->size().toSize());
00071         pm.fill(Qt::transparent);
00072 
00073         if (mime->is("image/svg+xml") || mime->is("image/svg+xml-compressed")) {
00074             if (!svg || svg->imagePath() != absImagePath) {
00075                 delete svg;
00076                 svg = new Svg();
00077                 svg->setImagePath(imagePath);
00078                 QObject::connect(svg, SIGNAL(repaintNeeded()), q, SLOT(setPixmap()));
00079             }
00080 
00081             QPainter p(&pm);
00082             svg->paint(&p, pm.rect());
00083         } else {
00084             delete svg;
00085             svg = 0;
00086             pm = QPixmap(absImagePath);
00087         }
00088 
00089         static_cast<QToolButton*>(q->widget())->setIcon(KIcon(pm));
00090     }
00091 
00092     void syncActiveRect();
00093     void syncBorders();
00094     void animationUpdate(qreal progress);
00095 
00096     ToolButton *q;
00097 
00098     FrameSvg *background;
00099     int animId;
00100     bool fadeIn;
00101     qreal opacity;
00102     QRectF activeRect;
00103 
00104     QString imagePath;
00105     QString absImagePath;
00106     Svg *svg;
00107 };
00108 
00109 void ToolButtonPrivate::syncActiveRect()
00110 {
00111     background->setElementPrefix("normal");
00112 
00113     qreal left, top, right, bottom;
00114     background->getMargins(left, top, right, bottom);
00115 
00116     background->setElementPrefix("active");
00117     qreal activeLeft, activeTop, activeRight, activeBottom;
00118     background->getMargins(activeLeft, activeTop, activeRight, activeBottom);
00119 
00120     activeRect = QRectF(QPointF(0, 0), q->size());
00121     activeRect.adjust(left - activeLeft, top - activeTop,
00122                       -(right - activeRight), -(bottom - activeBottom));
00123 
00124     background->setElementPrefix("normal");
00125 }
00126 
00127 void ToolButtonPrivate::syncBorders()
00128 {
00129     //set margins from the normal element
00130     qreal left, top, right, bottom;
00131 
00132     background->setElementPrefix("normal");
00133     background->getMargins(left, top, right, bottom);
00134     q->setContentsMargins(left, top, right, bottom);
00135 
00136     //calc the rect for the over effect
00137     syncActiveRect();
00138 }
00139 
00140 void ToolButtonPrivate::animationUpdate(qreal progress)
00141 {
00142     if (progress == 1) {
00143         animId = 0;
00144         fadeIn = true;
00145     }
00146 
00147     opacity = fadeIn ? progress : 1 - progress;
00148 
00149     // explicit update
00150     q->update();
00151 }
00152 
00153 ToolButton::ToolButton(QGraphicsWidget *parent)
00154     : QGraphicsProxyWidget(parent),
00155       d(new ToolButtonPrivate(this))
00156 {
00157     QToolButton *native = new QToolButton;
00158     connect(native, SIGNAL(clicked()), this, SIGNAL(clicked()));
00159     setWidget(native);
00160     native->setAttribute(Qt::WA_NoSystemBackground);
00161     native->setAutoRaise(true);
00162 
00163     d->background = new FrameSvg(this);
00164     d->background->setImagePath("widgets/button");
00165     d->background->setCacheAllRenderedFrames(true);
00166     d->background->setElementPrefix("normal");
00167     d->syncBorders();
00168     setAcceptHoverEvents(true);
00169     connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), SLOT(syncBorders()));
00170 }
00171 
00172 ToolButton::~ToolButton()
00173 {
00174     delete d;
00175 }
00176 
00177 void ToolButton::setAction(QAction *action)
00178 {
00179     d->setAction(action);
00180 }
00181 
00182 QAction *ToolButton::action() const
00183 {
00184     return d->action;
00185 }
00186 
00187 void ToolButton::setAutoRaise(bool raise)
00188 {
00189     nativeWidget()->setAutoRaise(raise);
00190 }
00191 
00192 bool ToolButton::autoRaise() const
00193 {
00194     return nativeWidget()->autoRaise();
00195 }
00196 
00197 void ToolButton::setText(const QString &text)
00198 {
00199     static_cast<QToolButton*>(widget())->setText(text);
00200 }
00201 
00202 QString ToolButton::text() const
00203 {
00204     return static_cast<QToolButton*>(widget())->text();
00205 }
00206 
00207 void ToolButton::setImage(const QString &path)
00208 {
00209     if (d->imagePath == path) {
00210         return;
00211     }
00212 
00213     delete d->svg;
00214     d->svg = 0;
00215     d->imagePath = path;
00216 
00217     bool absolutePath = !path.isEmpty() &&
00218                         #ifdef Q_WS_WIN
00219                             !QDir::isRelativePath(path)
00220                         #else
00221                             (path[0] == '/' || path.startsWith(":/"))
00222                         #endif
00223         ;
00224 
00225     if (absolutePath) {
00226         d->absImagePath = path;
00227     } else {
00228         //TODO: package support
00229         d->absImagePath = Theme::defaultTheme()->imagePath(path);
00230     }
00231 
00232     d->setPixmap();
00233 }
00234 
00235 void ToolButton::setIcon(const QIcon &icon)
00236 {
00237     nativeWidget()->setIcon(icon);
00238 }
00239 
00240 QIcon ToolButton::icon() const
00241 {
00242     return nativeWidget()->icon();
00243 }
00244 
00245 QString ToolButton::image() const
00246 {
00247     return d->imagePath;
00248 }
00249 
00250 void ToolButton::setStyleSheet(const QString &stylesheet)
00251 {
00252     widget()->setStyleSheet(stylesheet);
00253 }
00254 
00255 QString ToolButton::styleSheet()
00256 {
00257     return widget()->styleSheet();
00258 }
00259 
00260 QToolButton *ToolButton::nativeWidget() const
00261 {
00262     return static_cast<QToolButton*>(widget());
00263 }
00264 
00265 void ToolButton::resizeEvent(QGraphicsSceneResizeEvent *event)
00266 {
00267     d->setPixmap();
00268 
00269    if (d->background) {
00270         //resize all four panels
00271         d->background->setElementPrefix("pressed");
00272         d->background->resizeFrame(size());
00273         d->background->setElementPrefix("focus");
00274         d->background->resizeFrame(size());
00275 
00276         d->syncActiveRect();
00277 
00278         d->background->setElementPrefix("active");
00279         d->background->resizeFrame(d->activeRect.size());
00280 
00281         d->background->setElementPrefix("normal");
00282         d->background->resizeFrame(size());
00283    }
00284 
00285    QGraphicsProxyWidget::resizeEvent(event);
00286 }
00287 
00288 void ToolButton::paint(QPainter *painter,
00289                        const QStyleOptionGraphicsItem *option,
00290                        QWidget *widget)
00291 {
00292     if (!styleSheet().isNull()) {
00293         QGraphicsProxyWidget::paint(painter, option, widget);
00294         return;
00295     }
00296 
00297     QToolButton *button = nativeWidget();
00298 
00299     QStyleOptionToolButton buttonOpt;
00300     buttonOpt.initFrom(button);
00301     buttonOpt.icon = button->icon();
00302     buttonOpt.text = button->text();
00303     buttonOpt.iconSize = button->iconSize();
00304     buttonOpt.toolButtonStyle = button->toolButtonStyle();
00305 
00306 
00307     if (button->isEnabled() && (d->animId || !button->autoRaise() || (buttonOpt.state & QStyle::State_MouseOver) || (buttonOpt.state & QStyle::State_On))) {
00308         if (button->isDown() || (buttonOpt.state & QStyle::State_On)) {
00309             d->background->setElementPrefix("pressed");
00310         } else {
00311             d->background->setElementPrefix("normal");
00312         }
00313         d->background->resizeFrame(size());
00314 
00315         if (d->animId) {
00316             QPixmap buffer = d->background->framePixmap();
00317 
00318             QPainter bufferPainter(&buffer);
00319             bufferPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
00320             QColor alphaColor(Qt::black);
00321             alphaColor.setAlphaF(qMin(qreal(0.95), d->opacity));
00322             bufferPainter.fillRect(buffer.rect(), alphaColor);
00323             bufferPainter.end();
00324 
00325             painter->drawPixmap(QPoint(0,0), buffer);
00326 
00327             buttonOpt.palette.setColor(QPalette::ButtonText, KColorUtils::mix(Plasma::Theme::defaultTheme()->color(Plasma::Theme::ButtonTextColor), Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor), 1-d->opacity));
00328         } else {
00329             d->background->paintFrame(painter);
00330             buttonOpt.palette.setColor(QPalette::ButtonText, Plasma::Theme::defaultTheme()->color(Plasma::Theme::ButtonTextColor));
00331         }
00332 
00333     } else {
00334         buttonOpt.palette.setColor(QPalette::ButtonText, Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor));
00335     }
00336 
00337     painter->setFont(Plasma::Theme::defaultTheme()->font(Plasma::Theme::DefaultFont));
00338     button->style()->drawControl(QStyle::CE_ToolButtonLabel, &buttonOpt, painter, button);
00339 }
00340 
00341 void ToolButton::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
00342 {
00343     if (nativeWidget()->isDown() || !nativeWidget()->autoRaise()) {
00344         return;
00345     }
00346 
00347     const int FadeInDuration = 75;
00348 
00349     if (d->animId) {
00350         Plasma::Animator::self()->stopCustomAnimation(d->animId);
00351     }
00352     d->animId = Plasma::Animator::self()->customAnimation(
00353         40 / (1000 / FadeInDuration), FadeInDuration,
00354         Plasma::Animator::LinearCurve, this, "animationUpdate");
00355 
00356     d->background->setElementPrefix("active");
00357 
00358     QGraphicsProxyWidget::hoverEnterEvent(event);
00359 }
00360 
00361 void ToolButton::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
00362 {
00363     if (nativeWidget()->isDown() || !nativeWidget()->autoRaise()) {
00364         return;
00365     }
00366 
00367     const int FadeOutDuration = 150;
00368 
00369     if (d->animId) {
00370         Plasma::Animator::self()->stopCustomAnimation(d->animId);
00371     }
00372 
00373     d->fadeIn = false;
00374     d->animId = Plasma::Animator::self()->customAnimation(
00375         40 / (1000 / FadeOutDuration), FadeOutDuration,
00376         Plasma::Animator::LinearCurve, this, "animationUpdate");
00377 
00378     d->background->setElementPrefix("active");
00379 
00380     QGraphicsProxyWidget::hoverLeaveEvent(event);
00381 }
00382 
00383 } // namespace Plasma
00384 
00385 #include <toolbutton.moc>
00386 

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
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
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