xdsopl-qsstv/qwt/qwt_plot_textlabel.cpp

247 wiersze
5.5 KiB
C++

/* -*- 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
*****************************************************************************/
#include "qwt_plot_textlabel.h"
#include "qwt_painter.h"
#include "qwt_scale_map.h"
#include <qpainter.h>
#include <qpixmap.h>
#include <qmath.h>
static QRect qwtItemRect( int renderFlags,
const QRectF &rect, const QSizeF &itemSize )
{
int x;
if ( renderFlags & Qt::AlignLeft )
{
x = rect.left();
}
else if ( renderFlags & Qt::AlignRight )
{
x = rect.right() - itemSize.width();
}
else
{
x = rect.center().x() - 0.5 * itemSize.width();
}
int y;
if ( renderFlags & Qt::AlignTop )
{
y = rect.top();
}
else if ( renderFlags & Qt::AlignBottom )
{
y = rect.bottom() - itemSize.height();
}
else
{
y = rect.center().y() - 0.5 * itemSize.height();
}
return QRect( x, y, itemSize.width(), itemSize.height() );
}
class QwtPlotTextLabel::PrivateData
{
public:
PrivateData():
margin( 5 )
{
}
QwtText text;
int margin;
QPixmap pixmap;
};
/*!
\brief Constructor
Initializes an text label with an empty text
Sets the following item attributes:
- QwtPlotItem::AutoScale: true
- QwtPlotItem::Legend: false
The z value is initialized by 150
\sa QwtPlotItem::setItemAttribute(), QwtPlotItem::setZ()
*/
QwtPlotTextLabel::QwtPlotTextLabel():
QwtPlotItem( QwtText( "Label" ) )
{
d_data = new PrivateData;
setItemAttribute( QwtPlotItem::AutoScale, false );
setItemAttribute( QwtPlotItem::Legend, false );
setZ( 150 );
}
//! Destructor
QwtPlotTextLabel::~QwtPlotTextLabel()
{
delete d_data;
}
//! \return QwtPlotItem::Rtti_PlotTextLabel
int QwtPlotTextLabel::rtti() const
{
return QwtPlotItem::Rtti_PlotTextLabel;
}
/*!
Set the text
The label will be aligned to the plot canvas according to
the alignment flags of text.
\param text Text to be displayed
\sa text(), QwtText::renderFlags()
*/
void QwtPlotTextLabel::setText( const QwtText &text )
{
if ( d_data->text != text )
{
d_data->text = text;
invalidateCache();
itemChanged();
}
}
/*!
\return Text to be displayed
\sa setText()
*/
QwtText QwtPlotTextLabel::text() const
{
return d_data->text;
}
/*!
Set the margin
The margin is the distance between the contentsRect()
of the plot canvas and the rectangle where the label can
be displayed.
\param margin Margin
\sa margin(), textRect()
*/
void QwtPlotTextLabel::setMargin( int margin )
{
margin = qMax( margin, 0 );
if ( d_data->margin != margin )
{
d_data->margin = margin;
itemChanged();
}
}
/*!
\return Margin added to the contentsMargins() of the canvas
\sa setMargin()
*/
int QwtPlotTextLabel::margin() const
{
return d_data->margin;
}
/*!
Draw the text label
\param painter Painter
\param xMap x Scale Map
\param yMap y Scale Map
\param canvasRect Contents rectangle of the canvas in painter coordinates
\sa textRect()
*/
void QwtPlotTextLabel::draw( QPainter *painter,
const QwtScaleMap &xMap, const QwtScaleMap &yMap,
const QRectF &canvasRect ) const
{
Q_UNUSED( xMap );
Q_UNUSED( yMap );
const int m = d_data->margin;
const QRectF rect = textRect( canvasRect.adjusted( m, m, -m, -m ),
d_data->text.textSize( painter->font() ) );
const bool doAlign = QwtPainter::roundingAlignment( painter );
if ( doAlign )
{
// when the paint device is aligning it is not one
// where scalability matters ( PDF, SVG ).
// As rendering a text label is an expensive operation
// we use a cache.
int pw = 0;
if ( d_data->text.borderPen().style() != Qt::NoPen )
pw = qMax( d_data->text.borderPen().width(), 1 );
QRect pixmapRect;
pixmapRect.setLeft( qFloor( rect.left() ) - pw );
pixmapRect.setTop( qFloor( rect.top() ) - pw );
pixmapRect.setRight( qCeil( rect.right() ) + pw );
pixmapRect.setBottom( qCeil( rect.bottom() ) + pw );
if ( d_data->pixmap.isNull() ||
( pixmapRect.size() != d_data->pixmap.size() ) )
{
d_data->pixmap = QPixmap( pixmapRect.size() );
d_data->pixmap.fill( Qt::transparent );
const QRect r( pw, pw,
pixmapRect.width() - 2 * pw, pixmapRect.height() - 2 * pw );
QPainter pmPainter( &d_data->pixmap );
d_data->text.draw( &pmPainter, r );
}
painter->drawPixmap( pixmapRect, d_data->pixmap );
}
else
{
d_data->text.draw( painter, rect );
}
}
/*!
\brief Align the text label
\param rect Canvas rectangle with margins subtracted
\param textSize Size required to draw the text
\return A rectangle aligned according the the alignment flags of
the text.
\sa setMargin(), QwtText::renderFlags(), QwtText::textSize()
*/
QRectF QwtPlotTextLabel::textRect(
const QRectF &rect, const QSizeF &textSize ) const
{
return qwtItemRect( d_data->text.renderFlags(), rect, textSize );
}
//! Invalidate all internal cache
void QwtPlotTextLabel::invalidateCache()
{
d_data->pixmap = QPixmap();
}