# 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 "qwt_math.h"
    00016 #include "qwt_text.h"
    00017 #include "qwt_painter.h"
    00018 #include "qwt_scale_map.h"
    00019 #include "qwt_scale_draw.h"
    00020
    00021 class QwtAbstractScaleDraw::PrivateData
    00022 {
    00023 public:
    00024     PrivateData():
    00025         components(Backbone | Ticks | Labels),
    00026         spacing(4),
    00027         minExtent(0)
    00028     {
    00029         tickLength[QwtScaleDiv::MinorTick] = 4;
    00030         tickLength[QwtScaleDiv::MediumTick] = 6;
    00031         tickLength[QwtScaleDiv::MajorTick] = 8;
    00032     }
    00033
    00034     int components;
    00035
    00036     QwtScaleMap map;
    00037     QwtScaleDiv scldiv;
    00038
    00039     int spacing;
    00040     int tickLength[QwtScaleDiv::NTickTypes];
    00041
    00042     int minExtent;
    00043
    00044     QMap<double, QwtText> labelCache;
    00045 };
    00046
    00054 QwtAbstractScaleDraw::QwtAbstractScaleDraw()
    00055 {
    00056     d_data = new QwtAbstractScaleDraw::PrivateData;
    00057 }
    00058
    00060 QwtAbstractScaleDraw::QwtAbstractScaleDraw(const QwtAbstractScaleDraw &other)
    00061 {
    00062     d_data = new QwtAbstractScaleDraw::PrivateData(*other.d_data);
    00063 }
    00064
    00066 QwtAbstractScaleDraw::~QwtAbstractScaleDraw()
    00067 {
    00068     delete d_data;
    00069 }
    00071 QwtAbstractScaleDraw &QwtAbstractScaleDraw::operator=(const QwtAbstractScaleDraw &other)
    00072 {
    00073     *d_data = *other.d_data;
    00074     return *this;
    00075 }
    00076
    00085 void QwtAbstractScaleDraw::enableComponent(
    00086     ScaleComponent component, bool enable)
    00087 {
    00088     if ( enable )
    00089         d_data->components |= component;
    00090     else
    00091         d_data->components &= ~component;
    00092 }
    00093
    00098 bool QwtAbstractScaleDraw::hasComponent(ScaleComponent component) const
    00099 {
    00100     return (d_data->components & component);
    00101 }
    00102
    00107 void QwtAbstractScaleDraw::setScaleDiv(const QwtScaleDiv &sd)
    00108 {
    00109     d_data->scldiv = sd;
    00110     d_data->map.setScaleInterval(sd.lBound(), sd.hBound());
    00111     d_data->labelCache.clear();
    00112 }
    00113
    00118 void QwtAbstractScaleDraw::setTransformation(
    00119     QwtScaleTransformation *transformation)
    00120 {
    00121     d_data->map.setTransformation(transformation);
    00122 }
    00123
    00125 const QwtScaleMap &QwtAbstractScaleDraw::map() const
    00126 {
    00127     return d_data->map;
    00128 }
    00129
    00131 QwtScaleMap &QwtAbstractScaleDraw::scaleMap()
    00132 {
    00133     return d_data->map;
    00134 }
    00135
    00137 const QwtScaleDiv& QwtAbstractScaleDraw::scaleDiv() const
    00138 {
    00139     return d_data->scldiv;
    00140 }
    00141
    00142 #if QT_VERSION < 0x040000
    00143
    00151 void QwtAbstractScaleDraw::draw(QPainter *painter,
    00152     const QColorGroup& colorGroup) const
    00153
    00154 #else
    00155
    00164 void QwtAbstractScaleDraw::draw(QPainter *painter,
    00165     const QPalette& palette) const
    00166 #endif
    00167 {
    00168     if ( hasComponent(QwtAbstractScaleDraw::Labels) )
    00169     {
    00170         painter->save();
    00171
    00172 #if QT_VERSION < 0x040000
    00173         painter->setPen(colorGroup.text()); // ignore pen style
    00174 #else
    00175         painter->setPen(palette.color(QPalette::Text)); // ignore pen style
    00176 #endif
    00177
    00178         const QwtValueList &majorTicks =
    00179             d_data->scldiv.ticks(QwtScaleDiv::MajorTick);
    00180
    00181         for (int i = 0; i < (int)majorTicks.count(); i++)
    00182         {
    00183             const double v = majorTicks[i];
    00184             if ( d_data->scldiv.contains(v) )
    00185                 drawLabel(painter, majorTicks[i]);
    00186         }
    00187
    00188         painter->restore();
    00189     }
    00190
    00191     if ( hasComponent(QwtAbstractScaleDraw::Ticks) )
    00192     {
    00193         painter->save();
    00194
    00195         QPen pen = painter->pen();
    00196 #if QT_VERSION < 0x040000
    00197         pen.setColor(colorGroup.foreground());
    00198 #else
    00199         pen.setColor(palette.color(QPalette::Foreground));
    00200 #endif
    00201         painter->setPen(pen);
    00202
    00203         for ( int tickType = QwtScaleDiv::MinorTick;
    00204             tickType < QwtScaleDiv::NTickTypes; tickType++ )
    00205         {
    00206             const QwtValueList &ticks = d_data->scldiv.ticks(tickType);
    00207             for (int i = 0; i < (int)ticks.count(); i++)
    00208             {
    00209                 const double v = ticks[i];
    00210                 if ( d_data->scldiv.contains(v) )
    00211                     drawTick(painter, v, d_data->tickLength[tickType]);
    00212             }
    00213         }
    00214
    00215         painter->restore();
    00216     }
    00217
    00218     if ( hasComponent(QwtAbstractScaleDraw::Backbone) )
    00219     {
    00220         painter->save();
    00221
    00222         QPen pen = painter->pen();
    00223 #if QT_VERSION < 0x040000
    00224         pen.setColor(colorGroup.foreground());
    00225 #else
    00226         pen.setColor(palette.color(QPalette::Foreground));
    00227 #endif
    00228         painter->setPen(pen);
    00229
    00230         drawBackbone(painter);
    00231
    00232         painter->restore();
    00233     }
    00234 }
    00235
    00246 void QwtAbstractScaleDraw::setSpacing(int spacing)
    00247 {
    00248     if ( spacing < 0 )
    00249         spacing = 0;
    00250
    00251     d_data->spacing = spacing;
    00252 }
    00253
    00262 int QwtAbstractScaleDraw::spacing() const
    00263 {
    00264     return d_data->spacing;
    00265 }
    00266
    00280 void QwtAbstractScaleDraw::setMinimumExtent(int minExtent)
    00281 {
    00282     if ( minExtent < 0 )
    00283         minExtent = 0;
    00284
    00285     d_data->minExtent = minExtent;
    00286 }
    00287
    00292 int QwtAbstractScaleDraw::minimumExtent() const
    00293 {
    00294     return d_data->minExtent;
    00295 }
    00296
    00305 void QwtAbstractScaleDraw::setTickLength(
    00306     QwtScaleDiv::TickType tickType, int length)
    00307 {
    00308     if ( tickType < QwtScaleDiv::MinorTick ||
    00309         tickType > QwtScaleDiv::MajorTick )
    00310     {
    00311         return;
    00312     }
    00313
    00314     if ( length < 0 )
    00315         length = 0;
    00316
    00317     const int maxTickLen = 1000;
    00318     if ( length > maxTickLen )
    00319         length = 1000;
    00320
    00321     d_data->tickLength[tickType] = length;
    00322 }
    00323
    00330 int QwtAbstractScaleDraw::tickLength(QwtScaleDiv::TickType tickType) const
    00331 {
    00332     if ( tickType < QwtScaleDiv::MinorTick ||
    00333         tickType > QwtScaleDiv::MajorTick )
    00334     {
    00335         return 0;
    00336     }
    00337
    00338     return d_data->tickLength[tickType];
    00339 }
    00340
    00344 int QwtAbstractScaleDraw::majTickLength() const
    00345 {
    00346     return d_data->tickLength[QwtScaleDiv::MajorTick];
    00347 }
    00348
    00359 QwtText QwtAbstractScaleDraw::label(double value) const
    00360 {
    00361     return QString::number(value);
    00362 }
    00363
    00377 const QwtText &QwtAbstractScaleDraw::tickLabel(
    00378     const QFont &font, double value) const
    00379 {
    00380     QMap<double, QwtText>::const_iterator it = d_data->labelCache.find(value);
    00381     if ( it == d_data->labelCache.end() )
    00382     {
    00383         QwtText lbl = label(value);
    00384         lbl.setRenderFlags(0);
    00385         lbl.setLayoutAttribute(QwtText::MinimumLayout);
    00386
    00387         (void)lbl.textSize(font); // initialize the internal cache
    00388
    00389         it = d_data->labelCache.insert(value, lbl);
    00390     }
    00391
    00392     return (*it);
    00393 }
    00394
    00402 void QwtAbstractScaleDraw::invalidateCache()
    00403 {
    00404     d_data->labelCache.clear();
    00405 }