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: |
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(sender: &animation, signal: &QVariantAnimation::valueChanged, context: q, slot: [this](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 | |
39 | KBusyIndicatorWidget::KBusyIndicatorWidget(QWidget *parent) |
40 | : QWidget(parent) |
41 | , d(new KBusyIndicatorWidgetPrivate(this)) |
42 | { |
43 | } |
44 | |
45 | KBusyIndicatorWidget::~KBusyIndicatorWidget() = default; |
46 | |
47 | QSize KBusyIndicatorWidget::minimumSizeHint() const |
48 | { |
49 | const auto extent = QApplication::style()->pixelMetric(metric: QStyle::PM_SmallIconSize); |
50 | return QSize(extent, extent); |
51 | } |
52 | |
53 | void KBusyIndicatorWidget::showEvent(QShowEvent *event) |
54 | { |
55 | QWidget::showEvent(event); |
56 | d->animation.start(); |
57 | } |
58 | |
59 | void KBusyIndicatorWidget::hideEvent(QHideEvent *event) |
60 | { |
61 | QWidget::hideEvent(event); |
62 | d->animation.pause(); |
63 | } |
64 | |
65 | void 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 | |
72 | void KBusyIndicatorWidget::paintEvent(QPaintEvent *) |
73 | { |
74 | QPainter painter(this); |
75 | painter.setRenderHint(hint: QPainter::SmoothPixmapTransform); |
76 | |
77 | // Rotate around the center and then reset back to origin for icon painting. |
78 | painter.translate(offset: d->paintCenter); |
79 | painter.rotate(a: d->rotation); |
80 | painter.translate(offset: -d->paintCenter); |
81 | |
82 | d->icon.paint(painter: &painter, rect: rect()); |
83 | } |
84 | |
85 | bool 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 | |
93 | #include "moc_kbusyindicatorwidget.cpp" |
94 | |