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

qwt_scale_widget.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_widget.h"
00016 #include "qwt_math.h"
00017 #include "qwt_paint_buffer.h"
00018 #include "qwt_scale_div.h"
00019 #include "qwt_text.h"
00020 
00021 class QwtScaleWidget::PrivateData
00022 {
00023 public:
00024     PrivateData():
00025         scaleDraw(NULL),
00026         title(NULL)
00027     {
00028     }
00029 
00030     ~PrivateData()
00031     {
00032         delete scaleDraw;
00033         delete title;
00034     }
00035 
00036     QwtScaleDraw *scaleDraw;
00037 
00038     int borderDist[2];
00039     int scaleLength;
00040     int baseDist;
00041 
00042     int titleOffset;
00043     int titleDist;
00044     QwtText *title;
00045 };
00046 
00054 QwtScaleWidget::QwtScaleWidget(QWidget *parent):
00055     QWidget(parent)
00056 {
00057     initScale(QwtScaleWidget::Left);
00058 }
00059 
00068 QwtScaleWidget::QwtScaleWidget(QwtScaleWidget::Position pos, QWidget *parent):
00069     QWidget(parent)
00070 {
00071     initScale(pos);
00072 }
00073 
00075 QwtScaleWidget::~QwtScaleWidget()
00076 {
00077     delete d_data;
00078 }
00079 
00081 void QwtScaleWidget::initScale(QwtScaleWidget::Position pos)
00082 {
00083     d_data = new PrivateData;
00084 
00085 #if QT_VERSION < 0x040000
00086     setWFlags(Qt::WNoAutoErase);
00087 #endif 
00088 
00089     QwtScaleDraw::Orientation sdo;
00090     d_data->borderDist[0] = 0;
00091     d_data->borderDist[1] = 0;
00092     d_data->baseDist = 4;
00093     d_data->titleOffset = 0;
00094     d_data->titleDist = 2;
00095 
00096     switch(pos)
00097     {
00098         case QwtScaleWidget::Left:
00099             sdo = QwtScaleDraw::Left;
00100             break;
00101         case QwtScaleWidget::Right:
00102             sdo = QwtScaleDraw::Right;
00103             break;
00104         case QwtScaleWidget::Bottom:
00105             sdo = QwtScaleDraw::Bottom;
00106             break;
00107         case QwtScaleWidget::Top:
00108             sdo = QwtScaleDraw::Top;
00109             break;
00110         default:
00111             sdo = QwtScaleDraw::Left;
00112     }
00113 
00114     d_data->scaleDraw = new QwtScaleDraw;
00115     d_data->scaleDraw->setGeometry(0, 0, 10, sdo);
00116 
00117     const int flags = Qt::AlignHCenter
00118 #if QT_VERSION < 0x040000
00119         | Qt::WordBreak | Qt::ExpandTabs;
00120 #else
00121         | Qt::TextExpandTabs | Qt::TextWordWrap;
00122 #endif
00123     d_data->title = new QwtPlainText( QString::null, font(), flags);
00124 
00125     QSizePolicy policy(QSizePolicy::MinimumExpanding,
00126         QSizePolicy::Fixed);
00127     if ( d_data->scaleDraw->orientation() == QwtScaleDraw::Left ||
00128         d_data->scaleDraw->orientation() == QwtScaleDraw::Right )
00129     {
00130         policy.transpose();
00131     }
00132 
00133     setSizePolicy(policy);
00134     
00135 #if QT_VERSION >= 0x040000
00136     setAttribute(Qt::WA_WState_OwnSizePolicy, false);
00137 #else
00138     clearWState( WState_OwnSizePolicy );
00139 #endif
00140 
00141 }
00142 
00148 void QwtScaleWidget::setTitle(const QString &text)
00149 {
00150     if (text == title())
00151         return;
00152 
00153     QwtText *title = QwtText::makeText(text, d_data->title->flags(),
00154         d_data->title->font(), d_data->title->color());
00155 
00156     delete d_data->title;
00157     d_data->title = title;
00158 
00159     layoutScale();
00160 }
00161 
00167 void QwtScaleWidget::setPosition(Position pos)
00168 {
00169     QwtScaleDraw::Orientation sdo;
00170     switch(pos)
00171     {
00172         case QwtScaleWidget::Left:
00173             sdo = QwtScaleDraw::Left;
00174             break;
00175         case QwtScaleWidget::Right:
00176             sdo = QwtScaleDraw::Right;
00177             break;
00178         case QwtScaleWidget::Bottom:
00179             sdo = QwtScaleDraw::Bottom;
00180             break;
00181         case QwtScaleWidget::Top:
00182             sdo = QwtScaleDraw::Top;
00183             break;
00184         default:
00185             sdo = QwtScaleDraw::Left;
00186     }
00187     
00188 #if QT_VERSION >= 0x040000
00189     if ( !testAttribute(Qt::WA_WState_OwnSizePolicy) )
00190 #else
00191     if ( !testWState( WState_OwnSizePolicy ) )
00192 #endif
00193     {
00194         QSizePolicy policy(QSizePolicy::MinimumExpanding,
00195             QSizePolicy::Fixed);
00196         if ( d_data->scaleDraw->orientation() == QwtScaleDraw::Left ||
00197             d_data->scaleDraw->orientation() == QwtScaleDraw::Right )
00198         {
00199             policy.transpose();
00200         }
00201         setSizePolicy(policy);
00202 
00203 #if QT_VERSION >= 0x040000
00204         setAttribute(Qt::WA_WState_OwnSizePolicy, false);
00205 #else
00206         clearWState( WState_OwnSizePolicy );
00207 #endif
00208     }
00209 
00210     if (d_data->scaleDraw)
00211         d_data->scaleDraw->setGeometry(0,0,10,sdo);
00212     layoutScale();
00213 }
00214 
00215         
00220 QwtScaleWidget::Position QwtScaleWidget::position() const 
00221 {
00222     if (!scaleDraw())
00223         return Left;
00224     
00225     QwtScaleDraw::Orientation ori = scaleDraw()->orientation();
00226     switch(ori)
00227     {
00228         case QwtScaleDraw::Left:
00229             return QwtScaleWidget::Left;
00230         case QwtScaleDraw::Right:
00231             return QwtScaleWidget::Right;
00232         case QwtScaleDraw::Bottom:
00233             return QwtScaleWidget::Bottom;
00234         case QwtScaleDraw::Top:
00235             return QwtScaleWidget::Top;
00236         default:
00237             return QwtScaleWidget::Left;
00238     }
00239 }
00240 
00249 void QwtScaleWidget::setBorderDist(int dist1, int dist2)
00250 {
00251     if ( dist1 != d_data->borderDist[0] || dist2 != d_data->borderDist[1] )
00252     {
00253         d_data->borderDist[0] = dist1;
00254         d_data->borderDist[1] = dist2;
00255         layoutScale();
00256     }
00257 }
00258 
00264 void QwtScaleWidget::setBaselineDist(int bd)
00265 {
00266     bd = qwtMax( 0, bd );
00267     if ( bd != d_data->baseDist )
00268     {
00269         d_data->baseDist = bd;
00270         layoutScale();
00271     }
00272 }
00273 
00279 void QwtScaleWidget::setTitleDist(int td)
00280 {
00281     td = qwtMax( 0, td );
00282     if ( td != d_data->titleDist )
00283     {
00284         d_data->titleDist = td;
00285         layoutScale();
00286     }
00287 }
00288 
00289 
00295 void QwtScaleWidget::setTitleFont(const QFont &f)
00296 {
00297     if (f == d_data->title->font())
00298         return;
00299 
00300     d_data->title->setFont(f);
00301     layoutScale();
00302 }
00303 
00309 void QwtScaleWidget::setTitleColor(const QColor &c)
00310 {
00311     d_data->title->setColor(c);
00312     update();
00313 }
00314 
00323 void QwtScaleWidget::setTitleFlags(int flags)
00324 {
00325     flags &= ~(Qt::AlignTop | Qt::AlignBottom);
00326     d_data->title->setFlags(flags);
00327     layoutScale(); // Qt::SingleLine, Qt::ExpandTabs might affect layout
00328 }
00329 
00341 void QwtScaleWidget::setLabelFormat(char f, int prec, int fieldwidth)
00342 {
00343     d_data->scaleDraw->setLabelFormat(f, prec, fieldwidth);
00344     layoutScale();
00345 }
00346 
00354 void QwtScaleWidget::setLabelFlags(int flags)
00355 {
00356     d_data->scaleDraw->setLabelFlags(flags);
00357     layoutScale();
00358 }
00359 
00365 void QwtScaleWidget::setLabelRotation(double rotation)
00366 {
00367     d_data->scaleDraw->setLabelRotation(rotation);
00368     layoutScale();
00369 }
00370 
00376 void QwtScaleWidget::setScaleDraw(QwtScaleDraw *sd)
00377 {
00378     if ( sd == NULL || sd == d_data->scaleDraw )
00379         return;
00380 
00381     if ( d_data->scaleDraw )
00382         *sd = *d_data->scaleDraw;
00383 
00384     delete d_data->scaleDraw;
00385     d_data->scaleDraw = sd;
00386 
00387     layoutScale();
00388 }
00389 
00400 void QwtScaleWidget::labelFormat(char &f, int &prec, int &fieldwidth) const
00401 {
00402     d_data->scaleDraw->labelFormat(f, prec, fieldwidth);
00403 }
00404 
00409 const QwtScaleDraw *QwtScaleWidget::scaleDraw() const 
00410 { 
00411     return d_data->scaleDraw; 
00412 }
00413 
00418 int QwtScaleWidget::titleFlags() const 
00419 { 
00420     return d_data->title->flags();
00421 }
00422 
00427 const QFont QwtScaleWidget::titleFont() const 
00428 {
00429     return d_data->title->font();
00430 }
00431 
00436 const QColor QwtScaleWidget::titleColor() const 
00437 {
00438     return d_data->title->color();
00439 }
00440 
00445 const QString QwtScaleWidget::title() const 
00446 {
00447     return d_data->title->text();
00448 }
00449 
00454 int QwtScaleWidget::startBorderDist() const 
00455 { 
00456     return d_data->borderDist[0]; 
00457 }  
00458 
00463 int QwtScaleWidget::endBorderDist() const 
00464 { 
00465     return d_data->borderDist[1]; 
00466 }
00467 
00472 int QwtScaleWidget::baseLineDist() const 
00473 { 
00474     return d_data->baseDist; 
00475 }
00476 
00481 int QwtScaleWidget::titleDist() const 
00482 { 
00483     return d_data->titleDist; 
00484 }
00485 
00489 void QwtScaleWidget::paintEvent(QPaintEvent *e)
00490 {
00491     const QRect &ur = e->rect();
00492     if ( ur.isValid() )
00493     {
00494 #if QT_VERSION < 0x040000
00495         QwtPaintBuffer paintBuffer(this, ur);
00496         draw(paintBuffer.painter());
00497 #else
00498         QPainter painter(this);
00499         draw(&painter);
00500 #endif
00501     }
00502 }
00503 
00507 void QwtScaleWidget::draw(QPainter *p) const
00508 {
00509 #if QT_VERSION < 0x040000
00510     d_data->scaleDraw->draw(p, colorGroup());
00511 #else
00512     d_data->scaleDraw->draw(p, palette());
00513 #endif
00514 
00515     QRect r = rect();
00516 
00517     switch(d_data->scaleDraw->orientation())
00518     {
00519         case QwtScaleDraw::Bottom:
00520             r.setTop( r.top() + d_data->titleOffset );
00521             break;
00522 
00523         case QwtScaleDraw::Left:
00524             r.setRight( r.right() - d_data->titleOffset );
00525             break;
00526 
00527         case QwtScaleDraw::Right:
00528             r.setLeft( r.left() + d_data->titleOffset );
00529             break;
00530 
00531         case QwtScaleDraw::Top:
00532         default:
00533             r.setBottom( r.bottom() - d_data->titleOffset );
00534             break;
00535     }
00536 
00537     drawTitle(p, d_data->scaleDraw->orientation(), r);
00538 }
00539 
00543 void QwtScaleWidget::resizeEvent(QResizeEvent *)
00544 {
00545     layoutScale(false);
00546 }
00547 
00549 //  the current rect and fonts.
00550 //  \param update_geometry   notify the layout system and call update
00551 //         to redraw the scale
00552 
00553 void QwtScaleWidget::layoutScale( bool update_geometry )
00554 {
00555     QRect r = this->rect();
00556 
00557     // Borders cannot be less than the minBorderDist
00558 
00559     int bd0, bd1;
00560     minBorderDist(bd0, bd1);
00561     if ( d_data->borderDist[0] > bd0 )
00562         bd0 = d_data->borderDist[0];
00563     if ( d_data->borderDist[1] > bd1 )
00564         bd1 = d_data->borderDist[1];
00565 
00566     switch(d_data->scaleDraw->orientation())
00567     {
00568     case QwtScaleDraw::Bottom:
00569         d_data->scaleDraw->setGeometry(r.x() + bd0, r.y() + d_data->baseDist,
00570             r.width() - bd0 - bd1, QwtScaleDraw::Bottom);
00571 
00572         d_data->titleOffset = d_data->titleDist + d_data->baseDist +
00573             d_data->scaleDraw->maxHeight(QPen(), font());
00574         break;
00575 
00576     case QwtScaleDraw::Top:
00577         d_data->scaleDraw->setGeometry(r.x() + bd0, r.bottom() - d_data->baseDist,
00578                r.width() - bd0 - bd1, QwtScaleDraw::Top);
00579         d_data->titleOffset =  d_data->titleDist + d_data->baseDist +
00580                            d_data->scaleDraw->maxHeight(QPen(), font());
00581         break;
00582 
00583     case QwtScaleDraw::Left:
00584         d_data->scaleDraw->setGeometry(r.right() - d_data->baseDist, r.y() + bd0,
00585                             r.height() - bd0 - bd1, QwtScaleDraw::Left);
00586         d_data->titleOffset = d_data->baseDist + d_data->titleDist +
00587                         d_data->scaleDraw->maxWidth(QPen(), font());
00588         break;
00589 
00590     case QwtScaleDraw::Right:
00591         d_data->scaleDraw->setGeometry(r.x() + d_data->baseDist, r.y() + bd0,
00592                             r.height() - bd0 - bd1, QwtScaleDraw::Right);
00593         d_data->titleOffset = d_data->baseDist + d_data->titleDist +
00594                           d_data->scaleDraw->maxWidth(QPen(), font());
00595         break;
00596     default:
00597         break;
00598     }
00599     if ( update_geometry )
00600     {
00601       updateGeometry();
00602       update();
00603     }
00604 }
00605 
00613 void QwtScaleWidget::drawTitle(QPainter *painter,
00614     QwtScaleDraw::Orientation o, const QRect &rect) const
00615 {
00616     QRect r;
00617     double angle;
00618     int flags = d_data->title->flags() & ~(Qt::AlignTop | Qt::AlignBottom);
00619 
00620     switch(o)
00621     {
00622 #ifndef QT_NO_TRANSFORMATIONS
00623         case QwtScaleDraw::Left:
00624             flags |= Qt::AlignTop;
00625             angle = -90.0;
00626             r.setRect(rect.left(), rect.bottom(), rect.height(), rect.width());
00627             break;
00628         case QwtScaleDraw::Right:
00629             flags |= Qt::AlignTop;
00630             angle = 90.0;
00631             r.setRect(rect.right(), rect.top(), rect.height(), rect.width());
00632             break;
00633 #else
00634         case QwtScaleDraw::Left:
00635         case QwtScaleDraw::Right:
00636             // swallow vertical titles
00637             return;
00638 #endif
00639         case QwtScaleDraw::Top:
00640             flags |= Qt::AlignTop;
00641             angle = 0.0;
00642             r = rect;
00643             break;
00644         case QwtScaleDraw::Bottom:
00645         default:
00646             flags |= Qt::AlignBottom;
00647             angle = 0.0;
00648             r = rect;
00649             break;
00650     }
00651 
00652     d_data->title->setFlags(flags);
00653 
00654     painter->save();
00655     painter->translate(r.x(), r.y());
00656 #ifndef QT_NO_TRANSFORMATIONS
00657     if (angle != 0.0)
00658         painter->rotate(angle);
00659 #endif
00660     d_data->title->draw(painter, QRect(0, 0, r.width(), r.height()));
00661 
00662     // Users do not expect to see AlignTop or AlignBottom
00663     d_data->title->setFlags(flags & ~(Qt::AlignTop | Qt::AlignBottom));
00664     painter->restore();
00665 }
00666 
00675 void QwtScaleWidget::scaleChange()
00676 {
00677     layoutScale();
00678 }
00679 
00683 QSize QwtScaleWidget::sizeHint() const
00684 {
00685     return minimumSizeHint();
00686 }
00687 
00691 QSize QwtScaleWidget::minimumSizeHint() const
00692 {
00693     Qt::Orientation o = Qt::Horizontal;
00694     if ( d_data->scaleDraw->orientation() == QwtScaleDraw::Left ||
00695         d_data->scaleDraw->orientation() == QwtScaleDraw::Right )
00696     {
00697         o = Qt::Vertical;
00698     }
00699 
00700     // Border Distance cannot be less than the scale minBorderDist
00701     // Note, the minBorderDist is already included in minHeight/minWidth
00702     int length = 0;
00703     int mbd1, mbd2;
00704     minBorderDist(mbd1, mbd2);
00705     length += qwtMax( 0, d_data->borderDist[0] - mbd1 );
00706     length += qwtMax( 0, d_data->borderDist[1] - mbd2 );
00707 
00708     if ( o == Qt::Vertical )
00709         length += d_data->scaleDraw->minHeight(QPen(), font());
00710     else
00711         length += d_data->scaleDraw->minWidth(QPen(), font());
00712 
00713     int dim = dimForLength(length, font());
00714     if ( length < dim )
00715     {
00716         // compensate for long titles
00717         length = dim;
00718         dim = dimForLength(length, font());
00719     }
00720 
00721     QSize size(length + 2, dim);
00722     if ( o == Qt::Vertical )
00723         size.transpose();
00724 
00725     return size;
00726 }
00727 
00734 int QwtScaleWidget::titleHeightForWidth(int width) const
00735 {
00736     return d_data->title->heightForWidth(width);
00737 }
00738 
00748 int QwtScaleWidget::dimForLength(int length, const QFont &scaleFont) const
00749 {
00750     int dim = d_data->baseDist;
00751     if ( d_data->scaleDraw->orientation() == QwtScaleDraw::Left ||
00752         d_data->scaleDraw->orientation() == QwtScaleDraw::Right )
00753     {
00754         dim += d_data->scaleDraw->minWidth(QPen(), scaleFont);
00755 #ifdef QT_NO_TRANSFORMATIONS
00756         return dim;
00757 #endif
00758     }
00759     else
00760         dim += d_data->scaleDraw->minHeight(QPen(), scaleFont);
00761 
00762     if ( !d_data->title->text().isEmpty() )
00763     {
00764         dim += titleHeightForWidth(length) + d_data->titleDist;
00765     }
00766     return dim;
00767 }
00768 
00779 void QwtScaleWidget::minBorderDist(int &start, int &end) const
00780 {
00781     d_data->scaleDraw->minBorderDist(font(), start, end);
00782 }
00783 
00792 void QwtScaleWidget::fontChange(const QFont &oldFont)
00793 {
00794     QWidget::fontChange( oldFont );
00795     layoutScale();
00796 }
00797 
00806 void QwtScaleWidget::setScaleDiv(const QwtScaleTransformation& transformation,
00807     const QwtScaleDiv &sd)
00808 {
00809     if (d_data->scaleDraw->scaleDiv() != sd)
00810     {
00811         d_data->scaleDraw->setTransformation(transformation);
00812         d_data->scaleDraw->setScaleDiv(sd);
00813         layoutScale();
00814     }
00815 }

Generated on Wed Aug 31 23:02:30 2005 for Qwt User's Guide by  doxygen 1.4.1