00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "qwt_interval_symbol.h"
00011 #include "qwt_painter.h"
00012 #include "qwt_math.h"
00013 #include <qpainter.h>
00014
00015 #if QT_VERSION < 0x040601
00016 #define qAtan2(y, x) ::atan2(y, x)
00017 #define qFastSin(x) qSin(x)
00018 #define qFastCos(x) qCos(x)
00019 #endif
00020
00021 class QwtIntervalSymbol::PrivateData
00022 {
00023 public:
00024 PrivateData():
00025 style( QwtIntervalSymbol::NoSymbol ),
00026 width( 6 )
00027 {
00028 }
00029
00030 bool operator==( const PrivateData &other ) const
00031 {
00032 return ( style == other.style )
00033 && ( width == other.width )
00034 && ( brush == other.brush )
00035 && ( pen == other.pen );
00036 }
00037
00038 QwtIntervalSymbol::Style style;
00039 int width;
00040
00041 QPen pen;
00042 QBrush brush;
00043 };
00044
00051 QwtIntervalSymbol::QwtIntervalSymbol( Style style )
00052 {
00053 d_data = new PrivateData();
00054 d_data->style = style;
00055 }
00056
00058 QwtIntervalSymbol::QwtIntervalSymbol( const QwtIntervalSymbol &other )
00059 {
00060 d_data = new PrivateData();
00061 *d_data = *other.d_data;
00062 }
00063
00065 QwtIntervalSymbol::~QwtIntervalSymbol()
00066 {
00067 delete d_data;
00068 }
00069
00071 QwtIntervalSymbol &QwtIntervalSymbol::operator=(
00072 const QwtIntervalSymbol &other )
00073 {
00074 *d_data = *other.d_data;
00075 return *this;
00076 }
00077
00079 bool QwtIntervalSymbol::operator==(
00080 const QwtIntervalSymbol &other ) const
00081 {
00082 return *d_data == *other.d_data;
00083 }
00084
00086 bool QwtIntervalSymbol::operator!=(
00087 const QwtIntervalSymbol &other ) const
00088 {
00089 return !( *d_data == *other.d_data );
00090 }
00091
00098 void QwtIntervalSymbol::setStyle( Style style )
00099 {
00100 d_data->style = style;
00101 }
00102
00107 QwtIntervalSymbol::Style QwtIntervalSymbol::style() const
00108 {
00109 return d_data->style;
00110 }
00111
00119 void QwtIntervalSymbol::setWidth( int width )
00120 {
00121 d_data->width = width;
00122 }
00123
00128 int QwtIntervalSymbol::width() const
00129 {
00130 return d_data->width;
00131 }
00132
00141 void QwtIntervalSymbol::setBrush( const QBrush &brush )
00142 {
00143 d_data->brush = brush;
00144 }
00145
00150 const QBrush& QwtIntervalSymbol::brush() const
00151 {
00152 return d_data->brush;
00153 }
00154
00168 void QwtIntervalSymbol::setPen( const QColor &color,
00169 qreal width, Qt::PenStyle style )
00170 {
00171 setPen( QPen( color, width, style ) );
00172 }
00173
00180 void QwtIntervalSymbol::setPen( const QPen &pen )
00181 {
00182 d_data->pen = pen;
00183 }
00184
00189 const QPen& QwtIntervalSymbol::pen() const
00190 {
00191 return d_data->pen;
00192 }
00193
00204 void QwtIntervalSymbol::draw( QPainter *painter, Qt::Orientation orientation,
00205 const QPointF &from, const QPointF &to ) const
00206 {
00207 const qreal pw = qMax( painter->pen().widthF(), qreal( 1.0 ) );
00208
00209 QPointF p1 = from;
00210 QPointF p2 = to;
00211 if ( QwtPainter::roundingAlignment( painter ) )
00212 {
00213 p1 = p1.toPoint();
00214 p2 = p2.toPoint();
00215 }
00216
00217 switch ( d_data->style )
00218 {
00219 case QwtIntervalSymbol::Bar:
00220 {
00221 QwtPainter::drawLine( painter, p1, p2 );
00222 if ( d_data->width > pw )
00223 {
00224 if ( ( orientation == Qt::Horizontal )
00225 && ( p1.y() == p2.y() ) )
00226 {
00227 const double sw = d_data->width;
00228
00229 const double y = p1.y() - sw / 2;
00230 QwtPainter::drawLine( painter,
00231 p1.x(), y, p1.x(), y + sw );
00232 QwtPainter::drawLine( painter,
00233 p2.x(), y, p2.x(), y + sw );
00234 }
00235 else if ( ( orientation == Qt::Vertical )
00236 && ( p1.x() == p2.x() ) )
00237 {
00238 const double sw = d_data->width;
00239
00240 const double x = p1.x() - sw / 2;
00241 QwtPainter::drawLine( painter,
00242 x, p1.y(), x + sw, p1.y() );
00243 QwtPainter::drawLine( painter,
00244 x, p2.y(), x + sw, p2.y() );
00245 }
00246 else
00247 {
00248 const double sw = d_data->width;
00249
00250 const double dx = p2.x() - p1.x();
00251 const double dy = p2.y() - p1.y();
00252 const double angle = qAtan2( dy, dx ) + M_PI_2;
00253 double dw2 = sw / 2.0;
00254
00255 const double cx = qFastCos( angle ) * dw2;
00256 const double sy = qFastSin( angle ) * dw2;
00257
00258 QwtPainter::drawLine( painter,
00259 p1.x() - cx, p1.y() - sy,
00260 p1.x() + cx, p1.y() + sy );
00261 QwtPainter::drawLine( painter,
00262 p2.x() - cx, p2.y() - sy,
00263 p2.x() + cx, p2.y() + sy );
00264 }
00265 }
00266 break;
00267 }
00268 case QwtIntervalSymbol::Box:
00269 {
00270 if ( d_data->width <= pw )
00271 {
00272 QwtPainter::drawLine( painter, p1, p2 );
00273 }
00274 else
00275 {
00276 if ( ( orientation == Qt::Horizontal )
00277 && ( p1.y() == p2.y() ) )
00278 {
00279 const double sw = d_data->width;
00280
00281 const double y = p1.y() - d_data->width / 2;
00282 QwtPainter::drawRect( painter,
00283 p1.x(), y, p2.x() - p1.x(), sw );
00284 }
00285 else if ( ( orientation == Qt::Vertical )
00286 && ( p1.x() == p2.x() ) )
00287 {
00288 const double sw = d_data->width;
00289
00290 const double x = p1.x() - d_data->width / 2;
00291 QwtPainter::drawRect( painter,
00292 x, p1.y(), sw, p2.y() - p1.y() );
00293 }
00294 else
00295 {
00296 const double sw = d_data->width;
00297
00298 const double dx = p2.x() - p1.x();
00299 const double dy = p2.y() - p1.y();
00300 const double angle = qAtan2( dy, dx ) + M_PI_2;
00301 double dw2 = sw / 2.0;
00302
00303 const double cx = qFastCos( angle ) * dw2;
00304 const double sy = qFastSin( angle ) * dw2;
00305
00306 QPolygonF polygon;
00307 polygon += QPointF( p1.x() - cx, p1.y() - sy );
00308 polygon += QPointF( p1.x() + cx, p1.y() + sy );
00309 polygon += QPointF( p2.x() + cx, p2.y() + sy );
00310 polygon += QPointF( p2.x() - cx, p2.y() - sy );
00311
00312 QwtPainter::drawPolygon( painter, polygon );
00313 }
00314 }
00315 break;
00316 }
00317 default:;
00318 }
00319 }