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_polygon.h"
00016 #include "qwt_dial_needle.h"
00017 
00018 #if QT_VERSION < 0x040000
00019 typedef QColorGroup QwtPalette;
00020 #else
00021 typedef QPalette QwtPalette;
00022 #endif
00023 
00025 QwtDialNeedle::QwtDialNeedle():
00026     d_palette(QApplication::palette())
00027 {
00028 }
00029 
00031 QwtDialNeedle::~QwtDialNeedle() 
00032 {
00033 }
00034 
00040 void QwtDialNeedle::setPalette(const QPalette &palette) 
00041 { 
00042     d_palette = palette; 
00043 }
00044 
00048 const QPalette &QwtDialNeedle::palette() const 
00049 { 
00050     return d_palette; 
00051 }
00052 
00054 void QwtDialNeedle::drawKnob(QPainter *painter,
00055     const QPoint &pos, int width, const QBrush &brush, bool sunken)
00056 {
00057     painter->save();
00058 
00059     QRect rect(0, 0, width, width);
00060     rect.moveCenter(pos);
00061 
00062     painter->setPen(Qt::NoPen);
00063     painter->setBrush(brush);
00064     painter->drawEllipse(rect);
00065 
00066     painter->setBrush(Qt::NoBrush);
00067 
00068     const int colorOffset = 20;
00069 
00070     int startAngle = 45;
00071     if ( sunken )
00072         startAngle += 180;
00073 
00074     QPen pen;
00075     pen.setWidth(1);
00076 
00077     pen.setColor(brush.color().dark(100 - colorOffset));
00078     painter->setPen(pen);
00079     painter->drawArc(rect, startAngle * 16, 180 * 16);
00080 
00081     pen.setColor(brush.color().dark(100 + colorOffset));
00082     painter->setPen(pen);
00083     painter->drawArc(rect, (startAngle + 180) * 16, 180 * 16);
00084 
00085     painter->restore();
00086 }
00087 
00091 QwtDialSimpleNeedle::QwtDialSimpleNeedle(Style style, bool hasKnob, 
00092         const QColor &mid, const QColor &base):
00093     d_style(style),
00094     d_hasKnob(hasKnob),
00095     d_width(-1)
00096 {
00097     QPalette palette;
00098     for ( int i = 0; i < QPalette::NColorGroups; i++ )
00099     {
00100         palette.setColor((QPalette::ColorGroup)i,
00101             QwtPalette::Mid, mid);
00102         palette.setColor((QPalette::ColorGroup)i,
00103             QwtPalette::Base, base);
00104     }
00105 
00106     setPalette(palette);
00107 }
00108 
00110 void QwtDialSimpleNeedle::setWidth(int width)
00111 {
00112     d_width = width;
00113 }
00114 
00118 int QwtDialSimpleNeedle::width() const
00119 {
00120     return d_width;
00121 }
00122 
00132 void QwtDialSimpleNeedle::draw(QPainter *painter, const QPoint &center,
00133     int length, double direction, QPalette::ColorGroup colorGroup) const
00134 {
00135     if ( d_style == Arrow )
00136     {
00137         drawArrowNeedle(painter, palette(), colorGroup,
00138             center, length, d_width, direction, d_hasKnob);
00139     }
00140     else
00141     {
00142         drawRayNeedle(painter, palette(), colorGroup, 
00143             center, length, d_width, direction, d_hasKnob); 
00144     }
00145 }
00146 
00150 void QwtDialSimpleNeedle::drawRayNeedle(QPainter *painter, 
00151     const QPalette &palette, QPalette::ColorGroup colorGroup,
00152     const QPoint &center, int length, int width, double direction, 
00153     bool hasKnob)
00154 {
00155     if ( width <= 0 )
00156         width = 5;
00157 
00158     direction *= M_PI / 180.0;
00159 
00160     painter->save();
00161 
00162     const QPoint p1(center.x() + 1, center.y() + 2);
00163     const QPoint p2 = qwtPolar2Pos(p1, length, direction);
00164 
00165     if ( width == 1 )
00166     {
00167         const QColor midColor =
00168             palette.color(colorGroup, QwtPalette::Mid);
00169 
00170         painter->setPen(QPen(midColor, 1));
00171         painter->drawLine(p1, p2);
00172     }
00173     else
00174     {
00175         QwtPolygon pa(4);
00176         pa.setPoint(0, qwtPolar2Pos(p1, width / 2, direction + M_PI_2));
00177         pa.setPoint(1, qwtPolar2Pos(p2, width / 2, direction + M_PI_2));
00178         pa.setPoint(2, qwtPolar2Pos(p2, width / 2, direction - M_PI_2));
00179         pa.setPoint(3, qwtPolar2Pos(p1, width / 2, direction - M_PI_2));
00180 
00181         painter->setPen(Qt::NoPen);
00182         painter->setBrush(palette.brush(colorGroup, QwtPalette::Mid));
00183         painter->drawPolygon(pa);
00184     }
00185     if ( hasKnob )
00186     {
00187         int knobWidth = qwtMax(qRound(width * 0.7), 5);
00188         if ( knobWidth % 2 == 0 )
00189             knobWidth++;
00190 
00191         drawKnob(painter, center, knobWidth, 
00192             palette.brush(colorGroup, QwtPalette::Base), 
00193             false);
00194     }
00195 
00196     painter->restore();
00197 }
00198 
00202 void QwtDialSimpleNeedle::drawArrowNeedle(QPainter *painter, 
00203     const QPalette &palette, QPalette::ColorGroup colorGroup,
00204     const QPoint &center, int length, int width,
00205     double direction, bool hasKnob)
00206 {
00207     direction *= M_PI / 180.0;
00208 
00209     painter->save();
00210 
00211     if ( width <= 0 )
00212     {
00213         width = (int)qwtMax(length * 0.06, 9.0);
00214         if ( width % 2 == 0 )
00215             width++;
00216     }
00217 
00218     const int peak = 3;
00219     const QPoint p1(center.x() + 1, center.y() + 1);
00220     const QPoint p2 = qwtPolar2Pos(p1, length - peak, direction);
00221     const QPoint p3 = qwtPolar2Pos(p1, length, direction);
00222 
00223     QwtPolygon pa(5);
00224     pa.setPoint(0, qwtPolar2Pos(p1, width / 2, direction - M_PI_2));
00225     pa.setPoint(1, qwtPolar2Pos(p2, 1, direction - M_PI_2));
00226     pa.setPoint(2, p3);
00227     pa.setPoint(3, qwtPolar2Pos(p2, 1, direction + M_PI_2));
00228     pa.setPoint(4, qwtPolar2Pos(p1, width / 2, direction + M_PI_2));
00229 
00230     painter->setPen(Qt::NoPen);
00231     painter->setBrush(palette.brush(colorGroup, QwtPalette::Mid));
00232     painter->drawPolygon(pa);
00233 
00234     QwtPolygon shadowPa(3);
00235 
00236     const int colorOffset = 10;
00237 
00238     int i;
00239     for ( i = 0; i < 3; i++ )
00240         shadowPa.setPoint(i, pa[i]);
00241 
00242     const QColor midColor = palette.color(colorGroup, QwtPalette::Mid);
00243 
00244     painter->setPen(midColor.dark(100 + colorOffset));
00245     painter->drawPolyline(shadowPa);
00246 
00247     for ( i = 0; i < 3; i++ )
00248         shadowPa.setPoint(i, pa[i + 2]);
00249 
00250     painter->setPen(midColor.dark(100 - colorOffset));
00251     painter->drawPolyline(shadowPa);
00252 
00253     if ( hasKnob )
00254     {
00255         drawKnob(painter, center, qRound(width * 1.3), 
00256             palette.brush(colorGroup, QwtPalette::Base),
00257             false);
00258     }
00259 
00260     painter->restore();
00261 }
00262 
00264 
00265 QwtCompassMagnetNeedle::QwtCompassMagnetNeedle(Style style,
00266         const QColor &light, const QColor &dark):
00267     d_style(style)
00268 {   
00269     QPalette palette;
00270     for ( int i = 0; i < QPalette::NColorGroups; i++ )
00271     {
00272         palette.setColor((QPalette::ColorGroup)i,
00273             QwtPalette::Light, light);
00274         palette.setColor((QPalette::ColorGroup)i,
00275             QwtPalette::Dark, dark);
00276         palette.setColor((QPalette::ColorGroup)i,
00277             QwtPalette::Base, Qt::darkGray);
00278     }
00279 
00280     setPalette(palette); 
00281 }
00282 
00292 void QwtCompassMagnetNeedle::draw(QPainter *painter, const QPoint &center,
00293     int length, double direction, QPalette::ColorGroup colorGroup) const
00294 {
00295     if ( d_style == ThinStyle )
00296     {
00297         drawThinNeedle(painter, palette(), colorGroup, 
00298             center, length, direction); 
00299     }
00300     else
00301     {
00302         drawTriangleNeedle(painter, palette(), colorGroup,
00303             center, length, direction);
00304     }
00305 }
00306 
00317 void QwtCompassMagnetNeedle::drawTriangleNeedle(QPainter *painter, 
00318     const QPalette &palette, QPalette::ColorGroup colorGroup,
00319     const QPoint &center, int length, double direction) 
00320 {
00321     const QBrush darkBrush = palette.brush(colorGroup, QwtPalette::Dark);
00322     const QBrush lightBrush = palette.brush(colorGroup, QwtPalette::Light);
00323 
00324     QBrush brush;
00325 
00326     const int width = qRound(length / 3.0);
00327     const int colorOffset =  10;
00328 
00329     painter->save();
00330     painter->setPen(Qt::NoPen);
00331 
00332     const QPoint arrowCenter(center.x() + 1, center.y() + 1);
00333 
00334     QwtPolygon pa(3);
00335     pa.setPoint(0, arrowCenter);
00336     pa.setPoint(1, qwtDegree2Pos(arrowCenter, length, direction));
00337 
00338     pa.setPoint(2, qwtDegree2Pos(arrowCenter, width / 2, direction + 90.0));
00339 
00340     brush = darkBrush;
00341     brush.setColor(brush.color().dark(100 + colorOffset));
00342     painter->setBrush(brush);
00343     painter->drawPolygon(pa);
00344 
00345     pa.setPoint(2, qwtDegree2Pos(arrowCenter, width / 2, direction - 90.0));
00346 
00347     brush = darkBrush;
00348     brush.setColor(brush.color().dark(100 - colorOffset));
00349     painter->setBrush(brush);
00350     painter->drawPolygon(pa);
00351 
00352     // --
00353 
00354     pa.setPoint(1, qwtDegree2Pos(arrowCenter, length, direction + 180.0));
00355 
00356     pa.setPoint(2, qwtDegree2Pos(arrowCenter, width / 2, direction + 90.0));
00357 
00358     brush = lightBrush;
00359     brush.setColor(brush.color().dark(100 + colorOffset));
00360     painter->setBrush(brush);
00361     painter->drawPolygon(pa);
00362 
00363     pa.setPoint(2, qwtDegree2Pos(arrowCenter, width / 2, direction - 90.0));
00364 
00365     brush = lightBrush;
00366     brush.setColor(brush.color().dark(100 - colorOffset));
00367     painter->setBrush(brush);
00368     painter->drawPolygon(pa);
00369 
00370     painter->restore();
00371 }
00372 
00383 void QwtCompassMagnetNeedle::drawThinNeedle(QPainter *painter, 
00384     const QPalette &palette, QPalette::ColorGroup colorGroup,
00385     const QPoint &center, int length, double direction) 
00386 {
00387     const QBrush darkBrush = palette.brush(colorGroup, QwtPalette::Dark);
00388     const QBrush lightBrush = palette.brush(colorGroup, QwtPalette::Light);
00389     const QBrush baseBrush = palette.brush(colorGroup, QwtPalette::Base);
00390 
00391     const int colorOffset = 10;
00392     const int width = qwtMax(qRound(length / 6.0), 3);
00393 
00394     painter->save();
00395 
00396     const QPoint arrowCenter(center.x() + 1, center.y() + 1);
00397 
00398     drawPointer(painter, darkBrush, colorOffset, 
00399         arrowCenter, length, width, direction);
00400     drawPointer(painter, lightBrush, -colorOffset, 
00401         arrowCenter, length, width, direction + 180.0);
00402     
00403     drawKnob(painter, arrowCenter, width, baseBrush, true);
00404 
00405     painter->restore();
00406 }
00407 
00419 void QwtCompassMagnetNeedle::drawPointer(
00420     QPainter *painter, const QBrush &brush,
00421     int colorOffset, const QPoint &center, int length, 
00422     int width, double direction)
00423 {
00424     painter->save();
00425 
00426     const int peak = qwtMax(qRound(length / 10.0), 5);
00427 
00428     const int knobWidth = width + 8;
00429     QRect knobRect(0, 0, knobWidth, knobWidth);
00430     knobRect.moveCenter(center);
00431 
00432     QwtPolygon pa(5);
00433 
00434     pa.setPoint(0, qwtDegree2Pos(center, width / 2, direction + 90.0));
00435     pa.setPoint(1, center);
00436     pa.setPoint(2, qwtDegree2Pos(pa.point(1), length - peak, direction));
00437     pa.setPoint(3, qwtDegree2Pos(center, length, direction));
00438     pa.setPoint(4, qwtDegree2Pos(pa.point(0), length - peak, direction));
00439 
00440     painter->setPen(Qt::NoPen);
00441 
00442     QBrush darkBrush = brush;
00443     darkBrush.setColor(darkBrush.color().dark(100 + colorOffset));
00444     painter->setBrush(darkBrush);
00445     painter->drawPolygon(pa);
00446     painter->drawPie(knobRect, qRound(direction * 16), 90 * 16);
00447 
00448     pa.setPoint(0, qwtDegree2Pos(center, width / 2, direction - 90.0));
00449     pa.setPoint(4, qwtDegree2Pos(pa.point(0), length - peak, direction));
00450 
00451     QBrush lightBrush = brush;
00452     lightBrush.setColor(lightBrush.color().dark(100 - colorOffset));
00453     painter->setBrush(lightBrush);
00454     painter->drawPolygon(pa);
00455     painter->drawPie(knobRect, qRound(direction * 16), -90 * 16);
00456 
00457     painter->restore();
00458 }
00459 
00467 QwtCompassWindArrow::QwtCompassWindArrow(Style style, 
00468         const QColor &light, const QColor &dark):
00469     d_style(style)
00470 {
00471     QPalette palette;
00472     for ( int i = 0; i < QPalette::NColorGroups; i++ )
00473     {
00474         palette.setColor((QPalette::ColorGroup)i,
00475             QwtPalette::Light, light);
00476         palette.setColor((QPalette::ColorGroup)i,
00477             QwtPalette::Dark, dark);
00478     }
00479 
00480     setPalette(palette);
00481 }
00482 
00492 void QwtCompassWindArrow::draw(QPainter *painter, const QPoint &center,
00493     int length, double direction, QPalette::ColorGroup colorGroup) const
00494 {
00495     if ( d_style == Style1 )
00496     {
00497         drawStyle1Needle(painter, palette(), colorGroup,
00498             center, length, direction);
00499     }
00500     else
00501     {
00502         drawStyle2Needle(painter, palette(), colorGroup,
00503             center, length, direction); 
00504     }
00505 }
00506 
00517 void QwtCompassWindArrow::drawStyle1Needle(QPainter *painter, 
00518     const QPalette &palette, QPalette::ColorGroup colorGroup,
00519     const QPoint &center, int length, double direction) 
00520 {
00521     const QBrush lightBrush = palette.brush(colorGroup, QwtPalette::Light);
00522 
00523     const double AR1[] = {0, 0.4, 0.3, 1, 0.8, 1, 0.3, 0.4};
00524     const double AW1[] = {0, -45, -20, -15, 0, 15, 20, 45};
00525 
00526     const QPoint arrowCenter(center.x() + 1, center.y() + 1);
00527 
00528     QwtPolygon pa(8);
00529     pa.setPoint(0, arrowCenter);
00530     for (int i=1; i<8; i++) 
00531     {
00532         const QPoint p = qwtDegree2Pos(center, 
00533             AR1[i] * length, direction + AW1[i]);
00534         pa.setPoint(i, p);
00535     }
00536 
00537     painter->save();
00538     painter->setPen(Qt::NoPen);
00539     painter->setBrush(lightBrush);
00540     painter->drawPolygon(pa);
00541     painter->restore();
00542 }
00543 
00554 void QwtCompassWindArrow::drawStyle2Needle(QPainter *painter, 
00555     const QPalette &palette, QPalette::ColorGroup colorGroup,
00556     const QPoint &center, int length, double direction) 
00557 {
00558     const QBrush lightBrush = palette.brush(colorGroup, QwtPalette::Light);
00559     const QBrush darkBrush = palette.brush(colorGroup, QwtPalette::Dark);
00560 
00561     painter->save();
00562     painter->setPen(Qt::NoPen);
00563 
00564     const double angle = 12.0;
00565     const double ratio = 0.7;
00566 
00567     const QPoint arrowCenter(center.x() + 1, center.y() + 1);
00568 
00569     QwtPolygon pa(3);
00570 
00571     pa.setPoint(0, center);
00572     pa.setPoint(2, qwtDegree2Pos(arrowCenter, ratio * length, direction));
00573 
00574     pa.setPoint(1, qwtDegree2Pos(arrowCenter, length, direction + angle));
00575     painter->setBrush(darkBrush);
00576     painter->drawPolygon(pa);
00577 
00578     pa.setPoint(1, qwtDegree2Pos(arrowCenter, length, direction - angle));
00579     painter->setBrush(lightBrush);
00580     painter->drawPolygon(pa);
00581 
00582     painter->restore();
00583 }
00584 

Generated on Mon Feb 26 21:22:36 2007 for Qwt User's Guide by  doxygen 1.4.6