source: ntrip/trunk/GnssCenter/qwt/qwt_round_scale_draw.cpp@ 10460

Last change on this file since 10460 was 4839, checked in by mervart, 12 years ago
File size: 8.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_round_scale_draw.h"
11#include "qwt_painter.h"
12#include "qwt_scale_div.h"
13#include "qwt_scale_map.h"
14#include <qpen.h>
15#include <qpainter.h>
16#include <qfontmetrics.h>
17#include <qmath.h>
18
19class QwtRoundScaleDraw::PrivateData
20{
21public:
22 PrivateData():
23 center( 50, 50 ),
24 radius( 50 ),
25 startAngle( -135 * 16 ),
26 endAngle( 135 * 16 )
27 {
28 }
29
30 QPointF center;
31 double radius;
32
33 double startAngle;
34 double endAngle;
35};
36
37/*!
38 \brief Constructor
39
40 The range of the scale is initialized to [0, 100],
41 The center is set to (50, 50) with a radius of 50.
42 The angle range is set to [-135, 135].
43*/
44QwtRoundScaleDraw::QwtRoundScaleDraw()
45{
46 d_data = new QwtRoundScaleDraw::PrivateData;
47
48 setRadius( 50 );
49 scaleMap().setPaintInterval( d_data->startAngle, d_data->endAngle );
50}
51
52//! Destructor
53QwtRoundScaleDraw::~QwtRoundScaleDraw()
54{
55 delete d_data;
56}
57
58/*!
59 Change of radius the scale
60
61 Radius is the radius of the backbone without ticks and labels.
62
63 \param radius New Radius
64 \sa moveCenter()
65*/
66void QwtRoundScaleDraw::setRadius( int radius )
67{
68 d_data->radius = radius;
69}
70
71/*!
72 Get the radius
73
74 Radius is the radius of the backbone without ticks and labels.
75
76 \sa setRadius(), extent()
77*/
78int QwtRoundScaleDraw::radius() const
79{
80 return d_data->radius;
81}
82
83/*!
84 Move the center of the scale draw, leaving the radius unchanged
85
86 \param center New center
87 \sa setRadius()
88*/
89void QwtRoundScaleDraw::moveCenter( const QPointF &center )
90{
91 d_data->center = center;
92}
93
94//! Get the center of the scale
95QPointF QwtRoundScaleDraw::center() const
96{
97 return d_data->center;
98}
99
100/*!
101 \brief Adjust the baseline circle segment for round scales.
102
103 The baseline will be drawn from min(angle1,angle2) to max(angle1, angle2).
104 The default setting is [ -135, 135 ].
105 An angle of 0 degrees corresponds to the 12 o'clock position,
106 and positive angles count in a clockwise direction.
107 \param angle1
108 \param angle2 boundaries of the angle interval in degrees.
109 \warning <ul>
110 <li>The angle range is limited to [-360, 360] degrees. Angles exceeding
111 this range will be clipped.
112 <li>For angles more than 359 degrees above or below min(angle1, angle2),
113 scale marks will not be drawn.
114 <li>If you need a counterclockwise scale, use QwtScaleDiv::setRange
115 </ul>
116*/
117void QwtRoundScaleDraw::setAngleRange( double angle1, double angle2 )
118{
119 angle1 = qBound( -360.0, angle1, 360.0 );
120 angle2 = qBound( -360.0, angle2, 360.0 );
121
122 d_data->startAngle = angle1 * 16.0;
123 d_data->endAngle = angle2 * 16.0;
124
125 if ( d_data->startAngle == d_data->endAngle )
126 {
127 d_data->startAngle -= 1;
128 d_data->endAngle += 1;
129 }
130
131 scaleMap().setPaintInterval( d_data->startAngle, d_data->endAngle );
132}
133
134/*!
135 Draws the label for a major scale tick
136
137 \param painter Painter
138 \param value Value
139
140 \sa drawTick(), drawBackbone()
141*/
142void QwtRoundScaleDraw::drawLabel( QPainter *painter, double value ) const
143{
144 const QwtText label = tickLabel( painter->font(), value );
145 if ( label.isEmpty() )
146 return;
147
148 const double tval = scaleMap().transform( value );
149 if ( ( tval > d_data->startAngle + 359 * 16 )
150 || ( tval < d_data->startAngle - 359 * 16 ) )
151 {
152 return;
153 }
154
155 double radius = d_data->radius;
156 if ( hasComponent( QwtAbstractScaleDraw::Ticks ) ||
157 hasComponent( QwtAbstractScaleDraw::Backbone ) )
158 {
159 radius += spacing();
160 }
161
162 if ( hasComponent( QwtAbstractScaleDraw::Ticks ) )
163 radius += tickLength( QwtScaleDiv::MajorTick );
164
165 const QSizeF sz = label.textSize( painter->font() );
166 const double arc = tval / 16.0 / 360.0 * 2 * M_PI;
167
168 const double x = d_data->center.x() +
169 ( radius + sz.width() / 2.0 ) * qSin( arc );
170 const double y = d_data->center.y() -
171 ( radius + sz.height() / 2.0 ) * cos( arc );
172
173 const QRectF r( x - sz.width() / 2, y - sz.height() / 2,
174 sz.width(), sz.height() );
175 label.draw( painter, r );
176}
177
178/*!
179 Draw a tick
180
181 \param painter Painter
182 \param value Value of the tick
183 \param len Lenght of the tick
184
185 \sa drawBackbone(), drawLabel()
186*/
187void QwtRoundScaleDraw::drawTick( QPainter *painter, double value, double len ) const
188{
189 if ( len <= 0 )
190 return;
191
192 const double tval = scaleMap().transform( value );
193
194 const double cx = d_data->center.x();
195 const double cy = d_data->center.y();
196 const double radius = d_data->radius;
197
198 if ( ( tval <= d_data->startAngle + 359 * 16 )
199 || ( tval >= d_data->startAngle - 359 * 16 ) )
200 {
201 const double arc = double( tval ) / 16.0 * M_PI / 180.0;
202
203 const double sinArc = qSin( arc );
204 const double cosArc = qCos( arc );
205
206 const double x1 = cx + radius * sinArc;
207 const double x2 = cx + ( radius + len ) * sinArc;
208 const double y1 = cy - radius * cosArc;
209 const double y2 = cy - ( radius + len ) * cosArc;
210
211 QwtPainter::drawLine( painter, x1, y1, x2, y2 );
212 }
213}
214
215/*!
216 Draws the baseline of the scale
217 \param painter Painter
218
219 \sa drawTick(), drawLabel()
220*/
221void QwtRoundScaleDraw::drawBackbone( QPainter *painter ) const
222{
223 const double a1 = qMin( scaleMap().p1(), scaleMap().p2() ) - 90 * 16;
224 const double a2 = qMax( scaleMap().p1(), scaleMap().p2() ) - 90 * 16;
225
226 const double radius = d_data->radius;
227 const double x = d_data->center.x() - radius;
228 const double y = d_data->center.y() - radius;
229
230 painter->drawArc( x, y, 2 * radius, 2 * radius,
231 -a2, a2 - a1 + 1 ); // counterclockwise
232}
233
234/*!
235 Calculate the extent of the scale
236
237 The extent is the distance between the baseline to the outermost
238 pixel of the scale draw. radius() + extent() is an upper limit
239 for the radius of the bounding circle.
240
241 \param font Font used for painting the labels
242
243 \sa setMinimumExtent(), minimumExtent()
244 \warning The implemented algo is not too smart and
245 calculates only an upper limit, that might be a
246 few pixels too large
247*/
248double QwtRoundScaleDraw::extent( const QFont &font ) const
249{
250 double d = 0.0;
251
252 if ( hasComponent( QwtAbstractScaleDraw::Labels ) )
253 {
254 const QwtScaleDiv &sd = scaleDiv();
255 const QList<double> &ticks = sd.ticks( QwtScaleDiv::MajorTick );
256 for ( int i = 0; i < ticks.count(); i++ )
257 {
258 const double value = ticks[i];
259 if ( !sd.contains( value ) )
260 continue;
261
262 const QwtText label = tickLabel( font, value );
263 if ( label.isEmpty() )
264 continue;
265
266 const double tval = scaleMap().transform( value );
267 if ( ( tval < d_data->startAngle + 360 * 16 )
268 && ( tval > d_data->startAngle - 360 * 16 ) )
269 {
270 const double arc = tval / 16.0 / 360.0 * 2 * M_PI;
271
272 const QSizeF sz = label.textSize( font );
273 const double off = qMax( sz.width(), sz.height() );
274
275 double x = off * qSin( arc );
276 double y = off * qCos( arc );
277
278 const double dist = qSqrt( x * x + y * y );
279 if ( dist > d )
280 d = dist;
281 }
282 }
283 }
284
285 if ( hasComponent( QwtAbstractScaleDraw::Ticks ) )
286 {
287 d += maxTickLength();
288 }
289
290 if ( hasComponent( QwtAbstractScaleDraw::Backbone ) )
291 {
292 const double pw = qMax( 1, penWidth() ); // penwidth can be zero
293 d += pw;
294 }
295
296 if ( hasComponent( QwtAbstractScaleDraw::Labels ) &&
297 ( hasComponent( QwtAbstractScaleDraw::Ticks ) ||
298 hasComponent( QwtAbstractScaleDraw::Backbone ) ) )
299 {
300 d += spacing();
301 }
302
303 d = qMax( d, minimumExtent() );
304
305 return d;
306}
Note: See TracBrowser for help on using the repository browser.