1 | // SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. |
2 | // |
3 | // SPDX-License-Identifier: GPL-3.0-or-later |
4 | |
5 | #include "statuswidget.h" |
6 | #include <QPaintEvent> |
7 | #include <QResizeEvent> |
8 | |
9 | class StatusWidgetPrivate |
10 | { |
11 | friend class StatusWidget; |
12 | QRectF drawRange; |
13 | QTimer timer; |
14 | QColor color = Qt::green; |
15 | StatusWidget::PatternFlags flags = StatusWidget::PatternFlag::Simple; |
16 | int currElemIndex = -1; |
17 | int elem = 8; |
18 | StatusWidget::State state = StatusWidget::State::Stoped; |
19 | }; |
20 | |
21 | StatusWidget::StatusWidget(QWidget *parent) |
22 | : QWidget (parent) |
23 | , d (new StatusWidgetPrivate) |
24 | { |
25 | |
26 | } |
27 | |
28 | StatusWidget::StatusWidget(PatternFlags flags, QWidget *parent) |
29 | : StatusWidget(parent) |
30 | { |
31 | d->flags = flags; |
32 | } |
33 | |
34 | StatusWidget::~StatusWidget() |
35 | { |
36 | if (d) { |
37 | delete d; |
38 | } |
39 | } |
40 | |
41 | void StatusWidget::setElemCount(int count) |
42 | { |
43 | d->elem = count; |
44 | } |
45 | |
46 | int StatusWidget::elemCount() |
47 | { |
48 | return d->elem; |
49 | } |
50 | |
51 | void StatusWidget::setPatternFlags(StatusWidget::PatternFlags flags) |
52 | { |
53 | d->flags = flags; |
54 | } |
55 | |
56 | StatusWidget::PatternFlags StatusWidget::patternFlags() |
57 | { |
58 | return d->flags; |
59 | } |
60 | |
61 | void StatusWidget::start(StatusWidget::RotaSpeed speed){ |
62 | QObject::connect(&d->timer,&QTimer::timeout,this,[=](){ |
63 | this->update(); |
64 | }); |
65 | d->timer.start(speed); |
66 | d->state = Running; |
67 | } |
68 | |
69 | void StatusWidget::setRotaSpeed(StatusWidget::RotaSpeed speed) |
70 | { |
71 | if(d->timer.interval() > 0) |
72 | d->timer.start(speed); |
73 | } |
74 | |
75 | void StatusWidget::start() |
76 | { |
77 | this->start(RotaSpeed::Usual); |
78 | } |
79 | |
80 | StatusWidget::RotaSpeed StatusWidget::rotaSpeed() const |
81 | { |
82 | return static_cast<RotaSpeed>(d->timer.interval()); |
83 | } |
84 | |
85 | void StatusWidget::stop() |
86 | { |
87 | d->timer.stop(); |
88 | d->state = Stoped; |
89 | } |
90 | |
91 | bool StatusWidget::isRunning() |
92 | { |
93 | if(d->timer.isActive() != (d->state == State::Running)) |
94 | { |
95 | qWarning() << "unknown errorr from timer paint" ; |
96 | } |
97 | |
98 | return d->timer.isActive() && d->state == State::Running; |
99 | } |
100 | |
101 | bool StatusWidget::isStoped() |
102 | { |
103 | return (!d->timer.isActive()) && d->state == State::Stoped; |
104 | } |
105 | |
106 | void StatusWidget::setError() |
107 | { |
108 | d->timer.stop(); |
109 | d->state = Error; |
110 | } |
111 | |
112 | bool StatusWidget::isError() |
113 | { |
114 | return d->state == State::Error; |
115 | } |
116 | |
117 | void StatusWidget::setWarning() |
118 | { |
119 | d->color = Qt::yellow; |
120 | } |
121 | |
122 | bool StatusWidget::isWarning() |
123 | { |
124 | return d->color == Qt::yellow; |
125 | } |
126 | |
127 | void StatusWidget::setRunningColor(QColor color) |
128 | { |
129 | d->color = color; |
130 | } |
131 | |
132 | void StatusWidget::paintEvent(QPaintEvent *event) |
133 | { |
134 | Q_UNUSED(event); |
135 | if(d->state == State::Stoped) return; |
136 | |
137 | QPainter painter(this); |
138 | |
139 | if(d->drawRange.isEmpty() || d->drawRange != this->rect()) |
140 | d->drawRange = this->rect(); |
141 | |
142 | if(d->elem <= 0) |
143 | d->elem = 8; |
144 | |
145 | if(d->state == State::Error) |
146 | return paintError(painter); |
147 | |
148 | if(d->flags.testFlag(PatternFlag::Ripple)) |
149 | return paintRipple(painter); |
150 | |
151 | if(d->flags.testFlag(PatternFlag::Twinkle)) |
152 | return paintTwinkle(painter); |
153 | |
154 | if(d->flags == PatternFlag::Ring |
155 | || d->flags.testFlag(PatternFlag::Simple)) |
156 | paintSimple(painter); |
157 | |
158 | if(d->flags.testFlag(PatternFlag::Radar)) |
159 | paintRadar(painter); |
160 | } |
161 | |
162 | void StatusWidget::paintError(QPainter &painter) |
163 | { |
164 | QRadialGradient gradient(this->rect().center(), |
165 | qMax(this->width(),this->height())/2, |
166 | this->rect().center()); |
167 | |
168 | gradient.setColorAt(0, Qt::red); |
169 | gradient.setColorAt(1, palette().window().color()); |
170 | gradient.setSpread(QGradient::ReflectSpread); |
171 | painter.setPen(Qt::red); |
172 | painter.setBrush(QBrush(gradient)); |
173 | auto len = qMin(this->width(), this->height()) / 3; |
174 | painter.drawEllipse(this->rect().center(), len,len); |
175 | } |
176 | |
177 | void StatusWidget::paintSimple(QPainter &painter) |
178 | { |
179 | qreal angle = (360 / d->elem) *16; |
180 | |
181 | if(d->currElemIndex == -1 || d->currElemIndex >= d->elem) |
182 | d->currElemIndex = 0; |
183 | |
184 | // QRadialGradient gradient(this->rect().center(), |
185 | // qMax(this->width(),this->height())/2, |
186 | // this->rect().center()); |
187 | // gradient.setColorAt(0, _color); |
188 | // gradient.setColorAt(1,palette().background().color()); |
189 | // gradient.setSpread(QGradient::ReflectSpread); |
190 | painter.setPen(palette().window().color()); |
191 | // painter.setBrush(QBrush(gradient)); |
192 | painter.setBrush(QBrush(d->color)); |
193 | painter.setRenderHint(QPainter::Antialiasing, true); |
194 | painter.drawPie(d->drawRange, d->currElemIndex * angle, angle); |
195 | d->currElemIndex ++; |
196 | |
197 | if (d->flags.testFlag(PatternFlag::Ring)) paintRing(painter); |
198 | |
199 | } |
200 | |
201 | void StatusWidget::paintRadar(QPainter &painter) |
202 | { |
203 | qreal angle = 360 / d->elem; |
204 | |
205 | static int currPieIndex = -1; |
206 | if(currPieIndex == -1 || currPieIndex >= d->elem) |
207 | currPieIndex = 0; |
208 | |
209 | QConicalGradient gradient(this->rect().center(), |
210 | (currPieIndex+1) * angle); |
211 | gradient.setColorAt(0, palette().window().color()); |
212 | gradient.setColorAt(1, d->color); |
213 | gradient.setSpread(QGradient::ReflectSpread); |
214 | painter.setPen(palette().window().color()); |
215 | painter.setBrush(QBrush(gradient)); |
216 | painter.setRenderHint(QPainter::Antialiasing, true); |
217 | painter.drawEllipse(this->rect().center(),this->width()/2,this->height()/2); |
218 | currPieIndex ++; |
219 | |
220 | if (d->flags.testFlag(PatternFlag::Ring)) paintRing(painter); |
221 | } |
222 | |
223 | void StatusWidget::paintRing(QPainter &painter) |
224 | { |
225 | auto background = this->palette().color(this->backgroundRole()); |
226 | painter.setPen(background); |
227 | painter.setBrush(background); |
228 | painter.drawEllipse(this->rect().center(), this->width() / 3,this->height() / 3); |
229 | } |
230 | |
231 | void StatusWidget::paintTwinkle(QPainter &painter) |
232 | { |
233 | auto background = this->palette().window(); |
234 | painter.setPen(background.color()); |
235 | |
236 | if(d->currElemIndex % 2 == 0) |
237 | { |
238 | painter.setBrush(this->palette().window()); |
239 | } |
240 | else |
241 | { |
242 | painter.setBrush(QColor(d->color)); |
243 | } |
244 | |
245 | painter.drawEllipse(this->rect().center(),this->width()/3,this->height()/3); |
246 | d->currElemIndex ++; |
247 | } |
248 | |
249 | void StatusWidget::paintRipple(QPainter &painter) |
250 | { |
251 | Q_UNUSED(painter); |
252 | } |
253 | |