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_color_map.h"
00016 #include "qwt_scale_widget.h"
00017 #include "qwt_scale_map.h"
00018 #include "qwt_math.h"
00019 #include "qwt_paint_buffer.h"
00020 #include "qwt_scale_div.h"
00021 #include "qwt_text.h"
00022
00023 class QwtScaleWidget::PrivateData
00024 {
00025 public:
00026 PrivateData():
00027 scaleDraw(NULL)
00028 {
00029 colorBar.colorMap = NULL;
00030 }
00031
00032 ~PrivateData()
00033 {
00034 delete scaleDraw;
00035 delete colorBar.colorMap;
00036 }
00037
00038 QwtScaleDraw *scaleDraw;
00039
00040 int borderDist[2];
00041 int minBorderDist[2];
00042 int scaleLength;
00043 int margin;
00044 int penWidth;
00045
00046 int titleOffset;
00047 int spacing;
00048 QwtText title;
00049
00050 struct t_colorBar
00051 {
00052 bool isEnabled;
00053 int width;
00054 QwtDoubleInterval interval;
00055 QwtColorMap *colorMap;
00056 } colorBar;
00057 };
00058
00063 QwtScaleWidget::QwtScaleWidget(QWidget *parent):
00064 QWidget(parent)
00065 {
00066 initScale(QwtScaleDraw::LeftScale);
00067 }
00068
00069 #if QT_VERSION < 0x040000
00070
00075 QwtScaleWidget::QwtScaleWidget(QWidget *parent, const char *name):
00076 QWidget(parent, name)
00077 {
00078 initScale(QwtScaleDraw::LeftScale);
00079 }
00080 #endif
00081
00087 QwtScaleWidget::QwtScaleWidget(
00088 QwtScaleDraw::Alignment align, QWidget *parent):
00089 QWidget(parent)
00090 {
00091 initScale(align);
00092 }
00093
00095 QwtScaleWidget::~QwtScaleWidget()
00096 {
00097 delete d_data;
00098 }
00099
00101 void QwtScaleWidget::initScale(QwtScaleDraw::Alignment align)
00102 {
00103 d_data = new PrivateData;
00104
00105 #if QT_VERSION < 0x040000
00106 setWFlags(Qt::WNoAutoErase);
00107 #endif
00108
00109 d_data->borderDist[0] = 0;
00110 d_data->borderDist[1] = 0;
00111 d_data->minBorderDist[0] = 0;
00112 d_data->minBorderDist[1] = 0;
00113 d_data->margin = 4;
00114 d_data->penWidth = 0;
00115 d_data->titleOffset = 0;
00116 d_data->spacing = 2;
00117
00118 d_data->scaleDraw = new QwtScaleDraw;
00119 d_data->scaleDraw->setAlignment(align);
00120 d_data->scaleDraw->setLength(10);
00121
00122 d_data->colorBar.colorMap = new QwtLinearColorMap();
00123 d_data->colorBar.isEnabled = false;
00124 d_data->colorBar.width = 10;
00125
00126 const int flags = Qt::AlignHCenter
00127 #if QT_VERSION < 0x040000
00128 | Qt::WordBreak | Qt::ExpandTabs;
00129 #else
00130 | Qt::TextExpandTabs | Qt::TextWordWrap;
00131 #endif
00132 d_data->title.setRenderFlags(flags);
00133 d_data->title.setFont(font());
00134
00135 QSizePolicy policy(QSizePolicy::MinimumExpanding,
00136 QSizePolicy::Fixed);
00137 if ( d_data->scaleDraw->orientation() == Qt::Vertical )
00138 policy.transpose();
00139
00140 setSizePolicy(policy);
00141
00142 #if QT_VERSION >= 0x040000
00143 setAttribute(Qt::WA_WState_OwnSizePolicy, false);
00144 #else
00145 clearWState( WState_OwnSizePolicy );
00146 #endif
00147
00148 }
00149
00150 void QwtScaleWidget::setTitle(const QString &title)
00151 {
00152 if ( d_data->title.text() != title )
00153 {
00154 d_data->title.setText(title);
00155 layoutScale();
00156 }
00157 }
00158
00167 void QwtScaleWidget::setTitle(const QwtText &title)
00168 {
00169 QwtText t = title;
00170 const int flags = title.renderFlags() & ~(Qt::AlignTop | Qt::AlignBottom);
00171 t.setRenderFlags(flags);
00172
00173 if (t != d_data->title)
00174 {
00175 d_data->title = t;
00176 layoutScale();
00177 }
00178 }
00179
00186 void QwtScaleWidget::setAlignment(QwtScaleDraw::Alignment alignment)
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() == Qt::Vertical )
00197 policy.transpose();
00198 setSizePolicy(policy);
00199
00200 #if QT_VERSION >= 0x040000
00201 setAttribute(Qt::WA_WState_OwnSizePolicy, false);
00202 #else
00203 clearWState( WState_OwnSizePolicy );
00204 #endif
00205 }
00206
00207 if (d_data->scaleDraw)
00208 d_data->scaleDraw->setAlignment(alignment);
00209 layoutScale();
00210 }
00211
00212
00217 QwtScaleDraw::Alignment QwtScaleWidget::alignment() const
00218 {
00219 if (!scaleDraw())
00220 return QwtScaleDraw::LeftScale;
00221
00222 return scaleDraw()->alignment();
00223 }
00224
00233 void QwtScaleWidget::setBorderDist(int dist1, int dist2)
00234 {
00235 if ( dist1 != d_data->borderDist[0] || dist2 != d_data->borderDist[1] )
00236 {
00237 d_data->borderDist[0] = dist1;
00238 d_data->borderDist[1] = dist2;
00239 layoutScale();
00240 }
00241 }
00242
00248 void QwtScaleWidget::setMargin(int margin)
00249 {
00250 margin = qwtMax( 0, margin );
00251 if ( margin != d_data->margin )
00252 {
00253 d_data->margin = margin;
00254 layoutScale();
00255 }
00256 }
00257
00263 void QwtScaleWidget::setSpacing(int spacing)
00264 {
00265 spacing = qwtMax( 0, spacing );
00266 if ( spacing != d_data->spacing )
00267 {
00268 d_data->spacing = spacing;
00269 layoutScale();
00270 }
00271 }
00272
00278 void QwtScaleWidget::setPenWidth(int width)
00279 {
00280 if ( width < 0 )
00281 width = 0;
00282
00283 if ( width != d_data->penWidth )
00284 {
00285 d_data->penWidth = width;
00286 layoutScale();
00287 }
00288 }
00289
00295 #if QT_VERSION < 0x040000
00296 void QwtScaleWidget::setLabelAlignment(int alignment)
00297 #else
00298 void QwtScaleWidget::setLabelAlignment(Qt::Alignment alignment)
00299 #endif
00300 {
00301 d_data->scaleDraw->setLabelAlignment(alignment);
00302 layoutScale();
00303 }
00304
00310 void QwtScaleWidget::setLabelRotation(double rotation)
00311 {
00312 d_data->scaleDraw->setLabelRotation(rotation);
00313 layoutScale();
00314 }
00315
00321 void QwtScaleWidget::setScaleDraw(QwtScaleDraw *sd)
00322 {
00323 if ( sd == NULL || sd == d_data->scaleDraw )
00324 return;
00325
00326 if ( d_data->scaleDraw )
00327 sd->setAlignment(d_data->scaleDraw->alignment());
00328
00329 delete d_data->scaleDraw;
00330 d_data->scaleDraw = sd;
00331
00332 layoutScale();
00333 }
00334
00339 const QwtScaleDraw *QwtScaleWidget::scaleDraw() const
00340 {
00341 return d_data->scaleDraw;
00342 }
00343
00348 QwtScaleDraw *QwtScaleWidget::scaleDraw()
00349 {
00350 return d_data->scaleDraw;
00351 }
00352
00357 QwtText QwtScaleWidget::title() const
00358 {
00359 return d_data->title;
00360 }
00361
00366 int QwtScaleWidget::startBorderDist() const
00367 {
00368 return d_data->borderDist[0];
00369 }
00370
00375 int QwtScaleWidget::endBorderDist() const
00376 {
00377 return d_data->borderDist[1];
00378 }
00379
00384 int QwtScaleWidget::margin() const
00385 {
00386 return d_data->margin;
00387 }
00388
00393 int QwtScaleWidget::spacing() const
00394 {
00395 return d_data->spacing;
00396 }
00397
00402 int QwtScaleWidget::penWidth() const
00403 {
00404 return d_data->penWidth;
00405 }
00409 void QwtScaleWidget::paintEvent(QPaintEvent *e)
00410 {
00411 const QRect &ur = e->rect();
00412 if ( ur.isValid() )
00413 {
00414 #if QT_VERSION < 0x040000
00415 QwtPaintBuffer paintBuffer(this, ur);
00416 draw(paintBuffer.painter());
00417 #else
00418 QPainter painter(this);
00419 draw(&painter);
00420 #endif
00421 }
00422 }
00423
00427 void QwtScaleWidget::draw(QPainter *painter) const
00428 {
00429 painter->save();
00430
00431 QPen scalePen = painter->pen();
00432 scalePen.setWidth(d_data->penWidth);
00433 painter->setPen(scalePen);
00434
00435 #if QT_VERSION < 0x040000
00436 d_data->scaleDraw->draw(painter, colorGroup());
00437 #else
00438 d_data->scaleDraw->draw(painter, palette());
00439 #endif
00440 painter->restore();
00441
00442 if ( d_data->colorBar.isEnabled && d_data->colorBar.width > 0 &&
00443 d_data->colorBar.interval.isValid() )
00444 {
00445 drawColorBar(painter, colorBarRect(rect()));
00446 }
00447
00448 QRect r = rect();
00449 if ( d_data->scaleDraw->orientation() == Qt::Horizontal )
00450 {
00451 r.setLeft(r.left() + d_data->borderDist[0]);
00452 r.setWidth(r.width() - d_data->borderDist[1]);
00453 }
00454 else
00455 {
00456 r.setTop(r.top() + d_data->borderDist[0]);
00457 r.setHeight(r.height() - d_data->borderDist[1]);
00458 }
00459
00460 if ( !d_data->title.isEmpty() )
00461 {
00462 QRect tr = r;
00463 switch(d_data->scaleDraw->alignment())
00464 {
00465 case QwtScaleDraw::LeftScale:
00466 tr.setRight( r.right() - d_data->titleOffset );
00467 break;
00468
00469 case QwtScaleDraw::RightScale:
00470 tr.setLeft( r.left() + d_data->titleOffset );
00471 break;
00472
00473 case QwtScaleDraw::BottomScale:
00474 tr.setTop( r.top() + d_data->titleOffset );
00475 break;
00476
00477 case QwtScaleDraw::TopScale:
00478 default:
00479 tr.setBottom( r.bottom() - d_data->titleOffset );
00480 break;
00481 }
00482
00483 drawTitle(painter, d_data->scaleDraw->alignment(), tr);
00484 }
00485 }
00486
00487 QRect QwtScaleWidget::colorBarRect(const QRect& rect) const
00488 {
00489 QRect cr = rect;
00490
00491 if ( d_data->scaleDraw->orientation() == Qt::Horizontal )
00492 {
00493 cr.setLeft(cr.left() + d_data->borderDist[0]);
00494 cr.setWidth(cr.width() - d_data->borderDist[1] + 1);
00495 }
00496 else
00497 {
00498 cr.setTop(cr.top() + d_data->borderDist[0]);
00499 cr.setHeight(cr.height() - d_data->borderDist[1] + 1);
00500 }
00501
00502 switch(d_data->scaleDraw->alignment())
00503 {
00504 case QwtScaleDraw::LeftScale:
00505 {
00506 cr.setLeft( cr.right() - d_data->spacing
00507 - d_data->colorBar.width + 1 );
00508 cr.setWidth(d_data->colorBar.width);
00509 break;
00510 }
00511
00512 case QwtScaleDraw::RightScale:
00513 {
00514 cr.setLeft( cr.left() + d_data->spacing );
00515 cr.setWidth(d_data->colorBar.width);
00516 break;
00517 }
00518
00519 case QwtScaleDraw::BottomScale:
00520 {
00521 cr.setTop( cr.top() + d_data->spacing );
00522 cr.setHeight(d_data->colorBar.width);
00523 break;
00524 }
00525
00526 case QwtScaleDraw::TopScale:
00527 {
00528 cr.setTop( cr.bottom() - d_data->spacing
00529 - d_data->colorBar.width + 1 );
00530 cr.setHeight(d_data->colorBar.width);
00531 break;
00532 }
00533 }
00534
00535 return cr;
00536 }
00537
00541 void QwtScaleWidget::resizeEvent(QResizeEvent *)
00542 {
00543 layoutScale(false);
00544 }
00545
00547
00548
00549
00550
00551 void QwtScaleWidget::layoutScale( bool update_geometry )
00552 {
00553 int bd0, bd1;
00554 getBorderDistHint(bd0, bd1);
00555 if ( d_data->borderDist[0] > bd0 )
00556 bd0 = d_data->borderDist[0];
00557 if ( d_data->borderDist[1] > bd1 )
00558 bd1 = d_data->borderDist[1];
00559
00560 int colorBarWidth = 0;
00561 if ( d_data->colorBar.isEnabled && d_data->colorBar.interval.isValid() )
00562 colorBarWidth = d_data->colorBar.width + d_data->spacing;
00563
00564 const QRect r = rect();
00565 int x, y, length;
00566
00567 if ( d_data->scaleDraw->orientation() == Qt::Vertical )
00568 {
00569 y = r.top() + bd0;
00570 length = r.height() - (bd0 + bd1);
00571
00572 if ( d_data->scaleDraw->alignment() == QwtScaleDraw::LeftScale )
00573 x = r.right() - d_data->margin - colorBarWidth;
00574 else
00575 x = r.left() + d_data->margin + colorBarWidth;
00576 }
00577 else
00578 {
00579 x = r.left() + bd0;
00580 length = r.width() - (bd0 + bd1);
00581
00582 if ( d_data->scaleDraw->alignment() == QwtScaleDraw::BottomScale )
00583 y = r.top() + d_data->margin + colorBarWidth;
00584 else
00585 y = r.bottom() - d_data->margin - colorBarWidth;
00586 }
00587
00588 d_data->scaleDraw->move(x, y);
00589 d_data->scaleDraw->setLength(length);
00590
00591 d_data->titleOffset = d_data->margin + d_data->spacing +
00592 colorBarWidth +
00593 d_data->scaleDraw->extent(QPen(Qt::black, d_data->penWidth), font());
00594
00595 if ( update_geometry )
00596 {
00597 updateGeometry();
00598 update();
00599 }
00600 }
00601
00602 void QwtScaleWidget::drawColorBar(QPainter *painter, const QRect& rect) const
00603 {
00604 if ( !d_data->colorBar.interval.isValid() )
00605 return;
00606
00607 const QwtScaleDraw* sd = d_data->scaleDraw;
00608
00609 QwtPainter::drawColorBar(painter, *d_data->colorBar.colorMap,
00610 d_data->colorBar.interval.normalized(), sd->map(),
00611 sd->orientation(), rect);
00612 }
00613
00621 void QwtScaleWidget::drawTitle(QPainter *painter,
00622 QwtScaleDraw::Alignment align, const QRect &rect) const
00623 {
00624 QRect r;
00625 double angle;
00626 int flags = d_data->title.renderFlags() &
00627 ~(Qt::AlignTop | Qt::AlignBottom | Qt::AlignVCenter);
00628
00629 switch(align)
00630 {
00631 case QwtScaleDraw::LeftScale:
00632 flags |= Qt::AlignTop;
00633 angle = -90.0;
00634 r.setRect(rect.left(), rect.bottom(), rect.height(), rect.width());
00635 break;
00636 case QwtScaleDraw::RightScale:
00637 flags |= Qt::AlignTop;
00638 angle = 90.0;
00639 r.setRect(rect.right(), rect.top(), rect.height(), rect.width());
00640 break;
00641 case QwtScaleDraw::TopScale:
00642 flags |= Qt::AlignTop;
00643 angle = 0.0;
00644 r = rect;
00645 break;
00646 case QwtScaleDraw::BottomScale:
00647 default:
00648 flags |= Qt::AlignBottom;
00649 angle = 0.0;
00650 r = rect;
00651 break;
00652 }
00653
00654 painter->save();
00655 painter->setFont(font());
00656 #if QT_VERSION < 0x040000
00657 painter->setPen(colorGroup().color(QColorGroup::Text));
00658 #else
00659 painter->setPen(palette().color(QPalette::Text));
00660 #endif
00661
00662 painter->translate(r.x(), r.y());
00663 if (angle != 0.0)
00664 painter->rotate(angle);
00665
00666 QwtText title = d_data->title;
00667 title.setRenderFlags(flags);
00668 title.draw(painter, QRect(0, 0, r.width(), r.height()));
00669
00670 painter->restore();
00671 }
00672
00681 void QwtScaleWidget::scaleChange()
00682 {
00683 layoutScale();
00684 }
00685
00689 QSize QwtScaleWidget::sizeHint() const
00690 {
00691 return minimumSizeHint();
00692 }
00693
00697 QSize QwtScaleWidget::minimumSizeHint() const
00698 {
00699 const Qt::Orientation o = d_data->scaleDraw->orientation();
00700
00701
00702
00703 int length = 0;
00704 int mbd1, mbd2;
00705 getBorderDistHint(mbd1, mbd2);
00706 length += qwtMax( 0, d_data->borderDist[0] - mbd1 );
00707 length += qwtMax( 0, d_data->borderDist[1] - mbd2 );
00708 length += d_data->scaleDraw->minLength(
00709 QPen(Qt::black, d_data->penWidth), font());
00710
00711 int dim = dimForLength(length, font());
00712 if ( length < dim )
00713 {
00714
00715 length = dim;
00716 dim = dimForLength(length, font());
00717 }
00718
00719 QSize size(length + 2, dim);
00720 if ( o == Qt::Vertical )
00721 size.transpose();
00722
00723 return size;
00724 }
00725
00732 int QwtScaleWidget::titleHeightForWidth(int width) const
00733 {
00734 return d_data->title.heightForWidth(width, font());
00735 }
00736
00746 int QwtScaleWidget::dimForLength(int length, const QFont &scaleFont) const
00747 {
00748 int dim = d_data->margin;
00749 dim += d_data->scaleDraw->extent(
00750 QPen(Qt::black, d_data->penWidth), scaleFont);
00751
00752 if ( !d_data->title.isEmpty() )
00753 dim += titleHeightForWidth(length) + d_data->spacing;
00754
00755 if ( d_data->colorBar.isEnabled && d_data->colorBar.interval.isValid() )
00756 dim += d_data->colorBar.width + d_data->spacing;
00757
00758 return dim;
00759 }
00760
00774 void QwtScaleWidget::getBorderDistHint(int &start, int &end) const
00775 {
00776 d_data->scaleDraw->getBorderDistHint(font(), start, end);
00777
00778 if ( start < d_data->minBorderDist[0] )
00779 start = d_data->minBorderDist[0];
00780
00781 if ( end < d_data->minBorderDist[1] )
00782 end = d_data->minBorderDist[1];
00783 }
00784
00793 void QwtScaleWidget::setMinBorderDist(int start, int end)
00794 {
00795 d_data->minBorderDist[0] = start;
00796 d_data->minBorderDist[1] = end;
00797 }
00798
00805 void QwtScaleWidget::getMinBorderDist(int &start, int &end) const
00806 {
00807 start = d_data->minBorderDist[0];
00808 end = d_data->minBorderDist[1];
00809 }
00810
00811 #if QT_VERSION < 0x040000
00812
00821 void QwtScaleWidget::fontChange(const QFont &oldFont)
00822 {
00823 QWidget::fontChange( oldFont );
00824 layoutScale();
00825 }
00826
00827 #endif
00828
00839 void QwtScaleWidget::setScaleDiv(
00840 QwtScaleTransformation *transformation,
00841 const QwtScaleDiv &scaleDiv)
00842 {
00843 QwtScaleDraw *sd = d_data->scaleDraw;
00844 if (sd->scaleDiv() != scaleDiv ||
00845 sd->map().transformation()->type() != transformation->type() )
00846 {
00847 sd->setTransformation(transformation);
00848 sd->setScaleDiv(scaleDiv);
00849 layoutScale();
00850
00851 emit scaleDivChanged();
00852 }
00853 else
00854 delete transformation;
00855 }
00856
00857 void QwtScaleWidget::setColorBarEnabled(bool on)
00858 {
00859 if ( on != d_data->colorBar.isEnabled )
00860 {
00861 d_data->colorBar.isEnabled = on;
00862 layoutScale();
00863 }
00864 }
00865
00866 bool QwtScaleWidget::isColorBarEnabled() const
00867 {
00868 return d_data->colorBar.isEnabled;
00869 }
00870
00871
00872 void QwtScaleWidget::setColorBarWidth(int width)
00873 {
00874 if ( width != d_data->colorBar.width )
00875 {
00876 d_data->colorBar.width = width;
00877 if ( isColorBarEnabled() )
00878 layoutScale();
00879 }
00880 }
00881
00882 int QwtScaleWidget::colorBarWidth() const
00883 {
00884 return d_data->colorBar.width;
00885 }
00886
00887 QwtDoubleInterval QwtScaleWidget::colorBarInterval() const
00888 {
00889 return d_data->colorBar.interval;
00890 }
00891
00892 void QwtScaleWidget::setColorMap(const QwtDoubleInterval &interval,
00893 const QwtColorMap &colorMap)
00894 {
00895 d_data->colorBar.interval = interval;
00896
00897 delete d_data->colorBar.colorMap;
00898 d_data->colorBar.colorMap = colorMap.copy();
00899
00900 if ( isColorBarEnabled() )
00901 layoutScale();
00902 }
00903
00904 const QwtColorMap &QwtScaleWidget::colorMap() const
00905 {
00906 return *d_data->colorBar.colorMap;
00907 }