21#include "private/meter_p.h"
27#include <QPropertyAnimation>
30#include <kglobalsettings.h>
38MeterPrivate::MeterPrivate(Meter *m)
44 meterType(Meter::AnalogMeter),
52void MeterPrivate::progressChanged(
int progress)
58void MeterPrivate::paint(QPainter *p,
const QString &elementID)
60 if (image->hasElement(elementID)) {
61 QRectF elementRect = image->elementRect(elementID);
62 image->paint(p, elementRect, elementID);
66void 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);
118QRectF 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);
158void 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");
181void MeterPrivate::paintBar(QPainter *p,
const QString &prefix)
183 QRectF elementRect = barRect();
185 image->setUsingRenderingCache(
false);
186 if (image->hasElement(
"hint-bar-stretch")) {
187 const QSize imageSize = image->size();
189 image->setElementPrefix(prefix);
190 image->resizeFrame(elementRect.size());
191 image->paintFrame(p, elementRect.topLeft());
192 image->resize(imageSize);
194 const QSize imageSize = image->size();
196 QSize tileSize = image->elementSize(
"bar-active-center");
198 if (elementRect.width() > elementRect.height()) {
199 qreal ratio = tileSize.height() / tileSize.width();
200 int numTiles = elementRect.width()/(elementRect.height()/ratio);
201 tileSize = QSize(elementRect.width()/numTiles, elementRect.height());
203 qreal ratio = tileSize.width() / tileSize.height();
204 int numTiles = elementRect.height()/(elementRect.width()/ratio);
205 tileSize = QSize(elementRect.width(), elementRect.height()/numTiles);
208 image->setElementPrefix(prefix);
209 image->resizeFrame(tileSize);
210 p->drawTiledPixmap(elementRect, image->framePixmap());
211 image->resize(imageSize);
213 image->setUsingRenderingCache(
true);
216void MeterPrivate::paintForeground(QPainter *p)
218 for (
int i = 0; i < labels.count(); ++i) {
222 paint(p,
"foreground");
225void MeterPrivate::setSizePolicyAndPreferredSize()
228 case Meter::BarMeterHorizontal:
229 meter->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
231 case Meter::BarMeterVertical:
232 meter->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
234 case Meter::AnalogMeter:
236 meter->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
249 QString labelName =
"label0";
250 while (image->hasElement(labelName)) {
251 if (image->elementRect(labelName).y() > prevY) {
252 prevY = image->elementRect(labelName).y();
256 labelName = QString(
"label%0").arg(i);
261 QFontMetrics fm(font);
263 meter->setPreferredHeight((rows + 1) * fm.height());
265 meter->setPreferredSize(QSizeF(30, 30));
269Meter::Meter(QGraphicsItem *parent) :
271 d(new MeterPrivate(this))
273 d->setSizePolicyAndPreferredSize();
275 d->animation =
new QPropertyAnimation(d,
"meterValue");
284void Meter::setMaximum(
int maximum)
289int Meter::maximum()
const
294void Meter::setMinimum(
int minimum)
299int Meter::minimum()
const
304int Meter::value()
const
309void Meter::setValue(
int value)
311 if (
value == d->targetValue) {
315 d->targetValue = qBound(d->minimum,
value, d->maximum);
316 int delta = abs(d->value - d->targetValue);
318 if (d->animation->state() != QAbstractAnimation::Running) {
319 d->animation->stop();
323 if (!(KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects) ||
324 delta / qreal(d->maximum) < 0.1) {
328 d->animation->setStartValue(d->value);
329 d->animation->setEndValue(
value);
330 d->animation->start();
335int MeterPrivate::meterValue()
const
340void MeterPrivate::setMeterValue(
int value)
342 progressChanged(value);
345void Meter::setLabel(
int index,
const QString &text)
347 while (d->labels.count() <= index) {
348 d->labels << QString();
350 d->labels[index] = text;
353QString Meter::label(
int index)
const
355 return d->labels[index];
358void Meter::setLabelColor(
int index,
const QColor &color)
360 while (d->colors.count() <= index) {
363 d->colors[index] = color;
366QColor Meter::labelColor(
int index)
const
368 return d->colors[index];
371void Meter::setLabelFont(
int index,
const QFont &font)
373 while (d->fonts.count() <= index) {
376 d->fonts[index] = font;
379QFont Meter::labelFont(
int index)
const
381 return d->fonts[index];
384void Meter::setLabelAlignment(
int index,
const Qt::Alignment alignment)
386 while (d->alignments.count() <= index) {
387 d->alignments << alignment;
389 d->alignments[index] = alignment;
392Qt::Alignment Meter::labelAlignment(
int index)
const
394 return d->alignments[index];
397QRectF Meter::labelRect(
int index)
const
399 QString elementID = QString(
"label%1").arg(index);
400 return d->image->elementRect(elementID);
407 foreach (
const QVariant &v, data) {
408 if (v.type() == QVariant::Int ||
409 v.type() == QVariant::UInt ||
410 v.type() == QVariant::LongLong ||
411 v.type() == QVariant::ULongLong) {
418void Meter::setSvg(
const QString &svg)
427 d->image->setImagePath(
svg);
430 d->setSizePolicyAndPreferredSize();
431 if (d->image->hasElement(
"rotateminmax")) {
432 QRectF r = d->image->elementRect(
"rotateminmax");
433 d->minrotate = (int)r.height();
434 d->maxrotate = (int)r.width();
438QString Meter::svg()
const
446 if (d->svg.isEmpty()) {
448 setSvg(
"widgets/bar_meter_horizontal");
450 setSvg(
"widgets/bar_meter_vertical");
452 setSvg(
"widgets/analog_meter");
455 d->setSizePolicyAndPreferredSize();
463void Meter::paint(QPainter *p,
470 if (d->svg.isEmpty()) {
478 QRectF rect(QPointF(0, 0), size());
480 qreal percentage = 0.0;
482 QPointF rotateCenter;
483 QSize intSize = QSize((
int)size().width(), (
int)size().height());
485 if (intSize != d->image->size()) {
486 d->image->resize(intSize);
489 if (d->maximum != d->minimum) {
490 percentage = (qreal)(d->value - d->minimum) / (d->maximum - d->minimum);
493 p->setRenderHint(QPainter::SmoothPixmapTransform);
494 switch (d->meterType) {
497 d->paintBackground(p);
500 clipRect = d->barRect();
501 if (clipRect.width() > clipRect.height()) {
502 clipRect.setWidth(clipRect.width() * percentage);
504 qreal bottom = clipRect.bottom();
505 clipRect.setHeight(clipRect.height() * percentage);
506 clipRect.moveBottom(bottom);
508 p->setClipRect(clipRect, Qt::IntersectClip);
511 if (d->image->hasElement(
"bar-active-center")) {
512 d->paintBar(p,
"bar-active");
518 d->paintForeground(p);
521 d->paintBackground(p);
524 if (d->image->hasElement(
"rotatecenter")) {
525 QRectF r = d->image->elementRect(
"rotatecenter");
526 rotateCenter = QPointF(r.left() + r.width() / 2,
527 r.top() + r.height() / 2);
529 rotateCenter = QPointF(rect.width() / 2, rect.height() / 2);
531 angle = percentage * (d->maxrotate - d->minrotate) + d->minrotate;
533 if (d->image->hasElement(
"pointer-shadow")) {
535 p->translate(rotateCenter+QPoint(2,3));
537 p->translate(-1 * rotateCenter);
538 d->paint(p,
"pointer-shadow");
542 p->translate(rotateCenter);
544 p->translate(-1 * rotateCenter);
545 d->paint(p,
"pointer");
548 d->paintForeground(p);
553QSizeF Meter::sizeHint(Qt::SizeHint which,
const QSizeF &constraint)
const
555 return QGraphicsWidget::sizeHint(which, constraint);
561#include "../private/meter_p.moc"
QHash< QString, QVariant > Data
Provides an SVG with borders.
void setValue(int value)
Set value for the meter.
void setSvg(const QString &svg)
Set svg file name.
void valueChanged(const int &value)
This signal is sent when the value of the meter changes programmatically.
MeterType
Meter types enum.
@ BarMeterHorizontal
Horizontal bar meter (like thermometer).
@ BarMeterVertical
Vertical bar meter (like thermometer).
@ AnalogMeter
Analog meter (like tachometer).
void setMeterType(MeterType type)
Set meter type.
Interface to the Plasma theme.
Q_INVOKABLE QFont font(FontRole role) const
Returns the font to be used by themed items.
@ DefaultFont
The standard text font.
static Theme * defaultTheme()
Singleton pattern accessor.
@ TextColor
the text color to be used by items resting on the background
Namespace for everything in libplasma.