| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618 | 
							- /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
 
-  * Qwt Widget Library
 
-  * Copyright (C) 1997   Josef Wilgen
 
-  * Copyright (C) 2002   Uwe Rathmann
 
-  *
 
-  * This library is free software; you can redistribute it and/or
 
-  * modify it under the terms of the Qwt License, Version 1.0
 
-  *****************************************************************************/
 
- #include "qwt_wheel.h"
 
- #include "qwt_math.h"
 
- #include "qwt_painter.h"
 
- #include <qevent.h>
 
- #include <qdrawutil.h>
 
- #include <qpainter.h>
 
- #include <qstyle.h>
 
- #define NUM_COLORS 30
 
- class QwtWheel::PrivateData
 
- {
 
- public:
 
-     PrivateData()
 
-     {
 
-         viewAngle = 175.0;
 
-         totalAngle = 360.0;
 
-         tickCnt = 10;
 
-         intBorder = 2;
 
-         borderWidth = 2;
 
-         wheelWidth = 20;
 
-     };
 
-     QRect sliderRect;
 
-     double viewAngle;
 
-     double totalAngle;
 
-     int tickCnt;
 
-     int intBorder;
 
-     int borderWidth;
 
-     int wheelWidth;
 
-     QColor colors[NUM_COLORS];
 
- };
 
- //! Constructor
 
- QwtWheel::QwtWheel( QWidget *parent ):
 
-     QwtAbstractSlider( Qt::Horizontal, parent )
 
- {
 
-     initWheel();
 
- }
 
- void QwtWheel::initWheel()
 
- {
 
-     d_data = new PrivateData;
 
-     setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed );
 
-     setAttribute( Qt::WA_WState_OwnSizePolicy, false );
 
-     setUpdateTime( 50 );
 
- }
 
- //! Destructor
 
- QwtWheel::~QwtWheel()
 
- {
 
-     delete d_data;
 
- }
 
- //! Set up the color array for the background pixmap.
 
- void QwtWheel::setColorArray()
 
- {
 
-     if ( !d_data->colors )
 
-         return;
 
-     const QColor light = palette().color( QPalette::Light );
 
-     const QColor dark = palette().color( QPalette::Dark );
 
-     if ( !d_data->colors[0].isValid() ||
 
-         d_data->colors[0] != light ||
 
-         d_data->colors[NUM_COLORS - 1] != dark )
 
-     {
 
-         d_data->colors[0] = light;
 
-         d_data->colors[NUM_COLORS - 1] = dark;
 
-         int dh, ds, dv, lh, ls, lv;
 
-         d_data->colors[0].getRgb( &lh, &ls, &lv );
 
-         d_data->colors[NUM_COLORS - 1].getRgb( &dh, &ds, &dv );
 
-         for ( int i = 1; i < NUM_COLORS - 1; ++i )
 
-         {
 
-             const double factor = double( i ) / double( NUM_COLORS );
 
-             d_data->colors[i].setRgb( lh + int( double( dh - lh ) * factor ),
 
-                       ls + int( double( ds - ls ) * factor ),
 
-                       lv + int( double( dv - lv ) * factor ) );
 
-         }
 
-     }
 
- }
 
- /*!
 
-   \brief Adjust the number of grooves in the wheel's surface.
 
-   The number of grooves is limited to 6 <= cnt <= 50.
 
-   Values outside this range will be clipped.
 
-   The default value is 10.
 
-   \param cnt Number of grooves per 360 degrees
 
-   \sa tickCnt()
 
- */
 
- void QwtWheel::setTickCnt( int cnt )
 
- {
 
-     d_data->tickCnt = qwtLim( cnt, 6, 50 );
 
-     update();
 
- }
 
- /*!
 
-   \return Number of grooves in the wheel's surface.
 
-   \sa setTickCnt()
 
- */
 
- int QwtWheel::tickCnt() const
 
- {
 
-     return d_data->tickCnt;
 
- }
 
- /*!
 
-     \return mass
 
- */
 
- double QwtWheel::mass() const
 
- {
 
-     return QwtAbstractSlider::mass();
 
- }
 
