⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qwt_plot_layout.cpp

📁 QWT5.01用于Qt开发的二维图形库程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
                        - dimAxis[QwtPlot::yRight];
                    length += qwtMin(dimAxis[QwtPlot::yLeft], 
                        scaleData.start - backboneOffset);
                    length += qwtMin(dimAxis[QwtPlot::yRight], 
                        scaleData.end - backboneOffset);
                }
                else // QwtPlot::yLeft, QwtPlot::yRight
                {
                    length = rect.height() - dimAxis[QwtPlot::xTop] 
                        - dimAxis[QwtPlot::xBottom];

                    if ( dimAxis[QwtPlot::xBottom] > 0 )
                    {
                        length += qwtMin(
                            d_data->layoutData.scale[QwtPlot::xBottom].tickOffset, 
                            scaleData.start - backboneOffset);
                    }
                    if ( dimAxis[QwtPlot::xTop] > 0 )
                    {
                        length += qwtMin(
                            d_data->layoutData.scale[QwtPlot::xTop].tickOffset, 
                            scaleData.end - backboneOffset);
                    }

                    if ( dimTitle > 0 )
                        length -= dimTitle + d_data->spacing;
                }

                int d = scaleData.dimWithoutTitle;
                if ( !scaleData.scaleWidget->title().isEmpty() )
                {
                    d += scaleData.scaleWidget->titleHeightForWidth(length);
                }

                if ( d > dimAxis[axis] )
                {
                    dimAxis[axis] = d;
                    done = false;
                }
            }
        }
    }
}

/*!
  Align the ticks of the axis to the canvas borders using
  the empty corners.
*/

void QwtPlotLayout::alignScales(int options,
    QRect &canvasRect, QRect scaleRect[QwtPlot::axisCnt]) const
{
    int axis;

    int backboneOffset[QwtPlot::axisCnt];
    for (axis = 0; axis < QwtPlot::axisCnt; axis++ )
    {
        backboneOffset[axis] = 0;
        if ( !d_data->alignCanvasToScales )
            backboneOffset[axis] += d_data->canvasMargin[axis];
        if ( !(options & IgnoreFrames) )
            backboneOffset[axis] += d_data->layoutData.canvas.frameWidth;
    }

    for (axis = 0; axis < QwtPlot::axisCnt; axis++ )
    {
        if ( !scaleRect[axis].isValid() )
            continue;

        const int startDist = d_data->layoutData.scale[axis].start;
        const int endDist = d_data->layoutData.scale[axis].end;

        QRect &axisRect = scaleRect[axis];

        if ( axis == QwtPlot::xTop || axis == QwtPlot::xBottom )
        {
            const int leftOffset = backboneOffset[QwtPlot::yLeft] - startDist;

            if ( scaleRect[QwtPlot::yLeft].isValid() )
            {
                int minLeft = scaleRect[QwtPlot::yLeft].left();
                int left = axisRect.left() + leftOffset;
                axisRect.setLeft(qwtMax(left, minLeft));
            }
            else
            {
                if ( d_data->alignCanvasToScales && leftOffset < 0 )
                {
                    canvasRect.setLeft(qwtMax(canvasRect.left(), 
                        axisRect.left() - leftOffset));
                }
                else
                {
                    if ( leftOffset > 0 )
                        axisRect.setLeft(axisRect.left() + leftOffset);
                }
            }

            const int rightOffset = backboneOffset[QwtPlot::yRight] - endDist;

            if ( scaleRect[QwtPlot::yRight].isValid() )
            {
                int maxRight = scaleRect[QwtPlot::yRight].right();
                int right = axisRect.right() - rightOffset;
                axisRect.setRight(qwtMin(right, maxRight));
            }
            else
            {
                if ( d_data->alignCanvasToScales && rightOffset < 0 )
                {
                    canvasRect.setRight( qwtMin(canvasRect.right(), 
                        axisRect.right() + rightOffset) );
                }
                else
                {
                    if ( rightOffset > 0 )
                        axisRect.setRight(axisRect.right() - rightOffset);
                }
            }
        }
        else // QwtPlot::yLeft, QwtPlot::yRight
        {
            const int bottomOffset = 
                backboneOffset[QwtPlot::xBottom] - endDist;

            if ( scaleRect[QwtPlot::xBottom].isValid() )
            {
                int maxBottom = scaleRect[QwtPlot::xBottom].top() + 
                    d_data->layoutData.scale[QwtPlot::xBottom].tickOffset;

                int bottom = axisRect.bottom() - bottomOffset;
                axisRect.setBottom(qwtMin(bottom, maxBottom));
            }
            else
            {
                if ( d_data->alignCanvasToScales && bottomOffset < 0 )
                {
                    canvasRect.setBottom(qwtMin(canvasRect.bottom(), 
                        axisRect.bottom() + bottomOffset));
                }
                else
                {
                    if ( bottomOffset > 0 )
                        axisRect.setBottom(axisRect.bottom() - bottomOffset);
                }
            }
        
            const int topOffset = backboneOffset[QwtPlot::xTop] - startDist;

            if ( scaleRect[QwtPlot::xTop].isValid() )
            {
                int minTop = scaleRect[QwtPlot::xTop].bottom() -
                    d_data->layoutData.scale[QwtPlot::xTop].tickOffset;

                int top = axisRect.top() + topOffset;
                axisRect.setTop(qwtMax(top, minTop));
            }
            else
            {
                if ( d_data->alignCanvasToScales && topOffset < 0 )
                {
                    canvasRect.setTop(qwtMax(canvasRect.top(), 
                        axisRect.top() - topOffset));
                }
                else
                {
                    if ( topOffset > 0 )
                        axisRect.setTop(axisRect.top() + topOffset);
                }
            }
        }
    }

    if ( d_data->alignCanvasToScales )
    {
        /*
          The canvas has been aligned to the scale with largest
          border distances. Now we have to realign the other scale.
         */

        if ( scaleRect[QwtPlot::xBottom].isValid() && 
            scaleRect[QwtPlot::xTop].isValid() )
        {
            for ( int axis = QwtPlot::xBottom; axis <= QwtPlot::xTop; axis++ )
            {
                scaleRect[axis].setLeft(canvasRect.left() + 1 
                    - d_data->layoutData.scale[axis].start);
                scaleRect[axis].setRight(canvasRect.right() - 1 
                    + d_data->layoutData.scale[axis].end);
            }
        }

        if ( scaleRect[QwtPlot::yLeft].isValid() && 
            scaleRect[QwtPlot::yRight].isValid() )
        {
            for ( int axis = QwtPlot::yLeft; axis <= QwtPlot::yRight; axis++ )
            {
                scaleRect[axis].setTop(canvasRect.top() + 1 
                    - d_data->layoutData.scale[axis].start);
                scaleRect[axis].setBottom(canvasRect.bottom() - 1 
                    + d_data->layoutData.scale[axis].end);
            }
        }
    }
}

