📄 qwt_plot_layout.cpp
字号:
/*!
\return Geometry for the title
\sa activate(), invalidate()
*/
const QRect &QwtPlotLayout::titleRect() const
{
return d_data->titleRect;
}
/*!
\return Geometry for the legend
\sa activate(), invalidate()
*/
const QRect &QwtPlotLayout::legendRect() const
{
return d_data->legendRect;
}
/*!
\param axis Axis index
\return Geometry for the scale
\sa activate(), invalidate()
*/
const QRect &QwtPlotLayout::scaleRect(int axis) const
{
if ( axis < 0 || axis >= QwtPlot::axisCnt )
{
static QRect dummyRect;
return dummyRect;
}
return d_data->scaleRect[axis];
}
/*!
\return Geometry for the canvas
\sa activate(), invalidate()
*/
const QRect &QwtPlotLayout::canvasRect() const
{
return d_data->canvasRect;
}
/*!
Invalidate the geometry of all components.
\sa activate()
*/
void QwtPlotLayout::invalidate()
{
d_data->titleRect = d_data->legendRect = d_data->canvasRect = QRect();
for (int axis = 0; axis < QwtPlot::axisCnt; axis++ )
d_data->scaleRect[axis] = QRect();
}
/*!
\brief Return a minimum size hint
\sa QwtPlot::minimumSizeHint()
*/
QSize QwtPlotLayout::minimumSizeHint(const QwtPlot *plot) const
{
class ScaleData
{
public:
ScaleData()
{
w = h = minLeft = minRight = tickOffset = 0;
}
int w;
int h;
int minLeft;
int minRight;
int tickOffset;
} scaleData[QwtPlot::axisCnt];
int canvasBorder[QwtPlot::axisCnt];
int axis;
for ( axis = 0; axis < QwtPlot::axisCnt; axis++ )
{
if ( plot->axisEnabled(axis) )
{
const QwtScaleWidget *scl = plot->axisWidget(axis);
ScaleData &sd = scaleData[axis];
const QSize hint = scl->minimumSizeHint();
sd.w = hint.width();
sd.h = hint.height();
scl->getBorderDistHint(sd.minLeft, sd.minRight);
sd.tickOffset = scl->margin();
if ( scl->scaleDraw()->hasComponent(QwtAbstractScaleDraw::Ticks) )
sd.tickOffset += scl->scaleDraw()->majTickLength();
}
canvasBorder[axis] = plot->canvas()->frameWidth() +
d_data->canvasMargin[axis] + 1;
}
for ( axis = 0; axis < QwtPlot::axisCnt; axis++ )
{
ScaleData &sd = scaleData[axis];
if ( sd.w && (axis == QwtPlot::xBottom || axis == QwtPlot::xTop) )
{
if ( (sd.minLeft > canvasBorder[QwtPlot::yLeft])
&& scaleData[QwtPlot::yLeft].w )
{
int shiftLeft = sd.minLeft - canvasBorder[QwtPlot::yLeft];
if ( shiftLeft > scaleData[QwtPlot::yLeft].w )
shiftLeft = scaleData[QwtPlot::yLeft].w;
sd.w -= shiftLeft;
}
if ( (sd.minRight > canvasBorder[QwtPlot::yRight])
&& scaleData[QwtPlot::yRight].w )
{
int shiftRight = sd.minRight - canvasBorder[QwtPlot::yRight];
if ( shiftRight > scaleData[QwtPlot::yRight].w )
shiftRight = scaleData[QwtPlot::yRight].w;
sd.w -= shiftRight;
}
}
if ( sd.h && (axis == QwtPlot::yLeft || axis == QwtPlot::yRight) )
{
if ( (sd.minLeft > canvasBorder[QwtPlot::xBottom]) &&
scaleData[QwtPlot::xBottom].h )
{
int shiftBottom = sd.minLeft - canvasBorder[QwtPlot::xBottom];
if ( shiftBottom > scaleData[QwtPlot::xBottom].tickOffset )
shiftBottom = scaleData[QwtPlot::xBottom].tickOffset;
sd.h -= shiftBottom;
}
if ( (sd.minLeft > canvasBorder[QwtPlot::xTop]) &&
scaleData[QwtPlot::xTop].h )
{
int shiftTop = sd.minRight - canvasBorder[QwtPlot::xTop];
if ( shiftTop > scaleData[QwtPlot::xTop].tickOffset )
shiftTop = scaleData[QwtPlot::xTop].tickOffset;
sd.h -= shiftTop;
}
}
}
const QwtPlotCanvas *canvas = plot->canvas();
const QSize minCanvasSize = canvas->minimumSize();
int w = scaleData[QwtPlot::yLeft].w + scaleData[QwtPlot::yRight].w;
int cw = qwtMax(scaleData[QwtPlot::xBottom].w, scaleData[QwtPlot::xTop].w)
+ 2 * (canvas->frameWidth() + 1);
w += qwtMax(cw, minCanvasSize.width());
int h = scaleData[QwtPlot::xBottom].h + scaleData[QwtPlot::xTop].h;
int ch = qwtMax(scaleData[QwtPlot::yLeft].h, scaleData[QwtPlot::yRight].h)
+ 2 * (canvas->frameWidth() + 1);
h += qwtMax(ch, minCanvasSize.height());
const QwtTextLabel *title = plot->titleLabel();
if (title && !title->text().isEmpty())
{
// If only QwtPlot::yLeft or QwtPlot::yRight is showing,
// we center on the plot canvas.
const bool centerOnCanvas = !(plot->axisEnabled(QwtPlot::yLeft)
&& plot->axisEnabled(QwtPlot::yRight));
int titleW = w;
if ( centerOnCanvas )
{
titleW -= scaleData[QwtPlot::yLeft].w
+ scaleData[QwtPlot::yRight].w;
}
int titleH = title->heightForWidth(titleW);
if ( titleH > titleW ) // Compensate for a long title
{
w = titleW = titleH;
if ( centerOnCanvas )
{
w += scaleData[QwtPlot::yLeft].w
+ scaleData[QwtPlot::yRight].w;
}
titleH = title->heightForWidth(titleW);
}
h += titleH + d_data->spacing;
}
// Compute the legend contribution
const QwtLegend *legend = plot->legend();
if ( d_data->legendPos != QwtPlot::ExternalLegend
&& legend && !legend->isEmpty() )
{
if ( d_data->legendPos == QwtPlot::LeftLegend
|| d_data->legendPos == QwtPlot::RightLegend )
{
int legendW = legend->sizeHint().width();
int legendH = legend->heightForWidth(legendW);
if ( legend->frameWidth() > 0 )
w += d_data->spacing;
if ( legendH > h )
legendW += legend->verticalScrollBar()->sizeHint().height();
if ( d_data->legendRatio < 1.0 )
legendW = qwtMin(legendW, int(w / (1.0 - d_data->legendRatio)));
w += legendW;
}
else // QwtPlot::Top, QwtPlot::Bottom
{
int legendW = qwtMin(legend->sizeHint().width(), w);
int legendH = legend->heightForWidth(legendW);
if ( legend->frameWidth() > 0 )
h += d_data->spacing;
if ( d_data->legendRatio < 1.0 )
legendH = qwtMin(legendH, int(h / (1.0 - d_data->legendRatio)));
h += legendH;
}
}
w += 2 * d_data->margin;
h += 2 * d_data->margin;
return QSize( w, h );
}
/*!
Find the geometry for the legend
\param options Options how to layout the legend
\param rect Rectangle where to place the legend
\return Geometry for the legend
*/
QRect QwtPlotLayout::layoutLegend(int options,
const QRect &rect) const
{
const QSize hint(d_data->layoutData.legend.hint);
int dim;
if ( d_data->legendPos == QwtPlot::LeftLegend
|| d_data->legendPos == QwtPlot::RightLegend )
{
// We don't allow vertical legends to take more than
// half of the available space.
dim = qwtMin(hint.width(), int(rect.width() * d_data->legendRatio));
if ( !(options & IgnoreScrollbars) )
{
if ( hint.height() > rect.height() )
{
// The legend will need additional
// space for the vertical scrollbar.
dim += d_data->layoutData.legend.vScrollBarWidth;
}
}
}
else
{
dim = qwtMin(hint.height(), int(rect.height() * d_data->legendRatio));
dim = qwtMax(dim, d_data->layoutData.legend.hScrollBarHeight);
}
QRect legendRect = rect;
switch(d_data->legendPos)
{
case QwtPlot::LeftLegend:
legendRect.setWidth(dim);
break;
case QwtPlot::RightLegend:
legendRect.setX(rect.right() - dim + 1);
legendRect.setWidth(dim);
break;
case QwtPlot::TopLegend:
legendRect.setHeight(dim);
break;
case QwtPlot::BottomLegend:
legendRect.setY(rect.bottom() - dim + 1);
legendRect.setHeight(dim);
break;
case QwtPlot::ExternalLegend:
break;
}
return legendRect;
}
/*!
Align the legend to the canvas
\param canvasRect Geometry of the canvas
\param legendRect Maximum geometry for the legend
\return Geometry for the aligned legend
*/
QRect QwtPlotLayout::alignLegend(const QRect &canvasRect,
const QRect &legendRect) const
{
QRect alignedRect = legendRect;
if ( d_data->legendPos == QwtPlot::BottomLegend
|| d_data->legendPos == QwtPlot::TopLegend )
{
if ( d_data->layoutData.legend.hint.width() < canvasRect.width() )
{
alignedRect.setX(canvasRect.x());
alignedRect.setWidth(canvasRect.width());
}
}
else
{
if ( d_data->layoutData.legend.hint.height() < canvasRect.height() )
{
alignedRect.setY(canvasRect.y());
alignedRect.setHeight(canvasRect.height());
}
}
return alignedRect;
}
/*!
Expand all line breaks in text labels, and calculate the height
of their widgets in orientation of the text.
\param options Options how to layout the legend
\param rect Bounding rect for title, axes and canvas.
\param dimTitle Expanded height of the title widget
\param dimAxis Expanded heights of the axis in axis orientation.
*/
void QwtPlotLayout::expandLineBreaks(int options, const QRect &rect,
int &dimTitle, int dimAxis[QwtPlot::axisCnt]) const
{
dimTitle = 0;
for ( int i = 0; i < QwtPlot::axisCnt; i++ )
dimAxis[i] = 0;
bool done = false;
while (!done)
{
done = true;
// the size for the 4 axis depend on each other. Expanding
// the height of a horizontal axis will shrink the height
// for the vertical axis, shrinking the height of a vertical
// axis will result in a line break what will expand the
// width and results in shrinking the width of a horizontal
// axis what might result in a line break of a horizontal
// axis ... . So we loop as long until no size changes.
if ( !d_data->layoutData.title.text.isEmpty() )
{
int w = rect.width();
if ( d_data->layoutData.scale[QwtPlot::yLeft].isEnabled
!= d_data->layoutData.scale[QwtPlot::yRight].isEnabled )
{
// center to the canvas
w -= dimAxis[QwtPlot::yLeft] + dimAxis[QwtPlot::yRight];
}
int d = d_data->layoutData.title.text.heightForWidth(w);
if ( !(options & IgnoreFrames) )
d += 2 * d_data->layoutData.title.frameWidth;
if ( d > dimTitle )
{
dimTitle = d;
done = false;
}
}
for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
{
int backboneOffset = d_data->canvasMargin[axis];
if ( !(options & IgnoreFrames) )
backboneOffset += d_data->layoutData.canvas.frameWidth;
const struct LayoutData::t_scaleData &scaleData =
d_data->layoutData.scale[axis];
if (scaleData.isEnabled)
{
int length;
if ( axis == QwtPlot::xTop || axis == QwtPlot::xBottom )
{
length = rect.width() - dimAxis[QwtPlot::yLeft]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -