00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <math.h>
00013 #include <qevent.h>
00014 #include <qdrawutil.h>
00015 #include <qpainter.h>
00016 #include <qwt_painter.h>
00017 #include "qwt_paint_buffer.h"
00018 #include "qwt_scale_draw.h"
00019 #include "qwt_scale_map.h"
00020 #include "qwt_slider.h"
00021
00022 class QwtSlider::PrivateData
00023 {
00024 public:
00025 QRect sliderRect;
00026
00027 int thumbLength;
00028 int thumbWidth;
00029 int borderWidth;
00030 int scaleDist;
00031 int xMargin;
00032 int yMargin;
00033
00034 QwtSlider::ScalePos scalePos;
00035 QwtSlider::BGSTYLE bgStyle;
00036
00037
00038
00039
00040
00041
00042 QwtScaleMap map;
00043 mutable QSize sizeHintCache;
00044 };
00045
00066 QwtSlider::QwtSlider(QWidget *parent,
00067 Qt::Orientation orientation, ScalePos scalePos, BGSTYLE bgStyle):
00068 QwtAbstractSlider(orientation, parent)
00069 {
00070 if (orientation == Qt::Vertical)
00071 setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
00072 else
00073 setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
00074
00075 #if QT_VERSION >= 0x040000
00076 setAttribute(Qt::WA_WState_OwnSizePolicy, false);
00077 #else
00078 clearWState( WState_OwnSizePolicy );
00079 #endif
00080
00081
00082 #if QT_VERSION < 0x040000
00083 setWFlags(Qt::WNoAutoErase);
00084 #endif
00085
00086 d_data = new QwtSlider::PrivateData;
00087
00088 d_data->borderWidth = 2;
00089 d_data->scaleDist = 4;
00090 d_data->scalePos = scalePos;
00091 d_data->xMargin = 0;
00092 d_data->yMargin = 0;
00093 d_data->bgStyle = bgStyle;
00094
00095 if (bgStyle == BgSlot)
00096 {
00097 d_data->thumbLength = 16;
00098 d_data->thumbWidth = 30;
00099 }
00100 else
00101 {
00102 d_data->thumbLength = 31;
00103 d_data->thumbWidth = 16;
00104 }
00105
00106 d_data->sliderRect.setRect(0,0,8,8);
00107
00108 QwtScaleDraw::Orientation so;
00109 if ( orientation == Qt::Vertical )
00110 {
00111
00112 if ((d_data->scalePos == Bottom) || (d_data->scalePos == Top))
00113 d_data->scalePos = None;
00114
00115 if (d_data->scalePos == Right)
00116 so = QwtScaleDraw::Right;
00117 else
00118 so = QwtScaleDraw::Left;
00119 }
00120 else
00121 {
00122
00123 if ((d_data->scalePos == Left) || (d_data->scalePos == Right))
00124 d_data->scalePos = None;
00125
00126 if (d_data->scalePos == Top)
00127 so = QwtScaleDraw::Top;
00128 else
00129 so = QwtScaleDraw::Bottom;
00130 }
00131
00132 scaleDraw()->setGeometry(0,0,100,so);
00133
00134 setRange(0.0, 100.0, 1.0);
00135 setValue(0.0);
00136 }
00137
00138 QwtSlider::~QwtSlider()
00139 {
00140 delete d_data;
00141 }
00142
00151 void QwtSlider::setOrientation(Qt::Orientation o)
00152 {
00153 if ( o == orientation() )
00154 return;
00155
00156 if (o == Qt::Horizontal)
00157 {
00158 if ((d_data->scalePos == Left) || (d_data->scalePos == Right))
00159 d_data->scalePos = None;
00160 }
00161 else
00162 {
00163 if ((d_data->scalePos == Bottom) || (d_data->scalePos == Top))
00164 d_data->scalePos = None;
00165 }
00166
00167 #if QT_VERSION >= 0x040000
00168 if ( !testAttribute(Qt::WA_WState_OwnSizePolicy) )
00169 #else
00170 if ( !testWState( WState_OwnSizePolicy ) )
00171 #endif
00172 {
00173 QSizePolicy sp = sizePolicy();
00174 sp.transpose();
00175 setSizePolicy(sp);
00176
00177 #if QT_VERSION >= 0x040000
00178 setAttribute(Qt::WA_WState_OwnSizePolicy, false);
00179 #else
00180 clearWState( WState_OwnSizePolicy );
00181 #endif
00182 }
00183
00184 QwtAbstractSlider::setOrientation(o);
00185 layoutSlider();
00186 }
00187
00200 void QwtSlider::setScalePosition(ScalePos s)
00201 {
00202 d_data->scalePos = s;
00203 if ((s == Bottom) || (s == Top))
00204 setOrientation(Qt::Horizontal);
00205 else if ((s == Left) || (s == Right))
00206 setOrientation(Qt::Vertical);
00207 else
00208 layoutSlider();
00209 }
00210
00212 QwtSlider::ScalePos QwtSlider::scalePosition() const
00213 {
00214 return d_data->scalePos;
00215 }
00216
00221 void QwtSlider::setBorderWidth(int bd)
00222 {
00223 if ( bd < 0 )
00224 bd = 0;
00225
00226 if ( bd != d_data->borderWidth )
00227 {
00228 d_data->borderWidth = bd;
00229 layoutSlider();
00230 }
00231 }
00232
00237 void QwtSlider::setThumbLength(int thumbLength)
00238 {
00239 if ( thumbLength < 8 )
00240 thumbLength = 8;
00241
00242 if ( thumbLength != d_data->thumbLength )
00243 {
00244 d_data->thumbLength = thumbLength;
00245 layoutSlider();
00246 }
00247 }
00248
00253 void QwtSlider::setThumbWidth(int w)
00254 {
00255 if ( w < 4 )
00256 w = 4;
00257
00258 if ( d_data->thumbWidth != w )
00259 {
00260 d_data->thumbWidth = w;
00261 layoutSlider();
00262 }
00263 }
00264
00265
00267 void QwtSlider::scaleChange()
00268 {
00269 layoutSlider();
00270 }
00271
00272
00274 void QwtSlider::fontChange(const QFont &f)
00275 {
00276 QwtAbstractSlider::fontChange( f );
00277 layoutSlider();
00278 }
00279
00281 void QwtSlider::drawSlider(QPainter *p, const QRect &r)
00282 {
00283 QRect cr(r);
00284
00285 if (d_data->bgStyle & BgTrough)
00286 {
00287 qDrawShadePanel(p, r.x(), r.y(),
00288 r.width(), r.height(),
00289 #if QT_VERSION < 0x040000
00290 colorGroup(),
00291 #else
00292 palette(),
00293 #endif
00294 true, d_data->borderWidth,0);
00295
00296 cr.setRect(r.x() + d_data->borderWidth,
00297 r.y() + d_data->borderWidth,
00298 r.width() - 2 * d_data->borderWidth,
00299 r.height() - 2 * d_data->borderWidth);
00300
00301 p->fillRect(cr.x(), cr.y(), cr.width(), cr.height(),
00302 #if QT_VERSION < 0x040000
00303 colorGroup().brush(QColorGroup::Mid)
00304 #else
00305 palette().brush(QPalette::Mid)
00306 #endif
00307 );
00308 }
00309
00310 if ( d_data->bgStyle & BgSlot)
00311 {
00312 int ws = 4;
00313 int ds = d_data->thumbLength / 2 - 4;
00314 if ( ds < 1 )
00315 ds = 1;
00316
00317 QRect rSlot;
00318 if (orientation() == Qt::Horizontal)
00319 {
00320 if ( cr.height() & 1 )
00321 ws++;
00322 rSlot = QRect(cr.x() + ds,
00323 cr.y() + (cr.height() - ws) / 2,
00324 cr.width() - 2 * ds, ws);
00325 }
00326 else
00327 {
00328 if ( cr.width() & 1 )
00329 ws++;
00330 rSlot = QRect(cr.x() + (cr.width() - ws) / 2,
00331 cr.y() + ds,
00332 ws, cr.height() - 2 * ds);
00333 }
00334 p->fillRect(rSlot.x(), rSlot.y(), rSlot.width(), rSlot.height(),
00335 #if QT_VERSION < 0x040000
00336 colorGroup().brush(QColorGroup::Dark)
00337 #else
00338 palette().brush(QPalette::Dark)
00339 #endif
00340 );
00341 qDrawShadePanel(p, rSlot.x(), rSlot.y(),
00342 rSlot.width(), rSlot.height(),
00343 #if QT_VERSION < 0x040000
00344 colorGroup(),
00345 #else
00346 palette(),
00347 #endif
00348 true, 1 ,0);
00349
00350 }
00351
00352 if ( isValid() )
00353 drawThumb(p, cr, xyPosition(value()));
00354 }
00355
00357 void QwtSlider::drawThumb(QPainter *p, const QRect &sliderRect, int pos)
00358 {
00359 pos++;
00360 if (orientation() == Qt::Horizontal)
00361 {
00362 qDrawShadePanel(p, pos - d_data->thumbLength / 2,
00363 sliderRect.y(), d_data->thumbLength, sliderRect.height(),
00364 #if QT_VERSION < 0x040000
00365 colorGroup(),
00366 #else
00367 palette(),
00368 #endif
00369 false, d_data->borderWidth,
00370 #if QT_VERSION < 0x040000
00371 &colorGroup().brush(QColorGroup::Button)
00372 #else
00373 &palette().brush(QPalette::Button)
00374 #endif
00375 );
00376
00377 qDrawShadeLine(p, pos, sliderRect.y(),
00378 pos, sliderRect.y() + sliderRect.height() - 2,
00379 #if QT_VERSION < 0x040000
00380 colorGroup(),
00381 #else
00382 palette(),
00383 #endif
00384 true, 1);
00385 }
00386 else
00387 {
00388 qDrawShadePanel(p,sliderRect.x(), pos - d_data->thumbLength / 2,
00389 sliderRect.width(), d_data->thumbLength,
00390 #if QT_VERSION < 0x040000
00391 colorGroup(),
00392 #else
00393 palette(),
00394 #endif
00395 false, d_data->borderWidth,
00396 #if QT_VERSION < 0x040000
00397 &colorGroup().brush(QColorGroup::Button)
00398 #else
00399 &palette().brush(QPalette::Button)
00400 #endif
00401 );
00402
00403 qDrawShadeLine(p, sliderRect.x(), pos,
00404 sliderRect.x() + sliderRect.width() - 2, pos,
00405 #if QT_VERSION < 0x040000
00406 colorGroup(),
00407 #else
00408 palette(),
00409 #endif
00410 true, 1);
00411 }
00412 }
00413
00415 int QwtSlider::xyPosition(double v) const
00416 {
00417 return d_data->map.transform(v);
00418 }
00419
00421 double QwtSlider::getValue(const QPoint &p)
00422 {
00423 return d_data->map.invTransform(
00424 orientation() == Qt::Horizontal ? p.x() : p.y());
00425 }
00426
00427
00434 void QwtSlider::getScrollMode(const QPoint &p,
00435 int &scrollMode, int &direction )
00436 {
00437 if (!d_data->sliderRect.contains(p))
00438 {
00439 scrollMode = ScrNone;
00440 direction = 0;
00441 return;
00442 }
00443
00444 const int pos = ( orientation() == Qt::Horizontal ) ? p.x() : p.y();
00445 const int markerPos = xyPosition(value());
00446
00447 if ((pos > markerPos - d_data->thumbLength / 2)
00448 && (pos < markerPos + d_data->thumbLength / 2))
00449 {
00450 scrollMode = ScrMouse;
00451 direction = 0;
00452 return;
00453 }
00454
00455 scrollMode = ScrPage;
00456 direction = (pos > markerPos) ? 1 : -1;
00457 if ( scaleDraw()->map().p1() > scaleDraw()->map().p2() )
00458 direction = -direction;
00459 }
00460
00462 void QwtSlider::paintEvent(QPaintEvent *e)
00463 {
00464 const QRect &ur = e->rect();
00465 if ( ur.isValid() )
00466 {
00467 #if QT_VERSION < 0x040000
00468 QwtPaintBuffer paintBuffer(this, ur);
00469 draw(paintBuffer.painter(), ur);
00470 #else
00471 QPainter painter(this);
00472 draw(&painter, ur);
00473 #endif
00474 }
00475 }
00476
00478 void QwtSlider::draw(QPainter *painter, const QRect&)
00479 {
00480 if (d_data->scalePos != None)
00481 {
00482 #if QT_VERSION < 0x040000
00483 scaleDraw()->draw(painter, colorGroup());
00484 #else
00485 scaleDraw()->draw(painter, palette());
00486 #endif
00487 }
00488
00489 drawSlider(painter, d_data->sliderRect);
00490
00491 if ( hasFocus() )
00492 QwtPainter::drawFocusRect(painter, this, d_data->sliderRect);
00493 }
00494
00496 void QwtSlider::resizeEvent(QResizeEvent *)
00497 {
00498 layoutSlider( false );
00499 }
00500
00507 void QwtSlider::layoutSlider( bool update_geometry )
00508 {
00509 int sliderWidth = d_data->thumbWidth;
00510 int sld1 = d_data->thumbLength / 2 - 1;
00511 int sld2 = d_data->thumbLength / 2 + d_data->thumbLength % 2;
00512 if ( d_data->bgStyle & BgTrough )
00513 {
00514 sliderWidth += 2 * d_data->borderWidth;
00515 sld1 += d_data->borderWidth;
00516 sld2 += d_data->borderWidth;
00517 }
00518
00519 int scd = 0;
00520 if ( d_data->scalePos != None )
00521 {
00522 int d1, d2;
00523 scaleDraw()->minBorderDist(font(), d1, d2);
00524 scd = qwtMax(d1, d2);
00525 }
00526
00527 int slo = scd - sld1;
00528 if ( slo < 0 )
00529 slo = 0;
00530
00531 const QRect r = rect();
00532 if (orientation() == Qt::Horizontal)
00533 {
00534 switch (d_data->scalePos)
00535 {
00536 case Top:
00537 d_data->sliderRect.setRect(
00538 r.x() + d_data->xMargin + slo,
00539 r.y() + r.height() -
00540 d_data->yMargin - sliderWidth,
00541 r.width() - 2 * d_data->xMargin - 2 * slo,
00542 sliderWidth);
00543 scaleDraw()->setGeometry(
00544 d_data->sliderRect.x() + sld1,
00545 d_data->sliderRect.y() - d_data->scaleDist,
00546 d_data->sliderRect.width() - sld1 - sld2,
00547 QwtScaleDraw::Top);
00548 break;
00549
00550 case Bottom:
00551 d_data->sliderRect.setRect(
00552 r.x() + d_data->xMargin + slo,
00553 r.y() + d_data->yMargin,
00554 r.width() - 2 * d_data->xMargin - 2 * slo,
00555 sliderWidth);
00556 scaleDraw()->setGeometry(
00557 d_data->sliderRect.x() + sld1,
00558 d_data->sliderRect.y() + d_data->sliderRect.height() + d_data->scaleDist,
00559 d_data->sliderRect.width() - sld1 - sld2,
00560 QwtScaleDraw::Bottom);
00561 break;
00562
00563 case None:
00564 default:
00565 d_data->sliderRect.setRect(
00566 r.x() + d_data->xMargin + slo,
00567 r.y() + d_data->yMargin,
00568 r.width() - 2 * d_data->xMargin - 2 * slo,
00569 sliderWidth);
00570 scaleDraw()->setGeometry(
00571 d_data->sliderRect.x() + sld1,
00572 0,
00573 d_data->sliderRect.width() - sld1 - sld2,
00574 QwtScaleDraw::Bottom);
00575 break;
00576 }
00577 }
00578 else
00579 {
00580 switch (d_data->scalePos)
00581 {
00582 case Right:
00583 d_data->sliderRect.setRect(
00584 r.x() + d_data->xMargin,
00585 r.y() + d_data->yMargin + slo,
00586 sliderWidth,
00587 r.height() - 2 * d_data->yMargin - 2 * slo);
00588 scaleDraw()->setGeometry(
00589 d_data->sliderRect.x() + d_data->sliderRect.width() + d_data->scaleDist,
00590 d_data->sliderRect.y() + sld1,
00591 d_data->sliderRect.height() - sld1 - sld2,
00592 QwtScaleDraw::Right);
00593 break;
00594
00595 case Left:
00596 d_data->sliderRect.setRect(
00597 r.x() + r.width() - sliderWidth - d_data->xMargin,
00598 r.y() + d_data->yMargin + slo,
00599 sliderWidth,
00600 r.height() - 2 * d_data->yMargin - 2 * slo);
00601 scaleDraw()->setGeometry(
00602 d_data->sliderRect.x() - d_data->scaleDist,
00603 d_data->sliderRect.y() + sld1,
00604 d_data->sliderRect.height() - sld1 - sld2,
00605 QwtScaleDraw::Left);
00606 break;
00607
00608 case None:
00609 default:
00610 d_data->sliderRect.setRect(
00611 r.x() + r.width() - sliderWidth - d_data->xMargin,
00612 r.y() + d_data->yMargin + slo,
00613 sliderWidth,
00614 r.height() - 2 * d_data->yMargin - 2 * slo);
00615 scaleDraw()->setGeometry(
00616 0, d_data->sliderRect.y() + sld1,
00617 d_data->sliderRect.height() - sld1 - sld2,
00618 QwtScaleDraw::Left);
00619 break;
00620 }
00621 }
00622
00623 d_data->map.setPaintXInterval(scaleDraw()->map().p1(),
00624 scaleDraw()->map().p2());
00625
00626 if ( update_geometry )
00627 {
00628 d_data->sizeHintCache = QSize();
00629 updateGeometry();
00630 update();
00631 }
00632 }
00633
00635 void QwtSlider::valueChange()
00636 {
00637 QwtAbstractSlider::valueChange();
00638 update();
00639 }
00640
00641
00643 void QwtSlider::rangeChange()
00644 {
00645 d_data->map.setScaleInterval(minValue(), maxValue());
00646
00647 if (autoScale())
00648 rescale(minValue(), maxValue());
00649
00650 QwtAbstractSlider::rangeChange();
00651 layoutSlider();
00652 }
00653
00659 void QwtSlider::setMargins(int xMargin, int yMargin)
00660 {
00661 if ( xMargin < 0 )
00662 xMargin = 0;
00663 if ( yMargin < 0 )
00664 yMargin = 0;
00665
00666 if ( xMargin != d_data->xMargin || yMargin != d_data->yMargin )
00667 {
00668 d_data->xMargin = xMargin;
00669 d_data->yMargin = yMargin;
00670 layoutSlider();
00671 }
00672 }
00673
00677 void QwtSlider::setBgStyle(BGSTYLE st)
00678 {
00679 d_data->bgStyle = st;
00680 layoutSlider();
00681 }
00682
00686 QwtSlider::BGSTYLE QwtSlider::bgStyle() const
00687 {
00688 return d_data->bgStyle;
00689 }
00690
00694 int QwtSlider::thumbLength() const
00695 {
00696 return d_data->thumbLength;
00697 }
00698
00702 int QwtSlider::thumbWidth() const
00703 {
00704 return d_data->thumbWidth;
00705 }
00706
00710 int QwtSlider::borderWidth() const
00711 {
00712 return d_data->borderWidth;
00713 }
00714
00718 QSize QwtSlider::sizeHint() const
00719 {
00720 return minimumSizeHint();
00721 }
00722
00728 QSize QwtSlider::minimumSizeHint() const
00729 {
00730 if (!d_data->sizeHintCache.isEmpty())
00731 return d_data->sizeHintCache;
00732
00733 int w = 0, h = 0;
00734
00735 int sliderWidth = d_data->thumbWidth;
00736 if (d_data->bgStyle & BgTrough)
00737 sliderWidth += 2 * d_data->borderWidth;
00738
00739 if (d_data->scalePos != None)
00740 {
00741 int msWidth = scaleDraw()->minWidth( QPen(), font() );
00742 int msHeight = scaleDraw()->minHeight( QPen(), font() );
00743
00744 int d1, d2;
00745 scaleDraw()->minBorderDist(font(), d1, d2);
00746 int msMbd = qwtMax(d1, d2);
00747
00748 int mbd = d_data->thumbLength / 2;
00749 if (d_data->bgStyle & BgTrough)
00750 mbd += d_data->borderWidth;
00751
00752 if ( mbd < msMbd )
00753 mbd = msMbd;
00754
00755 if (orientation() == Qt::Vertical)
00756 {
00757 w = 2 * d_data->xMargin + sliderWidth + msWidth + d_data->scaleDist;
00758 h = msHeight - 2 * msMbd + 2 * mbd + 2 * d_data->yMargin;
00759 }
00760 else
00761 {
00762 w = msWidth - 2 * msMbd + 2 * mbd + 2 * d_data->xMargin;
00763 h = 2 * d_data->yMargin + sliderWidth + msHeight + d_data->scaleDist;
00764 }
00765 }
00766 else
00767 {
00768 if (orientation() == Qt::Vertical)
00769 {
00770 w = 2 * d_data->xMargin + sliderWidth;
00771 h = 200 + 2 * d_data->yMargin;
00772 }
00773 else
00774 {
00775 w = 200 + 2 * d_data->xMargin;
00776 h = 2 * d_data->yMargin + sliderWidth;
00777 }
00778 }
00779 d_data->sizeHintCache = QSize(w, h);
00780 return d_data->sizeHintCache;
00781 }