00001 //# QPImageCache.h: Classes for caching axes images. 00002 //# Copyright (C) 2009 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 QPIMAGECACHE_H_ 00028 #define QPIMAGECACHE_H_ 00029 00030 #ifdef AIPS_HAS_QWT 00031 00032 #include <graphics/GenericPlotter/PlotOptions.h> 00033 00034 #include <QCache> 00035 #include <QImage> 00036 #include <QMap> 00037 00038 namespace casa { 00039 00040 //# Forward Declarations 00041 class QPCanvas; 00042 00043 00044 // Abstraction of whatever Qt class the plotter uses to store images. 00045 // Currently is a QImage to avoid threading issues associated with QPixmap. 00046 // This class is assumed to use memory intelligently, so that only one 00047 // underlying image is used, with copy-on-write semantics. This is done 00048 // automatically with most Qt classes (such as QImage or QPixmap). 00049 class QPImageCache { 00050 public: 00051 // Creates a null, blank image. 00052 QPImageCache(); 00053 00054 // Creates a new image with the given size. 00055 // <group> 00056 QPImageCache(const QSize& size); 00057 QPImageCache(int width, int height); 00058 // </group> 00059 00060 // Copies the given image, with copy-on-write semantics. 00061 QPImageCache(const QPImageCache& copy); 00062 00063 // Destructor. 00064 ~QPImageCache(); 00065 00066 00067 // Returns true if this image is null/invalid, false otherwise. 00068 bool isNull() const; 00069 00070 // Returns the size of this image. 00071 QSize size() const; 00072 00073 // Fills the image with the given value. 00074 void fill(unsigned int fillValue); 00075 00076 // Returns the depth of the image. 00077 int depth() const; 00078 00079 // Returns a painter that can draw into this image. It is the caller's 00080 // responsibility to delete the painter upon completion. 00081 QPainter* painter(); 00082 00083 // Draws the image using the given painter, into the given draw rect. If 00084 // the image is not the same size as the draw rect, it will be stretched 00085 // appropriately. 00086 // <group> 00087 void paint(QPainter& painter, const QRect& drawRect) const; 00088 void paint(QPainter* painter, const QRect& drawRect) const { 00089 if(painter != NULL) paint(*painter, drawRect); } 00090 // </group> 00091 00092 00093 // Used to access the underlying data structure. Direct access should be 00094 // avoided, in case it changes in the future. 00095 // <group> 00096 QImage& asQImage(); 00097 const QImage& asQImage() const; 00098 // </group> 00099 00100 00101 // Copy operator, with copy-on-write semantics. 00102 QPImageCache& operator=(const QPImageCache& copy); 00103 00104 // Equality operators. 00105 // <group> 00106 bool operator==(const QPImageCache& other); 00107 bool operator!=(const QPImageCache& other) { return !(operator==(other)); } 00108 // </group> 00109 00110 private: 00111 // Underlying image. 00112 QImage m_image; 00113 }; 00114 00115 00116 // Class to managed cached images associated with a canvas axes stack. 00117 class QPAxesCache { 00118 public: 00119 // Static // 00120 00121 // Default cache size limit, in kilobytes. 00122 static const int DEFAULT_MEMORY_LIMIT_KB; 00123 00124 // Convenient access to class name for logging. 00125 static const String CLASS_NAME; 00126 00127 // Convenience class to use as a key. Every axis that has at least one 00128 // item attached to it will get an entry in the map, along with its range. 00129 class Key : public QMap<PlotAxis, QPair<double, double> > { 00130 public: 00131 // Default constructor. Empty key. 00132 Key(); 00133 00134 // Constructor which uses the current axes state of the given canvas. 00135 Key(const QPCanvas& canvas); 00136 00137 // Destructor. 00138 ~Key(); 00139 00140 00141 // Sets the key value using the current axes state of the given canvas. 00142 void setValue(const QPCanvas& canvas); 00143 00144 // Returns a hash for this key. 00145 uint hash() const; 00146 }; 00147 00148 00149 // Non-Static // 00150 00151 // Constructor which takes a size limit for the cache. 00152 QPAxesCache(QPCanvas& canvas, int sizeLimitKb = DEFAULT_MEMORY_LIMIT_KB); 00153 00154 // Destructor. 00155 ~QPAxesCache(); 00156 00157 00158 // Returns the current size of the cache. 00159 unsigned int size() const; 00160 00161 // Returns the (approximate) current memory size of the cache, in 00162 // kilobytes. 00163 int memorySize() const; 00164 00165 // Gets/Sets the size limit for the cache, in kilobytes. 00166 // <group> 00167 int memoryLimit() const; 00168 void setMemoryLimit(int memoryLimitKb); 00169 // </group> 00170 00171 // Returns the current size of the images that are cached. This can be 00172 // used to check for resizing, in which case the cache should probably be 00173 // cleared. 00174 QSize currImageSize() const; 00175 00176 // Gets/Sets the fixed cache image size. See 00177 // PlotCanvas::cachedAxesStackImageSize(). 00178 // <group> 00179 QSize fixedImageSize() const; 00180 void setFixedSize(QSize size); 00181 // </group> 00182 00183 // Clears all cached images. 00184 void clear(); 00185 00186 // Clears all cached images for the given layer(s). 00187 // <group> 00188 void clearLayer(PlotCanvasLayer layer); 00189 void clearLayers(int layersFlag); 00190 // </group> 00191 00192 // Returns true if the cache has an entry for the current axes state of its 00193 // canvas, false otherwise. 00194 bool currHasImage() const; 00195 00196 // Returns true if the cache has an image for the current axes state of its 00197 // parent for the given layer, false otherwise. 00198 bool currHasImage(PlotCanvasLayer layer) const; 00199 00200 // Returns the image for the current axes state of its canvas for the given 00201 // layer, or a null image if there is none. 00202 QPImageCache currImage(PlotCanvasLayer layer); 00203 00204 // Adds the given image for the current axes state of its canvas for the 00205 // given layer. The current image size is set to the size of the given 00206 // image (unless it is a null image). 00207 void addCurrImage(PlotCanvasLayer layer, const QPImageCache& image); 00208 00209 private: 00210 // Convenience class to use as a value. 00211 class Value : public QMap<PlotCanvasLayer, QPImageCache> { 00212 public: 00213 // Default constructor. 00214 Value(); 00215 00216 // Copy constructor. 00217 Value(const QMap<PlotCanvasLayer, QPImageCache>& copy); 00218 00219 // Destructor. 00220 ~Value(); 00221 00222 // Returns the approximate memory size, in kilobytes. 00223 int memorySize() const; 00224 }; 00225 00226 00227 // Parent canvas. 00228 QPCanvas& m_canvas; 00229 00230 // Image cache. 00231 QCache<Key, Value> m_cache; 00232 00233 // Fixed image size. 00234 QSize m_fixedSize; 00235 }; 00236 00237 } 00238 00239 // Provides a hashing function for QPAxesCache::Key, for use with Qt. 00240 uint qHash(const casa::QPAxesCache::Key& key); 00241 00242 #endif 00243 #endif /* QPIMAGECACHE_H_ */