qwt_scale_widget.cpp 20.9 KB
Newer Older
pixhawk's avatar
pixhawk committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
 * Qwt Widget Library
 * Copyright (C) 1997   Josef Wilgen
 * Copyright (C) 2002   Uwe Rathmann
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the Qwt License, Version 1.0
 *****************************************************************************/

// vim: expandtab

#include <qpainter.h>
#include <qevent.h>
#include "qwt_painter.h"
#include "qwt_color_map.h"
#include "qwt_scale_widget.h"
#include "qwt_scale_map.h"
#include "qwt_math.h"
#include "qwt_paint_buffer.h"
#include "qwt_scale_div.h"
#include "qwt_text.h"

class QwtScaleWidget::PrivateData
{
public:
    PrivateData():
27
        scaleDraw(NULL) {
pixhawk's avatar
pixhawk committed
28 29 30
        colorBar.colorMap = NULL;
    }

31
    ~PrivateData() {
pixhawk's avatar
pixhawk committed
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
        delete scaleDraw;
        delete colorBar.colorMap;
    }

    QwtScaleDraw *scaleDraw;

    int borderDist[2];
    int minBorderDist[2];
    int scaleLength;
    int margin;
    int penWidth;

    int titleOffset;
    int spacing;
    QwtText title;

48
    struct t_colorBar {
pixhawk's avatar
pixhawk committed
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
        bool isEnabled;
        int width;
        QwtDoubleInterval interval;
        QwtColorMap *colorMap;
    } colorBar;
};

/*!
  \brief Create a scale with the position QwtScaleWidget::Left
  \param parent Parent widget
*/
QwtScaleWidget::QwtScaleWidget(QWidget *parent):
    QWidget(parent)
{
    initScale(QwtScaleDraw::LeftScale);
}

#if QT_VERSION < 0x040000
/*!
  \brief Create a scale with the position QwtScaleWidget::Left
  \param parent Parent widget
  \param name Object name
*/
QwtScaleWidget::QwtScaleWidget(QWidget *parent, const char *name):
    QWidget(parent, name)
{
    initScale(QwtScaleDraw::LeftScale);
}
#endif

/*!
  \brief Constructor
81
  \param align Alignment.
pixhawk's avatar
pixhawk committed
82 83 84
  \param parent Parent widget
*/
QwtScaleWidget::QwtScaleWidget(
85
    QwtScaleDraw::Alignment align, QWidget *parent):
pixhawk's avatar
pixhawk committed
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
    QWidget(parent)
{
    initScale(align);
}

//! Destructor
QwtScaleWidget::~QwtScaleWidget()
{
    delete d_data;
}

//! Initialize the scale
void QwtScaleWidget::initScale(QwtScaleDraw::Alignment align)
{
    d_data = new PrivateData;

#if QT_VERSION < 0x040000
    setWFlags(Qt::WNoAutoErase);
104
#endif
pixhawk's avatar
pixhawk committed
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121

    d_data->borderDist[0] = 0;
    d_data->borderDist[1] = 0;
    d_data->minBorderDist[0] = 0;
    d_data->minBorderDist[1] = 0;
    d_data->margin = 4;
    d_data->penWidth = 0;
    d_data->titleOffset = 0;
    d_data->spacing = 2;

    d_data->scaleDraw = new QwtScaleDraw;
    d_data->scaleDraw->setAlignment(align);
    d_data->scaleDraw->setLength(10);

    d_data->colorBar.colorMap = new QwtLinearColorMap();
    d_data->colorBar.isEnabled = false;
    d_data->colorBar.width = 10;
122

pixhawk's avatar
pixhawk committed
123 124
    const int flags = Qt::AlignHCenter
#if QT_VERSION < 0x040000
125
                      | Qt::WordBreak | Qt::ExpandTabs;
pixhawk's avatar
pixhawk committed
126
#else
127
                      | Qt::TextExpandTabs | Qt::TextWordWrap;
pixhawk's avatar
pixhawk committed
128
#endif
129 130
    d_data->title.setRenderFlags(flags);
    d_data->title.setFont(font());
pixhawk's avatar
pixhawk committed
131 132

    QSizePolicy policy(QSizePolicy::MinimumExpanding,
133
                       QSizePolicy::Fixed);
pixhawk's avatar
pixhawk committed
134 135 136 137
    if ( d_data->scaleDraw->orientation() == Qt::Vertical )
        policy.transpose();

    setSizePolicy(policy);
138

pixhawk's avatar
pixhawk committed
139 140 141 142 143 144 145 146 147 148
#if QT_VERSION >= 0x040000
    setAttribute(Qt::WA_WState_OwnSizePolicy, false);
#else
    clearWState( WState_OwnSizePolicy );
#endif

}