- /*!
 
-   \brief Set the internal border width of the wheel.
 
-   The internal border must not be smaller than 1
 
-   and is limited in dependence on the wheel's size.
 
-   Values outside the allowed range will be clipped.
 
-   The internal border defaults to 2.
 
-   \param w border width
 
-   \sa internalBorder()
 
- */
 
- void QwtWheel::setInternalBorder( int w )
 
- {
 
-     const int d = qMin( width(), height() ) / 3;
 
-     w = qMin( w, d );
 
-     d_data->intBorder = qMax( w, 1 );
 
-     layoutWheel();
 
- }
 
- /*!
 
-    \return Internal border width of the wheel.
 
-    \sa setInternalBorder()
 
- */
 
- int QwtWheel::internalBorder() const
 
- {
 
-     return d_data->intBorder;
 
- }
 
- /*!
 
-    Draw the Wheel's background gradient
 
-    \param painter Painter
 
-    \param r Bounding rectangle
 
- */
 
- void QwtWheel::drawWheelBackground( QPainter *painter, const QRect &r )
 
- {
 
-     painter->save();
 
-     //
 
-     // initialize pens
 
-     //
 
-     const QColor light = palette().color( QPalette::Light );
 
-     const QColor dark = palette().color( QPalette::Dark );
 
-     QPen lightPen;
 
-     lightPen.setColor( light );
 
-     lightPen.setWidth( d_data->intBorder );
 
-     QPen darkPen;
 
-     darkPen.setColor( dark );
 
-     darkPen.setWidth( d_data->intBorder );
 
-     setColorArray();
 
-     //
 
-     // initialize auxiliary variables
 
-     //
 
-     const int nFields = NUM_COLORS * 13 / 10;
 
-     const int hiPos = nFields - NUM_COLORS + 1;
 
-     if ( orientation() == Qt::Horizontal )
 
-     {
 
-         const int rx = r.x();
 
-         int ry = r.y() + d_data->intBorder;
 
-         const int rh = r.height() - 2 * d_data->intBorder;
 
-         const int rw = r.width();
 
-         //
 
-         //  draw shaded background
 
-         //
 
-         int x1 = rx;
 
-         for ( int i = 1; i < nFields; i++ )
 
-         {
 
-             const int x2 = rx + ( rw * i ) / nFields;
 
-             painter->fillRect( x1, ry, x2 - x1 + 1 , rh,
 
-                 d_data->colors[qAbs( i-hiPos )] );
 
-             x1 = x2 + 1;
 
-         }
 
-         painter->fillRect( x1, ry, rw - ( x1 - rx ), rh,
 
-             d_data->colors[NUM_COLORS - 1] );
 
-         //
 
-         // draw internal border
 
-         //
 
-         painter->setPen( lightPen );
 
-         ry = r.y() + d_data->intBorder / 2;
 
-         painter->drawLine( r.x(), ry, r.x() + r.width() , ry );
 
-         painter->setPen( darkPen );
 
-         ry = r.y() + r.height() - ( d_data->intBorder - d_data->intBorder / 2 );
 
-         painter->drawLine( r.x(), ry , r.x() + r.width(), ry );
 
-     }
 
-     else // Qt::Vertical
 
-     {
 
-         int rx = r.x() + d_data->intBorder;
 
-         const int ry = r.y();
 
-         const int rh = r.height();
 
-         const int rw = r.width() - 2 * d_data->intBorder;
 
-         //
 
-         // draw shaded background
 
-         //
 
-         int y1 = ry;
 
-         for ( int i = 1; i < nFields; i++ )
 
-         {
 
-             const int y2 = ry + ( rh * i ) / nFields;
 
-             painter->fillRect( rx, y1, rw, y2 - y1 + 1,
 
-                 d_data->colors[qAbs( i-hiPos )] );
 
-             y1 = y2 + 1;
 
-         }
 
-         painter->fillRect( rx, y1, rw, rh - ( y1 - ry ),
 
-             d_data->colors[NUM_COLORS - 1] );
 
-         //
 
-         //  draw internal borders
 
-         //
 
-         painter->setPen( lightPen );
 
-         rx = r.x() + d_data->intBorder / 2;
 
-         painter->drawLine( rx, r.y(), rx, r.y() + r.height() );
 
-         painter->setPen( darkPen );
 
-         rx = r.x() + r.width() - ( d_data->intBorder - d_data->intBorder / 2 );
 
-         painter->drawLine( rx, r.y(), rx , r.y() + r.height() );
 
-     }
 
-     painter->restore();
 
- }
 