/*!
  \brief Recalculate the geometry of all components. 

  \param plot Plot to be layout
  \param plotRect Rect where to place the components
  \param options Options

  \sa invalidate(), titleRect(),
      legendRect(), scaleRect(), canvasRect()
*/
void QwtPlotLayout::activate(const QwtPlot *plot,
    const QRect &plotRect, int options) 
{
    invalidate();

    QRect rect(plotRect);  // undistributed rest of the plot rect

    if ( !(options & IgnoreMargin) )
    {
        // subtract the margin

        rect.setRect(
            rect.x() + d_data->margin, 
            rect.y() + d_data->margin,
            rect.width() - 2 * d_data->margin, 
            rect.height() - 2 * d_data->margin
        );
    }

    // We extract all layout relevant data from the widgets,
    // filter them through pfilter and save them to d_data->layoutData.

    d_data->layoutData.init(plot, rect);

    if (!(options & IgnoreLegend) 
        && d_data->legendPos != QwtPlot::ExternalLegend
        && plot->legend() && !plot->legend()->isEmpty() )
    {
        d_data->legendRect = layoutLegend(options, rect);

        // subtract d_data->legendRect from rect

        const QRegion region(rect);
        rect = region.subtract(d_data->legendRect).boundingRect(); 

        if ( d_data->layoutData.legend.frameWidth && 
            !(options & IgnoreFrames ) )
        {
            // In case of a frame we have to insert a spacing.
            // Otherwise the leading of the font separates
            // legend and scale/canvas

            switch(d_data->legendPos)
            {
                case QwtPlot::LeftLegend:
                    rect.setLeft(rect.left() + d_data->spacing);
                    break;
                case QwtPlot::RightLegend:
                    rect.setRight(rect.right() - d_data->spacing);
                    break;
                case QwtPlot::TopLegend:
                    rect.setTop(rect.top() + d_data->spacing);
                    break;
                case QwtPlot::BottomLegend:
                    rect.setBottom(rect.bottom() - d_data->spacing);
                    break;
                case QwtPlot::ExternalLegend:
                    break; // suppress compiler warning
            }
        }
    }

    /*
     +---+-----------+---+
     |       Title       |
     +---+-----------+---+
     |   |   Axis    |   |
     +---+-----------+---+
     | A |           | A |
     | x |  Canvas   | x |
     | i |           | i |
     | s |           | s |
     +---+-----------+---+
     |   |   Axis    |   |
     +---+-----------+---+
    */


    // axes and title include text labels. The height of each
    // label depends on its line breaks, that depend on the width
    // for the label. A line break in a horizontal text will reduce
    // the available width for vertical texts and vice versa. 
    // expandLineBreaks finds the height/width for title and axes
    // including all line breaks.

    int dimTitle, dimAxes[QwtPlot::axisCnt];
    expandLineBreaks(options, rect, dimTitle, dimAxes);

    if (dimTitle > 0 )
    {
        d_data->titleRect = QRect(rect.x(), rect.y(),
            rect.width(), dimTitle);

        if ( d_data->layoutData.scale[QwtPlot::yLeft].isEnabled !=
            d_data->layoutData.scale[QwtPlot::yRight].isEnabled )
        {
            // if only one of the y axes is missing we align
            // the title centered to the canvas

            d_data->titleRect.setX(rect.x() + dimAxes[QwtPlot::yLeft]);
            d_data->titleRect.setWidth(rect.width() 
                - dimAxes[QwtPlot::yLeft] - dimAxes[QwtPlot::yRight]);
        }

        // subtract title 
        rect.setTop(rect.top() + dimTitle + d_data->spacing);
    }

    d_data->canvasRect.setRect(
        rect.x() + dimAxes[QwtPlot::yLeft],
        rect.y() + dimAxes[QwtPlot::xTop],
        rect.width() - dimAxes[QwtPlot::yRight] - dimAxes[QwtPlot::yLeft],
        rect.height() - dimAxes[QwtPlot::xBottom] - dimAxes[QwtPlot::xTop]);

    for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
    {
        // set the rects for the axes

        if ( dimAxes[axis] )
        {
            int dim = dimAxes[axis];
            QRect &scaleRect = d_data->scaleRect[axis];

            scaleRect = d_data->canvasRect;
            switch(axis)
            {
                case QwtPlot::yLeft:
                    scaleRect.setX(d_data->canvasRect.left() - dim);
                    scaleRect.setWidth(dim);
                    break;
                case QwtPlot::yRight:
                    scaleRect.setX(d_data->canvasRect.right() + 1);
                    scaleRect.setWidth(dim);
                    break;
                case QwtPlot::xBottom:
                    scaleRect.setY(d_data->canvasRect.bottom() + 1);
                    scaleRect.setHeight(dim);
                    break;
                case QwtPlot::xTop:
                    scaleRect.setY(d_data->canvasRect.top() - dim);
                    scaleRect.setHeight(dim);
                    break;
            }
#if QT_VERSION < 0x040000
            scaleRect = scaleRect.normalize();
#else
            scaleRect = scaleRect.normalized();
#endif
        }
    }

    // +---+-----------+---+
    // |  <-   Axis   ->   |
    // +-^-+-----------+-^-+
    // | | |           | | |
    // |   |           |   |
    // | A |           | A |
    // | x |  Canvas   | x |
    // | i |           | i |
    // | s |           | s |
    // |   |           |   |
    // | | |           | | |
    // +-V-+-----------+-V-+
    // |   <-  Axis   ->   |
    // +---+-----------+---+

    // The ticks of the axes - not the labels above - should
    // be aligned to the canvas. So we try to use the empty
    // corners to extend the axes, so that the label texts
    // left/right of the min/max ticks are moved into them.
 
    alignScales(options, d_data->canvasRect, d_data->scaleRect);

    if (!d_data->legendRect.isEmpty() )
    {
        // We prefer to align the legend to the canvas - not to
        // the complete plot - if possible.

        d_data->legendRect = alignLegend(d_data->canvasRect, d_data->legendRect);
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -