casa
$Rev:20696$
|
00001 //# QPPlotItem.qo.h: Superclass for all plot items in qwt plotter. 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 QPPLOTITEM_H_ 00028 #define QPPLOTITEM_H_ 00029 00030 #ifdef AIPS_HAS_QWT 00031 00032 #include <graphics/GenericPlotter/PlotItem.h> 00033 00034 #include <casaqt/QwtPlotter/QPImageCache.h> 00035 #include <graphics/GenericPlotter/PlotLogger.h> 00036 #include <graphics/GenericPlotter/PlotOperation.h> 00037 00038 #include <QHash> 00039 #include <QPainter> 00040 #include <QThread> 00041 00042 #include <qwt_plot.h> 00043 00044 #include <casa/namespace.h> 00045 00046 namespace casa { 00047 00048 //# Forward Declarations 00049 class QPCanvas; 00050 00051 00052 // Abstract superclass for any layered item that will be drawn on a 00053 // QPLayeredCanvas. 00054 class QPLayerItem : public virtual QwtPlotItem { 00055 friend class QPCanvas; 00056 friend class QPLayeredCanvas; 00057 friend class QPDrawThread; 00058 00059 public: 00060 // Constructor. 00061 QPLayerItem(); 00062 00063 // Destructor. 00064 virtual ~QPLayerItem(); 00065 00066 00067 // Implements QwtPlotItem::draw(). 00068 virtual void draw(QPainter* p, const QwtScaleMap& xMap, 00069 const QwtScaleMap& yMap, const QRect& canvasRect) const; 00070 00071 // See PlotItem::drawSegments(). 00072 virtual unsigned int itemDrawSegments(unsigned int segmentThreshold) const; 00073 00074 00075 // ABSTRACT METHODS // 00076 00077 // Forces subclasses to override QwtPlotItem::itemChanged() to redraw only 00078 // the necessary layer. 00079 virtual void itemChanged() = 0; 00080 00081 // Returns true if this item should be drawn, false otherwise. This is 00082 // used to avoid drawing attached items that are empty or otherwise have 00083 // nothing to draw. 00084 virtual bool shouldDraw() const = 0; 00085 00086 // See PlotItem::drawCount(). 00087 virtual unsigned int itemDrawCount() const = 0; 00088 00089 // See PlotItem::title(). 00090 virtual String itemTitle() const = 0; 00091 00092 protected: 00093 // Like QwtPlotItem::draw() except that the child item should only draw 00094 // drawCount items starting at drawIndex. The indexing may not be 00095 // applicable to all layer items (i.e., some items may draw everything in 00096 // this call rather than segmenting). 00097 virtual void draw_(QPainter* p, const QwtScaleMap& xMap, 00098 const QwtScaleMap& yMap, const QRect& drawRect, 00099 unsigned int drawIndex, unsigned int drawCount) const = 0; 00100 }; 00101 00102 00103 // Subclass of PlotItem to take care of common functionality that is provided 00104 // by QwtPlotItem. 00105 class QPPlotItem : public virtual PlotItem, public QPLayerItem { 00106 friend class QPCanvas; 00107 friend class QPDrawThread; 00108 00109 public: 00110 // Static // 00111 00112 // Convenient access to "origin" name for draw method for logging. 00113 static const String DRAW_NAME; 00114 00115 00116 // Returns true if the given pointer is a Qwt plotter implementation, 00117 // false otherwise. 00118 static bool isQPPlotItem(const PlotItemPtr item); 00119 00120 // If the given item is not a Qwt plotter implementation, returns a copy 00121 // of the proper class. Otherwise, returns the item. If wasCloned is 00122 // given, it will be set to true if the returned item is new, false 00123 // otherwise. 00124 static QPPlotItem* cloneItem(const PlotItemPtr item, bool* wasCloned=NULL); 00125 00126 // Returns true if the two items are the same type (class), false 00127 // otherwise. 00128 static bool sameType(QPPlotItem* item1, QPPlotItem* item2); 00129 00130 // Returns true if the given item is a Plot type (QPBarPlot, QPHistogram, 00131 // QPRasterPlot, or QPScatterPlot) or not. 00132 static bool isPlot(QPPlotItem* item); 00133 00134 00135 // Non-Static // 00136 00137 // Constructor. 00138 QPPlotItem(); 00139 00140 // Destructor. 00141 virtual ~QPPlotItem(); 00142 00143 00144 // PlotItem methods // 00145 00146 // Implements PlotItem::canvas(). 00147 PlotCanvas* canvas() const; 00148 00149 // Implements PlotItem::title(). 00150 String title() const; 00151 00152 // Implements PlotItem::setTitle(). 00153 void setTitle(const String& newTitle); 00154 00155 // Implements PlotItem::isQWidget(). 00156 virtual bool isQWidget() const { return false; } 00157 00158 // Implements PlotItem::xAxis(). 00159 PlotAxis xAxis() const; 00160 00161 // Implements PlotItem::yAxis(). 00162 PlotAxis yAxis() const; 00163 00164 // Implements PlotItem::setXAxis(). 00165 void setXAxis(PlotAxis x); 00166 00167 // Implements PlotItem::setYAxis(). 00168 void setYAxis(PlotAxis y); 00169 00170 00171 // QPLayerItem methods // 00172 00173 // Implements QPLayerItem::itemChanged() to only redraw the canvas layer 00174 // this item is in. 00175 virtual void itemChanged(); 00176 00177 // Implements QPLayerItem::shouldDraw(). 00178 virtual bool shouldDraw() const { return isValid(); } 00179 00180 // Implements QPLayerItem::itemDrawCount(). 00181 unsigned int itemDrawCount() const{ return shouldDraw()? drawCount() : 0; } 00182 00183 // Implements QPLayerItem::itemTitle(). 00184 String itemTitle() const { return title(); } 00185 00186 00187 // QPPlotItem methods // 00188 00189 // Returns the layer this item is attached to. 00190 PlotCanvasLayer canvasLayer() const { return m_layer; } 00191 00192 // Provides access to QwtPlotItem methods that have been overloaded. 00193 // <group> 00194 const QwtText& qwtTitle() const { return QwtPlotItem::title(); } 00195 void setQwtTitle(const QwtText& text) { QwtPlotItem::setTitle(text); } 00196 QwtPlot::Axis qwtXAxis() const{return QwtPlot::Axis(QwtPlotItem::xAxis());} 00197 QwtPlot::Axis qwtYAxis() const{return QwtPlot::Axis(QwtPlotItem::yAxis());} 00198 void qwtAttach(QwtPlot* plot) { QwtPlotItem::attach(plot); } 00199 void qwtDetach() { QwtPlotItem::detach(); } 00200 // </group> 00201 00202 00203 // ABSTRACT METHODS // 00204 00205 // Forces children to override QwtPlotItem::boundingRect(). 00206 virtual QwtDoubleRect boundingRect() const = 0; 00207 00208 // Forces children to override QwtPlotItem::legendItem(). 00209 virtual QWidget* legendItem() const = 0; 00210 00211 protected: 00212 // Attached canvas (or NULL for none). 00213 QPCanvas* m_canvas; 00214 00215 // Flag for whether this object's creation has been logged or not. This 00216 // happens the first time the item is attached to a canvas. 00217 bool m_loggedCreation; 00218 00219 // Which layer this item is in. 00220 PlotCanvasLayer m_layer; 00221 00222 00223 // Provides access to QwtPlotItem's attach and detach methods for QPCanvas. 00224 // <group> 00225 void attach(QPCanvas* canvas, PlotCanvasLayer layer); 00226 void detach(); 00227 // </group> 00228 00229 // Provides access to the plotter's logger for children. 00230 PlotLoggerPtr logger() const; 00231 00232 // Provides access to logging destruction, for children. Should be called 00233 // in children's destructor. 00234 void logDestruction(); 00235 00236 // Provides access to log method enter/exit, for children. 00237 void logMethod(const String& methodName, bool entering, 00238 const String& message = String()) const; 00239 00240 // Provides access to QPCanvas's draw operation for children. 00241 PlotOperationPtr drawOperation() const; 00242 00243 00244 // ABSTRACT METHODS // 00245 00246 // Returns the class name for the child, for logging purposes. 00247 virtual const String& className() const = 0; 00248 }; 00249 00250 00251 // Thread for drawing multiple QPPlotItems into QPImageCaches based on its 00252 // canvas layer. Once the thread is finished, the QPImageCaches can be copied 00253 // to the canvas caches and shown on the GUI widget as needed. The thread will 00254 // emit a signal after each "segment" is drawn, either the whole item for small 00255 // items or part of a large item. 00256 class QPDrawThread : public QThread { 00257 Q_OBJECT 00258 00259 public: 00260 // Static // 00261 00262 // Convenient access to class name. 00263 static const String CLASS_NAME; 00264 00265 // Returns the default segment threshold. 00266 static const unsigned int DEFAULT_SEGMENT_THRESHOLD; 00267 00268 // Returns item1->z() < item2->z(). 00269 // <group> 00270 static bool itemSortByZ(const QPLayerItem* item1,const QPLayerItem* item2); 00271 // </group> 00272 00273 // Draws the given items, sorted by z-order, using the given painter, rect, 00274 // and maps. If PlotOperation parameters are given, they are updated as 00275 // needed. 00276 // <group> 00277 static void drawItem(const QPLayerItem* item, QPainter* painter, 00278 const QRect& rect, const QwtScaleMap maps[QwtPlot::axisCnt]); 00279 static void drawItem(const QPLayerItem* item, QPainter* painter, 00280 const QRect& rect, const QwtScaleMap maps[QwtPlot::axisCnt], 00281 unsigned int drawIndex, unsigned int drawCount); 00282 static void drawItems(const QList<const QPLayerItem*>& items, 00283 QPainter* painter, const QRect& rect, 00284 const QwtScaleMap maps[QwtPlot::axisCnt], 00285 PlotOperationPtr op = PlotOperationPtr(), 00286 unsigned int currentSegment = 0, unsigned int totalSegments = 0, 00287 unsigned int segmentThreshold = 00288 QPDrawThread::DEFAULT_SEGMENT_THRESHOLD); 00289 static void drawItems(const QList<const QPPlotItem*>& items, 00290 QPainter* painter, const QRect& rect, 00291 const QwtScaleMap maps[QwtPlot::axisCnt], 00292 PlotOperationPtr op = PlotOperationPtr(), 00293 unsigned int currentSegment = 0, unsigned int totalSegments = 0, 00294 unsigned int segmentThreshold = 00295 QPDrawThread::DEFAULT_SEGMENT_THRESHOLD); 00296 // </group> 00297 00298 00299 // Non-Static // 00300 00301 // Constructor which takes a list of items to draw, axes maps, the drawing 00302 // rectangle, an optional fixed image size, and an optional segment 00303 // threshold. 00304 QPDrawThread(const QList<const QPPlotItem*>& items, 00305 const QwtScaleMap maps[QwtPlot::axisCnt], QSize imageSize, 00306 unsigned int segmentTreshold = DEFAULT_SEGMENT_THRESHOLD); 00307 00308 // Destructor. 00309 ~QPDrawThread(); 00310 00311 // Returns the total segments that will be drawn. This is AT LEAST the 00312 // number of items to be drawn. 00313 unsigned int totalSegments() const; 00314 00315 // Implements QThread::run(). Draws the items into one of the two images 00316 // depending on their layers. Emits segmentDrawn() after each segment is 00317 // finished. 00318 void run(); 00319 00320 // Returns the image result for the given layer. Should only be done AFTER 00321 // the thread is finished. If clearResult is true, then the resulting 00322 // image is removed from the thread's images. 00323 QPImageCache drawResult(PlotCanvasLayer layer, bool clearResult = true); 00324 00325 public slots: 00326 // Cancels this thread. If the thread is currently running, it will finish 00327 // the segment it is on and then stop. 00328 void cancel(); 00329 00330 private: 00331 // Items to draw. 00332 QList<const QPPlotItem*> m_items; 00333 00334 // Axes maps. 00335 QwtScaleMap m_axesMaps[QwtPlot::axisCnt]; 00336 00337 // Images to draw into. 00338 QHash<PlotCanvasLayer, QPImageCache*> m_images; 00339 00340 // Maximum number of draw items per segment. 00341 unsigned int m_segmentThreshold; 00342 00343 // Flag that thread checks while running, to cancel rest of draw. 00344 bool m_cancelFlag; 00345 }; 00346 00347 } 00348 00349 #endif 00350 00351 #endif /* QPPLOTITEM_H_ */