Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages

# qwt_scale.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 <qevent.h>
    00014 #include "qwt_painter.h"
    00015 #include "qwt_scale.h"
    00016 #include "qwt_math.h"
    00017 #include "qwt_paint_buffer.h"
    00018 #include "qwt_text.h"
    00019
    00027 QwtScale::QwtScale(QWidget *parent, const char *name):
    00028     QWidget(parent, name, Qt::WRepaintNoErase|Qt::WResizeNoErase)
    00029 {
    00030     initScale(QwtScale::Left);
    00031 }
    00032
    00041 QwtScale::QwtScale(QwtScale::Position pos, QWidget *parent, const char *name):
    00042     QWidget(parent,name, Qt::WRepaintNoErase|Qt::WResizeNoErase)
    00043 {
    00044     initScale(pos);
    00045 }
    00046
    00048 QwtScale::~QwtScale()
    00049 {
    00050     delete d_scaleDraw;
    00051     delete d_title;
    00052 }
    00053
    00055 void QwtScale::initScale(QwtScale::Position pos)
    00056 {
    00057     QwtScaleDraw::Orientation sdo;
    00058     d_borderDist[0] = 0;
    00059     d_borderDist[1] = 0;
    00060     d_baseDist = 4;
    00061     d_titleOffset = 0;
    00062     d_titleDist = 2;
    00063
    00064     switch(pos)
    00065     {
    00066         case QwtScale::Left:
    00067             sdo = QwtScaleDraw::Left;
    00068             break;
    00069         case QwtScale::Right:
    00070             sdo = QwtScaleDraw::Right;
    00071             break;
    00072         case QwtScale::Bottom:
    00073             sdo = QwtScaleDraw::Bottom;
    00074             break;
    00075         case QwtScale::Top:
    00076             sdo = QwtScaleDraw::Top;
    00077             break;
    00078         default:
    00079             sdo = QwtScaleDraw::Left;
    00080     }
    00081
    00082     d_scaleDraw = new QwtScaleDraw;
    00083     d_scaleDraw->setGeometry(0, 0, 10, sdo);
    00084
    00085     d_title = new QwtPlainText( QString::null, font(),
    00086                 Qt::AlignHCenter | Qt::WordBreak | Qt::ExpandTabs);
    00087 }
    00088
    00094 void QwtScale::setTitle(const QString &text)
    00095 {
    00096     if (text == title())
    00097         return;
    00098
    00099     QwtText *title = QwtText::makeText(text, d_title->alignment(),
    00100         d_title->font(), d_title->color());
    00101
    00102     delete d_title;
    00103     d_title = title;
    00104
    00105     layoutScale();
    00106 }
    00107
    00113 void QwtScale::setPosition(Position pos)
    00114 {
    00115     QwtScaleDraw::Orientation sdo;
    00116     switch(pos)
    00117     {
    00118         case QwtScale::Left:
    00119             sdo = QwtScaleDraw::Left;
    00120             break;
    00121         case QwtScale::Right:
    00122             sdo = QwtScaleDraw::Right;
    00123             break;
    00124         case QwtScale::Bottom:
    00125             sdo = QwtScaleDraw::Bottom;
    00126             break;
    00127         case QwtScale::Top:
    00128             sdo = QwtScaleDraw::Top;
    00129             break;
    00130         default:
    00131             sdo = QwtScaleDraw::Left;
    00132     }
    00133
    00134     if (d_scaleDraw)
    00135         d_scaleDraw->setGeometry(0,0,10,sdo);
    00136     layoutScale();
    00137 }
    00138
    00139
    00144 QwtScale::Position QwtScale::position() const
    00145 {
    00146     if (!scaleDraw())
    00147         return Left;
    00148
    00149     QwtScaleDraw::Orientation ori = scaleDraw()->orientation();
    00150     switch(ori)
    00151     {
    00152         case QwtScaleDraw::Left:
    00153             return QwtScale::Left;
    00154         case QwtScaleDraw::Right:
    00155             return QwtScale::Right;
    00156         case QwtScaleDraw::Bottom:
    00157             return QwtScale::Bottom;
    00158         case QwtScaleDraw::Top:
    00159             return QwtScale::Top;
    00160         default:
    00161             return QwtScale::Left;
    00162     }
    00163 }
    00164
    00173 void QwtScale::setBorderDist(int dist1, int dist2)
    00174 {
    00175     if ( dist1 != d_borderDist[0] || dist2 != d_borderDist[1] )
    00176     {
    00177         d_borderDist[0] = dist1;
    00178         d_borderDist[1] = dist2;
    00179         layoutScale();
    00180     }
    00181 }
    00182
    00188 void QwtScale::setBaselineDist(int bd)
    00189 {
    00190     bd = qwtMax( 0, bd );
    00191     if ( bd != d_baseDist )
    00192     {
    00193         d_baseDist = bd;
    00194         layoutScale();
    00195     }
    00196 }
    00197
    00203 void QwtScale::setTitleDist(int td)
    00204 {
    00205     td = qwtMax( 0, td );
    00206     if ( td != d_titleDist )
    00207     {
    00208         d_titleDist = td;
    00209         layoutScale();
    00210     }
    00211 }
    00212
    00213
    00219 void QwtScale::setTitleFont(const QFont &f)
    00220 {
    00221     if (f == d_title->font())
    00222         return;
    00223
    00224     d_title->setFont(f);
    00225     layoutScale();
    00226 }
    00227
    00233 void QwtScale::setTitleColor(const QColor &c)
    00234 {
    00235     d_title->setColor(c);
    00236     update();
    00237 }
    00238
    00247 void QwtScale::setTitleAlignment(int flags)
    00248 {
    00249     flags &= ~(Qt::AlignTop | Qt::AlignBottom);
    00250     d_title->setAlignment(flags);
    00251     layoutScale(); // Qt::SingleLine, Qt::ExpandTabs might affect layout
    00252 }
    00253
    00265 void QwtScale::setLabelFormat(char f, int prec, int fieldwidth)
    00266 {
    00267     d_scaleDraw->setLabelFormat(f, prec, fieldwidth);
    00268     layoutScale();
    00269 }
    00270
    00278 void QwtScale::setLabelAlignment(int align)
    00279 {
    00280     d_scaleDraw->setLabelAlignment(align);
    00281     layoutScale();
    00282 }
    00283
    00289 void QwtScale::setLabelRotation(double rotation)
    00290 {
    00291     d_scaleDraw->setLabelRotation(rotation);
    00292     layoutScale();
    00293 }
    00294
    00300 void QwtScale::setScaleDraw(QwtScaleDraw *sd)
    00301 {
    00302     if ( sd == NULL || sd == d_scaleDraw )
    00303         return;
    00304
    00305     if ( d_scaleDraw )
    00306         *sd = *d_scaleDraw;
    00307
    00308     delete d_scaleDraw;
    00309     d_scaleDraw = sd;
    00310
    00311     layoutScale();
    00312 }
    00313
    00324 void QwtScale::labelFormat(char &f, int &prec, int &fieldwidth) const
    00325 {
    00326     d_scaleDraw->labelFormat(f, prec, fieldwidth);
    00327 }
    00328
    00333 const QwtScaleDraw *QwtScale::scaleDraw() const
    00334 {
    00335     return d_scaleDraw;
    00336 }
    00337
    00342 int QwtScale::titleAlignment() const
    00343 {
    00344     return d_title->alignment();
    00345 }
    00346
    00351 const QFont QwtScale::titleFont() const
    00352 {
    00353     return d_title->font();
    00354 }
    00355
    00360 const QColor QwtScale::titleColor() const
    00361 {
    00362     return d_title->color();
    00363 }
    00364
    00369 const QString QwtScale::title() const
    00370 {
    00371     return d_title->text();
    00372 }
    00373
    00378 int QwtScale::startBorderDist() const
    00379 {
    00380     return d_borderDist[0];
    00381 }
    00382
    00387 int QwtScale::endBorderDist() const
    00388 {
    00389     return d_borderDist[1];
    00390 }
    00391
    00396 int QwtScale::baseLineDist() const
    00397 {
    00398     return d_baseDist;
    00399 }
    00400
    00405 int QwtScale::titleDist() const
    00406 {
    00407     return d_titleDist;
    00408 }
    00409
    00413 void QwtScale::paintEvent(QPaintEvent *e)
    00414 {
    00415     const QRect &ur = e->rect();
    00416     if ( ur.isValid() )
    00417     {
    00418         QwtPaintBuffer paintBuffer(this, ur);
    00419         draw(paintBuffer.painter());
    00420     }
    00421 }
    00422
    00426 void QwtScale::draw(QPainter *p) const
    00427 {
    00428     d_scaleDraw->draw(p);
    00429
    00430     QRect r = rect();
    00431
    00432     switch(d_scaleDraw->orientation())
    00433     {
    00434         case QwtScaleDraw::Bottom:
    00435             r.setTop( r.top() + d_titleOffset );
    00436             break;
    00437
    00438         case QwtScaleDraw::Left:
    00439             r.setRight( r.right() - d_titleOffset );
    00440             break;
    00441
    00442         case QwtScaleDraw::Right:
    00443             r.setLeft( r.left() + d_titleOffset );
    00444             break;
    00445
    00446         case QwtScaleDraw::Top:
    00447         default:
    00448             r.setBottom( r.bottom() - d_titleOffset );
    00449             break;
    00450     }
    00451
    00452     drawTitle(p, d_scaleDraw->orientation(), r);
    00453 }
    00454
    00458 void QwtScale::resizeEvent(QResizeEvent *)
    00459 {
    00460     layoutScale(FALSE);
    00461 }
    00462
    00464 //  the current rect and fonts.
    00465 //  \param update_geometry   notify the layout system and call update
    00466 //         to redraw the scale
    00467
    00468 void QwtScale::layoutScale( bool update_geometry )
    00469 {
    00470     QRect r = this->rect();
    00471
    00472     // Borders cannot be less than the minBorderDist
    00473
    00474     int bd0, bd1;
    00475     minBorderDist(bd0, bd1);
    00476     if ( d_borderDist[0] > bd0 )
    00477         bd0 = d_borderDist[0];
    00478     if ( d_borderDist[1] > bd1 )
    00479         bd1 = d_borderDist[1];
    00480
    00481     const QFontMetrics fm(font());
    00482     switch(d_scaleDraw->orientation())
    00483     {
    00484     case QwtScaleDraw::Bottom:
    00485         d_scaleDraw->setGeometry(r.x() + bd0, r.y() + d_baseDist,
    00486             r.width() - bd0 - bd1, QwtScaleDraw::Bottom);
    00487
    00488         d_titleOffset = d_titleDist + d_baseDist +
    00489             d_scaleDraw->maxHeight(QPen(), fm);
    00490         break;
    00491
    00492     case QwtScaleDraw::Top:
    00493         d_scaleDraw->setGeometry(r.x() + bd0, r.bottom() - d_baseDist,
    00494                r.width() - bd0 - bd1, QwtScaleDraw::Top);
    00495         d_titleOffset =  d_titleDist + d_baseDist +
    00496                            d_scaleDraw->maxHeight(QPen(), fm);
    00497         break;
    00498
    00499     case QwtScaleDraw::Left:
    00500         d_scaleDraw->setGeometry(r.right() - d_baseDist, r.y() + bd0,
    00501                             r.height() - bd0 - bd1, QwtScaleDraw::Left);
    00502         d_titleOffset = d_baseDist + d_titleDist +
    00503                         d_scaleDraw->maxWidth(QPen(), fm);
    00504         break;
    00505
    00506     case QwtScaleDraw::Right:
    00507         d_scaleDraw->setGeometry(r.x() + d_baseDist, r.y() + bd0,
    00508                             r.height() - bd0 - bd1, QwtScaleDraw::Right);
    00509         d_titleOffset = d_baseDist + d_titleDist +
    00510                           d_scaleDraw->maxWidth(QPen(), fm);
    00511         break;
    00512     default:
    00513         break;
    00514     }
    00515     if ( update_geometry )
    00516     {
    00517       updateGeometry();
    00518       update();
    00519     }
    00520 }
    00521
    00529 void QwtScale::drawTitle(QPainter *painter,
    00530     QwtScaleDraw::Orientation o, const QRect &rect) const
    00531 {
    00532     QRect r;
    00533     double angle;
    00534     int align = d_title->alignment() & ~(Qt::AlignTop | Qt::AlignBottom);
    00535
    00536     switch(o)
    00537     {
    00538 #ifndef QT_NO_TRANSFORMATIONS
    00539         case QwtScaleDraw::Left:
    00540             align |= Qt::AlignTop;
    00541             angle = -90.0;
    00542             r.setRect(rect.left(), rect.bottom(), rect.height(), rect.width());
    00543             break;
    00544         case QwtScaleDraw::Right:
    00545             align |= Qt::AlignTop;
    00546             angle = 90.0;
    00547             r.setRect(rect.right(), rect.top(), rect.height(), rect.width());
    00548             break;
    00549 #else
    00550         case QwtScaleDraw::Left:
    00551         case QwtScaleDraw::Right:
    00552             // swallow vertical titles
    00553             return;
    00554 #endif
    00555         case QwtScaleDraw::Top:
    00556             align |= Qt::AlignTop;
    00557             angle = 0.0;
    00558             r = rect;
    00559             break;
    00560         case QwtScaleDraw::Bottom:
    00561         default:
    00562             align |= Qt::AlignBottom;
    00563             angle = 0.0;
    00564             r = rect;
    00565             break;
    00566     }
    00567
    00568     d_title->setAlignment(align);
    00569
    00570     painter->save();
    00571     painter->translate(r.x(), r.y());
    00572 #ifndef QT_NO_TRANSFORMATIONS
    00573     if (angle != 0.0)
    00574         painter->rotate(angle);
    00575 #endif
    00576     d_title->draw(painter, QRect(0, 0, r.width(), r.height()));
    00577
    00578     // Users do not expect to see AlignTop or AlignBottom
    00579     d_title->setAlignment(align & ~(Qt::AlignTop | Qt::AlignBottom));
    00580     painter->restore();
    00581 }
    00582
    00591 void QwtScale::scaleChange()
    00592 {
    00593     layoutScale();
    00594 }
    00595
    00600 QSizePolicy QwtScale::sizePolicy() const
    00601 {
    00602     QSizePolicy sp;
    00603     if ( d_scaleDraw->orientation() == QwtScaleDraw::Left ||
    00604         d_scaleDraw->orientation() == QwtScaleDraw::Right )
    00605     {
    00606         sp.setHorData( QSizePolicy::Fixed );
    00607         sp.setVerData( QSizePolicy::MinimumExpanding );
    00608     }
    00609     else
    00610     {
    00611         sp.setHorData( QSizePolicy::MinimumExpanding );
    00612         sp.setVerData( QSizePolicy::Fixed );
    00613     }
    00614     return sp;
    00615 }
    00616
    00620 QSize QwtScale::sizeHint() const
    00621 {
    00622     return minimumSizeHint();
    00623 }
    00624
    00628 QSize QwtScale::minimumSizeHint() const
    00629 {
    00630     Qt::Orientation o = Qt::Horizontal;
    00631     if ( d_scaleDraw->orientation() == QwtScaleDraw::Left ||
    00632         d_scaleDraw->orientation() == QwtScaleDraw::Right )
    00633     {
    00634         o = Qt::Vertical;
    00635     }
    00636
    00637     // Border Distance cannot be less than the scale minBorderDist
    00638     // Note, the minBorderDist is already included in minHeight/minWidth
    00639     int length = 0;
    00640     int mbd1, mbd2;
    00641     minBorderDist(mbd1, mbd2);
    00642     length += qwtMax( 0, d_borderDist[0] - mbd1 );
    00643     length += qwtMax( 0, d_borderDist[1] - mbd2 );
    00644
    00645     const QFontMetrics fm(font());
    00646     if ( o == Qt::Vertical )
    00647         length += d_scaleDraw->minHeight(QPen(), fm);
    00648     else
    00649         length += d_scaleDraw->minWidth(QPen(), fm);
    00650
    00651     int dim = dimForLength(length, fm);
    00652     if ( length < dim )
    00653     {
    00654         // compensate for long titles
    00655         length = dim;
    00656         dim = dimForLength(length, fm);
    00657     }
    00658
    00659     QSize size(length + 2, dim);
    00660     if ( o == Qt::Vertical )
    00661         size.transpose();
    00662
    00663     return size;
    00664 }
    00665
    00672 int QwtScale::titleHeightForWidth(int width) const
    00673 {
    00674     return d_title->heightForWidth(width);
    00675 }
    00676
    00686 int QwtScale::dimForLength(int length,
    00687     const QFontMetrics &scaleFontMetrics) const
    00688 {
    00689     int dim = d_baseDist;
    00690     if ( d_scaleDraw->orientation() == QwtScaleDraw::Left ||
    00691         d_scaleDraw->orientation() == QwtScaleDraw::Right )
    00692     {
    00693         dim += d_scaleDraw->minWidth(QPen(), scaleFontMetrics);
    00694 #ifdef QT_NO_TRANSFORMATIONS
    00695         return dim;
    00696 #endif
    00697     }
    00698     else
    00699         dim += d_scaleDraw->minHeight(QPen(), scaleFontMetrics);
    00700
    00701     if ( !d_title->text().isEmpty() )
    00702     {
    00703         dim += titleHeightForWidth(length) + d_titleDist;
    00704     }
    00705     return dim;
    00706 }
    00707
    00718 void QwtScale::minBorderDist(int &start, int &end) const
    00719 {
    00720     const QFontMetrics fm(font());
    00721     d_scaleDraw->minBorderDist(fm, start, end);
    00722 }
    00723
    00732 void QwtScale::fontChange(const QFont &oldFont)
    00733 {
    00734     QWidget::fontChange( oldFont );
    00735     layoutScale();
    00736 }
    00737
    00746 void QwtScale::setScaleDiv(const QwtScaleDiv &sd)
    00747 {
    00748     if (d_scaleDraw->scaleDiv() != sd)
    00749     {
    00750         d_scaleDraw->setScale(sd);
    00751         layoutScale();
    00752     }
    00753 }
    00754
    00755 // Local Variables:
    00756 // mode: C++
    00757 // c-file-style: "stroustrup"
    00758 // indent-tabs-mode: nil
    00759 // End: