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 Tue Nov 16 21:12:21 2004 for Qwt User's Guide by doxygen 1.3.8