21 #include "private/meter_p.h"
27 #include <QPropertyAnimation>
30 #include <kglobalsettings.h>
38 MeterPrivate::MeterPrivate(Meter *m)
44 meterType(Meter::AnalogMeter),
52 void MeterPrivate::progressChanged(
int progress)
58 void MeterPrivate::paint(QPainter *p,
const QString &elementID)
60 if (image->hasElement(elementID)) {
61 QRectF elementRect = image->elementRect(elementID);
62 image->paint(p, elementRect, elementID);
66 void MeterPrivate::text(QPainter *p,
int index)
68 QString elementID = QString(
"label%1").arg(index);
69 QString text = labels[index];
71 if (image->hasElement(elementID)) {
72 QRectF elementRect = image->elementRect(elementID);
73 Qt::Alignment align = Qt::AlignCenter;
76 if (colors.count() > index) {
77 p->setPen(QPen(colors[index]));
81 if (fonts.count() > index) {
82 p->setFont(fonts[index]);
85 QFontMetricsF fm(p->font());
87 if (elementRect.height() < fm.height()) {
88 QPointF oldCenter = elementRect.center();
89 elementRect.setHeight(fm.height());
90 elementRect.moveCenter(oldCenter);
93 if (alignments.count() > index) {
94 align = alignments[index];
96 if (elementRect.width() > elementRect.height()) {
97 if (align&Qt::AlignLeft) {
98 p->drawText(elementRect.bottomLeft(), text);
100 p->drawText(elementRect, align, text);
104 QPointF rotateCenter(
105 elementRect.left() + elementRect.width() / 2,
106 elementRect.top() + elementRect.height() / 2);
107 p->translate(rotateCenter);
109 p->translate(elementRect.height() / -2,
110 elementRect.width() / -2);
111 QRectF r(0, 0, elementRect.height(), elementRect.width());
112 p->drawText(r, align, text);
118 QRectF MeterPrivate::barRect()
122 if (labels.count() > 0) {
123 elementRect = image->elementRect(
"background");
125 elementRect = QRectF(QPoint(0,0), meter->size());
128 if (image->hasElement(
"hint-bar-stretch") || !image->hasElement(
"bar-active-center")) {
132 QSize imageSize = image->size();
134 QSize tileSize = image->elementSize(
"bar-active-center");
135 image->resize(imageSize);
137 if (elementRect.width() > elementRect.height()) {
138 qreal ratio = qMax(1, tileSize.height() / tileSize.width());
139 int numTiles = qMax(qreal(1.0), qreal(elementRect.width())/(qreal(elementRect.height())/ratio));
140 tileSize = QSize(elementRect.width()/numTiles, elementRect.height());
142 QPoint center = elementRect.center().toPoint();
143 elementRect.setWidth(tileSize.width()*numTiles);
144 elementRect.moveCenter(center);
146 qreal ratio = qMax(1, tileSize.width() / tileSize.height());
147 int numTiles = qMax(qreal(1.0), qreal(elementRect.height())/(qreal(elementRect.width())/ratio));
148 tileSize = QSize(elementRect.width(), elementRect.height()/numTiles);
150 QPoint center = elementRect.center().toPoint();
151 elementRect.setHeight(tileSize.height()*numTiles);
152 elementRect.moveCenter(center);
158 void MeterPrivate::paintBackground(QPainter *p)
161 if (image->hasElement(
"background-center")) {
162 QRectF elementRect = barRect();
163 if (elementRect.isEmpty()) {
167 QSize imageSize = image->size();
170 image->setElementPrefix(
"background");
171 image->resizeFrame(elementRect.size());
172 image->paintFrame(p, elementRect.topLeft());
173 image->resize(imageSize);
175 paintBar(p,
"bar-inactive");
177 paint(p,
"background");
181 void MeterPrivate::paintBar(QPainter *p,
const QString &prefix)
183 QRectF elementRect = barRect();
185 image->setUsingRenderingCache(
false);
186 if (image->hasElement(
"hint-bar-stretch")) {
187 image->resizeFrame(elementRect.size());
188 image->paintFrame(p);
190 QSize imageSize = image->size();
192 QSize tileSize = image->elementSize(
"bar-active-center");
194 if (elementRect.width() > elementRect.height()) {
195 qreal ratio = tileSize.height() / tileSize.width();
196 int numTiles = elementRect.width()/(elementRect.height()/ratio);
197 tileSize = QSize(elementRect.width()/numTiles, elementRect.height());
199 qreal ratio = tileSize.width() / tileSize.height();
200 int numTiles = elementRect.height()/(elementRect.width()/ratio);
201 tileSize = QSize(elementRect.width(), elementRect.height()/numTiles);
204 image->setElementPrefix(prefix);
205 image->resizeFrame(tileSize);
206 p->drawTiledPixmap(elementRect, image->framePixmap());
207 image->resize(imageSize);
209 image->setUsingRenderingCache(
true);
212 void MeterPrivate::paintForeground(QPainter *p)
214 for (
int i = 0; i < labels.count(); ++i) {
218 paint(p,
"foreground");
221 void MeterPrivate::setSizePolicyAndPreferredSize()
225 meter->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
228 meter->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
232 meter->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
245 QString labelName =
"label0";
246 while (image->hasElement(labelName)) {
247 if (image->elementRect(labelName).y() > prevY) {
248 prevY = image->elementRect(labelName).y();
252 labelName = QString(
"label%0").arg(i);
257 QFontMetrics fm(font);
259 meter->setPreferredHeight((rows + 1) * fm.height());
261 meter->setPreferredSize(QSizeF(30, 30));
267 d(new MeterPrivate(this))
269 d->setSizePolicyAndPreferredSize();
271 d->animation =
new QPropertyAnimation(d,
"meterValue");
307 if (value == d->targetValue) {
311 d->targetValue = qBound(d->minimum, value, d->maximum);
312 int delta = abs(d->value - d->targetValue);
314 if (d->animation->state() != QAbstractAnimation::Running) {
315 d->animation->stop();
319 if (!(KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects) ||
320 delta / qreal(d->maximum) < 0.1) {
324 d->animation->setStartValue(d->value);
325 d->animation->setEndValue(value);
326 d->animation->start();
331 int MeterPrivate::meterValue()
const
336 void MeterPrivate::setMeterValue(
int value)
338 progressChanged(value);
343 while (d->labels.count() <= index) {
344 d->labels << QString();
346 d->labels[index] = text;
351 return d->labels[index];
356 while (d->colors.count() <= index) {
359 d->colors[index] = color;
364 return d->colors[index];
369 while (d->fonts.count() <= index) {
372 d->fonts[index] = font;
377 return d->fonts[index];
382 while (d->alignments.count() <= index) {
383 d->alignments << alignment;
385 d->alignments[index] = alignment;
390 return d->alignments[index];
395 QString elementID = QString(
"label%1").arg(index);
396 return d->image->elementRect(elementID);
403 foreach (
const QVariant &v, data) {
404 if (v.type() == QVariant::Int ||
405 v.type() == QVariant::UInt ||
406 v.type() == QVariant::LongLong ||
407 v.type() == QVariant::ULongLong) {
423 d->image->setImagePath(svg);
426 d->setSizePolicyAndPreferredSize();
427 if (d->image->hasElement(
"rotateminmax")) {
428 QRectF r = d->image->elementRect(
"rotateminmax");
429 d->minrotate = (int)r.height();
430 d->maxrotate = (int)r.width();
442 if (d->svg.isEmpty()) {
444 setSvg(
"widgets/bar_meter_horizontal");
446 setSvg(
"widgets/bar_meter_vertical");
448 setSvg(
"widgets/analog_meter");
451 d->setSizePolicyAndPreferredSize();
466 if (d->svg.isEmpty()) {
474 QRectF rect(QPointF(0, 0), size());
476 qreal percentage = 0.0;
478 QPointF rotateCenter;
479 QSize intSize = QSize((
int)size().width(), (
int)size().height());
481 if (intSize != d->image->size()) {
482 d->image->resize(intSize);
485 if (d->maximum != d->minimum) {
486 percentage = (qreal)(d->value - d->minimum) / (d->maximum - d->minimum);
489 p->setRenderHint(QPainter::SmoothPixmapTransform);
490 switch (d->meterType) {
493 d->paintBackground(p);
496 clipRect = d->barRect();
497 if (clipRect.width() > clipRect.height()) {
498 clipRect.setWidth(clipRect.width() * percentage);
500 qreal bottom = clipRect.bottom();
501 clipRect.setHeight(clipRect.height() * percentage);
502 clipRect.moveBottom(bottom);
504 p->setClipRect(clipRect, Qt::IntersectClip);
507 if (d->image->hasElement(
"bar-active-center")) {
508 d->paintBar(p,
"bar-active");
514 d->paintForeground(p);
517 d->paintBackground(p);
520 if (d->image->hasElement(
"rotatecenter")) {
521 QRectF r = d->image->elementRect(
"rotatecenter");
522 rotateCenter = QPointF(r.left() + r.width() / 2,
523 r.top() + r.height() / 2);
525 rotateCenter = QPointF(rect.width() / 2, rect.height() / 2);
527 angle = percentage * (d->maxrotate - d->minrotate) + d->minrotate;
529 if (d->image->hasElement(
"pointer-shadow")) {
531 p->translate(rotateCenter+QPoint(2,3));
533 p->translate(-1 * rotateCenter);
534 d->paint(p,
"pointer-shadow");
538 p->translate(rotateCenter);
540 p->translate(-1 * rotateCenter);
541 d->paint(p,
"pointer");
544 d->paintForeground(p);
557 #include "../private/meter_p.moc"