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
00161 void QwtThermo::setScaleDraw(QwtScaleDraw *scaleDraw)
00162 {
00163 setAbstractScaleDraw(scaleDraw);
00164 }
00165
00170 const QwtScaleDraw *QwtThermo::scaleDraw() const
00171 {
00172 return (QwtScaleDraw *)abstractScaleDraw();
00173 }
00174
00179 QwtScaleDraw *QwtThermo::scaleDraw()
00180 {
00181 return (QwtScaleDraw *)abstractScaleDraw();
00182 }
00183
00185 void QwtThermo::paintEvent(QPaintEvent *e)
00186 {
00187
00188 const QRect &ur = e->rect();
00189 if ( ur.isValid() )
00190 {
00191 #if QT_VERSION < 0x040000
00192 QwtPaintBuffer paintBuffer(this, ur);
00193 draw(paintBuffer.painter(), ur);
00194 #else
00195 QPainter painter(this);
00196 draw(&painter, ur);
00197 #endif
00198 }
00199 }
00200
00202 void QwtThermo::draw(QPainter *p, const QRect& ur)
00203 {
00204 if ( !d_data->thermoRect.contains(ur) )
00205 {
00206 if (d_data->scalePos != NoScale)
00207 {
00208 #if QT_VERSION < 0x040000
00209 scaleDraw()->draw(p, colorGroup());
00210 #else
00211 scaleDraw()->draw(p, palette());
00212 #endif
00213 }
00214
00215 qDrawShadePanel(p,
00216 d_data->thermoRect.x() - d_data->borderWidth,
00217 d_data->thermoRect.y() - d_data->borderWidth,
00218 d_data->thermoRect.width() + 2*d_data->borderWidth,
00219 d_data->thermoRect.height() + 2*d_data->borderWidth,
00220 #if QT_VERSION < 0x040000
00221 colorGroup(),
00222 #else
00223 palette(),
00224 #endif
00225 true, d_data->borderWidth,0);
00226 }
00227 drawThermo(p);
00228 }
00229
00231 void QwtThermo::resizeEvent(QResizeEvent *)
00232 {
00233 layoutThermo( false );
00234 }
00235
00242 void QwtThermo::layoutThermo( bool update_geometry )
00243 {
00244 QRect r = rect();
00245 int mbd = 0;
00246 if ( d_data->scalePos != NoScale )
00247 {
00248 int d1, d2;
00249 scaleDraw()->getBorderDistHint(font(), d1, d2);
00250 mbd = qwtMax(d1, d2);
00251 }
00252
00253 if ( d_data->orientation == Qt::Horizontal )
00254 {
00255 switch ( d_data->scalePos )
00256 {
00257 case TopScale:
00258 {
00259 d_data->thermoRect.setRect(
00260 r.x() + mbd + d_data->borderWidth,
00261 r.y() + r.height()
00262 - d_data->thermoWidth - 2*d_data->borderWidth,
00263 r.width() - 2*(d_data->borderWidth + mbd),
00264 d_data->thermoWidth);
00265 scaleDraw()->setAlignment(QwtScaleDraw::TopScale);
00266 scaleDraw()->move( d_data->thermoRect.x(),
00267 d_data->thermoRect.y() - d_data->borderWidth
00268 - d_data->scaleDist);
00269 scaleDraw()->setLength(d_data->thermoRect.width());
00270 break;
00271 }
00272
00273 case BottomScale:
00274 case NoScale:
00275 default:
00276
00277
00278 {
00279 d_data->thermoRect.setRect(
00280 r.x() + mbd + d_data->borderWidth,
00281 r.y() + d_data->borderWidth,
00282 r.width() - 2*(d_data->borderWidth + mbd),
00283 d_data->thermoWidth);
00284 scaleDraw()->setAlignment(QwtScaleDraw::BottomScale);
00285 scaleDraw()->move(
00286 d_data->thermoRect.x(),
00287 d_data->thermoRect.y() + d_data->thermoRect.height()
00288 + d_data->borderWidth + d_data->scaleDist );
00289 scaleDraw()->setLength(d_data->thermoRect.width());
00290 break;
00291 }
00292 }
00293 d_data->map.setPaintInterval(d_data->thermoRect.x(),
00294 d_data->thermoRect.x() + d_data->thermoRect.width() - 1);
00295 }
00296 else
00297 {
00298 switch ( d_data->scalePos )
00299 {
00300 case RightScale:
00301 {
00302 d_data->thermoRect.setRect(
00303 r.x() + d_data->borderWidth,
00304 r.y() + mbd + d_data->borderWidth,
00305 d_data->thermoWidth,
00306 r.height() - 2*(d_data->borderWidth + mbd));
00307 scaleDraw()->setAlignment(QwtScaleDraw::RightScale);
00308 scaleDraw()->move(
00309 d_data->thermoRect.x() + d_data->thermoRect.width()
00310 + d_data->borderWidth + d_data->scaleDist,
00311 d_data->thermoRect.y());
00312 scaleDraw()->setLength(d_data->thermoRect.height());
00313 break;
00314 }
00315
00316 case LeftScale:
00317 case NoScale:
00318 default:
00319
00320
00321 {
00322 d_data->thermoRect.setRect(
00323 r.x() + r.width() - 2*d_data->borderWidth - d_data->thermoWidth,
00324 r.y() + mbd + d_data->borderWidth,
00325 d_data->thermoWidth,
00326 r.height() - 2*(d_data->borderWidth + mbd));
00327 scaleDraw()->setAlignment(QwtScaleDraw::LeftScale);
00328 scaleDraw()->move(
00329 d_data->thermoRect.x() - d_data->scaleDist
00330 - d_data->borderWidth,
00331 d_data->thermoRect.y() );
00332 scaleDraw()->setLength(d_data->thermoRect.height());
00333 break;
00334 }
00335 }
00336 d_data->map.setPaintInterval(
00337 d_data->thermoRect.y() + d_data->thermoRect.height() - 1,
00338 d_data->thermoRect.y());
00339 }
00340 if ( update_geometry )
00341 {
00342 updateGeometry();
00343 update();
00344 }
00345 }
00346
00365 void QwtThermo::setOrientation(Qt::Orientation o, ScalePos s)
00366 {
00367 if ( o == d_data->orientation && s == d_data->scalePos )
00368 return;
00369
00370 switch(o)
00371 {
00372 case Qt::Horizontal:
00373 {
00374 if ((s == NoScale) || (s == BottomScale) || (s == TopScale))
00375 d_data->scalePos = s;
00376 else
00377 d_data->scalePos = NoScale;
00378 break;
00379 }
00380 case Qt::Vertical:
00381 {
00382 if ((s == NoScale) || (s == LeftScale) || (s == RightScale))
00383 d_data->scalePos = s;
00384 else
00385 d_data->scalePos = NoScale;
00386 break;
00387 }
00388 }
00389
00390 if ( o != d_data->orientation )
00391 {
00392 #if QT_VERSION >= 0x040000
00393 if ( !testAttribute(Qt::WA_WState_OwnSizePolicy) )
00394 #else
00395 if ( !testWState( WState_OwnSizePolicy ) )
00396 #endif
00397 {
00398 QSizePolicy sp = sizePolicy();
00399 sp.transpose();
00400 setSizePolicy(sp);
00401
00402 #if QT_VERSION >= 0x040000
00403 setAttribute(Qt::WA_WState_OwnSizePolicy, false);
00404 #else
00405 clearWState( WState_OwnSizePolicy );
00406 #endif
00407 }
00408 }
00409
00410 d_data->orientation = o;
00411 layoutThermo();
00412 }
00413
00428 void QwtThermo::setScalePosition(ScalePos s)
00429 {
00430 if ((s == BottomScale) || (s == TopScale))
00431 setOrientation(Qt::Horizontal, s);
00432 else if ((s == LeftScale) || (s == RightScale))
00433 setOrientation(Qt::Vertical, s);
00434 else
00435 setOrientation(d_data->orientation, NoScale);
00436 }
00437
00439 QwtThermo::ScalePos QwtThermo::scalePosition() const
00440 {
00441 return d_data->scalePos;
00442 }
00443
00445 void QwtThermo::fontChange(const QFont &f)
00446 {
00447 QWidget::fontChange( f );
00448 layoutThermo();
00449 }
00450
00452 void QwtThermo::scaleChange()
00453 {
00454 update();
00455 layoutThermo();
00456 }
00457
00459 void QwtThermo::drawThermo(QPainter *p)
00460 {
00461 int alarm = 0, taval = 0;
00462
00463 QRect fRect;
00464 QRect aRect;
00465 QRect bRect;
00466
00467 int inverted = ( d_data->maxValue < d_data->minValue );
00468
00469
00470
00471
00472
00473
00474 if (d_data->alarmEnabled)
00475 {
00476 if (inverted)
00477 {
00478 alarm = ((d_data->alarmLevel >= d_data->maxValue)
00479 && (d_data->alarmLevel <= d_data->minValue)
00480 && (d_data->value >= d_data->alarmLevel));
00481
00482 }
00483 else
00484 {
00485 alarm = (( d_data->alarmLevel >= d_data->minValue)
00486 && (d_data->alarmLevel <= d_data->maxValue)
00487 && (d_data->value >= d_data->alarmLevel));
00488 }
00489 }
00490
00491
00492
00493
00494 int tval = transform(d_data->value);
00495
00496 if (alarm)
00497 taval = transform(d_data->alarmLevel);
00498
00499
00500
00501
00502 if ( d_data->orientation == Qt::Horizontal )
00503 {
00504 if (inverted)
00505 {
00506 bRect.setRect(d_data->thermoRect.x(), d_data->thermoRect.y(),
00507 tval - d_data->thermoRect.x(),
00508 d_data->thermoRect.height());
00509
00510 if (alarm)
00511 {
00512 aRect.setRect(tval, d_data->thermoRect.y(),
00513 taval - tval + 1,
00514 d_data->thermoRect.height());
00515 fRect.setRect(taval + 1, d_data->thermoRect.y(),
00516 d_data->thermoRect.x() + d_data->thermoRect.width() - (taval + 1),
00517 d_data->thermoRect.height());
00518 }
00519 else
00520 {
00521 fRect.setRect(tval, d_data->thermoRect.y(),
00522 d_data->thermoRect.x() + d_data->thermoRect.width() - tval,
00523 d_data->thermoRect.height());
00524 }
00525 }
00526 else
00527 {
00528 bRect.setRect(tval + 1, d_data->thermoRect.y(),
00529 d_data->thermoRect.width() - (tval + 1 - d_data->thermoRect.x()),
00530 d_data->thermoRect.height());
00531
00532 if (alarm)
00533 {
00534 aRect.setRect(taval, d_data->thermoRect.y(),
00535 tval - taval + 1,
00536 d_data->thermoRect.height());
00537 fRect.setRect(d_data->thermoRect.x(), d_data->thermoRect.y(),
00538 taval - d_data->thermoRect.x(),
00539 d_data->thermoRect.height());
00540 }
00541 else
00542 {
00543 fRect.setRect(d_data->thermoRect.x(), d_data->thermoRect.y(),
00544 tval - d_data->thermoRect.x() + 1,
00545 d_data->thermoRect.height());
00546 }
00547
00548 }
00549 }
00550 else
00551 {
00552 if (tval < d_data->thermoRect.y())
00553 tval = d_data->thermoRect.y();
00554 else
00555 {
00556 if (tval > d_data->thermoRect.y() + d_data->thermoRect.height())
00557 tval = d_data->thermoRect.y() + d_data->thermoRect.height();
00558 }
00559
00560 if (inverted)
00561 {
00562 bRect.setRect(d_data->thermoRect.x(), tval + 1,
00563 d_data->thermoRect.width(),
00564 d_data->thermoRect.height() - (tval + 1 - d_data->thermoRect.y()));
00565
00566 if (alarm)
00567 {
00568 aRect.setRect(d_data->thermoRect.x(), taval,
00569 d_data->thermoRect.width(),
00570 tval - taval + 1);
00571 fRect.setRect(d_data->thermoRect.x(), d_data->thermoRect.y(),
00572 d_data->thermoRect.width(),
00573 taval - d_data->thermoRect.y());
00574 }
00575 else
00576 {
00577 fRect.setRect(d_data->thermoRect.x(), d_data->thermoRect.y(),
00578 d_data->thermoRect.width(),
00579 tval - d_data->thermoRect.y() + 1);
00580 }
00581 }
00582 else
00583 {
00584 bRect.setRect(d_data->thermoRect.x(), d_data->thermoRect.y(),
00585 d_data->thermoRect.width(),
00586 tval - d_data->thermoRect.y());
00587 if (alarm)
00588 {
00589 aRect.setRect(d_data->thermoRect.x(),tval,
00590 d_data->thermoRect.width(),
00591 taval - tval + 1);
00592 fRect.setRect(d_data->thermoRect.x(),taval + 1,
00593 d_data->thermoRect.width(),
00594 d_data->thermoRect.y() + d_data->thermoRect.height() - (taval + 1));
00595 }
00596 else
00597 {
00598 fRect.setRect(d_data->thermoRect.x(),tval,
00599 d_data->thermoRect.width(),
00600 d_data->thermoRect.y() + d_data->thermoRect.height() - tval);
00601 }
00602 }
00603 }
00604
00605
00606
00607
00608 const QColor bgColor =
00609 #if QT_VERSION < 0x040000
00610 colorGroup().color(QColorGroup::Background);
00611 #else
00612 palette().color(QPalette::Background);
00613 #endif
00614 p->fillRect(bRect, bgColor);
00615
00616 if (alarm)
00617 p->fillRect(aRect, d_data->alarmBrush);
00618
00619 p->fillRect(fRect, d_data->fillBrush);
00620 }
00621
00623 void QwtThermo::setBorderWidth(int w)
00624 {
00625 if ((w >= 0) && (w < (qwtMin(d_data->thermoRect.width(),
00626 d_data->thermoRect.height()) + d_data->borderWidth) / 2 - 1))
00627 {
00628 d_data->borderWidth = w;
00629 layoutThermo();
00630 }
00631 }
00632
00634 int QwtThermo::borderWidth() const
00635 {
00636 return d_data->borderWidth;
00637 }
00638
00645 void QwtThermo::setRange(double vmin, double vmax, bool logarithmic)
00646 {
00647 d_data->minValue = vmin;
00648 d_data->maxValue = vmax;
00649
00650 if ( logarithmic )
00651 setScaleEngine(new QwtLog10ScaleEngine);
00652 else
00653 setScaleEngine(new QwtLinearScaleEngine);
00654
00655
00656
00657
00658
00659
00660
00661 d_data->map.setTransformation(scaleEngine()->transformation());
00662 d_data->map.setScaleInterval(d_data->minValue, d_data->maxValue);
00663
00664 if (autoScale())
00665 rescale(d_data->minValue, d_data->maxValue);
00666
00667 layoutThermo();
00668 }
00669
00674 void QwtThermo::setFillBrush(const QBrush& brush)
00675 {
00676 d_data->fillBrush = brush;
00677 update();
00678 }
00679
00681 const QBrush& QwtThermo::fillBrush() const
00682 {
00683 return d_data->fillBrush;
00684 }
00685
00690 void QwtThermo::setFillColor(const QColor &c)
00691 {
00692 d_data->fillBrush.setColor(c);
00693 update();
00694 }
00695
00697 const QColor &QwtThermo::fillColor() const
00698 {
00699 return d_data->fillBrush.color();
00700 }
00701
00706 void QwtThermo::setAlarmBrush(const QBrush& brush)
00707 {
00708 d_data->alarmBrush = brush;
00709 update();
00710 }
00711
00713 const QBrush& QwtThermo::alarmBrush() const
00714 {
00715 return d_data->alarmBrush;
00716 }
00717
00722 void QwtThermo::setAlarmColor(const QColor &c)
00723 {
00724 d_data->alarmBrush.setColor(c);
00725 update();
00726 }
00727
00729 const QColor &QwtThermo::alarmColor() const
00730 {
00731 return d_data->alarmBrush.color();
00732 }
00733
00735 void QwtThermo::setAlarmLevel(double v)
00736 {
00737 d_data->alarmLevel = v;
00738 d_data->alarmEnabled = 1;
00739 update();
00740 }
00741
00743 double QwtThermo::alarmLevel() const
00744 {
00745 return d_data->alarmLevel;
00746 }
00747
00749 void QwtThermo::setPipeWidth(int w)
00750 {
00751 if (w > 0)
00752 {
00753 d_data->thermoWidth = w;
00754 layoutThermo();
00755 }
00756 }
00757
00759 int QwtThermo::pipeWidth() const
00760 {
00761 return d_data->thermoWidth;
00762 }
00763
00764
00779 void QwtThermo::setMargin(int)
00780 {
00781 }
00782
00783
00788 void QwtThermo::setAlarmEnabled(bool tf)
00789 {
00790 d_data->alarmEnabled = tf;
00791 update();
00792 }
00793
00795 bool QwtThermo::alarmEnabled() const
00796 {
00797 return d_data->alarmEnabled;
00798 }
00799
00804 QSize QwtThermo::sizeHint() const
00805 {
00806 return minimumSizeHint();
00807 }
00808
00814 QSize QwtThermo::minimumSizeHint() const
00815 {
00816 int w = 0, h = 0;
00817
00818 if ( d_data->scalePos != NoScale )
00819 {
00820 const int sdExtent = scaleDraw()->extent( QPen(), font() );
00821 const int sdLength = scaleDraw()->minLength( QPen(), font() );
00822
00823 w = sdLength;
00824 h = d_data->thermoWidth + sdExtent +
00825 d_data->borderWidth + d_data->scaleDist;
00826
00827 }
00828 else
00829 {
00830 w = 200;
00831 h = d_data->thermoWidth;
00832 }
00833
00834 if ( d_data->orientation == Qt::Vertical )
00835 qSwap(w, h);
00836
00837 w += 2 * d_data->borderWidth;
00838 h += 2 * d_data->borderWidth;
00839
00840 return QSize( w, h );
00841 }
00842
00843 int QwtThermo::transform(double value) const
00844 {
00845 const double min = qwtMin(d_data->map.s1(), d_data->map.s2());
00846 const double max = qwtMax(d_data->map.s1(), d_data->map.s2());
00847
00848 if ( value > max )
00849 value = max;
00850 if ( value < min )
00851 value = min;
00852
00853 return d_data->map.transform(value);
00854 }