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 Tue Nov 16 21:12:21 2004 for Qwt User's Guide by doxygen 1.3.8