Changeset 8127 in ntrip for trunk/BNC/qwt/qwt_plot_layout.cpp


Ignore:
Timestamp:
May 10, 2017, 3:20:54 PM (7 years ago)
Author:
stoecker
Message:

update qwt and qwtpolar, many QT5 fixes (unfinished)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/BNC/qwt/qwt_plot_layout.cpp

    r4271 r8127  
    1111#include "qwt_text.h"
    1212#include "qwt_text_label.h"
    13 #include "qwt_plot_canvas.h"
    1413#include "qwt_scale_widget.h"
    15 #include "qwt_legend.h"
     14#include "qwt_abstract_legend.h"
    1615#include <qscrollbar.h>
    1716#include <qmath.h>
     
    2524    {
    2625        int frameWidth;
    27         int vScrollBarWidth;
    28         int hScrollBarHeight;
     26        int hScrollExtent;
     27        int vScrollExtent;
    2928        QSize hint;
    3029    } legend;
     
    3534        int frameWidth;
    3635    } title;
     36
     37    struct t_footerData
     38    {
     39        QwtText text;
     40        int frameWidth;
     41    } footer;
    3742
    3843    struct t_scaleData
     
    4449        int end;
    4550        int baseLineOffset;
    46         int tickOffset;
     51        double tickOffset;
    4752        int dimWithoutTitle;
    4853    } scale[QwtPlot::axisCnt];
     
    5055    struct t_canvasData
    5156    {
    52         int frameWidth;
     57        int contentsMargins[ QwtPlot::axisCnt ];
     58
    5359    } canvas;
    5460};
     
    5763  Extract all layout relevant data from the plot components
    5864*/
    59 
    6065void QwtPlotLayout::LayoutData::init( const QwtPlot *plot, const QRectF &rect )
    6166{
    6267    // legend
    6368
    64     if ( plot->plotLayout()->legendPosition() != QwtPlot::ExternalLegend
    65         && plot->legend() )
     69    if ( plot->legend() )
    6670    {
    6771        legend.frameWidth = plot->legend()->frameWidth();
    68         legend.vScrollBarWidth =
    69             plot->legend()->verticalScrollBar()->sizeHint().width();
    70         legend.hScrollBarHeight =
    71             plot->legend()->horizontalScrollBar()->sizeHint().height();
     72        legend.hScrollExtent =
     73            plot->legend()->scrollExtent( Qt::Horizontal );
     74        legend.vScrollExtent =
     75            plot->legend()->scrollExtent( Qt::Vertical );
    7276
    7377        const QSize hint = plot->legend()->sizeHint();
    7478
    75         int w = qMin( hint.width(), qFloor( rect.width() ) );
     79        const int w = qMin( hint.width(), qFloor( rect.width() ) );
     80
    7681        int h = plot->legend()->heightForWidth( w );
    77         if ( h == 0 )
     82        if ( h <= 0 )
    7883            h = hint.height();
    79 
    80         if ( h > rect.height() )
    81             w += legend.vScrollBarWidth;
    8284
    8385        legend.hint = QSize( w, h );
     
    99101    }
    100102
     103    // footer
     104
     105    footer.frameWidth = 0;
     106    footer.text = QwtText();
     107
     108    if ( plot->footerLabel() )
     109    {
     110        const QwtTextLabel *label = plot->footerLabel();
     111        footer.text = label->text();
     112        if ( !( footer.text.testPaintAttribute( QwtText::PaintUsingTextFont ) ) )
     113            footer.text.setFont( label->font() );
     114
     115        footer.frameWidth = plot->footerLabel()->frameWidth();
     116    }
     117
    101118    // scales
    102119
     
    140157            scale[axis].end = 0;
    141158            scale[axis].baseLineOffset = 0;
    142             scale[axis].tickOffset = 0;
     159            scale[axis].tickOffset = 0.0;
    143160            scale[axis].dimWithoutTitle = 0;
    144161        }
     
    147164    // canvas
    148165
    149     canvas.frameWidth = plot->canvas()->frameWidth();
     166    plot->canvas()->getContentsMargins(
     167        &canvas.contentsMargins[ QwtPlot::yLeft ],
     168        &canvas.contentsMargins[ QwtPlot::xTop ],
     169        &canvas.contentsMargins[ QwtPlot::yRight ],
     170        &canvas.contentsMargins[ QwtPlot::xBottom ] );
    150171}
    151172
     
    154175public:
    155176    PrivateData():
    156         spacing( 5 ),
    157         alignCanvasToScales( false )
     177        spacing( 5 )
    158178    {
    159179    }
    160180
    161181    QRectF titleRect;
     182    QRectF footerRect;
    162183    QRectF legendRect;
    163184    QRectF scaleRect[QwtPlot::axisCnt];
     
    170191    unsigned int spacing;
    171192    unsigned int canvasMargin[QwtPlot::axisCnt];
    172     bool alignCanvasToScales;
     193    bool alignCanvasToScales[QwtPlot::axisCnt];
    173194};
    174195
     
    183204    setLegendPosition( QwtPlot::BottomLegend );
    184205    setCanvasMargin( 4 );
     206    setAlignCanvasToScales( false );
    185207
    186208    invalidate();
     
    203225  \sa canvasMargin()
    204226
    205   \warning The margin will have no effect when alignCanvasToScales is true
     227  \warning The margin will have no effect when alignCanvasToScale() is true
    206228*/
    207229
     
    221243
    222244/*!
     245    \param axisId Axis index
    223246    \return Margin around the scale tick borders
    224247    \sa setCanvasMargin()
    225248*/
    226 int QwtPlotLayout::canvasMargin( int axis ) const
    227 {
    228     if ( axis < 0 || axis >= QwtPlot::axisCnt )
     249int QwtPlotLayout::canvasMargin( int axisId ) const
     250{
     251    if ( axisId < 0 || axisId >= QwtPlot::axisCnt )
    229252        return 0;
    230253
    231     return d_data->canvasMargin[axis];
     254    return d_data->canvasMargin[axisId];
     255}
     256
     257/*!
     258  \brief Set the align-canvas-to-axis-scales flag for all axes
     259
     260  \param on True/False
     261  \sa setAlignCanvasToScale(), alignCanvasToScale()
     262*/
     263void QwtPlotLayout::setAlignCanvasToScales( bool on )
     264{
     265    for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
     266        d_data->alignCanvasToScales[axis] = on;
    232267}
    233268
    234269/*!
    235270  Change the align-canvas-to-axis-scales setting. The canvas may:
     271
    236272  - extend beyond the axis scale ends to maximize its size,
    237273  - align with the axis scale ends to control its size.
    238274
    239   \param alignCanvasToScales New align-canvas-to-axis-scales setting
    240 
    241   \sa setCanvasMargin()
    242   \note In this context the term 'scale' means the backbone of a scale.
    243   \warning In case of alignCanvasToScales == true canvasMargin will have
    244            no effect
    245 */
    246 void QwtPlotLayout::setAlignCanvasToScales( bool alignCanvasToScales )
    247 {
    248     d_data->alignCanvasToScales = alignCanvasToScales;
     275  The axisId parameter is somehow confusing as it identifies a border
     276  of the plot and not the axes, that are aligned. F.e when QwtPlot::yLeft
     277  is set, the left end of the the x-axes ( QwtPlot::xTop, QwtPlot::xBottom )
     278  is aligned.
     279
     280  \param axisId Axis index
     281  \param on New align-canvas-to-axis-scales setting
     282
     283  \sa setCanvasMargin(), alignCanvasToScale(), setAlignCanvasToScales()
     284  \warning In case of on == true canvasMargin() will have no effect
     285*/
     286void QwtPlotLayout::setAlignCanvasToScale( int axisId, bool on )
     287{
     288    if ( axisId >= 0 && axisId < QwtPlot::axisCnt )
     289        d_data->alignCanvasToScales[axisId] = on;
    249290}
    250291
     
    254295  - align with the axis scale ends to control its size.
    255296
     297  \param axisId Axis index
    256298  \return align-canvas-to-axis-scales setting
    257   \sa setAlignCanvasToScales, setCanvasMargin()
    258   \note In this context the term 'scale' means the backbone of a scale.
    259 */
    260 bool QwtPlotLayout::alignCanvasToScales() const
    261 {
    262     return d_data->alignCanvasToScales;
     299  \sa setAlignCanvasToScale(), setAlignCanvasToScale(), setCanvasMargin()
     300*/
     301bool QwtPlotLayout::alignCanvasToScale( int axisId ) const
     302{
     303    if ( axisId < 0 || axisId >= QwtPlot::axisCnt )
     304        return false;
     305
     306    return d_data->alignCanvasToScales[ axisId ];
    263307}
    264308
     
    267311  between the plot components.
    268312
    269   \param spacing new spacing
    270   \sa setMargin(), spacing()
     313  \param spacing New spacing
     314  \sa setCanvasMargin(), spacing()
    271315*/
    272316void QwtPlotLayout::setSpacing( int spacing )
     
    276320
    277321/*!
    278   \return spacing
     322  \return Spacing
    279323  \sa margin(), setSpacing()
    280324*/
     
    287331  \brief Specify the position of the legend
    288332  \param pos The legend's position.
    289   \param ratio Ratio between legend and the bounding rect
    290                of title, canvas and axes. The legend will be shrinked
     333  \param ratio Ratio between legend and the bounding rectangle
     334               of title, footer, canvas and axes. The legend will be shrunk
    291335               if it would need more space than the given ratio.
    292336               The ratio is limited to ]0.0 .. 1.0]. In case of <= 0.0
     
    318362            d_data->legendPos = pos;
    319363            break;
    320         case QwtPlot::ExternalLegend:
    321             d_data->legendRatio = ratio; // meaningless
    322             d_data->legendPos = pos;
    323364        default:
    324365            break;
     
    351392/*!
    352393  Specify the relative size of the legend in the plot
    353   \param ratio Ratio between legend and the bounding rect
    354                of title, canvas and axes. The legend will be shrinked
     394  \param ratio Ratio between legend and the bounding rectangle
     395               of title, footer, canvas and axes. The legend will be shrunk
    355396               if it would need more space than the given ratio.
    356397               The ratio is limited to ]0.0 .. 1.0]. In case of <= 0.0
     
    373414
    374415/*!
     416  \brief Set the geometry for the title
     417
     418  This method is intended to be used from derived layouts
     419  overloading activate()
     420
     421  \sa titleRect(), activate()
     422 */
     423void QwtPlotLayout::setTitleRect( const QRectF &rect )
     424{
     425    d_data->titleRect = rect;
     426}
     427
     428/*!
    375429  \return Geometry for the title
    376430  \sa activate(), invalidate()
    377431*/
    378 
    379 const QRectF &QwtPlotLayout::titleRect() const
     432QRectF QwtPlotLayout::titleRect() const
    380433{
    381434    return d_data->titleRect;
     435}
     436
     437/*!
     438  \brief Set the geometry for the footer
     439
     440  This method is intended to be used from derived layouts
     441  overloading activate()
     442
     443  \sa footerRect(), activate()
     444 */
     445void QwtPlotLayout::setFooterRect( const QRectF &rect )
     446{
     447    d_data->footerRect = rect;
     448}
     449
     450/*!
     451  \return Geometry for the footer
     452  \sa activate(), invalidate()
     453*/
     454QRectF QwtPlotLayout::footerRect() const
     455{
     456    return d_data->footerRect;
     457}
     458
     459/*!
     460  \brief Set the geometry for the legend
     461
     462  This method is intended to be used from derived layouts
     463  overloading activate()
     464
     465  \param rect Rectangle for the legend
     466
     467  \sa legendRect(), activate()
     468 */
     469void QwtPlotLayout::setLegendRect( const QRectF &rect )
     470{
     471    d_data->legendRect = rect;
    382472}
    383473
     
    386476  \sa activate(), invalidate()
    387477*/
    388 
    389 const QRectF &QwtPlotLayout::legendRect() const
     478QRectF QwtPlotLayout::legendRect() const
    390479{
    391480    return d_data->legendRect;
     481}
     482
     483/*!
     484  \brief Set the geometry for an axis
     485
     486  This method is intended to be used from derived layouts
     487  overloading activate()
     488
     489  \param axis Axis index
     490  \param rect Rectangle for the scale
     491
     492  \sa scaleRect(), activate()
     493 */
     494void QwtPlotLayout::setScaleRect( int axis, const QRectF &rect )
     495{
     496    if ( axis >= 0 && axis < QwtPlot::axisCnt )
     497        d_data->scaleRect[axis] = rect;
    392498}
    393499
     
    397503  \sa activate(), invalidate()
    398504*/
    399 
    400 const QRectF &QwtPlotLayout::scaleRect( int axis ) const
     505QRectF QwtPlotLayout::scaleRect( int axis ) const
    401506{
    402507    if ( axis < 0 || axis >= QwtPlot::axisCnt )
     
    409514
    410515/*!
     516  \brief Set the geometry for the canvas
     517
     518  This method is intended to be used from derived layouts
     519  overloading activate()
     520
     521  \sa canvasRect(), activate()
     522 */
     523void QwtPlotLayout::setCanvasRect( const QRectF &rect )
     524{
     525    d_data->canvasRect = rect;
     526}
     527
     528/*!
    411529  \return Geometry for the canvas
    412530  \sa activate(), invalidate()
    413531*/
    414 
    415 const QRectF &QwtPlotLayout::canvasRect() const
     532QRectF QwtPlotLayout::canvasRect() const
    416533{
    417534    return d_data->canvasRect;
     
    424541void QwtPlotLayout::invalidate()
    425542{
    426     d_data->titleRect = d_data->legendRect = d_data->canvasRect = QRect();
     543    d_data->titleRect = d_data->footerRect
     544        = d_data->legendRect = d_data->canvasRect = QRect();
     545
    427546    for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
    428547        d_data->scaleRect[axis] = QRect();
     
    430549
    431550/*!
    432   \brief Return a minimum size hint
     551  \return Minimum size hint
     552  \param plot Plot widget
     553
    433554  \sa QwtPlot::minimumSizeHint()
    434555*/
     
    453574    int canvasBorder[QwtPlot::axisCnt];
    454575
     576    int fw;
     577    plot->canvas()->getContentsMargins( &fw, NULL, NULL, NULL );
     578
    455579    int axis;
    456580    for ( axis = 0; axis < QwtPlot::axisCnt; axis++ )
     
    467591            sd.tickOffset = scl->margin();
    468592            if ( scl->scaleDraw()->hasComponent( QwtAbstractScaleDraw::Ticks ) )
    469                 sd.tickOffset += scl->scaleDraw()->maxTickLength();
    470         }
    471 
    472         canvasBorder[axis] = plot->canvas()->frameWidth() +
    473             d_data->canvasMargin[axis] + 1;
    474 
     593                sd.tickOffset += qCeil( scl->scaleDraw()->maxTickLength() );
     594        }
     595
     596        canvasBorder[axis] = fw + d_data->canvasMargin[axis] + 1;
    475597    }
    476598
     
    524646    }
    525647
    526     const QwtPlotCanvas *canvas = plot->canvas();
     648    const QWidget *canvas = plot->canvas();
     649
     650    int left, top, right, bottom;
     651    canvas->getContentsMargins( &left, &top, &right, &bottom );
     652
    527653    const QSize minCanvasSize = canvas->minimumSize();
    528654
    529655    int w = scaleData[QwtPlot::yLeft].w + scaleData[QwtPlot::yRight].w;
    530656    int cw = qMax( scaleData[QwtPlot::xBottom].w, scaleData[QwtPlot::xTop].w )
    531         + 2 * ( canvas->frameWidth() + 1 );
     657        + left + 1 + right + 1;
    532658    w += qMax( cw, minCanvasSize.width() );
    533659
    534660    int h = scaleData[QwtPlot::xBottom].h + scaleData[QwtPlot::xTop].h;
    535661    int ch = qMax( scaleData[QwtPlot::yLeft].h, scaleData[QwtPlot::yRight].h )
    536         + 2 * ( canvas->frameWidth() + 1 );
     662        + top + 1 + bottom + 1;
    537663    h += qMax( ch, minCanvasSize.height() );
    538664
    539     const QwtTextLabel *title = plot->titleLabel();
    540     if ( title && !title->text().isEmpty() )
    541     {
    542         // If only QwtPlot::yLeft or QwtPlot::yRight is showing,
    543         // we center on the plot canvas.
    544         const bool centerOnCanvas = !( plot->axisEnabled( QwtPlot::yLeft )
    545             && plot->axisEnabled( QwtPlot::yRight ) );
    546 
    547         int titleW = w;
    548         if ( centerOnCanvas )
    549         {
    550             titleW -= scaleData[QwtPlot::yLeft].w
    551                 + scaleData[QwtPlot::yRight].w;
    552         }
    553 
    554         int titleH = title->heightForWidth( titleW );
    555         if ( titleH > titleW ) // Compensate for a long title
    556         {
    557             w = titleW = titleH;
     665    const QwtTextLabel *labels[2];
     666    labels[0] = plot->titleLabel();
     667    labels[1] = plot->footerLabel();
     668
     669    for ( int i = 0; i < 2; i++ )
     670    {
     671        const QwtTextLabel *label   = labels[i];
     672        if ( label && !label->text().isEmpty() )
     673        {
     674            // If only QwtPlot::yLeft or QwtPlot::yRight is showing,
     675            // we center on the plot canvas.
     676            const bool centerOnCanvas = !( plot->axisEnabled( QwtPlot::yLeft )
     677                && plot->axisEnabled( QwtPlot::yRight ) );
     678
     679            int labelW = w;
    558680            if ( centerOnCanvas )
    559681            {
    560                 w += scaleData[QwtPlot::yLeft].w
     682                labelW -= scaleData[QwtPlot::yLeft].w
    561683                    + scaleData[QwtPlot::yRight].w;
    562684            }
    563685
    564             titleH = title->heightForWidth( titleW );
    565         }
    566         h += titleH + d_data->spacing;
     686            int labelH = label->heightForWidth( labelW );
     687            if ( labelH > labelW ) // Compensate for a long title
     688            {
     689                w = labelW = labelH;
     690                if ( centerOnCanvas )
     691                {
     692                    w += scaleData[QwtPlot::yLeft].w
     693                        + scaleData[QwtPlot::yRight].w;
     694                }
     695
     696                labelH = label->heightForWidth( labelW );
     697            }
     698            h += labelH + d_data->spacing;
     699        }
    567700    }
    568701
    569702    // Compute the legend contribution
    570703
    571     const QwtLegend *legend = plot->legend();
    572     if ( d_data->legendPos != QwtPlot::ExternalLegend
    573         && legend && !legend->isEmpty() )
     704    const QwtAbstractLegend *legend = plot->legend();
     705    if ( legend && !legend->isEmpty() )
    574706    {
    575707        if ( d_data->legendPos == QwtPlot::LeftLegend
     
    583715
    584716            if ( legendH > h )
    585                 legendW += legend->verticalScrollBar()->sizeHint().height();
     717                legendW += legend->scrollExtent( Qt::Horizontal );
    586718
    587719            if ( d_data->legendRatio < 1.0 )
     
    610742/*!
    611743  Find the geometry for the legend
     744
    612745  \param options Options how to layout the legend
    613746  \param rect Rectangle where to place the legend
     747
    614748  \return Geometry for the legend
    615749  \sa Options
     
    637771                // space for the vertical scrollbar.
    638772
    639                 dim += d_data->layoutData.legend.vScrollBarWidth;
     773                dim += d_data->layoutData.legend.hScrollExtent;
    640774            }
    641775        }
     
    644778    {
    645779        dim = qMin( hint.height(), int( rect.height() * d_data->legendRatio ) );
    646         dim = qMax( dim, d_data->layoutData.legend.hScrollBarHeight );
     780        dim = qMax( dim, d_data->layoutData.legend.vScrollExtent );
    647781    }
    648782
     
    664798            legendRect.setHeight( dim );
    665799            break;
    666         case QwtPlot::ExternalLegend:
    667             break;
    668800    }
    669801
     
    673805/*!
    674806  Align the legend to the canvas
     807
    675808  \param canvasRect Geometry of the canvas
    676809  \param legendRect Maximum geometry for the legend
     810
    677811  \return Geometry for the aligned legend
    678812*/
     
    708842
    709843  \param options Options how to layout the legend
    710   \param rect Bounding rect for title, axes and canvas.
     844  \param rect Bounding rectangle for title, footer, axes and canvas.
    711845  \param dimTitle Expanded height of the title widget
     846  \param dimFooter Expanded height of the footer widget
    712847  \param dimAxis Expanded heights of the axis in axis orientation.
    713848
    714849  \sa Options
    715850*/
    716 void QwtPlotLayout::expandLineBreaks( int options, const QRectF &rect,
    717     int &dimTitle, int dimAxis[QwtPlot::axisCnt] ) const
    718 {
    719     dimTitle = 0;
     851void QwtPlotLayout::expandLineBreaks( Options options, const QRectF &rect,
     852    int &dimTitle, int &dimFooter, int dimAxis[QwtPlot::axisCnt] ) const
     853{
     854    dimTitle = dimFooter = 0;
    720855    for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
    721856        dimAxis[axis] = 0;
     
    725860    {
    726861        backboneOffset[axis] = 0;
    727         if ( !d_data->alignCanvasToScales )
     862        if ( !( options & IgnoreFrames ) )
     863            backboneOffset[axis] += d_data->layoutData.canvas.contentsMargins[ axis ];
     864
     865        if ( !d_data->alignCanvasToScales[axis] )
    728866            backboneOffset[axis] += d_data->canvasMargin[axis];
    729         if ( !( options & IgnoreFrames ) )
    730             backboneOffset[axis] += d_data->layoutData.canvas.frameWidth;
    731867    }
    732868
     
    744880        // axis ... . So we loop as long until no size changes.
    745881
    746         if ( !d_data->layoutData.title.text.isEmpty() )
    747         {
    748             int w = rect.width();
     882        if ( !( ( options & IgnoreTitle ) ||
     883            d_data->layoutData.title.text.isEmpty() ) )
     884        {
     885            double w = rect.width();
    749886
    750887            if ( d_data->layoutData.scale[QwtPlot::yLeft].isEnabled
     
    766903        }
    767904
     905        if ( !( ( options & IgnoreFooter ) ||
     906            d_data->layoutData.footer.text.isEmpty() ) )
     907        {
     908            double w = rect.width();
     909
     910            if ( d_data->layoutData.scale[QwtPlot::yLeft].isEnabled
     911                != d_data->layoutData.scale[QwtPlot::yRight].isEnabled )
     912            {
     913                // center to the canvas
     914                w -= dimAxis[QwtPlot::yLeft] + dimAxis[QwtPlot::yRight];
     915            }
     916
     917            int d = qCeil( d_data->layoutData.footer.text.heightForWidth( w ) );
     918            if ( !( options & IgnoreFrames ) )
     919                d += 2 * d_data->layoutData.footer.frameWidth;
     920
     921            if ( d > dimFooter )
     922            {
     923                dimFooter = d;
     924                done = false;
     925            }
     926        }
     927
    768928        for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
    769929        {
     
    773933            if ( scaleData.isEnabled )
    774934            {
    775                 int length;
     935                double length;
    776936                if ( axis == QwtPlot::xTop || axis == QwtPlot::xBottom )
    777937                {
     
    804964                        length += qMin(
    805965                            d_data->layoutData.scale[QwtPlot::xBottom].tickOffset,
    806                             scaleData.start - backboneOffset[QwtPlot::xBottom] );
     966                            double( scaleData.start - backboneOffset[QwtPlot::xBottom] ) );
    807967                    }
    808968                    if ( dimAxis[QwtPlot::xTop] > 0 )
     
    810970                        length += qMin(
    811971                            d_data->layoutData.scale[QwtPlot::xTop].tickOffset,
    812                             scaleData.end - backboneOffset[QwtPlot::xTop] );
     972                            double( scaleData.end - backboneOffset[QwtPlot::xTop] ) );
    813973                    }
    814974
     
    820980                if ( !scaleData.scaleWidget->title().isEmpty() )
    821981                {
    822                     d += scaleData.scaleWidget->titleHeightForWidth( length );
     982                    d += scaleData.scaleWidget->titleHeightForWidth( qFloor( length ) );
    823983                }
    824984
     
    838998  the empty corners.
    839999
     1000  \param options Layout options
     1001  \param canvasRect Geometry of the canvas ( IN/OUT )
     1002  \param scaleRect Geometries of the scales ( IN/OUT )
     1003
    8401004  \sa Options
    8411005*/
    8421006
    843 void QwtPlotLayout::alignScales( int options,
     1007void QwtPlotLayout::alignScales( Options options,
    8441008    QRectF &canvasRect, QRectF scaleRect[QwtPlot::axisCnt] ) const
    8451009{
     
    8481012    {
    8491013        backboneOffset[axis] = 0;
    850         if ( !d_data->alignCanvasToScales )
     1014
     1015        if ( !d_data->alignCanvasToScales[axis] )
     1016        {
    8511017            backboneOffset[axis] += d_data->canvasMargin[axis];
     1018        }
     1019
    8521020        if ( !( options & IgnoreFrames ) )
    853             backboneOffset[axis] += d_data->layoutData.canvas.frameWidth;
     1021        {
     1022            backboneOffset[axis] +=
     1023                d_data->layoutData.canvas.contentsMargins[axis];
     1024        }
    8541025    }
    8551026
     
    8721043            if ( leftScaleRect.isValid() )
    8731044            {
    874                 const int dx = leftOffset + leftScaleRect.width();
    875                 if ( d_data->alignCanvasToScales && dx < 0 )
     1045                const double dx = leftOffset + leftScaleRect.width();
     1046                if ( d_data->alignCanvasToScales[QwtPlot::yLeft] && dx < 0.0 )
    8761047                {
    8771048                    /*
     
    8791050                      of the left scale.
    8801051                     */
    881                     canvasRect.setLeft( qMax( canvasRect.left(),
    882                         axisRect.left() - dx ) );
     1052                    const double cLeft = canvasRect.left(); // qreal -> double
     1053                    canvasRect.setLeft( qMax( cLeft, axisRect.left() - dx ) );
    8831054                }
    8841055                else
     
    8911062            else
    8921063            {
    893                 if ( d_data->alignCanvasToScales && leftOffset < 0 )
     1064                if ( d_data->alignCanvasToScales[QwtPlot::yLeft] && leftOffset < 0 )
    8941065                {
    8951066                    canvasRect.setLeft( qMax( canvasRect.left(),
     
    9091080            if ( rightScaleRect.isValid() )
    9101081            {
    911                 const int dx = rightOffset + rightScaleRect.width();
    912                 if ( d_data->alignCanvasToScales && dx < 0 )
     1082                const double dx = rightOffset + rightScaleRect.width();
     1083                if ( d_data->alignCanvasToScales[QwtPlot::yRight] && dx < 0 )
    9131084                {
    9141085                    /*
     
    9161087                      of the right scale.
    9171088                     */
    918                     canvasRect.setRight( qMin( canvasRect.right(),
    919                         axisRect.right() + dx ) );
     1089                    const double cRight = canvasRect.right(); // qreal -> double
     1090                    canvasRect.setRight( qMin( cRight, axisRect.right() + dx ) );
    9201091                }   
    9211092
     
    9261097            else
    9271098            {
    928                 if ( d_data->alignCanvasToScales && rightOffset < 0 )
     1099                if ( d_data->alignCanvasToScales[QwtPlot::yRight] && rightOffset < 0 )
    9291100                {
    9301101                    canvasRect.setRight( qMin( canvasRect.right(),
     
    9461117            if ( bottomScaleRect.isValid() )
    9471118            {
    948                 const int dy = bottomOffset + bottomScaleRect.height();
    949                 if ( d_data->alignCanvasToScales && dy < 0 )
     1119                const double dy = bottomOffset + bottomScaleRect.height();
     1120                if ( d_data->alignCanvasToScales[QwtPlot::xBottom] && dy < 0 )
    9501121                {
    9511122                    /*
     
    9531124                      of the bottom scale.
    9541125                     */
    955                     canvasRect.setBottom( qMin( canvasRect.bottom(),
    956                         axisRect.bottom() + dy ) );
     1126                    const double cBottom = canvasRect.bottom(); // qreal -> double
     1127                    canvasRect.setBottom( qMin( cBottom, axisRect.bottom() + dy ) );
    9571128                }
    9581129                else
     
    9661137            else
    9671138            {
    968                 if ( d_data->alignCanvasToScales && bottomOffset < 0 )
     1139                if ( d_data->alignCanvasToScales[QwtPlot::xBottom] && bottomOffset < 0 )
    9691140                {
    9701141                    canvasRect.setBottom( qMin( canvasRect.bottom(),
     
    9831154            if ( topScaleRect.isValid() )
    9841155            {
    985                 const int dy = topOffset + topScaleRect.height();
    986                 if ( d_data->alignCanvasToScales && dy < 0 )
     1156                const double dy = topOffset + topScaleRect.height();
     1157                if ( d_data->alignCanvasToScales[QwtPlot::xTop] && dy < 0 )
    9871158                {
    9881159                    /*
     
    9901161                      of the top scale.
    9911162                     */
    992                     canvasRect.setTop( qMax( canvasRect.top(),
    993                         axisRect.top() - dy ) );
     1163                    const double cTop = canvasRect.top(); // qreal -> double
     1164                    canvasRect.setTop( qMax( cTop, axisRect.top() - dy ) );
    9941165                }
    9951166                else
     
    10031174            else
    10041175            {
    1005                 if ( d_data->alignCanvasToScales && topOffset < 0 )
     1176                if ( d_data->alignCanvasToScales[QwtPlot::xTop] && topOffset < 0 )
    10061177                {
    10071178                    canvasRect.setTop( qMax( canvasRect.top(),
     
    10171188    }
    10181189
    1019     if ( d_data->alignCanvasToScales )
    1020     {
    1021         /*
    1022           The canvas has been aligned to the scale with largest
    1023           border distances. Now we have to realign the other scale.
    1024          */
    1025 
    1026         int fw = 0;
    1027         if ( !( options & IgnoreFrames ) )
    1028             fw = d_data->layoutData.canvas.frameWidth;
    1029 
    1030         for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
    1031         {
    1032             if ( !scaleRect[axis].isValid() )
    1033                 continue;
    1034 
    1035             if ( axis == QwtPlot::xBottom || axis == QwtPlot::xTop )
    1036             {
    1037                 scaleRect[axis].setLeft( canvasRect.left() + fw
    1038                     - d_data->layoutData.scale[axis].start );
    1039                 scaleRect[axis].setRight( canvasRect.right() - fw - 1
    1040                     + d_data->layoutData.scale[axis].end );
    1041             }   
    1042             else
    1043             {
    1044                 scaleRect[axis].setTop( canvasRect.top() + fw
    1045                     - d_data->layoutData.scale[axis].start );
    1046                 scaleRect[axis].setBottom( canvasRect.bottom() - fw - 1
    1047                     + d_data->layoutData.scale[axis].end );
    1048             }
    1049         }
    1050 
    1051         if ( scaleRect[QwtPlot::xTop].isValid() )
    1052             scaleRect[QwtPlot::xTop].setBottom( canvasRect.top() );
    1053         if ( scaleRect[QwtPlot::xBottom].isValid() )
    1054             scaleRect[QwtPlot::xBottom].setTop( canvasRect.bottom() );
    1055         if ( scaleRect[QwtPlot::yLeft].isValid() )
    1056             scaleRect[QwtPlot::yLeft].setRight( canvasRect.left() );
    1057         if ( scaleRect[QwtPlot::yRight].isValid() )
    1058             scaleRect[QwtPlot::yRight].setLeft( canvasRect.right() );
     1190    /*
     1191      The canvas has been aligned to the scale with largest
     1192      border distances. Now we have to realign the other scale.
     1193     */
     1194
     1195
     1196    for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
     1197    {
     1198        QRectF &sRect = scaleRect[axis];
     1199
     1200        if ( !sRect.isValid() )
     1201            continue;
     1202
     1203        if ( axis == QwtPlot::xBottom || axis == QwtPlot::xTop )
     1204        {
     1205            if ( d_data->alignCanvasToScales[QwtPlot::yLeft] )
     1206            {
     1207                double y = canvasRect.left() - d_data->layoutData.scale[axis].start;
     1208                if ( !( options & IgnoreFrames ) )
     1209                    y += d_data->layoutData.canvas.contentsMargins[ QwtPlot::yLeft ];
     1210
     1211                sRect.setLeft( y );
     1212            }
     1213            if ( d_data->alignCanvasToScales[QwtPlot::yRight] )
     1214            {
     1215                double y = canvasRect.right() - 1 + d_data->layoutData.scale[axis].end;
     1216                if ( !( options & IgnoreFrames ) )
     1217                    y -= d_data->layoutData.canvas.contentsMargins[ QwtPlot::yRight ];
     1218
     1219                sRect.setRight( y );
     1220            }
     1221
     1222            if ( d_data->alignCanvasToScales[ axis ] )
     1223            {
     1224                if ( axis == QwtPlot::xTop )
     1225                    sRect.setBottom( canvasRect.top() );
     1226                else
     1227                    sRect.setTop( canvasRect.bottom() );
     1228            }
     1229        }
     1230        else
     1231        {
     1232            if ( d_data->alignCanvasToScales[QwtPlot::xTop] )
     1233            {
     1234                double x = canvasRect.top() - d_data->layoutData.scale[axis].start;
     1235                if ( !( options & IgnoreFrames ) )
     1236                    x += d_data->layoutData.canvas.contentsMargins[ QwtPlot::xTop ];
     1237
     1238                sRect.setTop( x );
     1239            }
     1240            if ( d_data->alignCanvasToScales[QwtPlot::xBottom] )
     1241            {
     1242                double x = canvasRect.bottom() - 1 + d_data->layoutData.scale[axis].end;
     1243                if ( !( options & IgnoreFrames ) )
     1244                    x -= d_data->layoutData.canvas.contentsMargins[ QwtPlot::xBottom ];
     1245
     1246                sRect.setBottom( x );
     1247            }
     1248
     1249            if ( d_data->alignCanvasToScales[ axis ] )
     1250            {
     1251                if ( axis == QwtPlot::yLeft )
     1252                    sRect.setRight( canvasRect.left() );
     1253                else
     1254                    sRect.setLeft( canvasRect.right() );
     1255            }
     1256        }
    10591257    }
    10601258}
     
    10641262
    10651263  \param plot Plot to be layout
    1066   \param plotRect Rect where to place the components
     1264  \param plotRect Rectangle where to place the components
    10671265  \param options Layout options
    10681266
    1069   \sa invalidate(), titleRect(),
     1267  \sa invalidate(), titleRect(), footerRect()
    10701268      legendRect(), scaleRect(), canvasRect()
    10711269*/
     
    10771275    QRectF rect( plotRect );  // undistributed rest of the plot rect
    10781276
    1079     // We extract all layout relevant data from the widgets,
    1080     // filter them through pfilter and save them to d_data->layoutData.
     1277    // We extract all layout relevant parameters from the widgets,
     1278    // and save them to d_data->layoutData.
    10811279
    10821280    d_data->layoutData.init( plot, rect );
    10831281
    10841282    if ( !( options & IgnoreLegend )
    1085         && d_data->legendPos != QwtPlot::ExternalLegend
    10861283        && plot->legend() && !plot->legend()->isEmpty() )
    10871284    {
     
    10911288
    10921289        const QRegion region( rect.toRect() );
    1093         rect = region.subtract( d_data->legendRect.toRect() ).boundingRect();
     1290        rect = region.subtracted( d_data->legendRect.toRect() ).boundingRect();
    10941291
    10951292        switch ( d_data->legendPos )
     
    11071304                rect.setBottom( rect.bottom() - d_data->spacing );
    11081305                break;
    1109             case QwtPlot::ExternalLegend:
    1110                 break; // suppress compiler warning
    11111306        }
    11121307    }
     
    11251320     |   |   Axis    |   |
    11261321     +---+-----------+---+
     1322     |      Footer       |
     1323     +---+-----------+---+
    11271324    */
    11281325
    1129     // axes and title include text labels. The height of each
     1326    // title, footer and axes include text labels. The height of each
    11301327    // label depends on its line breaks, that depend on the width
    11311328    // for the label. A line break in a horizontal text will reduce
    11321329    // the available width for vertical texts and vice versa.
    1133     // expandLineBreaks finds the height/width for title and axes
     1330    // expandLineBreaks finds the height/width for title, footer and axes
    11341331    // including all line breaks.
    11351332
    1136     int dimTitle, dimAxes[QwtPlot::axisCnt];
    1137     expandLineBreaks( options, rect, dimTitle, dimAxes );
     1333    int dimTitle, dimFooter, dimAxes[QwtPlot::axisCnt];
     1334    expandLineBreaks( options, rect, dimTitle, dimFooter, dimAxes );
    11381335
    11391336    if ( dimTitle > 0 )
    11401337    {
    1141         d_data->titleRect = QRect( rect.x(), rect.y(),
    1142             rect.width(), dimTitle );
     1338        d_data->titleRect.setRect(
     1339            rect.left(), rect.top(), rect.width(), dimTitle );
     1340
     1341        rect.setTop( d_data->titleRect.bottom() + d_data->spacing );
    11431342
    11441343        if ( d_data->layoutData.scale[QwtPlot::yLeft].isEnabled !=
     
    11481347            // the title centered to the canvas
    11491348
    1150             d_data->titleRect.setX( rect.x() + dimAxes[QwtPlot::yLeft] );
     1349            d_data->titleRect.setX( rect.left() + dimAxes[QwtPlot::yLeft] );
    11511350            d_data->titleRect.setWidth( rect.width()
    11521351                - dimAxes[QwtPlot::yLeft] - dimAxes[QwtPlot::yRight] );
    11531352        }
    1154 
    1155         // subtract title
    1156         rect.setTop( rect.top() + dimTitle + d_data->spacing );
     1353    }
     1354
     1355    if ( dimFooter > 0 )
     1356    {
     1357        d_data->footerRect.setRect(
     1358            rect.left(), rect.bottom() - dimFooter, rect.width(), dimFooter );
     1359
     1360        rect.setBottom( d_data->footerRect.top() - d_data->spacing );
     1361
     1362        if ( d_data->layoutData.scale[QwtPlot::yLeft].isEnabled !=
     1363            d_data->layoutData.scale[QwtPlot::yRight].isEnabled )
     1364        {
     1365            // if only one of the y axes is missing we align
     1366            // the footer centered to the canvas
     1367
     1368            d_data->footerRect.setX( rect.left() + dimAxes[QwtPlot::yLeft] );
     1369            d_data->footerRect.setWidth( rect.width()
     1370                - dimAxes[QwtPlot::yLeft] - dimAxes[QwtPlot::yRight] );
     1371        }
    11571372    }
    11581373
Note: See TracChangeset for help on using the changeset viewer.