casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
QPCanvasHelpers.qo.h
Go to the documentation of this file.
00001 //# QPCanvasHelpers.qo.h: Helper classes for QPCanvas.
00002 //# Copyright (C) 2008
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //# $Id: $
00027 #ifndef QPCANVASHELPERS_QO_H_
00028 #define QPCANVASHELPERS_QO_H_
00029 
00030 #ifdef AIPS_HAS_QWT
00031 
00032 #include <casaqt/QwtPlotter/QPOptions.h>
00033 #include <casaqt/QwtPlotter/QPPlotItem.qo.h>
00034 #include <graphics/GenericPlotter/PlotCanvas.h>
00035 
00036 #include <qwt_legend.h>
00037 #include <qwt_plot.h>
00038 #include <qwt_plot_grid.h>
00039 #include <qwt_scale_draw.h>
00040 
00041 #include <QObject>
00042 #include <QMouseEvent>
00043 #include <QSpacerItem>
00044 
00045 #include <casa/namespace.h>
00046 
00047 namespace casa {
00048 
00049 //# Forward Declarations
00050 class QPCanvas;
00051 
00052 
00053 // Miscellaneous Classes //
00054 
00055 // Filter to install on the QwtPlotCanvas to catch mouse move events (which
00056 // are otherwise stolen by other filters in QwtPicker classes).
00057 class QPMouseFilter : public QObject {
00058     Q_OBJECT
00059     
00060 public:
00061     // Constructor which takes the canvas to install itself on.
00062     QPMouseFilter(QwtPlotCanvas* canvas);
00063     
00064     // Destructor.
00065     ~QPMouseFilter();
00066     
00067     // Turns mouse tracking on or off on the underlying canvas.
00068     void turnTracking(bool on);
00069     
00070 signals:
00071     // This signal is emitted if tracking is turned on, and when a
00072     // QMouseEvent is received for a mouse move on the underlying canvas.
00073     void mouseMoveEvent(QMouseEvent* e);
00074     
00075 protected:
00076     // Filter the events on the given object.  Checks only for mouse events
00077     // on the underlying canvas.
00078     bool eventFilter(QObject* obj, QEvent* ev);
00079     
00080 private:
00081     // Canvas.
00082     QwtPlotCanvas* m_canvas;
00083 };
00084 
00085 
00086 // Subclass of QwtScaleDraw to implement additional functionality.  Keeps track
00087 // of which PlotAxisScale is set, and can use reference values instead of
00088 // absolute values (see PlotCanvas::setAxisReferenceValue()).  Additionally,
00089 // for date values it can convert a double in either modified julian seconds or
00090 // modified julian days into a String representation of the date, using a
00091 // format that can be set.
00092 class QPScaleDraw : public QwtScaleDraw {
00093 public: 
00094         // Constructor that takes the parent and axis to attach to.
00095     QPScaleDraw(QwtPlot* parent, QwtPlot::Axis axis);
00096     
00097     // Destructor.
00098     ~QPScaleDraw();
00099     
00100     // Gets/Sets the scale used.
00101     // <group>
00102     PlotAxisScale scale() const;
00103     void setScale(PlotAxisScale scale);
00104     // </group>
00105     
00106     // Gets/Sets the format used for date values.  See Plotter::dateFormat().
00107     // <group>
00108     const String& dateFormat() const;
00109     void setDateFormat(const String& newFormat);
00110     // </group>
00111     
00112     // Gets/Sets the format used for relative date values.  See
00113     // Plotter::relativeDateFormat().
00114     // <group>
00115     const String& relativeDateFormat() const;
00116     void setRelativeDateFormat(const String& newFormat);
00117     // </group>
00118     
00119     // Gets/Sets the reference value.  See PlotCanvas::setAxisReferenceValue().
00120     // <group>
00121     bool referenceValueSet() const;    
00122     double referenceValue() const;    
00123     void setReferenceValue(bool on, double value = 0);
00124     // </group>
00125     
00126     // Overrides QwtScaleDraw::label().
00127     QwtText label(double value) const;
00128     
00129 private:
00130         // Parent.
00131         QwtPlot* m_parent;
00132         
00133         // Axis.
00134         QwtPlot::Axis m_axis;
00135         
00136         // Scale.
00137         PlotAxisScale m_scale;
00138         
00139         // Date formats.
00140         // <group>
00141         String m_dateFormat;
00142         String m_relativeDateFormat;
00143         // </group>
00144         
00145         // Reference value.
00146         // <group>
00147         bool m_referenceSet;
00148         double m_referenceValue;
00149         // </group>
00150 };
00151 
00152 
00153 // Legend Classes //
00154 
00155 // Subclass of QwtLegend to handle outline and background, and be able to draw
00156 // itself using a QPainter.
00157 class QPLegend : public QwtLegend {
00158 public:
00159     // Constructor which takes optional parent widget.
00160     QPLegend(QWidget* parent = NULL);
00161     
00162     // Destructor.
00163     ~QPLegend();
00164     
00165     
00166     // Overrides QwtLegend::sizeHint() to take border into account.
00167     QSize sizeHint() const;
00168     
00169     // Gets/Sets the outline.
00170     // <group>
00171     const QPLine& line() const;
00172     const QPen& pen() const;
00173     void setLine(const PlotLine& line);
00174     void setLine(const QPen& pen) { setLine(QPLine(pen)); }
00175     // </group>
00176     
00177     // Gets/Sets the background.
00178     // <group>
00179     const QPAreaFill& areaFill() const;
00180     const QBrush& brush() const;
00181     void setAreaFill(const PlotAreaFill& fill);
00182     void setAreaFill(const QBrush& brush) { setAreaFill(QPAreaFill(brush)); }
00183     // </group>
00184     
00185     // Draws the legend's outline and bacgkround using the given painter on the
00186     // given rect.  If useQwtPainter is true, QwtPainter is used (which
00187     // preserves any set QwtMetricsMap).
00188     void drawOutlineAndBackground(QPainter* painter, const QRect& rect,
00189             bool useQwtPainter = false);
00190     
00191 protected:
00192     // Overrides QWidget::paintEvent() to draw outline and background if
00193     // needed.
00194     void paintEvent(QPaintEvent* event);
00195     
00196 private:
00197     // Outline.
00198     QPLine m_line;
00199     
00200     // Background.
00201     QPAreaFill m_areaFill;
00202 };
00203 
00204 
00205 // Holder for QPLegend that is responsible for its placement.
00206 class QPLegendHolder : public QWidget {
00207     Q_OBJECT
00208     
00209 public:
00210     // Default padding for internal legends.
00211     static const int DEFAULT_INTERNAL_PADDING;
00212     
00213     // Converts from our legend position to Qwt's.
00214     static QwtPlot::LegendPosition legendPosition(
00215             PlotCanvas::LegendPosition pos);
00216     
00217     
00218     // Constructor which takes the canvas and initial position.
00219     QPLegendHolder(QPCanvas* canvas, PlotCanvas::LegendPosition position,
00220             int padding = DEFAULT_INTERNAL_PADDING);
00221     
00222     // Destructor.
00223     ~QPLegendHolder();
00224 
00225     
00226     // Shows/hides the legend.
00227     // <group>
00228     bool legendShown() const;
00229     void showLegend(bool show = true);
00230     // </group>
00231     
00232     // Gets/Sets the legend position.
00233     // <group>
00234     bool isInternal() const;
00235     PlotCanvas::LegendPosition position() const;
00236     void setPosition(PlotCanvas::LegendPosition position);
00237     // </group>
00238     
00239     // Gets/Sets the outline.
00240     // <group>
00241     const QPLine& line() const { return m_legend->line(); }
00242     const QPen& pen() const { return m_legend->pen(); }
00243     void setLine(const PlotLine& line) { m_legend->setLine(line); }
00244     void setLine(const QPen& pen) { m_legend->setLine(pen); }
00245     // </group>
00246     
00247     // Gets/Sets the background.
00248     // <group>
00249     const QPAreaFill& areaFill() const { return m_legend->areaFill(); }
00250     const QBrush& brush() const { return m_legend->brush(); }
00251     void setAreaFill(const PlotAreaFill& fill) { m_legend->setAreaFill(fill); }
00252     void setAreaFill(const QBrush& brush) { m_legend->setAreaFill(brush); }
00253     // </group>
00254     
00255     // Returns the rect for the internal legend, given a canvas rect.
00256     QRect internalLegendRect(const QRect& canvasRect,
00257             bool useQwtPainter = false) const;
00258     
00259     // See QPLegend::drawOutlineAndBackground.
00260     void drawOutlineAndBackground(QPainter* painter, const QRect& rect,
00261             bool useQwtPainter = false) {
00262         m_legend->drawOutlineAndBackground(painter, rect, useQwtPainter); }
00263     
00264 private:
00265     // Canvas.
00266     QPCanvas* m_canvas;
00267     
00268     // Actual legend.
00269     QPLegend* m_legend;
00270     
00271     // Current position.
00272     PlotCanvas::LegendPosition m_position;
00273     
00274     // Spacers for internal legends.
00275     QSpacerItem* m_spaceTop, *m_spaceLeft, *m_spaceRight, *m_spaceBottom;
00276     
00277     // Padding for internal legends.
00278     int m_padding;
00279     
00280     
00281     // Update the spacers for the position, padding, and line width.
00282     void updateSpacers();
00283 };
00284 
00285 
00286 // "Base" Item Classes //
00287 
00288 // Abstract superclass for all "base" item classes.  Base items are a special
00289 // type of plot item that are not PlotItems but *are* QwtPlotItems that go
00290 // below the normal items.
00291 class QPBaseItem : public QPLayerItem {
00292     friend class QPLayeredCanvas;
00293     
00294 public:
00295     // Z indexes for known base items.
00296     // <group>
00297     static const double BASE_Z_CARTAXIS;
00298     static const double BASE_Z_GRID;
00299     // </group>    
00300     
00301     
00302     // Constructor.
00303     QPBaseItem();
00304     
00305     // Destructor.
00306     virtual ~QPBaseItem();
00307     
00308     
00309     // Implements QPLayerItem::itemChanged().  Calls default definition.
00310     virtual void itemChanged() { QwtPlotItem::itemChanged(); }
00311     
00312     // Implements QPLayerItem::itemDrawCount().
00313     virtual unsigned int itemDrawCount() const { return 1; }
00314     
00315 protected:
00316     // Attached canvas, or NULL for none.
00317     QPCanvas* m_canvas;
00318     
00319     
00320     // Attaches this item to the given canvas.
00321     void qpAttach(QPCanvas* canvas);
00322     
00323     // Detaches this item from its canvas.
00324     void qpDetach();
00325 };
00326 
00327 
00328 // Subclass of QPBaseItem for drawing grids.  Basically just a wrapper for
00329 // QwtPlotGrid.
00330 class QPGrid : public QPBaseItem, public QwtPlotGrid {
00331 public:
00332     // Constructor.
00333     QPGrid();
00334     
00335     // Destructor.
00336     ~QPGrid();
00337     
00338 
00339     // Overrides QwtPlotItem::itemChanged() to use QPBaseItem's definition.
00340     void itemChanged() { QPBaseItem::itemChanged(); }
00341     
00342     // Implements QPLayerItem::shouldDraw().
00343     bool shouldDraw() const;
00344     
00345     // Implements QPLayerItem::itemTitle().
00346     String itemTitle() const { return "grid"; }
00347     
00348     // Overrides QwtPlotItem::boundingRect() to use QwtPlotGrid's definition.
00349     QwtDoubleRect boundingRect() const { return QwtPlotGrid::boundingRect(); }
00350     
00351     // Overrides QwtPlotItem::updateScaleDiv() to use QwtPlotGrid's definition.
00352     void updateScaleDiv(const QwtScaleDiv& xDiv, const QwtScaleDiv& yDiv) {
00353         QwtPlotGrid::updateScaleDiv(xDiv, yDiv); }
00354     
00355 protected:
00356     // Implements QPLayerItem::draw_().  Ignores draw index and count.
00357     void draw_(QPainter* p, const QwtScaleMap& xMap,
00358                 const QwtScaleMap& yMap, const QRect& drawRect,
00359                 unsigned int drawIndex, unsigned int drawCount) const {
00360                 (void)drawIndex; (void)drawCount;
00361         QwtPlotGrid::draw(p, xMap, yMap, drawRect); }
00362 };
00363 
00364 
00365 // Subclass of QPBaseItem for drawing cartesian axes.  See
00366 // http://pyqwt.sourceforge.net/examples/CartesianDemo.py.html .
00367 class QPCartesianAxis : public QPBaseItem {
00368 public:
00369     // "Master" is the one being drawn; "slave" is the one that the master
00370     // is attached to.
00371     QPCartesianAxis(QwtPlot::Axis master, QwtPlot::Axis slave);
00372     
00373     // Destructor.
00374     ~QPCartesianAxis();
00375 
00376     
00377     // Implements QPLayerItem::shouldDraw().
00378     bool shouldDraw() const { return true; }
00379     
00380     // Implements QPLayerItem::itemTitle().
00381     String itemTitle() const { return "cartesian axis"; }
00382     
00383 protected:
00384     // Implements QPLayerItem::draw_().  Ignores draw index and count.
00385     void draw_(QPainter* p, const QwtScaleMap& xMap,
00386                 const QwtScaleMap& yMap, const QRect& drawRect,
00387                 unsigned int drawIndex, unsigned int drawCount) const;
00388     
00389 private:
00390     // Master axis.
00391     QwtPlot::Axis m_axis;
00392     
00393     // Scale draw.
00394     QwtScaleDraw m_scaleDraw;
00395 };
00396 
00397 }
00398 
00399 #endif
00400 
00401 #endif /* QPCANVASHELPERS_QO_H_ */