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