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
00116 void QwtThermo::setMaxValue(double max)
00117 {
00118 setRange(d_data->minValue, max);
00119 }
00120
00122 double QwtThermo::maxValue() const
00123 {
00124 return d_data->maxValue;
00125 }
00126
00133 void QwtThermo::setMinValue(double min)
00134 {
00135 setRange(min, d_data->maxValue);
00136 }
00137
00139 double QwtThermo::minValue() const
00140 {
00141 return d_data->minValue;
00142 }
00143
00150 void QwtThermo::setValue(double value)
00151 {
00152 if (d_data->value != value)
00153 {
00154 d_data->value = value;
00155 update();
00156 }
00157 }
00158
00160 double QwtThermo::value() const
00161 {
00162 return d_data->value;
00163 }
00164
00176 void QwtThermo::setScaleDraw(QwtScaleDraw *scaleDraw)
00177 {
00178 setAbstractScaleDraw(scaleDraw);
00179 }
00180
00185 const QwtScaleDraw *QwtThermo::scaleDraw() const
00186 {
00187 return (QwtScaleDraw *)abstractScaleDraw();
00188 }
00189
00194 QwtScaleDraw *QwtThermo::scaleDraw()
00195 {
00196 return (QwtScaleDraw *)abstractScaleDraw();
00197 }
00198
00203 void QwtThermo::paintEvent(QPaintEvent *event)
00204 {
00205
00206 const QRect &ur = event->rect();
00207 if ( ur.isValid() )
00208 {
00209 #if QT_VERSION < 0x040000
00210 QwtPaintBuffer paintBuffer(this, ur);
00211 draw(paintBuffer.painter(), ur);
00212 #else
00213 QPainter painter(this);
00214 draw(&painter, ur);
00215 #endif
00216 }
00217 }
00218
00225 void QwtThermo::draw(QPainter *painter, const QRect& rect)
00226 {
00227 if ( !d_data->thermoRect.contains(rect) )
00228 {
00229 if (d_data->scalePos != NoScale)
00230 {
00231 #if QT_VERSION < 0x040000
00232 scaleDraw()->draw(painter, colorGroup());
00233 #else
00234 scaleDraw()->draw(painter, palette());
00235 #endif
00236 }
00237
00238 qDrawShadePanel(painter,
00239 d_data->thermoRect.x() - d_data->borderWidth,
00240 d_data->thermoRect.y() - d_data->borderWidth,
00241 d_data->thermoRect.width() + 2 * d_data->borderWidth,
00242 d_data->thermoRect.height() + 2 * d_data->borderWidth,
00243 #if QT_VERSION < 0x040000
00244 colorGroup(),
00245 #else
00246 palette(),
00247 #endif
00248 true, d_data->borderWidth, 0);
00249 }
00250 drawThermo(painter);
00251 }
00252
00254 void QwtThermo::resizeEvent(QResizeEvent *)
00255 {
00256 layoutThermo( false );
00257 }
00258
00266 void QwtThermo::layoutThermo( bool update_geometry )
00267 {
00268 QRect r = rect();
00269 int mbd = 0;
00270 if ( d_data->scalePos != NoScale )
00271 {
00272 int d1, d2;
00273 scaleDraw()->getBorderDistHint(font(), d1, d2);
00274 mbd = qwtMax(d1, d2);
00275 }
00276
00277 if ( d_data->orientation == Qt::Horizontal )
00278 {
00279 switch ( d_data->scalePos )
00280 {
00281 case TopScale:
00282 {
00283 d_data->thermoRect.setRect(
00284 r.x() + mbd + d_data->borderWidth,
00285 r.y() + r.height()
00286 - d_data->thermoWidth - 2*d_data->borderWidth,
00287 r.width() - 2*(d_data->borderWidth + mbd),
00288 d_data->thermoWidth);
00289 scaleDraw()->setAlignment(QwtScaleDraw::TopScale);
00290 scaleDraw()->move( d_data->thermoRect.x(),
00291 d_data->thermoRect.y() - d_data->borderWidth
00292 - d_data->scaleDist);
00293 scaleDraw()->setLength(d_data->thermoRect.width());
00294 break;
00295 }
00296
00297 case BottomScale:
00298 case NoScale:
00299 default:
00300
00301
00302 {
00303 d_data->thermoRect.setRect(
00304 r.x() + mbd + d_data->borderWidth,
00305 r.y() + d_data->borderWidth,
00306 r.width() - 2*(d_data->borderWidth + mbd),
00307 d_data->thermoWidth);
00308 scaleDraw()->setAlignment(QwtScaleDraw::BottomScale);
00309 scaleDraw()->move(
00310 d_data->thermoRect.x(),
00311 d_data->thermoRect.y() + d_data->thermoRect.height()
00312 + d_data->borderWidth + d_data->scaleDist );
00313 scaleDraw()->setLength(d_data->thermoRect.width());
00314 break;
00315 }
00316 }
00317 d_data->map.setPaintInterval(d_data->thermoRect.x(),
00318 d_data->thermoRect.x() + d_data->thermoRect.width() - 1);
00319 }
00320 else
00321 {
00322 switch ( d_data->scalePos )
00323 {
00324 case RightScale:
00325 {
00326 d_data->thermoRect.setRect(
00327 r.x() + d_data->borderWidth,
00328 r.y() + mbd + d_data->borderWidth,
00329 d_data->thermoWidth,
00330 r.height() - 2*(d_data->borderWidth + mbd));
00331 scaleDraw()->setAlignment(QwtScaleDraw::RightScale);
00332 scaleDraw()->move(
00333 d_data->thermoRect.x() + d_data->thermoRect.width()
00334 + d_data->borderWidth + d_data->scaleDist,
00335 d_data->thermoRect.y());
00336 scaleDraw()->setLength(d_data->thermoRect.height());
00337 break;
00338 }
00339
00340 case LeftScale:
00341 case NoScale:
00342 default:
00343
00344
00345 {
00346 d_data->thermoRect.setRect(
00347 r.x() + r.width() - 2*d_data->borderWidth - d_data->thermoWidth,
00348 r.y() + mbd + d_data->borderWidth,
00349 d_data->thermoWidth,
00350 r.height() - 2*(d_data->borderWidth + mbd));
00351 scaleDraw()->setAlignment(QwtScaleDraw::LeftScale);
00352 scaleDraw()->move(
00353 d_data->thermoRect.x() - d_data->scaleDist
00354 - d_data->borderWidth,
00355 d_data->thermoRect.y() );
00356 scaleDraw()->setLength(d_data->thermoRect.height());
00357 break;
00358 }
00359 }
00360 d_data->map.setPaintInterval(
00361 d_data->thermoRect.y() + d_data->thermoRect.height() - 1,
00362 d_data->thermoRect.y());
00363 }
00364 if ( update_geometry )
00365 {
00366 updateGeometry();
00367 update();
00368 }
00369 }
00370
00389 void QwtThermo::setOrientation(Qt::Orientation o, ScalePos s)
00390 {
00391 if ( o == d_data->orientation && s == d_data->scalePos )
00392 return;
00393
00394 switch(o)
00395 {
00396 case Qt::Horizontal:
00397 {
00398 if ((s == NoScale) || (s == BottomScale) || (s == TopScale))
00399 d_data->scalePos = s;
00400 else
00401 d_data->scalePos = NoScale;
00402 break;
00403 }
00404 case Qt::Vertical:
00405 {
00406 if ((s == NoScale) || (s == LeftScale) || (s == RightScale))
00407 d_data->scalePos = s;
00408 else
00409 d_data->scalePos = NoScale;
00410 break;
00411 }
00412 }
00413
00414 if ( o != d_data->orientation )
00415 {
00416 #if QT_VERSION >= 0x040000
00417 if ( !testAttribute(Qt::WA_WState_OwnSizePolicy) )
00418 #else
00419 if ( !testWState( WState_OwnSizePolicy ) )
00420 #endif
00421 {
00422 QSizePolicy sp = sizePolicy();
00423 sp.transpose();
00424 setSizePolicy(sp);
00425
00426 #if QT_VERSION >= 0x040000
00427 setAttribute(Qt::WA_WState_OwnSizePolicy, false);
00428 #else
00429 clearWState( WState_OwnSizePolicy );
00430 #endif
00431 }
00432 }
00433
00434 d_data->orientation = o;
00435 layoutThermo();
00436 }
00437
00452 void QwtThermo::setScalePosition(ScalePos scalePos)
00453 {
00454 if ((scalePos == BottomScale) || (scalePos == TopScale))
00455 setOrientation(Qt::Horizontal, scalePos);
00456 else if ((scalePos == LeftScale) || (scalePos == RightScale))
00457 setOrientation(Qt::Vertical, scalePos);
00458 else
00459 setOrientation(d_data->orientation, NoScale);
00460 }
00461
00466 QwtThermo::ScalePos QwtThermo::scalePosition() const
00467 {
00468 return d_data->scalePos;
00469 }
00470
00472 void QwtThermo::fontChange(const QFont &f)
00473 {
00474 QWidget::fontChange( f );
00475 layoutThermo();
00476 }
00477
00479 void QwtThermo::scaleChange()
00480 {
00481 update();
00482 layoutThermo();
00483 }
00484
00489 void QwtThermo::drawThermo(QPainter *painter)
00490 {
00491 int alarm = 0, taval = 0;
00492
00493 QRect fRect;
00494 QRect aRect;
00495 QRect bRect;
00496
00497 int inverted = ( d_data->maxValue < d_data->minValue );
00498
00499
00500
00501
00502
00503
00504 if (d_data->alarmEnabled)
00505 {
00506 if (inverted)
00507 {
00508 alarm = ((d_data->alarmLevel >= d_data->maxValue)
00509 && (d_data->alarmLevel <= d_data->minValue)
00510 && (d_data->value >= d_data->alarmLevel));
00511
00512 }
00513 else
00514 {
00515 alarm = (( d_data->alarmLevel >= d_data->minValue)
00516 && (d_data->alarmLevel <= d_data->maxValue)
00517 && (d_data->value >= d_data->alarmLevel));
00518 }
00519 }
00520
00521
00522
00523
00524 int tval = transform(d_data->value);
00525
00526 if (alarm)
00527 taval = transform(d_data->alarmLevel);
00528
00529
00530
00531
00532 if ( d_data->orientation == Qt::Horizontal )
00533 {
00534 if (inverted)
00535 {
00536 bRect.setRect(d_data->thermoRect.x(), d_data->thermoRect.y(),
00537 tval - d_data->thermoRect.x(),
00538 d_data->thermoRect.height());
00539
00540 if (alarm)
00541 {
00542 aRect.setRect(tval, d_data->thermoRect.y(),
00543 taval - tval + 1,
00544 d_data->thermoRect.height());
00545 fRect.setRect(taval + 1, d_data->thermoRect.y(),
00546 d_data->thermoRect.x() + d_data->thermoRect.width() - (taval + 1),
00547 d_data->thermoRect.height());
00548 }
00549 else
00550 {
00551 fRect.setRect(tval, d_data->thermoRect.y(),
00552 d_data->thermoRect.x() + d_data->thermoRect.width() - tval,
00553 d_data->thermoRect.height());
00554 }
00555 }
00556 else
00557 {
00558 bRect.setRect(tval + 1, d_data->thermoRect.y(),
00559 d_data->thermoRect.width() - (tval + 1 - d_data->thermoRect.x()),
00560 d_data->thermoRect.height());
00561
00562 if (alarm)
00563 {
00564 aRect.setRect(taval, d_data->thermoRect.y(),
00565 tval - taval + 1,
00566 d_data->thermoRect.height());
00567 fRect.setRect(d_data->thermoRect.x(), d_data->thermoRect.y(),
00568 taval - d_data->thermoRect.x(),
00569 d_data->thermoRect.height());
00570 }
00571 else
00572 {
00573 fRect.setRect(d_data->thermoRect.x(), d_data->thermoRect.y(),
00574 tval - d_data->thermoRect.x() + 1,
00575 d_data->thermoRect.height());
00576 }
00577
00578 }
00579 }
00580 else
00581 {
00582 if (tval < d_data->thermoRect.y())
00583 tval = d_data->thermoRect.y();
00584 else
00585 {
00586 if (tval > d_data->thermoRect.y() + d_data->thermoRect.height())
00587 tval = d_data->thermoRect.y() + d_data->thermoRect.height();
00588 }
00589
00590 if (inverted)
00591 {
00592 bRect.setRect(d_data->thermoRect.x(), tval + 1,
00593 d_data->thermoRect.width(),
00594 d_data->thermoRect.height() - (tval + 1 - d_data->thermoRect.y()));
00595
00596 if (alarm)
00597 {
00598 aRect.setRect(d_data->thermoRect.x(), taval,
00599 d_data->thermoRect.width(),
00600 tval - taval + 1);
00601 fRect.setRect(d_data->thermoRect.x(), d_data->thermoRect.y(),
00602 d_data->thermoRect.width(),
00603 taval - d_data->thermoRect.y());
00604 }
00605 else
00606 {
00607 fRect.setRect(d_data->thermoRect.x(), d_data->thermoRect.y(),
00608 d_data->thermoRect.width(),
00609 tval - d_data->thermoRect.y() + 1);
00610 }
00611 }
00612 else
00613 {
00614 bRect.setRect(d_data->thermoRect.x(), d_data->thermoRect.y(),
00615 d_data->thermoRect.width(),
00616 tval - d_data->thermoRect.y());
00617 if (alarm)
00618 {
00619 aRect.setRect(d_data->thermoRect.x(),tval,
00620 d_data->thermoRect.width(),
00621 taval - tval + 1);
00622 fRect.setRect(d_data->thermoRect.x(),taval + 1,
00623 d_data->thermoRect.width(),
00624 d_data->thermoRect.y() + d_data->thermoRect.height() - (taval + 1));
00625 }
00626 else
00627 {
00628 fRect.setRect(d_data->thermoRect.x(),tval,
00629 d_data->thermoRect.width(),
00630 d_data->thermoRect.y() + d_data->thermoRect.height() - tval);
00631 }
00632 }
00633 }
00634
00635
00636
00637
00638 const QColor bgColor =
00639 #if QT_VERSION < 0x040000
00640 colorGroup().color(QColorGroup::Background);
00641 #else
00642 palette().color(QPalette::Background);
00643 #endif
00644 painter->fillRect(bRect, bgColor);
00645
00646 if (alarm)
00647 painter->fillRect(aRect, d_data->alarmBrush);
00648
00649 painter->fillRect(fRect, d_data->fillBrush);
00650 }
00651
00657 void QwtThermo::setBorderWidth(int width)
00658 {
00659 if ((width >= 0) && (width < (qwtMin(d_data->thermoRect.width(),
00660 d_data->thermoRect.height()) + d_data->borderWidth) / 2 - 1))
00661 {
00662 d_data->borderWidth = width;
00663 layoutThermo();
00664 }
00665 }
00666
00671 int QwtThermo::borderWidth() const
00672 {
00673 return d_data->borderWidth;
00674 }
00675
00682 void QwtThermo::setRange(double vmin, double vmax, bool logarithmic)
00683 {
00684 d_data->minValue = vmin;
00685 d_data->maxValue = vmax;
00686
00687 if ( logarithmic )
00688 setScaleEngine(new QwtLog10ScaleEngine);
00689 else
00690 setScaleEngine(new QwtLinearScaleEngine);
00691
00692
00693
00694
00695
00696
00697
00698 d_data->map.setTransformation(scaleEngine()->transformation());
00699 d_data->map.setScaleInterval(d_data->minValue, d_data->maxValue);
00700
00701 if (autoScale())
00702 rescale(d_data->minValue, d_data->maxValue);
00703
00704 layoutThermo();
00705 }
00706
00712 void QwtThermo::setFillBrush(const QBrush& brush)
00713 {
00714 d_data->fillBrush = brush;
00715 update();
00716 }
00717
00722 const QBrush& QwtThermo::fillBrush() const
00723 {
00724 return d_data->fillBrush;
00725 }
00726
00732 void QwtThermo::setFillColor(const QColor &c)
00733 {
00734 d_data->fillBrush.setColor(c);
00735 update();
00736 }
00737
00742 const QColor &QwtThermo::fillColor() const
00743 {
00744 return d_data->fillBrush.color();
00745 }
00746
00752 void QwtThermo::setAlarmBrush(const QBrush& brush)
00753 {
00754 d_data->alarmBrush = brush;
00755 update();
00756 }
00757
00762 const QBrush& QwtThermo::alarmBrush() const
00763 {
00764 return d_data->alarmBrush;
00765 }
00766
00771 void QwtThermo::setAlarmColor(const QColor &c)
00772 {
00773 d_data->alarmBrush.setColor(c);
00774 update();
00775 }
00776
00778 const QColor &QwtThermo::alarmColor() const
00779 {
00780 return d_data->alarmBrush.color();
00781 }
00782
00789 void QwtThermo::setAlarmLevel(double level)
00790 {
00791 d_data->alarmLevel = level;
00792 d_data->alarmEnabled = 1;
00793 update();
00794 }
00795
00800 double QwtThermo::alarmLevel() const
00801 {
00802 return d_data->alarmLevel;
00803 }
00804
00811 void QwtThermo::setPipeWidth(int width)
00812 {
00813 if (width > 0)
00814 {
00815 d_data->thermoWidth = width;
00816 layoutThermo();
00817 }
00818 }
00819
00824 int QwtThermo::pipeWidth() const
00825 {
00826 return d_data->thermoWidth;
00827 }
00828
00829
00844 void QwtThermo::setMargin(int)
00845 {
00846 }
00847
00848
00853 void QwtThermo::setAlarmEnabled(bool tf)
00854 {
00855 d_data->alarmEnabled = tf;
00856 update();
00857 }
00858
00860 bool QwtThermo::alarmEnabled() const
00861 {
00862 return d_data->alarmEnabled;
00863 }
00864
00869 QSize QwtThermo::sizeHint() const
00870 {
00871 return minimumSizeHint();
00872 }
00873
00879 QSize QwtThermo::minimumSizeHint() const
00880 {
00881 int w = 0, h = 0;
00882
00883 if ( d_data->scalePos != NoScale )
00884 {
00885 const int sdExtent = scaleDraw()->extent( QPen(), font() );
00886 const int sdLength = scaleDraw()->minLength( QPen(), font() );
00887
00888 w = sdLength;
00889 h = d_data->thermoWidth + sdExtent +
00890 d_data->borderWidth + d_data->scaleDist;
00891
00892 }
00893 else
00894 {
00895 w = 200;
00896 h = d_data->thermoWidth;
00897 }
00898
00899 if ( d_data->orientation == Qt::Vertical )
00900 qSwap(w, h);
00901
00902 w += 2 * d_data->borderWidth;
00903 h += 2 * d_data->borderWidth;
00904
00905 return QSize( w, h );
00906 }
00907
00908 int QwtThermo::transform(double value) const
00909 {
00910 const double min = qwtMin(d_data->map.s1(), d_data->map.s2());
00911 const double max = qwtMax(d_data->map.s1(), d_data->map.s2());
00912
00913 if ( value > max )
00914 value = max;
00915 if ( value < min )
00916 value = min;
00917
00918 return d_data->map.transform(value);
00919 }