mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Work on a new spin animation
This commit is contained in:
parent
cdca0c8c29
commit
4ce301c1b0
@ -1,9 +1,87 @@
|
||||
#pragma once
|
||||
|
||||
#include <QtWidgets/QWidget>
|
||||
#include <QObject>
|
||||
#include <QColor>
|
||||
#include <QHash>
|
||||
#include <QPainter>
|
||||
#include <QPropertyAnimation>
|
||||
#include <QParallelAnimationGroup>
|
||||
|
||||
class SpinAnimator: public QObject {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(float arc_length READ get_arc_length WRITE set_arc_length)
|
||||
Q_PROPERTY(int arc_rotation READ get_arc_rotation WRITE set_arc_rotation)
|
||||
Q_PROPERTY(int overall_rotation READ get_overall_rotation WRITE set_overall_rotation)
|
||||
public:
|
||||
SpinAnimator(QObject* parent = 0) :
|
||||
QObject(parent),
|
||||
m_arc_length(0),
|
||||
m_arc_rotation(0),
|
||||
m_overall_rotation(0),
|
||||
m_has_pending_updates(false),
|
||||
m_animation(this)
|
||||
{
|
||||
QPropertyAnimation *a;
|
||||
#define S(property, duration) a = new QPropertyAnimation(this, QByteArray(#property), this); a->setEasingCurve(QEasingCurve::InOutCubic); a->setDuration(duration); a->setLoopCount(-1); m_animation.addAnimation(a);
|
||||
S(arc_length, 1400);
|
||||
const float arc_length_max = 0.734f, arc_length_min = 0.01f;
|
||||
a->setStartValue(arc_length_min);
|
||||
a->setKeyValueAt(0.25, arc_length_min);
|
||||
a->setKeyValueAt(0.5, arc_length_max);
|
||||
a->setKeyValueAt(0.75, arc_length_max);
|
||||
a->setEndValue(arc_length_min);
|
||||
|
||||
S(arc_rotation, 1400);
|
||||
a->setStartValue(0);
|
||||
a->setKeyValueAt(0.25, 0);
|
||||
a->setKeyValueAt(0.5, 45);
|
||||
a->setKeyValueAt(0.75, 45);
|
||||
a->setEndValue(360);
|
||||
|
||||
S(overall_rotation, 2000);
|
||||
a->setStartValue(0);
|
||||
a->setEndValue(360);
|
||||
#undef S
|
||||
}
|
||||
~SpinAnimator() { m_animation.stop(); m_animation.clear(); }
|
||||
void start() { m_animation.start(); }
|
||||
void stop() { m_animation.stop(); }
|
||||
bool is_running() { return m_animation.state() == QAbstractAnimation::Running; }
|
||||
void draw(QPainter &painter, QRect bounds, const QColor &color) {
|
||||
m_has_pending_updates = false;
|
||||
painter.save();
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
QRectF rect(bounds);
|
||||
float thickness = std::max(3.f, std::min((float)rect.width() / 10.f, 24.f));
|
||||
QPen pen(color);
|
||||
pen.setWidthF(thickness);
|
||||
float ht = thickness / 2 + 1;
|
||||
rect.adjust(ht, ht, -ht, -ht);
|
||||
pen.setCapStyle(Qt::RoundCap);
|
||||
painter.setPen(pen);
|
||||
int rotated_by = (m_overall_rotation + m_arc_rotation) * 16;
|
||||
int arc_length = (int)(m_arc_length * 360 * 16);
|
||||
painter.drawArc(rect, -rotated_by, -arc_length);
|
||||
painter.restore();
|
||||
}
|
||||
|
||||
float get_arc_length() const { return m_arc_length; }
|
||||
int get_arc_rotation() const { return m_arc_rotation; }
|
||||
int get_overall_rotation() const { return m_overall_rotation; }
|
||||
public slots:
|
||||
void set_arc_length(float val) { m_arc_length = val; notify_of_update(); }
|
||||
void set_arc_rotation(int val) { m_arc_rotation = val; notify_of_update(); }
|
||||
void set_overall_rotation(int val) { m_overall_rotation = val; notify_of_update(); }
|
||||
signals:
|
||||
void updated();
|
||||
private:
|
||||
float m_arc_length;
|
||||
int m_arc_rotation, m_overall_rotation;
|
||||
bool m_has_pending_updates;
|
||||
void notify_of_update() { if (!m_has_pending_updates) { m_has_pending_updates = true; emit updated(); } }
|
||||
QParallelAnimationGroup m_animation;
|
||||
};
|
||||
|
||||
/*!
|
||||
\class QProgressIndicator
|
||||
|
@ -12,6 +12,29 @@ void set_no_activate_on_click(QWidget *widget);
|
||||
void draw_snake_spinner(QPainter &painter, QRect rect, int angle, const QColor & light, const QColor & dark);
|
||||
%End
|
||||
|
||||
class SpinAnimator : QObject {
|
||||
|
||||
%TypeHeaderCode
|
||||
#include <QProgressIndicator.h>
|
||||
%End
|
||||
|
||||
public:
|
||||
SpinAnimator(QWidget *parent /TransferThis/ = 0);
|
||||
float get_arc_length() const ;
|
||||
int get_arc_rotation() const ;
|
||||
int get_overall_rotation() const ;
|
||||
void draw(QPainter &painter, QRect bounds, const QColor &color);
|
||||
void start();
|
||||
void stop();
|
||||
bool is_running();
|
||||
public slots:
|
||||
void set_arc_length(float val) ;
|
||||
void set_arc_rotation(int val) ;
|
||||
void set_overall_rotation(int val) ;
|
||||
signals:
|
||||
void updated();
|
||||
};
|
||||
|
||||
class QProgressIndicator : QWidget {
|
||||
|
||||
%TypeHeaderCode
|
||||
|
@ -94,6 +94,31 @@ class WaitLayout(QStackedLayout):
|
||||
self.wp.msg = val
|
||||
|
||||
|
||||
def develop():
|
||||
from PyQt5.Qt import QPalette, QPainter, QRect
|
||||
from calibre.gui2 import Application
|
||||
from calibre_extensions.progress_indicator import SpinAnimator
|
||||
|
||||
class Widget(QWidget):
|
||||
|
||||
def __init__(self):
|
||||
QWidget.__init__(self)
|
||||
self.a = SpinAnimator(self)
|
||||
self.a.updated.connect(self.update)
|
||||
|
||||
def paintEvent(self, ev):
|
||||
p = QPainter(self)
|
||||
pal = self.palette()
|
||||
self.a.draw(p, QRect(0, 0, 64, 64), pal.color(QPalette.ColorRole.WindowText))
|
||||
p.end()
|
||||
|
||||
app = Application([])
|
||||
w = Widget()
|
||||
w.show()
|
||||
w.a.start()
|
||||
app.exec_()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from calibre.gui2 import Application
|
||||
app = Application([])
|
||||
|
Loading…
x
Reference in New Issue
Block a user