void QwtScaleWidget::setTitle(const QString &title)
{
149
    if ( d_data->title.text() != title ) {
pixhawk's avatar
pixhawk committed
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
        d_data->title.setText(title);
        layoutScale();
    }
}

/*!
  \brief Give title new text contents
  \param title New title
  \sa QwtScaleWidget::title
  \warning The title flags are interpreted in
               direction of the label, AlignTop, AlignBottom can't be set
               as the title will always be aligned to the scale.
*/
void QwtScaleWidget::setTitle(const QwtText &title)
{
    QwtText t = title;
    const int flags = title.renderFlags() & ~(Qt::AlignTop | Qt::AlignBottom);
    t.setRenderFlags(flags);

169
    if (t != d_data->title) {
pixhawk's avatar
pixhawk committed
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
        d_data->title = t;
        layoutScale();
    }
}

/*!
  Change the alignment

  \param alignment New alignment
  \sa QwtScaleWidget::alignment
*/
void QwtScaleWidget::setAlignment(QwtScaleDraw::Alignment alignment)
{
#if QT_VERSION >= 0x040000
    if ( !testAttribute(Qt::WA_WState_OwnSizePolicy) )
#else
    if ( !testWState( WState_OwnSizePolicy ) )
#endif
    {
        QSizePolicy policy(QSizePolicy::MinimumExpanding,
190
                           QSizePolicy::Fixed);
pixhawk's avatar
pixhawk committed
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206
        if ( d_data->scaleDraw->orientation() == Qt::Vertical )
            policy.transpose();
        setSizePolicy(policy);

#if QT_VERSION >= 0x040000
        setAttribute(Qt::WA_WState_OwnSizePolicy, false);
#else
        clearWState( WState_OwnSizePolicy );
#endif
    }

    if (d_data->scaleDraw)
        d_data->scaleDraw->setAlignment(alignment);
    layoutScale();
}

207 208 209

/*!
    \return position
pixhawk's avatar
pixhawk committed
210 211
    \sa QwtScaleWidget::setPosition
*/
212
QwtScaleDraw::Alignment QwtScaleWidget::alignment() const
pixhawk's avatar
pixhawk committed
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229
{
    if (!scaleDraw())
        return QwtScaleDraw::LeftScale;

    return scaleDraw()->alignment();
}

/*!
  Specify distances of the scale's endpoints from the
  widget's borders. The actual borders will never be less
  than minimum border distance.
  \param dist1 Left or top Distance
  \param dist2 Right or bottom distance
  \sa QwtScaleWidget::borderDist
*/
void QwtScaleWidget::setBorderDist(int dist1, int dist2)
{
230
    if ( dist1 != d_data->borderDist[0] || dist2 != d_data->borderDist[1] ) {
pixhawk's avatar
pixhawk committed
231 232 233 234 235 236 237 238 239 240 241 242 243 244
        d_data->borderDist[0] = dist1;
        d_data->borderDist[1] = dist2;
        layoutScale();
    }
}

/*!
  \brief Specify the margin to the colorBar/base line.
  \param margin Margin
  \sa QwtScaleWidget::margin
*/
void QwtScaleWidget::setMargin(int margin)
{
    margin = qwtMax( 0, margin );
245
    if ( margin != d_data->margin ) {
pixhawk's avatar
pixhawk committed
246 247 248 249 250 251 252 253 254 255 256 257 258
        d_data->margin = margin;
        layoutScale();
    }
}

