Changeset View
Changeset View
Standalone View
Standalone View
kstyle/widgets/progressbar.cpp
- This file was added.
1 | #include "breezestyle.h" | ||||
---|---|---|---|---|---|
2 | | ||||
3 | namespace BreezePrivate | ||||
4 | { | ||||
5 | //_______________________________________________________________ | ||||
6 | #if !BREEZE_USE_KDE4 | ||||
7 | bool isProgressBarHorizontal(const QStyleOptionProgressBar *option) | ||||
8 | { | ||||
9 | return option && ((option->state & QStyle::State_Horizontal) || option->orientation == Qt::Horizontal); | ||||
10 | } | ||||
11 | #endif | ||||
12 | | ||||
13 | } | ||||
14 | | ||||
15 | namespace Breeze | ||||
16 | { | ||||
17 | //______________________________________________________________________________ | ||||
18 | void Helper::renderProgressBarGroove(QPainter *painter, const QRect &rect, const QColor &color) const | ||||
19 | { | ||||
20 | // setup painter | ||||
21 | painter->setRenderHint(QPainter::Antialiasing, true); | ||||
22 | | ||||
23 | const QRectF baseRect(rect); | ||||
24 | const qreal radius(0.5 * Metrics::ProgressBar_Thickness); | ||||
25 | | ||||
26 | // content | ||||
27 | if (color.isValid()) { | ||||
28 | painter->setPen(Qt::NoPen); | ||||
29 | painter->setBrush(color); | ||||
30 | painter->drawRoundedRect(baseRect, radius, radius); | ||||
31 | } | ||||
32 | } | ||||
33 | | ||||
34 | //______________________________________________________________________________ | ||||
35 | void Helper::renderProgressBarBusyContents(QPainter *painter, const QRect &rect, const QColor &first, const QColor &second, bool horizontal, bool reverse, int progress) const | ||||
36 | { | ||||
37 | // setup painter | ||||
38 | painter->setRenderHint(QPainter::Antialiasing, true); | ||||
39 | | ||||
40 | const QRectF baseRect(rect); | ||||
41 | const qreal radius(0.5 * Metrics::ProgressBar_Thickness); | ||||
42 | | ||||
43 | // setup brush | ||||
44 | QPixmap pixmap(horizontal ? 2 * Metrics::ProgressBar_BusyIndicatorSize : 1, horizontal ? 1 : 2 * Metrics::ProgressBar_BusyIndicatorSize); | ||||
45 | pixmap.fill(second); | ||||
46 | if (horizontal) { | ||||
47 | QPainter painter(&pixmap); | ||||
48 | painter.setBrush(first); | ||||
49 | painter.setPen(Qt::NoPen); | ||||
50 | | ||||
51 | progress %= 2 * Metrics::ProgressBar_BusyIndicatorSize; | ||||
52 | if (reverse) | ||||
53 | progress = 2 * Metrics::ProgressBar_BusyIndicatorSize - progress - 1; | ||||
54 | painter.drawRect(QRect(0, 0, Metrics::ProgressBar_BusyIndicatorSize, 1).translated(progress, 0)); | ||||
55 | | ||||
56 | if (progress > Metrics::ProgressBar_BusyIndicatorSize) { | ||||
57 | painter.drawRect(QRect(0, 0, Metrics::ProgressBar_BusyIndicatorSize, 1).translated(progress - 2 * Metrics::ProgressBar_BusyIndicatorSize, 0)); | ||||
58 | } | ||||
59 | | ||||
60 | } else { | ||||
61 | QPainter painter(&pixmap); | ||||
62 | painter.setBrush(first); | ||||
63 | painter.setPen(Qt::NoPen); | ||||
64 | | ||||
65 | progress %= 2 * Metrics::ProgressBar_BusyIndicatorSize; | ||||
66 | progress = 2 * Metrics::ProgressBar_BusyIndicatorSize - progress - 1; | ||||
67 | painter.drawRect(QRect(0, 0, 1, Metrics::ProgressBar_BusyIndicatorSize).translated(0, progress)); | ||||
68 | | ||||
69 | if (progress > Metrics::ProgressBar_BusyIndicatorSize) { | ||||
70 | painter.drawRect(QRect(0, 0, 1, Metrics::ProgressBar_BusyIndicatorSize).translated(0, progress - 2 * Metrics::ProgressBar_BusyIndicatorSize)); | ||||
71 | } | ||||
72 | } | ||||
73 | | ||||
74 | painter->setPen(Qt::NoPen); | ||||
75 | painter->setBrush(pixmap); | ||||
76 | painter->drawRoundedRect(baseRect, radius, radius); | ||||
77 | } | ||||
78 | | ||||
79 | //___________________________________________________________________________________________________________________ | ||||
80 | QRect Style::progressBarGrooveRect(const QStyleOption *option, const QWidget *widget) const | ||||
81 | { | ||||
82 | // cast option and check | ||||
83 | const auto progressBarOption(qstyleoption_cast<const QStyleOptionProgressBar *>(option)); | ||||
84 | if (!progressBarOption) | ||||
85 | return option->rect; | ||||
86 | | ||||
87 | // get flags and orientation | ||||
88 | const bool textVisible(progressBarOption->textVisible); | ||||
89 | const bool busy(progressBarOption->minimum == 0 && progressBarOption->maximum == 0); | ||||
90 | | ||||
91 | #if BREEZE_USE_KDE4 | ||||
92 | const auto progressBarOption2(qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)); | ||||
93 | const bool horizontal(!progressBarOption2 || progressBarOption2->orientation == Qt::Horizontal); | ||||
94 | #else | ||||
95 | const bool horizontal(BreezePrivate::isProgressBarHorizontal(progressBarOption)); | ||||
96 | #endif | ||||
97 | | ||||
98 | // copy rectangle and adjust | ||||
99 | auto rect(option->rect); | ||||
100 | const int frameWidth(pixelMetric(PM_DefaultFrameWidth, option, widget)); | ||||
101 | if (horizontal) | ||||
102 | rect = insideMargin(rect, frameWidth, 0); | ||||
103 | else | ||||
104 | rect = insideMargin(rect, 0, frameWidth); | ||||
105 | | ||||
106 | if (textVisible && !busy && horizontal) { | ||||
107 | auto textRect(subElementRect(SE_ProgressBarLabel, option, widget)); | ||||
108 | textRect = visualRect(option, textRect); | ||||
109 | rect.setRight(textRect.left() - Metrics::ProgressBar_ItemSpacing - 1); | ||||
110 | rect = visualRect(option, rect); | ||||
111 | rect = centerRect(rect, rect.width(), Metrics::ProgressBar_Thickness); | ||||
112 | | ||||
113 | } else if (horizontal) { | ||||
114 | rect = centerRect(rect, rect.width(), Metrics::ProgressBar_Thickness); | ||||
115 | | ||||
116 | } else { | ||||
117 | rect = centerRect(rect, Metrics::ProgressBar_Thickness, rect.height()); | ||||
118 | } | ||||
119 | | ||||
120 | return rect; | ||||
121 | } | ||||
122 | | ||||
123 | //___________________________________________________________________________________________________________________ | ||||
124 | QRect Style::progressBarContentsRect(const QStyleOption *option, const QWidget *widget) const | ||||
125 | { | ||||
126 | // cast option and check | ||||
127 | const auto progressBarOption(qstyleoption_cast<const QStyleOptionProgressBar *>(option)); | ||||
128 | if (!progressBarOption) | ||||
129 | return QRect(); | ||||
130 | | ||||
131 | // get groove rect | ||||
132 | const auto rect(progressBarGrooveRect(option, widget)); | ||||
133 | | ||||
134 | // in busy mode, grooveRect is used | ||||
135 | const bool busy(progressBarOption->minimum == 0 && progressBarOption->maximum == 0); | ||||
136 | if (busy) | ||||
137 | return rect; | ||||
138 | | ||||
139 | // get orientation | ||||
140 | #if BREEZE_USE_KDE4 | ||||
141 | const auto progressBarOption2(qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)); | ||||
142 | const bool horizontal(!progressBarOption2 || progressBarOption2->orientation == Qt::Horizontal); | ||||
143 | #else | ||||
144 | const bool horizontal(BreezePrivate::isProgressBarHorizontal(progressBarOption)); | ||||
145 | #endif | ||||
146 | | ||||
147 | // check inverted appearance | ||||
148 | #if BREEZE_USE_KDE4 | ||||
149 | const bool inverted(progressBarOption2 ? progressBarOption2->invertedAppearance : false); | ||||
150 | #else | ||||
151 | const bool inverted(progressBarOption->invertedAppearance); | ||||
152 | #endif | ||||
153 | | ||||
154 | // get progress and steps | ||||
155 | const qreal progress(progressBarOption->progress - progressBarOption->minimum); | ||||
156 | const int steps(qMax(progressBarOption->maximum - progressBarOption->minimum, 1)); | ||||
157 | | ||||
158 | // Calculate width fraction | ||||
159 | const qreal widthFrac = qMin(qreal(1), progress / steps); | ||||
160 | | ||||
161 | // convert the pixel width | ||||
162 | const int indicatorSize(widthFrac * (horizontal ? rect.width() : rect.height())); | ||||
163 | | ||||
164 | QRect indicatorRect; | ||||
165 | if (horizontal) { | ||||
166 | indicatorRect = QRect(inverted ? (rect.right() - indicatorSize + 1) : rect.left(), rect.y(), indicatorSize, rect.height()); | ||||
167 | indicatorRect = visualRect(option->direction, rect, indicatorRect); | ||||
168 | | ||||
169 | } else | ||||
170 | indicatorRect = QRect(rect.x(), inverted ? rect.top() : (rect.bottom() - indicatorSize + 1), rect.width(), indicatorSize); | ||||
171 | | ||||
172 | return indicatorRect; | ||||
173 | } | ||||
174 | | ||||
175 | //___________________________________________________________________________________________________________________ | ||||
176 | QRect Style::progressBarLabelRect(const QStyleOption *option, const QWidget *) const | ||||
177 | { | ||||
178 | // cast option and check | ||||
179 | const auto progressBarOption(qstyleoption_cast<const QStyleOptionProgressBar *>(option)); | ||||
180 | if (!progressBarOption) | ||||
181 | return QRect(); | ||||
182 | | ||||
183 | // get flags and check | ||||
184 | const bool textVisible(progressBarOption->textVisible); | ||||
185 | const bool busy(progressBarOption->minimum == 0 && progressBarOption->maximum == 0); | ||||
186 | if (!textVisible || busy) | ||||
187 | return QRect(); | ||||
188 | | ||||
189 | // get direction and check | ||||
190 | #if BREEZE_USE_KDE4 | ||||
191 | const auto progressBarOption2(qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)); | ||||
192 | const bool horizontal(!progressBarOption2 || progressBarOption2->orientation == Qt::Horizontal); | ||||
193 | #else | ||||
194 | const bool horizontal(BreezePrivate::isProgressBarHorizontal(progressBarOption)); | ||||
195 | #endif | ||||
196 | if (!horizontal) | ||||
197 | return QRect(); | ||||
198 | | ||||
199 | int textWidth = qMax(option->fontMetrics.size(_mnemonics->textFlags(), progressBarOption->text).width(), option->fontMetrics.size(_mnemonics->textFlags(), QStringLiteral("100%")).width()); | ||||
200 | | ||||
201 | auto rect(insideMargin(option->rect, Metrics::Frame_FrameWidth, 0)); | ||||
202 | rect.setLeft(rect.right() - textWidth + 1); | ||||
203 | rect = visualRect(option, rect); | ||||
204 | | ||||
205 | return rect; | ||||
206 | } | ||||
207 | | ||||
208 | //______________________________________________________________ | ||||
209 | QSize Style::progressBarSizeFromContents(const QStyleOption *option, const QSize &contentsSize, const QWidget *) const | ||||
210 | { | ||||
211 | // cast option | ||||
212 | const auto progressBarOption(qstyleoption_cast<const QStyleOptionProgressBar *>(option)); | ||||
213 | if (!progressBarOption) | ||||
214 | return contentsSize; | ||||
215 | | ||||
216 | #if BREEZE_USE_KDE4 | ||||
217 | const auto progressBarOption2(qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)); | ||||
218 | const bool horizontal(!progressBarOption2 || progressBarOption2->orientation == Qt::Horizontal); | ||||
219 | #else | ||||
220 | const bool horizontal(BreezePrivate::isProgressBarHorizontal(progressBarOption)); | ||||
221 | #endif | ||||
222 | | ||||
223 | // make local copy | ||||
224 | QSize size(contentsSize); | ||||
225 | | ||||
226 | if (horizontal) { | ||||
227 | // check text visibility | ||||
228 | const bool textVisible(progressBarOption->textVisible); | ||||
229 | | ||||
230 | size.setWidth(qMax(size.width(), int(Metrics::ProgressBar_Thickness))); | ||||
231 | size.setHeight(qMax(size.height(), int(Metrics::ProgressBar_Thickness))); | ||||
232 | if (textVisible) | ||||
233 | size.setHeight(qMax(size.height(), option->fontMetrics.height())); | ||||
234 | | ||||
235 | } else { | ||||
236 | size.setHeight(qMax(size.height(), int(Metrics::ProgressBar_Thickness))); | ||||
237 | size.setWidth(qMax(size.width(), int(Metrics::ProgressBar_Thickness))); | ||||
238 | } | ||||
239 | | ||||
240 | return size; | ||||
241 | } | ||||
242 | | ||||
243 | //___________________________________________________________________________________ | ||||
244 | bool Style::drawProgressBarControl(const QStyleOption *option, QPainter *painter, const QWidget *widget) const | ||||
245 | { | ||||
246 | const auto progressBarOption(qstyleoption_cast<const QStyleOptionProgressBar *>(option)); | ||||
247 | if (!progressBarOption) | ||||
248 | return true; | ||||
249 | | ||||
250 | // render groove | ||||
251 | #if BREEZE_USE_KDE4 | ||||
252 | QStyleOptionProgressBarV2 progressBarOption2 = *progressBarOption; | ||||
253 | #else | ||||
254 | QStyleOptionProgressBar progressBarOption2 = *progressBarOption; | ||||
255 | #endif | ||||
256 | progressBarOption2.rect = subElementRect(SE_ProgressBarGroove, progressBarOption, widget); | ||||
257 | drawControl(CE_ProgressBarGroove, &progressBarOption2, painter, widget); | ||||
258 | | ||||
259 | #if QT_VERSION >= 0x050000 | ||||
260 | const QObject *styleObject(widget ? widget : progressBarOption->styleObject); | ||||
261 | #else | ||||
262 | const QObject *styleObject(widget); | ||||
263 | #endif | ||||
264 | | ||||
265 | // enable busy animations | ||||
266 | // need to check both widget and passed styleObject, used for QML | ||||
267 | if (styleObject && _animations->busyIndicatorEngine().enabled()) { | ||||
268 | #if QT_VERSION >= 0x050000 | ||||
269 | // register QML object if defined | ||||
270 | if (!widget && progressBarOption->styleObject) { | ||||
271 | _animations->busyIndicatorEngine().registerWidget(progressBarOption->styleObject); | ||||
272 | } | ||||
273 | #endif | ||||
274 | | ||||
275 | _animations->busyIndicatorEngine().setAnimated(styleObject, progressBarOption->maximum == 0 && progressBarOption->minimum == 0); | ||||
276 | } | ||||
277 | | ||||
278 | // check if animated and pass to option | ||||
279 | if (_animations->busyIndicatorEngine().isAnimated(styleObject)) { | ||||
280 | progressBarOption2.progress = _animations->busyIndicatorEngine().value(); | ||||
281 | } | ||||
282 | | ||||
283 | // render contents | ||||
284 | progressBarOption2.rect = subElementRect(SE_ProgressBarContents, progressBarOption, widget); | ||||
285 | drawControl(CE_ProgressBarContents, &progressBarOption2, painter, widget); | ||||
286 | | ||||
287 | // render text | ||||
288 | const bool textVisible(progressBarOption->textVisible); | ||||
289 | const bool busy(progressBarOption->minimum == 0 && progressBarOption->maximum == 0); | ||||
290 | if (textVisible && !busy) { | ||||
291 | progressBarOption2.rect = subElementRect(SE_ProgressBarLabel, progressBarOption, widget); | ||||
292 | drawControl(CE_ProgressBarLabel, &progressBarOption2, painter, widget); | ||||
293 | } | ||||
294 | | ||||
295 | return true; | ||||
296 | } | ||||
297 | | ||||
298 | //___________________________________________________________________________________ | ||||
299 | bool Style::drawProgressBarContentsControl(const QStyleOption *option, QPainter *painter, const QWidget *) const | ||||
300 | { | ||||
301 | const auto progressBarOption(qstyleoption_cast<const QStyleOptionProgressBar *>(option)); | ||||
302 | if (!progressBarOption) | ||||
303 | return true; | ||||
304 | | ||||
305 | // copy rect and palette | ||||
306 | auto rect(option->rect); | ||||
307 | const auto &palette(option->palette); | ||||
308 | | ||||
309 | // get direction | ||||
310 | #if BREEZE_USE_KDE4 | ||||
311 | const auto progressBarOption2(qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)); | ||||
312 | const bool horizontal = !progressBarOption2 || progressBarOption2->orientation == Qt::Horizontal; | ||||
313 | const bool inverted(progressBarOption2 ? progressBarOption2->invertedAppearance : false); | ||||
314 | #else | ||||
315 | const bool horizontal(BreezePrivate::isProgressBarHorizontal(progressBarOption)); | ||||
316 | const bool inverted(progressBarOption->invertedAppearance); | ||||
317 | #endif | ||||
318 | bool reverse = horizontal && option->direction == Qt::RightToLeft; | ||||
319 | if (inverted) | ||||
320 | reverse = !reverse; | ||||
321 | | ||||
322 | // check if anything is to be drawn | ||||
323 | const bool busy((progressBarOption->minimum == 0 && progressBarOption->maximum == 0)); | ||||
324 | if (busy) { | ||||
325 | const qreal progress(_animations->busyIndicatorEngine().value()); | ||||
326 | | ||||
327 | const auto &first = palette.color(QPalette::Highlight); | ||||
328 | const auto second(KColorUtils::mix(palette.color(QPalette::Highlight), palette.color(QPalette::Window), 0.7)); | ||||
329 | _helper->renderProgressBarBusyContents(painter, rect, first, second, horizontal, reverse, progress); | ||||
330 | | ||||
331 | } else { | ||||
332 | const QRegion oldClipRegion(painter->clipRegion()); | ||||
333 | if (horizontal) { | ||||
334 | if (rect.width() < Metrics::ProgressBar_Thickness) { | ||||
335 | painter->setClipRect(rect, Qt::IntersectClip); | ||||
336 | if (reverse) | ||||
337 | rect.setLeft(rect.left() - Metrics::ProgressBar_Thickness + rect.width()); | ||||
338 | else | ||||
339 | rect.setWidth(Metrics::ProgressBar_Thickness); | ||||
340 | } | ||||
341 | | ||||
342 | } else { | ||||
343 | if (rect.height() < Metrics::ProgressBar_Thickness) { | ||||
344 | painter->setClipRect(rect, Qt::IntersectClip); | ||||
345 | if (reverse) | ||||
346 | rect.setHeight(Metrics::ProgressBar_Thickness); | ||||
347 | else | ||||
348 | rect.setTop(rect.top() - Metrics::ProgressBar_Thickness + rect.height()); | ||||
349 | } | ||||
350 | } | ||||
351 | | ||||
352 | auto contentsColor(option->state.testFlag(QStyle::State_Selected) ? palette.color(QPalette::HighlightedText) : palette.color(QPalette::Highlight)); | ||||
353 | | ||||
354 | _helper->renderProgressBarContents(painter, rect, contentsColor); | ||||
355 | painter->setClipRegion(oldClipRegion); | ||||
356 | } | ||||
357 | | ||||
358 | return true; | ||||
359 | } | ||||
360 | | ||||
361 | //___________________________________________________________________________________ | ||||
362 | bool Style::drawProgressBarGrooveControl(const QStyleOption *option, QPainter *painter, const QWidget *) const | ||||
363 | { | ||||
364 | const auto &palette(option->palette); | ||||
365 | const auto color(_helper->alphaColor(palette.color(QPalette::WindowText), 0.3)); | ||||
366 | _helper->renderProgressBarGroove(painter, option->rect, color); | ||||
367 | return true; | ||||
368 | } | ||||
369 | | ||||
370 | //___________________________________________________________________________________ | ||||
371 | bool Style::drawProgressBarLabelControl(const QStyleOption *option, QPainter *painter, const QWidget *) const | ||||
372 | { | ||||
373 | // cast option and check | ||||
374 | const auto progressBarOption(qstyleoption_cast<const QStyleOptionProgressBar *>(option)); | ||||
375 | if (!progressBarOption) | ||||
376 | return true; | ||||
377 | | ||||
378 | // get direction and check | ||||
379 | #if BREEZE_USE_KDE4 | ||||
380 | const auto progressBarOption2(qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)); | ||||
381 | const bool horizontal = !progressBarOption2 || progressBarOption2->orientation == Qt::Horizontal; | ||||
382 | #else | ||||
383 | const bool horizontal(BreezePrivate::isProgressBarHorizontal(progressBarOption)); | ||||
384 | #endif | ||||
385 | if (!horizontal) | ||||
386 | return true; | ||||
387 | | ||||
388 | // store rect and palette | ||||
389 | const auto &rect(option->rect); | ||||
390 | const auto &palette(option->palette); | ||||
391 | | ||||
392 | // store state and direction | ||||
393 | const State &state(option->state); | ||||
394 | const bool enabled(state & State_Enabled); | ||||
395 | | ||||
396 | // define text rect | ||||
397 | Qt::Alignment hAlign((progressBarOption->textAlignment == Qt::AlignLeft) ? Qt::AlignHCenter : progressBarOption->textAlignment); | ||||
398 | drawItemText(painter, rect, Qt::AlignVCenter | hAlign, palette, enabled, progressBarOption->text, QPalette::WindowText); | ||||
399 | | ||||
400 | return true; | ||||
401 | } | ||||
402 | | ||||
403 | } |