114 lines
2.1 KiB
C++
114 lines
2.1 KiB
C++
#include "busy_icon.h"
|
|
|
|
#include "qad_types.h"
|
|
|
|
#include <QApplication>
|
|
#include <QPainter>
|
|
#include <qmath.h>
|
|
|
|
|
|
BusyIcon::BusyIcon(QWidget * parent): QWidget(parent) {}
|
|
|
|
|
|
BusyIcon::~BusyIcon() {}
|
|
|
|
|
|
void BusyIcon::start() {
|
|
stop();
|
|
timer = startTimer(25);
|
|
}
|
|
|
|
|
|
void BusyIcon::stop() {
|
|
if (timer == 0) return;
|
|
killTimer(timer);
|
|
timer = 0;
|
|
}
|
|
|
|
|
|
QIcon BusyIcon::icon() {
|
|
return icon_;
|
|
}
|
|
|
|
|
|
void BusyIcon::setIcon(QIcon i) {
|
|
icon_ = i;
|
|
image = i.pixmap(512, 512).toImage();
|
|
}
|
|
|
|
|
|
void BusyIcon::setIconSize(qreal s) {
|
|
icon_size = s;
|
|
updateGeometry();
|
|
update();
|
|
}
|
|
|
|
|
|
void BusyIcon::setIconScale(qreal s) {
|
|
icon_scale = s;
|
|
updateGeometry();
|
|
update();
|
|
}
|
|
|
|
|
|
void BusyIcon::setCircleWidth(qreal s) {
|
|
circle_width = s;
|
|
updateGeometry();
|
|
update();
|
|
}
|
|
|
|
|
|
QSize BusyIcon::sizeHint() const {
|
|
return preferredIconSize(icon_size, this);
|
|
}
|
|
|
|
|
|
void BusyIcon::timerEvent(QTimerEvent *) {
|
|
if (!isVisible()) return;
|
|
ang += 1;
|
|
update();
|
|
}
|
|
|
|
|
|
QPointF point(qreal r, qreal a) {
|
|
return QPointF(-r * sin(a), -r * cos(a));
|
|
}
|
|
qreal frag(qreal a, qreal f) {
|
|
int i = (int)(a / f);
|
|
return a - (i * f);
|
|
}
|
|
qreal angle(int a) {
|
|
return (cos(frag(a / 15., M_PI)) - 1) * M_PI;
|
|
}
|
|
|
|
void BusyIcon::paintEvent(QPaintEvent *) {
|
|
QPainter p(this);
|
|
if (rect().isEmpty()) return;
|
|
qreal w = width(), h = height();
|
|
p.translate(w / 2., h / 2.);
|
|
p.scale(qMin(w, h), qMin(w, h));
|
|
|
|
float imgsz = icon_scale / 100.f, ioff = circle_width / 200.f;
|
|
p.setRenderHint(QPainter::SmoothPixmapTransform);
|
|
p.setRenderHint(QPainter::Antialiasing);
|
|
p.drawImage(QRectF(-imgsz / 2., -imgsz / 2., imgsz, imgsz), image);
|
|
p.setPen(Qt::NoPen);
|
|
p.setBrush(palette().brush(QPalette::Active, QPalette::Highlight));
|
|
p.setRenderHint(QPainter::Antialiasing);
|
|
|
|
qreal sa = angle(ang), ea = angle(ang + 10);
|
|
if (ea > sa) ea -= M_PI * 2.;
|
|
qreal rs = 0.5 - ioff, rb = 0.5;
|
|
int steps = qMin(128, qRound(qAbs(ea - sa) / 0.025));
|
|
QPolygonF pol;
|
|
for (int i = 0; i <= steps; ++i) {
|
|
qreal c = i / (qreal)steps;
|
|
pol << point(rs, sa * c + ea * (1. - c));
|
|
}
|
|
for (int i = 0; i <= steps; ++i) {
|
|
qreal c = i / (qreal)steps;
|
|
pol << point(rb, ea * c + sa * (1. - c));
|
|
}
|
|
p.drawPolygon(pol);
|
|
}
|