📄 qwt_plot_layout.cpp
字号:
/* -*- 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 <qscrollbar.h>
#include "qwt_rect.h"
#include "qwt_text.h"
#include "qwt_text_label.h"
#include "qwt_plot_canvas.h"
#include "qwt_scale_widget.h"
#include "qwt_legend.h"
#include "qwt_plot_layout.h"
class QwtPlotLayout::LayoutData
{
public:
void init(const QwtPlot *, const QRect &rect);
struct t_legendData
{
int frameWidth;
int vScrollBarWidth;
int hScrollBarHeight;
QSize hint;
} legend;
struct t_titleData
{
QwtText text;
int frameWidth;
} title;
struct t_scaleData
{
bool isEnabled;
const QwtScaleWidget *scaleWidget;
QFont scaleFont;
int start;
int end;
int baseLineOffset;
int tickOffset;
int dimWithoutTitle;
} scale[QwtPlot::axisCnt];
struct t_canvasData
{
int frameWidth;
} canvas;
};
/*
Extract all layout relevant data from the plot components
*/
void QwtPlotLayout::LayoutData::init(const QwtPlot *plot, const QRect &rect)
{
// legend
if ( plot->plotLayout()->legendPosition() != QwtPlot::ExternalLegend
&& plot->legend() )
{
legend.frameWidth = plot->legend()->frameWidth();
legend.vScrollBarWidth =
plot->legend()->verticalScrollBar()->sizeHint().width();
legend.hScrollBarHeight =
plot->legend()->horizontalScrollBar()->sizeHint().height();
const QSize hint = plot->legend()->sizeHint();
int w = qwtMin(hint.width(), rect.width());
int h = plot->legend()->heightForWidth(w);
if ( h == 0 )
h = hint.height();
if ( h > rect.height() )
w += legend.vScrollBarWidth;
legend.hint = QSize(w, h);
}
// title
title.frameWidth = 0;
title.text = QwtText();
if (plot->titleLabel() )
{
const QwtTextLabel *label = plot->titleLabel();
title.text = label->text();
if ( !(title.text.testPaintAttribute(QwtText::PaintUsingTextFont)) )
title.text.setFont(label->font());
title.frameWidth = plot->titleLabel()->frameWidth();
}
// scales
for (int axis = 0; axis < QwtPlot::axisCnt; axis++ )
{
if ( plot->axisEnabled(axis) )
{
const QwtScaleWidget *scaleWidget = plot->axisWidget(axis);
scale[axis].isEnabled = true;
scale[axis].scaleWidget = scaleWidget;
scale[axis].scaleFont = scaleWidget->font();
scale[axis].start = scaleWidget->startBorderDist();
scale[axis].end = scaleWidget->endBorderDist();
scale[axis].baseLineOffset = scaleWidget->margin();
scale[axis].tickOffset = scaleWidget->margin();
if ( scaleWidget->scaleDraw()->hasComponent(
QwtAbstractScaleDraw::Ticks) )
{
scale[axis].tickOffset +=
(int)scaleWidget->scaleDraw()->majTickLength();
}
scale[axis].dimWithoutTitle = scaleWidget->dimForLength(
QWIDGETSIZE_MAX, scale[axis].scaleFont);
if ( !scaleWidget->title().isEmpty() )
{
scale[axis].dimWithoutTitle -=
scaleWidget->titleHeightForWidth(QWIDGETSIZE_MAX);
}
}
else
{
scale[axis].isEnabled = false;
scale[axis].start = 0;
scale[axis].end = 0;
scale[axis].baseLineOffset = 0;
scale[axis].tickOffset = 0;
scale[axis].dimWithoutTitle = 0;
}
}
// canvas
canvas.frameWidth = plot->canvas()->frameWidth();
}
class QwtPlotLayout::PrivateData
{
public:
PrivateData():
margin(0),
spacing(5),
alignCanvasToScales(false)
{
}
QRect titleRect;
QRect legendRect;
QRect scaleRect[QwtPlot::axisCnt];
QRect canvasRect;
QwtPlotLayout::LayoutData layoutData;
QwtPlot::LegendPosition legendPos;
double legendRatio;
unsigned int margin;
unsigned int spacing;
unsigned int canvasMargin[QwtPlot::axisCnt];
bool alignCanvasToScales;
};
/*!
\brief Constructor
*/
QwtPlotLayout::QwtPlotLayout()
{
d_data = new PrivateData;
setLegendPosition(QwtPlot::BottomLegend);
setCanvasMargin(4);
invalidate();
}
//! Destructor
QwtPlotLayout::~QwtPlotLayout()
{
delete d_data;
}
/*!
Change the margin of the plot. The margin is the space
around all components.
\param margin new margin
\sa margin(), setSpacing(),
QwtPlot::setMargin()
*/
void QwtPlotLayout::setMargin(int margin)
{
if ( margin < 0 )
margin = 0;
d_data->margin = margin;
}
/*!
\return margin
\sa setMargin(), spacing(), QwtPlot::margin()
*/
int QwtPlotLayout::margin() const
{
return d_data->margin;
}
/*!
Change a margin of the canvas. The margin is the space
above/below the scale ticks. A negative margin will
be set to -1, excluding the borders of the scales.
\param margin New margin
\param axis One of QwtPlot::Axis. Specifies where the position of the margin.
-1 means margin at all borders.
\sa canvasMargin()
\warning The margin will have no effect when alignCanvasToScales is true
*/
void QwtPlotLayout::setCanvasMargin(int margin, int axis)
{
if ( margin < -1 )
margin = -1;
if ( axis == -1 )
{
for (axis = 0; axis < QwtPlot::axisCnt; axis++)
d_data->canvasMargin[axis] = margin;
}
else if ( axis >= 0 || axis < QwtPlot::axisCnt )
d_data->canvasMargin[axis] = margin;
}
/*!
\return Margin around the scale tick borders
\sa setCanvasMargin()
*/
int QwtPlotLayout::canvasMargin(int axis) const
{
if ( axis < 0 || axis >= QwtPlot::axisCnt )
return 0;
return d_data->canvasMargin[axis];
}
/*!
Change the align-canvas-to-axis-scales setting. The canvas may:
- extend beyond the axis scale ends to maximize its size,
- align with the axis scale ends to control its size.
\param alignCanvasToScales New align-canvas-to-axis-scales setting
\sa setCanvasMargin()
\note In this context the term 'scale' means the backbone of a scale.
\warning In case of alignCanvasToScales == true canvasMargin will have
no effect
*/
void QwtPlotLayout::setAlignCanvasToScales(bool alignCanvasToScales)
{
d_data->alignCanvasToScales = alignCanvasToScales;
}
/*!
Return the align-canvas-to-axis-scales setting. The canvas may:
- extend beyond the axis scale ends to maximize its size
- align with the axis scale ends to control its size.
\return align-canvas-to-axis-scales setting
\sa setAlignCanvasToScales, setCanvasMargin()
\note In this context the term 'scale' means the backbone of a scale.
*/
bool QwtPlotLayout::alignCanvasToScales() const
{
return d_data->alignCanvasToScales;
}
/*!
Change the spacing of the plot. The spacing is the distance
between the plot components.
\param spacing new spacing
\sa setMargin(), spacing()
*/
void QwtPlotLayout::setSpacing(int spacing)
{
d_data->spacing = qwtMax(0, spacing);
}
/*!
\return spacing
\sa margin(), setSpacing()
*/
int QwtPlotLayout::spacing() const
{
return d_data->spacing;
}
/*!
\brief Specify the position of the legend
\param pos The legend's position.
\param ratio Ratio between legend and the bounding rect
of title, canvas and axes. The legend will be shrinked
if it would need more space than the given ratio.
The ratio is limited to ]0.0 .. 1.0]. In case of <= 0.0
it will be reset to the default ratio.
The default vertical/horizontal ratio is 0.33/0.5.
\sa QwtPlot::setLegendPosition()
*/
void QwtPlotLayout::setLegendPosition(QwtPlot::LegendPosition pos, double ratio)
{
if ( ratio > 1.0 )
ratio = 1.0;
switch(pos)
{
case QwtPlot::TopLegend:
case QwtPlot::BottomLegend:
if ( ratio <= 0.0 )
ratio = 0.33;
d_data->legendRatio = ratio;
d_data->legendPos = pos;
break;
case QwtPlot::LeftLegend:
case QwtPlot::RightLegend:
if ( ratio <= 0.0 )
ratio = 0.5;
d_data->legendRatio = ratio;
d_data->legendPos = pos;
break;
case QwtPlot::ExternalLegend:
d_data->legendRatio = ratio; // meaningless
d_data->legendPos = pos;
default:
break;
}
}
/*!
\brief Specify the position of the legend
\param pos The legend's position. Valid values are
\c QwtPlot::LeftLegend, \c QwtPlot::RightLegend,
\c QwtPlot::TopLegend, \c QwtPlot::BottomLegend.
\sa QwtPlot::setLegendPosition()
*/
void QwtPlotLayout::setLegendPosition(QwtPlot::LegendPosition pos)
{
setLegendPosition(pos, 0.0);
}
/*!
\return Position of the legend
\sa setLegendPosition(), QwtPlot::setLegendPosition(),
QwtPlot::legendPosition()
*/
QwtPlot::LegendPosition QwtPlotLayout::legendPosition() const
{
return d_data->legendPos;
}
/*!
Specify the relative size of the legend in the plot
\param ratio Ratio between legend and the bounding rect
of title, canvas and axes. The legend will be shrinked
if it would need more space than the given ratio.
The ratio is limited to ]0.0 .. 1.0]. In case of <= 0.0
it will be reset to the default ratio.
The default vertical/horizontal ratio is 0.33/0.5.
*/
void QwtPlotLayout::setLegendRatio(double ratio)
{
setLegendPosition(legendPosition(), ratio);
}
/*!
\return The relative size of the legend in the plot.
\sa setLegendPosition()
*/
double QwtPlotLayout::legendRatio() const
{
return d_data->legendRatio;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -