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

qwt_thermo.cpp

Go to the documentation of this file.
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 <qstyle.h>
00012 #include <qpixmap.h>
00013 #include <qdrawutil.h>
00014 #include "qwt_math.h"
00015 #include "qwt_paint_buffer.h"
00016 #include "qwt_thermo.h"
00017 
00019 QwtThermo::QwtThermo(QWidget *parent, const char *name): 
00020     QWidget(parent, name, WRepaintNoErase|WResizeNoErase)
00021 {
00022     init();
00023 }
00024 
00026 QwtThermo::~QwtThermo()
00027 {
00028 }
00029 
00031 void QwtThermo::init()
00032 {
00033     // initialize data members
00034     d_orient = Qt::Vertical;
00035     d_scalePos = Left;
00036     d_scaleDist = 3;
00037     d_thermoWidth = 10;
00038     d_borderWidth = 2;
00039     d_maxValue = 1.0;
00040     d_minValue = 0.0;
00041     d_value = 0.0;
00042     d_alarmLevel = 0.0;
00043     d_alarmEnabled = 0;
00044 
00045     // initialize colors;
00046     d_fillColor = black;
00047     d_alarmColor = white;
00048 
00049     // initialize scales
00050     d_map.setDblRange(d_minValue, d_maxValue);
00051     d_scaleDraw->setScale(d_minValue, d_maxValue, d_maxMajor, d_maxMinor);
00052 }
00053 
00054 
00056 void QwtThermo::setValue(double v)
00057 {
00058     if (d_value != v)
00059     {
00060         d_value = v;
00061         update();
00062     }
00063 }
00064 
00066 void QwtThermo::paintEvent(QPaintEvent *e)
00067 {
00068     // Use double-buffering
00069     const QRect &ur = e->rect();
00070     if ( ur.isValid() )
00071     {
00072     QwtPaintBuffer paintBuffer(this, ur);
00073         draw(paintBuffer.painter(), ur);
00074     }
00075 }
00076 
00078 void QwtThermo::draw(QPainter *p, const QRect& ur)
00079 {
00080     if ( !d_thermoRect.contains(ur) )
00081     {
00082         if (d_scalePos != None)
00083             d_scaleDraw->draw(p);
00084 
00085         qDrawShadePanel(p,
00086             d_thermoRect.x() - d_borderWidth,
00087             d_thermoRect.y() - d_borderWidth,
00088             d_thermoRect.width() + 2*d_borderWidth,
00089             d_thermoRect.height() + 2*d_borderWidth,
00090             colorGroup(), TRUE, d_borderWidth,0);
00091     }
00092     drawThermo(p);
00093 }
00094 
00096 void QwtThermo::resizeEvent(QResizeEvent *)
00097 {
00098     layoutThermo( FALSE );
00099 }
00100 
00102 //  the current rect and fonts.
00103 //  \param update_geometry notify the layout system and call update
00104 //         to redraw the scale
00105 void QwtThermo::layoutThermo( bool update_geometry )
00106 {
00107     QRect r = this->rect();
00108     int mbd = 0;
00109     if ( d_scalePos != None )
00110   {
00111     int d1, d2;
00112         d_scaleDraw->minBorderDist(fontMetrics(), d1, d2);
00113         mbd = QMAX(d1, d2);
00114   }
00115 
00116     if ( d_orient == Qt::Horizontal )
00117     {
00118         switch ( d_scalePos )
00119         {
00120             case None:
00121                 d_thermoRect.setRect(r.x() + d_borderWidth,
00122                     r.y() + d_borderWidth,
00123                     r.width() - 2*d_borderWidth,
00124                     r.height() - 2*d_borderWidth);
00125                 break;
00126 
00127             case Bottom:
00128                 d_thermoRect.setRect(r.x() + mbd + d_borderWidth,
00129                     r.y() + d_borderWidth,
00130                     r.width() - 2*(d_borderWidth + mbd),
00131                     d_thermoWidth);
00132                 d_scaleDraw->setGeometry(d_thermoRect.x(),
00133                     d_thermoRect.y() + d_thermoRect.height()
00134                     + d_borderWidth + d_scaleDist,
00135                     d_thermoRect.width(),
00136                     QwtScaleDraw::Bottom);
00137                 break;
00138 
00139             case Top:
00140             default:
00141                 d_thermoRect.setRect(r.x() + mbd + d_borderWidth,
00142                     r.y() + r.height()
00143                     - d_thermoWidth - 2*d_borderWidth,
00144                     r.width() - 2*(d_borderWidth + mbd),
00145                     d_thermoWidth);
00146                 d_scaleDraw->setGeometry(d_thermoRect.x(),
00147                     d_thermoRect.y() - d_borderWidth - d_scaleDist,
00148                     d_thermoRect.width(),
00149                     QwtScaleDraw::Top);
00150                 break;
00151         }
00152         d_map.setIntRange(d_thermoRect.x(),
00153         d_thermoRect.x() + d_thermoRect.width() - 1);
00154     }
00155     else // Qt::Vertical
00156     {
00157         switch ( d_scalePos )
00158         {
00159             case None:
00160                 d_thermoRect.setRect(r.x() + d_borderWidth,
00161                     r.y() + d_borderWidth,
00162                     r.width() - 2*d_borderWidth,
00163                     r.height() - 2*d_borderWidth);
00164                 break;
00165 
00166             case Left:
00167                 d_thermoRect.setRect(r.x() +  r.width()
00168                     - 2*d_borderWidth - d_thermoWidth,
00169                     r.y() + mbd + d_borderWidth,
00170                     d_thermoWidth,
00171                     r.height() - 2*(d_borderWidth + mbd));
00172                 d_scaleDraw->setGeometry(d_thermoRect.x() - 
00173                     d_scaleDist - d_borderWidth,
00174                     d_thermoRect.y(),
00175                     d_thermoRect.height(),
00176                     QwtScaleDraw::Left);
00177                 break;
00178 
00179             case Right:
00180             default:
00181                 d_thermoRect.setRect(r.x() + d_borderWidth,
00182                     r.y() + mbd + d_borderWidth,
00183                     d_thermoWidth,
00184                     r.height() - 2*(d_borderWidth + mbd));
00185                 d_scaleDraw->setGeometry(d_thermoRect.x() + d_thermoRect.width()
00186                     + d_borderWidth + d_scaleDist,
00187                     d_thermoRect.y(),
00188                     d_thermoRect.height(),
00189                     QwtScaleDraw::Right);
00190                 break;
00191         }
00192         d_map.setIntRange( d_thermoRect.y() + d_thermoRect.height() - 1,
00193             d_thermoRect.y());
00194     }
00195     if ( update_geometry )
00196     {
00197         updateGeometry();
00198         update();
00199     }
00200 }
00201 
00214 void QwtThermo::setOrientation(Qt::Orientation o, ScalePos s)
00215 {
00216     switch(o)
00217     {
00218         case Qt::Horizontal:
00219             d_orient = Qt::Horizontal;
00220             if ((s == None) || (s == Bottom) || (s == Top))
00221                 d_scalePos = s;
00222             else
00223                 d_scalePos = None;
00224             break;
00225 
00226         case Qt::Vertical:
00227             d_orient = Qt::Vertical;
00228             if ((s == None) || (s == Left) || (s == Right))
00229                 d_scalePos = s;
00230             else
00231                 d_scalePos = None;
00232             break;
00233     }
00234     layoutThermo();
00235 }
00236 
00238 void QwtThermo::fontChange(const QFont &f)
00239 {
00240     QWidget::fontChange( f );
00241     layoutThermo();
00242 }
00243 
00245 void QwtThermo::scaleChange()
00246 {
00247     update();
00248     layoutThermo();
00249 }
00250 
00252 void QwtThermo::drawThermo(QPainter *p)
00253 {
00254     int alarm  = 0, taval = 0;
00255 
00256     QRect fRect;
00257     QRect aRect;
00258     QRect bRect;
00259 
00260     int inverted = ( d_maxValue < d_minValue );
00261 
00262     //
00263     //  Determine if value exceeds alarm threshold.
00264     //  Note: The alarm value is allowed to lie
00265     //        outside the interval (minValue, maxValue).
00266     //
00267     if (d_alarmEnabled)
00268     {
00269         if (inverted)
00270         {
00271             alarm = ((d_alarmLevel >= d_maxValue)
00272                  && (d_alarmLevel <= d_minValue)
00273                  && (d_value >= d_alarmLevel));
00274         
00275         }
00276         else
00277         {
00278             alarm = (( d_alarmLevel >= d_minValue)
00279                  && (d_alarmLevel <= d_maxValue)
00280                  && (d_value >= d_alarmLevel));
00281         }
00282     }
00283 
00284     //
00285     //  transform values
00286     //
00287     int tval = d_map.limTransform(d_value);
00288 
00289     if (alarm)
00290        taval = d_map.limTransform(d_alarmLevel);
00291 
00292     //
00293     //  calculate recangles
00294     //
00295     if ( d_orient == Qt::Horizontal )
00296     {
00297         if (inverted)
00298         {
00299             bRect.setRect(d_thermoRect.x(), d_thermoRect.y(),
00300                   tval - d_thermoRect.x(),
00301                   d_thermoRect.height());
00302         
00303             if (alarm)
00304             {
00305                 aRect.setRect(tval, d_thermoRect.y(),
00306                       taval - tval + 1,
00307                       d_thermoRect.height());
00308                 fRect.setRect(taval + 1, d_thermoRect.y(),
00309                       d_thermoRect.x() + d_thermoRect.width() - (taval + 1),
00310                       d_thermoRect.height());
00311             }
00312             else
00313             {
00314                 fRect.setRect(tval, d_thermoRect.y(),
00315                       d_thermoRect.x() + d_thermoRect.width() - tval,
00316                       d_thermoRect.height());
00317             }
00318         }
00319         else
00320         {
00321             bRect.setRect(tval + 1, d_thermoRect.y(),
00322                   d_thermoRect.width() - (tval + 1 - d_thermoRect.x()),
00323                   d_thermoRect.height());
00324         
00325             if (alarm)
00326             {
00327                 aRect.setRect(taval, d_thermoRect.y(),
00328                       tval - taval + 1,
00329                       d_thermoRect.height());
00330                 fRect.setRect(d_thermoRect.x(), d_thermoRect.y(),
00331                       taval - d_thermoRect.x(),
00332                       d_thermoRect.height());
00333             }
00334             else
00335             {
00336                 fRect.setRect(d_thermoRect.x(), d_thermoRect.y(),
00337                       tval - d_thermoRect.x() + 1,
00338                       d_thermoRect.height());
00339             }
00340         
00341         }
00342     }
00343     else // Qt::Vertical
00344     {
00345         if (tval < d_thermoRect.y())
00346             tval = d_thermoRect.y();
00347         else 
00348         {
00349             if (tval > d_thermoRect.y() + d_thermoRect.height())
00350                 tval = d_thermoRect.y() + d_thermoRect.height();
00351         }
00352 
00353         if (inverted)
00354         {
00355             bRect.setRect(d_thermoRect.x(), tval + 1,
00356             d_thermoRect.width(),
00357             d_thermoRect.height() - (tval + 1 - d_thermoRect.y()));
00358 
00359             if (alarm)
00360             {
00361                 aRect.setRect(d_thermoRect.x(), taval,
00362                     d_thermoRect.width(),
00363                     tval - taval + 1);
00364                 fRect.setRect(d_thermoRect.x(), d_thermoRect.y(),
00365                     d_thermoRect.width(),
00366                 taval - d_thermoRect.y());
00367             }
00368             else
00369             {
00370                 fRect.setRect(d_thermoRect.x(), d_thermoRect.y(),
00371                     d_thermoRect.width(),
00372                     tval - d_thermoRect.y() + 1);
00373             }
00374         }
00375         else
00376         {
00377             bRect.setRect(d_thermoRect.x(), d_thermoRect.y(),
00378             d_thermoRect.width(),
00379             tval - d_thermoRect.y());
00380             if (alarm)
00381             {
00382                 aRect.setRect(d_thermoRect.x(),tval,
00383                     d_thermoRect.width(),
00384                     taval - tval + 1);
00385                 fRect.setRect(d_thermoRect.x(),taval + 1,
00386                     d_thermoRect.width(),
00387                     d_thermoRect.y() + d_thermoRect.height() - (taval + 1));
00388             }
00389             else
00390             {
00391                 fRect.setRect(d_thermoRect.x(),tval,
00392                     d_thermoRect.width(),
00393                 d_thermoRect.y() + d_thermoRect.height() - tval);
00394             }
00395         }
00396     }
00397 
00398     //
00399     // paint thermometer
00400     //
00401     p->fillRect(bRect, colorGroup().color(QColorGroup::Background));
00402 
00403     if (alarm)
00404        p->fillRect(aRect, d_alarmColor);
00405 
00406     p->fillRect(fRect, d_fillColor);
00407 }
00408 
00410 void QwtThermo::setBorderWidth(int w)
00411 {
00412     if ((w >= 0) && (w < (qwtMin(d_thermoRect.width(), 
00413         d_thermoRect.height()) + d_borderWidth) / 2  - 1))
00414     {
00415         d_borderWidth = w;
00416         layoutThermo();
00417     }
00418 }
00419 
00425 void QwtThermo::setRange(double vmin, double vmax)
00426 {
00427     d_minValue = vmin;
00428     d_maxValue = vmax;
00429 
00430     d_map.setDblRange(d_minValue, d_maxValue);
00431     if (!hasUserScale())
00432     {
00433         QwtScaleDiv oldscl(d_scaleDraw->scaleDiv());
00434 
00435         d_scaleDraw->setScale(d_minValue, d_maxValue, d_maxMajor, d_maxMinor);
00436         if (oldscl != d_scaleDraw->scaleDiv())
00437             scaleChange();
00438     }
00439     layoutThermo();
00440 }
00441 
00446 void QwtThermo::setFillColor(const QColor &c)
00447 {
00448     d_fillColor = c;
00449     update();
00450 }
00451 
00456 void QwtThermo::setAlarmColor(const QColor &c)
00457 {
00458     d_alarmColor = c;
00459     update();
00460 }
00461 
00463 void QwtThermo::setAlarmLevel(double v)
00464 {
00465     d_alarmLevel = v;
00466     d_alarmEnabled = 1;
00467     update();
00468 }
00469 
00471 void QwtThermo::setPipeWidth(int w)
00472 {
00473     if (w > 0)
00474     {
00475         d_thermoWidth = w;
00476         layoutThermo();
00477     }
00478 }
00479 
00480 
00495 void QwtThermo::setMargin(int)
00496 {
00497 }
00498 
00499 
00504 void QwtThermo::setAlarmEnabled(int tf)
00505 {
00506     d_alarmEnabled = tf;
00507     update();
00508 }
00509 
00515 QSizePolicy QwtThermo::sizePolicy() const
00516 {
00517     QSizePolicy sp;
00518     if ( d_scaleDraw->orientation() == QwtScaleDraw::Left ||
00519         d_scaleDraw->orientation() == QwtScaleDraw::Right )
00520     {
00521         sp.setHorData( QSizePolicy::Fixed );
00522         sp.setVerData( QSizePolicy::MinimumExpanding );
00523     }
00524     else
00525     {
00526         sp.setHorData( QSizePolicy::MinimumExpanding );
00527         sp.setVerData( QSizePolicy::Fixed );
00528     }
00529     return sp;
00530 }
00531 
00536 QSize QwtThermo::sizeHint() const
00537 {
00538     return minimumSizeHint();
00539 }
00540 
00546 QSize QwtThermo::minimumSizeHint() const
00547 {
00548     int w = 0, h = 0;
00549 
00550     if ( d_scalePos != None )
00551     {
00552         int smw = d_scaleDraw->minWidth( QPen(), fontMetrics() );
00553         int smh = d_scaleDraw->minHeight( QPen(), fontMetrics() );
00554 
00555         if ( d_orient == Qt::Vertical )
00556         {
00557             w = d_thermoWidth + smw + 3 * d_borderWidth + d_scaleDist;
00558             h = smh + 2 * d_borderWidth;
00559         }
00560         else
00561         {
00562             w = smw + 2 * d_borderWidth;
00563             h = d_thermoWidth + smh + 3 * d_borderWidth + d_scaleDist;
00564         }
00565 
00566     }
00567     else // no scale
00568     {
00569         if ( d_orient == Qt::Vertical )
00570         {
00571             w = d_thermoWidth + 2 * d_borderWidth;
00572             h = 200 + 2 * d_borderWidth;
00573         }
00574         else
00575         {
00576             w = 200 + 2 * d_borderWidth;
00577             h = d_thermoWidth + 2 * d_borderWidth;
00578         }
00579     }
00580     return QSize( w, h );
00581 }

Generated on Fri Nov 7 14:11:46 2003 for Qwt Developer's Guide by doxygen 1.3.2