You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
261 lines
5.8 KiB
261 lines
5.8 KiB
/* -*- 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() ) ); |
|
|
|
bool doCache = QwtPainter::roundingAlignment( painter ); |
|
if ( doCache ) |
|
{ |
|
switch( painter->paintEngine()->type() ) |
|
{ |
|
case QPaintEngine::Picture: |
|
case QPaintEngine::User: // usually QwtGraphic |
|
{ |
|
// don't use a cache for record/replay devices |
|
doCache = false; |
|
break; |
|
} |
|
default:; |
|
} |
|
} |
|
|
|
if ( doCache ) |
|
{ |
|
// 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(); |
|
}
|
|
|