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

Last change on this file since 8643 was 8127, checked in by stoecker, 8 years ago

update qwt and qwtpolar, many QT5 fixes (unfinished)

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