source: ntrip/trunk/BNC/qwt/qwt_plot_scaleitem.cpp@ 7722

Last change on this file since 7722 was 4271, checked in by mervart, 12 years ago
File size: 10.5 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_scaleitem.h"
11#include "qwt_plot.h"
12#include "qwt_plot_canvas.h"
13#include "qwt_scale_map.h"
14#include "qwt_interval.h"
15#include <qpalette.h>
16#include <qpainter.h>
17
18class QwtPlotScaleItem::PrivateData
19{
20public:
21 PrivateData():
22 position( 0.0 ),
23 borderDistance( -1 ),
24 scaleDivFromAxis( true ),
25 scaleDraw( new QwtScaleDraw() )
26 {
27 }
28
29 ~PrivateData()
30 {
31 delete scaleDraw;
32 }
33
34 void updateBorders( const QRectF &,
35 const QwtScaleMap &, const QwtScaleMap & );
36
37 QPalette palette;
38 QFont font;
39 double position;
40 int borderDistance;
41 bool scaleDivFromAxis;
42 QwtScaleDraw *scaleDraw;
43 QRectF canvasRectCache;
44};
45
46void QwtPlotScaleItem::PrivateData::updateBorders( const QRectF &canvasRect,
47 const QwtScaleMap &xMap, const QwtScaleMap &yMap )
48{
49 canvasRectCache = canvasRect;
50
51 QwtInterval interval;
52 if ( scaleDraw->orientation() == Qt::Horizontal )
53 {
54 interval.setMinValue( xMap.invTransform( canvasRect.left() ) );
55 interval.setMaxValue( xMap.invTransform( canvasRect.right() - 1 ) );
56 }
57 else
58 {
59 interval.setMinValue( yMap.invTransform( canvasRect.bottom() - 1 ) );
60 interval.setMaxValue( yMap.invTransform( canvasRect.top() ) );
61 }
62
63 QwtScaleDiv scaleDiv = scaleDraw->scaleDiv();
64 scaleDiv.setInterval( interval );
65 scaleDraw->setScaleDiv( scaleDiv );
66}
67/*!
68 \brief Constructor for scale item at the position pos.
69
70 \param alignment In case of QwtScaleDraw::BottomScale or QwtScaleDraw::TopScale
71 the scale item is corresponding to the xAxis(),
72 otherwise it corresponds to the yAxis().
73
74 \param pos x or y position, depending on the corresponding axis.
75
76 \sa setPosition(), setAlignment()
77*/
78QwtPlotScaleItem::QwtPlotScaleItem(
79 QwtScaleDraw::Alignment alignment, const double pos ):
80 QwtPlotItem( QwtText( "Scale" ) )
81{
82 d_data = new PrivateData;
83 d_data->position = pos;
84 d_data->scaleDraw->setAlignment( alignment );
85
86 setZ( 11.0 );
87}
88
89//! Destructor
90QwtPlotScaleItem::~QwtPlotScaleItem()
91{
92 delete d_data;
93}
94
95//! \return QwtPlotItem::Rtti_PlotScale
96int QwtPlotScaleItem::rtti() const
97{
98 return QwtPlotItem::Rtti_PlotScale;
99}
100
101/*!
102 \brief Assign a scale division
103
104 When assigning a scaleDiv the scale division won't be synchronized
105 with the corresponding axis anymore.
106
107 \param scaleDiv Scale division
108 \sa scaleDiv(), setScaleDivFromAxis(), isScaleDivFromAxis()
109*/
110void QwtPlotScaleItem::setScaleDiv( const QwtScaleDiv& scaleDiv )
111{
112 d_data->scaleDivFromAxis = false;
113 d_data->scaleDraw->setScaleDiv( scaleDiv );
114}
115
116//! \return Scale division
117const QwtScaleDiv& QwtPlotScaleItem::scaleDiv() const
118{
119 return d_data->scaleDraw->scaleDiv();
120}
121
122/*!
123 Enable/Disable the synchronization of the scale division with
124 the corresponding axis.
125
126 \param on true/false
127 \sa isScaleDivFromAxis()
128*/
129void QwtPlotScaleItem::setScaleDivFromAxis( bool on )
130{
131 if ( on != d_data->scaleDivFromAxis )
132 {
133 d_data->scaleDivFromAxis = on;
134 if ( on )
135 {
136 const QwtPlot *plt = plot();
137 if ( plt )
138 {
139 updateScaleDiv( *plt->axisScaleDiv( xAxis() ),
140 *plt->axisScaleDiv( yAxis() ) );
141 itemChanged();
142 }
143 }
144 }
145}
146
147/*!
148 \return True, if the synchronization of the scale division with
149 the corresponding axis is enabled.
150 \sa setScaleDiv(), setScaleDivFromAxis()
151*/
152bool QwtPlotScaleItem::isScaleDivFromAxis() const
153{
154 return d_data->scaleDivFromAxis;
155}
156
157/*!
158 Set the palette
159 \sa QwtAbstractScaleDraw::draw(), palette()
160*/
161void QwtPlotScaleItem::setPalette( const QPalette &palette )
162{
163 if ( palette != d_data->palette )
164 {
165 d_data->palette = palette;
166 itemChanged();
167 }
168}
169
170/*!
171 \return palette
172 \sa setPalette()
173*/
174QPalette QwtPlotScaleItem::palette() const
175{
176 return d_data->palette;
177}
178
179/*!
180 Change the tick label font
181 \sa font()
182*/
183void QwtPlotScaleItem::setFont( const QFont &font )
184{
185 if ( font != d_data->font )
186 {
187 d_data->font = font;
188 itemChanged();
189 }
190}
191
192/*!
193 \return tick label font
194 \sa setFont()
195*/
196QFont QwtPlotScaleItem::font() const
197{
198 return d_data->font;
199}
200
201/*!
202 \brief Set a scale draw
203
204 \param scaleDraw object responsible for drawing scales.
205
206 The main use case for replacing the default QwtScaleDraw is
207 to overload QwtAbstractScaleDraw::label, to replace or swallow
208 tick labels.
209
210 \sa scaleDraw()
211*/
212void QwtPlotScaleItem::setScaleDraw( QwtScaleDraw *scaleDraw )
213{
214 if ( scaleDraw == NULL )
215 return;
216
217 if ( scaleDraw != d_data->scaleDraw )
218 delete d_data->scaleDraw;
219
220 d_data->scaleDraw = scaleDraw;
221
222 const QwtPlot *plt = plot();
223 if ( plt )
224 {
225 updateScaleDiv( *plt->axisScaleDiv( xAxis() ),
226 *plt->axisScaleDiv( yAxis() ) );
227 }
228
229 itemChanged();
230}
231
232/*!
233 \return Scale draw
234 \sa setScaleDraw()
235*/
236const QwtScaleDraw *QwtPlotScaleItem::scaleDraw() const
237{
238 return d_data->scaleDraw;
239}
240
241/*!
242 \return Scale draw
243 \sa setScaleDraw()
244*/
245QwtScaleDraw *QwtPlotScaleItem::scaleDraw()
246{
247 return d_data->scaleDraw;
248}
249
250/*!
251 Change the position of the scale
252
253 The position is interpreted as y value for horizontal axes
254 and as x value for vertical axes.
255
256 The border distance is set to -1.
257
258 \param pos New position
259 \sa position(), setAlignment()
260*/
261void QwtPlotScaleItem::setPosition( double pos )
262{
263 if ( d_data->position != pos )
264 {
265 d_data->position = pos;
266 d_data->borderDistance = -1;
267 itemChanged();
268 }
269}
270
271/*!
272 \return Position of the scale
273 \sa setPosition(), setAlignment()
274*/
275double QwtPlotScaleItem::position() const
276{
277 return d_data->position;
278}
279
280/*!
281 \brief Align the scale to the canvas
282
283 If distance is >= 0 the scale will be aligned to a
284 border of the contents rect of the canvas. If
285 alignment() is QwtScaleDraw::LeftScale, the scale will
286 be aligned to the right border, if it is QwtScaleDraw::TopScale
287 it will be aligned to the bottom (and vice versa),
288
289 If distance is < 0 the scale will be at the position().
290
291 \param distance Number of pixels between the canvas border and the
292 backbone of the scale.
293
294 \sa setPosition(), borderDistance()
295*/
296void QwtPlotScaleItem::setBorderDistance( int distance )
297{
298 if ( distance < 0 )
299 distance = -1;
300
301 if ( distance != d_data->borderDistance )
302 {
303 d_data->borderDistance = distance;
304 itemChanged();
305 }
306}
307
308/*!
309 \return Distance from a canvas border
310 \sa setBorderDistance(), setPosition()
311*/
312int QwtPlotScaleItem::borderDistance() const
313{
314 return d_data->borderDistance;
315}
316
317/*!
318 Change the alignment of the scale
319
320 The alignment sets the orientation of the scale and the position of
321 the ticks:
322
323 - QwtScaleDraw::BottomScale: horizontal, ticks below
324 - QwtScaleDraw::TopScale: horizontal, ticks above
325 - QwtScaleDraw::LeftScale: vertical, ticks left
326 - QwtScaleDraw::RightScale: vertical, ticks right
327
328 For horizontal scales the position corresponds to QwtPlotItem::yAxis(),
329 otherwise to QwtPlotItem::xAxis().
330
331 \sa scaleDraw(), QwtScaleDraw::alignment(), setPosition()
332*/
333void QwtPlotScaleItem::setAlignment( QwtScaleDraw::Alignment alignment )
334{
335 QwtScaleDraw *sd = d_data->scaleDraw;
336 if ( sd->alignment() != alignment )
337 {
338 sd->setAlignment( alignment );
339 itemChanged();
340 }
341}
342
343/*!
344 \brief Draw the scale
345*/
346void QwtPlotScaleItem::draw( QPainter *painter,
347 const QwtScaleMap &xMap, const QwtScaleMap &yMap,
348 const QRectF &canvasRect ) const
349{
350 if ( d_data->scaleDivFromAxis )
351 {
352 if ( canvasRect != d_data->canvasRectCache )
353 d_data->updateBorders( canvasRect, xMap, yMap );
354 }
355
356 QPen pen = painter->pen();
357 pen.setStyle( Qt::SolidLine );
358 painter->setPen( pen );
359
360 QwtScaleDraw *sd = d_data->scaleDraw;
361 if ( sd->orientation() == Qt::Horizontal )
362 {
363 double y;
364 if ( d_data->borderDistance >= 0 )
365 {
366 if ( sd->alignment() == QwtScaleDraw::BottomScale )
367 y = canvasRect.top() + d_data->borderDistance;
368 else
369 {
370 y = canvasRect.bottom() - d_data->borderDistance;
371 }
372
373 }
374 else
375 {
376 y = yMap.transform( d_data->position );
377 }
378
379 if ( y < canvasRect.top() || y > canvasRect.bottom() )
380 return;
381
382 sd->move( canvasRect.left(), y );
383 sd->setLength( canvasRect.width() - 1 );
384 sd->setTransformation( xMap.transformation()->copy() );
385 }
386 else // == Qt::Vertical
387 {
388 double x;
389 if ( d_data->borderDistance >= 0 )
390 {
391 if ( sd->alignment() == QwtScaleDraw::RightScale )
392 x = canvasRect.left() + d_data->borderDistance;
393 else
394 {
395 x = canvasRect.right() - d_data->borderDistance;
396 }
397 }
398 else
399 {
400 x = xMap.transform( d_data->position );
401 }
402 if ( x < canvasRect.left() || x > canvasRect.right() )
403 return;
404
405 sd->move( x, canvasRect.top() );
406 sd->setLength( canvasRect.height() - 1 );
407 sd->setTransformation( yMap.transformation()->copy() );
408 }
409
410 painter->setFont( d_data->font );
411
412 sd->draw( painter, d_data->palette );
413}
414
415/*!
416 \brief Update the item to changes of the axes scale division
417
418 In case of isScaleDivFromAxis(), the scale draw is synchronized
419 to the correspond axis.
420
421 \param xScaleDiv Scale division of the x-axis
422 \param yScaleDiv Scale division of the y-axis
423
424 \sa QwtPlot::updateAxes()
425*/
426
427void QwtPlotScaleItem::updateScaleDiv( const QwtScaleDiv& xScaleDiv,
428 const QwtScaleDiv& yScaleDiv )
429{
430 QwtScaleDraw *sd = d_data->scaleDraw;
431 if ( d_data->scaleDivFromAxis && sd )
432 {
433 sd->setScaleDiv(
434 sd->orientation() == Qt::Horizontal ? xScaleDiv : yScaleDiv );
435
436 const QwtPlot *plt = plot();
437 if ( plt != NULL )
438 {
439 d_data->updateBorders( plt->canvas()->contentsRect(),
440 plt->canvasMap( xAxis() ), plt->canvasMap( yAxis() ) );
441 }
442 }
443}
Note: See TracBrowser for help on using the repository browser.