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:

Generated on Sun Nov 21 11:12:44 2004 for Qwt User's Guide by doxygen 1.3.5