00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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();
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
00550
00551
00552
00553 void QwtScaleWidget::layoutScale( bool update_geometry )
00554 {
00555 QRect r = this->rect();
00556
00557
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
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
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
00701
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
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 }