00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
#include <qpainter.h>
00011
#include <qpalette.h>
00012
#include <qstyle.h>
00013
#include <qevent.h>
00014
#include "qwt_knob.h"
00015
#include "qwt_math.h"
00016
#include "qwt_paint_buffer.h"
00017
00023 QwtKnob::QwtKnob(QWidget* parent,
const char *name):
00024
QwtSliderBase(Qt::Horizontal, parent, name,
00025 Qt::WRepaintNoErase|Qt::WResizeNoErase)
00026 {
00027 d_angle = 0.0;
00028 d_oldAngle = 0.0;
00029 d_nTurns = 0.0;
00030 d_borderWidth = 2;
00031 d_borderDist = 4;
00032 d_totalAngle = 270.0;
00033 d_scaleDist = 4;
00034 d_hasScale = 0;
00035 d_symbol = Line;
00036 d_maxScaleTicks = 11;
00037 d_knobWidth = 50;
00038 d_dotWidth = 8;
00039
00040
scaleDraw()->
setGeometry(
00041 0, 0, d_knobWidth + 2 * d_scaleDist, QwtScaleDraw::Round );
00042
setUpdateTime(50);
00043
setTotalAngle( 270.0 );
00044 recalcAngle();
00045 setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum));
00046 }
00047
00049 QwtKnob::~QwtKnob()
00050 {
00051 }
00052
00057 void QwtKnob::setSymbol(QwtKnob::Symbol s)
00058 {
00059
if ( d_symbol != s )
00060 {
00061 d_symbol = s;
00062 update();
00063 }
00064 }
00065
00070 QwtKnob::Symbol QwtKnob::symbol()
const
00071
{
00072
return d_symbol;
00073 }
00074
00083 void QwtKnob::setTotalAngle (
double angle)
00084 {
00085
if (angle < 10.0)
00086 d_totalAngle = 10.0;
00087
else
00088 d_totalAngle = angle;
00089
scaleDraw()->
setAngleRange( -0.5 * d_totalAngle, 0.5 * d_totalAngle);
00090 layoutKnob();
00091 }
00092
00093
00099 void QwtKnob::drawKnob(QPainter *p,
const QRect &r)
00100 {
00101
const int bw2 = d_borderWidth / 2;
00102
00103 QRect aRect(r.x() + bw2, r.y() + bw2,
00104 r.width() - 2 * bw2, r.height() - 2 * bw2);
00105
00106
00107
00108
00109 p->setBrush(colorGroup().brush(QColorGroup::Button));
00110 p->drawEllipse(aRect);
00111
00112
00113
00114
00115 QPen pn;
00116 pn.setWidth(d_borderWidth);
00117
00118 pn.setColor(colorGroup().light());
00119 p->setPen(pn);
00120 p->drawArc(aRect, 45*16,180*16);
00121
00122 pn.setColor(colorGroup().dark());
00123 p->setPen(pn);
00124 p->drawArc(aRect, 225*16,180*16);
00125
00126
00127
00128
00129
if (
isValid() )
00130
drawMarker(p, d_angle, colorGroup().buttonText());
00131 }
00132
00139
void QwtKnob::valueChange()
00140 {
00141 recalcAngle();
00142 update();
00143
QwtSliderBase::valueChange();
00144 }
00145
00152
double QwtKnob::getValue(
const QPoint &p)
00153 {
00154
const double dx = double((rect().x() + rect().width() / 2) - p.x() );
00155
const double dy = double((rect().y() + rect().height() / 2) - p.y() );
00156
00157
const double arc = atan2(-dx,dy) * 180.0 / M_PI;
00158
00159
double newValue = 0.5 * (
minValue() +
maxValue())
00160 + (arc + d_nTurns * 360.0) * (
maxValue() -
minValue())
00161 / d_totalAngle;
00162
00163
const double oneTurn = fabs(
maxValue() -
minValue()) * 360.0 / d_totalAngle;
00164
const double eqValue =
value() + d_mouseOffset;
00165
00166
if (fabs(newValue - eqValue) > 0.5 * oneTurn)
00167 {
00168
if (newValue < eqValue)
00169 newValue += oneTurn;
00170
else
00171 newValue -= oneTurn;
00172 }
00173
00174
return newValue;
00175 }
00176
00183
void QwtKnob::getScrollMode(
const QPoint &p,
int &scrollMode,
int &direction)
00184 {
00185
const int r = d_kRect.width() / 2;
00186
00187
const int dx = d_kRect.x() + r - p.x();
00188
const int dy = d_kRect.y() + r - p.y();
00189
00190
if ( (dx * dx) + (dy * dy) <= (r * r))
00191 {
00192 scrollMode = ScrMouse;
00193 direction = 0;
00194 }
00195
else
00196 {
00197 scrollMode = ScrTimer;
00198
double arc = atan2(
double(-dx),
double(dy)) * 180.0 / M_PI;
00199
if ( arc < d_angle)
00200 direction = -1;
00201
else if (arc > d_angle)
00202 direction = 1;
00203
else
00204 direction = 0;
00205 }
00206 }
00207
00208
00214
void QwtKnob::rangeChange()
00215 {
00216
if (!
hasUserScale())
00217 {
00218
scaleDraw()->
setScale(
minValue(),
maxValue(),
00219
scaleMaxMajor(),
scaleMaxMinor());
00220 }
00221 layoutKnob();
00222 recalcAngle();
00223 }
00224
00228 void QwtKnob::resizeEvent(QResizeEvent *)
00229 {
00230 layoutKnob( FALSE );
00231 }
00232
00234
00235
00236
00237
void QwtKnob::layoutKnob(
bool update_geometry )
00238 {
00239
const QRect &r = rect();
00240
00241
const int width = qwtMin(qwtMin(r.height(), r.width()), d_knobWidth);
00242
const int width_2 = width / 2;
00243
00244 d_kRect.setRect(r.x() + r.width() / 2 - width_2,
00245 r.y() + r.height() / 2 - width_2,
00246 width, width);
00247
00248
scaleDraw()->
setGeometry(d_kRect.x() - d_scaleDist,
00249 d_kRect.y() - d_scaleDist,
00250 width + 2 * d_scaleDist, QwtScaleDraw::Round );
00251
00252
if ( update_geometry )
00253 {
00254 updateGeometry();
00255 update();
00256 }
00257 }
00258
00262 void QwtKnob::paintEvent(QPaintEvent *e)
00263 {
00264
const QRect &ur = e->rect();
00265
if ( ur.isValid() )
00266 {
00267
QwtPaintBuffer paintBuffer(
this, ur);
00268
draw(paintBuffer.
painter(), ur);
00269 }
00270 }
00271
00275 void QwtKnob::draw(QPainter *painter,
const QRect& ur)
00276 {
00277
if ( !d_kRect.contains( ur ) )
00278
scaleDraw()->
draw( painter );
00279
drawKnob( painter, d_kRect );
00280
00281
if ( hasFocus() )
00282 {
00283 QRect r = rect();
00284
00285
#if QT_VERSION < 300
00286
style().drawFocusRect(painter, r, colorGroup());
00287
#else
00288
style().drawPrimitive(QStyle::PE_FocusRect, painter,
00289 r, colorGroup());
00290
#endif
00291
}
00292
00293 }
00294
00301 void QwtKnob::drawMarker(QPainter *p,
double arc,
const QColor &c)
00302 {
00303
const double rarc = arc * M_PI / 180.0;
00304
const double ca = cos(rarc);
00305
const double sa = - sin(rarc);
00306
00307
int radius = d_kRect.width() / 2 - d_borderWidth;
00308
if (radius < 3)
00309 radius = 3;
00310
00311
const int ym = d_kRect.y() + radius + d_borderWidth;
00312
const int xm = d_kRect.x() + radius + d_borderWidth;
00313
00314
switch (d_symbol)
00315 {
00316
case Dot:
00317 {
00318 p->setBrush(c);
00319 p->setPen(Qt::NoPen);
00320
00321
const double rb = double(qwtMax(radius - 4 - d_dotWidth / 2, 0));
00322 p->drawEllipse(xm -
int(floor (sa * rb + 0.5)) - d_dotWidth / 2,
00323 ym -
int(floor (ca * rb + 0.5)) - d_dotWidth / 2,
00324 d_dotWidth, d_dotWidth);
00325
break;
00326 }
00327
case Line:
00328 {
00329 p->setPen(QPen(c, 2));
00330
00331
const double rb = qwtMax(
double((radius - 4) / 3.0), 0.0);
00332
const double re = qwtMax(
double(radius - 4), 0.0);
00333
00334 p->drawLine (xm -
int (floor (sa * rb + 0.5)),
00335 ym -
int (floor (ca * rb + 0.5)),
00336 xm -
int (floor (sa * re + 0.5)),
00337 ym -
int (floor (ca * re + 0.5)));
00338
00339
break;
00340 }
00341 }
00342 }
00343
00350 void QwtKnob::setKnobWidth(
int w)
00351 {
00352 d_knobWidth = qwtMax(w,5);
00353 layoutKnob();
00354 }
00355
00360 void QwtKnob::setBorderWidth(
int bw)
00361 {
00362 d_borderWidth = qwtMax(bw, 0);
00363 layoutKnob();
00364 }
00365
00370
void QwtKnob::recalcAngle()
00371 {
00372 d_oldAngle = d_angle;
00373
00374
00375
00376
00377
if (
maxValue() ==
minValue())
00378 {
00379 d_angle = 0;
00380 d_nTurns = 0;
00381 }
00382
else
00383 {
00384 d_angle = (
value() - 0.5 * (
minValue() +
maxValue()))
00385 / (
maxValue() -
minValue()) * d_totalAngle;
00386 d_nTurns = floor((d_angle + 180.0) / 360.0);
00387 d_angle = d_angle - d_nTurns * 360.0;
00388 }
00389 }
00390
00391
00396
void QwtKnob::scaleChange()
00397 {
00398 layoutKnob();
00399 }
00400
00405
void QwtKnob::fontChange(
const QFont &f)
00406 {
00407 QwtSliderBase::fontChange( f );
00408 layoutKnob();
00409 }
00410
00414 QSize
QwtKnob::sizeHint()
const
00415
{
00416
return minimumSizeHint();
00417 }
00418
00424 QSize
QwtKnob::minimumSizeHint()
const
00425
{
00426
00427
const int sh =
scaleDraw()->
minHeight( QPen(), fontMetrics() );
00428
const int d = 2 * sh + 2 * d_scaleDist + d_knobWidth;
00429
00430
return QSize( d, d );
00431 }
00432
00433
00434
00435
00436
00437