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: