Line data Source code
1 : // SPDX-FileCopyrightText: 2016 Anne Jan Brouwer
2 : // SPDX-License-Identifier: GPL-3.0-or-later
3 : /*
4 : * This code is based on https://github.com/mojocorp/QProgressIndicator
5 : * and published under
6 : *
7 : * The MIT License (MIT)
8 : *
9 : * Copyright (c) 2011 Morgan Leborgne
10 : *
11 : * Permission is hereby granted, free of charge, to any person obtaining a copy
12 : * of this software and associated documentation files (the "Software"), to deal
13 : * in the Software without restriction, including without limitation the rights
14 : * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 : * copies of the Software, and to permit persons to whom the Software is
16 : * furnished to do so, subject to the following conditions:
17 : *
18 : * The above copyright notice and this permission notice shall be included in
19 : * all copies or substantial portions of the Software.
20 : *
21 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 : * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 : * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 : * SOFTWARE.
28 : */
29 : #include "qprogressindicator.h"
30 : #include <QPainter>
31 :
32 : /**
33 : * @brief QProgressIndicator::QProgressIndicator constructor.
34 : * @param parent widget the indicator is placed in.
35 : */
36 0 : QProgressIndicator::QProgressIndicator(QWidget *parent)
37 0 : : QWidget(parent), m_angle(0), m_timerId(-1), m_delay(40),
38 0 : m_displayedWhenStopped(false), m_color(Qt::black) {
39 0 : setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
40 0 : setFocusPolicy(Qt::NoFocus);
41 0 : }
42 :
43 0 : auto QProgressIndicator::isAnimated() const -> bool { return m_timerId != -1; }
44 :
45 0 : void QProgressIndicator::setDisplayedWhenStopped(bool state) {
46 0 : m_displayedWhenStopped = state;
47 :
48 0 : update();
49 0 : }
50 :
51 0 : auto QProgressIndicator::isDisplayedWhenStopped() const -> bool {
52 0 : return m_displayedWhenStopped;
53 : }
54 :
55 0 : void QProgressIndicator::startAnimation() {
56 0 : m_angle = 0;
57 :
58 0 : if (m_timerId == -1) {
59 0 : m_timerId = startTimer(m_delay);
60 : }
61 0 : }
62 :
63 0 : void QProgressIndicator::stopAnimation() {
64 0 : if (m_timerId != -1) {
65 0 : killTimer(m_timerId);
66 : }
67 :
68 0 : m_timerId = -1;
69 :
70 0 : update();
71 0 : }
72 :
73 0 : void QProgressIndicator::setAnimationDelay(int delay) {
74 0 : if (m_timerId != -1) {
75 0 : killTimer(m_timerId);
76 : }
77 :
78 0 : m_delay = delay;
79 :
80 0 : if (m_timerId != -1) {
81 0 : m_timerId = startTimer(m_delay);
82 : }
83 0 : }
84 :
85 0 : void QProgressIndicator::setColor(const QColor &color) {
86 0 : m_color = color;
87 :
88 0 : update();
89 0 : }
90 :
91 : /**
92 : * @brief QProgressIndicator::sizeHint default minimum size.
93 : * @return QSize(20, 20)
94 : */
95 0 : auto QProgressIndicator::sizeHint() const -> QSize { return {20, 20}; }
96 :
97 : /**
98 : * @brief QProgressIndicator::heightForWidth square ratio.
99 : * @param w requested width
100 : * @return w returned height
101 : */
102 0 : auto QProgressIndicator::heightForWidth(int w) const -> int { return w; }
103 :
104 : /**
105 : * @brief QProgressIndicator::timerEvent do the actual animation.
106 : */
107 0 : void QProgressIndicator::timerEvent(QTimerEvent * /*event*/) {
108 0 : m_angle = (m_angle + 30) % 360;
109 :
110 0 : update();
111 0 : }
112 :
113 : /**
114 : * @brief QProgressIndicator::paintEvent draw the spinner.
115 : */
116 0 : void QProgressIndicator::paintEvent(QPaintEvent * /*event*/) {
117 0 : if (!m_displayedWhenStopped && !isAnimated()) {
118 0 : return;
119 : }
120 :
121 : int width = qMin(this->width(), this->height());
122 :
123 0 : QPainter p(this);
124 0 : p.setRenderHint(QPainter::Antialiasing);
125 :
126 0 : auto outerRadius = int((width - 1) * 0.5);
127 0 : auto innerRadius = int((width - 1) * 0.5 * 0.38);
128 :
129 0 : int capsuleHeight = outerRadius - innerRadius;
130 : int capsuleWidth =
131 0 : (width > 32) ? int(capsuleHeight * 0.23) : int(capsuleHeight * 0.35);
132 0 : int capsuleRadius = capsuleWidth / 2;
133 :
134 0 : for (int i = 0; i < 12; ++i) {
135 0 : QColor color = m_color;
136 0 : color.setAlphaF(int(1.0f - (i / 12.0f)));
137 0 : p.setPen(Qt::NoPen);
138 0 : p.setBrush(color);
139 0 : p.save();
140 0 : p.translate(rect().center());
141 0 : p.rotate(int(m_angle - i * 30.0f));
142 0 : p.drawRoundedRect(int(-capsuleWidth * 0.5), -(innerRadius + capsuleHeight),
143 : capsuleWidth, capsuleHeight, capsuleRadius,
144 : capsuleRadius);
145 0 : p.restore();
146 : }
147 0 : }
|