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 brushes;
00047     d_fillBrush = QBrush(Qt::black);
00048     d_alarmBrush = QBrush(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             case None: // like Bottom but without scale
00140             default:   // inconsistent orientation and scale position
00141                        // Mapping between values and pixels requires
00142                        // initialization of the scale geometry
00143                 d_thermoRect.setRect(
00144                     r.x() + mbd + d_borderWidth,
00145                     r.y() + d_borderWidth,
00146                     r.width() - 2*(d_borderWidth + mbd),
00147                     d_thermoWidth);
00148                 scaleDraw()->setGeometry(
00149                     d_thermoRect.x(),
00150                     d_thermoRect.y() + d_thermoRect.height()
00151                     + d_borderWidth + d_scaleDist,
00152                     d_thermoRect.width(),
00153                     QwtScaleDraw::Bottom);
00154                 break;
00155         }
00156         d_map.setIntRange(d_thermoRect.x(),
00157             d_thermoRect.x() + d_thermoRect.width() - 1);
00158     }
00159     else // Qt::Vertical
00160     {
00161         switch ( d_scalePos )
00162         {
00163             case Right:
00164                 d_thermoRect.setRect(
00165                     r.x() + d_borderWidth,
00166                     r.y() + mbd + d_borderWidth,
00167                     d_thermoWidth,
00168                     r.height() - 2*(d_borderWidth + mbd));
00169                 scaleDraw()->setGeometry(
00170                     d_thermoRect.x() + d_thermoRect.width()
00171                     + d_borderWidth + d_scaleDist,
00172                     d_thermoRect.y(),
00173                     d_thermoRect.height(),
00174                     QwtScaleDraw::Right);
00175                 break;
00176 
00177             case Left:
00178             case None: // like Left but without scale
00179             default:   // inconsistent orientation and scale position
00180                        // Mapping between values and pixels requires
00181                        // initialization of the scale geometry
00182                 d_thermoRect.setRect(
00183                     r.x() + r.width() - 2*d_borderWidth - d_thermoWidth,
00184                     r.y() + mbd + d_borderWidth,
00185                     d_thermoWidth,
00186                     r.height() - 2*(d_borderWidth + mbd));
00187                 scaleDraw()->setGeometry(
00188                     d_thermoRect.x() - d_scaleDist - d_borderWidth,
00189                     d_thermoRect.y(),
00190                     d_thermoRect.height(),
00191                     QwtScaleDraw::Left);
00192                 break;
00193         }
00194         d_map.setIntRange(d_thermoRect.y() + d_thermoRect.height() - 1,
00195             d_thermoRect.y());
00196     }
00197     if ( update_geometry )
00198     {
00199         updateGeometry();
00200         update();
00201     }
00202 }
00203 
00220 void QwtThermo::setOrientation(Qt::Orientation o, ScalePos s)
00221 {
00222     switch(o)
00223     {
00224         case Qt::Horizontal:
00225             d_orient = Qt::Horizontal;
00226             if ((s == None) || (s == Bottom) || (s == Top))
00227                 d_scalePos = s;
00228             else
00229                 d_scalePos = None;
00230             break;
00231 
00232         case Qt::Vertical:
00233             d_orient = Qt::Vertical;
00234             if ((s == None) || (s == Left) || (s == Right))
00235                 d_scalePos = s;
00236             else
00237                 d_scalePos = None;
00238             break;
00239     }
00240     layoutThermo();
00241 }
00242 
00257 void QwtThermo::setScalePosition(ScalePos s)
00258 {
00259     if ((s == Bottom) || (s == Top))
00260         setOrientation(Qt::Horizontal, s);
00261     else if ((s == Left) || (s == Right))
00262         setOrientation(Qt::Vertical, s);
00263     else
00264         setOrientation(d_orient, None);
00265 }
00266 
00268 QwtThermo::ScalePos QwtThermo::scalePosition() const
00269 {
00270     return d_scalePos;
00271 }
00272 
00274 void QwtThermo::fontChange(const QFont &f)
00275 {
00276     QWidget::fontChange( f );
00277     layoutThermo();
00278 }
00279 
00281 void QwtThermo::scaleChange()
00282 {
00283     update();
00284     layoutThermo();
00285 }
00286 
00288 void QwtThermo::drawThermo(QPainter *p)
00289 {
00290     int alarm  = 0, taval = 0;
00291 
00292     QRect fRect;
00293     QRect aRect;
00294     QRect bRect;
00295 
00296     int inverted = ( d_maxValue < d_minValue );
00297 
00298     //
00299     //  Determine if value exceeds alarm threshold.
00300     //  Note: The alarm value is allowed to lie
00301     //        outside the interval (minValue, maxValue).
00302     //
00303     if (d_alarmEnabled)
00304     {
00305         if (inverted)
00306         {
00307             alarm = ((d_alarmLevel >= d_maxValue)
00308                  && (d_alarmLevel <= d_minValue)
00309                  && (d_value >= d_alarmLevel));
00310         
00311         }
00312         else
00313         {
00314             alarm = (( d_alarmLevel >= d_minValue)
00315                  && (d_alarmLevel <= d_maxValue)
00316                  && (d_value >= d_alarmLevel));
00317         }
00318     }
00319 
00320     //
00321     //  transform values
00322     //
00323     int tval = d_map.limTransform(d_value);
00324 
00325     if (alarm)
00326        taval = d_map.limTransform(d_alarmLevel);
00327 
00328     //
00329     //  calculate recangles
00330     //
00331     if ( d_orient == Qt::Horizontal )
00332     {
00333         if (inverted)
00334         {
00335             bRect.setRect(d_thermoRect.x(), d_thermoRect.y(),
00336                   tval - d_thermoRect.x(),
00337                   d_thermoRect.height());
00338         
00339             if (alarm)
00340             {
00341                 aRect.setRect(tval, d_thermoRect.y(),
00342                       taval - tval + 1,
00343                       d_thermoRect.height());
00344                 fRect.setRect(taval + 1, d_thermoRect.y(),
00345                       d_thermoRect.x() + d_thermoRect.width() - (taval + 1),
00346                       d_thermoRect.height());
00347             }
00348             else
00349             {
00350                 fRect.setRect(tval, d_thermoRect.y(),
00351                       d_thermoRect.x() + d_thermoRect.width() - tval,
00352                       d_thermoRect.height());
00353             }
00354         }
00355         else
00356         {
00357             bRect.setRect(tval + 1, d_thermoRect.y(),
00358                   d_thermoRect.width() - (tval + 1 - d_thermoRect.x()),
00359                   d_thermoRect.height());
00360         
00361             if (alarm)
00362             {
00363                 aRect.setRect(taval, d_thermoRect.y(),
00364                       tval - taval + 1,
00365                       d_thermoRect.height());
00366                 fRect.setRect(d_thermoRect.x(), d_thermoRect.y(),
00367                       taval - d_thermoRect.x(),
00368                       d_thermoRect.height());
00369             }
00370             else
00371             {
00372                 fRect.setRect(d_thermoRect.x(), d_thermoRect.y(),
00373                       tval - d_thermoRect.x() + 1,
00374                       d_thermoRect.height());
00375             }
00376         
00377         }
00378     }
00379     else // Qt::Vertical
00380     {
00381         if (tval < d_thermoRect.y())
00382             tval = d_thermoRect.y();
00383         else 
00384         {
00385             if (tval > d_thermoRect.y() + d_thermoRect.height())
00386                 tval = d_thermoRect.y() + d_thermoRect.height();
00387         }
00388 
00389         if (inverted)
00390         {
00391             bRect.setRect(d_thermoRect.x(), tval + 1,
00392             d_thermoRect.width(),
00393             d_thermoRect.height() - (tval + 1 - d_thermoRect.y()));
00394 
00395             if (alarm)
00396             {
00397                 aRect.setRect(d_thermoRect.x(), taval,
00398                     d_thermoRect.width(),
00399                     tval - taval + 1);
00400                 fRect.setRect(d_thermoRect.x(), d_thermoRect.y(),
00401                     d_thermoRect.width(),
00402                 taval - d_thermoRect.y());
00403             }
00404             else
00405             {
00406                 fRect.setRect(d_thermoRect.x(), d_thermoRect.y(),
00407                     d_thermoRect.width(),
00408                     tval - d_thermoRect.y() + 1);
00409             }
00410         }
00411         else
00412         {
00413             bRect.setRect(d_thermoRect.x(), d_thermoRect.y(),
00414             d_thermoRect.width(),
00415             tval - d_thermoRect.y());
00416             if (alarm)
00417             {
00418                 aRect.setRect(d_thermoRect.x(),tval,
00419                     d_thermoRect.width(),
00420                     taval - tval + 1);
00421                 fRect.setRect(d_thermoRect.x(),taval + 1,
00422                     d_thermoRect.width(),
00423                     d_thermoRect.y() + d_thermoRect.height() - (taval + 1));
00424             }
00425             else
00426             {
00427                 fRect.setRect(d_thermoRect.x(),tval,
00428                     d_thermoRect.width(),
00429                 d_thermoRect.y() + d_thermoRect.height() - tval);
00430             }
00431         }
00432     }
00433 
00434     //
00435     // paint thermometer
00436     //
00437     p->fillRect(bRect, colorGroup().color(QColorGroup::Background));
00438 
00439     if (alarm)
00440        p->fillRect(aRect, d_alarmBrush);
00441 
00442     p->fillRect(fRect, d_fillBrush);
00443 }
00444 
00446 void QwtThermo::setBorderWidth(int w)
00447 {
00448     if ((w >= 0) && (w < (qwtMin(d_thermoRect.width(), 
00449         d_thermoRect.height()) + d_borderWidth) / 2  - 1))
00450     {
00451         d_borderWidth = w;
00452         layoutThermo();
00453     }
00454 }
00455 
00457 int QwtThermo::borderWidth() const
00458 {
00459     return d_borderWidth;
00460 }
00461 
00468 void QwtThermo::setRange(double vmin, double vmax, bool logarithmic)
00469 {
00470     d_minValue = vmin;
00471     d_maxValue = vmax;
00472 
00473     d_map.setDblRange(d_minValue, d_maxValue, logarithmic);
00474     if (!hasUserScale())
00475     {
00476         QwtScaleDiv oldscl(scaleDraw()->scaleDiv());
00477 
00478         scaleDraw()->setScale(d_minValue, d_maxValue,
00479             scaleMaxMajor(), scaleMaxMinor(), 0.0, logarithmic);
00480         if (oldscl != scaleDraw()->scaleDiv())
00481             scaleChange();
00482     }
00483     layoutThermo();
00484 }
00485 
00490 void QwtThermo::setFillBrush(const QBrush& b)
00491 {
00492     d_fillBrush = b;
00493     update();
00494 }
00495 
00497 const QBrush& QwtThermo::fillBrush() const
00498 {
00499     return d_fillBrush;
00500 }
00501 
00506 void QwtThermo::setFillColor(const QColor &c)
00507 {
00508     d_fillBrush.setColor(c);
00509     update();
00510 }
00511 
00513 const QColor &QwtThermo::fillColor() const
00514 {
00515     return d_fillBrush.color();
00516 }
00517 
00522 void QwtThermo::setAlarmBrush(const QBrush& b)
00523 {
00524     d_alarmBrush = b;
00525     update();
00526 }
00527 
00529 const QBrush& QwtThermo::alarmBrush() const
00530 {
00531     return d_alarmBrush;
00532 }
00533 
00538 void QwtThermo::setAlarmColor(const QColor &c)
00539 {
00540     d_alarmBrush.setColor(c);
00541     update();
00542 }
00543 
00545 const QColor &QwtThermo::alarmColor() const
00546 {
00547     return d_alarmBrush.color();
00548 }
00549 
00551 void QwtThermo::setAlarmLevel(double v)
00552 {
00553     d_alarmLevel = v;
00554     d_alarmEnabled = 1;
00555     update();
00556 }
00557 
00559 double QwtThermo::alarmLevel() const
00560 {
00561     return d_alarmLevel;
00562 }
00563 
00565 void QwtThermo::setPipeWidth(int w)
00566 {
00567     if (w > 0)
00568     {
00569         d_thermoWidth = w;
00570         layoutThermo();
00571     }
00572 }
00573 
00575 int QwtThermo::pipeWidth() const
00576 {
00577     return d_thermoWidth;
00578 }
00579 
00580 
00595 void QwtThermo::setMargin(int)
00596 {
00597 }
00598 
00599 
00604 void QwtThermo::setAlarmEnabled(bool tf)
00605 {
00606     d_alarmEnabled = tf;
00607     update();
00608 }
00609 
00611 bool QwtThermo::alarmEnabled() const
00612 {
00613     return d_alarmEnabled;
00614 }
00615 
00621 QSizePolicy QwtThermo::sizePolicy() const
00622 {
00623     QSizePolicy sp;
00624     if ( scaleDraw()->orientation() == QwtScaleDraw::Left ||
00625         scaleDraw()->orientation() == QwtScaleDraw::Right )
00626     {
00627         sp.setHorData( QSizePolicy::Fixed );
00628         sp.setVerData( QSizePolicy::MinimumExpanding );
00629     }
00630     else
00631     {
00632         sp.setHorData( QSizePolicy::MinimumExpanding );
00633         sp.setVerData( QSizePolicy::Fixed );
00634     }
00635     return sp;
00636 }
00637 
00642 QSize QwtThermo::sizeHint() const
00643 {
00644     return minimumSizeHint();
00645 }
00646 
00652 QSize QwtThermo::minimumSizeHint() const
00653 {
00654     int w = 0, h = 0;
00655 
00656     if ( d_scalePos != None )
00657     {
00658         int smw = scaleDraw()->minWidth( QPen(), fontMetrics() );
00659         int smh = scaleDraw()->minHeight( QPen(), fontMetrics() );
00660 
00661         if ( d_orient == Qt::Vertical )
00662         {
00663             w = d_thermoWidth + smw + 3 * d_borderWidth + d_scaleDist;
00664             h = smh + 2 * d_borderWidth;
00665         }
00666         else
00667         {
00668             w = smw + 2 * d_borderWidth;
00669             h = d_thermoWidth + smh + 3 * d_borderWidth + d_scaleDist;
00670         }
00671 
00672     }
00673     else // no scale
00674     {
00675         if ( d_orient == Qt::Vertical )
00676         {
00677             w = d_thermoWidth + 2 * d_borderWidth;
00678             h = 200 + 2 * d_borderWidth;
00679         }
00680         else
00681         {
00682             w = 200 + 2 * d_borderWidth;
00683             h = d_thermoWidth + 2 * d_borderWidth;
00684         }
00685     }
00686     return QSize( w, h );
00687 }
00688 
00689 // Local Variables:
00690 // mode: C++
00691 // c-file-style: "stroustrup"
00692 // indent-tabs-mode: nil
00693 // End:

Generated on Sun Nov 21 11:12:44 2004 for Qwt User's Guide by doxygen 1.3.5