/*!
  \brief Specify the distance between color bar, scale and title
  \param spacing Spacing
  \sa QwtScaleWidget::spacing
*/
void QwtScaleWidget::setSpacing(int spacing)
{
    spacing = qwtMax( 0, spacing );
259
    if ( spacing != d_data->spacing ) {
pixhawk's avatar
pixhawk committed
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274
        d_data->spacing = spacing;
        layoutScale();
    }
}

/*!
  \brief Specify the width of the scale pen
  \param width Pen width
  \sa QwtScaleWidget::penWidth
*/
void QwtScaleWidget::setPenWidth(int width)
{
    if ( width < 0 )
        width = 0;

275
    if ( width != d_data->penWidth ) {
pixhawk's avatar
pixhawk committed
276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325
        d_data->penWidth = width;
        layoutScale();
    }
}

/*!
  \brief Change the alignment for the labels.

  \sa QwtScaleDraw::setLabelAlignment(), QwtScaleWidget::setLabelRotation()
*/
#if QT_VERSION < 0x040000
void QwtScaleWidget::setLabelAlignment(int alignment)
#else
void QwtScaleWidget::setLabelAlignment(Qt::Alignment alignment)
#endif
{
    d_data->scaleDraw->setLabelAlignment(alignment);
    layoutScale();
}

/*!
  \brief Change the rotation for the labels.
  See QwtScaleDraw::setLabelRotation().
  \sa QwtScaleDraw::setLabelRotation(), QwtScaleWidget::setLabelFlags()
*/
void QwtScaleWidget::setLabelRotation(double rotation)
{
    d_data->scaleDraw->setLabelRotation(rotation);
    layoutScale();
}

/*!
  \brief Set a scale draw
  sd has to be created with new and will be deleted in
  QwtScaleWidget::~QwtScale or the next call of QwtScaleWidget::setScaleDraw.
*/
void QwtScaleWidget::setScaleDraw(QwtScaleDraw *sd)
{
    if ( sd == NULL || sd == d_data->scaleDraw )
        return;

    if ( d_data->scaleDraw )
        sd->setAlignment(d_data->scaleDraw->alignment());

    delete d_data->scaleDraw;
    d_data->scaleDraw = sd;

    layoutScale();
}

326
/*!
pixhawk's avatar
pixhawk committed
327 328 329
    scaleDraw of this scale
    \sa QwtScaleDraw::setScaleDraw
*/
330 331 332
const QwtScaleDraw *QwtScaleWidget::scaleDraw() const
{
    return d_data->scaleDraw;
pixhawk's avatar
pixhawk committed
333 334
}

335
/*!
pixhawk's avatar
pixhawk committed
336 337 338
    scaleDraw of this scale
    \sa QwtScaleDraw::setScaleDraw
*/
339 340 341
QwtScaleDraw *QwtScaleWidget::scaleDraw()
{
    return d_data->scaleDraw;
pixhawk's avatar
pixhawk committed
342 343
}

344 345
/*!
    \return title
pixhawk's avatar
pixhawk committed
346 347
    \sa QwtScaleWidget::setTitle
*/
348
QwtText QwtScaleWidget::title() const
pixhawk's avatar
pixhawk committed
349 350 351 352
{
    return d_data->title;
}

353 354
/*!
    \return start border distance
pixhawk's avatar
pixhawk committed
355 356
    \sa QwtScaleWidget::setBorderDist
*/
357 358 359 360
int QwtScaleWidget::startBorderDist() const
{
    return d_data->borderDist[0];
}
pixhawk's avatar
pixhawk committed
361

362 363
/*!
    \return end border distance
pixhawk's avatar
pixhawk committed
364 365
    \sa QwtScaleWidget::setBorderDist
*/
366 367 368
int QwtScaleWidget::endBorderDist() const
{
    return d_data->borderDist[1];
pixhawk's avatar
pixhawk committed
369 370
}

371
/*!
pixhawk's avatar
pixhawk committed
372 373 374
    \return margin
    \sa QwtScaleWidget::setMargin
*/
375 376 377
int QwtScaleWidget::margin() const
{
    return d_data->margin;
pixhawk's avatar
pixhawk committed
378 379
}

380
/*!
pixhawk's avatar
pixhawk committed
381 382 383
    \return distance between scale and title
    \sa QwtScaleWidget::setMargin
*/
384 385 386
int QwtScaleWidget::spacing() const
{
    return d_data->spacing;
pixhawk's avatar
pixhawk committed
387 388
}

