source: ntrip/trunk/BNC/qwt/qwt_plot_marker.cpp@ 9184

Last change on this file since 9184 was 8127, checked in by stoecker, 7 years ago

update qwt and qwtpolar, many QT5 fixes (unfinished)

File size: 14.0 KB
Line 
1/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
2 * Qwt Widget Library
3 * Copyright (C) 1997 Josef Wilgen
4 * Copyright (C) 2002 Uwe Rathmann
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the Qwt License, Version 1.0
8 *****************************************************************************/
9
10#include "qwt_plot_marker.h"
11#include "qwt_painter.h"
12#include "qwt_scale_map.h"
13#include "qwt_symbol.h"
14#include "qwt_text.h"
15#include "qwt_math.h"
16#include <qpainter.h>
17
18class QwtPlotMarker::PrivateData
19{
20public:
21 PrivateData():
22 labelAlignment( Qt::AlignCenter ),
23 labelOrientation( Qt::Horizontal ),
24 spacing( 2 ),
25 symbol( NULL ),
26 style( QwtPlotMarker::NoLine ),
27 xValue( 0.0 ),
28 yValue( 0.0 )
29 {
30 }
31
32 ~PrivateData()
33 {
34 delete symbol;
35 }
36
37 QwtText label;
38 Qt::Alignment labelAlignment;
39 Qt::Orientation labelOrientation;
40 int spacing;
41
42 QPen pen;
43 const QwtSymbol *symbol;
44 LineStyle style;
45
46 double xValue;
47 double yValue;
48};
49
50//! Sets alignment to Qt::AlignCenter, and style to QwtPlotMarker::NoLine
51QwtPlotMarker::QwtPlotMarker( const QString &title ):
52 QwtPlotItem( QwtText( title ) )
53{
54 d_data = new PrivateData;
55 setZ( 30.0 );
56}
57
58//! Sets alignment to Qt::AlignCenter, and style to QwtPlotMarker::NoLine
59QwtPlotMarker::QwtPlotMarker( const QwtText &title ):
60 QwtPlotItem( title )
61{
62 d_data = new PrivateData;
63 setZ( 30.0 );
64}
65
66//! Destructor
67QwtPlotMarker::~QwtPlotMarker()
68{
69 delete d_data;
70}
71
72//! \return QwtPlotItem::Rtti_PlotMarker
73int QwtPlotMarker::rtti() const
74{
75 return QwtPlotItem::Rtti_PlotMarker;
76}
77
78//! Return Value
79QPointF QwtPlotMarker::value() const
80{
81 return QPointF( d_data->xValue, d_data->yValue );
82}
83
84//! Return x Value
85double QwtPlotMarker::xValue() const
86{
87 return d_data->xValue;
88}
89
90//! Return y Value
91double QwtPlotMarker::yValue() const
92{
93 return d_data->yValue;
94}
95
96//! Set Value
97void QwtPlotMarker::setValue( const QPointF& pos )
98{
99 setValue( pos.x(), pos.y() );
100}
101
102//! Set Value
103void QwtPlotMarker::setValue( double x, double y )
104{
105 if ( x != d_data->xValue || y != d_data->yValue )
106 {
107 d_data->xValue = x;
108 d_data->yValue = y;
109 itemChanged();
110 }
111}
112
113//! Set X Value
114void QwtPlotMarker::setXValue( double x )
115{
116 setValue( x, d_data->yValue );
117}
118
119//! Set Y Value
120void QwtPlotMarker::setYValue( double y )
121{
122 setValue( d_data->xValue, y );
123}
124
125/*!
126 Draw the marker
127
128 \param painter Painter
129 \param xMap x Scale Map
130 \param yMap y Scale Map
131 \param canvasRect Contents rectangle of the canvas in painter coordinates
132*/
133void QwtPlotMarker::draw( QPainter *painter,
134 const QwtScaleMap &xMap, const QwtScaleMap &yMap,
135 const QRectF &canvasRect ) const
136{
137 const QPointF pos( xMap.transform( d_data->xValue ),
138 yMap.transform( d_data->yValue ) );
139
140 // draw lines
141
142 drawLines( painter, canvasRect, pos );
143
144 // draw symbol
145 if ( d_data->symbol &&
146 ( d_data->symbol->style() != QwtSymbol::NoSymbol ) )
147 {
148 const QSizeF sz = d_data->symbol->size();
149
150 const QRectF clipRect = canvasRect.adjusted(
151 -sz.width(), -sz.height(), sz.width(), sz.height() );
152
153 if ( clipRect.contains( pos ) )
154 d_data->symbol->drawSymbol( painter, pos );
155 }
156
157 drawLabel( painter, canvasRect, pos );
158}
159
160/*!
161 Draw the lines marker
162
163 \param painter Painter
164 \param canvasRect Contents rectangle of the canvas in painter coordinates
165 \param pos Position of the marker, translated into widget coordinates
166
167 \sa drawLabel(), QwtSymbol::drawSymbol()
168*/
169void QwtPlotMarker::drawLines( QPainter *painter,
170 const QRectF &canvasRect, const QPointF &pos ) const
171{
172 if ( d_data->style == NoLine )
173 return;
174
175 const bool doAlign = QwtPainter::roundingAlignment( painter );
176
177 painter->setPen( d_data->pen );
178 if ( d_data->style == QwtPlotMarker::HLine ||
179 d_data->style == QwtPlotMarker::Cross )
180 {
181 double y = pos.y();
182 if ( doAlign )
183 y = qRound( y );
184
185 QwtPainter::drawLine( painter, canvasRect.left(),
186 y, canvasRect.right() - 1.0, y );
187 }
188 if ( d_data->style == QwtPlotMarker::VLine ||
189 d_data->style == QwtPlotMarker::Cross )
190 {
191 double x = pos.x();
192 if ( doAlign )
193 x = qRound( x );
194
195 QwtPainter::drawLine( painter, x,
196 canvasRect.top(), x, canvasRect.bottom() - 1.0 );
197 }
198}
199
200/*!
201 Align and draw the text label of the marker
202
203 \param painter Painter
204 \param canvasRect Contents rectangle of the canvas in painter coordinates
205 \param pos Position of the marker, translated into widget coordinates
206
207 \sa drawLabel(), QwtSymbol::drawSymbol()
208*/
209void QwtPlotMarker::drawLabel( QPainter *painter,
210 const QRectF &canvasRect, const QPointF &pos ) const
211{
212 if ( d_data->label.isEmpty() )
213 return;
214
215 Qt::Alignment align = d_data->labelAlignment;
216 QPointF alignPos = pos;
217
218 QSizeF symbolOff( 0, 0 );
219
220 switch ( d_data->style )
221 {
222 case QwtPlotMarker::VLine:
223 {
224 // In VLine-style the y-position is pointless and
225 // the alignment flags are relative to the canvas
226
227 if ( d_data->labelAlignment & Qt::AlignTop )
228 {
229 alignPos.setY( canvasRect.top() );
230 align &= ~Qt::AlignTop;
231 align |= Qt::AlignBottom;
232 }
233 else if ( d_data->labelAlignment & Qt::AlignBottom )
234 {
235 // In HLine-style the x-position is pointless and
236 // the alignment flags are relative to the canvas
237
238 alignPos.setY( canvasRect.bottom() - 1 );
239 align &= ~Qt::AlignBottom;
240 align |= Qt::AlignTop;
241 }
242 else
243 {
244 alignPos.setY( canvasRect.center().y() );
245 }
246 break;
247 }
248 case QwtPlotMarker::HLine:
249 {
250 if ( d_data->labelAlignment & Qt::AlignLeft )
251 {
252 alignPos.setX( canvasRect.left() );
253 align &= ~Qt::AlignLeft;
254 align |= Qt::AlignRight;
255 }
256 else if ( d_data->labelAlignment & Qt::AlignRight )
257 {
258 alignPos.setX( canvasRect.right() - 1 );
259 align &= ~Qt::AlignRight;
260 align |= Qt::AlignLeft;
261 }
262 else
263 {
264 alignPos.setX( canvasRect.center().x() );
265 }
266 break;
267 }
268 default:
269 {
270 if ( d_data->symbol &&
271 ( d_data->symbol->style() != QwtSymbol::NoSymbol ) )
272 {
273 symbolOff = d_data->symbol->size() + QSizeF( 1, 1 );
274 symbolOff /= 2;
275 }
276 }
277 }
278
279 qreal pw2 = d_data->pen.widthF() / 2.0;
280 if ( pw2 == 0.0 )
281 pw2 = 0.5;
282
283 const int spacing = d_data->spacing;
284
285 const qreal xOff = qMax( pw2, symbolOff.width() );
286 const qreal yOff = qMax( pw2, symbolOff.height() );
287
288 const QSizeF textSize = d_data->label.textSize( painter->font() );
289
290 if ( align & Qt::AlignLeft )
291 {
292 alignPos.rx() -= xOff + spacing;
293 if ( d_data->labelOrientation == Qt::Vertical )
294 alignPos.rx() -= textSize.height();
295 else
296 alignPos.rx() -= textSize.width();
297 }
298 else if ( align & Qt::AlignRight )
299 {
300 alignPos.rx() += xOff + spacing;
301 }
302 else
303 {
304 if ( d_data->labelOrientation == Qt::Vertical )
305 alignPos.rx() -= textSize.height() / 2;
306 else
307 alignPos.rx() -= textSize.width() / 2;
308 }
309
310 if ( align & Qt::AlignTop )
311 {
312 alignPos.ry() -= yOff + spacing;
313 if ( d_data->labelOrientation != Qt::Vertical )
314 alignPos.ry() -= textSize.height();
315 }
316 else if ( align & Qt::AlignBottom )
317 {
318 alignPos.ry() += yOff + spacing;
319 if ( d_data->labelOrientation == Qt::Vertical )
320 alignPos.ry() += textSize.width();
321 }
322 else
323 {
324 if ( d_data->labelOrientation == Qt::Vertical )
325 alignPos.ry() += textSize.width() / 2;
326 else
327 alignPos.ry() -= textSize.height() / 2;
328 }
329
330 painter->translate( alignPos.x(), alignPos.y() );
331 if ( d_data->labelOrientation == Qt::Vertical )
332 painter->rotate( -90.0 );
333
334 const QRectF textRect( 0, 0, textSize.width(), textSize.height() );
335 d_data->label.draw( painter, textRect );
336}
337
338/*!
339 \brief Set the line style
340 \param style Line style.
341 \sa lineStyle()
342*/
343void QwtPlotMarker::setLineStyle( LineStyle style )
344{
345 if ( style != d_data->style )
346 {
347 d_data->style = style;
348
349 legendChanged();
350 itemChanged();
351 }
352}
353
354/*!
355 \return the line style
356 \sa setLineStyle()
357*/
358QwtPlotMarker::LineStyle QwtPlotMarker::lineStyle() const
359{
360 return d_data->style;
361}
362
363/*!
364 \brief Assign a symbol
365 \param symbol New symbol
366 \sa symbol()
367*/
368void QwtPlotMarker::setSymbol( const QwtSymbol *symbol )
369{
370 if ( symbol != d_data->symbol )
371 {
372 delete d_data->symbol;
373 d_data->symbol = symbol;
374
375 if ( symbol )
376 setLegendIconSize( symbol->boundingRect().size() );
377
378 legendChanged();
379 itemChanged();
380 }
381}
382
383/*!
384 \return the symbol
385 \sa setSymbol(), QwtSymbol
386*/
387const QwtSymbol *QwtPlotMarker::symbol() const
388{
389 return d_data->symbol;
390}
391
392/*!
393 \brief Set the label
394 \param label Label text
395 \sa label()
396*/
397void QwtPlotMarker::setLabel( const QwtText& label )
398{
399 if ( label != d_data->label )
400 {
401 d_data->label = label;
402 itemChanged();
403 }
404}
405
406/*!
407 \return the label
408 \sa setLabel()
409*/
410QwtText QwtPlotMarker::label() const
411{
412 return d_data->label;
413}
414
415/*!
416 \brief Set the alignment of the label
417
418 In case of QwtPlotMarker::HLine the alignment is relative to the
419 y position of the marker, but the horizontal flags correspond to the
420 canvas rectangle. In case of QwtPlotMarker::VLine the alignment is
421 relative to the x position of the marker, but the vertical flags
422 correspond to the canvas rectangle.
423
424 In all other styles the alignment is relative to the marker's position.
425
426 \param align Alignment.
427 \sa labelAlignment(), labelOrientation()
428*/
429void QwtPlotMarker::setLabelAlignment( Qt::Alignment align )
430{
431 if ( align != d_data->labelAlignment )
432 {
433 d_data->labelAlignment = align;
434 itemChanged();
435 }
436}
437
438/*!
439 \return the label alignment
440 \sa setLabelAlignment(), setLabelOrientation()
441*/
442Qt::Alignment QwtPlotMarker::labelAlignment() const
443{
444 return d_data->labelAlignment;
445}
446
447/*!
448 \brief Set the orientation of the label
449
450 When orientation is Qt::Vertical the label is rotated by 90.0 degrees
451 ( from bottom to top ).
452
453 \param orientation Orientation of the label
454
455 \sa labelOrientation(), setLabelAlignment()
456*/
457void QwtPlotMarker::setLabelOrientation( Qt::Orientation orientation )
458{
459 if ( orientation != d_data->labelOrientation )
460 {
461 d_data->labelOrientation = orientation;
462 itemChanged();
463 }
464}
465
466/*!
467 \return the label orientation
468 \sa setLabelOrientation(), labelAlignment()
469*/
470Qt::Orientation QwtPlotMarker::labelOrientation() const
471{
472 return d_data->labelOrientation;
473}
474
475/*!
476 \brief Set the spacing
477
478 When the label is not centered on the marker position, the spacing
479 is the distance between the position and the label.
480
481 \param spacing Spacing
482 \sa spacing(), setLabelAlignment()
483*/
484void QwtPlotMarker::setSpacing( int spacing )
485{
486 if ( spacing < 0 )
487 spacing = 0;
488
489 if ( spacing == d_data->spacing )
490 return;
491
492 d_data->spacing = spacing;
493 itemChanged();
494}
495
496/*!
497 \return the spacing
498 \sa setSpacing()
499*/
500int QwtPlotMarker::spacing() const
501{
502 return d_data->spacing;
503}
504
505/*!
506 Build and assign a line pen
507
508 In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it
509 non cosmetic ( see QPen::isCosmetic() ). This method has been introduced
510 to hide this incompatibility.
511
512 \param color Pen color
513 \param width Pen width
514 \param style Pen style
515
516 \sa pen(), brush()
517 */
518void QwtPlotMarker::setLinePen( const QColor &color, qreal width, Qt::PenStyle style )
519{
520 setLinePen( QPen( color, width, style ) );
521}
522
523/*!
524 Specify a pen for the line.
525
526 \param pen New pen
527 \sa linePen()
528*/
529void QwtPlotMarker::setLinePen( const QPen &pen )
530{
531 if ( pen != d_data->pen )
532 {
533 d_data->pen = pen;
534
535 legendChanged();
536 itemChanged();
537 }
538}
539
540/*!
541 \return the line pen
542 \sa setLinePen()
543*/
544const QPen &QwtPlotMarker::linePen() const
545{
546 return d_data->pen;
547}
548
549QRectF QwtPlotMarker::boundingRect() const
550{
551 return QRectF( d_data->xValue, d_data->yValue, 0.0, 0.0 );
552}
553
554/*!
555 \return Icon representing the marker on the legend
556
557 \param index Index of the legend entry
558 ( usually there is only one )
559 \param size Icon size
560
561 \sa setLegendIconSize(), legendData()
562*/
563QwtGraphic QwtPlotMarker::legendIcon( int index,
564 const QSizeF &size ) const
565{
566 Q_UNUSED( index );
567
568 if ( size.isEmpty() )
569 return QwtGraphic();
570
571 QwtGraphic icon;
572 icon.setDefaultSize( size );
573 icon.setRenderHint( QwtGraphic::RenderPensUnscaled, true );
574
575 QPainter painter( &icon );
576 painter.setRenderHint( QPainter::Antialiasing,
577 testRenderHint( QwtPlotItem::RenderAntialiased ) );
578
579 if ( d_data->style != QwtPlotMarker::NoLine )
580 {
581 painter.setPen( d_data->pen );
582
583 if ( d_data->style == QwtPlotMarker::HLine ||
584 d_data->style == QwtPlotMarker::Cross )
585 {
586 const double y = 0.5 * size.height();
587
588 QwtPainter::drawLine( &painter,
589 0.0, y, size.width(), y );
590 }
591
592 if ( d_data->style == QwtPlotMarker::VLine ||
593 d_data->style == QwtPlotMarker::Cross )
594 {
595 const double x = 0.5 * size.width();
596
597 QwtPainter::drawLine( &painter,
598 x, 0.0, x, size.height() );
599 }
600 }
601
602 if ( d_data->symbol )
603 {
604 const QRect r( 0.0, 0.0, size.width(), size.height() );
605 d_data->symbol->drawSymbol( &painter, r );
606 }
607
608 return icon;
609}
610
Note: See TracBrowser for help on using the repository browser.