# 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 }