123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403 |
- /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
- * Qwt Widget Library
- * Copyright (C) 1997 Josef Wilgen
- * Copyright (C) 2002 Uwe Rathmann
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the Qwt License, Version 1.0
- *****************************************************************************/
- #include "qwt_abstract_scale_draw.h"
- #include "qwt_math.h"
- #include "qwt_text.h"
- #include "qwt_painter.h"
- #include "qwt_scale_map.h"
- #include <qpainter.h>
- #include <qpalette.h>
- #include <qmap.h>
- #include <qlocale.h>
- class QwtAbstractScaleDraw::PrivateData
- {
- public:
- PrivateData():
- components( Backbone | Ticks | Labels ),
- spacing( 4.0 ),
- penWidth( 0 ),
- minExtent( 0.0 )
- {
- tickLength[QwtScaleDiv::MinorTick] = 4.0;
- tickLength[QwtScaleDiv::MediumTick] = 6.0;
- tickLength[QwtScaleDiv::MajorTick] = 8.0;
- }
- int components;
- QwtScaleMap map;
- QwtScaleDiv scldiv;
- double spacing;
- double tickLength[QwtScaleDiv::NTickTypes];
- int penWidth;
- double minExtent;
- QMap<double, QwtText> labelCache;
- };
- /*!
- \brief Constructor
- The range of the scale is initialized to [0, 100],
- The spacing (distance between ticks and labels) is
- set to 4, the tick lengths are set to 4,6 and 8 pixels
- */
- QwtAbstractScaleDraw::QwtAbstractScaleDraw()
- {
- d_data = new QwtAbstractScaleDraw::PrivateData;
- }
- //! Destructor
- QwtAbstractScaleDraw::~QwtAbstractScaleDraw()
- {
- delete d_data;
- }
- /*!
- En/Disable a component of the scale
- \param component Scale component
- \param enable On/Off
- \sa hasComponent()
- */
- void QwtAbstractScaleDraw::enableComponent(
- ScaleComponent component, bool enable )
- {
- if ( enable )
- d_data->components |= component;
- else
- d_data->components &= ~component;
- }
- /*!
- Check if a component is enabled
- \sa enableComponent()
- */
- bool QwtAbstractScaleDraw::hasComponent( ScaleComponent component ) const
- {
- return ( d_data->components & component );
- }
- /*!
- Change the scale division
- \param sd New scale division
- */
- void QwtAbstractScaleDraw::setScaleDiv( const QwtScaleDiv &sd )
- {
- d_data->scldiv = sd;
- d_data->map.setScaleInterval( sd.lowerBound(), sd.upperBound() );
- d_data->labelCache.clear();
- }
- /*!
- Change the transformation of the scale
- \param transformation New scale transformation
- */
- void QwtAbstractScaleDraw::setTransformation(
- QwtScaleTransformation *transformation )
- {
- d_data->map.setTransformation( transformation );
- }
- //! \return Map how to translate between scale and pixel values
- const QwtScaleMap &QwtAbstractScaleDraw::map() const
- {
- return d_data->map;
- }
- //! \return Map how to translate between scale and pixel values
- QwtScaleMap &QwtAbstractScaleDraw::scaleMap()
- {
- return d_data->map;
- }
- //! \return scale division
- const QwtScaleDiv& QwtAbstractScaleDraw::scaleDiv() const
- {
- return d_data->scldiv;
- }
- /*!
- \brief Specify the width of the scale pen
- \param width Pen width
- \sa penWidth()
- */
- void QwtAbstractScaleDraw::setPenWidth( int width )
- {
- if ( width < 0 )
- width = 0;
- if ( width != d_data->penWidth )
- d_data->penWidth = width;
- }
- /*!
- \return Scale pen width
- \sa setPenWidth()
- */
- int QwtAbstractScaleDraw::penWidth() const
- {
- return d_data->penWidth;
- }
- /*!
- \brief Draw the scale
- \param painter The painter
- \param palette Palette, text color is used for the labels,
- foreground color for ticks and backbone
- */
- void QwtAbstractScaleDraw::draw( QPainter *painter,
- const QPalette& palette ) const
- {
- painter->save();
- QPen pen = painter->pen();
- pen.setWidth( d_data->penWidth );
- pen.setCosmetic( false );
- painter->setPen( pen );
- if ( hasComponent( QwtAbstractScaleDraw::Labels ) )
- {
- painter->save();
- painter->setPen( palette.color( QPalette::Text ) ); // ignore pen style
- const QList<double> &majorTicks =
- d_data->scldiv.ticks( QwtScaleDiv::MajorTick );
- for ( int i = 0; i < ( int )majorTicks.count(); i++ )
- {
- const double v = majorTicks[i];
- if ( d_data->scldiv.contains( v ) )
- drawLabel( painter, majorTicks[i] );
- }
- painter->restore();
- }
- if ( hasComponent( QwtAbstractScaleDraw::Ticks ) )
- {
- painter->save();
- QPen pen = painter->pen();
- pen.setColor( palette.color( QPalette::WindowText ) );
- pen.setCapStyle( Qt::FlatCap );
- painter->setPen( pen );
- for ( int tickType = QwtScaleDiv::MinorTick;
- tickType < QwtScaleDiv::NTickTypes; tickType++ )
- {
- const QList<double> &ticks = d_data->scldiv.ticks( tickType );
- for ( int i = 0; i < ( int )ticks.count(); i++ )
- {
- const double v = ticks[i];
- if ( d_data->scldiv.contains( v ) )
- drawTick( painter, v, d_data->tickLength[tickType] );
- }
- }
- painter->restore();
- }
- if ( hasComponent( QwtAbstractScaleDraw::Backbone ) )
- {
- painter->save();
- QPen pen = painter->pen();
- pen.setColor( palette.color( QPalette::WindowText ) );
- pen.setCapStyle( Qt::FlatCap );
- painter->setPen( pen );
- drawBackbone( painter );
- painter->restore();
- }
- painter->restore();
- }
- /*!
- \brief Set the spacing between tick and labels
- The spacing is the distance between ticks and labels.
- The default spacing is 4 pixels.
- \param spacing Spacing
- \sa spacing()
- */
- void QwtAbstractScaleDraw::setSpacing( double spacing )
- {
- if ( spacing < 0 )
- spacing = 0;
- d_data->spacing = spacing;
- }
- /*!
- \brief Get the spacing
- The spacing is the distance between ticks and labels.
- The default spacing is 4 pixels.
- \sa setSpacing()
- */
- double QwtAbstractScaleDraw::spacing() const
- {
- return d_data->spacing;
- }
- /*!
- \brief Set a minimum for the extent
- The extent is calculated from the coomponents of the
- scale draw. In situations, where the labels are
- changing and the layout depends on the extent (f.e scrolling
- a scale), setting an upper limit as minimum extent will
- avoid jumps of the layout.
- \param minExtent Minimum extent
- \sa extent(), minimumExtent()
- */
- void QwtAbstractScaleDraw::setMinimumExtent( double minExtent )
- {
- if ( minExtent < 0.0 )
- minExtent = 0.0;
- d_data->minExtent = minExtent;
- }
- /*!
- Get the minimum extent
- \sa extent(), setMinimumExtent()
- */
- double QwtAbstractScaleDraw::minimumExtent() const
- {
- return d_data->minExtent;
- }
- /*!
- Set the length of the ticks
- \param tickType Tick type
- \param length New length
- \warning the length is limited to [0..1000]
- */
- void QwtAbstractScaleDraw::setTickLength(
- QwtScaleDiv::TickType tickType, double length )
- {
- if ( tickType < QwtScaleDiv::MinorTick ||
- tickType > QwtScaleDiv::MajorTick )
- {
- return;
- }
- if ( length < 0.0 )
- length = 0.0;
- const double maxTickLen = 1000.0;
- if ( length > maxTickLen )
- length = maxTickLen;
- d_data->tickLength[tickType] = length;
- }
- /*!
- Return the length of the ticks
- \sa setTickLength(), majTickLength()
- */
- double QwtAbstractScaleDraw::tickLength( QwtScaleDiv::TickType tickType ) const
- {
- if ( tickType < QwtScaleDiv::MinorTick ||
- tickType > QwtScaleDiv::MajorTick )
- {
- return 0;
- }
- return d_data->tickLength[tickType];
- }
- /*!
- The same as QwtAbstractScaleDraw::tickLength(QwtScaleDiv::MajorTick).
- */
- double QwtAbstractScaleDraw::majTickLength() const
- {
- return d_data->tickLength[QwtScaleDiv::MajorTick];
- }
- /*!
- \brief Convert a value into its representing label
- The value is converted to a plain text using
- QLocale::system().toString(value).
- This method is often overloaded by applications to have individual
- labels.
- \param value Value
- \return Label string.
- */
- QwtText QwtAbstractScaleDraw::label( double value ) const
- {
- return QLocale::system().toString( value );
- }
- /*!
- \brief Convert a value into its representing label and cache it.
- The conversion between value and label is called very often
- in the layout and painting code. Unfortunately the
- calculation of the label sizes might be slow (really slow
- for rich text in Qt4), so it's necessary to cache the labels.
- \param font Font
- \param value Value
- \return Tick label
- */
- const QwtText &QwtAbstractScaleDraw::tickLabel(
- const QFont &font, double value ) const
- {
- QMap<double, QwtText>::const_iterator it = d_data->labelCache.find( value );
- if ( it == d_data->labelCache.end() )
- {
- QwtText lbl = label( value );
- lbl.setRenderFlags( 0 );
- lbl.setLayoutAttribute( QwtText::MinimumLayout );
- ( void )lbl.textSize( font ); // initialize the internal cache
- it = d_data->labelCache.insert( value, lbl );
- }
- return ( *it );
- }
- /*!
- Invalidate the cache used by QwtAbstractScaleDraw::tickLabel
- The cache is invalidated, when a new QwtScaleDiv is set. If
- the labels need to be changed. while the same QwtScaleDiv is set,
- QwtAbstractScaleDraw::invalidateCache needs to be called manually.
- */
- void QwtAbstractScaleDraw::invalidateCache()
- {
- d_data->labelCache.clear();
- }
|