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 | bool KBusyIndicatorWidget::isRunning() const |
54 | { |
55 | return d->animation.state() == QAbstractAnimation::Running; |
56 | } |
57 | |
58 | void KBusyIndicatorWidget::start() |
59 | { |
60 | d->animation.start(); |
61 | } |
62 | |
63 | void KBusyIndicatorWidget::stop() |
64 | { |
65 | if (d->animation.state() == QAbstractAnimation::Running) // avoid warning if never started yet |
66 | d->animation.pause(); |
67 | } |
68 | |
69 | void KBusyIndicatorWidget::setRunning(const bool enable) |
70 | { |
71 | if (enable) |
72 | start(); |
73 | else |
74 | stop(); |
75 | } |
76 | |
77 | void KBusyIndicatorWidget::showEvent(QShowEvent *event) |
78 | { |
79 | QWidget::showEvent(event); |
80 | start(); |
81 | } |
82 | |
83 | void KBusyIndicatorWidget::hideEvent(QHideEvent *event) |
84 | { |
85 | QWidget::hideEvent(event); |
86 | stop(); |
87 | } |
88 | |
89 | void KBusyIndicatorWidget::resizeEvent(QResizeEvent *event) |
90 | { |
91 | QWidget::resizeEvent(event); |
92 | d->paintCenter = QPointF(event->size().width() / 2.0, // |
93 | event->size().height() / 2.0); |
94 | } |
95 | |
96 | void KBusyIndicatorWidget::paintEvent(QPaintEvent *) |
97 | { |
98 | QPainter painter(this); |
99 | painter.setRenderHint(hint: QPainter::SmoothPixmapTransform); |
100 | |
101 | // Rotate around the center and then reset back to origin for icon painting. |
102 | painter.translate(offset: d->paintCenter); |
103 | painter.rotate(a: d->rotation); |
104 | painter.translate(offset: -d->paintCenter); |
105 | |
106 | d->icon.paint(painter: &painter, rect: rect()); |
107 | } |
108 | |
109 | bool KBusyIndicatorWidget::event(QEvent *event) |
110 | { |
111 | // Only overridden to be flexible WRT binary compatible in the future. |
112 | // Overriding later has potential to change the call going through |
113 | // the vtable or not. |
114 | return QWidget::event(event); |
115 | } |
116 | |
117 | #include "moc_kbusyindicatorwidget.cpp" |
118 |