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

qwt_slider.cpp

Go to the documentation of this file.
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 <math.h>
00011 #include <qstyle.h>
00012 #include <qdrawutil.h>
00013 #include <qpainter.h>
00014 #include "qwt_paint_buffer.h"
00015 #include "qwt_slider.h"
00016 
00031 QwtSlider::QwtSlider(QWidget *parent, const char *name,
00032         Qt::Orientation orient, ScalePos scalePos, int bgStyle): 
00033     QwtSliderBase(orient, parent, name, WRepaintNoErase|WResizeNoErase)
00034 {
00035     d_borderWidth = 2;
00036     d_scaleDist = 4;
00037     d_scalePos = scalePos;
00038     d_xMargin = 0;
00039     d_yMargin = 0;
00040     d_bgStyle = bgStyle;
00041 
00042     if (bgStyle == BgSlot)
00043     {
00044         d_thumbLength = 16;
00045         d_thumbWidth = 30;
00046     }
00047     else
00048     {
00049         d_thumbLength = 31;
00050         d_thumbWidth = 16;
00051     }
00052 
00053     d_sliderRect.setRect(0,0,8,8);
00054 
00055     QwtScaleDraw::Orientation so;
00056     if ( orientation() == Qt::Vertical )
00057     {
00058         if (d_scalePos == Right)
00059            so = QwtScaleDraw::Right;
00060         else
00061            so = QwtScaleDraw::Left;
00062     }
00063     else
00064     {
00065         if (d_scalePos == Bottom)
00066            so = QwtScaleDraw::Bottom;
00067         else
00068            so = QwtScaleDraw::Top;
00069     }
00070 
00071     d_scaleDraw->setGeometry(0,0,100,so);
00072 }
00073 
00082 void QwtSlider::setOrientation(Qt::Orientation o) 
00083 {
00084     QwtSliderBase::setOrientation(o);
00085     layoutSlider();
00086 }
00087 
00092 void QwtSlider::setBorderWidth(int bd)
00093 {
00094     if ( bd < 0 )
00095         bd = 0;
00096 
00097     if ( bd != d_borderWidth )
00098     {
00099         d_borderWidth = bd;
00100         layoutSlider();
00101     }
00102 }
00103 
00108 void QwtSlider::setThumbLength(int thumbLength)
00109 {
00110     if ( thumbLength < 8 )
00111         thumbLength = 8;
00112 
00113     if ( thumbLength != d_thumbLength )
00114     {
00115         d_thumbLength = thumbLength;
00116         layoutSlider();
00117     }
00118 }
00119 
00124 void QwtSlider::setThumbWidth(int w)
00125 {
00126     if ( w < 4 )
00127         w = 4;
00128 
00129     if ( d_thumbWidth != w )
00130     {
00131         d_thumbWidth = w;
00132         layoutSlider();
00133     }
00134 }
00135 
00136 
00138 void QwtSlider::scaleChange()
00139 {
00140     if (!hasUserScale())
00141     {
00142         d_scaleDraw->setScale(minValue(), maxValue(), 
00143             d_maxMajor, d_maxMinor, d_scaleDraw->scaleDiv().logScale());
00144     }
00145 
00146     layoutSlider();
00147 }
00148 
00149 
00151 void QwtSlider::fontChange(const QFont &f)
00152 {
00153     QwtSliderBase::fontChange( f );
00154     layoutSlider();
00155 }
00156 
00158 void QwtSlider::drawSlider(QPainter *p, const QRect &r)
00159 {
00160     QRect cr(r);
00161 
00162     if (d_bgStyle & BgTrough)
00163     {
00164         qDrawShadePanel(p, r.x(), r.y(),
00165             r.width(), r.height(),
00166             colorGroup(), TRUE, d_borderWidth,0);
00167 
00168         cr.setRect(r.x() + d_borderWidth,
00169             r.y() + d_borderWidth,
00170             r.width() - 2 * d_borderWidth,
00171             r.height() - 2 * d_borderWidth);
00172 
00173         p->fillRect(cr.x(), cr.y(), cr.width(), cr.height(), 
00174             colorGroup().brush(QColorGroup::Mid));
00175     }
00176 
00177     if ( d_bgStyle & BgSlot)
00178     {
00179         int ws = 4;
00180         int ds = d_thumbLength / 2 - 4;
00181         if ( ds < 1 )
00182             ds = 1;
00183 
00184         QRect rSlot;
00185         if (orientation() == Qt::Horizontal)
00186         {
00187             if ( cr.height() & 1 )
00188                 ws++;
00189             rSlot = QRect(cr.x() + ds, 
00190                     cr.y() + (cr.height() - ws) / 2,
00191                     cr.width() - 2 * ds, ws);
00192         }
00193         else
00194         {
00195             if ( cr.width() & 1 )
00196                 ws++;
00197             rSlot = QRect(cr.x() + (cr.width() - ws) / 2, 
00198                     cr.y() + ds,
00199                     ws, cr.height() - 2 * ds);
00200         }
00201         p->fillRect(rSlot.x(), rSlot.y(), rSlot.width(), rSlot.height(),
00202             colorGroup().brush(QColorGroup::Dark));
00203         qDrawShadePanel(p, rSlot.x(), rSlot.y(),
00204             rSlot.width(), rSlot.height(), colorGroup(), TRUE, 1 ,0);
00205 
00206     }
00207 
00208     drawThumb(p, cr, xyPosition(value()));
00209 }
00210 
00212 void QwtSlider::drawThumb(QPainter *p, const QRect &sliderRect, int pos)
00213 {
00214     pos++; // shade line points one pixel below
00215     if (orientation() == Qt::Horizontal)
00216     {
00217         qDrawShadePanel(p, pos - d_thumbLength / 2, 
00218             sliderRect.y(), d_thumbLength, sliderRect.height(),
00219             colorGroup(), FALSE, d_borderWidth, 
00220             &colorGroup().brush(QColorGroup::Button));
00221 
00222         qDrawShadeLine(p, pos, sliderRect.y(), 
00223             pos, sliderRect.y() + sliderRect.height() - 2, 
00224             colorGroup(), TRUE, 1);
00225     }
00226     else // Vertical
00227     {
00228         qDrawShadePanel(p,sliderRect.x(), pos - d_thumbLength / 2, 
00229             sliderRect.width(), d_thumbLength,
00230             colorGroup(),FALSE, d_borderWidth, 
00231             &colorGroup().brush(QColorGroup::Button));
00232 
00233         qDrawShadeLine(p, sliderRect.x(), pos,
00234             sliderRect.x() + sliderRect.width() - 2, pos, 
00235             colorGroup(), TRUE, 1);
00236     }
00237 }
00238 
00240 int QwtSlider::xyPosition(double v) const
00241 {
00242     int pos;
00243     if ( minValue() == d_scaleDraw->d1() && maxValue() == d_scaleDraw->d2() )
00244     {
00245         // We prefer to use the transformation of d_scaleDraw
00246         // So ticks and marker are always in sync and we don't have
00247         // to take care of rounding problems.
00248 
00249         pos = d_scaleDraw->transform(v);
00250     }
00251     else
00252     {
00253         // range and d_scaleDraw differ ? Sounds strange but
00254         // might happen with logarithmic scales
00255 
00256         const double f = (v - minValue()) / (maxValue() - minValue());
00257         double dPos;
00258         if ( orientation() == Qt::Horizontal )
00259             dPos = d_scaleDraw->i1() + f * (d_scaleDraw->i2() - d_scaleDraw->i1());
00260         else
00261             dPos = d_scaleDraw->i1() - f * (d_scaleDraw->i1() - d_scaleDraw->i2());
00262         pos = (int)floor(dPos + 0.5); // rint(dPos)
00263     }
00264     return pos;
00265 }
00266 
00268 double QwtSlider::getValue(const QPoint &p)
00269 {
00270     double rv;
00271 
00272     if ( minValue() == d_scaleDraw->d1() && maxValue() == d_scaleDraw->d2() )
00273     {
00274         rv = d_scaleDraw->invTransform(
00275             orientation() == Qt::Horizontal ? p.x() : p.y());
00276     }
00277     else
00278     {
00279         double pos;
00280         double range;
00281         if ( orientation() == Qt::Horizontal )
00282         {
00283             pos = p.x() - d_scaleDraw->i1();
00284             range = d_scaleDraw->i2() - d_scaleDraw->i1();
00285         }
00286         else
00287         {
00288             pos = d_scaleDraw->i1() - p.y();
00289             range = d_scaleDraw->i1() - d_scaleDraw->i2();
00290         }
00291             
00292         rv = minValue() + pos / range * (maxValue() - minValue()); 
00293     }
00294 
00295     return(rv);
00296 }
00297 
00298 
00305 void QwtSlider::getScrollMode(const QPoint &p, 
00306     int &scrollMode, int &direction )
00307 {
00308     if (!d_sliderRect.contains(p))
00309     {
00310         scrollMode = ScrNone;
00311         direction = 0;
00312         return;
00313     }
00314 
00315     const int pos = ( orientation() == Qt::Horizontal ) ? p.x() : p.y();
00316     const int markerPos = xyPosition(value());
00317 
00318     if ((pos > markerPos - d_thumbLength / 2)
00319         && (pos < markerPos + d_thumbLength / 2))
00320     {
00321         scrollMode = ScrMouse;
00322         direction = 0;
00323         return;
00324     }
00325 
00326     scrollMode = ScrPage;
00327     direction = (pos > markerPos) ? 1 : -1;
00328     if ( d_scaleDraw->i1() > d_scaleDraw->i2() )
00329         direction = -direction;
00330 }
00331 
00333 void QwtSlider::paintEvent(QPaintEvent *e)
00334 {
00335     const QRect &ur = e->rect();
00336     if ( ur.isValid() )
00337     {
00338         QwtPaintBuffer paintBuffer(this, ur);
00339         draw(paintBuffer.painter(), ur);
00340     }
00341 }
00342 
00344 void QwtSlider::draw(QPainter *painter, const QRect&)
00345 {
00346     if (d_scalePos != None)
00347         d_scaleDraw->draw(painter);
00348 
00349     drawSlider(painter, d_sliderRect);
00350     if ( hasFocus() )
00351     {
00352         const QRect rect = d_sliderRect;
00353 
00354 #if QT_VERSION < 300
00355         style().drawFocusRect(painter, rect, colorGroup());
00356 #else
00357         style().drawPrimitive(QStyle::PE_FocusRect, painter,
00358             rect, colorGroup());
00359 #endif
00360     }
00361 }
00362 
00364 void QwtSlider::resizeEvent(QResizeEvent *)
00365 {
00366     layoutSlider( FALSE );
00367 }
00368 
00370 //  the current rect and fonts.
00371 //  \param update_geometry  notify the layout system and call update
00372 //         to redraw the scale
00373 
00374 void QwtSlider::layoutSlider( bool update_geometry )
00375 {
00376     int sliderWidth = d_thumbWidth;
00377     int sld1 = d_thumbLength / 2 - 1;
00378     int sld2 = d_thumbLength / 2 + d_thumbLength % 2;
00379     if ( d_bgStyle & BgTrough )
00380     {
00381         sliderWidth += 2 * d_borderWidth;
00382         sld1 += d_borderWidth;
00383         sld2 += d_borderWidth;
00384     }
00385 
00386     int scd = 0;
00387     if ( d_scalePos != None )
00388     {
00389         int d1, d2;
00390         d_scaleDraw->minBorderDist(fontMetrics(), d1, d2);
00391         scd = QMAX(d1, d2);
00392     }
00393 
00394     int slo = scd - sld1;
00395     if ( slo < 0 )
00396         slo = 0;
00397 
00398     const QRect r = rect();
00399     switch ( d_scalePos )
00400     {
00401         case Top:
00402         {
00403             d_sliderRect.setRect(r.x() + d_xMargin + slo,
00404                 r.y() + r.height() -
00405                 d_yMargin - sliderWidth,
00406                 r.width() - 2 * d_xMargin - 2 * slo,
00407                 sliderWidth);
00408             d_scaleDraw->setGeometry(d_sliderRect.x() + sld1,
00409                 d_sliderRect.y() - d_scaleDist,
00410                 d_sliderRect.width() - sld1 - sld2,
00411                 QwtScaleDraw::Top);
00412             break;
00413         }
00414         case Bottom:
00415         {
00416             d_sliderRect.setRect(r.x() + d_xMargin + slo,
00417                 r.y() + d_yMargin,
00418                 r.width() - 2 * d_xMargin - 2 * slo,
00419                 sliderWidth);
00420             d_scaleDraw->setGeometry(d_sliderRect.x() + sld1,
00421                 d_sliderRect.y() + d_sliderRect.height() +
00422                 d_scaleDist,
00423                 d_sliderRect.width() - sld1 - sld2,
00424                 QwtScaleDraw::Bottom);
00425             break;
00426         }
00427         case Left:
00428         {
00429             d_sliderRect.setRect(r.x() + r.width() -
00430                 sliderWidth - d_xMargin,
00431                 r.y() + d_yMargin + slo,
00432                 sliderWidth,
00433                 r.height() - 2 * d_yMargin - 2 * slo);
00434             d_scaleDraw->setGeometry(d_sliderRect.x() - d_scaleDist,
00435                 d_sliderRect.y() + sld1,
00436                 d_sliderRect.height() - sld1 - sld2,
00437                 QwtScaleDraw::Left);
00438             break;
00439         }
00440         case Right:
00441         {
00442             d_sliderRect.setRect(r.x() + d_xMargin,
00443                 r.y() + d_yMargin + slo,
00444                 sliderWidth,
00445                 r.height() - 2 * d_yMargin - 2 * slo);
00446             d_scaleDraw->setGeometry(d_sliderRect.x() + d_sliderRect.width() +
00447                 d_scaleDist,
00448                 d_sliderRect.y() + sld1,
00449                 d_sliderRect.height() - sld1 - sld2,
00450                 QwtScaleDraw::Right);
00451             break;
00452         }
00453         default:
00454         {
00455             d_sliderRect.setRect(r.x() + d_xMargin,
00456                 r.y() + d_yMargin,
00457                 r.width() - 2 * d_xMargin,
00458                 r.height() - 2 * d_yMargin);
00459 
00460             // QwtScaleDraw is derived from QwtDiMap. Even if
00461             // no scale is required we keep the map alive.
00462 
00463             if ( orientation() == Qt::Horizontal )
00464             {
00465                 d_scaleDraw->setIntRange(
00466                     d_sliderRect.x() + sld1,
00467                     d_sliderRect.x() + d_sliderRect.width() - sld2 - 1);
00468             }
00469             else
00470             {
00471                 d_scaleDraw->setIntRange(
00472                     d_sliderRect.y() + d_sliderRect.height() - sld2 - 1,
00473                     d_sliderRect.y() + sld1);
00474             }
00475         }
00476     }
00477 
00478     if ( update_geometry )
00479     {
00480         updateGeometry();
00481         update();
00482     }
00483 }
00484 
00486 void QwtSlider::valueChange()
00487 {
00488     QwtSliderBase::valueChange();
00489     update();
00490 }
00491 
00492 
00494 void QwtSlider::rangeChange()
00495 {
00496     if (!hasUserScale())
00497     {
00498         d_scaleDraw->setScale(minValue(), maxValue(), 
00499             d_maxMajor, d_maxMinor, d_scaleDraw->scaleDiv().logScale());
00500     }
00501 
00502     QwtSliderBase::rangeChange();
00503     layoutSlider();
00504 }
00505 
00511 void QwtSlider::setMargins(int xMargin, int yMargin)
00512 {
00513     if ( xMargin < 0 )
00514         xMargin = 0;
00515     if ( yMargin < 0 )
00516         yMargin = 0;
00517 
00518     if ( xMargin != d_xMargin || yMargin != d_yMargin )
00519     {
00520         d_xMargin = xMargin;
00521         d_yMargin = yMargin;
00522         layoutSlider();
00523     }
00524 }
00525 
00530 QSizePolicy QwtSlider::sizePolicy() const
00531 {
00532     QSizePolicy sp;
00533     if ( orientation() == Qt::Horizontal )
00534     {
00535         sp.setHorData( QSizePolicy::MinimumExpanding );
00536         sp.setVerData( QSizePolicy::Fixed );
00537     }
00538     else
00539     {
00540         sp.setHorData( QSizePolicy::Fixed );
00541         sp.setVerData( QSizePolicy::MinimumExpanding );
00542     }
00543     return sp;
00544 }
00545 
00549 QSize QwtSlider::sizeHint() const
00550 {
00551     return minimumSizeHint();
00552 }
00553 
00559 QSize QwtSlider::minimumSizeHint() const
00560 {
00561     int w = 0, h = 0;
00562 
00563     int sliderWidth = d_thumbWidth;
00564     if (d_bgStyle & BgTrough)
00565         sliderWidth += 2 * d_borderWidth;
00566 
00567     if (d_scalePos != None)
00568     {
00569         int msWidth = d_scaleDraw->minWidth( QPen(), fontMetrics() );
00570         int msHeight = d_scaleDraw->minHeight( QPen(), fontMetrics() );
00571         
00572         int d1, d2;
00573         d_scaleDraw->minBorderDist(fontMetrics(), d1, d2);
00574         int msMbd = QMAX(d1, d2);
00575 
00576         int mbd = d_thumbLength / 2;
00577         if (d_bgStyle & BgTrough)
00578             mbd += d_borderWidth;
00579 
00580         if ( mbd < msMbd )
00581             mbd = msMbd;
00582 
00583         if (orientation() == Qt::Vertical)
00584         {
00585             w = 2 * d_xMargin + sliderWidth + msWidth + d_scaleDist;
00586             h = msHeight - 2 * msMbd + 2 * mbd + 2 * d_yMargin;
00587         }
00588         else
00589         {
00590             w = msWidth - 2 * msMbd + 2 * mbd + 2 * d_xMargin;
00591             h = 2 * d_yMargin + sliderWidth  + msHeight + d_scaleDist;
00592         }
00593     }
00594     else  // no scale
00595     {
00596         if (orientation() == Qt::Vertical)
00597         {
00598             w = 2 * d_xMargin + sliderWidth;
00599             h = 200 + 2 * d_yMargin;
00600         }
00601         else
00602         {
00603             w = 200 + 2 * d_xMargin;
00604             h = 2 * d_yMargin + sliderWidth;
00605         }
00606     }
00607     return QSize(w,h);
00608 }

Generated on Fri Nov 7 14:11:46 2003 for Qwt Developer's Guide by doxygen 1.3.2