389
/*!
pixhawk's avatar
pixhawk committed
390 391 392 393 394 395
    \return Scale pen width
    \sa QwtScaleWidget::setPenWidth
*/
int QwtScaleWidget::penWidth() const
{
    return d_data->penWidth;
396
}
pixhawk's avatar
pixhawk committed
397 398 399 400 401 402
/*!
  \brief paintEvent
*/
void QwtScaleWidget::paintEvent(QPaintEvent *e)
{
    const QRect &ur = e->rect();
403
    if ( ur.isValid() ) {
pixhawk's avatar
pixhawk committed
404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423
#if QT_VERSION < 0x040000
        QwtPaintBuffer paintBuffer(this, ur);
        draw(paintBuffer.painter());
#else
        QPainter painter(this);
        draw(&painter);
#endif
    }
}

/*!
  \brief draw the scale
*/
void QwtScaleWidget::draw(QPainter *painter) const
{
    painter->save();

    QPen scalePen = painter->pen();
    scalePen.setWidth(d_data->penWidth);
    painter->setPen(scalePen);
424

pixhawk's avatar
pixhawk committed
425 426 427 428 429 430 431 432
#if QT_VERSION < 0x040000
    d_data->scaleDraw->draw(painter, colorGroup());
#else
    d_data->scaleDraw->draw(painter, palette());
#endif
    painter->restore();

    if ( d_data->colorBar.isEnabled && d_data->colorBar.width > 0 &&
433
            d_data->colorBar.interval.isValid() ) {
pixhawk's avatar
pixhawk committed
434 435 436 437
        drawColorBar(painter, colorBarRect(rect()));
    }

    QRect r = rect();
438
    if ( d_data->scaleDraw->orientation() == Qt::Horizontal ) {
pixhawk's avatar
pixhawk committed
439 440
        r.setLeft(r.left() + d_data->borderDist[0]);
        r.setWidth(r.width() - d_data->borderDist[1]);
441
    } else {
pixhawk's avatar
pixhawk committed
442 443 444 445
        r.setTop(r.top() + d_data->borderDist[0]);
        r.setHeight(r.height() - d_data->borderDist[1]);
    }

446
    if ( !d_data->title.isEmpty() ) {
pixhawk's avatar
pixhawk committed
447
        QRect tr = r;
448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464
        switch(d_data->scaleDraw->alignment()) {
        case QwtScaleDraw::LeftScale:
            tr.setRight( r.right() - d_data->titleOffset );
            break;

        case QwtScaleDraw::RightScale:
            tr.setLeft( r.left() + d_data->titleOffset );
            break;

        case QwtScaleDraw::BottomScale:
            tr.setTop( r.top() + d_data->titleOffset );
            break;

        case QwtScaleDraw::TopScale:
        default:
            tr.setBottom( r.bottom() - d_data->titleOffset );
            break;
pixhawk's avatar
pixhawk committed
465 466 467 468 469 470 471 472 473 474
        }

        drawTitle(painter, d_data->scaleDraw->alignment(), tr);
    }
}

QRect QwtScaleWidget::colorBarRect(const QRect& rect) const
{
    QRect cr = rect;

475
    if ( d_data->scaleDraw->orientation() == Qt::Horizontal ) {
pixhawk's avatar
pixhawk committed
476 477
        cr.setLeft(cr.left() + d_data->borderDist[0]);
        cr.setWidth(cr.width() - d_data->borderDist[1] + 1);
478
    } else {
pixhawk's avatar
pixhawk committed
479 480 481 482
        cr.setTop(cr.top() + d_data->borderDist[0]);
        cr.setHeight(cr.height() - d_data->borderDist[1] + 1);
    }

483 484 485 486 487 488 489
    switch(d_data->scaleDraw->alignment()) {
    case QwtScaleDraw::LeftScale: {
        cr.setLeft( cr.right() - d_data->spacing
                    - d_data->colorBar.width + 1 );
        cr.setWidth(d_data->colorBar.width);
        break;
    }
pixhawk's avatar
pixhawk committed
490

491 492 493 494 495
    case QwtScaleDraw::RightScale: {
        cr.setLeft( cr.left() + d_data->spacing );
        cr.setWidth(d_data->colorBar.width);
        break;
    }
pixhawk's avatar
pixhawk committed
496

497 498 499 500 501
    case QwtScaleDraw::BottomScale: {
        cr.setTop( cr.top() + d_data->spacing );
        cr.setHeight(d_data->colorBar.width);
        break;
    }
pixhawk's avatar
pixhawk committed
502

503 504 505 506 507 508
    case QwtScaleDraw::TopScale: {
        cr.setTop( cr.bottom() - d_data->spacing
                   - d_data->colorBar.width + 1 );
        cr.setHeight(d_data->colorBar.width);
        break;
    }
pixhawk's avatar
pixhawk committed
509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542
    }

    return cr;
}

