source: ntrip/trunk/BNC/qwt/qwt_polar_grid.cpp

Last change on this file was 11158, checked in by stuerze, 8 days ago

deprecated functions exchanged libs updated

File size: 31.7 KB
Line 
1/******************************************************************************
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_grid.h"
10#include "qwt_painter.h"
11#include "qwt_text.h"
12#include "qwt_clipper.h"
13#include "qwt_scale_map.h"
14#include "qwt_scale_engine.h"
15#include "qwt_scale_div.h"
16#include "qwt_scale_draw.h"
17#include "qwt_round_scale_draw.h"
18
19#include <qpainter.h>
20#include <qpen.h>
21#include <float.h>
22
23static inline bool isClose( double value1, double value2 )
24{
25 return qAbs( value1 - value2 ) < DBL_EPSILON;
26}
27
28namespace
29{
30 class AxisData
31 {
32 public:
33 AxisData()
34 : isVisible( false )
35 , scaleDraw( NULL )
36 {
37 }
38
39 ~AxisData()
40 {
41 delete scaleDraw;
42 }
43
44 bool isVisible;
45 mutable QwtAbstractScaleDraw* scaleDraw;
46 QPen pen;
47 QFont font;
48 };
49
50 class GridData
51 {
52 public:
53 GridData()
54 : isVisible( true )
55 , isMinorVisible( false )
56 {
57 }
58
59 bool isVisible;
60 bool isMinorVisible;
61 QwtScaleDiv scaleDiv;
62
63 QPen majorPen;
64 QPen minorPen;
65 };
66}
67
68class QwtPolarGrid::PrivateData
69{
70 public:
71 GridData gridData[QwtPolar::ScaleCount];
72 AxisData axisData[QwtPolar::AxesCount];
73 QwtPolarGrid::DisplayFlags displayFlags;
74 QwtPolarGrid::GridAttributes attributes;
75};
76
77/*!
78 \brief Constructor
79
80 Enables major and disables minor grid lines.
81 The azimuth and right radial axis are visible. all other axes
82 are hidden. Autoscaling is enabled.
83 */
84QwtPolarGrid::QwtPolarGrid()
85 : QwtPolarItem( QwtText( "Grid" ) )
86{
87 m_data = new PrivateData;
88
89 for ( int axisId = 0; axisId < QwtPolar::AxesCount; axisId++ )
90 {
91 AxisData& axis = m_data->axisData[axisId];
92 switch( axisId )
93 {
94 case QwtPolar::AxisAzimuth:
95 {
96 axis.scaleDraw = new QwtRoundScaleDraw;
97 axis.scaleDraw->setTickLength( QwtScaleDiv::MinorTick, 2 );
98 axis.scaleDraw->setTickLength( QwtScaleDiv::MediumTick, 2 );
99 axis.scaleDraw->setTickLength( QwtScaleDiv::MajorTick, 4 );
100 axis.isVisible = true;
101 break;
102 }
103 case QwtPolar::AxisLeft:
104 {
105 QwtScaleDraw* scaleDraw = new QwtScaleDraw;
106 scaleDraw->setAlignment( QwtScaleDraw::BottomScale );
107
108 axis.scaleDraw = scaleDraw;
109 axis.isVisible = false;
110 break;
111 }
112 case QwtPolar::AxisRight:
113 {
114 QwtScaleDraw* scaleDraw = new QwtScaleDraw;
115 scaleDraw->setAlignment( QwtScaleDraw::BottomScale );
116
117 axis.scaleDraw = scaleDraw;
118 axis.isVisible = true;
119 break;
120 }
121 case QwtPolar::AxisTop:
122 {
123 QwtScaleDraw* scaleDraw = new QwtScaleDraw;
124 scaleDraw->setAlignment( QwtScaleDraw::LeftScale );
125
126 axis.scaleDraw = scaleDraw;
127 axis.isVisible = false;
128 break;
129 }
130 case QwtPolar::AxisBottom:
131 {
132 QwtScaleDraw* scaleDraw = new QwtScaleDraw;
133 scaleDraw->setAlignment( QwtScaleDraw::LeftScale );
134
135 axis.scaleDraw = scaleDraw;
136 axis.isVisible = true;
137 break;
138 }
139 default:;
140 }
141 }
142
143 m_data->attributes = AutoScaling;
144
145 m_data->displayFlags = DisplayFlags();
146 m_data->displayFlags |= SmartOriginLabel;
147 m_data->displayFlags |= HideMaxRadiusLabel;
148 m_data->displayFlags |= ClipAxisBackground;
149 m_data->displayFlags |= SmartScaleDraw;
150 m_data->displayFlags |= ClipGridLines;
151
152 setZ( 10.0 );
153 setRenderHint( RenderAntialiased, true );
154}
155
156//! Destructor
157QwtPolarGrid::~QwtPolarGrid()
158{
159 delete m_data;
160}
161
162//! \return QwtPlotItem::Rtti_PolarGrid
163int QwtPolarGrid::rtti() const
164{
165 return QwtPolarItem::Rtti_PolarGrid;
166}
167
168/*!
169 Change the display flags
170
171 \param flag See DisplayFlag
172 \param on true/false
173 */
174void QwtPolarGrid::setDisplayFlag( DisplayFlag flag, bool on )
175{
176 if ( ( ( m_data->displayFlags & flag ) != 0 ) != on )
177 {
178 if ( on )
179 m_data->displayFlags |= flag;
180 else
181 m_data->displayFlags &= ~flag;
182
183 itemChanged();
184 }
185}
186
187/*!
188 \return true, if flag is enabled
189 \param flag See DisplayFlag
190 */
191bool QwtPolarGrid::testDisplayFlag( DisplayFlag flag ) const
192{
193 return ( m_data->displayFlags & flag );
194}
195
196/*!
197 \brief Specify an attribute for the grid
198
199 \param attribute Grid attribute
200 \param on On/Off
201
202 /sa GridAttribute, testGridAttribute(), updateScaleDiv(),
203 QwtPolarPlot::zoom(), QwtPolarPlot::scaleDiv()
204 */
205void QwtPolarGrid::setGridAttribute( GridAttribute attribute, bool on )
206{
207 if ( bool( m_data->attributes & attribute ) == on )
208 return;
209
210 if ( on )
211 m_data->attributes |= attribute;
212 else
213 m_data->attributes &= ~attribute;
214
215 itemChanged();
216}
217
218/*!
219 \return true, if attribute is enabled
220 \sa GridAttribute, setGridAttribute()
221 */
222bool QwtPolarGrid::testGridAttribute( GridAttribute attribute ) const
223{
224 return m_data->attributes & attribute;
225}
226
227/*!
228 Assign a pen for painting an axis
229
230 \param axisId Axis id (QwtPolar::Axis)
231 \param pen Pen
232
233 \sa axisPen()
234 */
235void QwtPolarGrid::setAxisPen( int axisId, const QPen& pen )
236{
237 if ( axisId < 0 || axisId >= QwtPolar::AxesCount )
238 return;
239
240 AxisData& axisData = m_data->axisData[axisId];
241 if ( axisData.pen != pen )
242 {
243 axisData.pen = pen;
244 itemChanged();
245 }
246}
247
248/*!
249 Show/Hide grid lines for a scale
250
251 \param scaleId Scale id ( QwtPolar::Scale )
252 \param show true/false
253 */
254void QwtPolarGrid::showGrid( int scaleId, bool show )
255{
256 if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
257 return;
258
259 GridData& grid = m_data->gridData[scaleId];
260 if ( grid.isVisible != show )
261 {
262 grid.isVisible = show;
263 itemChanged();
264 }
265}
266
267/*!
268 \return true if grid lines are enabled
269 \param scaleId Scale id ( QwtPolar::Scale )
270 \sa QwtPolar::Scale, showGrid()
271 */
272bool QwtPolarGrid::isGridVisible( int scaleId ) const
273{
274 if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
275 return false;
276
277 return m_data->gridData[scaleId].isVisible;
278}
279
280/*!
281 Show/Hide minor grid lines for a scale
282
283 To display minor grid lines. showGrid() needs to be enabled too.
284
285 \param scaleId Scale id ( QwtPolar::Scale )
286 \param show true/false
287
288 \sa showGrid
289 */
290void QwtPolarGrid::showMinorGrid( int scaleId, bool show )
291{
292 if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
293 return;
294
295 GridData& grid = m_data->gridData[scaleId];
296 if ( grid.isMinorVisible != show )
297 {
298 grid.isMinorVisible = show;
299 itemChanged();
300 }
301}
302
303/*!
304 \return true if minor grid lines are enabled
305 \param scaleId Scale id ( QwtPolar::Scale )
306 \sa showMinorGrid()
307 */
308bool QwtPolarGrid::isMinorGridVisible( int scaleId ) const
309{
310 if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
311 return false;
312
313 return m_data->gridData[scaleId].isMinorVisible;
314}
315
316/*!
317 Show/Hide an axis
318
319 \param axisId Axis id (QwtPolar::Axis)
320 \param show true/false
321
322 \sa isAxisVisible()
323 */
324void QwtPolarGrid::showAxis( int axisId, bool show )
325{
326 if ( axisId < 0 || axisId >= QwtPolar::AxesCount )
327 return;
328
329 AxisData& axisData = m_data->axisData[axisId];
330 if ( axisData.isVisible != show )
331 {
332 axisData.isVisible = show;
333 itemChanged();
334 }
335}
336
337/*!
338 \return true if the axis is visible
339 \param axisId Axis id (QwtPolar::Axis)
340
341 \sa showAxis()
342 */
343bool QwtPolarGrid::isAxisVisible( int axisId ) const
344{
345 if ( axisId < 0 || axisId >= QwtPolar::AxesCount )
346 return false;
347
348 return m_data->axisData[axisId].isVisible;
349}
350
351/*!
352 Assign a pen for all axes and grid lines
353
354 \param pen Pen
355 \sa setMajorGridPen(), setMinorGridPen(), setAxisPen()
356 */
357void QwtPolarGrid::setPen( const QPen& pen )
358{
359 bool isChanged = false;
360
361 for ( int scaleId = 0; scaleId < QwtPolar::ScaleCount; scaleId++ )
362 {
363 GridData& grid = m_data->gridData[scaleId];
364 if ( grid.majorPen != pen || grid.minorPen != pen )
365 {
366 grid.majorPen = pen;
367 grid.minorPen = pen;
368 isChanged = true;
369 }
370 }
371 for ( int axisId = 0; axisId < QwtPolar::AxesCount; axisId++ )
372 {
373 AxisData& axis = m_data->axisData[axisId];
374 if ( axis.pen != pen )
375 {
376 axis.pen = pen;
377 isChanged = true;
378 }
379 }
380 if ( isChanged )
381 itemChanged();
382}
383
384/*!
385 Assign a font for all scale tick labels
386
387 \param font Font
388 \sa setAxisFont()
389 */
390void QwtPolarGrid::setFont( const QFont& font )
391{
392 bool isChanged = false;
393 for ( int axisId = 0; axisId < QwtPolar::AxesCount; axisId++ )
394 {
395 AxisData& axis = m_data->axisData[axisId];
396 if ( axis.font != font )
397 {
398 axis.font = font;
399 isChanged = true;
400 }
401 }
402 if ( isChanged )
403 itemChanged();
404}
405
406/*!
407 Assign a pen for the major grid lines
408
409 \param pen Pen
410 \sa setPen(), setMinorGridPen(), majorGridPen
411 */
412void QwtPolarGrid::setMajorGridPen( const QPen& pen )
413{
414 bool isChanged = false;
415
416 for ( int scaleId = 0; scaleId < QwtPolar::ScaleCount; scaleId++ )
417 {
418 GridData& grid = m_data->gridData[scaleId];
419 if ( grid.majorPen != pen )
420 {
421 grid.majorPen = pen;
422 isChanged = true;
423 }
424 }
425 if ( isChanged )
426 itemChanged();
427}
428
429/*!
430 Assign a pen for the major grid lines of a specific scale
431
432 \param scaleId Scale id ( QwtPolar::Scale )
433 \param pen Pen
434 \sa setPen(), setMinorGridPen(), majorGridPen
435 */
436void QwtPolarGrid::setMajorGridPen( int scaleId, const QPen& pen )
437{
438 if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
439 return;
440
441 GridData& grid = m_data->gridData[scaleId];
442 if ( grid.majorPen != pen )
443 {
444 grid.majorPen = pen;
445 itemChanged();
446 }
447}
448
449/*!
450 \return Pen for painting the major grid lines of a specific scale
451 \param scaleId Scale id ( QwtPolar::Scale )
452 \sa setMajorGridPen(), minorGridPen()
453 */
454QPen QwtPolarGrid::majorGridPen( int scaleId ) const
455{
456 if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
457 return QPen();
458
459 const GridData& grid = m_data->gridData[scaleId];
460 return grid.majorPen;
461}
462
463/*!
464 Assign a pen for the minor grid lines
465
466 \param pen Pen
467 \sa setPen(), setMajorGridPen(), minorGridPen()
468 */
469void QwtPolarGrid::setMinorGridPen( const QPen& pen )
470{
471 bool isChanged = false;
472
473 for ( int scaleId = 0; scaleId < QwtPolar::ScaleCount; scaleId++ )
474 {
475 GridData& grid = m_data->gridData[scaleId];
476 if ( grid.minorPen != pen )
477 {
478 grid.minorPen = pen;
479 isChanged = true;
480 }
481 }
482 if ( isChanged )
483 itemChanged();
484}
485
486/*!
487 Assign a pen for the minor grid lines of a specific scale
488
489 \param scaleId Scale id ( QwtPolar::Scale )
490 \param pen Pen
491 \sa setPen(), setMajorGridPen(), minorGridPen
492 */
493void QwtPolarGrid::setMinorGridPen( int scaleId, const QPen& pen )
494{
495 if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
496 return;
497
498 GridData& grid = m_data->gridData[scaleId];
499 if ( grid.minorPen != pen )
500 {
501 grid.minorPen = pen;
502 itemChanged();
503 }
504}
505
506/*!
507 \return Pen for painting the minor grid lines of a specific scale
508 \param scaleId Scale id ( QwtPolar::Scale )
509 */
510QPen QwtPolarGrid::minorGridPen( int scaleId ) const
511{
512 if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
513 return QPen();
514
515 const GridData& grid = m_data->gridData[scaleId];
516 return grid.minorPen;
517}
518
519/*!
520 \return Pen for painting a specific axis
521
522 \param axisId Axis id (QwtPolar::Axis)
523 \sa setAxisPen()
524 */
525QPen QwtPolarGrid::axisPen( int axisId ) const
526{
527 if ( axisId < 0 || axisId >= QwtPolar::AxesCount )
528 return QPen();
529
530 return m_data->axisData[axisId].pen;
531}
532
533/*!
534 Assign a font for the tick labels of a specific axis
535
536 \param axisId Axis id (QwtPolar::Axis)
537 \param font new Font
538 */
539void QwtPolarGrid::setAxisFont( int axisId, const QFont& font )
540{
541 if ( axisId < 0 || axisId >= QwtPolar::AxesCount )
542 return;
543
544 AxisData& axisData = m_data->axisData[axisId];
545 if ( axisData.font != font )
546 {
547 axisData.font = font;
548 itemChanged();
549 }
550}
551
552/*!
553 \return Font for the tick labels of a specific axis
554 \param axisId Axis id (QwtPolar::Axis)
555 */
556QFont QwtPolarGrid::axisFont( int axisId ) const
557{
558 if ( axisId < 0 || axisId >= QwtPolar::AxesCount )
559 return QFont();
560
561 return m_data->axisData[axisId].font;
562}
563
564/*!
565 Draw the grid and axes
566
567 \param painter Painter
568 \param azimuthMap Maps azimuth values to values related to 0.0, M_2PI
569 \param radialMap Maps radius values into painter coordinates.
570 \param pole Position of the pole in painter coordinates
571 \param radius Radius of the complete plot area in painter coordinates
572 \param canvasRect Contents rect of the canvas in painter coordinates
573 */
574void QwtPolarGrid::draw( QPainter* painter,
575 const QwtScaleMap& azimuthMap, const QwtScaleMap& radialMap,
576 const QPointF& pole, double radius,
577 const QRectF& canvasRect ) const
578{
579 updateScaleDraws( azimuthMap, radialMap, pole, radius );
580
581 painter->save();
582
583 if ( testDisplayFlag( ClipAxisBackground ) )
584 {
585 QRegion clipRegion( canvasRect.toRect() );
586 for ( int axisId = 0; axisId < QwtPolar::AxesCount; axisId++ )
587 {
588 const AxisData& axis = m_data->axisData[axisId];
589 if ( axisId != QwtPolar::AxisAzimuth && axis.isVisible )
590 {
591 QwtScaleDraw* scaleDraw = static_cast< QwtScaleDraw* >( axis.scaleDraw );
592 if ( scaleDraw->hasComponent( QwtScaleDraw::Labels ) )
593 {
594 const QList< double >& ticks =
595 scaleDraw->scaleDiv().ticks( QwtScaleDiv::MajorTick );
596 for ( int i = 0; i < int( ticks.size() ); i++ )
597 {
598 if ( !scaleDraw->scaleDiv().contains( ticks[i] ) )
599 continue;
600
601 QRect labelRect =
602 scaleDraw->boundingLabelRect( axis.font, ticks[i] );
603
604 const int margin = 2;
605 labelRect.adjust( -margin, -margin, margin, margin );
606
607 if ( labelRect.isValid() )
608 clipRegion -= QRegion( labelRect );
609 }
610 }
611 }
612 }
613 painter->setClipRegion( clipRegion );
614 }
615
616 // draw radial grid
617
618 const GridData& radialGrid = m_data->gridData[QwtPolar::Radius];
619 if ( radialGrid.isVisible && radialGrid.isMinorVisible )
620 {
621 painter->setPen( radialGrid.minorPen );
622
623 drawCircles( painter, canvasRect, pole, radialMap,
624 radialGrid.scaleDiv.ticks( QwtScaleDiv::MinorTick ) );
625 drawCircles( painter, canvasRect, pole, radialMap,
626 radialGrid.scaleDiv.ticks( QwtScaleDiv::MediumTick ) );
627 }
628 if ( radialGrid.isVisible )
629 {
630 painter->setPen( radialGrid.majorPen );
631
632 drawCircles( painter, canvasRect, pole, radialMap,
633 radialGrid.scaleDiv.ticks( QwtScaleDiv::MajorTick ) );
634 }
635
636 // draw azimuth grid
637
638 const GridData& azimuthGrid =
639 m_data->gridData[QwtPolar::Azimuth];
640
641 if ( azimuthGrid.isVisible && azimuthGrid.isMinorVisible )
642 {
643 painter->setPen( azimuthGrid.minorPen );
644
645 drawRays( painter, canvasRect, pole, radius, azimuthMap,
646 azimuthGrid.scaleDiv.ticks( QwtScaleDiv::MinorTick ) );
647 drawRays( painter, canvasRect, pole, radius, azimuthMap,
648 azimuthGrid.scaleDiv.ticks( QwtScaleDiv::MediumTick ) );
649 }
650 if ( azimuthGrid.isVisible )
651 {
652 painter->setPen( azimuthGrid.majorPen );
653
654 drawRays( painter, canvasRect, pole, radius, azimuthMap,
655 azimuthGrid.scaleDiv.ticks( QwtScaleDiv::MajorTick ) );
656 }
657 painter->restore();
658
659 for ( int axisId = 0; axisId < QwtPolar::AxesCount; axisId++ )
660 {
661 const AxisData& axis = m_data->axisData[axisId];
662 if ( axis.isVisible )
663 {
664 painter->save();
665 drawAxis( painter, axisId );
666 painter->restore();
667 }
668 }
669}
670
671/*!
672 Draw lines from the pole
673
674 \param painter Painter
675 \param canvasRect Contents rect of the canvas in painter coordinates
676 \param pole Position of the pole in painter coordinates
677 \param radius Length of the lines in painter coordinates
678 \param azimuthMap Maps azimuth values to values related to 0.0, M_2PI
679 \param values Azimuth values, indicating the direction of the lines
680 */
681void QwtPolarGrid::drawRays(
682 QPainter* painter, const QRectF& canvasRect,
683 const QPointF& pole, double radius,
684 const QwtScaleMap& azimuthMap, const QList< double >& values ) const
685{
686 for ( int i = 0; i < int( values.size() ); i++ )
687 {
688 double azimuth = azimuthMap.transform( values[i] );
689 azimuth = ::fmod( azimuth, 2 * M_PI );
690
691 bool skipLine = false;
692 if ( testDisplayFlag( SmartScaleDraw ) )
693 {
694 const QwtAbstractScaleDraw::ScaleComponent bone =
695 QwtAbstractScaleDraw::Backbone;
696 if ( isClose( azimuth, 0.0 ) )
697 {
698 const AxisData& axis = m_data->axisData[QwtPolar::AxisRight];
699 if ( axis.isVisible && axis.scaleDraw->hasComponent( bone ) )
700 skipLine = true;
701 }
702 else if ( isClose( azimuth, M_PI / 2 ) )
703 {
704 const AxisData& axis = m_data->axisData[QwtPolar::AxisTop];
705 if ( axis.isVisible && axis.scaleDraw->hasComponent( bone ) )
706 skipLine = true;
707 }
708 else if ( isClose( azimuth, M_PI ) )
709 {
710 const AxisData& axis = m_data->axisData[QwtPolar::AxisLeft];
711 if ( axis.isVisible && axis.scaleDraw->hasComponent( bone ) )
712 skipLine = true;
713 }
714 else if ( isClose( azimuth, 3 * M_PI / 2.0 ) )
715 {
716 const AxisData& axis = m_data->axisData[QwtPolar::AxisBottom];
717 if ( axis.isVisible && axis.scaleDraw->hasComponent( bone ) )
718 skipLine = true;
719 }
720 }
721 if ( !skipLine )
722 {
723 const QPointF pos = qwtPolar2Pos( pole, radius, azimuth );
724
725 /*
726 Qt4 is horrible slow, when painting primitives,
727 with coordinates far outside the visible area.
728 */
729
730 QPolygonF polygon( 2 );
731 polygon[0] = pole.toPoint();
732 polygon[1] = pos.toPoint();
733
734 if ( testDisplayFlag( ClipGridLines ) )
735 QwtClipper::clipPolygonF( canvasRect, polygon );
736
737 QwtPainter::drawPolyline( painter, polygon );
738 }
739 }
740}
741
742/*!
743 Draw circles
744
745 \param painter Painter
746 \param canvasRect Contents rect of the canvas in painter coordinates
747 \param pole Position of the pole in painter coordinates
748 \param radialMap Maps radius values into painter coordinates.
749 \param values Radial values, indicating the distances from the pole
750 */
751void QwtPolarGrid::drawCircles(
752 QPainter* painter, const QRectF& canvasRect,
753 const QPointF& pole, const QwtScaleMap& radialMap,
754 const QList< double >& values ) const
755{
756 for ( int i = 0; i < int( values.size() ); i++ )
757 {
758 const double val = values[i];
759
760 const GridData& gridData =
761 m_data->gridData[QwtPolar::Radius];
762
763 bool skipLine = false;
764 if ( testDisplayFlag( SmartScaleDraw ) )
765 {
766 const AxisData& axis = m_data->axisData[QwtPolar::AxisAzimuth];
767 if ( axis.isVisible &&
768 axis.scaleDraw->hasComponent( QwtAbstractScaleDraw::Backbone ) )
769 {
770 if ( isClose( val, gridData.scaleDiv.upperBound() ) )
771 skipLine = true;
772 }
773 }
774
775 if ( isClose( val, gridData.scaleDiv.lowerBound() ) )
776 skipLine = true;
777
778 if ( !skipLine )
779 {
780 const double radius = radialMap.transform( val );
781
782 QRectF outerRect( 0, 0, 2 * radius, 2 * radius );
783 outerRect.moveCenter( pole );
784
785 if ( testDisplayFlag( ClipGridLines ) )
786 {
787 /*
788 Qt4 is horrible slow, when painting primitives,
789 with coordinates far outside the visible area.
790 We need to clip.
791 */
792
793 const QVector< QwtInterval > angles =
794 QwtClipper::clipCircle( canvasRect, pole, radius );
795
796 for ( int j = 0; j < angles.size(); j++ )
797 {
798 const QwtInterval intv = angles[j];
799
800 if ( intv.minValue() == 0 && intv.maxValue() == 2 * M_PI )
801 {
802 QwtPainter::drawEllipse( painter, outerRect );
803 }
804 else
805 {
806 const double from = qwtDegrees( intv.minValue() );
807 const double to = qwtDegrees( intv.maxValue() );
808
809 double span = to - from;
810 if ( span < 0.0 )
811 span += 360.0;
812
813 painter->drawArc( outerRect,
814 qRound( from * 16 ), qRound( span * 16 ) );
815 }
816 }
817 }
818 else
819 {
820 QwtPainter::drawEllipse( painter, outerRect );
821 }
822 }
823 }
824}
825
826/*!
827 Paint an axis
828
829 \param painter Painter
830 \param axisId Axis id (QwtPolar::Axis)
831 */
832void QwtPolarGrid::drawAxis( QPainter* painter, int axisId ) const
833{
834 if ( axisId < 0 || axisId >= QwtPolar::AxesCount )
835 return;
836
837 AxisData& axis = m_data->axisData[axisId];
838
839 painter->setPen( axis.pen );
840 painter->setFont( axis.font );
841
842 QPalette pal;
843 pal.setColor( QPalette::WindowText, axis.pen.color() );
844 pal.setColor( QPalette::Text, axis.pen.color() );
845
846 axis.scaleDraw->draw( painter, pal );
847}
848
849/*!
850 Update the axis scale draw geometries
851
852 \param azimuthMap Maps azimuth values to values related to 0.0, M_2PI
853 \param radialMap Maps radius values into painter coordinates.
854 \param pole Position of the pole in painter coordinates
855 \param radius Radius of the complete plot area in painter coordinates
856
857 \sa updateScaleDiv()
858 */
859void QwtPolarGrid::updateScaleDraws(
860 const QwtScaleMap& azimuthMap, const QwtScaleMap& radialMap,
861 const QPointF& pole, double radius ) const
862{
863 const QPoint p = pole.toPoint();
864
865 const QwtInterval interval =
866 m_data->gridData[QwtPolar::ScaleRadius].scaleDiv.interval();
867
868 const int min = radialMap.transform( interval.minValue() );
869 const int max = radialMap.transform( interval.maxValue() );
870 const int l = max - min;
871
872 for ( int axisId = 0; axisId < QwtPolar::AxesCount; axisId++ )
873 {
874 AxisData& axis = m_data->axisData[axisId];
875
876 if ( axisId == QwtPolar::AxisAzimuth )
877 {
878 QwtRoundScaleDraw* scaleDraw =
879 static_cast< QwtRoundScaleDraw* >( axis.scaleDraw );
880
881 scaleDraw->setRadius( qRound( radius ) );
882 scaleDraw->moveCenter( p );
883
884 double from = ::fmod( 90.0 - qwtDegrees( azimuthMap.p1() ), 360.0 );
885 if ( from < 0.0 )
886 from += 360.0;
887
888 scaleDraw->setAngleRange( from, from - 360.0 );
889
890 const QwtTransform* transform = azimuthMap.transformation();
891 if ( transform )
892 scaleDraw->setTransformation( transform->copy() );
893 else
894 scaleDraw->setTransformation( NULL );
895 }
896 else
897 {
898 QwtScaleDraw* scaleDraw =
899 static_cast< QwtScaleDraw* >( axis.scaleDraw );
900
901 switch( axisId )
902 {
903 case QwtPolar::AxisLeft:
904 {
905 scaleDraw->move( p.x() - min, p.y() );
906 scaleDraw->setLength( -l );
907 break;
908 }
909 case QwtPolar::AxisRight:
910 {
911 scaleDraw->move( p.x() + min, p.y() );
912 scaleDraw->setLength( l );
913 break;
914 }
915 case QwtPolar::AxisTop:
916 {
917 scaleDraw->move( p.x(), p.y() - max );
918 scaleDraw->setLength( l );
919 break;
920 }
921 case QwtPolar::AxisBottom:
922 {
923 scaleDraw->move( p.x(), p.y() + max );
924 scaleDraw->setLength( -l );
925 break;
926 }
927 }
928 const QwtTransform* transform = radialMap.transformation();
929 if ( transform )
930 scaleDraw->setTransformation( transform->copy() );
931 else
932 scaleDraw->setTransformation( NULL );
933 }
934 }
935}
936
937/*!
938 \brief Update the item to changes of the axes scale division
939
940 If AutoScaling is enabled the radial scale is calculated
941 from the interval, otherwise the scales are adopted to
942 the plot scales.
943
944 \param azimuthScaleDiv Scale division of the azimuth-scale
945 \param radialScaleDiv Scale division of the radius-axis
946 \param interval The interval of the radius-axis, that is
947 visible on the canvas
948
949 \sa QwtPolarPlot::setGridAttributes()
950 */
951
952void QwtPolarGrid::updateScaleDiv( const QwtScaleDiv& azimuthScaleDiv,
953 const QwtScaleDiv& radialScaleDiv, const QwtInterval& interval )
954{
955 GridData& radialGrid = m_data->gridData[QwtPolar::Radius];
956
957 const QwtPolarPlot* plt = plot();
958 if ( plt && testGridAttribute( AutoScaling ) )
959 {
960 const QwtScaleEngine* se = plt->scaleEngine( QwtPolar::Radius );
961 radialGrid.scaleDiv = se->divideScale(
962 interval.minValue(), interval.maxValue(),
963 plt->scaleMaxMajor( QwtPolar::Radius ),
964 plt->scaleMaxMinor( QwtPolar::Radius ), 0 );
965 }
966 else
967 {
968 if ( radialGrid.scaleDiv != radialScaleDiv )
969 radialGrid.scaleDiv = radialScaleDiv;
970 }
971
972 GridData& azimuthGrid = m_data->gridData[QwtPolar::Azimuth];
973 if ( azimuthGrid.scaleDiv != azimuthScaleDiv )
974 {
975 azimuthGrid.scaleDiv = azimuthScaleDiv;
976 }
977
978 bool hasOrigin = false;
979 for ( int axisId = 0; axisId < QwtPolar::AxesCount; axisId++ )
980 {
981 AxisData& axis = m_data->axisData[axisId];
982 if ( axis.isVisible && axis.scaleDraw )
983 {
984 if ( axisId == QwtPolar::AxisAzimuth )
985 {
986 axis.scaleDraw->setScaleDiv( azimuthGrid.scaleDiv );
987 if ( testDisplayFlag( SmartScaleDraw ) )
988 {
989 axis.scaleDraw->enableComponent(
990 QwtAbstractScaleDraw::Ticks, !azimuthGrid.isVisible );
991 }
992 }
993 else
994 {
995 QwtScaleDiv sd = radialGrid.scaleDiv;
996
997 QList< double > ticks = sd.ticks( QwtScaleDiv::MajorTick );
998
999 if ( testDisplayFlag( SmartOriginLabel ) )
1000 {
1001 bool skipOrigin = hasOrigin;
1002 if ( !skipOrigin )
1003 {
1004 if ( axisId == QwtPolar::AxisLeft
1005 || axisId == QwtPolar::AxisRight )
1006 {
1007 if ( m_data->axisData[QwtPolar::AxisBottom].isVisible )
1008 skipOrigin = true;
1009 }
1010 else
1011 {
1012 if ( m_data->axisData[QwtPolar::AxisLeft].isVisible )
1013 skipOrigin = true;
1014 }
1015 }
1016 if ( ticks.size() > 0 && ticks.first() == sd.lowerBound() )
1017 {
1018 if ( skipOrigin )
1019 ticks.removeFirst();
1020 else
1021 hasOrigin = true;
1022 }
1023 }
1024
1025 if ( testDisplayFlag( HideMaxRadiusLabel ) )
1026 {
1027 if ( ticks.size() > 0 && ticks.last() == sd.upperBound() )
1028 ticks.removeLast();
1029 }
1030
1031 sd.setTicks( QwtScaleDiv::MajorTick, ticks );
1032 axis.scaleDraw->setScaleDiv( sd );
1033
1034 if ( testDisplayFlag( SmartScaleDraw ) )
1035 {
1036 axis.scaleDraw->enableComponent(
1037 QwtAbstractScaleDraw::Ticks, !radialGrid.isVisible );
1038 }
1039
1040 }
1041 }
1042 }
1043}
1044
1045/*!
1046 \return Number of pixels, that are necessary to paint the azimuth scale
1047 \sa QwtRoundScaleDraw::extent()
1048 */
1049int QwtPolarGrid::marginHint() const
1050{
1051 const AxisData& axis = m_data->axisData[QwtPolar::AxisAzimuth];
1052 if ( axis.isVisible )
1053 {
1054 const int extent = axis.scaleDraw->extent( axis.font );
1055 return extent;
1056 }
1057
1058 return 0;
1059}
1060
1061/*!
1062 Returns the scale draw of a specified axis
1063
1064 \param axisId axis index ( QwtPolar::AxisLeft <= axisId <= QwtPolar::AxisBottom)
1065 \return specified scaleDraw for axis, or NULL if axis is invalid.
1066 \sa azimuthScaleDraw()
1067 */
1068const QwtScaleDraw* QwtPolarGrid::scaleDraw( int axisId ) const
1069{
1070 if ( axisId >= QwtPolar::AxisLeft && axisId <= QwtPolar::AxisBottom )
1071 return static_cast< QwtScaleDraw* >( m_data->axisData[axisId].scaleDraw );
1072
1073 return NULL;
1074}
1075
1076/*!
1077 Returns the scale draw of a specified axis
1078
1079 \param axisId axis index ( QwtPolar::AxisLeft <= axisId <= QwtPolar::AxisBottom)
1080 \return specified scaleDraw for axis, or NULL if axis is invalid.
1081 \sa setScaleDraw(), azimuthScaleDraw()
1082 */
1083QwtScaleDraw* QwtPolarGrid::scaleDraw( int axisId )
1084{
1085 if ( axisId >= QwtPolar::AxisLeft && axisId <= QwtPolar::AxisBottom )
1086 return static_cast< QwtScaleDraw* >( m_data->axisData[axisId].scaleDraw );
1087
1088 return NULL;
1089}
1090
1091/*!
1092 \brief Set a scale draw
1093
1094 \param axisId axis index ( QwtPolar::AxisLeft <= axisId <= QwtPolar::AxisBottom)
1095 \param scaleDraw object responsible for drawing scales.
1096
1097 \sa scaleDraw(), setAzimuthScaleDraw()
1098 */
1099void QwtPolarGrid::setScaleDraw( int axisId, QwtScaleDraw* scaleDraw )
1100{
1101 if ( axisId < QwtPolar::AxisLeft || axisId > QwtPolar::AxisBottom )
1102 return;
1103
1104 AxisData& axisData = m_data->axisData[axisId];
1105 if ( axisData.scaleDraw != scaleDraw )
1106 {
1107 delete axisData.scaleDraw;
1108 axisData.scaleDraw = scaleDraw;
1109 itemChanged();
1110 }
1111}
1112
1113/*!
1114 \return Scale draw for the azimuth scale
1115 \sa setAzimuthScaleDraw(), scaleDraw()
1116 */
1117const QwtRoundScaleDraw* QwtPolarGrid::azimuthScaleDraw() const
1118{
1119 return static_cast< QwtRoundScaleDraw* >(
1120 m_data->axisData[QwtPolar::AxisAzimuth].scaleDraw );
1121}
1122
1123/*!
1124 \return Scale draw for the azimuth scale
1125 \sa setAzimuthScaleDraw(), scaleDraw()
1126 */
1127QwtRoundScaleDraw* QwtPolarGrid::azimuthScaleDraw()
1128{
1129 return static_cast< QwtRoundScaleDraw* >(
1130 m_data->axisData[QwtPolar::AxisAzimuth].scaleDraw );
1131}
1132
1133/*!
1134 \brief Set a scale draw for the azimuth scale
1135
1136 \param scaleDraw object responsible for drawing scales.
1137 \sa azimuthScaleDraw(), setScaleDraw()
1138 */
1139void QwtPolarGrid::setAzimuthScaleDraw( QwtRoundScaleDraw* scaleDraw )
1140{
1141 AxisData& axisData = m_data->axisData[QwtPolar::AxisAzimuth];
1142 if ( axisData.scaleDraw != scaleDraw )
1143 {
1144 delete axisData.scaleDraw;
1145 axisData.scaleDraw = scaleDraw;
1146 itemChanged();
1147 }
1148}
Note: See TracBrowser for help on using the repository browser.