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

qwt_slider.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 // vim: expandtab 00011 00012 #include <math.h> 00013 #include <qstyle.h> 00014 #include <qevent.h> 00015 #include <qdrawutil.h> 00016 #include <qpainter.h> 00017 #include "qwt_paint_buffer.h" 00018 #include "qwt_slider.h" 00019 00040 QwtSlider::QwtSlider(QWidget *parent, const char *name, 00041 Qt::Orientation orient, ScalePos scalePos, BGSTYLE bgStyle): 00042 QwtSliderBase(orient, parent, name, Qt::WRepaintNoErase|Qt::WResizeNoErase) 00043 { 00044 d_borderWidth = 2; 00045 d_scaleDist = 4; 00046 d_scalePos = scalePos; 00047 d_xMargin = 0; 00048 d_yMargin = 0; 00049 d_bgStyle = bgStyle; 00050 00051 if (bgStyle == BgSlot) 00052 { 00053 d_thumbLength = 16; 00054 d_thumbWidth = 30; 00055 } 00056 else 00057 { 00058 d_thumbLength = 31; 00059 d_thumbWidth = 16; 00060 } 00061 00062 d_sliderRect.setRect(0,0,8,8); 00063 00064 QwtScaleDraw::Orientation so; 00065 if ( orientation() == Qt::Vertical ) 00066 { 00067 // enforce a valid combination of scale position and orientation 00068 if ((d_scalePos == Bottom) || (d_scalePos == Top)) 00069 d_scalePos = None; 00070 // adopt the policy of layoutSlider (None lays out like Left) 00071 if (d_scalePos == Right) 00072 so = QwtScaleDraw::Right; 00073 else 00074 so = QwtScaleDraw::Left; 00075 } 00076 else 00077 { 00078 // enforce a valid combination of scale position and orientation 00079 if ((d_scalePos == Left) || (d_scalePos == Right)) 00080 d_scalePos = None; 00081 // adopt the policy of layoutSlider (None lays out like Bottom) 00082 if (d_scalePos == Top) 00083 so = QwtScaleDraw::Top; 00084 else 00085 so = QwtScaleDraw::Bottom; 00086 } 00087 00088 scaleDraw()->setGeometry(0,0,100,so); 00089 } 00090 00099 void QwtSlider::setOrientation(Qt::Orientation o) 00100 { 00101 if (o == Qt::Horizontal) 00102 { 00103 if ((d_scalePos == Left) || (d_scalePos == Right)) 00104 d_scalePos = None; 00105 } 00106 else // if (o == Qt::Vertical) 00107 { 00108 if ((d_scalePos == Bottom) || (d_scalePos == Top)) 00109 d_scalePos = None; 00110 } 00111 QwtSliderBase::setOrientation(o); 00112 layoutSlider(); 00113 } 00114 00127 void QwtSlider::setScalePosition(ScalePos s) 00128 { 00129 d_scalePos = s; 00130 if ((s == Bottom) || (s == Top)) 00131 setOrientation(Qt::Horizontal); 00132 else if ((s == Left) || (s == Right)) 00133 setOrientation(Qt::Vertical); 00134 else 00135 layoutSlider(); 00136 } 00137 00139 QwtSlider::ScalePos QwtSlider::scalePosition() const 00140 { 00141 return d_scalePos; 00142 } 00143 00148 void QwtSlider::setBorderWidth(int bd) 00149 { 00150 if ( bd < 0 ) 00151 bd = 0; 00152 00153 if ( bd != d_borderWidth ) 00154 { 00155 d_borderWidth = bd; 00156 layoutSlider(); 00157 } 00158 } 00159 00164 void QwtSlider::setThumbLength(int thumbLength) 00165 { 00166 if ( thumbLength < 8 ) 00167 thumbLength = 8; 00168 00169 if ( thumbLength != d_thumbLength ) 00170 { 00171 d_thumbLength = thumbLength; 00172 layoutSlider(); 00173 } 00174 } 00175 00180 void QwtSlider::setThumbWidth(int w) 00181 { 00182 if ( w < 4 ) 00183 w = 4; 00184 00185 if ( d_thumbWidth != w ) 00186 { 00187 d_thumbWidth = w; 00188 layoutSlider(); 00189 } 00190 } 00191 00192 00194 void QwtSlider::scaleChange() 00195 { 00196 if (!hasUserScale()) 00197 { 00198 scaleDraw()->setScale(minValue(), maxValue(), 00199 scaleMaxMajor(), scaleMaxMinor(), 00200 scaleDraw()->scaleDiv().logScale()); 00201 } 00202 00203 layoutSlider(); 00204 } 00205 00206 00208 void QwtSlider::fontChange(const QFont &f) 00209 { 00210 QwtSliderBase::fontChange( f ); 00211 layoutSlider(); 00212 } 00213 00215 void QwtSlider::drawSlider(QPainter *p, const QRect &r) 00216 { 00217 QRect cr(r); 00218 00219 if (d_bgStyle & BgTrough) 00220 { 00221 qDrawShadePanel(p, r.x(), r.y(), 00222 r.width(), r.height(), 00223 colorGroup(), TRUE, d_borderWidth,0); 00224 00225 cr.setRect(r.x() + d_borderWidth, 00226 r.y() + d_borderWidth, 00227 r.width() - 2 * d_borderWidth, 00228 r.height() - 2 * d_borderWidth); 00229 00230 p->fillRect(cr.x(), cr.y(), cr.width(), cr.height(), 00231 colorGroup().brush(QColorGroup::Mid)); 00232 } 00233 00234 if ( d_bgStyle & BgSlot) 00235 { 00236 int ws = 4; 00237 int ds = d_thumbLength / 2 - 4; 00238 if ( ds < 1 ) 00239 ds = 1; 00240 00241 QRect rSlot; 00242 if (orientation() == Qt::Horizontal) 00243 { 00244 if ( cr.height() & 1 ) 00245 ws++; 00246 rSlot = QRect(cr.x() + ds, 00247 cr.y() + (cr.height() - ws) / 2, 00248 cr.width() - 2 * ds, ws); 00249 } 00250 else 00251 { 00252 if ( cr.width() & 1 ) 00253 ws++; 00254 rSlot = QRect(cr.x() + (cr.width() - ws) / 2, 00255 cr.y() + ds, 00256 ws, cr.height() - 2 * ds); 00257 } 00258 p->fillRect(rSlot.x(), rSlot.y(), rSlot.width(), rSlot.height(), 00259 colorGroup().brush(QColorGroup::Dark)); 00260 qDrawShadePanel(p, rSlot.x(), rSlot.y(), 00261 rSlot.width(), rSlot.height(), colorGroup(), TRUE, 1 ,0); 00262 00263 } 00264 00265 if ( isValid() ) 00266 drawThumb(p, cr, xyPosition(value())); 00267 } 00268 00270 void QwtSlider::drawThumb(QPainter *p, const QRect &sliderRect, int pos) 00271 { 00272 pos++; // shade line points one pixel below 00273 if (orientation() == Qt::Horizontal) 00274 { 00275 qDrawShadePanel(p, pos - d_thumbLength / 2, 00276 sliderRect.y(), d_thumbLength, sliderRect.height(), 00277 colorGroup(), FALSE, d_borderWidth, 00278 &colorGroup().brush(QColorGroup::Button)); 00279 00280 qDrawShadeLine(p, pos, sliderRect.y(), 00281 pos, sliderRect.y() + sliderRect.height() - 2, 00282 colorGroup(), TRUE, 1); 00283 } 00284 else // Vertical 00285 { 00286 qDrawShadePanel(p,sliderRect.x(), pos - d_thumbLength / 2, 00287 sliderRect.width(), d_thumbLength, 00288 colorGroup(),FALSE, d_borderWidth, 00289 &colorGroup().brush(QColorGroup::Button)); 00290 00291 qDrawShadeLine(p, sliderRect.x(), pos, 00292 sliderRect.x() + sliderRect.width() - 2, pos, 00293 colorGroup(), TRUE, 1); 00294 } 00295 } 00296 00298 int QwtSlider::xyPosition(double v) const 00299 { 00300 int pos; 00301 if ( minValue() == scaleDraw()->d1() && maxValue() == scaleDraw()->d2() ) 00302 { 00303 // We prefer to use the transformation of scaleDraw 00304 // So ticks and marker are always in sync and we don't have 00305 // to take care of rounding problems. 00306 00307 pos = scaleDraw()->transform(v); 00308 } 00309 else 00310 { 00311 // range and scaleDraw differ ? Sounds strange but 00312 // might happen with logarithmic scales 00313 00314 const double f = (v - minValue()) / (maxValue() - minValue()); 00315 double dPos; 00316 if ( orientation() == Qt::Horizontal ) 00317 dPos = scaleDraw()->i1() + f * (scaleDraw()->i2() - scaleDraw()->i1()); 00318 else 00319 dPos = scaleDraw()->i1() - f * (scaleDraw()->i1() - scaleDraw()->i2()); 00320 pos = qRound(dPos); 00321 } 00322 return pos; 00323 } 00324 00326 double QwtSlider::getValue(const QPoint &p) 00327 { 00328 double rv; 00329 00330 if ( minValue() == scaleDraw()->d1() && maxValue() == scaleDraw()->d2() ) 00331 { 00332 rv = scaleDraw()->invTransform( 00333 orientation() == Qt::Horizontal ? p.x() : p.y()); 00334 } 00335 else 00336 { 00337 double pos; 00338 double range; 00339 if ( orientation() == Qt::Horizontal ) 00340 { 00341 pos = p.x() - scaleDraw()->i1(); 00342 range = scaleDraw()->i2() - scaleDraw()->i1(); 00343 } 00344 else 00345 { 00346 pos = scaleDraw()->i1() - p.y(); 00347 range = scaleDraw()->i1() - scaleDraw()->i2(); 00348 } 00349 00350 rv = minValue() + pos / range * (maxValue() - minValue()); 00351 } 00352 00353 return(rv); 00354 } 00355 00356 00363 void QwtSlider::getScrollMode(const QPoint &p, 00364 int &scrollMode, int &direction ) 00365 { 00366 if (!d_sliderRect.contains(p)) 00367 { 00368 scrollMode = ScrNone; 00369 direction = 0; 00370 return; 00371 } 00372 00373 const int pos = ( orientation() == Qt::Horizontal ) ? p.x() : p.y(); 00374 const int markerPos = xyPosition(value()); 00375 00376 if ((pos > markerPos - d_thumbLength / 2) 00377 && (pos < markerPos + d_thumbLength / 2)) 00378 { 00379 scrollMode = ScrMouse; 00380 direction = 0; 00381 return; 00382 } 00383 00384 scrollMode = ScrPage; 00385 direction = (pos > markerPos) ? 1 : -1; 00386 if ( scaleDraw()->i1() > scaleDraw()->i2() ) 00387 direction = -direction; 00388 } 00389 00391 void QwtSlider::paintEvent(QPaintEvent *e) 00392 { 00393 const QRect &ur = e->rect(); 00394 if ( ur.isValid() ) 00395 { 00396 QwtPaintBuffer paintBuffer(this, ur); 00397 draw(paintBuffer.painter(), ur); 00398 } 00399 } 00400 00402 void QwtSlider::draw(QPainter *painter, const QRect&) 00403 { 00404 if (d_scalePos != None) 00405 scaleDraw()->draw(painter); 00406 00407 drawSlider(painter, d_sliderRect); 00408 if ( hasFocus() ) 00409 { 00410 const QRect rect = d_sliderRect; 00411 00412 #if QT_VERSION < 300 00413 style().drawFocusRect(painter, rect, colorGroup()); 00414 #else 00415 style().drawPrimitive(QStyle::PE_FocusRect, painter, 00416 rect, colorGroup()); 00417 #endif 00418 } 00419 } 00420 00422 void QwtSlider::resizeEvent(QResizeEvent *) 00423 { 00424 layoutSlider( FALSE ); 00425 } 00426 00433 void QwtSlider::layoutSlider( bool update_geometry ) 00434 { 00435 int sliderWidth = d_thumbWidth; 00436 int sld1 = d_thumbLength / 2 - 1; 00437 int sld2 = d_thumbLength / 2 + d_thumbLength % 2; 00438 if ( d_bgStyle & BgTrough ) 00439 { 00440 sliderWidth += 2 * d_borderWidth; 00441 sld1 += d_borderWidth; 00442 sld2 += d_borderWidth; 00443 } 00444 00445 int scd = 0; 00446 if ( d_scalePos != None ) 00447 { 00448 int d1, d2; 00449 scaleDraw()->minBorderDist(fontMetrics(), d1, d2); 00450 scd = QMAX(d1, d2); 00451 } 00452 00453 int slo = scd - sld1; 00454 if ( slo < 0 ) 00455 slo = 0; 00456 00457 const QRect r = rect(); 00458 if (orientation() == Qt::Horizontal) 00459 { 00460 switch (d_scalePos) 00461 { 00462 case Top: 00463 d_sliderRect.setRect( 00464 r.x() + d_xMargin + slo, 00465 r.y() + r.height() - 00466 d_yMargin - sliderWidth, 00467 r.width() - 2 * d_xMargin - 2 * slo, 00468 sliderWidth); 00469 scaleDraw()->setGeometry( 00470 d_sliderRect.x() + sld1, 00471 d_sliderRect.y() - d_scaleDist, 00472 d_sliderRect.width() - sld1 - sld2, 00473 QwtScaleDraw::Top); 00474 break; 00475 00476 case Bottom: 00477 d_sliderRect.setRect( 00478 r.x() + d_xMargin + slo, 00479 r.y() + d_yMargin, 00480 r.width() - 2 * d_xMargin - 2 * slo, 00481 sliderWidth); 00482 scaleDraw()->setGeometry( 00483 d_sliderRect.x() + sld1, 00484 d_sliderRect.y() + d_sliderRect.height() + d_scaleDist, 00485 d_sliderRect.width() - sld1 - sld2, 00486 QwtScaleDraw::Bottom); 00487 break; 00488 00489 case None: // like Bottom, but no scale. See QwtSlider(). 00490 default: // inconsistent orientation and scale position 00491 // QwtScaleDraw is derived from QwtDiMap. 00492 // The map serves to transform between coordinates and doubles. 00493 d_sliderRect.setRect( 00494 r.x() + d_xMargin + slo, 00495 r.y() + d_yMargin, 00496 r.width() - 2 * d_xMargin - 2 * slo, 00497 sliderWidth); 00498 scaleDraw()->setIntRange( 00499 d_sliderRect.x() + sld1, 00500 d_sliderRect.x() + d_sliderRect.width() - sld2 - 1); 00501 break; 00502 } 00503 } 00504 else // if (orientation() == Qt::Vertical 00505 { 00506 switch (d_scalePos) 00507 { 00508 case Right: 00509 d_sliderRect.setRect( 00510 r.x() + d_xMargin, 00511 r.y() + d_yMargin + slo, 00512 sliderWidth, 00513 r.height() - 2 * d_yMargin - 2 * slo); 00514 scaleDraw()->setGeometry( 00515 d_sliderRect.x() + d_sliderRect.width() + d_scaleDist, 00516 d_sliderRect.y() + sld1, 00517 d_sliderRect.height() - sld1 - sld2, 00518 QwtScaleDraw::Right); 00519 break; 00520 00521 case Left: 00522 d_sliderRect.setRect( 00523 r.x() + r.width() - sliderWidth - d_xMargin, 00524 r.y() + d_yMargin + slo, 00525 sliderWidth, 00526 r.height() - 2 * d_yMargin - 2 * slo); 00527 scaleDraw()->setGeometry( 00528 d_sliderRect.x() - d_scaleDist, 00529 d_sliderRect.y() + sld1, 00530 d_sliderRect.height() - sld1 - sld2, 00531 QwtScaleDraw::Left); 00532 break; 00533 00534 case None: // like Left, but no scale. See QwtSlider(). 00535 default: // inconsistent orientation and scale position 00536 // QwtScaleDraw is derived from QwtDiMap. 00537 // The map serves to transform between coordinates and doubles. 00538 d_sliderRect.setRect( 00539 r.x() + r.width() - sliderWidth - d_xMargin, 00540 r.y() + d_yMargin + slo, 00541 sliderWidth, 00542 r.height() - 2 * d_yMargin - 2 * slo); 00543 scaleDraw()->setIntRange( 00544 d_sliderRect.y() + d_sliderRect.height() - sld2 - 1, 00545 d_sliderRect.y() + sld1); 00546 break; 00547 } 00548 } 00549 00550 if ( update_geometry ) 00551 { 00552 updateGeometry(); 00553 update(); 00554 } 00555 } 00556 00558 void QwtSlider::valueChange() 00559 { 00560 QwtSliderBase::valueChange(); 00561 update(); 00562 } 00563 00564 00566 void QwtSlider::rangeChange() 00567 { 00568 if (!hasUserScale()) 00569 { 00570 scaleDraw()->setScale(minValue(), maxValue(), 00571 scaleMaxMajor(), scaleMaxMinor(), 00572 scaleDraw()->scaleDiv().logScale()); 00573 } 00574 00575 QwtSliderBase::rangeChange(); 00576 layoutSlider(); 00577 } 00578 00584 void QwtSlider::setMargins(int xMargin, int yMargin) 00585 { 00586 if ( xMargin < 0 ) 00587 xMargin = 0; 00588 if ( yMargin < 0 ) 00589 yMargin = 0; 00590 00591 if ( xMargin != d_xMargin || yMargin != d_yMargin ) 00592 { 00593 d_xMargin = xMargin; 00594 d_yMargin = yMargin; 00595 layoutSlider(); 00596 } 00597 } 00598 00603 QSizePolicy QwtSlider::sizePolicy() const 00604 { 00605 QSizePolicy sp; 00606 if ( orientation() == Qt::Horizontal ) 00607 { 00608 sp.setHorData( QSizePolicy::MinimumExpanding ); 00609 sp.setVerData( QSizePolicy::Fixed ); 00610 } 00611 else 00612 { 00613 sp.setHorData( QSizePolicy::Fixed ); 00614 sp.setVerData( QSizePolicy::MinimumExpanding ); 00615 } 00616 return sp; 00617 } 00618 00622 QSize QwtSlider::sizeHint() const 00623 { 00624 return minimumSizeHint(); 00625 } 00626 00632 QSize QwtSlider::minimumSizeHint() const 00633 { 00634 int w = 0, h = 0; 00635 00636 int sliderWidth = d_thumbWidth; 00637 if (d_bgStyle & BgTrough) 00638 sliderWidth += 2 * d_borderWidth; 00639 00640 if (d_scalePos != None) 00641 { 00642 int msWidth = scaleDraw()->minWidth( QPen(), fontMetrics() ); 00643 int msHeight = scaleDraw()->minHeight( QPen(), fontMetrics() ); 00644 00645 int d1, d2; 00646 scaleDraw()->minBorderDist(fontMetrics(), d1, d2); 00647 int msMbd = QMAX(d1, d2); 00648 00649 int mbd = d_thumbLength / 2; 00650 if (d_bgStyle & BgTrough) 00651 mbd += d_borderWidth; 00652 00653 if ( mbd < msMbd ) 00654 mbd = msMbd; 00655 00656 if (orientation() == Qt::Vertical) 00657 { 00658 w = 2 * d_xMargin + sliderWidth + msWidth + d_scaleDist; 00659 h = msHeight - 2 * msMbd + 2 * mbd + 2 * d_yMargin; 00660 } 00661 else 00662 { 00663 w = msWidth - 2 * msMbd + 2 * mbd + 2 * d_xMargin; 00664 h = 2 * d_yMargin + sliderWidth + msHeight + d_scaleDist; 00665 } 00666 } 00667 else // no scale 00668 { 00669 if (orientation() == Qt::Vertical) 00670 { 00671 w = 2 * d_xMargin + sliderWidth; 00672 h = 200 + 2 * d_yMargin; 00673 } 00674 else 00675 { 00676 w = 200 + 2 * d_xMargin; 00677 h = 2 * d_yMargin + sliderWidth; 00678 } 00679 } 00680 return QSize(w,h); 00681 } 00682 00683 // Local Variables: 00684 // mode: C++ 00685 // c-file-style: "stroustrup" 00686 // indent-tabs-mode: nil 00687 // End:

Generated on Tue Nov 16 21:12:21 2004 for Qwt User's Guide by doxygen 1.3.8