#include "busy_icon.h" #include "qad_types.h" #include #include #include 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); }