/*!
  \brief resizeEvent
*/
void QwtScaleWidget::resizeEvent(QResizeEvent *)
{
    layoutScale(false);
}

//! Recalculate the scale's geometry and layout based on
//  the current rect and fonts.
//  \param update_geometry   notify the layout system and call update
//         to redraw the scale

void QwtScaleWidget::layoutScale( bool update_geometry )
{
    int bd0, bd1;
    getBorderDistHint(bd0, bd1);
    if ( d_data->borderDist[0] > bd0 )
        bd0 = d_data->borderDist[0];
    if ( d_data->borderDist[1] > bd1 )
        bd1 = d_data->borderDist[1];

    int colorBarWidth = 0;
    if ( d_data->colorBar.isEnabled && d_data->colorBar.interval.isValid() )
        colorBarWidth = d_data->colorBar.width + d_data->spacing;

    const QRect r = rect();
    int x, y, length;

543
    if ( d_data->scaleDraw->orientation() == Qt::Vertical ) {
pixhawk's avatar
pixhawk committed
544 545 546 547 548 549 550
        y = r.top() + bd0;
        length = r.height() - (bd0 + bd1);

        if ( d_data->scaleDraw->alignment() == QwtScaleDraw::LeftScale )
            x = r.right() - d_data->margin - colorBarWidth;
        else
            x = r.left() + d_data->margin + colorBarWidth;
551 552
    } else {
        x = r.left() + bd0;
pixhawk's avatar
pixhawk committed
553 554 555 556 557 558 559 560 561 562 563 564
        length = r.width() - (bd0 + bd1);

        if ( d_data->scaleDraw->alignment() == QwtScaleDraw::BottomScale )
            y = r.top() + d_data->margin + colorBarWidth;
        else
            y = r.bottom() - d_data->margin - colorBarWidth;
    }

    d_data->scaleDraw->move(x, y);
    d_data->scaleDraw->setLength(length);

    d_data->titleOffset = d_data->margin + d_data->spacing +
565 566
                          colorBarWidth +
                          d_data->scaleDraw->extent(QPen(Qt::black, d_data->penWidth), font());
pixhawk's avatar
pixhawk committed
567

568 569 570
    if ( update_geometry ) {
        updateGeometry();
        update();
pixhawk's avatar
pixhawk committed
571 572 573 574 575 576 577 578 579 580
    }
}

void QwtScaleWidget::drawColorBar(QPainter *painter, const QRect& rect) const
{
    if ( !d_data->colorBar.interval.isValid() )
        return;

    const QwtScaleDraw* sd = d_data->scaleDraw;

581 582 583
    QwtPainter::drawColorBar(painter, *d_data->colorBar.colorMap,
                             d_data->colorBar.interval.normalized(), sd->map(),
                             sd->orientation(), rect);
pixhawk's avatar
pixhawk committed
584 585 586 587 588 589 590 591 592 593
}

/*!
  Rotate and paint a title according to its position into a given rectangle.
  \param painter Painter
  \param align Alignment
  \param rect Bounding rectangle
*/

void QwtScaleWidget::drawTitle(QPainter *painter,
594
                               QwtScaleDraw::Alignment align, const QRect &rect) const
