libplasma
meter.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "meter.h"
00021 #include "plasma/svg.h"
00022 #include <kdebug.h>
00023 #include <QPainter>
00024
00025 namespace Plasma {
00026
00027 class MeterPrivate
00028 {
00029 public:
00030 MeterPrivate(Meter* m) :
00031 minimum(0),
00032 maximum(100),
00033 value(0),
00034 meterType(Meter::AnalogMeter),
00035 image(0),
00036 minrotate(0),
00037 maxrotate(360),
00038 meter(m) {};
00039
00040 void paint(QPainter *p, const QString& elementID)
00041 {
00042 if (image->hasElement(elementID)) {
00043 QRectF elementRect = image->elementRect(elementID);
00044 image->paint(p, elementRect.topLeft(), elementID);
00045 }
00046 }
00047
00048 void text(QPainter *p, int index)
00049 {
00050 QString elementID = QString("label%1").arg(index);
00051 QString text = labels[index];
00052
00053 if (image->hasElement(elementID)) {
00054 QRectF elementRect = image->elementRect(elementID);
00055 Qt::Alignment align = Qt::AlignCenter;
00056
00057 if (colors.count() > index) {
00058 p->setPen(QPen(colors[index]));
00059 }
00060 if (fonts.count() > index) {
00061 p->setFont(fonts[index]);
00062 }
00063 if (alignments.count() > index) {
00064 align = alignments[index];
00065 }
00066 if (elementRect.width() > elementRect.height()) {
00067 p->drawText(elementRect, align, text);
00068 } else {
00069 p->save();
00070 QPointF rotateCenter(
00071 elementRect.left() + elementRect.width() / 2,
00072 elementRect.top() + elementRect.height() / 2);
00073 p->translate(rotateCenter);
00074 p->rotate(-90);
00075 p->translate(elementRect.height() / -2,
00076 elementRect.width() / -2);
00077 QRectF r(0, 0, elementRect.height(), elementRect.width());
00078 p->drawText(r, align, text);
00079 p->restore();
00080 }
00081 }
00082 }
00083
00084 void paintBackground(QPainter *p)
00085 {
00086 paint(p, "background");
00087 p->save();
00088 }
00089
00090 void paintForeground(QPainter *p)
00091 {
00092 p->restore();
00093 for (int i = 0; i < labels.count(); ++i) {
00094 text(p, i);
00095 }
00096 paint(p, "foreground");
00097 }
00098
00099 void setSizePolicyAndPreferredSize()
00100 {
00101 switch (meterType) {
00102 case Meter::BarMeterHorizontal:
00103 meter->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
00104 break;
00105 case Meter::BarMeterVertical:
00106 meter->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
00107 break;
00108 case Meter::AnalogMeter:
00109 default:
00110 meter->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
00111 break;
00112 }
00113 if (image) {
00114 meter->setPreferredSize(image->size());
00115 } else {
00116 meter->setPreferredSize(QSizeF(30, 30));
00117 }
00118 }
00119
00120 int minimum;
00121 int maximum;
00122 int value;
00123 QStringList labels;
00124 QList<Qt::Alignment> alignments;
00125 QList<QColor> colors;
00126 QList<QFont> fonts;
00127 QString svg;
00128 Meter::MeterType meterType;
00129 Plasma::Svg *image;
00130 int minrotate;
00131 int maxrotate;
00132 Meter* meter;
00133 };
00134
00135 Meter::Meter(QGraphicsItem *parent) :
00136 QGraphicsWidget(parent),
00137 d(new MeterPrivate(this))
00138 {
00139 d->setSizePolicyAndPreferredSize();
00140 }
00141
00142 Meter::~Meter()
00143 {
00144 delete d;
00145 }
00146
00147 void Meter::setMaximum(int maximum)
00148 {
00149 d->maximum = maximum;
00150 }
00151
00152 int Meter::maximum() const
00153 {
00154 return d->maximum;
00155 }
00156
00157 void Meter::setMinimum(int minimum)
00158 {
00159 d->minimum = minimum;
00160 }
00161
00162 int Meter::minimum() const
00163 {
00164 return d->minimum;
00165 }
00166
00167 void Meter::setValue(int value)
00168 {
00169 d->value = value;
00170 update();
00171 }
00172
00173 int Meter::value() const
00174 {
00175 return d->value;
00176 }
00177
00178 void Meter::setLabel(int index, const QString &text)
00179 {
00180 while (d->labels.count() <= index) {
00181 d->labels << QString();
00182 }
00183 d->labels[index] = text;
00184 }
00185
00186 QString Meter::label(int index) const
00187 {
00188 return d->labels[index];
00189 }
00190
00191 void Meter::setLabelColor(int index, const QColor &color)
00192 {
00193 while (d->colors.count() <= index) {
00194 d->colors << color;
00195 }
00196 d->colors[index] = color;
00197 }
00198
00199 QColor Meter::labelColor(int index) const
00200 {
00201 return d->colors[index];
00202 }
00203
00204 void Meter::setLabelFont(int index, const QFont &font)
00205 {
00206 while (d->fonts.count() <= index) {
00207 d->fonts << font;
00208 }
00209 d->fonts[index] = font;
00210 }
00211
00212 QFont Meter::labelFont(int index) const
00213 {
00214 return d->fonts[index];
00215 }
00216
00217 void Meter::setLabelAlignment(int index, Qt::Alignment alignment)
00218 {
00219 while (d->alignments.count() <= index) {
00220 d->alignments << alignment;
00221 }
00222 d->alignments[index] = alignment;
00223 }
00224
00225 Qt::Alignment Meter::labelAlignment(int index) const
00226 {
00227 return d->alignments[index];
00228 }
00229
00230 void Meter::dataUpdated(const QString &sourceName, const Plasma::DataEngine::Data &data)
00231 {
00232 Q_UNUSED(sourceName)
00233
00234 foreach (const QVariant &d, data) {
00235 if (d.canConvert(QVariant::Int)) {
00236 setValue(d.toInt());
00237 return;
00238 }
00239 }
00240 }
00241
00242 void Meter::setSvg(const QString &svg)
00243 {
00244 d->svg = svg;
00245 delete d->image;
00246 d->image = new Plasma::Svg(this);
00247 d->image->setImagePath(svg);
00248
00249 d->image->resize();
00250 d->setSizePolicyAndPreferredSize();
00251 if (d->image->hasElement("rotateminmax")) {
00252 QRectF r = d->image->elementRect("rotateminmax");
00253 d->minrotate = (int)r.height();
00254 d->maxrotate = (int)r.width();
00255 }
00256 }
00257
00258 QString Meter::svg() const
00259 {
00260 return d->svg;
00261 }
00262
00263 void Meter::setMeterType(MeterType meterType)
00264 {
00265 d->meterType = meterType;
00266 if (d->svg.isEmpty()) {
00267 if (meterType == BarMeterHorizontal) {
00268 setSvg("widgets/bar_meter_horizontal");
00269 } else if (meterType == BarMeterVertical) {
00270 setSvg("widgets/bar_meter_vertical");
00271 } else if (meterType == AnalogMeter) {
00272 setSvg("widgets/analog_meter");
00273 }
00274 }
00275 d->setSizePolicyAndPreferredSize();
00276 }
00277
00278 Meter::MeterType Meter::meterType() const
00279 {
00280 return d->meterType;
00281 }
00282
00283 void Meter::paint(QPainter *p,
00284 const QStyleOptionGraphicsItem *option,
00285 QWidget *widget)
00286 {
00287 Q_UNUSED(option)
00288 Q_UNUSED(widget)
00289 QRectF rect(QPointF(0, 0), size());
00290 QRectF clipRect;
00291 qreal percentage = 0.0;
00292 qreal angle = 0.0;
00293 QPointF rotateCenter;
00294 QSize intSize = QSize((int)size().width(), (int)size().height());
00295
00296 if (intSize != d->image->size()) {
00297 d->image->resize(intSize);
00298 }
00299
00300 if (d->maximum != d->minimum) {
00301 percentage = (qreal)d->value / (d->maximum - d->minimum);
00302 }
00303 p->setRenderHint(QPainter::SmoothPixmapTransform);
00304 switch (d->meterType) {
00305 case BarMeterHorizontal:
00306 case BarMeterVertical:
00307 d->paintBackground(p);
00308
00309 clipRect = d->image->elementRect("bar");
00310 if (clipRect.width() > clipRect.height()) {
00311 clipRect.setWidth(clipRect.width() * percentage);
00312 } else {
00313 qreal bottom = clipRect.bottom();
00314 clipRect.setHeight(clipRect.height() * percentage);
00315 clipRect.moveBottom(bottom);
00316 }
00317 p->setClipRect(clipRect);
00318 d->paint(p, "bar");
00319
00320 d->paintForeground(p);
00321 break;
00322 case AnalogMeter:
00323 d->paintBackground(p);
00324
00325 if (d->image->hasElement("rotatecenter")) {
00326 QRectF r = d->image->elementRect("rotatecenter");
00327 rotateCenter = QPointF(r.left() + r.width() / 2,
00328 r.top() + r.height() / 2);
00329 } else {
00330 rotateCenter = QPointF(rect.width() / 2, rect.height() / 2);
00331 }
00332 angle = percentage * (d->maxrotate - d->minrotate) + d->minrotate;
00333
00334 p->translate(rotateCenter);
00335 p->rotate(angle);
00336 p->translate(-1 * rotateCenter);
00337 d->paint(p, "pointer");
00338
00339 d->paintForeground(p);
00340 break;
00341 }
00342 }
00343
00344 }
00345
00346 #include "meter.moc"