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     {
00027     }
00028 
00029     ~PrivateData()
00030     {
00031         delete scaleDraw;
00032     }
00033 
00034     QwtScaleDraw *scaleDraw;
00035 
00036     int borderDist[2];
00037     int minBorderDist[2];
00038     int scaleLength;
00039     int baseDist;
00040 
00041     int titleOffset;
00042     int titleDist;
00043     QwtText title;
00044 };
00045 
00052 QwtScaleWidget::QwtScaleWidget(QWidget *parent):
00053     QWidget(parent)
00054 {
00055     initScale(QwtScaleDraw::LeftScale);
00056 }
00057 
00063 QwtScaleWidget::QwtScaleWidget(
00064         QwtScaleDraw::Alignment align, QWidget *parent):
00065     QWidget(parent)
00066 {
00067     initScale(align);
00068 }
00069 
00071 QwtScaleWidget::~QwtScaleWidget()
00072 {
00073     delete d_data;
00074 }
00075 
00077 void QwtScaleWidget::initScale(QwtScaleDraw::Alignment align)
00078 {
00079     d_data = new PrivateData;
00080 
00081 #if QT_VERSION < 0x040000
00082     setWFlags(Qt::WNoAutoErase);
00083 #endif 
00084 
00085     d_data->borderDist[0] = 0;
00086     d_data->borderDist[1] = 0;
00087     d_data->minBorderDist[0] = 0;
00088     d_data->minBorderDist[1] = 0;
00089     d_data->baseDist = 4;
00090     d_data->titleOffset = 0;
00091     d_data->titleDist = 2;
00092 
00093     d_data->scaleDraw = new QwtScaleDraw;
00094     d_data->scaleDraw->setAlignment(align);
00095     d_data->scaleDraw->setLength(10);
00096 
00097     const int flags = Qt::AlignHCenter
00098 #if QT_VERSION < 0x040000
00099         | Qt::WordBreak | Qt::ExpandTabs;
00100 #else
00101         | Qt::TextExpandTabs | Qt::TextWordWrap;
00102 #endif
00103     d_data->title.setFlags(flags); 
00104     d_data->title.setFont(font()); 
00105 
00106     QSizePolicy policy(QSizePolicy::MinimumExpanding,
00107         QSizePolicy::Fixed);
00108     if ( d_data->scaleDraw->orientation() == Qt::Vertical )
00109         policy.transpose();
00110 
00111     setSizePolicy(policy);
00112     
00113 #if QT_VERSION >= 0x040000
00114     setAttribute(Qt::WA_WState_OwnSizePolicy, false);
00115 #else
00116     clearWState( WState_OwnSizePolicy );
00117 #endif
00118 
00119 }
00120 
00121 void QwtScaleWidget::setTitle(const QString &title)
00122 {
00123     if ( d_data->title.text() != title )
00124     {
00125         d_data->title.setText(title);
00126         layoutScale();
00127     }
00128 }
00129 
00138 void QwtScaleWidget::setTitle(const QwtText &title)
00139 {
00140     QwtText t = title;
00141     const int flags = title.flags() & ~(Qt::AlignTop | Qt::AlignBottom);
00142     t.setFlags(flags);
00143 
00144     if (t != d_data->title)
00145     {
00146         d_data->title = t;
00147         layoutScale();
00148     }
00149 }
00150 
00157 void QwtScaleWidget::setAlignment(QwtScaleDraw::Alignment alignment)
00158 {
00159 #if QT_VERSION >= 0x040000
00160     if ( !testAttribute(Qt::WA_WState_OwnSizePolicy) )
00161 #else
00162     if ( !testWState( WState_OwnSizePolicy ) )
00163 #endif
00164     {
00165         QSizePolicy policy(QSizePolicy::MinimumExpanding,
00166             QSizePolicy::Fixed);
00167         if ( d_data->scaleDraw->orientation() == Qt::Vertical )
00168             policy.transpose();
00169         setSizePolicy(policy);
00170 
00171 #if QT_VERSION >= 0x040000
00172         setAttribute(Qt::WA_WState_OwnSizePolicy, false);
00173 #else
00174         clearWState( WState_OwnSizePolicy );
00175 #endif
00176     }
00177 
00178     if (d_data->scaleDraw)
00179         d_data->scaleDraw->setAlignment(alignment);
00180     layoutScale();
00181 }
00182 
00183         
00188 QwtScaleDraw::Alignment QwtScaleWidget::alignment() const 
00189 {
00190     if (!scaleDraw())
00191         return QwtScaleDraw::LeftScale;
00192 
00193     return scaleDraw()->alignment();
00194 }
00195 
00204 void QwtScaleWidget::setBorderDist(int dist1, int dist2)
00205 {
00206     if ( dist1 != d_data->borderDist[0] || dist2 != d_data->borderDist[1] )
00207     {
00208         d_data->borderDist[0] = dist1;
00209         d_data->borderDist[1] = dist2;
00210         layoutScale();
00211     }
00212 }
00213 
00219 void QwtScaleWidget::setBaselineDist(int bd)
00220 {
00221     bd = qwtMax( 0, bd );
00222     if ( bd != d_data->baseDist )
00223     {
00224         d_data->baseDist = bd;
00225         layoutScale();
00226     }
00227 }
00228 
00234 void QwtScaleWidget::setTitleDist(int td)
00235 {
00236     td = qwtMax( 0, td );
00237     if ( td != d_data->titleDist )
00238     {
00239         d_data->titleDist = td;
00240         layoutScale();
00241     }
00242 }
00243 
00249 #if QT_VERSION < 0x040000
00250 void QwtScaleWidget::setLabelAlignment(int alignment)
00251 #else
00252 void QwtScaleWidget::setLabelAlignment(Qt::Alignment alignment)
00253 #endif
00254 {
00255     d_data->scaleDraw->setLabelAlignment(alignment);
00256     layoutScale();
00257 }
00258 
00264 void QwtScaleWidget::setLabelRotation(double rotation)
00265 {
00266     d_data->scaleDraw->setLabelRotation(rotation);
00267     layoutScale();
00268 }
00269 
00275 void QwtScaleWidget::setScaleDraw(QwtScaleDraw *sd)
00276 {
00277     if ( sd == NULL || sd == d_data->scaleDraw )
00278         return;
00279 
00280     if ( d_data->scaleDraw )
00281         *sd = *d_data->scaleDraw;
00282 
00283     delete d_data->scaleDraw;
00284     d_data->scaleDraw = sd;
00285 
00286     layoutScale();
00287 }
00288 
00293 const QwtScaleDraw *QwtScaleWidget::scaleDraw() const 
00294 { 
00295     return d_data->scaleDraw; 
00296 }
00297 
00302 QwtScaleDraw *QwtScaleWidget::scaleDraw() 
00303 { 
00304     return d_data->scaleDraw; 
00305 }
00306 
00311 QwtText QwtScaleWidget::title() const 
00312 {
00313     return d_data->title;
00314 }
00315 
00320 int QwtScaleWidget::startBorderDist() const 
00321 { 
00322     return d_data->borderDist[0]; 
00323 }  
00324 
00329 int QwtScaleWidget::endBorderDist() const 
00330 { 
00331     return d_data->borderDist[1]; 
00332 }
00333 
00338 int QwtScaleWidget::baseLineDist() const 
00339 { 
00340     return d_data->baseDist; 
00341 }
00342 
00347 int QwtScaleWidget::titleDist() const 
00348 { 
00349     return d_data->titleDist; 
00350 }
00351 
00355 void QwtScaleWidget::paintEvent(QPaintEvent *e)
00356 {
00357     const QRect &ur = e->rect();
00358     if ( ur.isValid() )
00359     {
00360 #if QT_VERSION < 0x040000
00361         QwtPaintBuffer paintBuffer(this, ur);
00362         draw(paintBuffer.painter());
00363 #else
00364         QPainter painter(this);
00365         draw(&painter);
00366 #endif
00367     }
00368 }
00369 
00373 void QwtScaleWidget::draw(QPainter *p) const
00374 {
00375 #if QT_VERSION < 0x040000
00376     d_data->scaleDraw->draw(p, colorGroup());
00377 #else
00378     d_data->scaleDraw->draw(p, palette());
00379 #endif
00380 
00381     QRect r = rect();
00382     if ( d_data->scaleDraw->orientation() == Qt::Horizontal )
00383     {
00384         r.setLeft(r.left() + d_data->borderDist[0]);
00385         r.setWidth(r.width() - d_data->borderDist[1]);
00386     }
00387     else
00388     {
00389         r.setTop(r.top() + d_data->borderDist[1]);
00390         r.setHeight(r.height() - d_data->borderDist[0]);
00391     }
00392 
00393     switch(d_data->scaleDraw->alignment())
00394     {
00395         case QwtScaleDraw::BottomScale:
00396             r.setTop( r.top() + d_data->titleOffset );
00397             break;
00398 
00399         case QwtScaleDraw::LeftScale:
00400             r.setRight( r.right() - d_data->titleOffset );
00401             break;
00402 
00403         case QwtScaleDraw::RightScale:
00404             r.setLeft( r.left() + d_data->titleOffset );
00405             break;
00406 
00407         case QwtScaleDraw::TopScale:
00408         default:
00409             r.setBottom( r.bottom() - d_data->titleOffset );
00410             break;
00411     }
00412 
00413     drawTitle(p, d_data->scaleDraw->alignment(), r);
00414 }
00415 
00419 void QwtScaleWidget::resizeEvent(QResizeEvent *)
00420 {
00421     layoutScale(false);
00422 }
00423 
00425 //  the current rect and fonts.
00426 //  \param update_geometry   notify the layout system and call update
00427 //         to redraw the scale
00428 
00429 void QwtScaleWidget::layoutScale( bool update_geometry )
00430 {
00431     int bd0, bd1;
00432     getBorderDistHint(bd0, bd1);
00433     if ( d_data->borderDist[0] > bd0 )
00434         bd0 = d_data->borderDist[0];
00435     if ( d_data->borderDist[1] > bd1 )
00436         bd1 = d_data->borderDist[1];
00437 
00438     const QRect r = rect();
00439     int x, y, length;
00440 
00441     if ( d_data->scaleDraw->orientation() == Qt::Vertical )
00442     {
00443         y = r.top() + bd0;
00444         length = r.height() - (bd0 + bd1);
00445 
00446         if ( d_data->scaleDraw->alignment() == QwtScaleDraw::LeftScale )
00447             x = r.right() - d_data->baseDist;
00448         else
00449             x = r.left() + d_data->baseDist;
00450     }
00451     else
00452     {
00453         x = r.left() + bd0; 
00454         length = r.width() - (bd0 + bd1);
00455 
00456         if ( d_data->scaleDraw->alignment() == QwtScaleDraw::BottomScale )
00457             y = r.top() + d_data->baseDist;
00458         else
00459             y = r.bottom() - d_data->baseDist;
00460     }
00461 
00462     d_data->scaleDraw->move(x, y);
00463     d_data->scaleDraw->setLength(length);
00464 
00465     d_data->titleOffset = d_data->baseDist + d_data->titleDist +
00466         d_data->scaleDraw->extent(QPen(), font());;
00467 
00468     if ( update_geometry )
00469     {
00470       updateGeometry();
00471       update();
00472     }
00473 }
00474 
00482 void QwtScaleWidget::drawTitle(QPainter *painter,
00483     QwtScaleDraw::Alignment align, const QRect &rect) const
00484 {
00485     QRect r;
00486     double angle;
00487     int flags = d_data->title.flags() & 
00488         ~(Qt::AlignTop | Qt::AlignBottom | Qt::AlignVCenter);
00489 
00490     switch(align)
00491     {
00492         case QwtScaleDraw::LeftScale:
00493             flags |= Qt::AlignTop;
00494             angle = -90.0;
00495             r.setRect(rect.left(), rect.bottom(), rect.height(), rect.width());
00496             break;
00497         case QwtScaleDraw::RightScale:
00498             flags |= Qt::AlignTop;
00499             angle = 90.0;
00500             r.setRect(rect.right(), rect.top(), rect.height(), rect.width());
00501             break;
00502         case QwtScaleDraw::TopScale:
00503             flags |= Qt::AlignTop;
00504             angle = 0.0;
00505             r = rect;
00506             break;
00507         case QwtScaleDraw::BottomScale:
00508         default:
00509             flags |= Qt::AlignBottom;
00510             angle = 0.0;
00511             r = rect;
00512             break;
00513     }
00514 
00515     painter->save();
00516     painter->setFont(font());
00517 #if QT_VERSION < 0x040000
00518     painter->setPen(colorGroup().color(QColorGroup::Text));
00519 #else
00520     painter->setPen(palette().color(QPalette::Text));
00521 #endif
00522 
00523     painter->translate(r.x(), r.y());
00524     if (angle != 0.0)
00525         painter->rotate(angle);
00526 
00527 
00528     QwtText title = d_data->title;
00529     title.setFlags(flags);
00530     title.draw(painter, QRect(0, 0, r.width(), r.height()));
00531 
00532     painter->restore();
00533 }
00534 
00543 void QwtScaleWidget::scaleChange()
00544 {
00545     layoutScale();
00546 }
00547 
00551 QSize QwtScaleWidget::sizeHint() const
00552 {
00553     return minimumSizeHint();
00554 }
00555 
00559 QSize QwtScaleWidget::minimumSizeHint() const
00560 {
00561     const Qt::Orientation o = d_data->scaleDraw->orientation();
00562 
00563     // Border Distance cannot be less than the scale borderDistHint
00564     // Note, the borderDistHint is already included in minHeight/minWidth
00565     int length = 0;
00566     int mbd1, mbd2;
00567     getBorderDistHint(mbd1, mbd2);
00568     length += qwtMax( 0, d_data->borderDist[0] - mbd1 );
00569     length += qwtMax( 0, d_data->borderDist[1] - mbd2 );
00570     length += d_data->scaleDraw->minLength(QPen(), font());
00571 
00572     int dim = dimForLength(length, font());
00573     if ( length < dim )
00574     {
00575         // compensate for long titles
00576         length = dim;
00577         dim = dimForLength(length, font());
00578     }
00579 
00580     QSize size(length + 2, dim);
00581     if ( o == Qt::Vertical )
00582         size.transpose();
00583 
00584     return size;
00585 }
00586 
00593 int QwtScaleWidget::titleHeightForWidth(int width) const
00594 {
00595     return d_data->title.heightForWidth(width, font());
00596 }
00597 
00607 int QwtScaleWidget::dimForLength(int length, const QFont &scaleFont) const
00608 {
00609     int dim = d_data->baseDist;
00610     dim += d_data->scaleDraw->extent(QPen(), scaleFont);
00611 
00612     if ( !d_data->title.isEmpty() )
00613     {
00614         dim += titleHeightForWidth(length) + d_data->titleDist;
00615     }
00616     return dim;
00617 }
00618 
00632 void QwtScaleWidget::getBorderDistHint(int &start, int &end) const
00633 {
00634     d_data->scaleDraw->getBorderDistHint(font(), start, end);
00635 
00636     if ( start < d_data->minBorderDist[0] )
00637         start = d_data->minBorderDist[0];
00638 
00639     if ( end < d_data->minBorderDist[1] )
00640         end = d_data->minBorderDist[1];
00641 }
00642 
00651 void QwtScaleWidget::setMinBorderDist(int start, int end)
00652 {
00653     d_data->minBorderDist[0] = start;
00654     d_data->minBorderDist[1] = end;
00655 }
00656 
00663 void QwtScaleWidget::getMinBorderDist(int &start, int &end) const
00664 {
00665     start = d_data->minBorderDist[0];
00666     end = d_data->minBorderDist[1];
00667 }
00668 
00669 #if QT_VERSION < 0x040000
00670 
00679 void QwtScaleWidget::fontChange(const QFont &oldFont)
00680 {
00681     QWidget::fontChange( oldFont );
00682     layoutScale();
00683 }
00684 
00685 #endif
00686 
00697 void QwtScaleWidget::setScaleDiv(
00698     const QwtScaleTransformation& transformation,
00699     const QwtScaleDiv &scaleDiv)
00700 {
00701     if (d_data->scaleDraw->scaleDiv() != scaleDiv)
00702     {
00703         d_data->scaleDraw->setTransformation(transformation);
00704         d_data->scaleDraw->setScaleDiv(scaleDiv);
00705         layoutScale();
00706     }
00707 }

Generated on Mon Jan 30 22:16:26 2006 for Qwt User's Guide by  doxygen 1.4.4