File indexing completed on 2023-11-26 04:55:45
0001 /* 0002 Circular countdown widget 0003 Copyright (C) 2011 Martin Klapetek <martin.klapetek@gmail.com> 0004 0005 This library is free software; you can redistribute it and/or 0006 modify it under the terms of the GNU Lesser General Public 0007 License as published by the Free Software Foundation; either 0008 version 2.1 of the License, or (at your option) any later version. 0009 0010 This library is distributed in the hope that it will be useful, 0011 but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 Lesser General Public License for more details. 0014 0015 You should have received a copy of the GNU Lesser General Public 0016 License along with this library; if not, write to the Free Software 0017 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 0018 */ 0019 0020 #include "circular-countdown.h" 0021 0022 #include <QPainter> 0023 #include <QPaintEvent> 0024 #include <QTimeLine> 0025 0026 namespace KTp 0027 { 0028 0029 class CircularCountdown::Private 0030 { 0031 public: 0032 Private(CircularCountdown *parent) 0033 : q(parent) 0034 { 0035 0036 } 0037 0038 CircularCountdown *q; 0039 QTimeLine *timeLine; 0040 }; 0041 0042 CircularCountdown::CircularCountdown(int msec, QWidget *parent) 0043 : QWidget(parent), 0044 d(new Private(this)) 0045 { 0046 setAutoFillBackground(false); 0047 0048 d->timeLine = new QTimeLine(msec, this); 0049 //circle has 360 degrees, for better smoothness we use 2x as much 0050 d->timeLine->setFrameRange(0, 720); 0051 //to paint the subtraction animation, we start from full circle to 0 0052 d->timeLine->setDirection(QTimeLine::Backward); 0053 0054 //repaint on every frame change for smooth animation 0055 connect(d->timeLine, SIGNAL(frameChanged(int)), this, SLOT(repaint())); 0056 0057 //repaint after animation is finished 0058 connect(d->timeLine, SIGNAL(finished()), this, SLOT(repaint())); 0059 0060 //emit timeoutReached() when the timeout is reached 0061 connect(d->timeLine, SIGNAL(finished()), this, SIGNAL(timeout())); 0062 } 0063 0064 CircularCountdown::~CircularCountdown() 0065 { 0066 delete d; 0067 } 0068 0069 void CircularCountdown::paintEvent(QPaintEvent *event) { 0070 Q_UNUSED(event); 0071 0072 if (d->timeLine->state() == QTimeLine::Running || d->timeLine->state() == QTimeLine::Paused) { 0073 QPainter painter(this); 0074 //always take parent widget's palette and use it's Base color 0075 painter.setBrush(QBrush(parentWidget()->palette().color(QPalette::Base), Qt::SolidPattern)); 0076 painter.setRenderHint(QPainter::Antialiasing); 0077 /* drawPie always paints 1/16th of a degree, the total circle is 5760 (16 * 360) 0078 * the first argument is this widget size with 2px padding 0079 * second argument is start position, which is 3 o'clock by default, 0080 * to move it to 12 o'clock we need to start at 90 degrees, hence 90 * 16 0081 * third argument tells how much of the current circle is painted 0082 * the range is [0..720], hence the *8 (to get 5760 in total) 0083 * and it's minus because we want it to rotate in the other direction 0084 */ 0085 painter.drawPie(this->rect().adjusted(2, 2, -2, -2), 90*16, -d->timeLine->currentFrame()*8); 0086 } 0087 } 0088 0089 QSize CircularCountdown::sizeHint() const 0090 { 0091 return QSize(16, 16); 0092 } 0093 0094 void CircularCountdown::setDuration(int msec) { 0095 d->timeLine->setDuration(msec); 0096 } 0097 0098 int CircularCountdown::duration() const 0099 { 0100 return d->timeLine->duration(); 0101 } 0102 0103 void CircularCountdown::start() { 0104 d->timeLine->start(); 0105 } 0106 0107 void CircularCountdown::stop() { 0108 d->timeLine->stop(); 0109 } 0110 0111 void CircularCountdown::pause() { 0112 //no, there really is no ->pause() if you're thinking about that ;) 0113 d->timeLine->setPaused(true); 0114 } 0115 0116 void CircularCountdown::resume() { 0117 d->timeLine->resume(); 0118 } 0119 0120 }