qwt_plot_marker.cpp
/******************************************************************************
* 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_marker.h"
#include "qwt_painter.h"
#include "qwt_scale_map.h"
#include "qwt_symbol.h"
#include "qwt_text.h"
#include "qwt_graphic.h"
#include "qwt_math.h"
#include <qpainter.h>
class QwtPlotMarker::PrivateData
{
public:
PrivateData()
: labelAlignment( Qt::AlignCenter )
, labelOrientation( Qt::Horizontal )
, spacing( 2 )
, symbol( NULL )
, style( QwtPlotMarker::NoLine )
, xValue( 0.0 )
, yValue( 0.0 )
{
}
~PrivateData()
{
delete symbol;
}
QwtText label;
Qt::Alignment labelAlignment;
Qt::Orientation labelOrientation;
int spacing;
QPen pen;
const QwtSymbol* symbol;
LineStyle style;
double xValue;
double yValue;
};
QwtPlotMarker::QwtPlotMarker()
{
m_data = new PrivateData;
setZ( 30.0 );
}
QwtPlotMarker::QwtPlotMarker( const QString& title )
: QwtPlotItem( QwtText( title ) )
{
m_data = new PrivateData;
setZ( 30.0 );
}
QwtPlotMarker::QwtPlotMarker( const QwtText& title )
: QwtPlotItem( title )
{
m_data = new PrivateData;
setZ( 30.0 );
}
QwtPlotMarker::~QwtPlotMarker()
{
delete m_data;
}
int QwtPlotMarker::rtti() const
{
return QwtPlotItem::Rtti_PlotMarker;
}
QPointF QwtPlotMarker::value() const
{
return QPointF( m_data->xValue, m_data->yValue );
}
double QwtPlotMarker::xValue() const
{
return m_data->xValue;
}
double QwtPlotMarker::yValue() const
{
return m_data->yValue;
}
void QwtPlotMarker::setValue( const QPointF& pos )
{
setValue( pos.x(), pos.y() );
}
void QwtPlotMarker::setValue( double x, double y )
{
if ( x != m_data->xValue || y != m_data->yValue )
{
m_data->xValue = x;
m_data->yValue = y;
itemChanged();
}
}
void QwtPlotMarker::setXValue( double x )
{
setValue( x, m_data->yValue );
}
void QwtPlotMarker::setYValue( double y )
{
setValue( m_data->xValue, y );
}
void QwtPlotMarker::draw( QPainter* painter,
const QwtScaleMap& xMap, const QwtScaleMap& yMap,
const QRectF& canvasRect ) const
{
const QPointF pos( xMap.transform( m_data->xValue ),
yMap.transform( m_data->yValue ) );
drawLines( painter, canvasRect, pos );
drawSymbol( painter, canvasRect, pos );
drawLabel( painter, canvasRect, pos );
}
void QwtPlotMarker::drawLines( QPainter* painter,
const QRectF& canvasRect, const QPointF& pos ) const
{
if ( m_data->style == NoLine )
return;
const bool doAlign = QwtPainter::roundingAlignment( painter );
painter->setPen( m_data->pen );
if ( m_data->style == QwtPlotMarker::HLine ||
m_data->style == QwtPlotMarker::Cross )
{
double y = pos.y();
if ( doAlign )
y = qRound( y );
QwtPainter::drawLine( painter, canvasRect.left(),
y, canvasRect.right() - 1.0, y );
}
if ( m_data->style == QwtPlotMarker::VLine ||
m_data->style == QwtPlotMarker::Cross )
{
double x = pos.x();
if ( doAlign )
x = qRound( x );
QwtPainter::drawLine( painter, x,
canvasRect.top(), x, canvasRect.bottom() - 1.0 );
}
}
void QwtPlotMarker::drawSymbol( QPainter* painter,
const QRectF& canvasRect, const QPointF& pos ) const
{
if ( m_data->symbol == NULL )
return;
const QwtSymbol& symbol = *m_data->symbol;
if ( symbol.style() != QwtSymbol::NoSymbol )
{
const QSizeF sz = symbol.size();
const QRectF clipRect = canvasRect.adjusted(
-sz.width(), -sz.height(), sz.width(), sz.height() );
if ( clipRect.contains( pos ) )
symbol.drawSymbol( painter, pos );
}
}
void QwtPlotMarker::drawLabel( QPainter* painter,
const QRectF& canvasRect, const QPointF& pos ) const
{
if ( m_data->label.isEmpty() )
return;
Qt::Alignment align = m_data->labelAlignment;
QPointF alignPos = pos;
QSizeF symbolOff( 0, 0 );
switch ( m_data->style )
{
case QwtPlotMarker::VLine:
{
// In VLine-style the y-position is pointless and
// the alignment flags are relative to the canvas
if ( m_data->labelAlignment & Qt::AlignTop )
{
alignPos.setY( canvasRect.top() );
align &= ~Qt::AlignTop;
align |= Qt::AlignBottom;
}
else if ( m_data->labelAlignment & Qt::AlignBottom )
{
// In HLine-style the x-position is pointless and
// the alignment flags are relative to the canvas
alignPos.setY( canvasRect.bottom() - 1 );
align &= ~Qt::AlignBottom;
align |= Qt::AlignTop;
}
else
{
alignPos.setY( canvasRect.center().y() );
}
break;
}
case QwtPlotMarker::HLine:
{
if ( m_data->labelAlignment & Qt::AlignLeft )
{
alignPos.setX( canvasRect.left() );
align &= ~Qt::AlignLeft;
align |= Qt::AlignRight;
}
else if ( m_data->labelAlignment & Qt::AlignRight )
{
alignPos.setX( canvasRect.right() - 1 );
align &= ~Qt::AlignRight;
align |= Qt::AlignLeft;
}
else
{
alignPos.setX( canvasRect.center().x() );
}
break;
}
default:
{
if ( m_data->symbol &&
( m_data->symbol->style() != QwtSymbol::NoSymbol ) )
{
symbolOff = m_data->symbol->size() + QSizeF( 1, 1 );
symbolOff /= 2;
}
}
}
qreal pw2 = m_data->pen.widthF() / 2.0;
if ( pw2 == 0.0 )
pw2 = 0.5;
const int spacing = m_data->spacing;
const qreal xOff = qwtMaxF( pw2, symbolOff.width() );
const qreal yOff = qwtMaxF( pw2, symbolOff.height() );
const QSizeF textSize = m_data->label.textSize( painter->font() );
if ( align & Qt::AlignLeft )
{
alignPos.rx() -= xOff + spacing;
if ( m_data->labelOrientation == Qt::Vertical )
alignPos.rx() -= textSize.height();
else
alignPos.rx() -= textSize.width();
}
else if ( align & Qt::AlignRight )
{
alignPos.rx() += xOff + spacing;
}
else
{
if ( m_data->labelOrientation == Qt::Vertical )
alignPos.rx() -= textSize.height() / 2;
else
alignPos.rx() -= textSize.width() / 2;
}
if ( align & Qt::AlignTop )
{
alignPos.ry() -= yOff + spacing;
if ( m_data->labelOrientation != Qt::Vertical )
alignPos.ry() -= textSize.height();
}
else if ( align & Qt::AlignBottom )
{
alignPos.ry() += yOff + spacing;
if ( m_data->labelOrientation == Qt::Vertical )
alignPos.ry() += textSize.width();
}
else
{
if ( m_data->labelOrientation == Qt::Vertical )
alignPos.ry() += textSize.width() / 2;
else
alignPos.ry() -= textSize.height() / 2;
}
painter->translate( alignPos.x(), alignPos.y() );
if ( m_data->labelOrientation == Qt::Vertical )
painter->rotate( -90.0 );
const QRectF textRect( 0, 0, textSize.width(), textSize.height() );
m_data->label.draw( painter, textRect );
}
void QwtPlotMarker::setLineStyle( LineStyle style )
{
if ( style != m_data->style )
{
m_data->style = style;
legendChanged();
itemChanged();
}
}
QwtPlotMarker::LineStyle QwtPlotMarker::lineStyle() const
{
return m_data->style;
}
void QwtPlotMarker::setSymbol( const QwtSymbol* symbol )
{
if ( symbol != m_data->symbol )
{
delete m_data->symbol;
m_data->symbol = symbol;
if ( symbol )
setLegendIconSize( symbol->boundingRect().size() );
legendChanged();
itemChanged();
}
}
const QwtSymbol* QwtPlotMarker::symbol() const
{
return m_data->symbol;
}
void QwtPlotMarker::setLabel( const QwtText& label )
{
if ( label != m_data->label )
{
m_data->label = label;
itemChanged();
}
}
QwtText QwtPlotMarker::label() const
{
return m_data->label;
}
void QwtPlotMarker::setLabelAlignment( Qt::Alignment align )
{
if ( align != m_data->labelAlignment )
{
m_data->labelAlignment = align;
itemChanged();
}
}
Qt::Alignment QwtPlotMarker::labelAlignment() const
{
return m_data->labelAlignment;
}
void QwtPlotMarker::setLabelOrientation( Qt::Orientation orientation )
{
if ( orientation != m_data->labelOrientation )
{
m_data->labelOrientation = orientation;
itemChanged();
}
}
Qt::Orientation QwtPlotMarker::labelOrientation() const
{
return m_data->labelOrientation;
}
void QwtPlotMarker::setSpacing( int spacing )
{
if ( spacing < 0 )
spacing = 0;
if ( spacing == m_data->spacing )
return;
m_data->spacing = spacing;
itemChanged();
}
int QwtPlotMarker::spacing() const
{
return m_data->spacing;
}
void QwtPlotMarker::setLinePen( const QColor& color, qreal width, Qt::PenStyle style )
{
setLinePen( QPen( color, width, style ) );
}
void QwtPlotMarker::setLinePen( const QPen& pen )
{
if ( pen != m_data->pen )
{
m_data->pen = pen;
legendChanged();
itemChanged();
}
}
const QPen& QwtPlotMarker::linePen() const
{
return m_data->pen;
}
QRectF QwtPlotMarker::boundingRect() const
{
// width/height of -1 does not affect the autoscale calculation
switch (m_data->style)
{
case QwtPlotMarker::HLine:
return QRectF( m_data->xValue, m_data->yValue, -1.0, 0.0 );
case QwtPlotMarker::VLine:
return QRectF( m_data->xValue, m_data->yValue, 0.0, -1.0 );
default:
return QRectF( m_data->xValue, m_data->yValue, 0.0, 0.0 );
}
}
QwtGraphic QwtPlotMarker::legendIcon( int index, const QSizeF& size ) const
{
Q_UNUSED( index );
if ( size.isEmpty() )
return QwtGraphic();
QwtGraphic icon;
icon.setDefaultSize( size );
icon.setRenderHint( QwtGraphic::RenderPensUnscaled, true );
QPainter painter( &icon );
painter.setRenderHint( QPainter::Antialiasing,
testRenderHint( QwtPlotItem::RenderAntialiased ) );
if ( m_data->style != QwtPlotMarker::NoLine )
{
painter.setPen( m_data->pen );
if ( m_data->style == QwtPlotMarker::HLine ||
m_data->style == QwtPlotMarker::Cross )
{
const double y = 0.5 * size.height();
QwtPainter::drawLine( &painter,
0.0, y, size.width(), y );
}
if ( m_data->style == QwtPlotMarker::VLine ||
m_data->style == QwtPlotMarker::Cross )
{
const double x = 0.5 * size.width();
QwtPainter::drawLine( &painter,
x, 0.0, x, size.height() );
}
}
if ( m_data->symbol )
{
const QRect r( 0.0, 0.0, size.width(), size.height() );
m_data->symbol->drawSymbol( &painter, r );
}
return icon;
}
QwtGraphic
A paint device for scalable graphics.
Definition: qwt_graphic.h:76
QwtGraphic::RenderPensUnscaled
@ RenderPensUnscaled
Definition: qwt_graphic.h:96
QwtGraphic::setRenderHint
void setRenderHint(RenderHint, bool on=true)
Definition: qwt_graphic.cpp:443
QwtGraphic::setDefaultSize
void setDefaultSize(const QSizeF &)
Set a default size.
Definition: qwt_graphic.cpp:553
QwtPainter::roundingAlignment
static bool roundingAlignment()
Definition: qwt_painter.h:183
QwtPainter::drawLine
static void drawLine(QPainter *, qreal x1, qreal y1, qreal x2, qreal y2)
Wrapper for QPainter::drawLine()
Definition: qwt_painter.h:154
QwtPlotItem
Base class for items on the plot canvas.
Definition: qwt_plot_item.h:67
QwtPlotItem::setLegendIconSize
void setLegendIconSize(const QSize &)
Definition: qwt_plot_item.cpp:373
QwtPlotItem::legendChanged
virtual void legendChanged()
Definition: qwt_plot_item.cpp:491
QwtPlotItem::setZ
void setZ(double z)
Set the z value.
Definition: qwt_plot_item.cpp:165
QwtPlotItem::Rtti_PlotMarker
@ Rtti_PlotMarker
For QwtPlotMarker.
Definition: qwt_plot_item.h:90
QwtPlotItem::RenderAntialiased
@ RenderAntialiased
Enable antialiasing.
Definition: qwt_plot_item.h:206
QwtPlotItem::testRenderHint
bool testRenderHint(RenderHint) const
Definition: qwt_plot_item.cpp:332
QwtPlotItem::itemChanged
virtual void itemChanged()
Definition: qwt_plot_item.cpp:481
QwtPlotMarker
A class for drawing markers.
Definition: qwt_plot_marker.h:46
QwtPlotMarker::setXValue
void setXValue(double)
Set X Value.
Definition: qwt_plot_marker.cpp:123
QwtPlotMarker::setLineStyle
void setLineStyle(LineStyle)
Set the line style.
Definition: qwt_plot_marker.cpp:366
QwtPlotMarker::lineStyle
LineStyle lineStyle() const
Definition: qwt_plot_marker.cpp:381
QwtPlotMarker::LineStyle
LineStyle
Definition: qwt_plot_marker.h:54
QwtPlotMarker::HLine
@ HLine
A horizontal line.
Definition: qwt_plot_marker.h:59
QwtPlotMarker::Cross
@ Cross
A crosshair.
Definition: qwt_plot_marker.h:65
QwtPlotMarker::NoLine
@ NoLine
No line.
Definition: qwt_plot_marker.h:56
QwtPlotMarker::VLine
@ VLine
A vertical line.
Definition: qwt_plot_marker.h:62
QwtPlotMarker::setLabelOrientation
void setLabelOrientation(Qt::Orientation)
Set the orientation of the label.
Definition: qwt_plot_marker.cpp:480
QwtPlotMarker::drawLines
virtual void drawLines(QPainter *, const QRectF &, const QPointF &) const
Definition: qwt_plot_marker.cpp:163
QwtPlotMarker::linePen
const QPen & linePen() const
Definition: qwt_plot_marker.cpp:567
QwtPlotMarker::label
QwtText label() const
Definition: qwt_plot_marker.cpp:433
QwtPlotMarker::setYValue
void setYValue(double)
Set Y Value.
Definition: qwt_plot_marker.cpp:129
QwtPlotMarker::spacing
int spacing() const
Definition: qwt_plot_marker.cpp:523
QwtPlotMarker::drawLabel
virtual void drawLabel(QPainter *, const QRectF &, const QPointF &) const
Definition: qwt_plot_marker.cpp:232
QwtPlotMarker::drawSymbol
virtual void drawSymbol(QPainter *, const QRectF &, const QPointF &) const
Definition: qwt_plot_marker.cpp:203
QwtPlotMarker::labelOrientation
Qt::Orientation labelOrientation() const
Definition: qwt_plot_marker.cpp:493
QwtPlotMarker::setSpacing
void setSpacing(int)
Set the spacing.
Definition: qwt_plot_marker.cpp:507
QwtPlotMarker::QwtPlotMarker
QwtPlotMarker()
Sets alignment to Qt::AlignCenter, and style to QwtPlotMarker::NoLine.
Definition: qwt_plot_marker.cpp:53
QwtPlotMarker::rtti
virtual int rtti() const override
Definition: qwt_plot_marker.cpp:82
QwtPlotMarker::~QwtPlotMarker
virtual ~QwtPlotMarker()
Destructor.
Definition: qwt_plot_marker.cpp:76
QwtPlotMarker::draw
virtual void draw(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &) const override
Definition: qwt_plot_marker.cpp:142
QwtPlotMarker::setLinePen
void setLinePen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)
Definition: qwt_plot_marker.cpp:541
QwtPlotMarker::yValue
double yValue() const
Return y Value.
Definition: qwt_plot_marker.cpp:100
QwtPlotMarker::setLabelAlignment
void setLabelAlignment(Qt::Alignment)
Set the alignment of the label.
Definition: qwt_plot_marker.cpp:452
QwtPlotMarker::setValue
void setValue(double, double)
Set Value.
Definition: qwt_plot_marker.cpp:112
QwtPlotMarker::setLabel
void setLabel(const QwtText &)
Set the label.
Definition: qwt_plot_marker.cpp:420
QwtPlotMarker::labelAlignment
Qt::Alignment labelAlignment() const
Definition: qwt_plot_marker.cpp:465
QwtPlotMarker::xValue
double xValue() const
Return x Value.
Definition: qwt_plot_marker.cpp:94
QwtPlotMarker::value
QPointF value() const
Return Value.
Definition: qwt_plot_marker.cpp:88
QwtPlotMarker::boundingRect
virtual QRectF boundingRect() const override
Definition: qwt_plot_marker.cpp:572
QwtPlotMarker::setSymbol
void setSymbol(const QwtSymbol *)
Assign a symbol.
Definition: qwt_plot_marker.cpp:391
QwtPlotMarker::symbol
const QwtSymbol * symbol() const
Definition: qwt_plot_marker.cpp:410
QwtPlotMarker::legendIcon
virtual QwtGraphic legendIcon(int index, const QSizeF &) const override
Definition: qwt_plot_marker.cpp:598
QwtScaleMap
A scale map.
Definition: qwt_scale_map.h:27
QwtScaleMap::transform
double transform(double s) const
Definition: qwt_scale_map.h:137
QwtSymbol
A class for drawing symbols.
Definition: qwt_symbol.h:32
QwtSymbol::style
Style style() const
Definition: qwt_symbol.cpp:1795
QwtSymbol::drawSymbol
void drawSymbol(QPainter *, const QRectF &) const
Draw the symbol into a rectangle.
Definition: qwt_symbol.cpp:1434
QwtSymbol::boundingRect
virtual QRect boundingRect() const
Definition: qwt_symbol.cpp:1637
QwtSymbol::NoSymbol
@ NoSymbol
No Style. The symbol cannot be drawn.
Definition: qwt_symbol.h:41
QwtSymbol::size
const QSize & size() const
Definition: qwt_symbol.cpp:1094
QwtText
A class representing a text.
Definition: qwt_text.h:52