pixhawk's avatar
pixhawk committed
595 596 597
{
    QRect r;
    double angle;
598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622
    int flags = d_data->title.renderFlags() &
                ~(Qt::AlignTop | Qt::AlignBottom | Qt::AlignVCenter);

    switch(align) {
    case QwtScaleDraw::LeftScale:
        flags |= Qt::AlignTop;
        angle = -90.0;
        r.setRect(rect.left(), rect.bottom(), rect.height(), rect.width());
        break;
    case QwtScaleDraw::RightScale:
        flags |= Qt::AlignTop;
        angle = 90.0;
        r.setRect(rect.right(), rect.top(), rect.height(), rect.width());
        break;
    case QwtScaleDraw::TopScale:
        flags |= Qt::AlignTop;
        angle = 0.0;
        r = rect;
        break;
    case QwtScaleDraw::BottomScale:
    default:
        flags |= Qt::AlignBottom;
        angle = 0.0;
        r = rect;
        break;
pixhawk's avatar
pixhawk committed
623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679
    }

    painter->save();
    painter->setFont(font());
#if QT_VERSION < 0x040000
    painter->setPen(colorGroup().color(QColorGroup::Text));
#else
    painter->setPen(palette().color(QPalette::Text));
#endif

    painter->translate(r.x(), r.y());
    if (angle != 0.0)
        painter->rotate(angle);

    QwtText title = d_data->title;
    title.setRenderFlags(flags);
    title.draw(painter, QRect(0, 0, r.width(), r.height()));

    painter->restore();
}

/*!
  \brief Notify a change of the scale

  This virtual function can be overloaded by derived
  classes. The default implementation updates the geometry
  and repaints the widget.
*/

void QwtScaleWidget::scaleChange()
{
    layoutScale();
}

/*!
  \return a size hint
*/
QSize QwtScaleWidget::sizeHint() const
{
    return minimumSizeHint();
}

/*!
  \return a minimum size hint
*/
QSize QwtScaleWidget::minimumSizeHint() const
{
    const Qt::Orientation o = d_data->scaleDraw->orientation();

    // Border Distance cannot be less than the scale borderDistHint
    // Note, the borderDistHint is already included in minHeight/minWidth
    int length = 0;
    int mbd1, mbd2;
    getBorderDistHint(mbd1, mbd2);
    length += qwtMax( 0, d_data->borderDist[0] - mbd1 );
    length += qwtMax( 0, d_data->borderDist[1] - mbd2 );
    length += d_data->scaleDraw->minLength(
680
                  QPen(Qt::black, d_data->penWidth), font());
pixhawk's avatar
pixhawk committed
681 682

    int dim = dimForLength(length, font());
683
    if ( length < dim ) {
pixhawk's avatar
pixhawk committed
684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719
        // compensate for long titles
        length = dim;
        dim = dimForLength(length, font());
    }

    QSize size(length + 2, dim);
    if ( o == Qt::Vertical )
        size.transpose();

    return size;
}

/*!
  \brief Find the height of the title for a given width.
  \param width Width
  \return height Height
 */

int QwtScaleWidget::titleHeightForWidth(int width) const
{
    return d_data->title.heightForWidth(width, font());
}

/*!
  \brief Find the minimum dimension for a given length.
         dim is the height, length the width seen in
         direction of the title.
  \param length width for horizontal, height for vertical scales
  \param scaleFont Font of the scale
  \return height for horizontal, width for vertical scales
*/

int QwtScaleWidget::dimForLength(int length, const QFont &scaleFont) const
{
    int dim = d_data->margin;
    dim += d_data->scaleDraw->extent(
720
               QPen(Qt::black, d_data->penWidth), scaleFont);
pixhawk's avatar
pixhawk committed
721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755

    if ( !d_data->title.isEmpty() )
        dim += titleHeightForWidth(length) + d_data->spacing;

    if ( d_data->colorBar.isEnabled && d_data->colorBar.interval.isValid() )
        dim += d_data->colorBar.width + d_data->spacing;

    return dim;
}

