00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <qpainter.h>
00011 #include <qevent.h>
00012 #include <qstyle.h>
00013 #include <qpixmap.h>
00014 #include <qdrawutil.h>
00015 #include "qwt_math.h"
00016 #include "qwt_scale_engine.h"
00017 #include "qwt_scale_draw.h"
00018 #include "qwt_scale_map.h"
00019 #include "qwt_paint_buffer.h"
00020 #include "qwt_thermo.h"
00021
00022 class QwtThermo::PrivateData
00023 {
00024 public:
00025 PrivateData():
00026 fillBrush(Qt::black),
00027 alarmBrush(Qt::white),
00028 orientation(Qt::Vertical),
00029 scalePos(QwtThermo::LeftScale),
00030 borderWidth(2),
00031 scaleDist(3),
00032 thermoWidth(10),
00033 minValue(0.0),
00034 maxValue(1.0),
00035 value(0.0),
00036 alarmLevel(0.0),
00037 alarmEnabled(false)
00038 {
00039 map.setScaleInterval(minValue, maxValue);
00040 }
00041
00042 QwtScaleMap map;
00043 QRect thermoRect;
00044 QBrush fillBrush;
00045 QBrush alarmBrush;
00046
00047 Qt::Orientation orientation;
00048 ScalePos scalePos;
00049 int borderWidth;
00050 int scaleDist;
00051 int thermoWidth;
00052
00053 double minValue;
00054 double maxValue;
00055 double value;
00056 double alarmLevel;
00057 bool alarmEnabled;
00058 };
00059
00064 QwtThermo::QwtThermo(QWidget *parent):
00065 QWidget(parent)
00066 {
00067 initThermo();
00068 }
00069
00070 #if QT_VERSION < 0x040000
00071
00076 QwtThermo::QwtThermo(QWidget *parent, const char *name):
00077 QWidget(parent, name)
00078 {
00079 initThermo();
00080 }
00081 #endif
00082
00083 void QwtThermo::initThermo()
00084 {
00085 #if QT_VERSION < 0x040000
00086 setWFlags(Qt::WNoAutoErase);
00087 #endif
00088 d_data = new PrivateData;
00089 setRange(d_data->minValue, d_data->maxValue, false);
00090
00091 QSizePolicy policy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
00092 if (d_data->orientation == Qt::Vertical)
00093 policy.transpose();
00094
00095 setSizePolicy(policy);
00096
00097 #if QT_VERSION >= 0x040000
00098 setAttribute(Qt::WA_WState_OwnSizePolicy, false);
00099 #else
00100 clearWState( WState_OwnSizePolicy );
00101 #endif
00102 }
00103
00105 QwtThermo::~QwtThermo()
00106 {
00107 delete d_data;
00108 }
00109
00111 void QwtThermo::setMaxValue(double v)
00112 {
00113 setRange(d_data->minValue, v);
00114 }
00115
00117 double QwtThermo::maxValue() const
00118 {
00119 return d_data->maxValue;
00120 }
00121
00123 void QwtThermo::setMinValue(double v)
00124 {
00125 setRange(v, d_data->maxValue);
00126 }
00127
00129 double QwtThermo::minValue() const
00130 {
00131 return d_data->minValue;
00132 }
00133
00135 void QwtThermo::setValue(double v)
00136 {
00137 if (d_data->value != v)
00138 {
00139 d_data->value = v;
00140 update();
00141 }
00142 }
00143
00145 double QwtThermo::value() const
00146 {
00147 return d_data->value;
00148 }
00149
00150 void QwtThermo::setScaleDraw(QwtScaleDraw *scaleDraw)
00151 {
00152 setAbstractScaleDraw(scaleDraw);
00153 }
00154
00155 const QwtScaleDraw *QwtThermo::scaleDraw() const
00156 {
00157 return (QwtScaleDraw *)abstractScaleDraw();
00158 }
00159
00160 QwtScaleDraw *QwtThermo::scaleDraw()
00161 {
00162 return (QwtScaleDraw *)abstractScaleDraw();
00163 }
00164
00166 void QwtThermo::paintEvent(QPaintEvent *e)
00167 {
00168
00169 const QRect &ur = e->rect();
00170 if ( ur.isValid() )
00171 {
00172 #if QT_VERSION < 0x040000
00173 QwtPaintBuffer paintBuffer(this, ur);
00174 draw(paintBuffer.painter(), ur);
00175 #else
00176 QPainter painter(this);
00177 draw(&painter, ur);
00178 #endif
00179 }
00180 }
00181
00183 void QwtThermo::draw(QPainter *p, const QRect& ur)
00184 {
00185 if ( !d_data->thermoRect.contains(ur) )
00186 {
00187 if (d_data->scalePos != NoScale)
00188 {
00189 #if QT_VERSION < 0x040000
00190 scaleDraw()->draw(p, colorGroup());
00191 #else
00192 scaleDraw()->draw(p, palette());
00193 #endif
00194 }
00195
00196 qDrawShadePanel(p,
00197 d_data->thermoRect.x() - d_data->borderWidth,
00198 d_data->thermoRect.y() - d_data->borderWidth,
00199 d_data->thermoRect.width() + 2*d_data->borderWidth,
00200 d_data->thermoRect.height() + 2*d_data->borderWidth,
00201 #if QT_VERSION < 0x040000
00202 colorGroup(),
00203 #else
00204 palette(),
00205 #endif
00206 true, d_data->borderWidth,0);
00207 }
00208 drawThermo(p);
00209 }
00210
00212 void QwtThermo::resizeEvent(QResizeEvent *)
00213 {
00214 layoutThermo( false );
00215 }
00216
00223 void QwtThermo::layoutThermo( bool update_geometry )
00224 {
00225 QRect r = rect();
00226 int mbd = 0;
00227 if ( d_data->scalePos != NoScale )
00228 {
00229 int d1, d2;
00230 scaleDraw()->getBorderDistHint(font(), d1, d2);
00231 mbd = qwtMax(d1, d2);
00232 }
00233
00234 if ( d_data->orientation == Qt::Horizontal )
00235 {
00236 switch ( d_data->scalePos )
00237 {
00238 case TopScale:
00239 {
00240 d_data->thermoRect.setRect(
00241 r.x() + mbd + d_data->borderWidth,
00242 r.y() + r.height()
00243 - d_data->thermoWidth - 2*d_data->borderWidth,
00244 r.width() - 2*(d_data->borderWidth + mbd),
00245 d_data->thermoWidth);
00246 scaleDraw()->setAlignment(QwtScaleDraw::TopScale);
00247 scaleDraw()->move( d_data->thermoRect.x(),
00248 d_data->thermoRect.y() - d_data->borderWidth
00249 - d_data->scaleDist);
00250 scaleDraw()->setLength(d_data->thermoRect.width());
00251 break;
00252 }
00253
00254 case BottomScale:
00255 case NoScale:
00256 default:
00257
00258
00259 {
00260 d_data->thermoRect.setRect(
00261 r.x() + mbd + d_data->borderWidth,
00262 r.y() + d_data->borderWidth,
00263 r.width() - 2*(d_data->borderWidth + mbd),
00264 d_data->thermoWidth);
00265 scaleDraw()->setAlignment(QwtScaleDraw::BottomScale);
00266 scaleDraw()->move(
00267 d_data->thermoRect.x(),
00268 d_data->thermoRect.y() + d_data->thermoRect.height()
00269 + d_data->borderWidth + d_data->scaleDist );
00270 scaleDraw()->setLength(d_data->thermoRect.width());
00271 break;
00272 }
00273 }
00274 d_data->map.setPaintInterval(d_data->thermoRect.x(),
00275 d_data->thermoRect.x() + d_data->thermoRect.width() - 1);
00276 }
00277 else
00278 {
00279 switch ( d_data->scalePos )
00280 {
00281 case RightScale:
00282 {
00283 d_data->thermoRect.setRect(
00284 r.x() + d_data->borderWidth,
00285 r.y() + mbd + d_data->borderWidth,
00286 d_data->thermoWidth,
00287 r.height() - 2*(d_data->borderWidth + mbd));
00288 scaleDraw()->setAlignment(QwtScaleDraw::RightScale);
00289 scaleDraw()->move(
00290 d_data->thermoRect.x() + d_data->thermoRect.width()
00291 + d_data->borderWidth + d_data->scaleDist,
00292 d_data->thermoRect.y());
00293 scaleDraw()->setLength(d_data->thermoRect.height());
00294 break;
00295 }
00296
00297 case LeftScale:
00298 case NoScale:
00299 default:
00300
00301
00302 {
00303 d_data->thermoRect.setRect(
00304 r.x() + r.width() - 2*d_data->borderWidth - d_data->thermoWidth,
00305 r.y() + mbd + d_data->borderWidth,
00306 d_data->thermoWidth,
00307 r.height() - 2*(d_data->borderWidth + mbd));
00308 scaleDraw()->setAlignment(QwtScaleDraw::LeftScale);
00309 scaleDraw()->move(
00310 d_data->thermoRect.x() - d_data->scaleDist
00311 - d_data->borderWidth,
00312 d_data->thermoRect.y() );
00313 scaleDraw()->setLength(d_data->thermoRect.height());
00314 break;
00315 }
00316 }
00317 d_data->map.setPaintInterval(
00318 d_data->thermoRect.y() + d_data->thermoRect.height() - 1,
00319 d_data->thermoRect.y());
00320 }
00321 if ( update_geometry )
00322 {
00323 updateGeometry();
00324 update();
00325 }
00326 }
00327
00346 void QwtThermo::setOrientation(Qt::Orientation o, ScalePos s)
00347 {
00348 if ( o == d_data->orientation && s == d_data->scalePos )
00349 return;
00350
00351 switch(o)
00352 {
00353 case Qt::Horizontal:
00354 {
00355 if ((s == NoScale) || (s == BottomScale) || (s == TopScale))
00356 d_data->scalePos = s;
00357 else
00358 d_data->scalePos = NoScale;
00359 break;
00360 }
00361 case Qt::Vertical:
00362 {
00363 if ((s == NoScale) || (s == LeftScale) || (s == RightScale))
00364 d_data->scalePos = s;
00365 else
00366 d_data->scalePos = NoScale;
00367 break;
00368 }
00369 }
00370
00371 if ( o != d_data->orientation )
00372 {
00373 #if QT_VERSION >= 0x040000
00374 if ( !testAttribute(Qt::WA_WState_OwnSizePolicy) )
00375 #else
00376 if ( !testWState( WState_OwnSizePolicy ) )
00377 #endif
00378 {
00379 QSizePolicy sp = sizePolicy();
00380 sp.transpose();
00381 setSizePolicy(sp);
00382
00383 #if QT_VERSION >= 0x040000
00384 setAttribute(Qt::WA_WState_OwnSizePolicy, false);
00385 #else
00386 clearWState( WState_OwnSizePolicy );
00387 #endif
00388 }
00389 }
00390
00391 d_data->orientation = o;
00392 layoutThermo();
00393 }
00394
00409 void QwtThermo::setScalePosition(ScalePos s)
00410 {
00411 if ((s == BottomScale) || (s == TopScale))
00412 setOrientation(Qt::Horizontal, s);
00413 else if ((s == LeftScale) || (s == RightScale))
00414 setOrientation(Qt::Vertical, s);
00415 else
00416 setOrientation(d_data->orientation, NoScale);
00417 }
00418
00420 QwtThermo::ScalePos QwtThermo::scalePosition() const
00421 {
00422 return d_data->scalePos;
00423 }
00424
00426 void QwtThermo::fontChange(const QFont &f)
00427 {
00428 QWidget::fontChange( f );
00429 layoutThermo();
00430 }
00431
00433 void QwtThermo::scaleChange()
00434 {
00435 update();
00436 layoutThermo();
00437 }
00438
00440 void QwtThermo::drawThermo(QPainter *p)
00441 {
00442 int alarm = 0, taval = 0;
00443
00444 QRect fRect;
00445 QRect aRect;
00446 QRect bRect;
00447
00448 int inverted = ( d_data->maxValue < d_data->minValue );
00449
00450
00451
00452
00453
00454
00455 if (d_data->alarmEnabled)
00456 {
00457 if (inverted)
00458 {
00459 alarm = ((d_data->alarmLevel >= d_data->maxValue)
00460 && (d_data->alarmLevel <= d_data->minValue)
00461 && (d_data->value >= d_data->alarmLevel));
00462
00463 }
00464 else
00465 {
00466 alarm = (( d_data->alarmLevel >= d_data->minValue)
00467 && (d_data->alarmLevel <= d_data->maxValue)
00468 && (d_data->value >= d_data->alarmLevel));
00469 }
00470 }
00471
00472
00473
00474
00475 int tval = transform(d_data->value);
00476
00477 if (alarm)
00478 taval = transform(d_data->alarmLevel);
00479
00480
00481
00482
00483 if ( d_data->orientation == Qt::Horizontal )
00484 {
00485 if (inverted)
00486 {
00487 bRect.setRect(d_data->thermoRect.x(), d_data->thermoRect.y(),
00488 tval - d_data->thermoRect.x(),
00489 d_data->thermoRect.height());
00490
00491 if (alarm)
00492 {
00493 aRect.setRect(tval, d_data->thermoRect.y(),
00494 taval - tval + 1,
00495 d_data->thermoRect.height());
00496 fRect.setRect(taval + 1, d_data->thermoRect.y(),
00497 d_data->thermoRect.x() + d_data->thermoRect.width() - (taval + 1),
00498 d_data->thermoRect.height());
00499 }
00500 else
00501 {
00502 fRect.setRect(tval, d_data->thermoRect.y(),
00503 d_data->thermoRect.x() + d_data->thermoRect.width() - tval,
00504 d_data->thermoRect.height());
00505 }
00506 }
00507 else
00508 {
00509 bRect.setRect(tval + 1, d_data->thermoRect.y(),
00510 d_data->thermoRect.width() - (tval + 1 - d_data->thermoRect.x()),
00511 d_data->thermoRect.height());
00512
00513 if (alarm)
00514 {
00515 aRect.setRect(taval, d_data->thermoRect.y(),
00516 tval - taval + 1,
00517 d_data->thermoRect.height());
00518 fRect.setRect(d_data->thermoRect.x(), d_data->thermoRect.y(),
00519 taval - d_data->thermoRect.x(),
00520 d_data->thermoRect.height());
00521 }
00522 else
00523 {
00524 fRect.setRect(d_data->thermoRect.x(), d_data->thermoRect.y(),
00525 tval - d_data->thermoRect.x() + 1,
00526 d_data->thermoRect.height());
00527 }
00528
00529 }
00530 }
00531 else
00532 {
00533 if (tval < d_data->thermoRect.y())
00534 tval = d_data->thermoRect.y();
00535 else
00536 {
00537 if (tval > d_data->thermoRect.y() + d_data->thermoRect.height())
00538 tval = d_data->thermoRect.y() + d_data->thermoRect.height();
00539 }
00540
00541 if (inverted)
00542 {
00543 bRect.setRect(d_data->thermoRect.x(), tval + 1,
00544 d_data->thermoRect.width(),
00545 d_data->thermoRect.height() - (tval + 1 - d_data->thermoRect.y()));
00546
00547 if (alarm)
00548 {
00549 aRect.setRect(d_data->thermoRect.x(), taval,
00550 d_data->thermoRect.width(),
00551 tval - taval + 1);
00552 fRect.setRect(d_data->thermoRect.x(), d_data->thermoRect.y(),
00553 d_data->thermoRect.width(),
00554 taval - d_data->thermoRect.y());
00555 }
00556 else
00557 {
00558 fRect.setRect(d_data->thermoRect.x(), d_data->thermoRect.y(),
00559 d_data->thermoRect.width(),
00560 tval - d_data->thermoRect.y() + 1);
00561 }
00562 }
00563 else
00564 {
00565 bRect.setRect(d_data->thermoRect.x(), d_data->thermoRect.y(),
00566 d_data->thermoRect.width(),
00567 tval - d_data->thermoRect.y());
00568 if (alarm)
00569 {
00570 aRect.setRect(d_data->thermoRect.x(),tval,
00571 d_data->thermoRect.width(),
00572 taval - tval + 1);
00573 fRect.setRect(d_data->thermoRect.x(),taval + 1,
00574 d_data->thermoRect.width(),
00575 d_data->thermoRect.y() + d_data->thermoRect.height() - (taval + 1));
00576 }
00577 else
00578 {
00579 fRect.setRect(d_data->thermoRect.x(),tval,
00580 d_data->thermoRect.width(),
00581 d_data->thermoRect.y() + d_data->thermoRect.height() - tval);
00582 }
00583 }
00584 }
00585
00586
00587
00588
00589 const QColor bgColor =
00590 #if QT_VERSION < 0x040000
00591 colorGroup().color(QColorGroup::Background);
00592 #else
00593 palette().color(QPalette::Background);
00594 #endif
00595 p->fillRect(bRect, bgColor);
00596
00597 if (alarm)
00598 p->fillRect(aRect, d_data->alarmBrush);
00599
00600 p->fillRect(fRect, d_data->fillBrush);
00601 }
00602
00604 void QwtThermo::setBorderWidth(int w)
00605 {
00606 if ((w >= 0) && (w < (qwtMin(d_data->thermoRect.width(),
00607 d_data->thermoRect.height()) + d_data->borderWidth) / 2 - 1))
00608 {
00609 d_data->borderWidth = w;
00610 layoutThermo();
00611 }
00612 }
00613
00615 int QwtThermo::borderWidth() const
00616 {
00617 return d_data->borderWidth;
00618 }
00619
00626 void QwtThermo::setRange(double vmin, double vmax, bool logarithmic)
00627 {
00628 d_data->minValue = vmin;
00629 d_data->maxValue = vmax;
00630
00631 if ( logarithmic )
00632 setScaleEngine(new QwtLog10ScaleEngine);
00633 else
00634 setScaleEngine(new QwtLinearScaleEngine);
00635
00636
00637
00638
00639
00640
00641
00642 d_data->map.setTransformation(scaleEngine()->transformation());
00643 d_data->map.setScaleInterval(d_data->minValue, d_data->maxValue);
00644
00645 if (autoScale())
00646 rescale(d_data->minValue, d_data->maxValue);
00647
00648 layoutThermo();
00649 }
00650
00655 void QwtThermo::setFillBrush(const QBrush& brush)
00656 {
00657 d_data->fillBrush = brush;
00658 update();
00659 }
00660
00662 const QBrush& QwtThermo::fillBrush() const
00663 {
00664 return d_data->fillBrush;
00665 }
00666
00671 void QwtThermo::setFillColor(const QColor &c)
00672 {
00673 d_data->fillBrush.setColor(c);
00674 update();
00675 }
00676
00678 const QColor &QwtThermo::fillColor() const
00679 {
00680 return d_data->fillBrush.color();
00681 }
00682
00687 void QwtThermo::setAlarmBrush(const QBrush& brush)
00688 {
00689 d_data->alarmBrush = brush;
00690 update();
00691 }
00692
00694 const QBrush& QwtThermo::alarmBrush() const
00695 {
00696 return d_data->alarmBrush;
00697 }
00698
00703 void QwtThermo::setAlarmColor(const QColor &c)
00704 {
00705 d_data->alarmBrush.setColor(c);
00706 update();
00707 }
00708
00710 const QColor &QwtThermo::alarmColor() const
00711 {
00712 return d_data->alarmBrush.color();
00713 }
00714
00716 void QwtThermo::setAlarmLevel(double v)
00717 {
00718 d_data->alarmLevel = v;
00719 d_data->alarmEnabled = 1;
00720 update();
00721 }
00722
00724 double QwtThermo::alarmLevel() const
00725 {
00726 return d_data->alarmLevel;
00727 }
00728
00730 void QwtThermo::setPipeWidth(int w)
00731 {
00732 if (w > 0)
00733 {
00734 d_data->thermoWidth = w;
00735 layoutThermo();
00736 }
00737 }
00738
00740 int QwtThermo::pipeWidth() const
00741 {
00742 return d_data->thermoWidth;
00743 }
00744
00745
00760 void QwtThermo::setMargin(int)
00761 {
00762 }
00763
00764
00769 void QwtThermo::setAlarmEnabled(bool tf)
00770 {
00771 d_data->alarmEnabled = tf;
00772 update();
00773 }
00774
00776 bool QwtThermo::alarmEnabled() const
00777 {
00778 return d_data->alarmEnabled;
00779 }
00780
00785 QSize QwtThermo::sizeHint() const
00786 {
00787 return minimumSizeHint();
00788 }
00789
00795 QSize QwtThermo::minimumSizeHint() const
00796 {
00797 int w = 0, h = 0;
00798
00799 if ( d_data->scalePos != NoScale )
00800 {
00801 const int sdExtent = scaleDraw()->extent( QPen(), font() );
00802 const int sdLength = scaleDraw()->minLength( QPen(), font() );
00803
00804 w = sdLength;
00805 h = d_data->thermoWidth + sdExtent +
00806 d_data->borderWidth + d_data->scaleDist;
00807
00808 }
00809 else
00810 {
00811 w = 200;
00812 h = d_data->thermoWidth;
00813 }
00814
00815 if ( d_data->orientation == Qt::Vertical )
00816 qSwap(w, h);
00817
00818 w += 2 * d_data->borderWidth;
00819 h += 2 * d_data->borderWidth;
00820
00821 return QSize( w, h );
00822 }
00823
00824 int QwtThermo::transform(double value) const
00825 {
00826 const double min = qwtMin(d_data->map.s1(), d_data->map.s2());
00827 const double max = qwtMax(d_data->map.s1(), d_data->map.s2());
00828
00829 if ( value > max )
00830 value = max;
00831 if ( value < min )
00832 value = min;
00833
00834 return d_data->map.transform(value);
00835 }