Files
qad/libs/widgets/busy_icon.cpp
peri4 e791618a17 version 2.32.0
work with icons - remove unused, organize and update to last oxygen
add BusyIcon widget
2024-10-30 22:22:44 +03:00

115 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();
ang = 0;
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);
}