/*!
  \brief Calculate a hint for the border distances.

  This member function calculates the distance
  of the scale's endpoints from the widget borders which
  is required for the mark labels to fit into the widget.
  The maximum of this distance an the minimum border distance
  is returned.

  \warning
  <ul> <li>The minimum border distance depends on the font.</ul>
  \sa setMinBorderDist(), getMinBorderDist(), setBorderDist()
*/
void QwtScaleWidget::getBorderDistHint(int &start, int &end) const
{
    d_data->scaleDraw->getBorderDistHint(font(), start, end);

    if ( start < d_data->minBorderDist[0] )
        start = d_data->minBorderDist[0];

    if ( end < d_data->minBorderDist[1] )
        end = d_data->minBorderDist[1];
}

/*!
756
  Set a minimum value for the distances of the scale's endpoints from
pixhawk's avatar
pixhawk committed
757
  the widget borders. This is useful to avoid that the scales
758
  are "jumping", when the tick labels or their positions change
pixhawk's avatar
pixhawk committed
759 760 761 762 763 764 765 766 767 768 769
  often.

  \sa getMinBorderDist(), getBorderDistHint()
*/
void QwtScaleWidget::setMinBorderDist(int start, int end)
{
    d_data->minBorderDist[0] = start;
    d_data->minBorderDist[1] = end;
}

/*!
770
  Get the minimum value for the distances of the scale's endpoints from
pixhawk's avatar
pixhawk committed
771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814
  the widget borders.

  \sa setMinBorderDist(), getBorderDistHint()
*/
void QwtScaleWidget::getMinBorderDist(int &start, int &end) const
{
    start = d_data->minBorderDist[0];
    end = d_data->minBorderDist[1];
}

#if QT_VERSION < 0x040000

/*!
  \brief Notify a change of the font

  This virtual function may be overloaded by derived widgets.
  The default implementation resizes the scale and repaints
  the widget.
  \param oldFont Previous font
*/
void QwtScaleWidget::fontChange(const QFont &oldFont)
{
    QWidget::fontChange( oldFont );
    layoutScale();
}

#endif

/*!
  \brief Assign a scale division

  The scale division determines where to set the tick marks.

  \param transformation Transformation, needed to translate between
                        scale and pixal values
  \param scaleDiv Scale Division
  \sa For more information about scale divisions, see QwtScaleDiv.
*/
void QwtScaleWidget::setScaleDiv(
    QwtScaleTransformation *transformation,
    const QwtScaleDiv &scaleDiv)
{
    QwtScaleDraw *sd = d_data->scaleDraw;
    if (sd->scaleDiv() != scaleDiv ||
815
            sd->map().transformation()->type() != transformation->type() ) {
pixhawk's avatar
pixhawk committed
816 817 818 819 820
        sd->setTransformation(transformation);
        sd->setScaleDiv(scaleDiv);
        layoutScale();

        emit scaleDivChanged();
821
    } else
pixhawk's avatar
pixhawk committed
822 823 824 825 826
        delete transformation;
}

void QwtScaleWidget::setColorBarEnabled(bool on)
{
827
    if ( on != d_data->colorBar.isEnabled ) {
pixhawk's avatar
pixhawk committed
828 829 830 831 832 833 834 835 836 837 838 839 840
        d_data->colorBar.isEnabled = on;
        layoutScale();
    }
}

bool QwtScaleWidget::isColorBarEnabled() const
{
    return d_data->colorBar.isEnabled;
}


void QwtScaleWidget::setColorBarWidth(int width)
{
841
    if ( width != d_data->colorBar.width ) {
pixhawk's avatar
pixhawk committed
842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858
        d_data->colorBar.width = width;
        if ( isColorBarEnabled() )
            layoutScale();
    }
}

int QwtScaleWidget::colorBarWidth() const
{
    return d_data->colorBar.width;
}

QwtDoubleInterval QwtScaleWidget::colorBarInterval() const
{
    return d_data->colorBar.interval;
}

void QwtScaleWidget::setColorMap(const QwtDoubleInterval &interval,
859
                                 const QwtColorMap &colorMap)
pixhawk's avatar
pixhawk committed
860 861 862 863 864 865 866 867 868 869 870 871 872 873
{
    d_data->colorBar.interval = interval;

    delete d_data->colorBar.colorMap;
    d_data->colorBar.colorMap = colorMap.copy();

    if ( isColorBarEnabled() )
        layoutScale();
}

const QwtColorMap &QwtScaleWidget::colorMap() const
{
    return *d_data->colorBar.colorMap;
}