Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages

qwt_thermo.cpp

00001 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
00002  * Qwt Widget Library
00003  * Copyright (C) 1997   Josef Wilgen
00004  * Copyright (C) 2002   Uwe Rathmann
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the Qwt License, Version 1.0
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_paint_buffer.h"
00017 #include "qwt_thermo.h"
00018 
00020 QwtThermo::QwtThermo(QWidget *parent, const char *name): 
00021     QWidget(parent, name, Qt::WRepaintNoErase|Qt::WResizeNoErase)
00022 {
00023     init();
00024 }
00025 
00027 QwtThermo::~QwtThermo()
00028 {
00029 }
00030 
00032 void QwtThermo::init()
00033 {
00034     // initialize data members
00035     d_orient = Qt::Vertical;
00036     d_scalePos = Left;
00037     d_scaleDist = 3;
00038     d_thermoWidth = 10;
00039     d_borderWidth = 2;
00040     d_maxValue = 1.0;
00041     d_minValue = 0.0;
00042     d_value = 0.0;
00043     d_alarmLevel = 0.0;
00044     d_alarmEnabled = 0;
00045 
00046     // initialize colors;
00047     d_fillColor = Qt::black;
00048     d_alarmColor = Qt::white;
00049 
00050     // initialize scales
00051     d_map.setDblRange(d_minValue, d_maxValue);
00052     scaleDraw()->setScale(d_minValue, d_maxValue,
00053         scaleMaxMajor(), scaleMaxMinor());
00054 }
00055 
00056 
00058 void QwtThermo::setValue(double v)
00059 {
00060     if (d_value != v)
00061     {
00062         d_value = v;
00063         update();
00064     }
00065 }
00066 
00068 void QwtThermo::paintEvent(QPaintEvent *e)
00069 {
00070     // Use double-buffering
00071     const QRect &ur = e->rect();
00072     if ( ur.isValid() )
00073     {
00074         QwtPaintBuffer paintBuffer(this, ur);
00075         draw(paintBuffer.painter(), ur);
00076     }
00077 }
00078 
00080 void QwtThermo::draw(QPainter *p, const QRect& ur)
00081 {
00082     if ( !d_thermoRect.contains(ur) )
00083     {
00084         if (d_scalePos != None)
00085             scaleDraw()->draw(p);
00086 
00087         qDrawShadePanel(p,
00088             d_thermoRect.x() - d_borderWidth,
00089             d_thermoRect.y() - d_borderWidth,
00090             d_thermoRect.width() + 2*d_borderWidth,
00091             d_thermoRect.height() + 2*d_borderWidth,
00092             colorGroup(), TRUE, d_borderWidth,0);
00093     }
00094     drawThermo(p);
00095 }
00096 
00098 void QwtThermo::resizeEvent(QResizeEvent *)
00099 {
00100     layoutThermo( FALSE );
00101 }
00102 
00109 void QwtThermo::layoutThermo( bool update_geometry )
00110 {
00111     QRect r = rect();
00112     int mbd = 0;
00113     if ( d_scalePos != None )
00114     {
00115         int d1, d2;
00116         scaleDraw()->minBorderDist(fontMetrics(), d1, d2);
00117         mbd = QMAX(d1, d2);
00118     }
00119 
00120     if ( d_orient == Qt::Horizontal )
00121     {
00122         switch ( d_scalePos )
00123         {
00124             case Top:
00125                 d_thermoRect.setRect(
00126                     r.x() + mbd + d_borderWidth,
00127                     r.y() + r.height()
00128                     - d_thermoWidth - 2*d_borderWidth,
00129                     r.width() - 2*(d_borderWidth + mbd),
00130                     d_thermoWidth);
00131                 scaleDraw()->setGeometry(
00132                     d_thermoRect.x(),
00133                     d_thermoRect.y() - d_borderWidth - d_scaleDist,
00134                     d_thermoRect.width(),
00135                     QwtScaleDraw::Top);
00136                 break;
00137 
00138             case Bottom:
00139                 d_thermoRect.setRect(
00140                     r.x() + mbd + d_borderWidth,
00141                     r.y() + d_borderWidth,
00142                     r.width() - 2*(d_borderWidth + mbd),
00143                     d_thermoWidth);
00144                 scaleDraw()->setGeometry(
00145                     d_thermoRect.x(),
00146                     d_thermoRect.y() + d_thermoRect.height()
00147                     + d_borderWidth + d_scaleDist,
00148                     d_thermoRect.width(),
00149                     QwtScaleDraw::Bottom);
00150                 break;
00151 
00152             case None: // like Bottom but without scale
00153             default:   // inconsistent orientation and scale position
00154                 d_thermoRect.setRect(
00155                     r.x() + mbd + d_borderWidth,
00156                     r.y() + d_borderWidth,
00157                     r.width() - 2*(d_borderWidth + mbd),
00158                     d_thermoWidth);
00159                 break;
00160 
00161         }
00162         d_map.setIntRange(d_thermoRect.x(),
00163             d_thermoRect.x() + d_thermoRect.width() - 1);
00164     }
00165     else // Qt::Vertical
00166     {
00167         switch ( d_scalePos )
00168         {
00169             case Right:
00170                 d_thermoRect.setRect(
00171                     r.x() + d_borderWidth,
00172                     r.y() + mbd + d_borderWidth,
00173                     d_thermoWidth,
00174                     r.height() - 2*(d_borderWidth + mbd));
00175                 scaleDraw()->setGeometry(
00176                     d_thermoRect.x() + d_thermoRect.width()
00177                     + d_borderWidth + d_scaleDist,
00178                     d_thermoRect.y(),
00179                     d_thermoRect.height(),
00180                     QwtScaleDraw::Right);
00181                 break;
00182 
00183             case Left:
00184                 d_thermoRect.setRect(
00185                     r.x() + r.width() - 2*d_borderWidth - d_thermoWidth,
00186                     r.y() + mbd + d_borderWidth,
00187                     d_thermoWidth,
00188                     r.height() - 2*(d_borderWidth + mbd));
00189                 scaleDraw()->setGeometry(
00190                     d_thermoRect.x() - d_scaleDist - d_borderWidth,
00191                     d_thermoRect.y(),
00192                     d_thermoRect.height(),
00193                     QwtScaleDraw::Left);
00194                 break;
00195 
00196             case None: // like Left but without scale
00197             default:   // inconsistent orientation and scale position
00198                 d_thermoRect.setRect(
00199                     r.x() + r.width() - 2*d_borderWidth - d_thermoWidth,
00200                     r.y() + mbd + d_borderWidth,
00201                     d_thermoWidth,
00202                     r.height() - 2*(d_borderWidth + mbd));
00203                 break;
00204         }
00205         d_map.setIntRange(d_thermoRect.y() + d_thermoRect.height() - 1,
00206             d_thermoRect.y());
00207     }
00208     if ( update_geometry )
00209     {
00210         updateGeometry();
00211         update();
00212     }
00213 }
00214 
00231 void QwtThermo::setOrientation(Qt::Orientation o, ScalePos s)
00232 {
00233     switch(o)
00234     {
00235         case Qt::Horizontal:
00236             d_orient = Qt::Horizontal;
00237             if ((s == None) || (s == Bottom) || (s == Top))
00238                 d_scalePos = s;
00239             else
00240                 d_scalePos = None;
00241             break;
00242 
00243         case Qt::Vertical:
00244             d_orient = Qt::Vertical;
00245             if ((s == None) || (s == Left) || (s == Right))
00246                 d_scalePos = s;
00247             else
00248                 d_scalePos = None;
00249             break;
00250     }
00251     layoutThermo();
00252 }
00253 
00268 void QwtThermo::setScalePosition(ScalePos s)
00269 {
00270     if ((s == Bottom) || (s == Top))
00271         setOrientation(Qt::Horizontal, s);
00272     else if ((s == Left) || (s == Right))
00273         setOrientation(Qt::Vertical, s);
00274     else
00275         setOrientation(d_orient, None);
00276 }
00277 
00279 QwtThermo::ScalePos QwtThermo::scalePosition() const
00280 {
00281     return d_scalePos;
00282 }
00283 
00285 void QwtThermo::fontChange(const QFont &f)
00286 {
00287     QWidget::fontChange( f );
00288     layoutThermo();
00289 }
00290 
00292 void QwtThermo::scaleChange()
00293 {
00294     update();
00295     layoutThermo();
00296 }
00297 
00299 void QwtThermo::drawThermo(QPainter *p)
00300 {
00301     int alarm  = 0, taval = 0;
00302 
00303     QRect fRect;
00304     QRect aRect;
00305     QRect bRect;
00306 
00307     int inverted = ( d_maxValue < d_minValue );
00308 
00309     //
00310     //  Determine if value exceeds alarm threshold.
00311     //  Note: The alarm value is allowed to lie
00312     //        outside the interval (minValue, maxValue).
00313     //
00314     if (d_alarmEnabled)
00315     {
00316         if (inverted)
00317         {
00318             alarm = ((d_alarmLevel >= d_maxValue)
00319                  && (d_alarmLevel <= d_minValue)
00320                  && (d_value >= d_alarmLevel));
00321         
00322         }
00323         else
00324         {
00325             alarm = (( d_alarmLevel >= d_minValue)
00326                  && (d_alarmLevel <= d_maxValue)
00327                  && (d_value >= d_alarmLevel));
00328         }
00329     }
00330 
00331     //
00332     //  transform values
00333     //
00334     int tval = d_map.limTransform(d_value);
00335 
00336     if (alarm)
00337        taval = d_map.limTransform(d_alarmLevel);
00338 
00339     //
00340     //  calculate recangles
00341     //
00342     if ( d_orient == Qt::Horizontal )
00343     {
00344         if (inverted)
00345         {
00346             bRect.setRect(d_thermoRect.x(), d_thermoRect.y(),
00347                   tval - d_thermoRect.x(),
00348                   d_thermoRect.height());
00349         
00350             if (alarm)
00351             {
00352                 aRect.setRect(tval, d_thermoRect.y(),
00353                       taval - tval + 1,
00354                       d_thermoRect.height());
00355                 fRect.setRect(taval + 1, d_thermoRect.y(),
00356                       d_thermoRect.x() + d_thermoRect.width() - (taval + 1),
00357                       d_thermoRect.height());
00358             }
00359             else
00360             {
00361                 fRect.setRect(tval, d_thermoRect.y(),
00362                       d_thermoRect.x() + d_thermoRect.width() - tval,
00363                       d_thermoRect.height());
00364             }
00365         }
00366         else
00367         {
00368             bRect.setRect(tval + 1, d_thermoRect.y(),
00369                   d_thermoRect.width() - (tval + 1 - d_thermoRect.x()),
00370                   d_thermoRect.height());
00371         
00372             if (alarm)
00373             {
00374                 aRect.setRect(taval, d_thermoRect.y(),
00375                       tval - taval + 1,
00376                       d_thermoRect.height());
00377                 fRect.setRect(d_thermoRect.x(), d_thermoRect.y(),
00378                       taval - d_thermoRect.x(),
00379                       d_thermoRect.height());
00380             }
00381             else
00382             {
00383                 fRect.setRect(d_thermoRect.x(), d_thermoRect.y(),
00384                       tval - d_thermoRect.x() + 1,
00385                       d_thermoRect.height());
00386             }
00387         
00388         }
00389     }
00390     else // Qt::Vertical
00391     {
00392         if (tval < d_thermoRect.y())
00393             tval = d_thermoRect.y();
00394         else 
00395         {
00396             if (tval > d_thermoRect.y() + d_thermoRect.height())
00397                 tval = d_thermoRect.y() + d_thermoRect.height();
00398         }
00399 
00400         if (inverted)
00401         {
00402             bRect.setRect(d_thermoRect.x(), tval + 1,
00403             d_thermoRect.width(),
00404             d_thermoRect.height() - (tval + 1 - d_thermoRect.y()));
00405 
00406             if (alarm)
00407             {
00408                 aRect.setRect(d_thermoRect.x(), taval,
00409                     d_thermoRect.width(),
00410                     tval - taval + 1);
00411                 fRect.setRect(d_thermoRect.x(), d_thermoRect.y(),
00412                     d_thermoRect.width(),
00413                 taval - d_thermoRect.y());
00414             }
00415             else
00416             {
00417                 fRect.setRect(d_thermoRect.x(), d_thermoRect.y(),
00418                     d_thermoRect.width(),
00419                     tval - d_thermoRect.y() + 1);
00420             }
00421         }
00422         else
00423         {
00424             bRect.setRect(d_thermoRect.x(), d_thermoRect.y(),
00425             d_thermoRect.width(),
00426             tval - d_thermoRect.y());
00427             if (alarm)
00428             {
00429                 aRect.setRect(d_thermoRect.x(),tval,
00430                     d_thermoRect.width(),
00431                     taval - tval + 1);
00432                 fRect.setRect(d_thermoRect.x(),taval + 1,
00433                     d_thermoRect.width(),
00434                     d_thermoRect.y() + d_thermoRect.height() - (taval + 1));
00435             }
00436             else
00437             {
00438                 fRect.setRect(d_thermoRect.x(),tval,
00439                     d_thermoRect.width(),
00440                 d_thermoRect.y() + d_thermoRect.height() - tval);
00441             }
00442         }
00443     }
00444 
00445     //
00446     // paint thermometer
00447     //
00448     p->fillRect(bRect, colorGroup().color(QColorGroup::Background));
00449 
00450     if (alarm)
00451        p->fillRect(aRect, d_alarmColor);
00452 
00453     p->fillRect(fRect, d_fillColor);
00454 }
00455 
00457 void QwtThermo::setBorderWidth(int w)
00458 {
00459     if ((w >= 0) && (w < (qwtMin(d_thermoRect.width(), 
00460         d_thermoRect.height()) + d_borderWidth) / 2  - 1))
00461     {
00462         d_borderWidth = w;
00463         layoutThermo();
00464     }
00465 }
00466 
00468 int QwtThermo::borderWidth() const
00469 {
00470     return d_borderWidth;
00471 }
00472 
00478 void QwtThermo::setRange(double vmin, double vmax)
00479 {
00480     d_minValue = vmin;
00481     d_maxValue = vmax;
00482 
00483     d_map.setDblRange(d_minValue, d_maxValue);
00484     if (!hasUserScale())
00485     {
00486         QwtScaleDiv oldscl(scaleDraw()->scaleDiv());
00487 
00488         scaleDraw()->setScale(d_minValue, d_maxValue,
00489             scaleMaxMajor(), scaleMaxMinor());
00490         if (oldscl != scaleDraw()->scaleDiv())
00491             scaleChange();
00492     }
00493     layoutThermo();
00494 }
00495 
00500 void QwtThermo::setFillColor(const QColor &c)
00501 {
00502     d_fillColor = c;
00503     update();
00504 }
00505 
00507 const QColor &QwtThermo::fillColor() const
00508 {
00509     return d_fillColor;
00510 }
00511 
00516 void QwtThermo::setAlarmColor(const QColor &c)
00517 {
00518     d_alarmColor = c;
00519     update();
00520 }
00521 
00523 const QColor &QwtThermo::alarmColor() const
00524 {
00525     return d_alarmColor;
00526 }
00527 
00529 void QwtThermo::setAlarmLevel(double v)
00530 {
00531     d_alarmLevel = v;
00532     d_alarmEnabled = 1;
00533     update();
00534 }
00535 
00537 double QwtThermo::alarmLevel() const
00538 {
00539     return d_alarmLevel;
00540 }
00541 
00543 void QwtThermo::setPipeWidth(int w)
00544 {
00545     if (w > 0)
00546     {
00547         d_thermoWidth = w;
00548         layoutThermo();
00549     }
00550 }
00551 
00553 int QwtThermo::pipeWidth() const
00554 {
00555     return d_thermoWidth;
00556 }
00557 
00558 
00573 void QwtThermo::setMargin(int)
00574 {
00575 }
00576 
00577 
00582 void QwtThermo::setAlarmEnabled(bool tf)
00583 {
00584     d_alarmEnabled = tf;
00585     update();
00586 }
00587 
00589 bool QwtThermo::alarmEnabled() const
00590 {
00591     return d_alarmEnabled;
00592 }
00593 
00599 QSizePolicy QwtThermo::sizePolicy() const
00600 {
00601     QSizePolicy sp;
00602     if ( scaleDraw()->orientation() == QwtScaleDraw::Left ||
00603         scaleDraw()->orientation() == QwtScaleDraw::Right )
00604     {
00605         sp.setHorData( QSizePolicy::Fixed );
00606         sp.setVerData( QSizePolicy::MinimumExpanding );
00607     }
00608     else
00609     {
00610         sp.setHorData( QSizePolicy::MinimumExpanding );
00611         sp.setVerData( QSizePolicy::Fixed );
00612     }
00613     return sp;
00614 }
00615 
00620 QSize QwtThermo::sizeHint() const
00621 {
00622     return minimumSizeHint();
00623 }
00624 
00630 QSize QwtThermo::minimumSizeHint() const
00631 {
00632     int w = 0, h = 0;
00633 
00634     if ( d_scalePos != None )
00635     {
00636         int smw = scaleDraw()->minWidth( QPen(), fontMetrics() );
00637         int smh = scaleDraw()->minHeight( QPen(), fontMetrics() );
00638 
00639         if ( d_orient == Qt::Vertical )
00640         {
00641             w = d_thermoWidth + smw + 3 * d_borderWidth + d_scaleDist;
00642             h = smh + 2 * d_borderWidth;
00643         }
00644         else
00645         {
00646             w = smw + 2 * d_borderWidth;
00647             h = d_thermoWidth + smh + 3 * d_borderWidth + d_scaleDist;
00648         }
00649 
00650     }
00651     else // no scale
00652     {
00653         if ( d_orient == Qt::Vertical )
00654         {
00655             w = d_thermoWidth + 2 * d_borderWidth;
00656             h = 200 + 2 * d_borderWidth;
00657         }
00658         else
00659         {
00660             w = 200 + 2 * d_borderWidth;
00661             h = d_thermoWidth + 2 * d_borderWidth;
00662         }
00663     }
00664     return QSize( w, h );
00665 }
00666 
00667 // Local Variables:
00668 // mode: C++
00669 // c-file-style: "stroustrup"
00670 // indent-tabs-mode: nil
00671 // End:

Generated on Sun Sep 26 23:24:38 2004 for Qwt User's Guide by doxygen 1.3.6