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

# qwt_dial_needle.cpp

    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 <qapplication.h>
    00012 #include <qpainter.h>
    00013 #include "qwt_math.h"
    00014 #include "qwt_painter.h"
    00015 #include "qwt_dial_needle.h"
    00016
    00018 QwtDialNeedle::QwtDialNeedle():
    00019     d_palette(QApplication::palette())
    00020 {
    00021 }
    00022
    00024 QwtDialNeedle::~QwtDialNeedle()
    00025 {
    00026 }
    00027
    00033 void QwtDialNeedle::setPalette(const QPalette &palette)
    00034 {
    00035     d_palette = palette;
    00036 }
    00037
    00041 const QPalette &QwtDialNeedle::palette() const
    00042 {
    00043     return d_palette;
    00044 }
    00045
    00047 void QwtDialNeedle::drawKnob(QPainter *painter,
    00048     const QPoint &pos, int width, const QBrush &brush, bool sunken)
    00049 {
    00050     painter->save();
    00051
    00052     QRect rect(0, 0, width, width);
    00053     rect.moveCenter(pos);
    00054
    00055     painter->setPen(Qt::NoPen);
    00056     painter->setBrush(brush);
    00057     painter->drawEllipse(rect);
    00058
    00059     painter->setBrush(Qt::NoBrush);
    00060
    00061     const int colorOffset = 20;
    00062
    00063     int startAngle = 45;
    00064     if ( sunken )
    00065         startAngle += 180;
    00066
    00067     QPen pen;
    00068     pen.setWidth(1);
    00069
    00070     pen.setColor(brush.color().dark(100 - colorOffset));
    00071     painter->setPen(pen);
    00072     painter->drawArc(rect, startAngle * 16, 180 * 16);
    00073
    00074     pen.setColor(brush.color().dark(100 + colorOffset));
    00075     painter->setPen(pen);
    00076     painter->drawArc(rect, (startAngle + 180) * 16, 180 * 16);
    00077
    00078     painter->restore();
    00079 }
    00080
    00085 const QColorGroup &QwtDialNeedle::colorGroup(QPalette::ColorGroup cg) const
    00086 {
    00087     switch(cg)
    00088     {
    00089         case QPalette::Disabled:
    00090             return d_palette.disabled();
    00091         case QPalette::Inactive:
    00092             return d_palette.inactive();
    00093         default:
    00094             return d_palette.active();
    00095     }
    00096 }
    00097
    00101 QwtDialSimpleNeedle::QwtDialSimpleNeedle(Style style, bool hasKnob,
    00102         const QColor &mid, const QColor &base):
    00103     d_style(style),
    00104     d_hasKnob(hasKnob),
    00105     d_width(-1)
    00106 {
    00107     QPalette palette;
    00108     for ( int i = 0; i < QPalette::NColorGroups; i++ )
    00109     {
    00110         palette.setColor((QPalette::ColorGroup)i,
    00111             QColorGroup::Mid, mid);
    00112         palette.setColor((QPalette::ColorGroup)i,
    00113             QColorGroup::Base, base);
    00114     }
    00115
    00116     setPalette(palette);
    00117 }
    00118
    00120 void QwtDialSimpleNeedle::setWidth(int width)
    00121 {
    00122     d_width = width;
    00123 }
    00124
    00128 int QwtDialSimpleNeedle::width() const
    00129 {
    00130     return d_width;
    00131 }
    00132
    00142 void QwtDialSimpleNeedle::draw(QPainter *painter, const QPoint &center,
    00143     int length, double direction, QPalette::ColorGroup cg) const
    00144 {
    00145     if ( d_style == Arrow )
    00146     {
    00147         drawArrowNeedle(painter, colorGroup(cg),
    00148             center, length, d_width, direction, d_hasKnob);
    00149     }
    00150     else
    00151     {
    00152         drawRayNeedle(painter, colorGroup(cg), center, length, d_width,
    00153             direction, d_hasKnob);
    00154     }
    00155 }
    00156
    00160 void QwtDialSimpleNeedle::drawRayNeedle(
    00161     QPainter *painter, const QColorGroup &cg,
    00162     const QPoint &center, int length, int width, double direction,
    00163     bool hasKnob)
    00164 {
    00165     if ( width <= 0 )
    00166         width = 5;
    00167
    00168     direction *= M_PI / 180.0;
    00169
    00170     painter->save();
    00171
    00172     const QPoint p1(center.x() + 1, center.y() + 2);
    00173     const QPoint p2 = qwtPolar2Pos(p1, length, direction);
    00174
    00175     if ( width == 1 )
    00176     {
    00177         painter->setPen(QPen(cg.mid(), 1));
    00178         painter->drawLine(p1, p2);
    00179     }
    00180     else
    00181     {
    00182         QPointArray pa(4);
    00183         pa.setPoint(0, qwtPolar2Pos(p1, width / 2, direction + M_PI_2));
    00184         pa.setPoint(1, qwtPolar2Pos(p2, width / 2, direction + M_PI_2));
    00185         pa.setPoint(2, qwtPolar2Pos(p2, width / 2, direction - M_PI_2));
    00186         pa.setPoint(3, qwtPolar2Pos(p1, width / 2, direction - M_PI_2));
    00187
    00188         painter->setPen(Qt::NoPen);
    00189         painter->setBrush(cg.brush(QColorGroup::Mid));
    00190         painter->drawPolygon(pa);
    00191     }
    00192     if ( hasKnob )
    00193     {
    00194         int knobWidth = QMAX(qRound(width * 0.7), 5);
    00195         if ( knobWidth % 2 == 0 )
    00196             knobWidth++;
    00197
    00198         drawKnob(painter, center, knobWidth,
    00199             cg.brush(QColorGroup::Base), FALSE);
    00200     }
    00201
    00202     painter->restore();
    00203 }
    00204
    00208 void QwtDialSimpleNeedle::drawArrowNeedle(
    00209     QPainter *painter, const QColorGroup &cg,
    00210     const QPoint &center, int length, int width,
    00211     double direction, bool hasKnob)
    00212 {
    00213     direction *= M_PI / 180.0;
    00214
    00215     painter->save();
    00216
    00217     if ( width <= 0 )
    00218     {
    00219         width = (int)QMAX(length * 0.06, 9);
    00220         if ( width % 2 == 0 )
    00221             width++;
    00222     }
    00223
    00224     const int peak = 3;
    00225     const QPoint p1(center.x() + 1, center.y() + 1);
    00226     const QPoint p2 = qwtPolar2Pos(p1, length - peak, direction);
    00227     const QPoint p3 = qwtPolar2Pos(p1, length, direction);
    00228
    00229     QPointArray pa(5);
    00230     pa.setPoint(0, qwtPolar2Pos(p1, width / 2, direction - M_PI_2));
    00231     pa.setPoint(1, qwtPolar2Pos(p2, 1, direction - M_PI_2));
    00232     pa.setPoint(2, p3);
    00233     pa.setPoint(3, qwtPolar2Pos(p2, 1, direction + M_PI_2));
    00234     pa.setPoint(4, qwtPolar2Pos(p1, width / 2, direction + M_PI_2));
    00235
    00236     painter->setPen(Qt::NoPen);
    00237     painter->setBrush(cg.brush(QColorGroup::Mid));
    00238     painter->drawPolygon(pa);
    00239
    00240     QPointArray shadowPa(3);
    00241
    00242     const int colorOffset = 10;
    00243
    00244     int i;
    00245     for ( i = 0; i < 3; i++ )
    00246         shadowPa.setPoint(i, pa[i]);
    00247
    00248     painter->setPen(cg.mid().dark(100 + colorOffset));
    00249     painter->drawPolyline(shadowPa);
    00250
    00251     for ( i = 0; i < 3; i++ )
    00252         shadowPa.setPoint(i, pa[i + 2]);
    00253
    00254     painter->setPen(cg.mid().dark(100 - colorOffset));
    00255     painter->drawPolyline(shadowPa);
    00256
    00257     if ( hasKnob )
    00258     {
    00259         drawKnob(painter, center, qRound(width * 1.3),
    00260             cg.brush(QColorGroup::Base), FALSE);
    00261     }
    00262
    00263     painter->restore();
    00264 }
    00265
    00267
    00268 QwtCompassMagnetNeedle::QwtCompassMagnetNeedle(Style style,
    00269         const QColor &light, const QColor &dark):
    00270     d_style(style)
    00271 {
    00272     QPalette palette;
    00273     for ( int i = 0; i < QPalette::NColorGroups; i++ )
    00274     {
    00275         palette.setColor((QPalette::ColorGroup)i,
    00276             QColorGroup::Light, light);
    00277         palette.setColor((QPalette::ColorGroup)i,
    00278             QColorGroup::Dark, dark);
    00279         palette.setColor((QPalette::ColorGroup)i,
    00280             QColorGroup::Base, Qt::darkGray);
    00281     }
    00282
    00283     setPalette(palette);
    00284 }
    00285
    00295 void QwtCompassMagnetNeedle::draw(QPainter *painter, const QPoint &center,
    00296     int length, double direction, QPalette::ColorGroup cg) const
    00297 {
    00298     if ( d_style == ThinStyle )
    00299     {
    00300         drawThinNeedle(painter, colorGroup(cg),
    00301             center, length, direction);
    00302     }
    00303     else
    00304     {
    00305         drawTriangleNeedle(painter, colorGroup(cg),
    00306             center, length, direction);
    00307     }
    00308 }
    00309
    00313 void QwtCompassMagnetNeedle::drawTriangleNeedle(
    00314     QPainter *painter, const QColorGroup &cg,
    00315     const QPoint &center, int length, double direction)
    00316 {
    00317     QBrush brush;
    00318
    00319     const int width = qRound(length / 3.0);
    00320     const int colorOffset =  10;
    00321
    00322     painter->save();
    00323     painter->setPen(Qt::NoPen);
    00324
    00325     const QPoint arrowCenter(center.x() + 1, center.y() + 1);
    00326
    00327     QPointArray pa(3);
    00328     pa.setPoint(0, arrowCenter);
    00329     pa.setPoint(1, qwtDegree2Pos(arrowCenter, length, direction));
    00330
    00331     pa.setPoint(2, qwtDegree2Pos(arrowCenter, width / 2, direction + 90.0));
    00332
    00333     brush = cg.brush(QColorGroup::Dark);
    00334     brush.setColor(brush.color().dark(100 + colorOffset));
    00335     painter->setBrush(brush);
    00336     painter->drawPolygon(pa);
    00337
    00338     pa.setPoint(2, qwtDegree2Pos(arrowCenter, width / 2, direction - 90.0));
    00339
    00340     brush = cg.brush(QColorGroup::Dark);
    00341     brush.setColor(brush.color().dark(100 - colorOffset));
    00342     painter->setBrush(brush);
    00343     painter->drawPolygon(pa);
    00344
    00345     // --
    00346
    00347     pa.setPoint(1, qwtDegree2Pos(arrowCenter, length, direction + 180.0));
    00348
    00349     pa.setPoint(2, qwtDegree2Pos(arrowCenter, width / 2, direction + 90.0));
    00350
    00351     brush = cg.brush(QColorGroup::Light);
    00352     brush.setColor(brush.color().dark(100 + colorOffset));
    00353     painter->setBrush(brush);
    00354     painter->drawPolygon(pa);
    00355
    00356     pa.setPoint(2, qwtDegree2Pos(arrowCenter, width / 2, direction - 90.0));
    00357
    00358     brush = cg.brush(QColorGroup::Light);
    00359     brush.setColor(brush.color().dark(100 - colorOffset));
    00360     painter->setBrush(brush);
    00361     painter->drawPolygon(pa);
    00362
    00363     painter->restore();
    00364 }
    00365
    00369 void QwtCompassMagnetNeedle::drawThinNeedle(
    00370     QPainter *painter, const QColorGroup &cg,
    00371     const QPoint &center, int length, double direction)
    00372 {
    00373     const int colorOffset = 10;
    00374     const int width = QMAX(qRound(length / 6.0), 3);
    00375
    00376     painter->save();
    00377
    00378     const QPoint arrowCenter(center.x() + 1, center.y() + 1);
    00379
    00380     drawPointer(painter, cg.brush(QColorGroup::Dark), colorOffset,
    00381         arrowCenter, length, width, direction);
    00382     drawPointer(painter, cg.brush(QColorGroup::Light), -colorOffset,
    00383         arrowCenter, length, width, direction + 180.0);
    00384
    00385     drawKnob(painter, arrowCenter, width,
    00386         cg.brush(QColorGroup::Base), TRUE);
    00387
    00388     painter->restore();
    00389 }
    00390
    00394 void QwtCompassMagnetNeedle::drawPointer(
    00395     QPainter *painter, const QBrush &brush,
    00396     int colorOffset, const QPoint &center, int length,
    00397     int width, double direction)
    00398 {
    00399     painter->save();
    00400
    00401     const int peak = QMAX(qRound(length / 10.0), 5);
    00402
    00403     const int knobWidth = width + 8;
    00404     QRect knobRect(0, 0, knobWidth, knobWidth);
    00405     knobRect.moveCenter(center);
    00406
    00407     QPointArray pa(5);
    00408
    00409     pa.setPoint(0, qwtDegree2Pos(center, width / 2, direction + 90.0));
    00410     pa.setPoint(1, center);
    00411     pa.setPoint(2, qwtDegree2Pos(pa.point(1), length - peak, direction));
    00412     pa.setPoint(3, qwtDegree2Pos(center, length, direction));
    00413     pa.setPoint(4, qwtDegree2Pos(pa.point(0), length - peak, direction));
    00414
    00415     painter->setPen(Qt::NoPen);
    00416
    00417     QBrush darkBrush = brush;
    00418     darkBrush.setColor(darkBrush.color().dark(100 + colorOffset));
    00419     painter->setBrush(darkBrush);
    00420     painter->drawPolygon(pa);
    00421     painter->drawPie(knobRect, qRound(direction * 16), 90 * 16);
    00422
    00423     pa.setPoint(0, qwtDegree2Pos(center, width / 2, direction - 90.0));
    00424     pa.setPoint(4, qwtDegree2Pos(pa.point(0), length - peak, direction));
    00425
    00426     QBrush lightBrush = brush;
    00427     lightBrush.setColor(lightBrush.color().dark(100 - colorOffset));
    00428     painter->setBrush(lightBrush);
    00429     painter->drawPolygon(pa);
    00430     painter->drawPie(knobRect, qRound(direction * 16), -90 * 16);
    00431
    00432     painter->restore();
    00433 }
    00434
    00436
    00437 QwtCompassWindArrow::QwtCompassWindArrow(Style style,
    00438         const QColor &light, const QColor &dark):
    00439     d_style(style)
    00440 {
    00441     QPalette palette;
    00442     for ( int i = 0; i < QPalette::NColorGroups; i++ )
    00443     {
    00444         palette.setColor((QPalette::ColorGroup)i,
    00445             QColorGroup::Light, light);
    00446         palette.setColor((QPalette::ColorGroup)i,
    00447             QColorGroup::Dark, dark);
    00448     }
    00449
    00450     setPalette(palette);
    00451 }
    00452
    00462 void QwtCompassWindArrow::draw(QPainter *painter, const QPoint &center,
    00463     int length, double direction, QPalette::ColorGroup cg) const
    00464 {
    00465     if ( d_style == Style1 )
    00466     {
    00467         drawStyle1Needle(painter, colorGroup(cg),
    00468             center, length, direction);
    00469     }
    00470     else
    00471     {
    00472         drawStyle2Needle(painter, colorGroup(cg),
    00473             center, length, direction);
    00474     }
    00475 }
    00476
    00480 void QwtCompassWindArrow::drawStyle1Needle(
    00481     QPainter *painter, const QColorGroup &cg,
    00482     const QPoint &center, int length, double direction)
    00483 {
    00484     const double AR1[] = {0, 0.4, 0.3, 1, 0.8, 1, 0.3, 0.4};
    00485     const double AW1[] = {0, -45, -20, -15, 0, 15, 20, 45};
    00486
    00487     const QPoint arrowCenter(center.x() + 1, center.y() + 1);
    00488
    00489     QPointArray pa(8);
    00490     pa.setPoint(0, arrowCenter);
    00491     for (int i=1; i<8; i++)
    00492     {
    00493         const QPoint p = qwtDegree2Pos(center,
    00494             AR1[i] * length, direction + AW1[i]);
    00495         pa.setPoint(i, p);
    00496     }
    00497
    00498     painter->save();
    00499     painter->setPen(Qt::NoPen);
    00500     painter->setBrush(cg.brush(QColorGroup::Light));
    00501     painter->drawPolygon(pa);
    00502     painter->restore();
    00503 }
    00504
    00508 void QwtCompassWindArrow::drawStyle2Needle(
    00509     QPainter *painter, const QColorGroup &cg,
    00510     const QPoint &center, int length, double direction)
    00511 {
    00512     painter->save();
    00513     painter->setPen(Qt::NoPen);
    00514
    00515     const double angle = 12.0;
    00516     const double ratio = 0.7;
    00517
    00518     const QPoint arrowCenter(center.x() + 1, center.y() + 1);
    00519
    00520     QPointArray pa(3);
    00521
    00522     pa.setPoint(0, center);
    00523     pa.setPoint(2, qwtDegree2Pos(arrowCenter, ratio * length, direction));
    00524
    00525     pa.setPoint(1, qwtDegree2Pos(arrowCenter, length, direction + angle));
    00526     painter->setBrush(cg.brush(QColorGroup::Dark));
    00527     painter->drawPolygon(pa);
    00528
    00529     pa.setPoint(1, qwtDegree2Pos(arrowCenter, length, direction - angle));
    00530     painter->setBrush(cg.brush(QColorGroup::Light));
    00531     painter->drawPolygon(pa);
    00532
    00533     painter->restore();
    00534 }
    00535