| 1 | /* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** | 
|---|
| 2 | * QwtPolar Widget Library | 
|---|
| 3 | * Copyright (C) 2008   Uwe Rathmann | 
|---|
| 4 | * | 
|---|
| 5 | * This library is free software; you can redistribute it and/or | 
|---|
| 6 | * modify it under the terms of the Qwt License, Version 1.0 | 
|---|
| 7 | *****************************************************************************/ | 
|---|
| 8 |  | 
|---|
| 9 | #include "qwt_polar_marker.h" | 
|---|
| 10 | #include "qwt_polar.h" | 
|---|
| 11 | #include <qwt_scale_map.h> | 
|---|
| 12 | #include <qwt_symbol.h> | 
|---|
| 13 | #include <qwt_text.h> | 
|---|
| 14 | #include <qpainter.h> | 
|---|
| 15 |  | 
|---|
| 16 | static const int LabelDist = 2; | 
|---|
| 17 |  | 
|---|
| 18 | class QwtPolarMarker::PrivateData | 
|---|
| 19 | { | 
|---|
| 20 | public: | 
|---|
| 21 | PrivateData(): | 
|---|
| 22 | align( Qt::AlignCenter ) | 
|---|
| 23 | { | 
|---|
| 24 | symbol = new QwtSymbol(); | 
|---|
| 25 | } | 
|---|
| 26 |  | 
|---|
| 27 | ~PrivateData() | 
|---|
| 28 | { | 
|---|
| 29 | delete symbol; | 
|---|
| 30 | } | 
|---|
| 31 |  | 
|---|
| 32 | QwtText label; | 
|---|
| 33 | Qt::Alignment align; | 
|---|
| 34 | QPen pen; | 
|---|
| 35 | const QwtSymbol *symbol; | 
|---|
| 36 |  | 
|---|
| 37 | QwtPointPolar pos; | 
|---|
| 38 | }; | 
|---|
| 39 |  | 
|---|
| 40 | //! Sets alignment to Qt::AlignCenter, and style to NoLine | 
|---|
| 41 | QwtPolarMarker::QwtPolarMarker(): | 
|---|
| 42 | QwtPolarItem( QwtText( "Marker" ) ) | 
|---|
| 43 | { | 
|---|
| 44 | d_data = new PrivateData; | 
|---|
| 45 |  | 
|---|
| 46 | setItemAttribute( QwtPolarItem::AutoScale ); | 
|---|
| 47 | setZ( 30.0 ); | 
|---|
| 48 | } | 
|---|
| 49 |  | 
|---|
| 50 | //! Destructor | 
|---|
| 51 | QwtPolarMarker::~QwtPolarMarker() | 
|---|
| 52 | { | 
|---|
| 53 | delete d_data; | 
|---|
| 54 | } | 
|---|
| 55 |  | 
|---|
| 56 | //! \return QwtPolarItem::Rtti_PlotMarker | 
|---|
| 57 | int QwtPolarMarker::rtti() const | 
|---|
| 58 | { | 
|---|
| 59 | return QwtPolarItem::Rtti_PolarMarker; | 
|---|
| 60 | } | 
|---|
| 61 |  | 
|---|
| 62 | //! \return Position of the marker | 
|---|
| 63 | QwtPointPolar QwtPolarMarker::position() const | 
|---|
| 64 | { | 
|---|
| 65 | return d_data->pos; | 
|---|
| 66 | } | 
|---|
| 67 |  | 
|---|
| 68 | //! Change the position of the marker | 
|---|
| 69 | void QwtPolarMarker::setPosition( const QwtPointPolar &pos ) | 
|---|
| 70 | { | 
|---|
| 71 | if ( d_data->pos != pos ) | 
|---|
| 72 | { | 
|---|
| 73 | d_data->pos = pos; | 
|---|
| 74 | itemChanged(); | 
|---|
| 75 | } | 
|---|
| 76 | } | 
|---|
| 77 |  | 
|---|
| 78 | /*! | 
|---|
| 79 | Draw the marker | 
|---|
| 80 |  | 
|---|
| 81 | \param painter Painter | 
|---|
| 82 | \param azimuthMap Maps azimuth values to values related to 0.0, M_2PI | 
|---|
| 83 | \param radialMap Maps radius values into painter coordinates. | 
|---|
| 84 | \param pole Position of the pole in painter coordinates | 
|---|
| 85 | \param radius Radius of the complete plot area in painter coordinates | 
|---|
| 86 | \param canvasRect Contents rect of the canvas in painter coordinates | 
|---|
| 87 | */ | 
|---|
| 88 | void QwtPolarMarker::draw( QPainter *painter, | 
|---|
| 89 | const QwtScaleMap &azimuthMap, const QwtScaleMap &radialMap, | 
|---|
| 90 | const QPointF &pole, double radius, | 
|---|
| 91 | const QRectF &canvasRect ) const | 
|---|
| 92 | { | 
|---|
| 93 | Q_UNUSED( radius ); | 
|---|
| 94 | Q_UNUSED( canvasRect ); | 
|---|
| 95 |  | 
|---|
| 96 | const double r = radialMap.transform( d_data->pos.radius() ); | 
|---|
| 97 | const double a = azimuthMap.transform( d_data->pos.azimuth() ); | 
|---|
| 98 |  | 
|---|
| 99 | const QPointF pos = qwtPolar2Pos( pole, r, a ); | 
|---|
| 100 |  | 
|---|
| 101 |  | 
|---|
| 102 | // draw symbol | 
|---|
| 103 | QSize sSym( 0, 0 ); | 
|---|
| 104 | if ( d_data->symbol->style() != QwtSymbol::NoSymbol ) | 
|---|
| 105 | { | 
|---|
| 106 | sSym = d_data->symbol->size(); | 
|---|
| 107 | d_data->symbol->drawSymbol( painter, pos ); | 
|---|
| 108 | } | 
|---|
| 109 |  | 
|---|
| 110 | // draw label | 
|---|
| 111 | if ( !d_data->label.isEmpty() ) | 
|---|
| 112 | { | 
|---|
| 113 | int xlw = qMax( int( d_data->pen.width() ), 1 ); | 
|---|
| 114 | int ylw = xlw; | 
|---|
| 115 |  | 
|---|
| 116 | int xlw1 = qMax( ( xlw + 1 ) / 2, ( sSym.width() + 1 ) / 2 ) + LabelDist; | 
|---|
| 117 | xlw = qMax( xlw / 2, ( sSym.width() + 1 ) / 2 ) + LabelDist; | 
|---|
| 118 | int ylw1 = qMax( ( ylw + 1 ) / 2, ( sSym.height() + 1 ) / 2 ) + LabelDist; | 
|---|
| 119 | ylw = qMax( ylw / 2, ( sSym. height() + 1 ) / 2 ) + LabelDist; | 
|---|
| 120 |  | 
|---|
| 121 | QRect tr( QPoint( 0, 0 ), d_data->label.textSize( painter->font() ).toSize() ); | 
|---|
| 122 | tr.moveCenter( QPoint( 0, 0 ) ); | 
|---|
| 123 |  | 
|---|
| 124 | int dx = pos.x(); | 
|---|
| 125 | int dy = pos.y(); | 
|---|
| 126 |  | 
|---|
| 127 | if ( d_data->align & Qt::AlignTop ) | 
|---|
| 128 | dy += tr.y() - ylw1; | 
|---|
| 129 | else if ( d_data->align & Qt::AlignBottom ) | 
|---|
| 130 | dy -= tr.y() - ylw1; | 
|---|
| 131 |  | 
|---|
| 132 | if ( d_data->align & Qt::AlignLeft ) | 
|---|
| 133 | dx += tr.x() - xlw1; | 
|---|
| 134 | else if ( d_data->align & Qt::AlignRight ) | 
|---|
| 135 | dx -= tr.x() - xlw1; | 
|---|
| 136 |  | 
|---|
| 137 | tr.translate( dx, dy ); | 
|---|
| 138 | d_data->label.draw( painter, tr ); | 
|---|
| 139 | } | 
|---|
| 140 | } | 
|---|
| 141 |  | 
|---|
| 142 | /*! | 
|---|
| 143 | \brief Assign a symbol | 
|---|
| 144 | \param symbol New symbol | 
|---|
| 145 | \sa symbol() | 
|---|
| 146 | */ | 
|---|
| 147 | void QwtPolarMarker::setSymbol( const QwtSymbol *symbol ) | 
|---|
| 148 | { | 
|---|
| 149 | if ( d_data->symbol != symbol ) | 
|---|
| 150 | { | 
|---|
| 151 | delete d_data->symbol; | 
|---|
| 152 | d_data->symbol = symbol; | 
|---|
| 153 | itemChanged(); | 
|---|
| 154 | } | 
|---|
| 155 | } | 
|---|
| 156 |  | 
|---|
| 157 | /*! | 
|---|
| 158 | \return the symbol | 
|---|
| 159 | \sa setSymbol(), QwtSymbol | 
|---|
| 160 | */ | 
|---|
| 161 | const QwtSymbol *QwtPolarMarker::symbol() const | 
|---|
| 162 | { | 
|---|
| 163 | return d_data->symbol; | 
|---|
| 164 | } | 
|---|
| 165 |  | 
|---|
| 166 | /*! | 
|---|
| 167 | \brief Set the label | 
|---|
| 168 | \param label label text | 
|---|
| 169 | \sa label() | 
|---|
| 170 | */ | 
|---|
| 171 | void QwtPolarMarker::setLabel( const QwtText& label ) | 
|---|
| 172 | { | 
|---|
| 173 | if ( label != d_data->label ) | 
|---|
| 174 | { | 
|---|
| 175 | d_data->label = label; | 
|---|
| 176 | itemChanged(); | 
|---|
| 177 | } | 
|---|
| 178 | } | 
|---|
| 179 |  | 
|---|
| 180 | /*! | 
|---|
| 181 | \return the label | 
|---|
| 182 | \sa setLabel() | 
|---|
| 183 | */ | 
|---|
| 184 | QwtText QwtPolarMarker::label() const | 
|---|
| 185 | { | 
|---|
| 186 | return d_data->label; | 
|---|
| 187 | } | 
|---|
| 188 |  | 
|---|
| 189 | /*! | 
|---|
| 190 | \brief Set the alignment of the label | 
|---|
| 191 |  | 
|---|
| 192 | The alignment determines where the label is drawn relative to | 
|---|
| 193 | the marker's position. | 
|---|
| 194 |  | 
|---|
| 195 | \param align Alignment. A combination of AlignTop, AlignBottom, | 
|---|
| 196 | AlignLeft, AlignRight, AlignCenter, AlgnHCenter, | 
|---|
| 197 | AlignVCenter. | 
|---|
| 198 | \sa labelAlignment() | 
|---|
| 199 | */ | 
|---|
| 200 | void QwtPolarMarker::setLabelAlignment( Qt::Alignment align ) | 
|---|
| 201 | { | 
|---|
| 202 | if ( align == d_data->align ) | 
|---|
| 203 | return; | 
|---|
| 204 |  | 
|---|
| 205 | d_data->align = align; | 
|---|
| 206 | itemChanged(); | 
|---|
| 207 | } | 
|---|
| 208 |  | 
|---|
| 209 | /*! | 
|---|
| 210 | \return the label alignment | 
|---|
| 211 | \sa setLabelAlignment() | 
|---|
| 212 | */ | 
|---|
| 213 | Qt::Alignment QwtPolarMarker::labelAlignment() const | 
|---|
| 214 | { | 
|---|
| 215 | return d_data->align; | 
|---|
| 216 | } | 
|---|
| 217 |  | 
|---|
| 218 | /*! | 
|---|
| 219 | Interval, that is necessary to display the item | 
|---|
| 220 | This interval can be useful for operations like clipping or autoscaling | 
|---|
| 221 |  | 
|---|
| 222 | \param scaleId Scale index | 
|---|
| 223 | \return bounding interval ( == position ) | 
|---|
| 224 |  | 
|---|
| 225 | \sa position() | 
|---|
| 226 | */ | 
|---|
| 227 | QwtInterval QwtPolarMarker::boundingInterval( int scaleId ) const | 
|---|
| 228 | { | 
|---|
| 229 | const double v = ( scaleId == QwtPolar::ScaleRadius ) | 
|---|
| 230 | ? d_data->pos.radius() : d_data->pos.azimuth(); | 
|---|
| 231 |  | 
|---|
| 232 | return QwtInterval( v, v ); | 
|---|
| 233 | } | 
|---|