Newer
Older
/* -*- 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_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():
spacing( 4.0 ),
penWidth( 0 ),
minExtent( 0.0 )
{
components = QwtAbstractScaleDraw::Backbone
| QwtAbstractScaleDraw::Ticks
| QwtAbstractScaleDraw::Labels;
tickLength[QwtScaleDiv::MinorTick] = 4.0;
tickLength[QwtScaleDiv::MediumTick] = 6.0;
tickLength[QwtScaleDiv::MajorTick] = 8.0;
double spacing;
double tickLength[QwtScaleDiv::NTickTypes];
int penWidth;
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
{
if ( enable )
d_data->components |= component;
else
d_data->components &= ~component;
}
/*!
Check if a component is enabled
\param component Component type
\return true, when component is enabled
\sa enableComponent()
bool QwtAbstractScaleDraw::hasComponent( ScaleComponent component ) const
void QwtAbstractScaleDraw::setScaleDiv( const QwtScaleDiv &scaleDiv )
d_data->scaleDiv = scaleDiv;
d_data->map.setScaleInterval( scaleDiv.lowerBound(), scaleDiv.upperBound() );
d_data->labelCache.clear();
}
/*!
Change the transformation of the scale
\param transformation New scale transformation
*/
void QwtAbstractScaleDraw::setTransformation(
}
//! \return Map how to translate between scale and pixel values
{
return d_data->map;
}
//! \return Map how to translate between scale and pixel values
QwtScaleMap &QwtAbstractScaleDraw::scaleMap()
//! \return scale division
const QwtScaleDiv& QwtAbstractScaleDraw::scaleDiv() const
{
\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;
}
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,
void QwtAbstractScaleDraw::draw( QPainter *painter,
const QPalette& palette ) const
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->scaleDiv.ticks( QwtScaleDiv::MajorTick );
if ( d_data->scaleDiv.contains( v ) )
drawLabel( painter, v );
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->scaleDiv.ticks( tickType );
for ( int i = 0; i < ticks.count(); i++ )
{
if ( d_data->scaleDiv.contains( v ) )
drawTick( painter, v, d_data->tickLength[tickType] );
pen.setColor( palette.color( QPalette::WindowText ) );
pen.setCapStyle( Qt::FlatCap );
painter->setPen( pen );
}
/*!
\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
{
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.
{
return d_data->spacing;
}
/*!
\brief Set a minimum for the extent
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 )
d_data->minExtent = minExtent;
}
/*!
Get the minimum extent
{
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(
if ( tickType < QwtScaleDiv::MinorTick ||
\return Length of the ticks
\sa setTickLength(), maxTickLength()
double QwtAbstractScaleDraw::tickLength( QwtScaleDiv::TickType tickType ) const
if ( tickType < QwtScaleDiv::MinorTick ||
return 0;
}
return d_data->tickLength[tickType];
}
/*!
\return Length of the longest tick
Useful for layout calculations
\sa tickLength(), setTickLength()
double length = 0.0;
for ( int i = 0; i < QwtScaleDiv::NTickTypes; i++ )
length = qMax( length, d_data->tickLength[i] );
return length;
\brief Convert a value into its representing label
The value is converted to a plain text using
This method is often overloaded by applications to have individual
labels.
\param value Value
\return Label string.
*/
}
/*!
\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(
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
The cache is invalidated, when a new QwtScaleDiv is set. If
the labels need to be changed. while the same QwtScaleDiv is set,