qwt_plot_marker.cpp
Go to the documentation of this file.
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 "qwt_plot_marker.h"
00011 #include "qwt_painter.h"
00012 #include "qwt_scale_map.h"
00013 #include "qwt_symbol.h"
00014 #include "qwt_text.h"
00015 #include "qwt_math.h"
00016 #include <qpainter.h>
00017 
00018 class QwtPlotMarker::PrivateData
00019 {
00020 public:
00021     PrivateData():
00022         labelAlignment( Qt::AlignCenter ),
00023         labelOrientation( Qt::Horizontal ),
00024         spacing( 2 ),
00025         symbol( NULL ),
00026         style( QwtPlotMarker::NoLine ),
00027         xValue( 0.0 ),
00028         yValue( 0.0 )
00029     {
00030     }
00031 
00032     ~PrivateData()
00033     {
00034         delete symbol;
00035     }
00036 
00037     QwtText label;
00038     Qt::Alignment labelAlignment;
00039     Qt::Orientation labelOrientation;
00040     int spacing;
00041 
00042     QPen pen;
00043     const QwtSymbol *symbol;
00044     LineStyle style;
00045 
00046     double xValue;
00047     double yValue;
00048 };
00049 
00051 QwtPlotMarker::QwtPlotMarker( const QString &title ):
00052     QwtPlotItem( QwtText( title ) )
00053 {
00054     d_data = new PrivateData;
00055     setZ( 30.0 );
00056 }
00057 
00059 QwtPlotMarker::QwtPlotMarker( const QwtText &title ):
00060     QwtPlotItem( title )
00061 {
00062     d_data = new PrivateData;
00063     setZ( 30.0 );
00064 }
00065 
00067 QwtPlotMarker::~QwtPlotMarker()
00068 {
00069     delete d_data;
00070 }
00071 
00073 int QwtPlotMarker::rtti() const
00074 {
00075     return QwtPlotItem::Rtti_PlotMarker;
00076 }
00077 
00079 QPointF QwtPlotMarker::value() const
00080 {
00081     return QPointF( d_data->xValue, d_data->yValue );
00082 }
00083 
00085 double QwtPlotMarker::xValue() const
00086 {
00087     return d_data->xValue;
00088 }
00089 
00091 double QwtPlotMarker::yValue() const
00092 {
00093     return d_data->yValue;
00094 }
00095 
00097 void QwtPlotMarker::setValue( const QPointF& pos )
00098 {
00099     setValue( pos.x(), pos.y() );
00100 }
00101 
00103 void QwtPlotMarker::setValue( double x, double y )
00104 {
00105     if ( x != d_data->xValue || y != d_data->yValue )
00106     {
00107         d_data->xValue = x;
00108         d_data->yValue = y;
00109         itemChanged();
00110     }
00111 }
00112 
00114 void QwtPlotMarker::setXValue( double x )
00115 {
00116     setValue( x, d_data->yValue );
00117 }
00118 
00120 void QwtPlotMarker::setYValue( double y )
00121 {
00122     setValue( d_data->xValue, y );
00123 }
00124 
00133 void QwtPlotMarker::draw( QPainter *painter,
00134     const QwtScaleMap &xMap, const QwtScaleMap &yMap,
00135     const QRectF &canvasRect ) const
00136 {
00137     const QPointF pos( xMap.transform( d_data->xValue ), 
00138         yMap.transform( d_data->yValue ) );
00139 
00140     drawLines( painter, canvasRect, pos );
00141     drawSymbol( painter, canvasRect, pos );
00142     drawLabel( painter, canvasRect, pos );
00143 }
00144 
00154 void QwtPlotMarker::drawLines( QPainter *painter,
00155     const QRectF &canvasRect, const QPointF &pos ) const
00156 {
00157     if ( d_data->style == NoLine )
00158         return;
00159 
00160     const bool doAlign = QwtPainter::roundingAlignment( painter );
00161 
00162     painter->setPen( d_data->pen );
00163     if ( d_data->style == QwtPlotMarker::HLine ||
00164         d_data->style == QwtPlotMarker::Cross )
00165     {
00166         double y = pos.y();
00167         if ( doAlign )
00168             y = qRound( y );
00169 
00170         QwtPainter::drawLine( painter, canvasRect.left(),
00171             y, canvasRect.right() - 1.0, y );
00172     }
00173     if ( d_data->style == QwtPlotMarker::VLine ||
00174         d_data->style == QwtPlotMarker::Cross )
00175     {
00176         double x = pos.x();
00177         if ( doAlign )
00178             x = qRound( x );
00179 
00180         QwtPainter::drawLine( painter, x,
00181             canvasRect.top(), x, canvasRect.bottom() - 1.0 );
00182     }
00183 }
00184 
00194 void QwtPlotMarker::drawSymbol( QPainter *painter,
00195     const QRectF &canvasRect, const QPointF &pos ) const
00196 {
00197     if ( d_data->symbol == NULL )
00198         return;
00199 
00200     const QwtSymbol &symbol = *d_data->symbol;
00201 
00202     if ( symbol.style() != QwtSymbol::NoSymbol )
00203     {
00204         const QSizeF sz = symbol.size();
00205     
00206         const QRectF clipRect = canvasRect.adjusted(
00207             -sz.width(), -sz.height(), sz.width(), sz.height() );
00208     
00209         if ( clipRect.contains( pos ) )
00210             symbol.drawSymbol( painter, pos );
00211     }
00212 }
00213 
00223 void QwtPlotMarker::drawLabel( QPainter *painter,
00224     const QRectF &canvasRect, const QPointF &pos ) const
00225 {
00226     if ( d_data->label.isEmpty() )
00227         return;
00228 
00229     Qt::Alignment align = d_data->labelAlignment;
00230     QPointF alignPos = pos;
00231 
00232     QSizeF symbolOff( 0, 0 );
00233 
00234     switch ( d_data->style )
00235     {
00236         case QwtPlotMarker::VLine:
00237         {
00238             // In VLine-style the y-position is pointless and
00239             // the alignment flags are relative to the canvas
00240 
00241             if ( d_data->labelAlignment & Qt::AlignTop )
00242             {
00243                 alignPos.setY( canvasRect.top() );
00244                 align &= ~Qt::AlignTop;
00245                 align |= Qt::AlignBottom;
00246             }
00247             else if ( d_data->labelAlignment & Qt::AlignBottom )
00248             {
00249                 // In HLine-style the x-position is pointless and
00250                 // the alignment flags are relative to the canvas
00251 
00252                 alignPos.setY( canvasRect.bottom() - 1 );
00253                 align &= ~Qt::AlignBottom;
00254                 align |= Qt::AlignTop;
00255             }
00256             else
00257             {
00258                 alignPos.setY( canvasRect.center().y() );
00259             }
00260             break;
00261         }
00262         case QwtPlotMarker::HLine:
00263         {
00264             if ( d_data->labelAlignment & Qt::AlignLeft )
00265             {
00266                 alignPos.setX( canvasRect.left() );
00267                 align &= ~Qt::AlignLeft;
00268                 align |= Qt::AlignRight;
00269             }
00270             else if ( d_data->labelAlignment & Qt::AlignRight )
00271             {
00272                 alignPos.setX( canvasRect.right() - 1 );
00273                 align &= ~Qt::AlignRight;
00274                 align |= Qt::AlignLeft;
00275             }
00276             else
00277             {
00278                 alignPos.setX( canvasRect.center().x() );
00279             }
00280             break;
00281         }
00282         default:
00283         {
00284             if ( d_data->symbol &&
00285                 ( d_data->symbol->style() != QwtSymbol::NoSymbol ) )
00286             {
00287                 symbolOff = d_data->symbol->size() + QSizeF( 1, 1 );
00288                 symbolOff /= 2;
00289             }
00290         }
00291     }
00292 
00293     qreal pw2 = d_data->pen.widthF() / 2.0;
00294     if ( pw2 == 0.0 )
00295         pw2 = 0.5;
00296 
00297     const int spacing = d_data->spacing;
00298 
00299     const qreal xOff = qMax( pw2, symbolOff.width() );
00300     const qreal yOff = qMax( pw2, symbolOff.height() );
00301 
00302     const QSizeF textSize = d_data->label.textSize( painter->font() );
00303 
00304     if ( align & Qt::AlignLeft )
00305     {
00306         alignPos.rx() -= xOff + spacing;
00307         if ( d_data->labelOrientation == Qt::Vertical )
00308             alignPos.rx() -= textSize.height();
00309         else
00310             alignPos.rx() -= textSize.width();
00311     }
00312     else if ( align & Qt::AlignRight )
00313     {
00314         alignPos.rx() += xOff + spacing;
00315     }
00316     else
00317     {
00318         if ( d_data->labelOrientation == Qt::Vertical )
00319             alignPos.rx() -= textSize.height() / 2;
00320         else
00321             alignPos.rx() -= textSize.width() / 2;
00322     }
00323 
00324     if ( align & Qt::AlignTop )
00325     {
00326         alignPos.ry() -= yOff + spacing;
00327         if ( d_data->labelOrientation != Qt::Vertical )
00328             alignPos.ry() -= textSize.height();
00329     }
00330     else if ( align & Qt::AlignBottom )
00331     {
00332         alignPos.ry() += yOff + spacing;
00333         if ( d_data->labelOrientation == Qt::Vertical )
00334             alignPos.ry() += textSize.width();
00335     }
00336     else
00337     {
00338         if ( d_data->labelOrientation == Qt::Vertical )
00339             alignPos.ry() += textSize.width() / 2;
00340         else
00341             alignPos.ry() -= textSize.height() / 2;
00342     }
00343 
00344     painter->translate( alignPos.x(), alignPos.y() );
00345     if ( d_data->labelOrientation == Qt::Vertical )
00346         painter->rotate( -90.0 );
00347 
00348     const QRectF textRect( 0, 0, textSize.width(), textSize.height() );
00349     d_data->label.draw( painter, textRect );
00350 }
00351 
00357 void QwtPlotMarker::setLineStyle( LineStyle style )
00358 {
00359     if ( style != d_data->style )
00360     {
00361         d_data->style = style;
00362 
00363         legendChanged();
00364         itemChanged();
00365     }
00366 }
00367 
00372 QwtPlotMarker::LineStyle QwtPlotMarker::lineStyle() const
00373 {
00374     return d_data->style;
00375 }
00376 
00382 void QwtPlotMarker::setSymbol( const QwtSymbol *symbol )
00383 {
00384     if ( symbol != d_data->symbol )
00385     {
00386         delete d_data->symbol;
00387         d_data->symbol = symbol;
00388 
00389         if ( symbol )
00390             setLegendIconSize( symbol->boundingRect().size() );
00391 
00392         legendChanged();
00393         itemChanged();
00394     }
00395 }
00396 
00401 const QwtSymbol *QwtPlotMarker::symbol() const
00402 {
00403     return d_data->symbol;
00404 }
00405 
00411 void QwtPlotMarker::setLabel( const QwtText& label )
00412 {
00413     if ( label != d_data->label )
00414     {
00415         d_data->label = label;
00416         itemChanged();
00417     }
00418 }
00419 
00424 QwtText QwtPlotMarker::label() const
00425 {
00426     return d_data->label;
00427 }
00428 
00443 void QwtPlotMarker::setLabelAlignment( Qt::Alignment align )
00444 {
00445     if ( align != d_data->labelAlignment )
00446     {
00447         d_data->labelAlignment = align;
00448         itemChanged();
00449     }
00450 }
00451 
00456 Qt::Alignment QwtPlotMarker::labelAlignment() const
00457 {
00458     return d_data->labelAlignment;
00459 }
00460 
00471 void QwtPlotMarker::setLabelOrientation( Qt::Orientation orientation )
00472 {
00473     if ( orientation != d_data->labelOrientation )
00474     {
00475         d_data->labelOrientation = orientation;
00476         itemChanged();
00477     }
00478 }
00479 
00484 Qt::Orientation QwtPlotMarker::labelOrientation() const
00485 {
00486     return d_data->labelOrientation;
00487 }
00488 
00498 void QwtPlotMarker::setSpacing( int spacing )
00499 {
00500     if ( spacing < 0 )
00501         spacing = 0;
00502 
00503     if ( spacing == d_data->spacing )
00504         return;
00505 
00506     d_data->spacing = spacing;
00507     itemChanged();
00508 }
00509 
00514 int QwtPlotMarker::spacing() const
00515 {
00516     return d_data->spacing;
00517 }
00518 
00532 void QwtPlotMarker::setLinePen( const QColor &color, qreal width, Qt::PenStyle style )
00533 {   
00534     setLinePen( QPen( color, width, style ) );
00535 }
00536 
00543 void QwtPlotMarker::setLinePen( const QPen &pen )
00544 {
00545     if ( pen != d_data->pen )
00546     {
00547         d_data->pen = pen;
00548 
00549         legendChanged();
00550         itemChanged();
00551     }
00552 }
00553 
00558 const QPen &QwtPlotMarker::linePen() const
00559 {
00560     return d_data->pen;
00561 }
00562 
00563 QRectF QwtPlotMarker::boundingRect() const
00564 {
00565     return QRectF( d_data->xValue, d_data->yValue, 0.0, 0.0 );
00566 }
00567 
00577 QwtGraphic QwtPlotMarker::legendIcon( int index,
00578     const QSizeF &size ) const
00579 {
00580     Q_UNUSED( index );
00581 
00582     if ( size.isEmpty() )
00583         return QwtGraphic();
00584 
00585     QwtGraphic icon;
00586     icon.setDefaultSize( size );
00587     icon.setRenderHint( QwtGraphic::RenderPensUnscaled, true );
00588 
00589     QPainter painter( &icon );
00590     painter.setRenderHint( QPainter::Antialiasing,
00591         testRenderHint( QwtPlotItem::RenderAntialiased ) );
00592 
00593     if ( d_data->style != QwtPlotMarker::NoLine )
00594     {
00595         painter.setPen( d_data->pen );
00596 
00597         if ( d_data->style == QwtPlotMarker::HLine ||
00598             d_data->style == QwtPlotMarker::Cross )
00599         {
00600             const double y = 0.5 * size.height();
00601 
00602             QwtPainter::drawLine( &painter, 
00603                 0.0, y, size.width(), y );
00604         }
00605 
00606         if ( d_data->style == QwtPlotMarker::VLine ||
00607             d_data->style == QwtPlotMarker::Cross )
00608         {
00609             const double x = 0.5 * size.width();
00610 
00611             QwtPainter::drawLine( &painter, 
00612                 x, 0.0, x, size.height() );
00613         }
00614     }
00615 
00616     if ( d_data->symbol )
00617     {
00618         const QRect r( 0.0, 0.0, size.width(), size.height() );
00619         d_data->symbol->drawSymbol( &painter, r );
00620     }
00621 
00622     return icon;
00623 }
00624 


plotjuggler
Author(s): Davide Faconti
autogenerated on Fri Sep 1 2017 02:41:56