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 {
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
00426
00427
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
00564
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
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 }