- /*!
 
-   \brief Set the total angle which the wheel can be turned.
 
-   One full turn of the wheel corresponds to an angle of
 
-   360 degrees. A total angle of n*360 degrees means
 
-   that the wheel has to be turned n times around its axis
 
-   to get from the minimum value to the maximum value.
 
-   The default setting of the total angle is 360 degrees.
 
-   \param angle total angle in degrees
 
-   \sa totalAngle()
 
- */
 
- void QwtWheel::setTotalAngle( double angle )
 
- {
 
-     if ( angle < 0.0 )
 
-         angle = 0.0;
 
-     d_data->totalAngle = angle;
 
-     update();
 
- }
 
- /*!
 
-   \return Total angle which the wheel can be turned.
 
-   \sa setTotalAngle()
 
- */
 
- double QwtWheel::totalAngle() const
 
- {
 
-     return d_data->totalAngle;
 
- }
 
- /*!
 
-   \brief Set the wheel's orientation.
 
-   \param o Orientation. Allowed values are
 
-            Qt::Horizontal and Qt::Vertical.
 
-    Defaults to Qt::Horizontal.
 
-   \sa QwtAbstractSlider::orientation()
 
- */
 
- void QwtWheel::setOrientation( Qt::Orientation o )
 
- {
 
-     if ( orientation() == o )
 
-         return;
 
-     if ( !testAttribute( Qt::WA_WState_OwnSizePolicy ) )
 
-     {
 
-         QSizePolicy sp = sizePolicy();
 
-         sp.transpose();
 
-         setSizePolicy( sp );
 
-         setAttribute( Qt::WA_WState_OwnSizePolicy, false );
 
-     }
 
-     QwtAbstractSlider::setOrientation( o );
 
-     layoutWheel();
 
- }
 
- /*!
 
-   \brief Specify the visible portion of the wheel.
 
-   You may use this function for fine-tuning the appearance of
 
-   the wheel. The default value is 175 degrees. The value is
 
-   limited from 10 to 175 degrees.
 
-   \param angle Visible angle in degrees
 
-   \sa viewAngle(), setTotalAngle()
 
- */
 
- void QwtWheel::setViewAngle( double angle )
 
- {
 
-     d_data->viewAngle = qwtLim( angle, 10.0, 175.0 );
 
-     update();
 
- }
 
- /*!
 
-   \return Visible portion of the wheel
 
-   \sa setViewAngle(), totalAngle()
 
- */
 
- double QwtWheel::viewAngle() const
 
- {
 
-     return d_data->viewAngle;
 
- }
 
- /*!
 
-   \brief Redraw the wheel
 
-   \param painter painter
 
-   \param r contents rectangle
 
- */
 
- void QwtWheel::drawWheel( QPainter *painter, const QRect &r )
 
