qwt_scale_widget.cpp
Go to the documentation of this file.
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 #include "qwt_scale_widget.h"
00011 #include "qwt_painter.h"
00012 #include "qwt_color_map.h"
00013 #include "qwt_scale_map.h"
00014 #include "qwt_math.h"
00015 #include "qwt_scale_div.h"
00016 #include "qwt_text.h"
00017 #include "qwt_scale_engine.h"
00018 #include <qpainter.h>
00019 #include <qevent.h>
00020 #include <qmath.h>
00021 #include <qstyle.h>
00022 #include <qstyleoption.h>
00023 
00024 class QwtScaleWidget::PrivateData
00025 {
00026 public:
00027     PrivateData():
00028         scaleDraw( NULL )
00029     {
00030         colorBar.colorMap = NULL;
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 
00046     int titleOffset;
00047     int spacing;
00048     QwtText title;
00049 
00050     QwtScaleWidget::LayoutFlags layoutFlags;
00051 
00052     struct t_colorBar
00053     {
00054         bool isEnabled;
00055         int width;
00056         QwtInterval interval;
00057         QwtColorMap *colorMap;
00058     } colorBar;
00059 };
00060 
00065 QwtScaleWidget::QwtScaleWidget( QWidget *parent ):
00066     QWidget( parent )
00067 {
00068     initScale( QwtScaleDraw::LeftScale );
00069 }
00070 
00076 QwtScaleWidget::QwtScaleWidget(
00077         QwtScaleDraw::Alignment align, QWidget *parent ):
00078     QWidget( parent )
00079 {
00080     initScale( align );
00081 }
00082 
00084 QwtScaleWidget::~QwtScaleWidget()
00085 {
00086     delete d_data;
00087 }
00088 
00090 void QwtScaleWidget::initScale( QwtScaleDraw::Alignment align )
00091 {
00092     d_data = new PrivateData;
00093 
00094     d_data->layoutFlags = 0;
00095     if ( align == QwtScaleDraw::RightScale )
00096         d_data->layoutFlags |= TitleInverted;
00097 
00098     d_data->borderDist[0] = 0;
00099     d_data->borderDist[1] = 0;
00100     d_data->minBorderDist[0] = 0;
00101     d_data->minBorderDist[1] = 0;
00102     d_data->margin = 4;
00103     d_data->titleOffset = 0;
00104     d_data->spacing = 2;
00105 
00106     d_data->scaleDraw = new QwtScaleDraw;
00107     d_data->scaleDraw->setAlignment( align );
00108     d_data->scaleDraw->setLength( 10 );
00109 
00110     d_data->scaleDraw->setScaleDiv(
00111         QwtLinearScaleEngine().divideScale( 0.0, 100.0, 10, 5 ) );
00112 
00113     d_data->colorBar.colorMap = new QwtLinearColorMap();
00114     d_data->colorBar.isEnabled = false;
00115     d_data->colorBar.width = 10;
00116 
00117     const int flags = Qt::AlignHCenter
00118         | Qt::TextExpandTabs | Qt::TextWordWrap;
00119     d_data->title.setRenderFlags( flags );
00120     d_data->title.setFont( font() );
00121 
00122     QSizePolicy policy( QSizePolicy::MinimumExpanding,
00123         QSizePolicy::Fixed );
00124     if ( d_data->scaleDraw->orientation() == Qt::Vertical )
00125         policy.transpose();
00126 
00127     setSizePolicy( policy );
00128 
00129     setAttribute( Qt::WA_WState_OwnSizePolicy, false );
00130 }
00131 
00140 void QwtScaleWidget::setLayoutFlag( LayoutFlag flag, bool on )
00141 {
00142     if ( ( ( d_data->layoutFlags & flag ) != 0 ) != on )
00143     {
00144         if ( on )
00145             d_data->layoutFlags |= flag;
00146         else
00147             d_data->layoutFlags &= ~flag;
00148     }
00149 }
00150 
00158 bool QwtScaleWidget::testLayoutFlag( LayoutFlag flag ) const
00159 {
00160     return ( d_data->layoutFlags & flag );
00161 }
00162 
00169 void QwtScaleWidget::setTitle( const QString &title )
00170 {
00171     if ( d_data->title.text() != title )
00172     {
00173         d_data->title.setText( title );
00174         layoutScale();
00175     }
00176 }
00177 
00187 void QwtScaleWidget::setTitle( const QwtText &title )
00188 {
00189     QwtText t = title;
00190     const int flags = title.renderFlags() & ~( Qt::AlignTop | Qt::AlignBottom );
00191     t.setRenderFlags( flags );
00192 
00193     if ( t != d_data->title )
00194     {
00195         d_data->title = t;
00196         layoutScale();
00197     }
00198 }
00199 
00206 void QwtScaleWidget::setAlignment( QwtScaleDraw::Alignment alignment )
00207 {
00208     if ( d_data->scaleDraw )
00209         d_data->scaleDraw->setAlignment( alignment );
00210 
00211     if ( !testAttribute( Qt::WA_WState_OwnSizePolicy ) )
00212     {
00213         QSizePolicy policy( QSizePolicy::MinimumExpanding,
00214             QSizePolicy::Fixed );
00215         if ( d_data->scaleDraw->orientation() == Qt::Vertical )
00216             policy.transpose();
00217 
00218         setSizePolicy( policy );
00219 
00220         setAttribute( Qt::WA_WState_OwnSizePolicy, false );
00221     }
00222 
00223     layoutScale();
00224 }
00225 
00226 
00231 QwtScaleDraw::Alignment QwtScaleWidget::alignment() const
00232 {
00233     if ( !scaleDraw() )
00234         return QwtScaleDraw::LeftScale;
00235 
00236     return scaleDraw()->alignment();
00237 }
00238 
00247 void QwtScaleWidget::setBorderDist( int dist1, int dist2 )
00248 {
00249     if ( dist1 != d_data->borderDist[0] || dist2 != d_data->borderDist[1] )
00250     {
00251         d_data->borderDist[0] = dist1;
00252         d_data->borderDist[1] = dist2;
00253         layoutScale();
00254     }
00255 }
00256 
00262 void QwtScaleWidget::setMargin( int margin )
00263 {
00264     margin = qMax( 0, margin );
00265     if ( margin != d_data->margin )
00266     {
00267         d_data->margin = margin;
00268         layoutScale();
00269     }
00270 }
00271 
00277 void QwtScaleWidget::setSpacing( int spacing )
00278 {
00279     spacing = qMax( 0, spacing );
00280     if ( spacing != d_data->spacing )
00281     {
00282         d_data->spacing = spacing;
00283         layoutScale();
00284     }
00285 }
00286 
00292 void QwtScaleWidget::setLabelAlignment( Qt::Alignment alignment )
00293 {
00294     d_data->scaleDraw->setLabelAlignment( alignment );
00295     layoutScale();
00296 }
00297 
00305 void QwtScaleWidget::setLabelRotation( double rotation )
00306 {
00307     d_data->scaleDraw->setLabelRotation( rotation );
00308     layoutScale();
00309 }
00310 
00322 void QwtScaleWidget::setScaleDraw( QwtScaleDraw *scaleDraw )
00323 {
00324     if ( ( scaleDraw == NULL ) || ( scaleDraw == d_data->scaleDraw ) )
00325         return;
00326 
00327     const QwtScaleDraw* sd = d_data->scaleDraw;
00328     if ( sd )
00329     {
00330         scaleDraw->setAlignment( sd->alignment() );
00331         scaleDraw->setScaleDiv( sd->scaleDiv() );
00332 
00333         QwtTransform *transform = NULL;
00334         if ( sd->scaleMap().transformation() )
00335             transform = sd->scaleMap().transformation()->copy();
00336 
00337         scaleDraw->setTransformation( transform );
00338     }
00339 
00340     delete d_data->scaleDraw;
00341     d_data->scaleDraw = scaleDraw;
00342 
00343     layoutScale();
00344 }
00345 
00350 const QwtScaleDraw *QwtScaleWidget::scaleDraw() const
00351 {
00352     return d_data->scaleDraw;
00353 }
00354 
00359 QwtScaleDraw *QwtScaleWidget::scaleDraw()
00360 {
00361     return d_data->scaleDraw;
00362 }
00363 
00368 QwtText QwtScaleWidget::title() const
00369 {
00370     return d_data->title;
00371 }
00372 
00377 int QwtScaleWidget::startBorderDist() const
00378 {
00379     return d_data->borderDist[0];
00380 }
00381 
00386 int QwtScaleWidget::endBorderDist() const
00387 {
00388     return d_data->borderDist[1];
00389 }
00390 
00395 int QwtScaleWidget::margin() const
00396 {
00397     return d_data->margin;
00398 }
00399 
00404 int QwtScaleWidget::spacing() const
00405 {
00406     return d_data->spacing;
00407 }
00408 
00412 void QwtScaleWidget::paintEvent( QPaintEvent *event )
00413 {
00414     QPainter painter( this );
00415     painter.setClipRegion( event->region() );
00416 
00417     QStyleOption opt;
00418     opt.init(this);
00419     style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this);
00420 
00421     draw( &painter );
00422 }
00423 
00427 void QwtScaleWidget::draw( QPainter *painter ) const
00428 {
00429     d_data->scaleDraw->draw( painter, palette() );
00430 
00431     if ( d_data->colorBar.isEnabled && d_data->colorBar.width > 0 &&
00432         d_data->colorBar.interval.isValid() )
00433     {
00434         drawColorBar( painter, colorBarRect( contentsRect() ) );
00435     }
00436 
00437     QRect r = contentsRect();
00438     if ( d_data->scaleDraw->orientation() == Qt::Horizontal )
00439     {
00440         r.setLeft( r.left() + d_data->borderDist[0] );
00441         r.setWidth( r.width() - d_data->borderDist[1] );
00442     }
00443     else
00444     {
00445         r.setTop( r.top() + d_data->borderDist[0] );
00446         r.setHeight( r.height() - d_data->borderDist[1] );
00447     }
00448 
00449     if ( !d_data->title.isEmpty() )
00450         drawTitle( painter, d_data->scaleDraw->alignment(), r );
00451 }
00452 
00459 QRectF QwtScaleWidget::colorBarRect( const QRectF& rect ) const
00460 {
00461     QRectF cr = rect;
00462 
00463     if ( d_data->scaleDraw->orientation() == Qt::Horizontal )
00464     {
00465         cr.setLeft( cr.left() + d_data->borderDist[0] );
00466         cr.setWidth( cr.width() - d_data->borderDist[1] + 1 );
00467     }
00468     else
00469     {
00470         cr.setTop( cr.top() + d_data->borderDist[0] );
00471         cr.setHeight( cr.height() - d_data->borderDist[1] + 1 );
00472     }
00473 
00474     switch ( d_data->scaleDraw->alignment() )
00475     {
00476         case QwtScaleDraw::LeftScale:
00477         {
00478             cr.setLeft( cr.right() - d_data->margin
00479                 - d_data->colorBar.width );
00480             cr.setWidth( d_data->colorBar.width );
00481             break;
00482         }
00483 
00484         case QwtScaleDraw::RightScale:
00485         {
00486             cr.setLeft( cr.left() + d_data->margin );
00487             cr.setWidth( d_data->colorBar.width );
00488             break;
00489         }
00490 
00491         case QwtScaleDraw::BottomScale:
00492         {
00493             cr.setTop( cr.top() + d_data->margin );
00494             cr.setHeight( d_data->colorBar.width );
00495             break;
00496         }
00497 
00498         case QwtScaleDraw::TopScale:
00499         {
00500             cr.setTop( cr.bottom() - d_data->margin
00501                 - d_data->colorBar.width );
00502             cr.setHeight( d_data->colorBar.width );
00503             break;
00504         }
00505     }
00506 
00507     return cr;
00508 }
00509 
00516 void QwtScaleWidget::changeEvent( QEvent *event )
00517 {
00518     if ( event->type() == QEvent::LocaleChange )
00519     {
00520         d_data->scaleDraw->invalidateCache();
00521     }
00522 
00523     QWidget::changeEvent( event );
00524 }
00525 
00530 void QwtScaleWidget::resizeEvent( QResizeEvent *event )
00531 {
00532     Q_UNUSED( event );
00533     layoutScale( false );
00534 }
00535 
00544 void QwtScaleWidget::layoutScale( bool update_geometry )
00545 {
00546     int bd0, bd1;
00547     getBorderDistHint( bd0, bd1 );
00548     if ( d_data->borderDist[0] > bd0 )
00549         bd0 = d_data->borderDist[0];
00550     if ( d_data->borderDist[1] > bd1 )
00551         bd1 = d_data->borderDist[1];
00552 
00553     int colorBarWidth = 0;
00554     if ( d_data->colorBar.isEnabled && d_data->colorBar.interval.isValid() )
00555         colorBarWidth = d_data->colorBar.width + d_data->spacing;
00556 
00557     const QRectF r = contentsRect();
00558     double x, y, length;
00559 
00560     if ( d_data->scaleDraw->orientation() == Qt::Vertical )
00561     {
00562         y = r.top() + bd0;
00563         length = r.height() - ( bd0 + bd1 );
00564 
00565         if ( d_data->scaleDraw->alignment() == QwtScaleDraw::LeftScale )
00566             x = r.right() - 1.0 - d_data->margin - colorBarWidth;
00567         else
00568             x = r.left() + d_data->margin + colorBarWidth;
00569     }
00570     else
00571     {
00572         x = r.left() + bd0;
00573         length = r.width() - ( bd0 + bd1 );
00574 
00575         if ( d_data->scaleDraw->alignment() == QwtScaleDraw::BottomScale )
00576             y = r.top() + d_data->margin + colorBarWidth;
00577         else
00578             y = r.bottom() - 1.0 - d_data->margin - colorBarWidth;
00579     }
00580 
00581     d_data->scaleDraw->move( x, y );
00582     d_data->scaleDraw->setLength( length );
00583 
00584     const int extent = qCeil( d_data->scaleDraw->extent( font() ) );
00585 
00586     d_data->titleOffset =
00587         d_data->margin + d_data->spacing + colorBarWidth + extent;
00588 
00589     if ( update_geometry )
00590     {
00591         updateGeometry();
00592         update();
00593     }
00594 }
00595 
00604 void QwtScaleWidget::drawColorBar( QPainter *painter, const QRectF& rect ) const
00605 {
00606     if ( !d_data->colorBar.interval.isValid() )
00607         return;
00608 
00609     const QwtScaleDraw* sd = d_data->scaleDraw;
00610 
00611     QwtPainter::drawColorBar( painter, *d_data->colorBar.colorMap,
00612         d_data->colorBar.interval.normalized(), sd->scaleMap(),
00613         sd->orientation(), rect );
00614 }
00615 
00624 void QwtScaleWidget::drawTitle( QPainter *painter,
00625     QwtScaleDraw::Alignment align, const QRectF &rect ) const
00626 {
00627     QRectF r = rect;
00628     double angle;
00629     int flags = d_data->title.renderFlags() &
00630         ~( Qt::AlignTop | Qt::AlignBottom | Qt::AlignVCenter );
00631 
00632     switch ( align )
00633     {
00634         case QwtScaleDraw::LeftScale:
00635             angle = -90.0;
00636             flags |= Qt::AlignTop;
00637             r.setRect( r.left(), r.bottom(),
00638                 r.height(), r.width() - d_data->titleOffset );
00639             break;
00640 
00641         case QwtScaleDraw::RightScale:
00642             angle = -90.0;
00643             flags |= Qt::AlignTop;
00644             r.setRect( r.left() + d_data->titleOffset, r.bottom(),
00645                 r.height(), r.width() - d_data->titleOffset );
00646             break;
00647 
00648         case QwtScaleDraw::BottomScale:
00649             angle = 0.0;
00650             flags |= Qt::AlignBottom;
00651             r.setTop( r.top() + d_data->titleOffset );
00652             break;
00653 
00654         case QwtScaleDraw::TopScale:
00655         default:
00656             angle = 0.0;
00657             flags |= Qt::AlignTop;
00658             r.setBottom( r.bottom() - d_data->titleOffset );
00659             break;
00660     }
00661 
00662     if ( d_data->layoutFlags & TitleInverted )
00663     {
00664         if ( align == QwtScaleDraw::LeftScale
00665             || align == QwtScaleDraw::RightScale )
00666         {
00667             angle = -angle;
00668             r.setRect( r.x() + r.height(), r.y() - r.width(),
00669                 r.width(), r.height() );
00670         }
00671     }
00672 
00673     painter->save();
00674     painter->setFont( font() );
00675     painter->setPen( palette().color( QPalette::Text ) );
00676 
00677     painter->translate( r.x(), r.y() );
00678     if ( angle != 0.0 )
00679         painter->rotate( angle );
00680 
00681     QwtText title = d_data->title;
00682     title.setRenderFlags( flags );
00683     title.draw( painter, QRectF( 0.0, 0.0, r.width(), r.height() ) );
00684 
00685     painter->restore();
00686 }
00687 
00696 void QwtScaleWidget::scaleChange()
00697 {
00698     layoutScale();
00699 }
00700 
00704 QSize QwtScaleWidget::sizeHint() const
00705 {
00706     return minimumSizeHint();
00707 }
00708 
00712 QSize QwtScaleWidget::minimumSizeHint() const
00713 {
00714     const Qt::Orientation o = d_data->scaleDraw->orientation();
00715 
00716     // Border Distance cannot be less than the scale borderDistHint
00717     // Note, the borderDistHint is already included in minHeight/minWidth
00718     int length = 0;
00719     int mbd1, mbd2;
00720     getBorderDistHint( mbd1, mbd2 );
00721     length += qMax( 0, d_data->borderDist[0] - mbd1 );
00722     length += qMax( 0, d_data->borderDist[1] - mbd2 );
00723     length += d_data->scaleDraw->minLength( font() );
00724 
00725     int dim = dimForLength( length, font() );
00726     if ( length < dim )
00727     {
00728         // compensate for long titles
00729         length = dim;
00730         dim = dimForLength( length, font() );
00731     }
00732 
00733     QSize size( length + 2, dim );
00734     if ( o == Qt::Vertical )
00735         size.transpose();
00736 
00737     int left, right, top, bottom;
00738     getContentsMargins( &left, &top, &right, &bottom );
00739     return size + QSize( left + right, top + bottom );
00740 }
00741 
00748 int QwtScaleWidget::titleHeightForWidth( int width ) const
00749 {
00750     return qCeil( d_data->title.heightForWidth( width, font() ) );
00751 }
00752 
00762 int QwtScaleWidget::dimForLength( int length, const QFont &scaleFont ) const
00763 {
00764     const int extent = qCeil( d_data->scaleDraw->extent( scaleFont ) );
00765 
00766     int dim = d_data->margin + extent + 1;
00767 
00768     if ( !d_data->title.isEmpty() )
00769         dim += titleHeightForWidth( length ) + d_data->spacing;
00770 
00771     if ( d_data->colorBar.isEnabled && d_data->colorBar.interval.isValid() )
00772         dim += d_data->colorBar.width + d_data->spacing;
00773 
00774     return dim;
00775 }
00776 
00795 void QwtScaleWidget::getBorderDistHint( int &start, int &end ) const
00796 {
00797     d_data->scaleDraw->getBorderDistHint( font(), start, end );
00798 
00799     if ( start < d_data->minBorderDist[0] )
00800         start = d_data->minBorderDist[0];
00801 
00802     if ( end < d_data->minBorderDist[1] )
00803         end = d_data->minBorderDist[1];
00804 }
00805 
00816 void QwtScaleWidget::setMinBorderDist( int start, int end )
00817 {
00818     d_data->minBorderDist[0] = start;
00819     d_data->minBorderDist[1] = end;
00820 }
00821 
00833 void QwtScaleWidget::getMinBorderDist( int &start, int &end ) const
00834 {
00835     start = d_data->minBorderDist[0];
00836     end = d_data->minBorderDist[1];
00837 }
00838 
00847 void QwtScaleWidget::setScaleDiv( const QwtScaleDiv &scaleDiv )
00848 {
00849     QwtScaleDraw *sd = d_data->scaleDraw;
00850     if ( sd->scaleDiv() != scaleDiv )
00851     {
00852         sd->setScaleDiv( scaleDiv );
00853         layoutScale();
00854 
00855         Q_EMIT scaleDivChanged();
00856     }
00857 }
00858 
00865 void QwtScaleWidget::setTransformation( QwtTransform *transformation )
00866 {
00867     d_data->scaleDraw->setTransformation( transformation );
00868     layoutScale();
00869 }
00870 
00875 void QwtScaleWidget::setColorBarEnabled( bool on )
00876 {
00877     if ( on != d_data->colorBar.isEnabled )
00878     {
00879         d_data->colorBar.isEnabled = on;
00880         layoutScale();
00881     }
00882 }
00883 
00888 bool QwtScaleWidget::isColorBarEnabled() const
00889 {
00890     return d_data->colorBar.isEnabled;
00891 }
00892 
00899 void QwtScaleWidget::setColorBarWidth( int width )
00900 {
00901     if ( width != d_data->colorBar.width )
00902     {
00903         d_data->colorBar.width = width;
00904         if ( isColorBarEnabled() )
00905             layoutScale();
00906     }
00907 }
00908 
00913 int QwtScaleWidget::colorBarWidth() const
00914 {
00915     return d_data->colorBar.width;
00916 }
00917 
00922 QwtInterval QwtScaleWidget::colorBarInterval() const
00923 {
00924     return d_data->colorBar.interval;
00925 }
00926 
00936 void QwtScaleWidget::setColorMap(
00937     const QwtInterval &interval, QwtColorMap *colorMap )
00938 {
00939     d_data->colorBar.interval = interval;
00940 
00941     if ( colorMap != d_data->colorBar.colorMap )
00942     {
00943         delete d_data->colorBar.colorMap;
00944         d_data->colorBar.colorMap = colorMap;
00945     }
00946 
00947     if ( isColorBarEnabled() )
00948         layoutScale();
00949 }
00950 
00955 const QwtColorMap *QwtScaleWidget::colorMap() const
00956 {
00957     return d_data->colorBar.colorMap;
00958 }


plotjuggler
Author(s): Davide Faconti
autogenerated on Fri Sep 1 2017 02:41:56