00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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
00068 if ((d_scalePos == Bottom) || (d_scalePos == Top))
00069 d_scalePos = None;
00070
00071 if (d_scalePos == Right)
00072 so = QwtScaleDraw::Right;
00073 else
00074 so = QwtScaleDraw::Left;
00075 }
00076 else
00077 {
00078
00079 if ((d_scalePos == Left) || (d_scalePos == Right))
00080 d_scalePos = None;
00081
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
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++;
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
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
00304
00305
00306
00307 pos = scaleDraw()->transform(v);
00308 }
00309 else
00310 {
00311
00312
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:
00490 default:
00491
00492
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
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:
00535 default:
00536
00537
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
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
00684
00685
00686
00687