| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,298 @@ | ||
| /* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** | ||
| * QwtPolar Widget Library | ||
| * Copyright (C) 2008 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_polar_canvas.h" | ||
| #include "qwt_polar_plot.h" | ||
| #include <qpainter.h> | ||
| #include <qevent.h> | ||
| #include <qpixmap.h> | ||
| #include <qstyle.h> | ||
| #include <qstyleoption.h> | ||
| #ifdef Q_WS_X11 | ||
| #include <qx11info_x11.h> | ||
| #endif | ||
|
|
||
| static inline void qwtDrawStyledBackground( | ||
| QWidget *widget, QPainter *painter ) | ||
| { | ||
| QStyleOption opt; | ||
| opt.initFrom( widget ); | ||
| widget->style()->drawPrimitive( QStyle::PE_Widget, &opt, painter, widget ); | ||
| } | ||
|
|
||
| static QWidget *qwtBackgroundWidget( QWidget *w ) | ||
| { | ||
| if ( w->parentWidget() == NULL ) | ||
| return w; | ||
|
|
||
| if ( w->autoFillBackground() ) | ||
| { | ||
| const QBrush brush = w->palette().brush( w->backgroundRole() ); | ||
| if ( brush.color().alpha() > 0 ) | ||
| return w; | ||
| } | ||
|
|
||
| if ( w->testAttribute( Qt::WA_StyledBackground ) ) | ||
| { | ||
| QImage image( 1, 1, QImage::Format_ARGB32 ); | ||
| image.fill( Qt::transparent ); | ||
|
|
||
| QPainter painter( &image ); | ||
| painter.translate( -w->rect().center() ); | ||
| qwtDrawStyledBackground( w, &painter ); | ||
| painter.end(); | ||
|
|
||
| if ( qAlpha( image.pixel( 0, 0 ) ) != 0 ) | ||
| return w; | ||
| } | ||
|
|
||
| return qwtBackgroundWidget( w->parentWidget() ); | ||
| } | ||
|
|
||
| class QwtPolarCanvas::PrivateData | ||
| { | ||
| public: | ||
| PrivateData(): | ||
| paintAttributes( 0 ), | ||
| backingStore( NULL ) | ||
| { | ||
| } | ||
|
|
||
| ~PrivateData() | ||
| { | ||
| delete backingStore; | ||
| } | ||
|
|
||
| QwtPolarCanvas::PaintAttributes paintAttributes; | ||
| QPixmap *backingStore; | ||
| }; | ||
|
|
||
| //! Constructor | ||
| QwtPolarCanvas::QwtPolarCanvas( QwtPolarPlot *plot ): | ||
| QFrame( plot ) | ||
| { | ||
| d_data = new PrivateData; | ||
|
|
||
| #ifndef QT_NO_CURSOR | ||
| setCursor( Qt::CrossCursor ); | ||
| #endif | ||
| setFocusPolicy( Qt::WheelFocus ); | ||
|
|
||
| setPaintAttribute( BackingStore, true ); | ||
| } | ||
|
|
||
| //! Destructor | ||
| QwtPolarCanvas::~QwtPolarCanvas() | ||
| { | ||
| delete d_data; | ||
| } | ||
|
|
||
| //! \return Parent plot widget | ||
| QwtPolarPlot *QwtPolarCanvas::plot() | ||
| { | ||
| return qobject_cast<QwtPolarPlot *>( parent() ); | ||
| } | ||
|
|
||
| //! \return Parent plot widget | ||
| const QwtPolarPlot *QwtPolarCanvas::plot() const | ||
| { | ||
| return qobject_cast<QwtPolarPlot *>( parent() ); | ||
| } | ||
|
|
||
| /*! | ||
| \brief Changing the paint attributes | ||
| \param attribute Paint attribute | ||
| \param on On/Off | ||
| The default setting enables BackingStore | ||
| \sa testPaintAttribute(), paintCache() | ||
| */ | ||
| void QwtPolarCanvas::setPaintAttribute( PaintAttribute attribute, bool on ) | ||
| { | ||
| if ( bool( d_data->paintAttributes & attribute ) == on ) | ||
| return; | ||
|
|
||
| if ( on ) | ||
| d_data->paintAttributes |= attribute; | ||
| else | ||
| d_data->paintAttributes &= ~attribute; | ||
|
|
||
| switch( attribute ) | ||
| { | ||
| case BackingStore: | ||
| { | ||
| if ( on ) | ||
| { | ||
| if ( d_data->backingStore == NULL ) | ||
| d_data->backingStore = new QPixmap(); | ||
|
|
||
| if ( isVisible() ) | ||
| { | ||
| const QRect cr = contentsRect(); | ||
| *d_data->backingStore = QPixmap::grabWidget( this, cr ); | ||
| } | ||
| } | ||
| else | ||
| { | ||
| delete d_data->backingStore; | ||
| d_data->backingStore = NULL; | ||
| } | ||
| break; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /*! | ||
| Test wether a paint attribute is enabled | ||
| \param attribute Paint attribute | ||
| \return true if the attribute is enabled | ||
| \sa setPaintAttribute() | ||
| */ | ||
| bool QwtPolarCanvas::testPaintAttribute( PaintAttribute attribute ) const | ||
| { | ||
| return ( d_data->paintAttributes & attribute ) != 0; | ||
| } | ||
|
|
||
| //! \return Backing store, might be null | ||
| const QPixmap *QwtPolarCanvas::backingStore() const | ||
| { | ||
| return d_data->backingStore; | ||
| } | ||
|
|
||
| //! Invalidate the internal backing store | ||
| void QwtPolarCanvas::invalidateBackingStore() | ||
| { | ||
| if ( d_data->backingStore ) | ||
| *d_data->backingStore = QPixmap(); | ||
| } | ||
|
|
||
| /*! | ||
| Paint event | ||
| \param event Paint event | ||
| */ | ||
| void QwtPolarCanvas::paintEvent( QPaintEvent *event ) | ||
| { | ||
| QPainter painter( this ); | ||
| painter.setClipRegion( event->region() ); | ||
|
|
||
| if ( ( d_data->paintAttributes & BackingStore ) | ||
| && d_data->backingStore != NULL ) | ||
| { | ||
| QPixmap &bs = *d_data->backingStore; | ||
| if ( bs.size() != size() ) | ||
| { | ||
| bs = QPixmap( size() ); | ||
| #ifdef Q_WS_X11 | ||
| if ( bs.x11Info().screen() != x11Info().screen() ) | ||
| bs.x11SetScreen( x11Info().screen() ); | ||
| #endif | ||
|
|
||
| QPainter p; | ||
|
|
||
| if ( testAttribute( Qt::WA_StyledBackground ) ) | ||
| { | ||
| p.begin( &bs ); | ||
| qwtDrawStyledBackground( this, &p ); | ||
| } | ||
| else | ||
| { | ||
| if ( autoFillBackground() ) | ||
| { | ||
| p.begin( &bs ); | ||
| p.fillRect( rect(), palette().brush( backgroundRole() ) ); | ||
| } | ||
| else | ||
| { | ||
| QWidget *bgWidget = qwtBackgroundWidget( plot() ); | ||
| bs.fill( bgWidget, mapTo( bgWidget, rect().topLeft() ) ); | ||
| p.begin( &bs ); | ||
| } | ||
| } | ||
|
|
||
| plot()->drawCanvas( &p, contentsRect() ); | ||
|
|
||
| if ( frameWidth() > 0 ) | ||
| drawFrame( &p ); | ||
| } | ||
|
|
||
| painter.drawPixmap( 0, 0, *d_data->backingStore ); | ||
| } | ||
| else | ||
| { | ||
| qwtDrawStyledBackground( this, &painter ); | ||
|
|
||
| plot()->drawCanvas( &painter, contentsRect() ); | ||
|
|
||
| if ( frameWidth() > 0 ) | ||
| drawFrame( &painter ); | ||
| } | ||
| } | ||
|
|
||
| /*! | ||
| Resize event | ||
| \param event Resize event | ||
| */ | ||
| void QwtPolarCanvas::resizeEvent( QResizeEvent *event ) | ||
| { | ||
| QFrame::resizeEvent( event ); | ||
|
|
||
| for ( int scaleId = 0; scaleId < QwtPolar::ScaleCount; scaleId++ ) | ||
| plot()->updateScale( scaleId ); | ||
| } | ||
|
|
||
| /*! | ||
| Translate a point from widget into plot coordinates | ||
| \param pos Point in widget coordinates of the plot canvas | ||
| \return Point in plot coordinates | ||
| \sa transform() | ||
| */ | ||
| QwtPointPolar QwtPolarCanvas::invTransform( const QPoint &pos ) const | ||
| { | ||
| const QwtPolarPlot *pl = plot(); | ||
|
|
||
| const QwtScaleMap azimuthMap = pl->scaleMap( QwtPolar::Azimuth ); | ||
| const QwtScaleMap radialMap = pl->scaleMap( QwtPolar::Radius ); | ||
|
|
||
| double dx = pos.x() - pl->plotRect().center().x(); | ||
| double dy = -( pos.y() - pl->plotRect().center().y() ); | ||
|
|
||
| const QwtPointPolar polarPos = QwtPointPolar( QPoint( dx, dy ) ).normalized(); | ||
|
|
||
| const double azimuth = azimuthMap.invTransform( polarPos.azimuth() ); | ||
| const double radius = radialMap.invTransform( polarPos.radius() ); | ||
|
|
||
| return QwtPointPolar( azimuth, radius ); | ||
| } | ||
|
|
||
| /*! | ||
| Translate a point from plot into widget coordinates | ||
| \param polarPos Point in plot coordinates | ||
| \return Point in widget coordinates | ||
| \sa transform() | ||
| */ | ||
| QPoint QwtPolarCanvas::transform( const QwtPointPolar &polarPos ) const | ||
| { | ||
| const QwtPolarPlot *pl = plot(); | ||
|
|
||
| const QwtScaleMap azimuthMap = pl->scaleMap( QwtPolar::Azimuth ); | ||
| const QwtScaleMap radialMap = pl->scaleMap( QwtPolar::Radius ); | ||
|
|
||
| const double radius = radialMap.transform( polarPos.radius() ); | ||
| const double azimuth = azimuthMap.transform( polarPos.azimuth() ); | ||
|
|
||
| const QPointF pos = qwtPolar2Pos( | ||
| pl->plotRect().center(), radius, azimuth ); | ||
|
|
||
| return pos.toPoint(); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| /* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** | ||
| * QwtPolar Widget Library | ||
| * Copyright (C) 2008 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 | ||
| *****************************************************************************/ | ||
|
|
||
| #ifndef QWT_POLAR_CANVAS_H | ||
| #define QWT_POLAR_CANVAS_H 1 | ||
|
|
||
| #include "qwt_polar_global.h" | ||
| #include <qwt_point_polar.h> | ||
| #include <qframe.h> | ||
|
|
||
| class QPainter; | ||
| class QwtPolarPlot; | ||
|
|
||
| /*! | ||
| \brief Canvas of a QwtPolarPlot. | ||
| The canvas is the widget, where all polar items are painted to. | ||
| \note In opposite to QwtPlot all axes are painted on the canvas. | ||
| \sa QwtPolarPlot | ||
| */ | ||
| class QWT_POLAR_EXPORT QwtPolarCanvas: public QFrame | ||
| { | ||
| Q_OBJECT | ||
|
|
||
| public: | ||
| /*! | ||
| \brief Paint attributes | ||
| The default setting enables BackingStore | ||
| \sa setPaintAttribute(), testPaintAttribute(), backingStore() | ||
| */ | ||
|
|
||
| enum PaintAttribute | ||
| { | ||
| /*! | ||
| Paint double buffered and reuse the content of the pixmap buffer | ||
| for some spontaneous repaints that happen when a plot gets unhidden, | ||
| deiconified or changes the focus. | ||
| */ | ||
| BackingStore = 0x01 | ||
| }; | ||
|
|
||
| //! Paint attributes | ||
| typedef QFlags<PaintAttribute> PaintAttributes; | ||
|
|
||
| explicit QwtPolarCanvas( QwtPolarPlot * ); | ||
| virtual ~QwtPolarCanvas(); | ||
|
|
||
| QwtPolarPlot *plot(); | ||
| const QwtPolarPlot *plot() const; | ||
|
|
||
| void setPaintAttribute( PaintAttribute, bool on = true ); | ||
| bool testPaintAttribute( PaintAttribute ) const; | ||
|
|
||
| const QPixmap *backingStore() const; | ||
| void invalidateBackingStore(); | ||
|
|
||
| QwtPointPolar invTransform( const QPoint & ) const; | ||
| QPoint transform( const QwtPointPolar & ) const; | ||
|
|
||
| protected: | ||
| virtual void paintEvent( QPaintEvent * ); | ||
| virtual void resizeEvent( QResizeEvent * ); | ||
|
|
||
| private: | ||
| class PrivateData; | ||
| PrivateData *d_data; | ||
| }; | ||
|
|
||
| Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPolarCanvas::PaintAttributes ) | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,163 @@ | ||
| /* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** | ||
| * QwtPolar Widget Library | ||
| * Copyright (C) 2008 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 | ||
| *****************************************************************************/ | ||
|
|
||
| #ifndef QWT_POLAR_CURVE_H | ||
| #define QWT_POLAR_CURVE_H | ||
|
|
||
| #include "qwt_polar_global.h" | ||
| #include "qwt_polar_item.h" | ||
| #include <qwt_point_polar.h> | ||
| #include <qwt_series_data.h> | ||
|
|
||
| class QPainter; | ||
| class QwtSymbol; | ||
| class QwtCurveFitter; | ||
|
|
||
| /*! | ||
| \brief An item, that represents a series of points | ||
| A curve is the representation of a series of points in polar coordinates. | ||
| The points are connected to the curve using the abstract QwtData interface. | ||
| \sa QwtPolarPlot, QwtSymbol, QwtScaleMap | ||
| */ | ||
|
|
||
| class QWT_POLAR_EXPORT QwtPolarCurve: public QwtPolarItem | ||
| { | ||
| public: | ||
| /*! | ||
| Curve styles. | ||
| \sa setStyle(), style() | ||
| */ | ||
| enum CurveStyle | ||
| { | ||
| //! Don't draw a curve. Note: This doesn't affect the symbols. | ||
| NoCurve, | ||
|
|
||
| /*! | ||
| Connect the points with straight lines. The lines might | ||
| be interpolated depending on the 'Fitted' attribute. Curve | ||
| fitting can be configured using setCurveFitter(). | ||
| */ | ||
| Lines, | ||
|
|
||
| //! Values > 100 are reserved for user specific curve styles | ||
| UserCurve = 100 | ||
| }; | ||
|
|
||
| /*! | ||
| \brief Attributes how to represent the curve on the legend | ||
| If none of the flags is activated QwtPlotCurve tries to find | ||
| a color representing the curve and paints a rectangle with it. | ||
| In the default setting all attributes are off. | ||
| \sa setLegendAttribute(), testLegendAttribute(), | ||
| drawLegendIdentifier() | ||
| */ | ||
|
|
||
| enum LegendAttribute | ||
| { | ||
| /*! | ||
| If the curveStyle() is not NoCurve a line is painted with the | ||
| curvePen(). | ||
| */ | ||
| LegendShowLine = 0x01, | ||
|
|
||
| //! If the curve has a valid symbol it is painted. | ||
| LegendShowSymbol = 0x02 | ||
| }; | ||
|
|
||
| //! Legend attributes | ||
| typedef QFlags<LegendAttribute> LegendAttributes; | ||
|
|
||
|
|
||
| explicit QwtPolarCurve(); | ||
| explicit QwtPolarCurve( const QwtText &title ); | ||
| explicit QwtPolarCurve( const QString &title ); | ||
|
|
||
| virtual ~QwtPolarCurve(); | ||
|
|
||
| virtual int rtti() const; | ||
|
|
||
| void setLegendAttribute( LegendAttribute, bool on = true ); | ||
| bool testLegendAttribute( LegendAttribute ) const; | ||
|
|
||
| void setData( QwtSeriesData<QwtPointPolar> *data ); | ||
| const QwtSeriesData<QwtPointPolar> *data() const; | ||
|
|
||
| size_t dataSize() const; | ||
| QwtPointPolar sample( int i ) const; | ||
|
|
||
| void setPen( const QPen & ); | ||
| const QPen &pen() const; | ||
|
|
||
| void setStyle( CurveStyle style ); | ||
| CurveStyle style() const; | ||
|
|
||
| void setSymbol( const QwtSymbol * ); | ||
| const QwtSymbol *symbol() const; | ||
|
|
||
| void setCurveFitter( QwtCurveFitter * ); | ||
| QwtCurveFitter *curveFitter() const; | ||
|
|
||
| virtual void draw( QPainter *p, | ||
| const QwtScaleMap &azimuthMap, const QwtScaleMap &radialMap, | ||
| const QPointF &pole, double radius, | ||
| const QRectF &canvasRect ) const; | ||
|
|
||
| virtual void draw( QPainter *p, | ||
| const QwtScaleMap &azimuthMap, const QwtScaleMap &radialMap, | ||
| const QPointF &pole, int from, int to ) const; | ||
|
|
||
| virtual void updateLegend( QwtLegend * ) const; | ||
| virtual QwtInterval boundingInterval( int scaleId ) const; | ||
|
|
||
| virtual void drawLegendIdentifier( QPainter *, const QRectF & ) const; | ||
|
|
||
| protected: | ||
|
|
||
| void init(); | ||
|
|
||
| virtual void drawCurve( QPainter *, int style, | ||
| const QwtScaleMap &azimuthMap, const QwtScaleMap &radialMap, | ||
| const QPointF &pole, int from, int to ) const; | ||
|
|
||
| virtual void drawSymbols( QPainter *, const QwtSymbol &, | ||
| const QwtScaleMap &azimuthMap, const QwtScaleMap &radialMap, | ||
| const QPointF &pole, int from, int to ) const; | ||
|
|
||
| void drawLines( QPainter *, | ||
| const QwtScaleMap &azimuthMap, const QwtScaleMap &radialMap, | ||
| const QPointF &pole, int from, int to ) const; | ||
|
|
||
| private: | ||
| QwtSeriesData<QwtPointPolar> *d_series; | ||
|
|
||
| class PrivateData; | ||
| PrivateData *d_data; | ||
| }; | ||
|
|
||
| //! \return the the curve data | ||
| inline const QwtSeriesData<QwtPointPolar> *QwtPolarCurve::data() const | ||
| { | ||
| return d_series; | ||
| } | ||
|
|
||
| /*! | ||
| \param i index | ||
| \return point at position i | ||
| */ | ||
| inline QwtPointPolar QwtPolarCurve::sample( int i ) const | ||
| { | ||
| return d_series->sample( i ); | ||
| } | ||
|
|
||
| Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPolarCurve::LegendAttributes ) | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,100 @@ | ||
| /* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** | ||
| * QwtPolar Widget Library | ||
| * Copyright (C) 2008 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_polar_fitter.h" | ||
|
|
||
| class QwtPolarFitter::PrivateData | ||
| { | ||
| public: | ||
| PrivateData(): | ||
| stepCount( 5 ) | ||
| { | ||
| } | ||
|
|
||
| int stepCount; | ||
| }; | ||
|
|
||
| /*! | ||
| Constructor | ||
| \param stepCount Number of points, that will be inserted between 2 points | ||
| \sa setStepCount() | ||
| */ | ||
| QwtPolarFitter::QwtPolarFitter( int stepCount ) | ||
| { | ||
| d_data = new PrivateData; | ||
| d_data->stepCount = stepCount; | ||
| } | ||
|
|
||
| //! Destructor | ||
| QwtPolarFitter::~QwtPolarFitter() | ||
| { | ||
| delete d_data; | ||
| } | ||
|
|
||
| /*! | ||
| Assign the number of points, that will be inserted between 2 points | ||
| The default value is 5. | ||
| \param stepCount Number of steps | ||
| \sa stepCount() | ||
| */ | ||
| void QwtPolarFitter::setStepCount( int stepCount ) | ||
| { | ||
| d_data->stepCount = qMax( stepCount, 0 ); | ||
| } | ||
|
|
||
| /*! | ||
| \return Number of points, that will be inserted between 2 points | ||
| \sa setStepCount() | ||
| */ | ||
| int QwtPolarFitter::stepCount() const | ||
| { | ||
| return d_data->stepCount; | ||
| } | ||
|
|
||
| /*! | ||
| Insert stepCount() number of additional points between 2 elements | ||
| of points. | ||
| \param points Array of points | ||
| \return Array of points including the additional points | ||
| */ | ||
| QPolygonF QwtPolarFitter::fitCurve( const QPolygonF &points ) const | ||
| { | ||
| if ( d_data->stepCount <= 0 || points.size() <= 1 ) | ||
| return points; | ||
|
|
||
| QPolygonF fittedPoints; | ||
|
|
||
| int numPoints = points.size() + ( points.size() - 1 ) * d_data->stepCount; | ||
|
|
||
| fittedPoints.resize( numPoints ); | ||
|
|
||
| int index = 0; | ||
| fittedPoints[index++] = points[0]; | ||
| for ( int i = 1; i < points.size(); i++ ) | ||
| { | ||
| const QPointF &p1 = points[i-1]; | ||
| const QPointF &p2 = points[i]; | ||
|
|
||
| const double dx = ( p2.x() - p1.x() ) / d_data->stepCount; | ||
| const double dy = ( p2.y() - p1.y() ) / d_data->stepCount; | ||
| for ( int j = 1; j <= d_data->stepCount; j++ ) | ||
| { | ||
| const double x = p1.x() + j * dx; | ||
| const double y = p1.y() + j * dy; | ||
|
|
||
| fittedPoints[index++] = QPointF( x, y ); | ||
| } | ||
| } | ||
| fittedPoints.resize( index ); | ||
|
|
||
| return fittedPoints; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| /* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** | ||
| * QwtPolar Widget Library | ||
| * Copyright (C) 2008 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 | ||
| *****************************************************************************/ | ||
|
|
||
| #ifndef QWT_POLAR_FITTER_H | ||
| #define QWT_POLAR_FITTER_H | ||
|
|
||
| #include "qwt_polar_global.h" | ||
| #include <qwt_curve_fitter.h> | ||
|
|
||
| /*! | ||
| \brief A simple curve fitter for polar points | ||
| QwtPolarFitter adds equidistant points between 2 curve points, | ||
| so that the connection gets rounded according to the nature of | ||
| a polar plot. | ||
| \sa QwtPolarCurve::setCurveFitter() | ||
| */ | ||
| class QWT_POLAR_EXPORT QwtPolarFitter: public QwtCurveFitter | ||
| { | ||
| public: | ||
| QwtPolarFitter( int stepCount = 5 ); | ||
| virtual ~QwtPolarFitter(); | ||
|
|
||
| void setStepCount( int size ); | ||
| int stepCount() const; | ||
|
|
||
| virtual QPolygonF fitCurve( const QPolygonF & ) const; | ||
|
|
||
| private: | ||
| class PrivateData; | ||
| PrivateData *d_data; | ||
| }; | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| /* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** | ||
| * QwtPolar Widget Library | ||
| * Copyright (C) 2008 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 | ||
| *****************************************************************************/ | ||
|
|
||
| #ifndef QWT_POLAR_GLOBAL_H | ||
| #define QWT_POLAR_GLOBAL_H | ||
|
|
||
| #include <qglobal.h> | ||
|
|
||
| // QWT_POLAR_VERSION is (major << 16) + (minor << 8) + patch. | ||
|
|
||
| #define QWT_POLAR_VERSION 0x010000 | ||
| #define QWT_POLAR_VERSION_STR "1.0.0" | ||
|
|
||
| #if defined(Q_WS_WIN) || defined(Q_WS_S60) | ||
|
|
||
| #if defined(_MSC_VER) /* MSVC Compiler */ | ||
| /* template-class specialization 'identifier' is already instantiated */ | ||
| #pragma warning(disable: 4660) | ||
| #endif // _MSC_VER | ||
|
|
||
| #ifdef QWT_POLAR_DLL | ||
|
|
||
| #if defined(QWT_POLAR_MAKEDLL) // create a Qwt DLL library | ||
| #define QWT_POLAR_EXPORT __declspec(dllexport) | ||
| #define QWT_POLAR_TEMPLATEDLL | ||
| #else // use a Qwt DLL library | ||
| #define QWT_POLAR_EXPORT __declspec(dllimport) | ||
| #endif | ||
|
|
||
| #endif // QWT_POLAR_MAKEDLL | ||
|
|
||
| #endif // Q_WS_WIN | ||
|
|
||
| #ifndef QWT_POLAR_EXPORT | ||
| #define QWT_POLAR_EXPORT | ||
| #endif | ||
|
|
||
| #endif // QWT_POLAR_GLOBAL_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,187 @@ | ||
| /* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** | ||
| * QwtPolar Widget Library | ||
| * Copyright (C) 2008 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 | ||
| *****************************************************************************/ | ||
|
|
||
| #ifndef QWT_POLAR_GRID_H | ||
| #define QWT_POLAR_GRID_H | ||
|
|
||
| #include "qwt_polar_global.h" | ||
| #include "qwt_polar.h" | ||
| #include "qwt_polar_item.h" | ||
| #include "qwt_polar_plot.h" | ||
|
|
||
| class QPainter; | ||
| class QPen; | ||
| class QwtScaleMap; | ||
| class QwtScaleDiv; | ||
| class QwtRoundScaleDraw; | ||
| class QwtScaleDraw; | ||
|
|
||
| /*! | ||
| \brief An item which draws scales and grid lines on a polar plot. | ||
| The QwtPolarGrid class can be used to draw a coordinate grid. | ||
| A coordinate grid consists of major and minor gridlines. | ||
| The locations of the gridlines are determined by the azimuth and radial | ||
| scale divisions. | ||
| QwtPolarGrid is also responsible for drawing the axis representing the | ||
| scales. It is possible to display 4 radial and one azimuth axis. | ||
| Whenever the scale divisions of the plot widget changes the grid | ||
| is synchronized by updateScaleDiv(). | ||
| \sa QwtPolarPlot, QwtPolar::Axis | ||
| */ | ||
|
|
||
| class QWT_POLAR_EXPORT QwtPolarGrid: public QwtPolarItem | ||
| { | ||
| public: | ||
| /*! | ||
| Mysterious flags trying to avoid conflicts, when painting the | ||
| scales and grid lines. | ||
| The default setting enables all flags. | ||
| \sa setDisplayFlag(), testDisplayFlag() | ||
| */ | ||
| enum DisplayFlag | ||
| { | ||
| /*! | ||
| Try to avoid situations, where the label of the origin is | ||
| painted over another axis. | ||
| */ | ||
| SmartOriginLabel = 1, | ||
|
|
||
| /*! | ||
| Often the outermost tick of the radial scale is close to the | ||
| canvas border. With HideMaxRadiusLabel enabled it is not painted. | ||
| */ | ||
| HideMaxRadiusLabel = 2, | ||
|
|
||
| /*! | ||
| The tick labels of the radial scales might be hard to read, when | ||
| they are painted on top of the radial grid lines ( or on top | ||
| of a curve/spectrogram ). When ClipAxisBackground the bounding rect | ||
| of each label is added to the clip region. | ||
| */ | ||
| ClipAxisBackground = 4, | ||
|
|
||
| /*! | ||
| Don't paint the backbone of the radial axes, when they are very close | ||
| to a line of the azimuth grid. | ||
| */ | ||
| SmartScaleDraw = 8, | ||
|
|
||
| /*! | ||
| All grid lines are clipped against the plot area before being painted. | ||
| When the plot is zoomed in this will have an significant impact | ||
| on the performance of the painting cde. | ||
| */ | ||
| ClipGridLines = 16 | ||
| }; | ||
|
|
||
| //! Display flags | ||
| typedef QFlags<DisplayFlag> DisplayFlags; | ||
|
|
||
| /*! | ||
| \brief Grid attributes | ||
| \sa setGridAttributes(), testGridAttributes() | ||
| */ | ||
| enum GridAttribute | ||
| { | ||
| /*! | ||
| When AutoScaling is enabled, the radial axes will be adjusted | ||
| to the interval, that is currently visible on the canvas plot. | ||
| */ | ||
| AutoScaling = 0x01 | ||
| }; | ||
|
|
||
| //! Grid attributes | ||
| typedef QFlags<GridAttribute> GridAttributes; | ||
|
|
||
| explicit QwtPolarGrid(); | ||
| virtual ~QwtPolarGrid(); | ||
|
|
||
| virtual int rtti() const; | ||
|
|
||
| void setDisplayFlag( DisplayFlag, bool on = true ); | ||
| bool testDisplayFlag( DisplayFlag ) const; | ||
|
|
||
| void setGridAttribute( GridAttribute, bool on = true ); | ||
| bool testGridAttribute( GridAttribute ) const; | ||
|
|
||
| void showGrid( int scaleId, bool show = true ); | ||
| bool isGridVisible( int scaleId ) const; | ||
|
|
||
| void showMinorGrid( int scaleId, bool show = true ); | ||
| bool isMinorGridVisible( int scaleId ) const; | ||
|
|
||
| void showAxis( int axisId, bool show = true ); | ||
| bool isAxisVisible( int axisId ) const; | ||
|
|
||
| void setPen( const QPen &p ); | ||
| void setFont( const QFont & ); | ||
|
|
||
| void setMajorGridPen( const QPen &p ); | ||
| void setMajorGridPen( int scaleId, const QPen &p ); | ||
| QPen majorGridPen( int scaleId ) const; | ||
|
|
||
| void setMinorGridPen( const QPen &p ); | ||
| void setMinorGridPen( int scaleId, const QPen &p ); | ||
| QPen minorGridPen( int scaleId ) const; | ||
|
|
||
| void setAxisPen( int axisId, const QPen &p ); | ||
| QPen axisPen( int axisId ) const; | ||
|
|
||
| void setAxisFont( int axisId, const QFont &p ); | ||
| QFont axisFont( int axisId ) const; | ||
|
|
||
| void setScaleDraw( int axisId, QwtScaleDraw * ); | ||
| const QwtScaleDraw *scaleDraw( int axisId ) const; | ||
| QwtScaleDraw *scaleDraw( int axisId ); | ||
|
|
||
| void setAzimuthScaleDraw( QwtRoundScaleDraw * ); | ||
| const QwtRoundScaleDraw *azimuthScaleDraw() const; | ||
| QwtRoundScaleDraw *azimuthScaleDraw(); | ||
|
|
||
| virtual void draw( QPainter *p, | ||
| const QwtScaleMap &azimuthMap, const QwtScaleMap &radialMap, | ||
| const QPointF &pole, double radius, | ||
| const QRectF &rect ) const; | ||
|
|
||
| virtual void updateScaleDiv( const QwtScaleDiv &azimuthMap, | ||
| const QwtScaleDiv &radialMap, const QwtInterval & ); | ||
|
|
||
| virtual int marginHint() const; | ||
|
|
||
| protected: | ||
| void drawRays( QPainter *, const QRectF &, | ||
| const QPointF &pole, double radius, | ||
| const QwtScaleMap &azimuthMap, const QList<double> & ) const; | ||
| void drawCircles( QPainter *, const QRectF &, | ||
| const QPointF &pole, const QwtScaleMap &radialMap, | ||
| const QList<double> & ) const; | ||
|
|
||
| void drawAxis( QPainter *, int axisId ) const; | ||
|
|
||
| private: | ||
| void updateScaleDraws( | ||
| const QwtScaleMap &azimuthMap, const QwtScaleMap &radialMap, | ||
| const QPointF &pole, const double radius ) const; | ||
|
|
||
| private: | ||
| class GridData; | ||
| class AxisData; | ||
| class PrivateData; | ||
| PrivateData *d_data; | ||
| }; | ||
|
|
||
| Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPolarGrid::DisplayFlags ) | ||
| Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPolarGrid::GridAttributes ) | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,176 @@ | ||
| /* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** | ||
| * QwtPolar Widget Library | ||
| * Copyright (C) 2008 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 | ||
| *****************************************************************************/ | ||
|
|
||
| #ifndef QWT_POLAR_ITEM_H | ||
| #define QWT_POLAR_ITEM_H | ||
|
|
||
| #include "qwt_polar_global.h" | ||
| #include <qwt_text.h> | ||
| #include <qwt_legend_itemmanager.h> | ||
| #include <qwt_interval.h> | ||
|
|
||
| class QString; | ||
| class QRect; | ||
| class QPointF; | ||
| class QPainter; | ||
| class QwtPolarPlot; | ||
| class QwtScaleMap; | ||
| class QwtScaleDiv; | ||
|
|
||
| /*! | ||
| \brief Base class for items on a polar plot | ||
| A QwtPolarItem is "something that can be painted on the canvas". | ||
| It is connected to the QwtPolar framework by a couple of virtual | ||
| methods, that are individually implemented in derived item classes. | ||
| QwtPolar offers an implementation of the most common types of items, | ||
| but deriving from QwtPolarItem makes it easy to implement additional | ||
| types of items. | ||
| */ | ||
| class QWT_POLAR_EXPORT QwtPolarItem: public QwtLegendItemManager | ||
| { | ||
| public: | ||
| /*! | ||
| \brief Runtime type information | ||
| RttiValues is used to cast plot items, without | ||
| having to enable runtime type information of the compiler. | ||
| */ | ||
| enum RttiValues | ||
| { | ||
| //! Unspecific value, that can be used, when it doesn't matter | ||
| Rtti_PolarItem = 0, | ||
|
|
||
| //! For QwtPolarGrid | ||
| Rtti_PolarGrid, | ||
|
|
||
| //! For QwtPolarMarker | ||
| Rtti_PolarMarker, | ||
|
|
||
| //! For QwtPolarCurve | ||
| Rtti_PolarCurve, | ||
|
|
||
| //! For QwtPolarSpectrogram | ||
| Rtti_PolarSpectrogram, | ||
|
|
||
| /*! | ||
| Values >= Rtti_PolarUserItem are reserved for plot items | ||
| not implemented in the QwtPolar library. | ||
| */ | ||
| Rtti_PolarUserItem = 1000 | ||
| }; | ||
|
|
||
| /*! | ||
| \brief Plot Item Attributes | ||
| \sa setItemAttribute(), testItemAttribute() | ||
| */ | ||
| enum ItemAttribute | ||
| { | ||
| //! The item is represented on the legend. | ||
| Legend = 0x01, | ||
|
|
||
| /*! | ||
| The boundingRect() of the item is included in the | ||
| autoscaling calculation. | ||
| */ | ||
| AutoScale = 0x02 | ||
| }; | ||
|
|
||
| //! Item attributes | ||
| typedef QFlags<ItemAttribute> ItemAttributes; | ||
|
|
||
| /*! | ||
| \brief Render hints | ||
| \sa setRenderHint(), testRenderHint() | ||
| */ | ||
| enum RenderHint | ||
| { | ||
| //! Enable antialiasing | ||
| RenderAntialiased = 0x01 | ||
| }; | ||
|
|
||
| //! Item attributes | ||
| typedef QFlags<RenderHint> RenderHints; | ||
|
|
||
| explicit QwtPolarItem( const QwtText &title = QwtText() ); | ||
| virtual ~QwtPolarItem(); | ||
|
|
||
| void attach( QwtPolarPlot *plot ); | ||
|
|
||
| /*! | ||
| \brief This method detaches a QwtPolarItem from any QwtPolarPlot it | ||
| has been associated with. | ||
| detach() is equivalent to calling attach( NULL ) | ||
| \sa attach( QwtPolarPlot* plot ) | ||
| */ | ||
| void detach() { attach( NULL ); } | ||
|
|
||
| QwtPolarPlot *plot() const; | ||
|
|
||
| void setTitle( const QString &title ); | ||
| void setTitle( const QwtText &title ); | ||
| const QwtText &title() const; | ||
|
|
||
| virtual int rtti() const; | ||
|
|
||
| void setItemAttribute( ItemAttribute, bool on = true ); | ||
| bool testItemAttribute( ItemAttribute ) const; | ||
|
|
||
| void setRenderHint( RenderHint, bool on = true ); | ||
| bool testRenderHint( RenderHint ) const; | ||
|
|
||
| double z() const; | ||
| void setZ( double z ); | ||
|
|
||
| void show(); | ||
| void hide(); | ||
| virtual void setVisible( bool ); | ||
| bool isVisible () const; | ||
|
|
||
| virtual void itemChanged(); | ||
|
|
||
| /*! | ||
| \brief Draw the item | ||
| \param painter Painter | ||
| \param azimuthMap Maps azimuth values to values related to 0.0, M_2PI | ||
| \param radialMap Maps radius values into painter coordinates. | ||
| \param pole Position of the pole in painter coordinates | ||
| \param radius Radius of the complete plot area in painter coordinates | ||
| \param canvasRect Contents rect of the canvas in painter coordinates | ||
| */ | ||
| virtual void draw( QPainter *painter, | ||
| const QwtScaleMap &azimuthMap, const QwtScaleMap &radialMap, | ||
| const QPointF &pole, double radius, | ||
| const QRectF &canvasRect ) const = 0; | ||
|
|
||
| virtual QwtInterval boundingInterval( int scaleId ) const; | ||
|
|
||
| virtual QWidget *legendItem() const; | ||
|
|
||
| virtual void updateLegend( QwtLegend * ) const; | ||
| virtual void updateScaleDiv( const QwtScaleDiv &, | ||
| const QwtScaleDiv &, const QwtInterval & ); | ||
|
|
||
| virtual int marginHint() const; | ||
|
|
||
| private: | ||
| // Disabled copy constructor and operator= | ||
| QwtPolarItem( const QwtPolarItem & ); | ||
| QwtPolarItem &operator=( const QwtPolarItem & ); | ||
|
|
||
| class PrivateData; | ||
| PrivateData *d_data; | ||
| }; | ||
|
|
||
| Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPolarItem::ItemAttributes ) | ||
| Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPolarItem::RenderHints ) | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,169 @@ | ||
| /* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** | ||
| * QwtPolar Widget Library | ||
| * Copyright (C) 2008 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_polar_itemdict.h" | ||
|
|
||
| class QwtPolarItemDict::PrivateData | ||
| { | ||
| public: | ||
| class ItemList: public QList<QwtPolarItem *> | ||
| { | ||
| public: | ||
| void insertItem( QwtPolarItem *item ) | ||
| { | ||
| if ( item == NULL ) | ||
| return; | ||
|
|
||
| // Unfortunately there is no inSort operation | ||
| // for lists in Qt4. The implementation below | ||
| // is slow, but there shouldn't be many plot items. | ||
|
|
||
| QList<QwtPolarItem *>::Iterator it; | ||
| for ( it = begin(); it != end(); ++it ) | ||
| { | ||
| if ( *it == item ) | ||
| return; | ||
|
|
||
| if ( ( *it )->z() > item->z() ) | ||
| { | ||
| insert( it, item ); | ||
| return; | ||
| } | ||
| } | ||
| append( item ); | ||
| } | ||
|
|
||
| void removeItem( QwtPolarItem *item ) | ||
| { | ||
| if ( item == NULL ) | ||
| return; | ||
|
|
||
| int i = 0; | ||
|
|
||
| QList<QwtPolarItem *>::Iterator it; | ||
| for ( it = begin(); it != end(); ++it ) | ||
| { | ||
| if ( item == *it ) | ||
| { | ||
| removeAt( i ); | ||
| return; | ||
| } | ||
| i++; | ||
| } | ||
| } | ||
| }; | ||
|
|
||
| ItemList itemList; | ||
| bool autoDelete; | ||
| }; | ||
|
|
||
| /*! | ||
| Constructor | ||
| Auto deletion is enabled. | ||
| \sa setAutoDelete, attachItem | ||
| */ | ||
| QwtPolarItemDict::QwtPolarItemDict() | ||
| { | ||
| d_data = new QwtPolarItemDict::PrivateData; | ||
| d_data->autoDelete = true; | ||
| } | ||
|
|
||
| /*! | ||
| Destructor | ||
| If autoDelete is on, all attached items will be deleted | ||
| \sa setAutoDelete, autoDelete, attachItem | ||
| */ | ||
| QwtPolarItemDict::~QwtPolarItemDict() | ||
| { | ||
| detachItems( QwtPolarItem::Rtti_PolarItem, d_data->autoDelete ); | ||
| delete d_data; | ||
| } | ||
|
|
||
| /*! | ||
| En/Disable Auto deletion | ||
| If Auto deletion is on all attached plot items will be deleted | ||
| in the destructor of QwtPolarItemDict. The default value is on. | ||
| \sa autoDelete, attachItem | ||
| */ | ||
| void QwtPolarItemDict::setAutoDelete( bool autoDelete ) | ||
| { | ||
| d_data->autoDelete = autoDelete; | ||
| } | ||
|
|
||
| /*! | ||
| \return true if auto deletion is enabled | ||
| \sa setAutoDelete, attachItem | ||
| */ | ||
| bool QwtPolarItemDict::autoDelete() const | ||
| { | ||
| return d_data->autoDelete; | ||
| } | ||
|
|
||
| /*! | ||
| Attach/Detach a plot item | ||
| Attached items will be deleted in the destructor, | ||
| if auto deletion is enabled (default). Manually detached | ||
| items are not deleted. | ||
| \param item Plot item to attach/detach | ||
| \ on If true attach, else detach the item | ||
| \sa setAutoDelete, ~QwtPolarItemDict | ||
| */ | ||
| void QwtPolarItemDict::attachItem( QwtPolarItem *item, bool on ) | ||
| { | ||
| if ( on ) | ||
| d_data->itemList.insertItem( item ); | ||
| else | ||
| d_data->itemList.removeItem( item ); | ||
| } | ||
|
|
||
| /*! | ||
| Detach items from the dictionary | ||
| \param rtti In case of QwtPolarItem::Rtti_PlotItem detach all items | ||
| otherwise only those items of the type rtti. | ||
| \param autoDelete If true, delete all detached items | ||
| */ | ||
| void QwtPolarItemDict::detachItems( int rtti, bool autoDelete ) | ||
| { | ||
| PrivateData::ItemList list = d_data->itemList; | ||
| QwtPolarItemIterator it = list.begin(); | ||
| while ( it != list.end() ) | ||
| { | ||
| QwtPolarItem *item = *it; | ||
|
|
||
| ++it; // increment before removing item from the list | ||
|
|
||
| if ( rtti == QwtPolarItem::Rtti_PolarItem || item->rtti() == rtti ) | ||
| { | ||
| item->attach( NULL ); | ||
| if ( autoDelete ) | ||
| delete item; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /*! | ||
| \brief A QwtPolarItemList of all attached plot items. | ||
| \return List of all attached plot items. | ||
| \note Use caution when iterating these lists, as removing/detaching | ||
| an item will invalidate the iterator. | ||
| Instead you can place pointers to objects to be | ||
| removed in a removal list, and traverse that list later. | ||
| */ | ||
| const QwtPolarItemList &QwtPolarItemDict::itemList() const | ||
| { | ||
| return d_data->itemList; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| /* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** | ||
| * QwtPolar Widget Library | ||
| * Copyright (C) 2008 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 | ||
| *****************************************************************************/ | ||
|
|
||
| #ifndef QWT_POLAR_ITEMDICT_H | ||
| #define QWT_POLAR_ITEMDICT_H | ||
|
|
||
| /*! \file !*/ | ||
|
|
||
| #include "qwt_polar_global.h" | ||
| #include "qwt_polar_item.h" | ||
| #include <qlist.h> | ||
|
|
||
| typedef QList<QwtPolarItem *>::ConstIterator QwtPolarItemIterator; | ||
| /// \var typedef QList< QwtPolarItem *> QwtPolarItemList | ||
| /// \brief See QT 4.x assistant documentation for QList | ||
| typedef QList<QwtPolarItem *> QwtPolarItemList; | ||
|
|
||
| /*! | ||
| \brief A dictionary for polar plot items | ||
| QwtPolarItemDict organizes polar plot items in increasing z-order. | ||
| If autoDelete() is enabled, all attached items will be deleted | ||
| in the destructor of the dictionary. | ||
| \sa QwtPolarItem::attach(), QwtPolarItem::detach(), QwtPolarItem::z() | ||
| */ | ||
| class QWT_POLAR_EXPORT QwtPolarItemDict | ||
| { | ||
| public: | ||
| explicit QwtPolarItemDict(); | ||
| ~QwtPolarItemDict(); | ||
|
|
||
| void setAutoDelete( bool ); | ||
| bool autoDelete() const; | ||
|
|
||
| const QwtPolarItemList& itemList() const; | ||
|
|
||
| void detachItems( int rtti = QwtPolarItem::Rtti_PolarItem, | ||
| bool autoDelete = true ); | ||
|
|
||
| private: | ||
| friend class QwtPolarItem; | ||
|
|
||
| void attachItem( QwtPolarItem *, bool ); | ||
|
|
||
| class PrivateData; | ||
| PrivateData *d_data; | ||
| }; | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,78 @@ | ||
| /* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** | ||
| * QwtPolar Widget Library | ||
| * Copyright (C) 2008 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 | ||
| *****************************************************************************/ | ||
|
|
||
| #ifndef QWT_POLAR_LAYOUT_H | ||
| #define QWT_POLAR_LAYOUT_H | ||
|
|
||
| #include "qwt_polar_global.h" | ||
| #include "qwt_polar_plot.h" | ||
|
|
||
| /*! | ||
| \brief Layout class for QwtPolarPlot. | ||
| Organizes the geometry for the different QwtPolarPlot components. | ||
| It is used by the QwtPolar widget to organize its internal widgets | ||
| or by QwtPolarRnderer to render its content to a QPaintDevice like | ||
| a QPrinter, QPixmap/QImage or QSvgRenderer. | ||
| */ | ||
|
|
||
| class QWT_POLAR_EXPORT QwtPolarLayout | ||
| { | ||
| public: | ||
|
|
||
| //! \brief Options to configure the plot layout engine | ||
| enum Option | ||
| { | ||
| //! Ignore the dimension of the scrollbars. | ||
| IgnoreScrollbars = 0x01, | ||
|
|
||
| //! Ignore all frames. | ||
| IgnoreFrames = 0x02, | ||
|
|
||
| //! Ignore the title. | ||
| IgnoreTitle = 0x04, | ||
|
|
||
| //! Ignore the legend. | ||
| IgnoreLegend = 0x08 | ||
| }; | ||
|
|
||
| //! Options to configure the plot layout engine | ||
| typedef QFlags<Option> Options; | ||
|
|
||
| explicit QwtPolarLayout(); | ||
| virtual ~QwtPolarLayout(); | ||
|
|
||
| void setLegendPosition( QwtPolarPlot::LegendPosition pos, double ratio ); | ||
| void setLegendPosition( QwtPolarPlot::LegendPosition pos ); | ||
| QwtPolarPlot::LegendPosition legendPosition() const; | ||
|
|
||
| void setLegendRatio( double ratio ); | ||
| double legendRatio() const; | ||
|
|
||
| virtual void activate( const QwtPolarPlot *, | ||
| const QRectF &rect, Options options = 0 ); | ||
|
|
||
| virtual void invalidate(); | ||
|
|
||
| const QRectF &titleRect() const; | ||
| const QRectF &legendRect() const; | ||
| const QRectF &canvasRect() const; | ||
|
|
||
| class LayoutData; | ||
|
|
||
| protected: | ||
| QRectF layoutLegend( Options options, QRectF & ) const; | ||
|
|
||
| private: | ||
| class PrivateData; | ||
| PrivateData *d_data; | ||
| }; | ||
|
|
||
| Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPolarLayout::Options ) | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,167 @@ | ||
| /* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** | ||
| * QwtPolar Widget Library | ||
| * Copyright (C) 2008 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_polar_magnifier.h" | ||
| #include "qwt_polar_plot.h" | ||
| #include "qwt_polar_canvas.h" | ||
| #include <qwt_scale_div.h> | ||
| #include <qwt_point_polar.h> | ||
| #include <qevent.h> | ||
|
|
||
| class QwtPolarMagnifier::PrivateData | ||
| { | ||
| public: | ||
| PrivateData(): | ||
| unzoomKey( Qt::Key_Home ), | ||
| unzoomKeyModifiers( Qt::NoModifier ) | ||
| { | ||
| } | ||
|
|
||
| int unzoomKey; | ||
| int unzoomKeyModifiers; | ||
| }; | ||
|
|
||
| /*! | ||
| Constructor | ||
| \param canvas Plot canvas to be magnified | ||
| */ | ||
| QwtPolarMagnifier::QwtPolarMagnifier( QwtPolarCanvas *canvas ): | ||
| QwtMagnifier( canvas ) | ||
| { | ||
| d_data = new PrivateData(); | ||
| } | ||
|
|
||
| //! Destructor | ||
| QwtPolarMagnifier::~QwtPolarMagnifier() | ||
| { | ||
| delete d_data; | ||
| } | ||
|
|
||
| /*! | ||
| Assign key and modifiers, that are used for unzooming | ||
| The default combination is Qt::Key_Home + Qt::NoModifier. | ||
| \param key Key code | ||
| \param modifiers Modifiers | ||
| \sa getUnzoomKey(), QwtPolarPlot::unzoom() | ||
| */ | ||
| void QwtPolarMagnifier::setUnzoomKey( int key, int modifiers ) | ||
| { | ||
| d_data->unzoomKey = key; | ||
| d_data->unzoomKeyModifiers = modifiers; | ||
| } | ||
|
|
||
| /*! | ||
| \return Key, and modifiers that are used for unzooming | ||
| \param key Key code | ||
| \param modifiers Modifiers | ||
| \sa setUnzoomKey(), QwtPolarPlot::unzoom() | ||
| */ | ||
| void QwtPolarMagnifier::getUnzoomKey( int &key, int &modifiers ) const | ||
| { | ||
| key = d_data->unzoomKey; | ||
| modifiers = d_data->unzoomKeyModifiers; | ||
| } | ||
|
|
||
| //! \return Observed plot canvas | ||
| QwtPolarCanvas *QwtPolarMagnifier::canvas() | ||
| { | ||
| return qobject_cast<QwtPolarCanvas *>( parent() ); | ||
| } | ||
|
|
||
| //! \return Observed plot canvas | ||
| const QwtPolarCanvas *QwtPolarMagnifier::canvas() const | ||
| { | ||
| return qobject_cast<QwtPolarCanvas *>( parent() ); | ||
| } | ||
|
|
||
| //! \return Observed plot | ||
| QwtPolarPlot *QwtPolarMagnifier::plot() | ||
| { | ||
| QwtPolarCanvas *c = canvas(); | ||
| if ( c ) | ||
| return c->plot(); | ||
|
|
||
| return NULL; | ||
| } | ||
|
|
||
| //! \return observed plot | ||
| const QwtPolarPlot *QwtPolarMagnifier::plot() const | ||
| { | ||
| const QwtPolarCanvas *c = canvas(); | ||
| if ( c ) | ||
| return c->plot(); | ||
|
|
||
| return NULL; | ||
| } | ||
|
|
||
| /*! | ||
| Handle a key press event for the observed widget. | ||
| \param event Key event | ||
| */ | ||
| void QwtPolarMagnifier::widgetKeyPressEvent( QKeyEvent *event ) | ||
| { | ||
| const int key = event->key(); | ||
| const int state = event->modifiers(); | ||
|
|
||
| if ( key == d_data->unzoomKey && | ||
| state == d_data->unzoomKeyModifiers ) | ||
| { | ||
| unzoom(); | ||
| return; | ||
| } | ||
|
|
||
| QwtMagnifier::widgetKeyPressEvent( event ); | ||
| } | ||
|
|
||
| /*! | ||
| Zoom in/out the zoomed area | ||
| \param factor A value < 1.0 zooms in, a value > 1.0 zooms out. | ||
| */ | ||
| void QwtPolarMagnifier::rescale( double factor ) | ||
| { | ||
| factor = qAbs( factor ); | ||
| if ( factor == 1.0 || factor == 0.0 ) | ||
| return; | ||
|
|
||
| QwtPolarPlot* plt = plot(); | ||
| if ( plt == NULL ) | ||
| return; | ||
|
|
||
| QwtPointPolar zoomPos; | ||
| double newZoomFactor = plt->zoomFactor() * factor; | ||
|
|
||
| if ( newZoomFactor >= 1.0 ) | ||
| newZoomFactor = 1.0; | ||
| else | ||
| zoomPos = plt->zoomPos(); | ||
|
|
||
| const bool autoReplot = plt->autoReplot(); | ||
| plt->setAutoReplot( false ); | ||
|
|
||
| plt->zoom( zoomPos, newZoomFactor ); | ||
|
|
||
| plt->setAutoReplot( autoReplot ); | ||
| plt->replot(); | ||
| } | ||
|
|
||
| //! Unzoom the plot widget | ||
| void QwtPolarMagnifier::unzoom() | ||
| { | ||
| QwtPolarPlot* plt = plot(); | ||
|
|
||
| const bool autoReplot = plt->autoReplot(); | ||
| plt->setAutoReplot( false ); | ||
|
|
||
| plt->unzoom(); | ||
|
|
||
| plt->setAutoReplot( autoReplot ); | ||
| plt->replot(); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| /* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** | ||
| * QwtPolar Widget Library | ||
| * Copyright (C) 2008 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 | ||
| *****************************************************************************/ | ||
|
|
||
| #ifndef QWT_POLAR_MAGNIFIER_H | ||
| #define QWT_POLAR_MAGNIFIER_H 1 | ||
|
|
||
| #include "qwt_polar_global.h" | ||
| #include "qwt_magnifier.h" | ||
|
|
||
| class QwtPolarPlot; | ||
| class QwtPolarCanvas; | ||
|
|
||
| /*! | ||
| \brief QwtPolarMagnifier provides zooming, by magnifying in steps. | ||
| Using QwtPlotMagnifier a plot can be zoomed in/out in steps using | ||
| keys, the mouse wheel or moving a mouse button in vertical direction. | ||
| Together with QwtPolarPanner it is possible to implement | ||
| an individual navigation of the plot canvas. | ||
| \sa QwtPolarPanner, QwtPolarPlot, QwtPolarCanvas | ||
| */ | ||
|
|
||
| class QWT_POLAR_EXPORT QwtPolarMagnifier: public QwtMagnifier | ||
| { | ||
| Q_OBJECT | ||
|
|
||
| public: | ||
| explicit QwtPolarMagnifier( QwtPolarCanvas * ); | ||
| virtual ~QwtPolarMagnifier(); | ||
|
|
||
| void setUnzoomKey( int key, int modifiers ); | ||
| void getUnzoomKey( int &key, int &modifiers ) const; | ||
|
|
||
| QwtPolarPlot *plot(); | ||
| const QwtPolarPlot *plot() const; | ||
|
|
||
| QwtPolarCanvas *canvas(); | ||
| const QwtPolarCanvas *canvas() const; | ||
|
|
||
| protected: | ||
| virtual void rescale( double factor ); | ||
| void unzoom(); | ||
|
|
||
| virtual void widgetKeyPressEvent( QKeyEvent * ); | ||
|
|
||
| private: | ||
| class PrivateData; | ||
| PrivateData *d_data; | ||
| }; | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,233 @@ | ||
| /* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** | ||
| * QwtPolar Widget Library | ||
| * Copyright (C) 2008 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_polar_marker.h" | ||
| #include "qwt_polar.h" | ||
| #include <qwt_scale_map.h> | ||
| #include <qwt_symbol.h> | ||
| #include <qwt_text.h> | ||
| #include <qpainter.h> | ||
|
|
||
| static const int LabelDist = 2; | ||
|
|
||
| class QwtPolarMarker::PrivateData | ||
| { | ||
| public: | ||
| PrivateData(): | ||
| align( Qt::AlignCenter ) | ||
| { | ||
| symbol = new QwtSymbol(); | ||
| } | ||
|
|
||
| ~PrivateData() | ||
| { | ||
| delete symbol; | ||
| } | ||
|
|
||
| QwtText label; | ||
| Qt::Alignment align; | ||
| QPen pen; | ||
| const QwtSymbol *symbol; | ||
|
|
||
| QwtPointPolar pos; | ||
| }; | ||
|
|
||
| //! Sets alignment to Qt::AlignCenter, and style to NoLine | ||
| QwtPolarMarker::QwtPolarMarker(): | ||
| QwtPolarItem( QwtText( "Marker" ) ) | ||
| { | ||
| d_data = new PrivateData; | ||
|
|
||
| setItemAttribute( QwtPolarItem::AutoScale ); | ||
| setZ( 30.0 ); | ||
| } | ||
|
|
||
| //! Destructor | ||
| QwtPolarMarker::~QwtPolarMarker() | ||
| { | ||
| delete d_data; | ||
| } | ||
|
|
||
| //! \return QwtPolarItem::Rtti_PlotMarker | ||
| int QwtPolarMarker::rtti() const | ||
| { | ||
| return QwtPolarItem::Rtti_PolarMarker; | ||
| } | ||
|
|
||
| //! \return Position of the marker | ||
| QwtPointPolar QwtPolarMarker::position() const | ||
| { | ||
| return d_data->pos; | ||
| } | ||
|
|
||
| //! Change the position of the marker | ||
| void QwtPolarMarker::setPosition( const QwtPointPolar &pos ) | ||
| { | ||
| if ( d_data->pos != pos ) | ||
| { | ||
| d_data->pos = pos; | ||
| itemChanged(); | ||
| } | ||
| } | ||
|
|
||
| /*! | ||
| Draw the marker | ||
| \param painter Painter | ||
| \param azimuthMap Maps azimuth values to values related to 0.0, M_2PI | ||
| \param radialMap Maps radius values into painter coordinates. | ||
| \param pole Position of the pole in painter coordinates | ||
| \param radius Radius of the complete plot area in painter coordinates | ||
| \param canvasRect Contents rect of the canvas in painter coordinates | ||
| */ | ||
| void QwtPolarMarker::draw( QPainter *painter, | ||
| const QwtScaleMap &azimuthMap, const QwtScaleMap &radialMap, | ||
| const QPointF &pole, double radius, | ||
| const QRectF &canvasRect ) const | ||
| { | ||
| Q_UNUSED( radius ); | ||
| Q_UNUSED( canvasRect ); | ||
|
|
||
| const double r = radialMap.transform( d_data->pos.radius() ); | ||
| const double a = azimuthMap.transform( d_data->pos.azimuth() ); | ||
|
|
||
| const QPointF pos = qwtPolar2Pos( pole, r, a ); | ||
|
|
||
|
|
||
| // draw symbol | ||
| QSize sSym( 0, 0 ); | ||
| if ( d_data->symbol->style() != QwtSymbol::NoSymbol ) | ||
| { | ||
| sSym = d_data->symbol->size(); | ||
| d_data->symbol->drawSymbol( painter, pos ); | ||
| } | ||
|
|
||
| // draw label | ||
| if ( !d_data->label.isEmpty() ) | ||
| { | ||
| int xlw = qMax( int( d_data->pen.width() ), 1 ); | ||
| int ylw = xlw; | ||
|
|
||
| int xlw1 = qMax( ( xlw + 1 ) / 2, ( sSym.width() + 1 ) / 2 ) + LabelDist; | ||
| xlw = qMax( xlw / 2, ( sSym.width() + 1 ) / 2 ) + LabelDist; | ||
| int ylw1 = qMax( ( ylw + 1 ) / 2, ( sSym.height() + 1 ) / 2 ) + LabelDist; | ||
| ylw = qMax( ylw / 2, ( sSym. height() + 1 ) / 2 ) + LabelDist; | ||
|
|
||
| QRect tr( QPoint( 0, 0 ), d_data->label.textSize( painter->font() ).toSize() ); | ||
| tr.moveCenter( QPoint( 0, 0 ) ); | ||
|
|
||
| int dx = pos.x(); | ||
| int dy = pos.y(); | ||
|
|
||
| if ( d_data->align & Qt::AlignTop ) | ||
| dy += tr.y() - ylw1; | ||
| else if ( d_data->align & Qt::AlignBottom ) | ||
| dy -= tr.y() - ylw1; | ||
|
|
||
| if ( d_data->align & Qt::AlignLeft ) | ||
| dx += tr.x() - xlw1; | ||
| else if ( d_data->align & Qt::AlignRight ) | ||
| dx -= tr.x() - xlw1; | ||
|
|
||
| tr.translate( dx, dy ); | ||
| d_data->label.draw( painter, tr ); | ||
| } | ||
| } | ||
|
|
||
| /*! | ||
| \brief Assign a symbol | ||
| \param symbol New symbol | ||
| \sa symbol() | ||
| */ | ||
| void QwtPolarMarker::setSymbol( const QwtSymbol *symbol ) | ||
| { | ||
| if ( d_data->symbol != symbol ) | ||
| { | ||
| delete d_data->symbol; | ||
| d_data->symbol = symbol; | ||
| itemChanged(); | ||
| } | ||
| } | ||
|
|
||
| /*! | ||
| \return the symbol | ||
| \sa setSymbol(), QwtSymbol | ||
| */ | ||
| const QwtSymbol *QwtPolarMarker::symbol() const | ||
| { | ||
| return d_data->symbol; | ||
| } | ||
|
|
||
| /*! | ||
| \brief Set the label | ||
| \param label label text | ||
| \sa label() | ||
| */ | ||
| void QwtPolarMarker::setLabel( const QwtText& label ) | ||
| { | ||
| if ( label != d_data->label ) | ||
| { | ||
| d_data->label = label; | ||
| itemChanged(); | ||
| } | ||
| } | ||
|
|
||
| /*! | ||
| \return the label | ||
| \sa setLabel() | ||
| */ | ||
| QwtText QwtPolarMarker::label() const | ||
| { | ||
| return d_data->label; | ||
| } | ||
|
|
||
| /*! | ||
| \brief Set the alignment of the label | ||
| The alignment determines where the label is drawn relative to | ||
| the marker's position. | ||
| \param align Alignment. A combination of AlignTop, AlignBottom, | ||
| AlignLeft, AlignRight, AlignCenter, AlgnHCenter, | ||
| AlignVCenter. | ||
| \sa labelAlignment() | ||
| */ | ||
| void QwtPolarMarker::setLabelAlignment( Qt::Alignment align ) | ||
| { | ||
| if ( align == d_data->align ) | ||
| return; | ||
|
|
||
| d_data->align = align; | ||
| itemChanged(); | ||
| } | ||
|
|
||
| /*! | ||
| \return the label alignment | ||
| \sa setLabelAlignment() | ||
| */ | ||
| Qt::Alignment QwtPolarMarker::labelAlignment() const | ||
| { | ||
| return d_data->align; | ||
| } | ||
|
|
||
| /*! | ||
| Interval, that is necessary to display the item | ||
| This interval can be useful for operations like clipping or autoscaling | ||
| \param scaleId Scale index | ||
| \return bounding interval ( == position ) | ||
| \sa position() | ||
| */ | ||
| QwtInterval QwtPolarMarker::boundingInterval( int scaleId ) const | ||
| { | ||
| const double v = ( scaleId == QwtPolar::ScaleRadius ) | ||
| ? d_data->pos.radius() : d_data->pos.azimuth(); | ||
|
|
||
| return QwtInterval( v, v ); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| /* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** | ||
| * QwtPolar Widget Library | ||
| * Copyright (C) 2008 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 | ||
| *****************************************************************************/ | ||
|
|
||
| #ifndef QWT_POLAR_MARKER_H | ||
| #define QWT_POLAR_MARKER_H | ||
|
|
||
| #include "qwt_polar_global.h" | ||
| #include "qwt_polar_item.h" | ||
| #include <qwt_point_polar.h> | ||
| #include <qstring.h> | ||
|
|
||
| class QRect; | ||
| class QwtText; | ||
| class QwtSymbol; | ||
|
|
||
| /*! | ||
| \brief A class for drawing markers | ||
| A marker can be a a symbol, a label or a combination of them, which can | ||
| be drawn around a center point inside a bounding rectangle. | ||
| The setSymbol() member assigns a symbol to the marker. | ||
| The symbol is drawn at the specified point. | ||
| With setLabel(), a label can be assigned to the marker. | ||
| The setLabelAlignment() member specifies where the label is | ||
| drawn. All the Align*-constants in Qt::AlignmentFlags (see Qt documentation) | ||
| are valid. The alignment refers to the center point of | ||
| the marker, which means, for example, that the label would be painted | ||
| left above the center point if the alignment was set to AlignLeft|AlignTop. | ||
| */ | ||
|
|
||
| class QWT_POLAR_EXPORT QwtPolarMarker: public QwtPolarItem | ||
| { | ||
| public: | ||
| explicit QwtPolarMarker(); | ||
| virtual ~QwtPolarMarker(); | ||
|
|
||
| virtual int rtti() const; | ||
|
|
||
| void setPosition( const QwtPointPolar & ); | ||
| QwtPointPolar position() const; | ||
|
|
||
| void setSymbol( const QwtSymbol *s ); | ||
| const QwtSymbol *symbol() const; | ||
|
|
||
| void setLabel( const QwtText& ); | ||
| QwtText label() const; | ||
|
|
||
| void setLabelAlignment( Qt::Alignment ); | ||
| Qt::Alignment labelAlignment() const; | ||
|
|
||
| virtual void draw( QPainter *painter, | ||
| const QwtScaleMap &azimuthMap, const QwtScaleMap &radialMap, | ||
| const QPointF &pole, double radius, | ||
| const QRectF &canvasRect ) const; | ||
|
|
||
| virtual QwtInterval boundingInterval( int scaleId ) const; | ||
|
|
||
| private: | ||
| class PrivateData; | ||
| PrivateData *d_data; | ||
| }; | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,118 @@ | ||
| /* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** | ||
| * QwtPolar Widget Library | ||
| * Copyright (C) 2008 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_polar_panner.h" | ||
| #include "qwt_polar_plot.h" | ||
| #include "qwt_polar_canvas.h" | ||
| #include <qwt_scale_div.h> | ||
| #include <qwt_point_polar.h> | ||
|
|
||
| //! Create a plot panner for a polar plot canvas | ||
| QwtPolarPanner::QwtPolarPanner( QwtPolarCanvas *canvas ): | ||
| QwtPanner( canvas ) | ||
| { | ||
| connect( this, SIGNAL( panned( int, int ) ), | ||
| SLOT( movePlot( int, int ) ) ); | ||
| } | ||
|
|
||
| //! Destructor | ||
| QwtPolarPanner::~QwtPolarPanner() | ||
| { | ||
| } | ||
|
|
||
| //! \return observed plot canvas | ||
| QwtPolarCanvas *QwtPolarPanner::canvas() | ||
| { | ||
| return qobject_cast<QwtPolarCanvas *>( parent() ); | ||
| } | ||
|
|
||
| //! \return observed plot canvas | ||
| const QwtPolarCanvas *QwtPolarPanner::canvas() const | ||
| { | ||
| return qobject_cast<const QwtPolarCanvas *>( parent() ); | ||
| } | ||
|
|
||
| //! \return observed plot | ||
| QwtPolarPlot *QwtPolarPanner::plot() | ||
| { | ||
| QwtPolarCanvas *c = canvas(); | ||
| if ( c ) | ||
| return c->plot(); | ||
|
|
||
| return NULL; | ||
| } | ||
|
|
||
| //! \return observed plot | ||
| const QwtPolarPlot *QwtPolarPanner::plot() const | ||
| { | ||
| const QwtPolarCanvas *c = canvas(); | ||
| if ( c ) | ||
| return c->plot(); | ||
|
|
||
| return NULL; | ||
| } | ||
|
|
||
| /*! | ||
| Adjust the zoomed area according to dx/dy | ||
| \param dx Pixel offset in x direction | ||
| \param dy Pixel offset in y direction | ||
| \sa QwtPanner::panned(), QwtPolarPlot::zoom() | ||
| */ | ||
| void QwtPolarPanner::movePlot( int dx, int dy ) | ||
| { | ||
| QwtPolarPlot *plot = QwtPolarPanner::plot(); | ||
| if ( plot == NULL || ( dx == 0 && dy == 0 ) ) | ||
| return; | ||
|
|
||
| const QwtScaleMap map = plot->scaleMap( QwtPolar::Radius ); | ||
|
|
||
| QwtPointPolar pos = plot->zoomPos(); | ||
| if ( map.s1() <= map.s2() ) | ||
| { | ||
| pos.setRadius( | ||
| map.transform( map.s1() + pos.radius() ) - map.p1() ); | ||
| pos.setPoint( pos.toPoint() - QPointF( dx, -dy ) ); | ||
| pos.setRadius( | ||
| map.invTransform( map.p1() + pos.radius() ) - map.s1() ); | ||
| } | ||
| else | ||
| { | ||
| pos.setRadius( | ||
| map.transform( map.s1() - pos.radius() ) - map.p1() ); | ||
| pos.setPoint( pos.toPoint() - QPointF( dx, -dy ) ); | ||
| pos.setRadius( | ||
| map.s1() - map.invTransform( map.p1() + pos.radius() ) ); | ||
| } | ||
|
|
||
| const bool doAutoReplot = plot->autoReplot(); | ||
| plot->setAutoReplot( false ); | ||
|
|
||
| plot->zoom( pos, plot->zoomFactor() ); | ||
|
|
||
| plot->setAutoReplot( doAutoReplot ); | ||
| plot->replot(); | ||
| } | ||
|
|
||
| /*! | ||
| Block panning when the plot zoom factor is >= 1.0. | ||
| \param event Mouse event | ||
| */ | ||
| void QwtPolarPanner::widgetMousePressEvent( QMouseEvent *event ) | ||
| { | ||
| const QwtPolarPlot *plot = QwtPolarPanner::plot(); | ||
| if ( plot ) | ||
| { | ||
| if ( plot->zoomFactor() < 1.0 ) | ||
| QwtPanner::widgetMousePressEvent( event ); | ||
| } | ||
| } | ||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| /* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** | ||
| * QwtPolar Widget Library | ||
| * Copyright (C) 2008 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 | ||
| *****************************************************************************/ | ||
|
|
||
| #ifndef QWT_POLAR_PANNER_H | ||
| #define QWT_POLAR_PANNER_H 1 | ||
|
|
||
| #include "qwt_polar_global.h" | ||
| #include "qwt_panner.h" | ||
|
|
||
| class QwtPolarPlot; | ||
| class QwtPolarCanvas; | ||
|
|
||
| /*! | ||
| \brief QwtPolarPanner provides panning of a polar plot canvas | ||
| QwtPolarPanner is a panner for a QwtPolarCanvas, that | ||
| adjusts the visible area after dropping | ||
| the canvas on its new position. | ||
| Together with QwtPolarMagnifier individual ways | ||
| of navigating on a QwtPolarPlot widget can be implemented easily. | ||
| \sa QwtPolarMagnifier | ||
| */ | ||
|
|
||
| class QWT_POLAR_EXPORT QwtPolarPanner: public QwtPanner | ||
| { | ||
| Q_OBJECT | ||
|
|
||
| public: | ||
| explicit QwtPolarPanner( QwtPolarCanvas * ); | ||
| virtual ~QwtPolarPanner(); | ||
|
|
||
| QwtPolarPlot *plot(); | ||
| const QwtPolarPlot *plot() const; | ||
|
|
||
| QwtPolarCanvas *canvas(); | ||
| const QwtPolarCanvas *canvas() const; | ||
|
|
||
| protected Q_SLOTS: | ||
| virtual void movePlot( int dx, int dy ); | ||
|
|
||
| protected: | ||
| virtual void widgetMousePressEvent( QMouseEvent * ); | ||
| }; | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,245 @@ | ||
| /* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** | ||
| * QwtPolar Widget Library | ||
| * Copyright (C) 2008 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_polar_picker.h" | ||
| #include "qwt_polar_plot.h" | ||
| #include "qwt_polar_canvas.h" | ||
| #include <qwt_scale_map.h> | ||
| #include <qwt_picker_machine.h> | ||
| #include <qwt_point_polar.h> | ||
|
|
||
| class QwtPolarPicker::PrivateData | ||
| { | ||
| public: | ||
| PrivateData() | ||
| { | ||
| } | ||
| }; | ||
|
|
||
| /*! | ||
| \brief Create a polar plot picker | ||
| \param canvas Plot canvas to observe, also the parent object | ||
| */ | ||
|
|
||
| QwtPolarPicker::QwtPolarPicker( QwtPolarCanvas *canvas ): | ||
| QwtPicker( canvas ) | ||
| { | ||
| d_data = new PrivateData; | ||
| } | ||
|
|
||
| /*! | ||
| Create a plot picker | ||
| \param rubberBand Rubberband style | ||
| \param trackerMode Tracker mode | ||
| \param canvas Plot canvas to observe, also the parent object | ||
| \sa QwtPicker, QwtPicker::setSelectionFlags(), QwtPicker::setRubberBand(), | ||
| QwtPicker::setTrackerMode | ||
| \sa QwtPolarPlot::autoReplot(), QwtPolarPlot::replot(), scaleRect() | ||
| */ | ||
| QwtPolarPicker::QwtPolarPicker( | ||
| RubberBand rubberBand, DisplayMode trackerMode, | ||
| QwtPolarCanvas *canvas ): | ||
| QwtPicker( rubberBand, trackerMode, canvas ) | ||
| { | ||
| d_data = new PrivateData; | ||
| } | ||
|
|
||
| //! Destructor | ||
| QwtPolarPicker::~QwtPolarPicker() | ||
| { | ||
| delete d_data; | ||
| } | ||
|
|
||
| //! \return Observed plot canvas | ||
| QwtPolarCanvas *QwtPolarPicker::canvas() | ||
| { | ||
| return qobject_cast<QwtPolarCanvas *>( parentWidget() ); | ||
| } | ||
|
|
||
| //! \return Observed plot canvas | ||
| const QwtPolarCanvas *QwtPolarPicker::canvas() const | ||
| { | ||
| return qobject_cast<const QwtPolarCanvas *>( parentWidget() ); | ||
| } | ||
|
|
||
| //! \return Plot widget, containing the observed plot canvas | ||
| QwtPolarPlot *QwtPolarPicker::plot() | ||
| { | ||
| QwtPolarCanvas *w = canvas(); | ||
| if ( w ) | ||
| return w->plot(); | ||
|
|
||
| return NULL; | ||
| } | ||
|
|
||
| //! \return Plot widget, containing the observed plot canvas | ||
| const QwtPolarPlot *QwtPolarPicker::plot() const | ||
| { | ||
| const QwtPolarCanvas *w = canvas(); | ||
| if ( w ) | ||
| return w->plot(); | ||
|
|
||
| return NULL; | ||
| } | ||
|
|
||
| /*! | ||
| Translate a pixel position into a position string | ||
| \param pos Position in pixel coordinates | ||
| \return Position string | ||
| */ | ||
| QwtText QwtPolarPicker::trackerText( const QPoint &pos ) const | ||
| { | ||
| return trackerTextPolar( invTransform( pos ) ); | ||
| } | ||
|
|
||
| /*! | ||
| \brief Translate a position into a position string | ||
| In case of HLineRubberBand the label is the value of the | ||
| y position, in case of VLineRubberBand the value of the x position. | ||
| Otherwise the label contains x and y position separated by a ',' . | ||
| The format for the double to string conversion is "%.4f". | ||
| \param pos Position | ||
| \return Position string | ||
| */ | ||
| QwtText QwtPolarPicker::trackerTextPolar( const QwtPointPolar &pos ) const | ||
| { | ||
| QString text; | ||
| text.sprintf( "%.4f, %.4f", pos.radius(), pos.azimuth() ); | ||
|
|
||
| return QwtText( text ); | ||
| } | ||
|
|
||
| /*! | ||
| Append a point to the selection and update rubberband and tracker. | ||
| \param pos Additional point | ||
| \sa isActive, begin(), end(), move(), appended() | ||
| \note The appended(const QPoint &), appended(const QDoublePoint &) | ||
| signals are emitted. | ||
| */ | ||
| void QwtPolarPicker::append( const QPoint &pos ) | ||
| { | ||
| QwtPicker::append( pos ); | ||
| Q_EMIT appended( invTransform( pos ) ); | ||
| } | ||
|
|
||
| /*! | ||
| Move the last point of the selection | ||
| \param pos New position | ||
| \sa isActive, begin(), end(), append() | ||
| \note The moved(const QPoint &), moved(const QDoublePoint &) | ||
| signals are emitted. | ||
| */ | ||
| void QwtPolarPicker::move( const QPoint &pos ) | ||
| { | ||
| QwtPicker::move( pos ); | ||
| Q_EMIT moved( invTransform( pos ) ); | ||
| } | ||
|
|
||
| /*! | ||
| Close a selection setting the state to inactive. | ||
| \param ok If true, complete the selection and emit selected signals | ||
| otherwise discard the selection. | ||
| \return true if the selection is accepted, false otherwise | ||
| */ | ||
|
|
||
| bool QwtPolarPicker::end( bool ok ) | ||
| { | ||
| ok = QwtPicker::end( ok ); | ||
| if ( !ok ) | ||
| return false; | ||
|
|
||
| QwtPolarPlot *plot = QwtPolarPicker::plot(); | ||
| if ( !plot ) | ||
| return false; | ||
|
|
||
| const QPolygon points = selection(); | ||
| if ( points.count() == 0 ) | ||
| return false; | ||
|
|
||
| QwtPickerMachine::SelectionType selectionType = | ||
| QwtPickerMachine::NoSelection; | ||
|
|
||
| if ( stateMachine() ) | ||
| selectionType = stateMachine()->selectionType(); | ||
|
|
||
| switch ( selectionType ) | ||
| { | ||
| case QwtPickerMachine::PointSelection: | ||
| { | ||
| const QwtPointPolar pos = invTransform( points[0] ); | ||
| Q_EMIT selected( pos ); | ||
| break; | ||
| } | ||
| case QwtPickerMachine::RectSelection: | ||
| case QwtPickerMachine::PolygonSelection: | ||
| { | ||
| QVector<QwtPointPolar> polarPoints( points.count() ); | ||
| for ( int i = 0; i < points.count(); i++ ) | ||
| polarPoints[i] = invTransform( points[i] ); | ||
|
|
||
| Q_EMIT selected( polarPoints ); | ||
| } | ||
| default: | ||
| break; | ||
| } | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
| /*! | ||
| Translate a point from widget into plot coordinates | ||
| \param pos Point in widget coordinates of the plot canvas | ||
| \return Point in plot coordinates | ||
| \sa transform(), canvas() | ||
| */ | ||
| QwtPointPolar QwtPolarPicker::invTransform( const QPoint &pos ) const | ||
| { | ||
| QwtPointPolar polarPos; | ||
| if ( canvas() == NULL ) | ||
| return QwtPointPolar(); | ||
|
|
||
| return canvas()->invTransform( pos ); | ||
| } | ||
|
|
||
| /*! | ||
| \return Bounding rectangle of the region, where picking is | ||
| supported. | ||
| */ | ||
| QRect QwtPolarPicker::pickRect() const | ||
| { | ||
| const QRect cr = canvas()->contentsRect(); | ||
| const QRect pr = plot()->plotRect( cr ).toRect(); | ||
|
|
||
| return cr & pr; | ||
| } | ||
|
|
||
| QPainterPath QwtPolarPicker::pickArea() const | ||
| { | ||
| const QRect cr = canvas()->contentsRect(); | ||
|
|
||
| QPainterPath crPath; | ||
| crPath.addRect( cr ); | ||
|
|
||
| QPainterPath prPath; | ||
| prPath.addEllipse( plot()->plotRect( cr ) ); | ||
|
|
||
| return crPath.intersected( prPath ); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| /* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** | ||
| * QwtPolar Widget Library | ||
| * Copyright (C) 2008 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 | ||
| *****************************************************************************/ | ||
|
|
||
| #ifndef QWT_POLAR_PICKER_H | ||
| #define QWT_POLAR_PICKER_H | ||
|
|
||
| #include "qwt_polar_global.h" | ||
| #include "qwt_picker.h" | ||
| #include <qvector.h> | ||
| #include <qpainterpath.h> | ||
|
|
||
| class QwtPolarPlot; | ||
| class QwtPolarCanvas; | ||
| class QwtPointPolar; | ||
|
|
||
| /*! | ||
| \brief QwtPolarPicker provides selections on a plot canvas | ||
| QwtPolarPicker is a QwtPicker tailored for selections on | ||
| a polar plot canvas. | ||
| */ | ||
|
|
||
| class QWT_POLAR_EXPORT QwtPolarPicker: public QwtPicker | ||
| { | ||
| Q_OBJECT | ||
|
|
||
| public: | ||
| explicit QwtPolarPicker( QwtPolarCanvas * ); | ||
| virtual ~QwtPolarPicker(); | ||
|
|
||
| explicit QwtPolarPicker( | ||
| RubberBand rubberBand, DisplayMode trackerMode, | ||
| QwtPolarCanvas * ); | ||
|
|
||
| QwtPolarPlot *plot(); | ||
| const QwtPolarPlot *plot() const; | ||
|
|
||
| QwtPolarCanvas *canvas(); | ||
| const QwtPolarCanvas *canvas() const; | ||
|
|
||
| virtual QRect pickRect() const; | ||
|
|
||
| Q_SIGNALS: | ||
|
|
||
| /*! | ||
| A signal emitted in case of selectionFlags() & PointSelection. | ||
| \param pos Selected point | ||
| */ | ||
| void selected( const QwtPointPolar &pos ); | ||
|
|
||
| /*! | ||
| A signal emitting the selected points, | ||
| at the end of a selection. | ||
| \param points Selected points | ||
| */ | ||
| void selected( const QVector<QwtPointPolar> &points ); | ||
|
|
||
| /*! | ||
| A signal emitted when a point has been appended to the selection | ||
| \param pos Position of the appended point. | ||
| \sa append(). moved() | ||
| */ | ||
| void appended( const QwtPointPolar &pos ); | ||
|
|
||
| /*! | ||
| A signal emitted whenever the last appended point of the | ||
| selection has been moved. | ||
| \param pos Position of the moved last point of the selection. | ||
| \sa move(), appended() | ||
| */ | ||
| void moved( const QwtPointPolar &pos ); | ||
|
|
||
| protected: | ||
| QwtPointPolar invTransform( const QPoint & ) const; | ||
|
|
||
| virtual QwtText trackerText( const QPoint & ) const; | ||
| virtual QwtText trackerTextPolar( const QwtPointPolar & ) const; | ||
|
|
||
| virtual void move( const QPoint & ); | ||
| virtual void append( const QPoint & ); | ||
| virtual bool end( bool ok = true ); | ||
|
|
||
| private: | ||
| virtual QPainterPath pickArea() const; | ||
|
|
||
| class PrivateData; | ||
| PrivateData *d_data; | ||
| }; | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,219 @@ | ||
| /* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** | ||
| * QwtPolar Widget Library | ||
| * Copyright (C) 2008 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 | ||
| *****************************************************************************/ | ||
|
|
||
| #ifndef QWT_POLAR_PLOT_H | ||
| #define QWT_POLAR_PLOT_H 1 | ||
|
|
||
| #include "qwt_polar_global.h" | ||
| #include "qwt_polar.h" | ||
| #include "qwt_polar_itemdict.h" | ||
| #include <qwt_interval.h> | ||
| #include <qwt_scale_map.h> | ||
| #include <qwt_point_polar.h> | ||
| #include <qframe.h> | ||
|
|
||
| class QwtRoundScaleDraw; | ||
| class QwtScaleEngine; | ||
| class QwtScaleDiv; | ||
| class QwtTextLabel; | ||
| class QwtPolarCanvas; | ||
| class QwtPolarLayout; | ||
|
|
||
| /*! | ||
| \brief A plotting widget, displaying a polar coordinate system | ||
| An unlimited number of plot items can be displayed on | ||
| its canvas. Plot items might be curves (QwtPolarCurve), markers | ||
| (QwtPolarMarker), the grid (QwtPolarGrid), or anything else derived | ||
| from QwtPolarItem. | ||
| The coordinate system is defined by a radial and a azimuth scale. | ||
| The scales at the axes can be explicitely set (QwtScaleDiv), or | ||
| are calculated from the plot items, using algorithms (QwtScaleEngine) which | ||
| can be configured separately for each axis. Autoscaling is supported | ||
| for the radial scale. | ||
| In opposite to QwtPlot the scales might be different from the | ||
| view, that is displayed on the canvas. The view can be changed by | ||
| zooming - f.e. by using QwtPolarPanner or QwtPolarMaginfier. | ||
| */ | ||
| class QWT_POLAR_EXPORT QwtPolarPlot: public QFrame, public QwtPolarItemDict | ||
| { | ||
| Q_OBJECT | ||
|
|
||
| Q_PROPERTY( QBrush plotBackground READ plotBackground WRITE setPlotBackground ) | ||
| Q_PROPERTY( double azimuthOrigin READ azimuthOrigin WRITE setAzimuthOrigin ) | ||
|
|
||
|
|
||
| public: | ||
| /*! | ||
| Position of the legend, relative to the canvas. | ||
| \sa insertLegend() | ||
| */ | ||
| enum LegendPosition | ||
| { | ||
| //! The legend will be left from the canvas. | ||
| LeftLegend, | ||
|
|
||
| //! The legend will be right from the canvas. | ||
| RightLegend, | ||
|
|
||
| //! The legend will be below the canvas. | ||
| BottomLegend, | ||
|
|
||
| //! The legend will be between canvas and title. | ||
| TopLegend, | ||
|
|
||
| /*! | ||
| External means that only the content of the legend | ||
| will be handled by QwtPlot, but not its geometry. | ||
| This might be interesting if an application wants to | ||
| have a legend in an external window ( or on the canvas ). | ||
| \note The legend is not painted by QwtPolarRenderer | ||
| */ | ||
| ExternalLegend | ||
| }; | ||
|
|
||
| explicit QwtPolarPlot( QWidget *parent = NULL ); | ||
| QwtPolarPlot( const QwtText &title, QWidget *parent = NULL ); | ||
|
|
||
| virtual ~QwtPolarPlot(); | ||
|
|
||
| void setTitle( const QString & ); | ||
| void setTitle( const QwtText & ); | ||
|
|
||
| QwtText title() const; | ||
|
|
||
| QwtTextLabel *titleLabel(); | ||
| const QwtTextLabel *titleLabel() const; | ||
|
|
||
| void setAutoReplot( bool tf = true ); | ||
| bool autoReplot() const; | ||
|
|
||
| void setAutoScale( int scaleId ); | ||
| bool hasAutoScale( int scaleId ) const; | ||
|
|
||
| void setScaleMaxMinor( int scaleId, int maxMinor ); | ||
| int scaleMaxMinor( int scaleId ) const; | ||
|
|
||
| int scaleMaxMajor( int scaleId ) const; | ||
| void setScaleMaxMajor( int scaleId, int maxMajor ); | ||
|
|
||
| QwtScaleEngine *scaleEngine( int scaleId ); | ||
| const QwtScaleEngine *scaleEngine( int scaleId ) const; | ||
| void setScaleEngine( int scaleId, QwtScaleEngine * ); | ||
|
|
||
| void setScale( int scaleId, double min, double max, double step = 0 ); | ||
|
|
||
| void setScaleDiv( int scaleId, const QwtScaleDiv & ); | ||
| const QwtScaleDiv *scaleDiv( int scaleId ) const; | ||
| QwtScaleDiv *scaleDiv( int scaleId ); | ||
|
|
||
| QwtScaleMap scaleMap( int scaleId, double radius ) const; | ||
| QwtScaleMap scaleMap( int scaleId ) const; | ||
|
|
||
| void updateScale( int scaleId ); | ||
|
|
||
| double azimuthOrigin() const; | ||
|
|
||
| void zoom( const QwtPointPolar&, double factor ); | ||
| void unzoom(); | ||
|
|
||
| QwtPointPolar zoomPos() const; | ||
| double zoomFactor() const; | ||
|
|
||
| // Canvas | ||
|
|
||
| QwtPolarCanvas *canvas(); | ||
| const QwtPolarCanvas *canvas() const; | ||
|
|
||
| void setPlotBackground ( const QBrush &c ); | ||
| const QBrush& plotBackground() const; | ||
|
|
||
| virtual void drawCanvas( QPainter *, const QRectF & ) const; | ||
|
|
||
| // Legend | ||
|
|
||
| void insertLegend( QwtLegend *, | ||
| LegendPosition = RightLegend, double ratio = -1.0 ); | ||
|
|
||
| QwtLegend *legend(); | ||
| const QwtLegend *legend() const; | ||
|
|
||
| // Layout | ||
| QwtPolarLayout *plotLayout(); | ||
| const QwtPolarLayout *plotLayout() const; | ||
|
|
||
| QwtInterval visibleInterval() const; | ||
| QRectF plotRect() const; | ||
| QRectF plotRect( const QRectF & ) const; | ||
|
|
||
| int plotMarginHint() const; | ||
|
|
||
| Q_SIGNALS: | ||
| /*! | ||
| A signal which is emitted when the user has clicked on | ||
| a legend item, which is in QwtLegend::ClickableItem mode. | ||
| \param plotItem Corresponding plot item of the | ||
| selected legend item | ||
| \note clicks are disabled as default | ||
| \sa QwtLegend::setItemMode, QwtLegend::itemMode | ||
| */ | ||
| void legendClicked( QwtPolarItem *plotItem ); | ||
|
|
||
| /*! | ||
| A signal which is emitted when the user has clicked on | ||
| a legend item, which is in QwtLegend::CheckableItem mode | ||
| \param plotItem Corresponding plot item of the | ||
| selected legend item | ||
| \param on True when the legen item is checked | ||
| \note clicks are disabled as default | ||
| \sa QwtLegend::setItemMode, QwtLegend::itemMode | ||
| */ | ||
| void legendChecked( QwtPolarItem *plotItem, bool on ); | ||
|
|
||
| /*! | ||
| A signal that is emitted, whenever the layout of the plot | ||
| has been recalculated. | ||
| */ | ||
| void layoutChanged(); | ||
|
|
||
| public Q_SLOTS: | ||
| virtual void replot(); | ||
| void autoRefresh(); | ||
| void setAzimuthOrigin( double ); | ||
|
|
||
| protected Q_SLOTS: | ||
| virtual void legendItemClicked(); | ||
| virtual void legendItemChecked( bool ); | ||
|
|
||
| protected: | ||
| virtual bool event( QEvent * ); | ||
| virtual void resizeEvent( QResizeEvent * ); | ||
|
|
||
| virtual void updateLayout(); | ||
|
|
||
| virtual void drawItems( QPainter *painter, | ||
| const QwtScaleMap &radialMap, const QwtScaleMap &azimuthMap, | ||
| const QPointF &pole, double radius, | ||
| const QRectF &canvasRect ) const; | ||
|
|
||
| private: | ||
| void initPlot( const QwtText & ); | ||
|
|
||
| class ScaleData; | ||
| class PrivateData; | ||
| PrivateData *d_data; | ||
| }; | ||
|
|
||
| #endif |