- {
 
-     //
 
-     // draw background gradient
 
-     //
 
-     drawWheelBackground( painter, r );
 
-     if ( maxValue() == minValue() || d_data->totalAngle == 0.0 )
 
-         return;
 
-     const QColor light = palette().color( QPalette::Light );
 
-     const QColor dark = palette().color( QPalette::Dark );
 
-     const double sign = ( minValue() < maxValue() ) ? 1.0 : -1.0;
 
-     double cnvFactor = qAbs( d_data->totalAngle / ( maxValue() - minValue() ) );
 
-     const double halfIntv = 0.5 * d_data->viewAngle / cnvFactor;
 
-     const double loValue = value() - halfIntv;
 
-     const double hiValue = value() + halfIntv;
 
-     const double tickWidth = 360.0 / double( d_data->tickCnt ) / cnvFactor;
 
-     const double sinArc = qSin( d_data->viewAngle * M_PI / 360.0 );
 
-     cnvFactor *= M_PI / 180.0;
 
-     //
 
-     // draw grooves
 
-     //
 
-     if ( orientation() == Qt::Horizontal )
 
-     {
 
-         const double halfSize = double( r.width() ) * 0.5;
 
-         int l1 = r.y() + d_data->intBorder;
 
-         int l2 = r.y() + r.height() - d_data->intBorder - 1;
 
-         // draw one point over the border if border > 1
 
-         if ( d_data->intBorder > 1 )
 
-         {
 
-             l1 --;
 
-             l2 ++;
 
-         }
 
-         const int maxpos = r.x() + r.width() - 2;
 
-         const int minpos = r.x() + 2;
 
-         //
 
-         // draw tick marks
 
-         //
 
-         for ( double tickValue = qCeil( loValue / tickWidth ) * tickWidth;
 
-             tickValue < hiValue; tickValue += tickWidth )
 
-         {
 
-             //
 
-             //  calculate position
 
-             //
 
-             const int tickPos = r.x() + r.width()
 
-                 - int( halfSize
 
-                     * ( sinArc + sign *  qSin( ( tickValue - value() ) * cnvFactor ) )
 
-                     / sinArc );
 
-             //
 
-             // draw vertical line
 
-             //
 
-             if ( ( tickPos <= maxpos ) && ( tickPos > minpos ) )
 
-             {
 
-                 painter->setPen( dark );
 
-                 painter->drawLine( tickPos - 1 , l1, tickPos - 1,  l2 );
 
-                 painter->setPen( light );
 
-                 painter->drawLine( tickPos, l1, tickPos, l2 );
 
-             }
 
-         }
 
-     }
 
-     else if ( orientation() == Qt::Vertical )
 
-     {
 
-         const double halfSize = double( r.height() ) * 0.5;
 
-         int l1 = r.x() + d_data->intBorder;
 
-         int l2 = r.x() + r.width() - d_data->intBorder - 1;
 
-         if ( d_data->intBorder > 1 )
 
-         {
 
-             l1--;
 
-             l2++;
 
-         }
 
-         const int maxpos = r.y() + r.height() - 2;
 
-         const int minpos = r.y() + 2;
 
-         //
 
-         // draw tick marks
 
-         //
 
-         for ( double tickValue = qCeil( loValue / tickWidth ) * tickWidth;
 
-             tickValue < hiValue; tickValue += tickWidth )
 
-         {
 
-             //
 
-             // calculate position
 
-             //
 
-             const int tickPos = r.y() + int( halfSize *
 
-                 ( sinArc + sign * qSin( ( tickValue - value() ) * cnvFactor ) )
 
-                 / sinArc );
 
-             //
 
-             //  draw horizontal line
 
-             //
 
-             if ( ( tickPos <= maxpos ) && ( tickPos > minpos ) )
 
-             {
 
-                 painter->setPen( dark );
 
-                 painter->drawLine( l1, tickPos - 1 , l2, tickPos - 1 );
 
-                 painter->setPen( light );
 
-                 painter->drawLine( l1, tickPos, l2, tickPos );
 
-             }
 
-         }
 
-     }
 
- }
 
- //! Determine the value corresponding to a specified point
 
- double QwtWheel::getValue( const QPoint &p )
 
- {
 
-     // The reference position is arbitrary, but the
 
-     // sign of the offset is important
 
-     int w, dx;
 
-     if ( orientation() == Qt::Vertical )
 
-     {
 
-         w = d_data->sliderRect.height();
 
-         dx = d_data->sliderRect.y() - p.y();
 
-     }
 
-     else
 
-     {
 
-         w = d_data->sliderRect.width();
 
-         dx = p.x() - d_data->sliderRect.x();
 
-     }
 
-     // w pixels is an arc of viewAngle degrees,
 
-     // so we convert change in pixels to change in angle
 
-     const double ang = dx * d_data->viewAngle / w;
 
-     // value range maps to totalAngle degrees,
 
-     // so convert the change in angle to a change in value
 
-     const double val = ang * ( maxValue() - minValue() ) / d_data->totalAngle;
 
-     // Note, range clamping and rasterizing to step is automatically
 
-     // handled by QwtAbstractSlider, so we simply return the change in value
 
-     return val;
 
- }
 
