Plasma
busywidget.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 "busywidget.h" 00021 00022 //Qt 00023 #include <QPainter> 00024 #include <QTimer> 00025 #include <QGraphicsSceneResizeEvent> 00026 #include <QTextOption> 00027 00028 //Plasma 00029 #include "plasma/theme.h" 00030 #include "plasma/svg.h" 00031 00032 namespace Plasma 00033 { 00034 00035 class BusyWidgetPrivate 00036 { 00037 public: 00038 BusyWidgetPrivate() 00039 : svg(0), 00040 timerId(0), 00041 rotationAngle(0), 00042 rotation(0), 00043 running(true) 00044 { 00045 } 00046 00047 ~BusyWidgetPrivate() 00048 { 00049 } 00050 00051 void themeChanged() 00052 { 00053 frames.clear(); 00054 rotationAngle = svg->elementSize("hint-rotation-angle").width(); 00055 00056 //use an angle near to rotationAngle but that it fits an integer number of times in 360 00057 int nFrames = 360/rotationAngle; 00058 rotationAngle = 360/nFrames; 00059 } 00060 00061 Svg *svg; 00062 QString styleSheet; 00063 int timerId; 00064 QHash<int, QPixmap> frames; 00065 qreal rotationAngle; 00066 qreal rotation; 00067 bool running; 00068 QString label; 00069 }; 00070 00071 00072 BusyWidget::BusyWidget(QGraphicsWidget *parent) 00073 : QGraphicsWidget(parent), 00074 d(new BusyWidgetPrivate) 00075 { 00076 d->svg = new Plasma::Svg(this); 00077 d->svg->setImagePath("widgets/busywidget"); 00078 d->svg->setContainsMultipleImages(true); 00079 d->themeChanged(); 00080 00081 connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), SLOT(themeChanged())); 00082 } 00083 00084 BusyWidget::~BusyWidget() 00085 { 00086 delete d; 00087 } 00088 00089 void BusyWidget::setRunning(bool running) 00090 { 00091 if (running && !d->timerId && isVisible()) { 00092 d->timerId = startTimer(150); 00093 } else if (!running && d->timerId) { 00094 killTimer(d->timerId); 00095 d->timerId = 0; 00096 } 00097 d->running = running; 00098 } 00099 00100 bool BusyWidget::isRunning() const 00101 { 00102 return d->running; 00103 } 00104 00105 void BusyWidget::setLabel(const QString &label) 00106 { 00107 d->label = label; 00108 update(); 00109 } 00110 00111 QString BusyWidget::label() const 00112 { 00113 return d->label; 00114 } 00115 00116 void BusyWidget::timerEvent(QTimerEvent *event) 00117 { 00118 if (event->timerId() != d->timerId) { 00119 QObject::timerEvent(event); 00120 return; 00121 } 00122 00123 d->rotation += d->rotationAngle; 00124 00125 qreal overflow = d->rotation - 360; 00126 if ( overflow > 0) { 00127 d->rotation = overflow; 00128 } 00129 update(); 00130 } 00131 00132 void BusyWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) 00133 { 00134 Q_UNUSED(option) 00135 Q_UNUSED(widget) 00136 00137 int intRotation = int(d->rotation); 00138 00139 QRectF spinnerRect(QPoint(0, 0), QSize(qMin(size().width(), size().height()), qMin(size().width(), size().height()))); 00140 spinnerRect.moveCenter(boundingRect().center()); 00141 00142 if (!isEnabled()) { 00143 painter->setOpacity(painter->opacity() / 2); 00144 } 00145 00146 if (!d->running && d->svg->hasElement("paused")) { 00147 d->svg->paint(painter, spinnerRect, "paused"); 00148 } else { 00149 if (!d->frames[intRotation]) { 00150 QPointF translatedPos(spinnerRect.width()/2, spinnerRect.height()/2); 00151 00152 d->frames[intRotation] = QPixmap(spinnerRect.size().toSize()); 00153 d->frames[intRotation].fill(Qt::transparent); 00154 00155 QPainter buffPainter(&d->frames[intRotation]); 00156 00157 buffPainter.setRenderHints(QPainter::SmoothPixmapTransform); 00158 buffPainter.translate(translatedPos); 00159 00160 if (d->svg->hasElement("busywidget-shadow")) { 00161 buffPainter.save(); 00162 buffPainter.translate(1,1); 00163 buffPainter.rotate(intRotation); 00164 d->svg->paint(&buffPainter, QRectF(-translatedPos.toPoint(), spinnerRect.size()), "busywidget-shadow"); 00165 buffPainter.restore(); 00166 } 00167 00168 buffPainter.rotate(intRotation); 00169 d->svg->paint(&buffPainter, QRectF(-translatedPos.toPoint(), spinnerRect.size()), "busywidget"); 00170 } 00171 00172 painter->drawPixmap(spinnerRect.topLeft().toPoint(), d->frames[intRotation]); 00173 } 00174 00175 painter->setPen(Plasma::Theme::defaultTheme()->color(Theme::TextColor)); 00176 Qt::Alignment align(Qt::AlignVCenter | Qt::AlignHCenter); 00177 painter->drawText(boundingRect(), d->label, QTextOption(align)); 00178 } 00179 00180 void BusyWidget::showEvent(QShowEvent *event) 00181 { 00182 Q_UNUSED(event) 00183 if (d->running) { 00184 d->timerId = startTimer(150); 00185 } 00186 } 00187 00188 void BusyWidget::hideEvent(QHideEvent *event) 00189 { 00190 Q_UNUSED(event) 00191 if (d->timerId) { 00192 killTimer(d->timerId); 00193 } 00194 00195 d->timerId = 0; 00196 } 00197 00198 void BusyWidget::resizeEvent(QGraphicsSceneResizeEvent *event) 00199 { 00200 Q_UNUSED(event) 00201 d->frames.clear(); 00202 } 00203 00204 void BusyWidget::mousePressEvent(QGraphicsSceneMouseEvent *event) 00205 { 00206 event->setAccepted(true); 00207 } 00208 00209 void BusyWidget::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) 00210 { 00211 if ((event->button() & Qt::LeftButton) || 00212 (event->buttons() & Qt::LeftButton)) { 00213 emit clicked(); 00214 } 00215 } 00216 00217 } // namespace Plasma 00218 00219 #include <busywidget.moc> 00220
KDE 4.6 API Reference