qwt_abstract_scale_draw.cpp

00001 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
00002  * Qwt Widget Library
00003  * Copyright (C) 1997   Josef Wilgen
00004  * Copyright (C) 2002   Uwe Rathmann
00005  * 
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the Qwt License, Version 1.0
00008  *****************************************************************************/
00009 
00010 // vim: expandtab
00011 
00012 #include <qpainter.h>
00013 #include <qpalette.h>
00014 #include <qmap.h>
00015 #include <qlocale.h>
00016 #include "qwt_math.h"
00017 #include "qwt_text.h"
00018 #include "qwt_painter.h"
00019 #include "qwt_scale_map.h"
00020 #include "qwt_scale_draw.h"
00021 
00022 class QwtAbstractScaleDraw::PrivateData
00023 {
00024 public:
00025     PrivateData():
00026         components(Backbone | Ticks | Labels),
00027         spacing(4),
00028         minExtent(0)
00029     {
00030         tickLength[QwtScaleDiv::MinorTick] = 4;
00031         tickLength[QwtScaleDiv::MediumTick] = 6;
00032         tickLength[QwtScaleDiv::MajorTick] = 8;
00033     }
00034 
00035     int components;
00036     
00037     QwtScaleMap map;
00038     QwtScaleDiv scldiv;
00039         
00040     int spacing;
00041     int tickLength[QwtScaleDiv::NTickTypes];
00042 
00043     int minExtent;
00044 
00045     QMap<double, QwtText> labelCache;
00046 };
00047 
00055 QwtAbstractScaleDraw::QwtAbstractScaleDraw()
00056 {
00057     d_data = new QwtAbstractScaleDraw::PrivateData;
00058 }
00059 
00061 QwtAbstractScaleDraw::QwtAbstractScaleDraw(const QwtAbstractScaleDraw &other)
00062 {
00063     d_data = new QwtAbstractScaleDraw::PrivateData(*other.d_data);
00064 }
00065 
00067 QwtAbstractScaleDraw::~QwtAbstractScaleDraw()
00068 {
00069     delete d_data;
00070 }
00072 QwtAbstractScaleDraw &QwtAbstractScaleDraw::operator=(const QwtAbstractScaleDraw &other)
00073 {
00074     *d_data = *other.d_data;
00075     return *this;
00076 }
00077 
00086 void QwtAbstractScaleDraw::enableComponent(
00087     ScaleComponent component, bool enable)
00088 {
00089     if ( enable )
00090         d_data->components |= component;
00091     else
00092         d_data->components &= ~component;
00093 }
00094 
00099 bool QwtAbstractScaleDraw::hasComponent(ScaleComponent component) const
00100 {
00101     return (d_data->components & component);
00102 }
00103 
00108 void QwtAbstractScaleDraw::setScaleDiv(const QwtScaleDiv &sd)
00109 {
00110     d_data->scldiv = sd;
00111     d_data->map.setScaleInterval(sd.lBound(), sd.hBound());
00112     d_data->labelCache.clear();
00113 }
00114 
00119 void QwtAbstractScaleDraw::setTransformation(
00120     QwtScaleTransformation *transformation)
00121 {
00122     d_data->map.setTransformation(transformation);
00123 }
00124 
00126 const QwtScaleMap &QwtAbstractScaleDraw::map() const
00127 {
00128     return d_data->map;
00129 }
00130 
00132 QwtScaleMap &QwtAbstractScaleDraw::scaleMap() 
00133 {
00134     return d_data->map;
00135 }
00136 
00138 const QwtScaleDiv& QwtAbstractScaleDraw::scaleDiv() const 
00139 { 
00140     return d_data->scldiv; 
00141 }
00142 
00143 #if QT_VERSION < 0x040000
00144 
00152 void QwtAbstractScaleDraw::draw(QPainter *painter, 
00153     const QColorGroup& colorGroup) const
00154 
00155 #else
00156 
00165 void QwtAbstractScaleDraw::draw(QPainter *painter, 
00166     const QPalette& palette) const
00167 #endif
00168 {
00169     if ( hasComponent(QwtAbstractScaleDraw::Labels) )
00170     {
00171         painter->save();
00172 
00173 #if QT_VERSION < 0x040000
00174         painter->setPen(colorGroup.text()); // ignore pen style
00175 #else
00176         painter->setPen(palette.color(QPalette::Text)); // ignore pen style
00177 #endif
00178 
00179         const QwtValueList &majorTicks = 
00180             d_data->scldiv.ticks(QwtScaleDiv::MajorTick);
00181 
00182         for (int i = 0; i < (int)majorTicks.count(); i++)
00183         {
00184             const double v = majorTicks[i];
00185             if ( d_data->scldiv.contains(v) )
00186                 drawLabel(painter, majorTicks[i]);
00187         }
00188 
00189         painter->restore();
00190     }
00191 
00192     if ( hasComponent(QwtAbstractScaleDraw::Ticks) )
00193     {
00194         painter->save();
00195 
00196         QPen pen = painter->pen();
00197 #if QT_VERSION < 0x040000
00198         pen.setColor(colorGroup.foreground());
00199 #else
00200         pen.setColor(palette.color(QPalette::Foreground));
00201 #endif
00202         painter->setPen(pen);
00203 
00204         for ( int tickType = QwtScaleDiv::MinorTick; 
00205             tickType < QwtScaleDiv::NTickTypes; tickType++ )
00206         {
00207             const QwtValueList &ticks = d_data->scldiv.ticks(tickType);
00208             for (int i = 0; i < (int)ticks.count(); i++)
00209             {
00210                 const double v = ticks[i];
00211                 if ( d_data->scldiv.contains(v) )
00212                     drawTick(painter, v, d_data->tickLength[tickType]);
00213             }
00214         }
00215 
00216         painter->restore();
00217     }
00218 
00219     if ( hasComponent(QwtAbstractScaleDraw::Backbone) )
00220     {
00221         painter->save();
00222 
00223         QPen pen = painter->pen();
00224 #if QT_VERSION < 0x040000
00225         pen.setColor(colorGroup.foreground());
00226 #else
00227         pen.setColor(palette.color(QPalette::Foreground));
00228 #endif
00229         painter->setPen(pen);
00230 
00231         drawBackbone(painter);
00232 
00233         painter->restore();
00234     }
00235 }
00236 
00247 void QwtAbstractScaleDraw::setSpacing(int spacing)
00248 {
00249     if ( spacing < 0 )
00250         spacing = 0;
00251 
00252     d_data->spacing = spacing;
00253 }
00254 
00263 int QwtAbstractScaleDraw::spacing() const
00264 {
00265     return d_data->spacing;
00266 }
00267 
00281 void QwtAbstractScaleDraw::setMinimumExtent(int minExtent)
00282 {
00283     if ( minExtent < 0 )
00284         minExtent = 0;
00285 
00286     d_data->minExtent = minExtent;
00287 }
00288 
00293 int QwtAbstractScaleDraw::minimumExtent() const
00294 {
00295     return d_data->minExtent;
00296 }
00297 
00306 void QwtAbstractScaleDraw::setTickLength(
00307     QwtScaleDiv::TickType tickType, int length)
00308 {
00309     if ( tickType < QwtScaleDiv::MinorTick || 
00310         tickType > QwtScaleDiv::MajorTick )
00311     {
00312         return;
00313     }
00314 
00315     if ( length < 0 )
00316         length = 0;
00317 
00318     const int maxTickLen = 1000;
00319     if ( length > maxTickLen )
00320         length = 1000;
00321 
00322     d_data->tickLength[tickType] = length;
00323 }
00324 
00331 int QwtAbstractScaleDraw::tickLength(QwtScaleDiv::TickType tickType) const
00332 {
00333     if ( tickType < QwtScaleDiv::MinorTick || 
00334         tickType > QwtScaleDiv::MajorTick )
00335     {
00336         return 0;
00337     }
00338 
00339     return d_data->tickLength[tickType];
00340 }
00341 
00345 int QwtAbstractScaleDraw::majTickLength() const
00346 {
00347     return d_data->tickLength[QwtScaleDiv::MajorTick];
00348 }
00349 
00361 QwtText QwtAbstractScaleDraw::label(double value) const
00362 {
00363     return QLocale::system().toString(value);
00364 }
00365 
00379 const QwtText &QwtAbstractScaleDraw::tickLabel(
00380     const QFont &font, double value) const
00381 {
00382     QMap<double, QwtText>::const_iterator it = d_data->labelCache.find(value);
00383     if ( it == d_data->labelCache.end() )
00384     {
00385         QwtText lbl = label(value);
00386         lbl.setRenderFlags(0);
00387         lbl.setLayoutAttribute(QwtText::MinimumLayout);
00388 
00389         (void)lbl.textSize(font); // initialize the internal cache
00390 
00391         it = d_data->labelCache.insert(value, lbl);
00392     }
00393 
00394     return (*it);
00395 }
00396 
00404 void QwtAbstractScaleDraw::invalidateCache()
00405 {
00406     d_data->labelCache.clear();
00407 }

Generated on Sun Mar 22 16:54:06 2009 for Qwt User's Guide by  doxygen 1.5.0