- //! Qt Resize Event
 
- void QwtWheel::resizeEvent( QResizeEvent * )
 
- {
 
-     layoutWheel( false );
 
- }
 
- //! Recalculate the slider's geometry and layout based on
 
- //  the current rect and fonts.
 
- //  \param update_geometry  notify the layout system and call update
 
- //         to redraw the scale
 
- void QwtWheel::layoutWheel( bool update_geometry )
 
- {
 
-     const QRect r = this->rect();
 
-     d_data->sliderRect.setRect( r.x() + d_data->borderWidth, r.y() + d_data->borderWidth,
 
-                                 r.width() - 2*d_data->borderWidth, r.height() - 2*d_data->borderWidth );
 
-     if ( update_geometry )
 
-     {
 
-         updateGeometry();
 
-         update();
 
-     }
 
- }
 
- //! Qt Paint Event
 
- void QwtWheel::paintEvent( QPaintEvent *e )
 
- {
 
-     // Use double-buffering
 
-     const QRect &ur = e->rect();
 
-     if ( ur.isValid() )
 
-     {
 
-         QPainter painter( this );
 
-         draw( &painter, ur );
 
-     }
 
- }
 
- /*!
 
-    Redraw panel and wheel
 
-    \param painter Painter
 
- */
 
- void QwtWheel::draw( QPainter *painter, const QRect& )
 
- {
 
-     qDrawShadePanel( painter, rect().x(), rect().y(),
 
-         rect().width(), rect().height(),
 
-         palette(), true, d_data->borderWidth );
 
-     drawWheel( painter, d_data->sliderRect );
 
-     if ( hasFocus() )
 
-         QwtPainter::drawFocusRect( painter, this );
 
- }
 
- //! Notify value change
 
- void QwtWheel::valueChange()
 
- {
 
-     QwtAbstractSlider::valueChange();
 
-     update();
 
- }
 
- /*!
 
-   \brief Determine the scrolling mode and direction corresponding
 
-          to a specified point
 
-   \param p point
 
-   \param scrollMode scrolling mode
 
-   \param direction direction
 
- */
 
- void QwtWheel::getScrollMode( const QPoint &p, int &scrollMode, int &direction )
 
- {
 
-     if ( d_data->sliderRect.contains( p ) )
 
-         scrollMode = ScrMouse;
 
-     else
 
-         scrollMode = ScrNone;
 
-     direction = 0;
 
- }
 
- /*!
 
-   \brief Set the mass of the wheel
 
-   Assigning a mass turns the wheel into a flywheel.
 
-   \param val the wheel's mass
 
- */
 
- void QwtWheel::setMass( double val )
 
- {
 
-     QwtAbstractSlider::setMass( val );
 
- }
 
- /*!
 
-   \brief Set the width of the wheel
 
-   Corresponds to the wheel height for horizontal orientation,
 
-   and the wheel width for vertical orientation.
 
-   \param w the wheel's width
 
- */
 
- void QwtWheel::setWheelWidth( int w )
 
- {
 
-     d_data->wheelWidth = w;
 
-     layoutWheel();
 
- }
 
- /*!
 
-   \return a size hint
 
- */
 
- QSize QwtWheel::sizeHint() const
 
- {
 
-     return minimumSizeHint();
 
- }
 
- /*!
 
-   \brief Return a minimum size hint
 
-   \warning The return value is based on the wheel width.
 
- */
 
- QSize QwtWheel::minimumSizeHint() const
 
- {
 
-     QSize sz( 3*d_data->wheelWidth + 2*d_data->borderWidth,
 
-         d_data->wheelWidth + 2*d_data->borderWidth );
 
-     if ( orientation() != Qt::Horizontal )
 
-         sz.transpose();
 
-     return sz;
 
- }
 
- /*!
 
-   \brief Call update() when the palette changes
 
- */
 
- void QwtWheel::paletteChange( const QPalette& )
 
- {
 
-     update();
 
- }
 
 
  |