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 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);
216 void MeterPrivate::paintForeground(QPainter *p)
218 for (
int i = 0; i < labels.count(); ++i) {
222 paint(p,
"foreground");
225 void MeterPrivate::setSizePolicyAndPreferredSize()
229 meter->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
232 meter->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
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));
271 d(new MeterPrivate(this))
273 d->setSizePolicyAndPreferredSize();
275 d->animation =
new QPropertyAnimation(d,
"meterValue");
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();
335 int MeterPrivate::meterValue()
const
340 void MeterPrivate::setMeterValue(
int value)
342 progressChanged(value);
347 while (d->labels.count() <= index) {
348 d->labels << QString();
350 d->labels[index] = text;
355 return d->labels[index];
360 while (d->colors.count() <= index) {
363 d->colors[index] = color;
368 return d->colors[index];
373 while (d->fonts.count() <= index) {
376 d->fonts[index] = font;
381 return d->fonts[index];
386 while (d->alignments.count() <= index) {
387 d->alignments << alignment;
389 d->alignments[index] = alignment;
394 return d->alignments[index];
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) {
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();
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();
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);
555 return QGraphicsWidget::sizeHint(which, constraint);
561 #include "../private/meter_p.moc"
MeterType meterType() const
QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint=QSizeF()) const
virtual void paint(QPainter *p, const QStyleOptionGraphicsItem *option, QWidget *widget=0)
Reimplemented from Plasma::Widget.
Meter(QGraphicsItem *parent=0)
Constructor.
void setLabelAlignment(int index, const Qt::Alignment alignment)
Set text label alignment for the meter.
void setMaximum(int maximum)
Set maximum value for the meter.
void setSvg(const QString &svg)
Set svg file name.
QRectF labelRect(int index) const
void setMinimum(int minimum)
Set minimum value for the meter.
Q_INVOKABLE QFont font(FontRole role) const
Returns the font to be used by themed items.
the text color to be used by items resting on the background
Provides an SVG with borders.
QHash< QString, QVariant > Data
void setMeterType(MeterType type)
Set meter type.
QString label(int index) const
void setValue(int value)
Set value for the meter.
Qt::Alignment labelAlignment(int index) const
QFont labelFont(int index) const
void setLabel(int index, const QString &text)
Set text label for the meter.
void setLabelColor(int index, const QColor &color)
Set text label color for the meter.
Vertical bar meter (like thermometer).
Interface to the Plasma theme.
QColor labelColor(int index) const
static Theme * defaultTheme()
Singleton pattern accessor.
void valueChanged(const int &value)
This signal is sent when the value of the meter changes programmatically.
Horizontal bar meter (like thermometer).
Analog meter (like tachometer).
void setLabelFont(int index, const QFont &font)
Set text label font for the meter.
void dataUpdated(const QString &sourceName, const Plasma::DataEngine::Data &data)
Used when connecting to a DataEngine.
MeterType
Meter types enum.