00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
#include <qevent.h>
00011
#include <qdrawutil.h>
00012
#include <qpainter.h>
00013
#include <qstyle.h>
00014
#include "qwt_math.h"
00015
#include "qwt_paint_buffer.h"
00016
#include "qwt_wheel.h"
00017
00018
00020 QwtWheel::QwtWheel(QWidget *parent,
const char *name):
00021
QwtSliderBase(Qt::Horizontal, parent, name,
00022 Qt::WRepaintNoErase|Qt::WResizeNoErase )
00023 {
00024 d_viewAngle = 175.0;
00025 d_totalAngle = 360.0;
00026 d_tickCnt = 10;
00027 d_intBorder = 2;
00028 d_borderWidth = 2;
00029 d_colorCnt = 30;
00030 d_wheelWidth = 20;
00031 d_allocContext = 0;
00032 d_colors =
new QColor[d_colorCnt];
00033
setUpdateTime(50);
00034 }
00035
00037 QwtWheel::~QwtWheel()
00038 {
00039
if ( d_allocContext )
00040 QColor::destroyAllocContext( d_allocContext );
00041
delete[] d_colors;
00042 }
00043
00045 void QwtWheel::setColorArray()
00046 {
00047
if ( !d_colors )
00048
return;
00049
00050 QColorGroup g = colorGroup();
00051
00052
if ( !d_colors[0].isValid() ||
00053 d_colors[0] != g.light() ||
00054 d_colors[d_colorCnt - 1] != g.dark() )
00055 {
00056
if ( d_allocContext )
00057 QColor::destroyAllocContext( d_allocContext );
00058
00059 d_allocContext = QColor::enterAllocContext();
00060
00061 d_colors[0] = g.light();
00062 d_colors[d_colorCnt - 1] = g.dark();
00063
00064
int dh, ds, dv, lh, ls, lv;
00065 d_colors[0].rgb(&lh, &ls, &lv);
00066 d_colors[d_colorCnt - 1].rgb(&dh, &ds, &dv);
00067
00068
for (
int i = 1; i < d_colorCnt - 1; ++i )
00069 {
00070
const double factor = double(i) / double(d_colorCnt);
00071
00072 d_colors[i].setRgb( lh +
int(
double(dh - lh) * factor ),
00073 ls +
int(
double(ds - ls) * factor ),
00074 lv +
int(
double(dv - lv) * factor ));
00075 }
00076 QColor::leaveAllocContext();
00077 }
00078 }
00079
00088 void QwtWheel::setTickCnt(
int cnt)
00089 {
00090 d_tickCnt =
qwtLim( cnt, 6, 50 );
00091 update();
00092 }
00093
00097 double QwtWheel::mass()
const
00098
{
00099
return QwtSliderBase::mass();
00100 }
00101
00102
00103
00114 void QwtWheel::setInternalBorder(
int w )
00115 {
00116
const int d = qwtMin( width(), height() ) / 3;
00117 w = qwtMin( w, d );
00118 d_intBorder = qwtMax( w, 1 );
00119
layoutWheel();
00120 }
00121
00123 void QwtWheel::drawWheelBackground( QPainter *p,
const QRect &r )
00124 {
00125 p->save();
00126
00127
00128
00129
00130
const QColorGroup g = colorGroup();
00131
00132 QPen lightPen;
00133 lightPen.setColor(g.light());
00134 lightPen.setWidth(d_intBorder);
00135
00136 QPen darkPen;
00137 darkPen.setColor(g.dark());
00138 darkPen.setWidth(d_intBorder);
00139
00140
setColorArray();
00141
00142
00143
00144
00145
00146
const int nFields = d_colorCnt * 13 / 10;
00147
const int hiPos = nFields - d_colorCnt + 1;
00148
00149
if (
orientation() == Qt::Horizontal )
00150 {
00151
const int rx = r.x();
00152
int ry = r.y() + d_intBorder;
00153
const int rh = r.height() - 2* d_intBorder;
00154
const int rw = r.width();
00155
00156
00157
00158
int x1 = rx;
00159
for (
int i = 1; i < nFields; i++ )
00160 {
00161
const int x2 = rx + (rw * i) / nFields;
00162 p->fillRect(x1, ry, x2-x1 + 1 ,rh, d_colors[qwtAbs(i-hiPos)]);
00163 x1 = x2 + 1;
00164 }
00165 p->fillRect(x1, ry, rw - (x1 - rx), rh, d_colors[d_colorCnt - 1]);
00166
00167
00168
00169
00170 p->setPen(lightPen);
00171 ry = r.y() + d_intBorder / 2;
00172 p->drawLine(r.x(), ry, r.x() + r.width() , ry);
00173
00174 p->setPen(darkPen);
00175 ry = r.y() + r.height() - (d_intBorder - d_intBorder / 2);
00176 p->drawLine(r.x(), ry , r.x() + r.width(), ry);
00177 }
00178
else
00179 {
00180
int rx = r.x() + d_intBorder;
00181
const int ry = r.y();
00182
const int rh = r.height();
00183
const int rw = r.width() - 2 * d_intBorder;
00184
00185
00186
00187
00188
int y1 = ry;
00189
for (
int i = 1; i < nFields; i++ )
00190 {
00191
const int y2 = ry + (rh * i) / nFields;
00192 p->fillRect(rx, y1, rw, y2-y1 + 1, d_colors[qwtAbs(i-hiPos)]);
00193 y1 = y2 + 1;
00194 }
00195 p->fillRect(rx, y1, rw, rh - (y1 - ry), d_colors[d_colorCnt - 1]);
00196
00197
00198
00199
00200 p->setPen(lightPen);
00201 rx = r.x() + d_intBorder / 2;
00202 p->drawLine(rx, r.y(), rx, r.y() + r.height());
00203
00204 p->setPen(darkPen);
00205 rx = r.x() + r.width() - (d_intBorder - d_intBorder / 2);
00206 p->drawLine(rx, r.y(), rx , r.y() + r.height());
00207 }
00208
00209 p->restore();
00210 }
00211
00212
00224 void QwtWheel::setTotalAngle(
double angle)
00225 {
00226 d_totalAngle =
qwtLim( angle, 10.0, 3600.0 );
00227 update();
00228 }
00229
00237 void QwtWheel::setOrientation(Qt::Orientation o)
00238 {
00239
if (
orientation() != o )
00240 {
00241
QwtSliderBase::setOrientation(o);
00242
layoutWheel();
00243 }
00244 }
00245
00254 void QwtWheel::setViewAngle(
double angle)
00255 {
00256 d_viewAngle =
qwtLim( angle, 10.0, 175.0 );
00257 update();
00258 }
00259
00265 void QwtWheel::drawWheel( QPainter *p,
const QRect &r )
00266 {
00267
const double sign = (
minValue() <
maxValue()) ? 1.0 : -1.0;
00268
double cnvFactor = qwtAbs(d_totalAngle / (
maxValue() -
minValue()));
00269
const double halfIntv = 0.5 * d_viewAngle / cnvFactor;
00270
const double loValue =
value() - halfIntv;
00271
const double hiValue =
value() + halfIntv;
00272
const double tickWidth = 360.0 / double(d_tickCnt) / cnvFactor;
00273
const double sinArc = sin(d_viewAngle * M_PI / 360.0);
00274 cnvFactor *= M_PI / 180.0;
00275
00276
00277
00278
00279
drawWheelBackground( p, r );
00280
00281
00282
00283
00284
if (
orientation() == Qt::Horizontal )
00285 {
00286
const double halfSize = double(r.width()) * 0.5;
00287
00288
int l1 = r.y() + d_intBorder;
00289
int l2 = r.y() + r.height() - d_intBorder - 1;
00290
00291
00292
if ( d_intBorder > 1 )
00293 {
00294 l1 --;
00295 l2 ++;
00296 }
00297
00298
const int maxpos = r.x() + r.width() - 2;
00299
const int minpos = r.x() + 2;
00300
00301
00302
00303
00304
for (
double tickValue = ceil(loValue / tickWidth) * tickWidth;
00305 tickValue < hiValue; tickValue += tickWidth )
00306 {
00307
00308
00309
00310
const int tickPos = r.x() + r.width()
00311 - int( halfSize
00312 * (sinArc + sign * sin((tickValue -
value()) * cnvFactor))
00313 / sinArc);
00314
00315
00316
00317
if ( (tickPos <= maxpos) && (tickPos > minpos) )
00318 {
00319 p->setPen(colorGroup().dark());
00320 p->drawLine(tickPos -1 , l1, tickPos - 1, l2 );
00321 p->setPen(colorGroup().light());
00322 p->drawLine(tickPos, l1, tickPos, l2);
00323 }
00324 }
00325 }
00326
else if (
orientation() == Qt::Vertical )
00327 {
00328
const double halfSize = double(r.height()) * 0.5;
00329
00330
int l1 = r.x() + d_intBorder;
00331
int l2 = r.x() + r.width() - d_intBorder - 1;
00332
00333
if ( d_intBorder > 1 )
00334 {
00335 l1--;
00336 l2++;
00337 }
00338
00339
const int maxpos = r.y() + r.height() - 2;
00340
const int minpos = r.y() + 2;
00341
00342
00343
00344
00345
for (
double tickValue = ceil(loValue / tickWidth) * tickWidth;
00346 tickValue < hiValue; tickValue += tickWidth )
00347 {
00348
00349
00350
00351
00352
const int tickPos = r.y() + int( halfSize *
00353 (sinArc + sign * sin((tickValue -
value()) * cnvFactor))
00354 / sinArc);
00355
00356
00357
00358
00359
if ( (tickPos <= maxpos) && (tickPos > minpos) )
00360 {
00361 p->setPen(colorGroup().dark());
00362 p->drawLine(l1, tickPos - 1 ,l2, tickPos - 1);
00363 p->setPen(colorGroup().light());
00364 p->drawLine(l1, tickPos, l2, tickPos);
00365 }
00366 }
00367 }
00368 }
00369
00370
00372 double QwtWheel::getValue(
const QPoint &p )
00373 {
00374
00375
00376
int w, dx;
00377
if (
orientation() == Qt::Vertical )
00378 {
00379 w = d_sliderRect.height();
00380 dx = d_sliderRect.y() - p.y();
00381 }
00382
else
00383 {
00384 w = d_sliderRect.width();
00385 dx = p.x() - d_sliderRect.x();
00386 }
00387
00388
00389
00390
const double ang = dx * d_viewAngle / w;
00391
00392
00393
00394
const double val = ang * (
maxValue() -
minValue() ) / d_totalAngle;
00395
00396
00397
00398
return val;
00399 }
00400
00402 void QwtWheel::resizeEvent(QResizeEvent *)
00403 {
00404
layoutWheel( FALSE );
00405 }
00406
00408
00409
00410
00411 void QwtWheel::layoutWheel(
bool update_geometry )
00412 {
00413
const QRect r = this->rect();
00414 d_sliderRect.setRect(r.x() + d_borderWidth, r.y() + d_borderWidth,
00415 r.width() - 2*d_borderWidth, r.height() - 2*d_borderWidth);
00416
00417
if ( update_geometry )
00418 {
00419 updateGeometry();
00420 update();
00421 }
00422 }
00423
00425 void QwtWheel::paintEvent(QPaintEvent *e)
00426 {
00427
00428
const QRect &ur = e->rect();
00429
if ( ur.isValid() )
00430 {
00431
QwtPaintBuffer paintBuffer(
this, ur);
00432
draw(paintBuffer.
painter(), ur);
00433 }
00434 }
00435
00437 void QwtWheel::draw(QPainter *painter,
const QRect&)
00438 {
00439 QColorGroup cg = colorGroup();
00440
00441
00442
00443 QWidget *parent = parentWidget();
00444
if ( parent )
00445 cg = parent->colorGroup();
00446
00447 qDrawShadePanel( painter, rect().x(), rect().y(),
00448 rect().width(), rect().height(),
00449 cg, TRUE, d_borderWidth );
00450
00451
drawWheel( painter, d_sliderRect );
00452
00453
if ( hasFocus() )
00454 {
00455 QRect r = rect();
00456
00457
#if QT_VERSION < 300
00458
style().drawFocusRect(painter, r, colorGroup());
00459
#else
00460
style().drawPrimitive(QStyle::PE_FocusRect, painter,
00461 r, colorGroup());
00462
#endif
00463
}
00464 }
00465
00467 void QwtWheel::valueChange()
00468 {
00469
QwtSliderBase::valueChange();
00470 update();
00471 }
00472
00473
00481 void QwtWheel::getScrollMode(
const QPoint &p,
int &scrollMode,
int &direction)
00482 {
00483
if ( d_sliderRect.contains(p) )
00484 scrollMode = ScrMouse;
00485
else
00486 scrollMode = ScrNone;
00487
00488 direction = 0;
00489 }
00490
00497 void QwtWheel::setMass(
double val)
00498 {
00499
QwtSliderBase::setMass(val);
00500 }
00501
00509 void QwtWheel::setWheelWidth(
int w)
00510 {
00511 d_wheelWidth = w;
00512
layoutWheel();
00513 }
00514
00520 QSizePolicy
QwtWheel::sizePolicy()
const
00521
{
00522 QSizePolicy sp;
00523
if (
orientation() == Qt::Horizontal )
00524 {
00525 sp.setHorData( QSizePolicy::Preferred );
00526 sp.setVerData( QSizePolicy::Fixed );
00527 }
00528
else
00529 {
00530 sp.setHorData( QSizePolicy::Fixed );
00531 sp.setVerData( QSizePolicy::Preferred );
00532 }
00533
return sp;
00534 }
00535
00539 QSize
QwtWheel::sizeHint()
const
00540
{
00541
return minimumSizeHint();
00542 }
00543
00548 QSize
QwtWheel::minimumSizeHint()
const
00549
{
00550 QSize sz( 3*d_wheelWidth + 2*d_borderWidth,
00551 d_wheelWidth + 2*d_borderWidth );
00552
if (
orientation() != Qt::Horizontal )
00553 sz.transpose();
00554
return sz;
00555 }
00556
00560 void QwtWheel::paletteChange(
const QPalette& )
00561 {
00562 update();
00563 }
00564