1 /* 2 SPDX-FileCopyrightText: 2019 Harald Sitter <sitter@kde.org> 3 4 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 */ 6 7 #include "kbusyindicatorwidget.h" 8 9 #include <QApplication> 10 #include <QIcon> 11 #include <QPainter> 12 #include <QResizeEvent> 13 #include <QStyle> 14 #include <QVariantAnimation> 15 16 class KBusyIndicatorWidgetPrivate 17 { 18 public: KBusyIndicatorWidgetPrivate(KBusyIndicatorWidget * parent)19 KBusyIndicatorWidgetPrivate(KBusyIndicatorWidget *parent) 20 : q(parent) 21 { 22 animation.setLoopCount(-1); 23 animation.setDuration(2000); 24 animation.setStartValue(0); 25 animation.setEndValue(360); 26 QObject::connect(&animation, &QVariantAnimation::valueChanged, q, [=](QVariant value) { 27 rotation = value.toReal(); 28 q->update(); // repaint new rotation 29 }); 30 } 31 32 KBusyIndicatorWidget *const q; 33 QVariantAnimation animation; 34 QIcon icon = QIcon::fromTheme(QStringLiteral("view-refresh")); 35 qreal rotation = 0; 36 QPointF paintCenter; 37 }; 38 KBusyIndicatorWidget(QWidget * parent)39KBusyIndicatorWidget::KBusyIndicatorWidget(QWidget *parent) 40 : QWidget(parent) 41 , d(new KBusyIndicatorWidgetPrivate(this)) 42 { 43 } 44 45 KBusyIndicatorWidget::~KBusyIndicatorWidget() = default; 46 minimumSizeHint() const47QSize KBusyIndicatorWidget::minimumSizeHint() const 48 { 49 const auto extent = QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize); 50 return QSize(extent, extent); 51 } 52 showEvent(QShowEvent * event)53void KBusyIndicatorWidget::showEvent(QShowEvent *event) 54 { 55 QWidget::showEvent(event); 56 d->animation.start(); 57 } 58 hideEvent(QHideEvent * event)59void KBusyIndicatorWidget::hideEvent(QHideEvent *event) 60 { 61 QWidget::hideEvent(event); 62 d->animation.pause(); 63 } 64 resizeEvent(QResizeEvent * event)65void KBusyIndicatorWidget::resizeEvent(QResizeEvent *event) 66 { 67 QWidget::resizeEvent(event); 68 d->paintCenter = QPointF(event->size().width() / 2.0, // 69 event->size().height() / 2.0); 70 } 71 paintEvent(QPaintEvent *)72void KBusyIndicatorWidget::paintEvent(QPaintEvent *) 73 { 74 QPainter painter(this); 75 painter.setRenderHint(QPainter::SmoothPixmapTransform); 76 77 // Rotate around the center and then reset back to origin for icon painting. 78 painter.translate(d->paintCenter); 79 painter.rotate(d->rotation); 80 painter.translate(-d->paintCenter); 81 82 d->icon.paint(&painter, rect()); 83 } 84 event(QEvent * event)85bool KBusyIndicatorWidget::event(QEvent *event) 86 { 87 // Only overridden to be flexible WRT binary compatible in the future. 88 // Overriding later has potential to change the call going through 89 // the vtable or not. 90 return QWidget::event(event); 91 } 92