casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
DisplayData.h
Go to the documentation of this file.
00001 //# DisplayData.h: base class for display objects
00002 //# Copyright (C) 1996,1997,1998,1999,2000,2001,2002,2003
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 
00028 #ifndef TRIALDISPLAY_DISPLAYDATA_H
00029 #define TRIALDISPLAY_DISPLAYDATA_H
00030 
00031 #include <casa/aips.h>
00032 #include <casa/Arrays/Vector.h>
00033 #include <casa/Arrays/Matrix.h>
00034 #include <casa/Containers/List.h>
00035 #include <coordinates/Coordinates/CoordinateSystem.h>
00036 #include <display/Utilities/DisplayOptions.h>
00037 #include <display/Utilities/DlTarget.h>
00038 #include <display/Display/WorldCanvasHolder.h>
00039 #include <display/Display/AttValBase.h>
00040 #include <display/DisplayEvents/DisplayEH.h>
00041 
00042 namespace casa { //# NAMESPACE CASA - BEGIN
00043 
00044 class Attribute;
00045 class AttributeBuffer;
00046 class Unit;
00047 class WorldCanvas;
00048 class Colormap;
00049 class String;
00050 class WCPositionEH;
00051 class WCMotionEH;
00052 class WCRefreshEH;
00053 class WCPositionEvent;
00054 class WCMotionEvent;
00055 class WCRefreshEvent;
00056 class Record;
00057 class ImageAnalysis;
00058 template <class T> class ImageInterface;
00059 
00060 // <summary> 
00061 // Base class for display objects.
00062 // </summary>
00063 //
00064 // <use visibility=export>
00065 // 
00066 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos="">
00067 // </reviewed>
00068 // 
00069 // <prerequisite>
00070 //   <li> WorldCanvas
00071 //   <li> WorldCanvasHolder
00072 //   <li> Attribute
00073 //   <li> AttributBuffer
00074 // </prerequisite>
00075 //
00076 // <etymology>
00077 // A class having "DisplayData" as its base is used to generate
00078 // "Display"s out of "Data."
00079 // </etymology>
00080 //
00081 // <synopsis> The basic drawing devices in the Display Library are the
00082 // PixelCanvas and the WorldCanvas. These devices know nothing about what real
00083 // data look like, what kind of object will draw on these devices and in what
00084 // kind of circumstances these devices will be used. The only thing they
00085 // define is the interface of how to draw on them and the way they communicate
00086 // with other objects (the event handlers).  Building in no assumptions in the
00087 // Canvases on how they will be used should give larger flexibility in how one
00088 // can actually use these Canvases.  Since the Canvases know nothing about how
00089 // real data looks, a class is needed to transform data into objects the
00090 // Canvases do understand. These are the DisplayData. A DisplayData generates,
00091 // based on data and some algorithm to represent that data, a number of
00092 // primitives that it draws on the WorldCanvas. So in a way, 'the data draw
00093 // themselves'. The definition of how data is represented (image, contour,
00094 // rendering, list of symbols from a catalogue, etc, etc) is entirely defined
00095 // by these DisplayData and as long it can be done using the primitives of the
00096 // WorldCanvas, there are no restrictions. If one finds a new way of
00097 // representing data, the only thing one has to do is to write a new
00098 // DisplayData that generates this representation and draws it on the
00099 // WorldCanvas using the primitives of the WorldCnvas.  
00100 //
00101 // To do the administration of a number of DisplayDatas on one WorldCanvas, a
00102 // bookkeeping class is needed, this is the WorldCnvasHolder.
00103 //
00104 // Some DisplayData will consist of a sequence of display object (eg a set of
00105 // channels in a data cube). The DisplayData are build with sequences in mind
00106 // (as is clear from the interface), and the Display Library is designed very
00107 // strongly with movies in mind. The programmer is free to define what a
00108 // sequence really means, but it is probably best to keep the structure of the
00109 // sequence in a DisplayData fairly logical. But there is not requirement on
00110 // the structure of the sequence. 
00111 //
00112 // Before a display object is displayed (ie when a refresh happens), a size
00113 // control step is performed. The WorldCanvas call a sizeControl event
00114 // handler. Normally this will be a handler that is installed by the
00115 // WorldCanvasHolder. All the WorldCanvasHolder does is to call the
00116 // sizeControl member function of all displayData registered with the
00117 // WorldCanvasHolder to do the sizeControl. The purpose of the size control is
00118 // to put the WorldCanvas in a correct state before the objects are actually
00119 // drawn. For example, for images there can be restrictions on the size of the
00120 // output array (eg the image is expanded using pixelreplication which means
00121 // that the draw area of the WorldCanvas must by an integral of the size of
00122 // the image). For each DisplayData the WorldCanvasHolder calls the sizeControl
00123 // function, supplying an AttributeBuffer where the DisplayData should set the
00124 // Attributes it needs to be set. THERE IS ONE IMPORTANT RULE IN THIS: a
00125 // DisplayData should never overwrite an Attribute that is already set in this
00126 // buffer. If the WorldCanvas cannot be put in a correct state during the size
00127 // control, a DisplayData should turn itself off. DisplayData are also
00128 // responsible for the linear coordinate system of the WorldCanvas and usually
00129 // setting that up will be done in this step.
00130 
00131 
00132 // (dk 6/04 note on 'size control').  The important WC state set during
00133 // sizeControl() defines a series of coordinate transformations, ultimately
00134 // between screen (PixelCanvas) pixels and coordinates in world space.
00135 // First, there are the limits of the WC's 'draw area', inside the labelling
00136 // margins, on the PC ('canvasDraw{X,Y}{Size,Offset}' WC  Attributes).
00137 // Second is the 'zoom window': the area of 'linear coordinate' space
00138 // currently mapped to the draw area ('lin{X,Y}{Min,Max}' WC Attributes).
00139 // Also stored in linear terms are the maximum extents of the data
00140 // ('lin{X,Y}{Min,Max}Limit' Attributes), which are used to set the zoom
00141 // window initially or when 'unzoom' (zoom-to-extent) is requested.
00142 //
00143 // 'Linear coordinates' often correspond to indices within the data
00144 // being displayed, although in principle this is not necessary.  They
00145 // serve to isolate the simple linear scaling/translation (zoom and pan)
00146 // transformations from the final transformation (often a nonlinear sky
00147 // projection) between 'linear coordinates' and world space (which is
00148 // changed less often).
00149 // 
00150 // (Also, linear coordinates define an entire plane, although a given
00151 // sky-coordinate projection to that plane may not be defined everywhere.
00152 // Keeping zoom windows defined in linear coordinates allows natural
00153 // display of all-sky images even when sky coordinates are not defined
00154 // everywhere in the display area.  In other words, the existing
00155 // scheme allows all-sky images to be displayed easily _in principle_;
00156 // it does not work currently due to inappropriate insistence of
00157 // WC::drawImage() that its draw area be given in world coordinates;
00158 // this is high on the list of bugfix priorities...).
00159 //
00160 // The final transformation makes use of the Coordinate classes (which
00161 // ultimately use wcslib for any needed sky projection).  It defines the
00162 // current 2D surface on display within some nD world space, as parameterized
00163 // by the X and Y linear coordinates.  State for this purpose includes the
00164 // 'WorldCanvas CoordinateSystem' or 'WCCS' (WorldCanvas::itsCoordinateSystem)
00165 // plus 'axis codes' (which have the odd Attribute names
00166 // '{x,y}axiscode (required match)').  They are intended to define the
00167 // coordinate values and types for the world space currently of interest.
00168 //
00169 // This latter transformation is not as simple or well-defined as it might
00170 // appear, however (and in my opinion this area still needs work).  First of
00171 // all, the WCCS is a rather late addition to WC interface, and in most cases
00172 // is _not even used_ to do WC linear-to-world transformations.  Instead, this
00173 // chore is handed off (via the older WCCoordinateHandler interface) to one
00174 // of the DDs currently registered on WC's companion object, WorldCanvasHolder.
00175 // Also, the axis codes do not always provide enough information about the
00176 // current world space for DDs to determine whether they are designed to
00177 // draw in that space (which, in my opinion, should be the codes' purpose).
00178 // They also implicitly assume a 1-to-1 correspondence between linear and
00179 // world coordinates, which is not very general.
00180 //
00181 // Back to how it works now, though.  During the 'sizeControl' step of
00182 // refresh, the WCH will attempt to determine a 'CS master DD'.  (Usually the
00183 // same DD will remain 'in charge' as long as it is registered).  Within
00184 // the sizeControl routine, DDs should test isCSMaster(wch) to determine
00185 // whether they have permission to become the CS master.  If so, and if they
00186 // are willing and able to become CS master, they must set all of the WC
00187 // state above and return True; in all other cases they should return False.
00188 // Only the CSmaster should set the WC CS or axis codes, and it will be
00189 // responsible for performing the WC's linToWorld, etc. transformation chores.
00190 // In other words, it is entirely in charge of the final transformation to
00191 // world coordinates.  In principle, other DDs may perform certain 'slave
00192 // sizeControl' tweaks (such as aligning the zoom window on data pixel
00193 // boundaries or redefining maximum zoom extents).  No current implementations
00194 // do anything but return False if they are not the master, however.
00195 //
00196 // Major implementation examples for sizeControl() can be found in the
00197 // ActiveCaching2dDD and PrincipalAxesDD classes.  They should be consulted
00198 // as well for the conventions for processing WC 'zoom/unzoom' order
00199 // attributes, another CSmaster responsibility.  (<\dk>)
00200 
00201 
00202 
00203 // The control of what is displayed in a display application is done with
00204 // setting restrictions on the WorldCanvasHolder (and possibly on the
00205 // Displaydata). Restrictions are implemented as Attributes and stored in
00206 // AttributeBuffers. To define what is displayed, one sets one or more
00207 // restrictions on the WorldCanvasHolder and calls a refresh on the
00208 // WorldCanvas. Most DisplayData will have pre-defined restrictions, for
00209 // example in an ImageDisplayData each image has defined the restriction
00210 // zIndex (set to the pixelindex of the 'third' axis in the data set) and
00211 // zValue (set to the 'third' worldcoordinate of the image). So to display
00212 // channel 13 of a data cube, one only has to set on the WorldCanvasHolder a
00213 // restriction called zIndex with value 13 and call refresh:
00214 //
00215 // <srcblock>
00216 // worldCanvasHolder.setRestriction("zIndex", 13);
00217 // worldCanvas.refresh();
00218 // </srcblock>
00219 //
00220 // Movies can be made using the Animator class. One way it to use indices, but
00221 // there is a generic way of defining movies using restrictions. So a sequence
00222 // does not have to correspond to a 'logical' or 'physical' sequence in some
00223 // datastructure (channels in a cube for example), but can be made of images
00224 // from different datasets (e.g. blinking) and display data in different
00225 // forms. This system is very flexible and there are no real limits to what a
00226 // movie really means. 
00227 //
00228 // The DisplayData also define the coordinate system of the WorldCanvas. If
00229 // the WorldCanvas has to do a coordinate transformation, it asks a coordinate
00230 // handler to do this. When a WorldCanvasHolder is created for a WorldCanvas,
00231 // the WorldCanvasHolder install a coordinate handler on the WorldCanvas. What
00232 // this coordinate handlers does is to ask the DisplayData that is first in
00233 // the list of the WorldcanvasHolder to do the transformation. This is quite
00234 // an indirect way of doing the transformation, but it is very flexible (and
00235 // the WorldCanvas does not have to know what an Aips++ coordinate system is,
00236 // or what a DisplayData is, , which makes the WorldCanvas more generic). Most
00237 // DisplayData will use the coordinate system of the data belonging to this
00238 // DisplayData to do the transformation, but this is not a requirement. As
00239 // long as you produce something that can be used as a coordinate system, it
00240 // does not matter how you compute it. The most important thing is that the
00241 // DisplayData are responsible for this. At the moment, only the Vector
00242 // version should be implemented, since efficient transformation of a series
00243 // of positions is not available in AIPS++. The Matrix versions are handled at
00244 // the WorldCanvas level at the moment.  Most DisplayData will assume that the
00245 // linear coordinate system of the WorldCanvas corresponds to some underlying
00246 // pixel array. The way the linear coordinate system is used is that it is the
00247 // input for the coordinate transformation to world coordinates. The
00248 // DisplayData are responsible for keeping the linear system correct.
00249 
00250 // Other event handlers that the DisplayData have to implement are the
00251 // position- and the motion event handlers. (PositionEH and MotionEH). These
00252 // are called by the WorldCanvasHolder in response to an event on the
00253 // WorldCanvas. It is up to the DisplayData what to do with these events.
00254 //
00255 // One can also register position- and motion event handlers on a
00256 // DisplayData. What kind of event a DisplayData generates in response to an
00257 // event on the WorldCanvas (passed to the DisplayData by the
00258 // WorldCanvasHolder by calling PositionEH/MotionEH) is entirely up to the
00259 // DisplayData, as long as the handlers are derived from WCPositionEH or
00260 // WCMotionEH. One can also install a refresh handler on a DisplayData,
00261 // although I have not thought of any use for that (but allowed for it to keep
00262 // symmetry with the other events).
00263 //
00264 // (1/02) DisplayEH interface has also been added for handling generic
00265 // DisplayEvents through handleEvent().  It is expected that DDs will handle
00266 // these events themselves, as needed, or pass them on in an ad-hoc manner.
00267 // However, nothing prevents implementing a dispatching list for passing
00268 // on these events too, if needed.
00269 //
00270 // (3/03) One can also register itself as a DisplayEventHandler on a
00271 // DisplayData. The handleEvent function of DisplayEH is implemented
00272 // to forward any DisplayEvents its receives to these
00273 // handlers. Therefore, all DisplayDatas that overide the handleEvent
00274 // function, should call the handleEvent function of its super class
00275 // so this forwarding can take place.
00276 //
00277 // A DisplayData also has to implement a refreshEH. This function is called by
00278 // the WorldCanvasHolder in response to a refresh request of the WorldCanvas.
00279 // This is a very important function: here the actual drawing has
00280 // to happen, using the draw primitives of the WorldCanvas. It is a good idea
00281 // to check the state of the WorldCanvas before the draw is actually done, and
00282 // decide not to draw if the state (for whatever reason) is not ok. Also be
00283 // aware that it is a requirement that one DisplayData can work for more than
00284 // one WorldCanvasHolders at a time, so the DisplayData has to do some
00285 // administration for that (which WorldCanvasHolders am I working for and
00286 // which one am I drawing on at the moment, things like that). See
00287 // ImageDisplayData for an example of that.
00288 //
00289 // DisplayData also have Attributes. These can be used to store whatever
00290 // information on a DisplayData. The Attributes give a standard interface to
00291 // do this. 
00292 // </synopsis>
00293 //
00294 // <example>
00295 // <srcBlock>
00296 // </srcBlock>
00297 // </example>
00298 //
00299 
00300 // <motivation>
00301 // An abstract interface between data and canvases was needed
00302 //</motivation>
00303 //
00304 // <todo> 
00305 //
00306 //   <li> When efficient implementations of the Matrix versions of the
00307 //   coordinate transformations become available in AIPS++, these should be
00308 //   implemented in DisplayData
00309 //
00310 // </todo>
00311 //
00312  
00313 class DisplayData : public DisplayOptions, public DisplayEH, public DlTarget {
00314 
00315 public:   
00316 
00317   enum DisplayState { DISPLAYED, UNDISPLAYED, LIMBO };
00318 
00319   // (Required) default constructor.
00320   DisplayData();
00321   
00322   // required destructor
00323   virtual ~DisplayData();
00324 
00325   // Coordinate transformations, called by WorldCanvasHolder (Matrix versions
00326   // not implemented)
00327   virtual Bool linToWorld(Vector<Double>& world, 
00328                           const Vector<Double>& lin) = 0;
00329   virtual Bool worldToLin(Vector<Double>& lin,
00330                           const Vector<Double>& world) = 0;
00331 
00332   // Format a string containing coordinate information at
00333   // the given world coordinate
00334   virtual String showPosition(const Vector<Double> &world,
00335                               const Bool &displayAxesOnly = False) = 0;
00336   
00337   // Format a string containing value information at the 
00338   // given world coordinate
00339   virtual String showValue(const Vector<Double> &world) = 0;
00340 
00341 
00342   virtual void setDisplayState( DisplayState s ) {
00343           displaystate = s;
00344   }
00345   virtual DisplayState getDisplayState( ) const { return displaystate; }
00346 
00347   virtual bool isDisplayable( ) const { return true; }
00348 
00349   // Some routines that give info on the axes names, units etc. I am not sure
00350   // this is the right way of doing it.
00351   // <group>
00352   virtual Vector<String> worldAxisNames() const = 0;
00353   virtual Vector<String> worldAxisUnits() const = 0;
00354   // </group>
00355 
00356   // Returns the number of elements in this DisplayData (mainly for movie
00357   // purposes).  First one is no. of elements for specific WCanvas.
00358   virtual const uInt nelements(const WorldCanvasHolder &wcHolder) const = 0;
00359   // and non-specific
00360   virtual const uInt nelements() const = 0;
00361 
00362   // Add general restrictions or a restriction for item <src>itemNum</src> of
00363   // this DisplayData. Note that the item versions of the restriction
00364   // interface are not implemented. I am not sure the item versions belong in
00365   // DisplayData and instead they should only appear in some derived classes.
00366   // <group>
00367   virtual void addRestrictions(AttributeBuffer& otherBuf);
00368   virtual void addRestriction(Attribute& newRestriction, Bool permanent);
00369   virtual void addElementRestrictions(const uInt itemNum, 
00370                                       AttributeBuffer& other);
00371   virtual void addElementRestriction(const uInt itemNum, 
00372                                      Attribute& newRestriction, 
00373                                      Bool permanent);
00374   // </group>
00375 
00376   // Set general restrictions or a restriction for item <src>itemNum</src> of
00377   // this DisplayData. Note that the item versions of the restriction
00378   // interface are not implemented.
00379   // <group>
00380   virtual void setRestrictions(AttributeBuffer& otherBuf);
00381   virtual void setRestriction(Attribute& newRestriction);
00382   virtual void setElementRestrictions(const uInt itemNum, 
00383                                       AttributeBuffer& other);
00384   virtual void setElementRestriction(const uInt itemNum, 
00385                                      Attribute& newRestriction);
00386   // </group>
00387 
00388   // Remove a general restriction or a restriction from item <src>itemNum</src>
00389   // <group>
00390   virtual void removeRestriction(const String& name);
00391   virtual void removeElementRestriction(const uInt itemNum, 
00392                                         const String& name);
00393   // </group>
00394 
00395   // Clear all general restrictions or all restrictions of item
00396   // <src>itemNum</src> (except the ones that are permanent of course...)
00397   // <group>
00398   virtual void clearRestrictions();
00399   virtual void clearElementRestrictions(const uInt itemNum);
00400   // </group>
00401 
00402   // Check if a general restriction or a restriction for item
00403   // <src>itemNum</src> with name <src>name</src> exists.
00404   // <group>
00405   virtual Bool existRestriction(const String& name);
00406   virtual Bool existElementRestriction(const uInt itemNum, 
00407                                        const String& name);  
00408   // </group>
00409 
00410   // Get a handle to the buffer of general restrictions or of the buffer of
00411   // restrictions for item <src>itemNum</src>
00412   // <group>
00413   virtual AttributeBuffer *restrictionBuffer();
00414   virtual AttributeBuffer *elementRestrictionBuffer(const uInt itemNum);
00415   // </group>
00416 
00417 
00418   // Check whether the DD is is compatible with all WC[H]
00419   // state, including its coordinate state, restrictions, and zIndex (if any).
00420   // It also assures that the DD is 'focused' on this WC[H] and its zindex
00421   // for purposes of drawing or event handling.
00422   // <group>
00423   virtual Bool conformsTo(const WorldCanvas *wCanvas) {
00424     rstrsConformed_ = csConformed_ = zIndexConformed_ = False;
00425     return (wCanvas!=0 && conformsTo(*wCanvas));  }
00426  
00427   virtual Bool conformsTo(const WorldCanvas& wc) {
00428     conformsToRstrs(wc);
00429     conformsToCS(wc);
00430     conformsToZIndex(wc);
00431     return conformed();  }
00432   // </group>
00433 
00434   // Determine whether DD restrictions are in conformance with restrictions
00435   // on the given WCH.  (Note: this will include blink index, if any,
00436   // but _not_ zIndex.  zIndex is an individual DM restriction, not an
00437   // overall DD restriction).
00438   virtual Bool conformsToRstrs(const WorldCanvas& wc) {
00439     rstrsConformed_ = wc.matchesRestrictions(restrictions);
00440     return rstrsConformed_;  }
00441 
00442   // Determine whether DD is compatible with the WC[H]'s current
00443   // world coordinates.  Derived DDs can override according to their
00444   // individual capabilities (PADD and ACDD match axis codes).
00445   // Overriding DDs should set csConformed_ to the value returned.
00446   virtual Bool conformsToCS(const WorldCanvas& /*wc*/) {
00447     csConformed_ = True;
00448     return csConformed_;  }
00449 
00450   // Determine whether DD is compatible with the current canvas
00451   // animation (zIndex) position.  (This usually means that it lies 
00452   // within the current number of DD animation frames).
00453   // (Generally, DDs should probably override setActiveZIndex_()
00454   // rather than this method).
00455   virtual Bool conformsToZIndex(const WorldCanvas& wc) {
00456     Int zindex = 0;     // (default in case no zIndex exists).
00457     const AttributeBuffer *rstrs = wc.restrictionBuffer();
00458     if (rstrs->exists("zIndex")) rstrs->getValue("zIndex",zindex);
00459     return setActiveZIndex_(zindex);  }
00460     
00461   // Retrieve 'Active' zIndex.  Not likely to be meaningful/useful
00462   // unless conformsTo(wch) (or conformsToZIndex(wch)) has been called
00463   // just prior (and has returned a True result).  Those calls make
00464   // wch the 'active' one; zIndex varies from one wch to another.
00465   // You can pass a wch, which will force a call to conformsToZIndex(wch).
00466   virtual Int activeZIndex(const WorldCanvas* wc=0) {
00467     if(wc!=0) conformsToZIndex(*wc);
00468     return activeZIndex_;  }
00469 
00470   
00471   
00472   // Set firstZIndex to minimum zIndex setting from all canvases where
00473   // this DD is registered.  (In the usual case where the DD is registered
00474   // on one [multi]panel, this will return its animator 'frame #' setting).
00475   // The routine will return false (and firstZIndex remain unchanged) if
00476   // there are no registered canvases with zIndex below axZrng--the total
00477   // number of frames on the Z axis.  axZrng can be supplied; the default
00478   // means 'use nelements()'.
00479   // (Note: to get the zindex from the 'currently active' wch instead,
00480   // a DD should check activeZIndex_.  Or, if the desired wch is known,
00481   // it can retrieve the zIndex itself from wch.restrictionBuffer()).
00482   virtual Bool getFirstZIndex(int& firstZIndex, Int axZrng=-1) const {
00483     Block<Int> zInds = allZIndices(axZrng);
00484     if(zInds.nelements()==0) return False;
00485     firstZIndex=zInds[0];    return True;  }
00486 
00487 
00488 
00489   // Add event handlers on the DisplayData. I am not sure there is also a need
00490   // for a refresh handler on a DisplayData, but allowing for it  makes
00491   // things 'symmetric'. These member functions throw an AipsError if a null
00492   // pointer is passed.
00493   // <group>
00494   virtual void addPositionEventHandler(WCPositionEH *positionHandler);
00495   virtual void addMotionEventHandler(WCMotionEH *motionHandler);
00496   virtual void addRefreshEventHandler(WCRefreshEH *refreshHandler);
00497   virtual void addDisplayEventHandler(DisplayEH *displayHandler);
00498   // </group>
00499 
00500   // Remove eventhandlers
00501   // <group>
00502   virtual void removePositionEventHandler(WCPositionEH& positionHandler);
00503   virtual void removeMotionEventHandler(WCMotionEH& motionHandler);
00504   virtual void removeRefreshEventHandler(WCRefreshEH& refreshHandler);
00505   virtual void removeDisplayEventHandler(DisplayEH& displayHandler);
00506   // </group>
00507 
00508   // Set/remove/get a ColourMap (sorry, ColorMap) for this DisplayData
00509   // setColormap() throw an AipsError is a null pointer is passed. colormap()
00510   // returns 0 if no Colormap is registered.
00511   // <group>
00512   virtual void setColormap(Colormap *cmap, Float weight);
00513   virtual void removeColormap();
00514   virtual Colormap *colormap() const
00515     { return itsColormap; }
00516   // </group>
00517 
00518 
00519   // set an Attribute or Attributes
00520   // <group>
00521   void setAttribute(Attribute& at);
00522   void setAttributes(AttributeBuffer& at);
00523   // </group>
00524 
00525   // User interface to get value from the attribute buffer
00526   // <group>
00527 
00528   Bool getAttributeValue(const String& name, uInt& newValue) ;  
00529   Bool getAttributeValue(const String& name, Int& newValue) ;
00530   Bool getAttributeValue(const String& name, Float& newValue) ;
00531   Bool getAttributeValue(const String& name, Double& newValue) ;
00532   Bool getAttributeValue(const String& name, Bool& newValue) ;
00533   Bool getAttributeValue(const String& name, String& newValue) ;
00534   Bool getAttributeValue(const String& name, Vector<uInt>& newValue) ;
00535   Bool getAttributeValue(const String& name, Vector<Int>& newValue) ;
00536   Bool getAttributeValue(const String& name, Vector<Float>& newValue) ;
00537   Bool getAttributeValue(const String& name, Vector<Double>& newValue) ;
00538   Bool getAttributeValue(const String& name, Vector<Bool>& newValue) ;
00539   Bool getAttributeValue(const String& name, Vector<String>& newValue) ;
00540   // </group>
00541 
00542   // Check if a certain Attribute exists
00543   Bool existsAttribute(String& name) ;
00544 
00545   // Remove an  Attribute 
00546   void removeAttribute(String& name);
00547 
00548   // Get the type of the Attribute
00549   AttValue::ValueType attributeType(String& name) ;
00550 
00551   // Set an attribute on any WorldCanvas for which this DD is CS master
00552   void setAttributeOnPrimaryWCHs(Attribute &at);
00553 
00554   // <group>
00555   virtual void notifyRegister(WorldCanvasHolder *wcHolder) ;
00556   // <src>ignoreRefresh</src> tells the DD not to refresh just to clean
00557   // up DMs
00558   virtual void notifyUnregister(WorldCanvasHolder& wcHolder,
00559                                 Bool ignoreRefresh = False) ;
00560   // </group>
00561 
00562   // remove this DD everywhere--will stop any more refresh handling by
00563   // the DD.  It is a good idea for top-level DDs to call this first
00564   // in their destructor.
00565   virtual void removeFromAllWCHs();
00566 
00567   // install the default options for this DisplayData
00568   virtual void setDefaultOptions();
00569 
00570   // apply options stored in val to the DisplayData; return value
00571   // True means a refresh is needed...
00572   virtual Bool setOptions(Record &rec, Record &recOut);
00573 
00574   // retrieve the current and default options and parameter types.
00575   virtual Record getOptions();
00576 
00577   // an explicit refresh: should be called if the DisplayData is
00578   // changed such that drawing is required.  If clean is True, 
00579   // the DD is totally rebuilt, in practice.  This is provided 
00580   // for higher level control, even explicit control of refresh
00581   // where necessary.
00582   // ..."refresh(True)"... does not seem to work <drs:Mar 21 2013>
00583   virtual void refresh(Bool clean = False);
00584 
00585   // an explicit request to draw the axes and/or labels.  Returns
00586   // True if axes were drawn, otherwise False;
00587   virtual Bool labelAxes(const WCRefreshEvent &ev);
00588 
00589   // Return the class name of this DisplayData; useful mostly for
00590   // debugging purposes, and perhaps future use in the glish widget
00591   // interface.
00592   virtual String className() { return String("DisplayData"); }
00593   virtual String description( ) const { return "not available"; }
00594 
00595   // Return the DisplayData type; used by the WorldCanvasHolder to
00596   // determine the order of drawing.
00597   virtual Display::DisplayDataType classType() = 0;
00598 
00599   virtual String dataType( ) const = 0;
00600   virtual const IPosition dataShape( ) const = 0;
00601   virtual const uInt dataDim( ) const = 0;
00602   virtual const Unit dataUnit( ) const = 0;
00603   virtual std::vector<int> displayAxes( ) const = 0;
00604 
00605   // Get image analyis about images... for non-image
00606   // "DisplayData" this function will return null...
00607   // Use dataType() to check...
00608   // Creates a new object (or a null pointer) which may need to be deleted...
00609   virtual ImageAnalysis *imageanalysis( ) const { return 0; }
00610   // Returns a pointer that should *not* be deleted...
00611   virtual ImageInterface<Float> *imageinterface( ) { return 0; }
00612 
00613   // Identify the WorldCanvasHolder for the given WorldCanvas.  Return
00614   // <src>0</src> if the DisplayData does not know of a
00615   // WorldCanvasHolder for the WorldCanvas.
00616   const WorldCanvasHolder *findHolder(const WorldCanvas *wCanvas) const;
00617   WorldCanvasHolder *findHolder(const WorldCanvas *wCanvas);
00618 
00619   // Return a sorted Block of all animation frame numbers currently set
00620   // onto all WCHs where this DD is registered.
00621   // The frame numbers returned are guaranteed to be in the range
00622   // 0 <= zIndex < axZrng, where axZrng is the total number of frames
00623   // on the Z axis.  axZrng can be supplied; the default is nelements().
00624   virtual Block<Int> allZIndices(Int axZrng=-1) const;
00625 
00626   // Will be called just before registering the [GTk]DD on a [GTk]PanelDisplay
00627   // which has none registered on it yet.  The DD can set the initial
00628   // animator position in this case by overriding this method to set
00629   // preferredZIndex and return True.
00630   virtual Bool zIndexHint(Int& /*preferredZIndex*/) const { return False;  }
00631 
00632   // Overide DisplayEH::handleEvent. This base class on forwards the
00633   // event on to listeners
00634   virtual void handleEvent(DisplayEvent &ev);
00635   
00636   // Is this DD the CS master of the passed WCH?
00637   // Defaulting wch to 0 asks whether this DD is CS master of _some_ WCH
00638   // on which it is registered.  (That option is mostly a kludge, since the
00639   // DD may be CS master of some WCHs and not others).
00640   virtual Bool isCSmaster(const WorldCanvasHolder* wch=0) const;
00641     
00642   // DD 'Absolute Pixel Coordinates', e.g. channel numbers, are internally
00643   // 0-based (they begin numbering at 0), but certain external user-interface
00644   // functions (e.g. showPosition(), used for position tracking) have
00645   // produced 1-based output traditionally for the glish-based viewer.
00646   // uiBase_, and related methods uiBase() and setUIBase(), allow newer
00647   // (python/Qt-based) code to cause external ui functions like showValue()
00648   // to report 0-based values instead.  Unless setUIBase(0) is called, the
00649   // traditional 1-based reporting behavior is retained by default.
00650   //
00651   // If you are using 0-basing in the user interface, you should call
00652   // setUIBase(0) right after constructing this DD, before other
00653   // user interface operations such as getOptions().
00654   // <group>
00655   virtual Int uiBase() { return uiBase_;  }
00656   
00657   virtual void setUIBase(Int uibase) {
00658     if(uibase==0 || uibase==1) uiBase_ = uibase;  }
00659   // </group>
00660 
00661   // Get and set method for the flag
00662   // <group>
00663   virtual Bool getDelTmpData( ){return delTmpData_;}
00664   virtual void setDelTmpData(Bool delTmpData){delTmpData_ = delTmpData;}
00665   // </group>
00666 
00667   const static String DATA_MIN;
00668   const static String DATA_MAX;
00669 
00670 protected:
00671 
00672   // DDs may override to adjust the internal stored current animation
00673   // index (activeZIndex_) if necessary, and to set return value False
00674   // iff the passed zindex won't work for the DD.  zIndexConformed_
00675   // should be set to the value returned; activeZIndex_ should also
00676   // be set appropriately.
00677   virtual Bool setActiveZIndex_(Int zindex) {
00678     activeZIndex_ = zindex;
00679     zIndexConformed_ = True;
00680     return zIndexConformed_;  }
00681 
00682   
00683   // The Book says that we should not put data members in class that is
00684   // supposed to only define an interface, but by putting these here, we can
00685   // implement some of the restriction & eventhandling stuff so that people do
00686   // not have to repeat it.
00687 
00688   // buffer for storing restrictions
00689   AttributeBuffer  restrictions;
00690  
00691   // buffer for storing Attributes
00692   AttributeBuffer attributes;
00693   
00694   // list of DisplayDataElements, which are of type DisplayMethod or derived
00695   PtrBlock<void *> DDelement;
00696   
00697   // Protected interface for WorldCanvasHolder, can be called by the friends
00698   // of DisplayData, but are nobody else's business. I decided to do this in
00699   // this way to avoid that the programmer has to both register the
00700   // DisplayData with the WorldCanvasHolder AND the WorldCanvasHolder with the
00701   // DisplayData. Now one of the two is done automatically.  
00702   // The WorldCanvasHolder is my friend. This is to hide the eventhandler
00703   // interfaces listed below from the outside world. The WorldCanvasHolder is
00704   // the only class that needs them
00705   friend class WorldCanvasHolder;
00706 
00707   // Indicates the 'current' animation frame, i.e. the zIndex on the canvas
00708   // for which confromsTo(wch) was last called.  Intended to be set only
00709   // by setActiveZIndex_() in this class or derived classes.
00710   Int activeZIndex_;
00711   
00712   // Flag indicating that temporary data should be removed when deleting
00713   // the object.
00714   Bool delTmpData_;
00715 
00716   // Somewhat limited-use state, saved here for 'efficiency'.  Indicates
00717   // that the last call to conformsToRstrs(), conformsToCS(), or
00718   // conformsToZIndex(), passed the respective compatibility tests.
00719   // (See conformed(), below).  Intended to be set only in the methods
00720   // conformsToRstrs(), conformsToCS() and setActiveZIndex_(), respectively.
00721   Bool rstrsConformed_, csConformed_, zIndexConformed_;
00722   
00723   // Returns result of last call to conformsTo(WCH&).  Methods like showValue()
00724   // which don't have access to the wch can use it instead, but that
00725   // shifts the burden elsewhere of being sure that conformsTo() was called
00726   // for the current WCH.  When possible, it is generally better and safer
00727   // to call conformsTo(wch) directly when needed, rather than querying this.
00728   Bool conformed() {
00729     return rstrsConformed_ && csConformed_ && zIndexConformed_;  }
00730   //Added so that when two images are loaded with no velocity
00731   //alignment, they can still show their position coordinates without
00732   //having to be rstrsConformed.
00733   Bool isCsAndZIndexConformed(){
00734           return csConformed_ && zIndexConformed_;
00735   }
00736   // Set (coordinate) state of WCH's WC.  Called by WCH::executeSizeControl().
00737   // (See important notes on interface and implementation of this function
00738   // in the class synopsis above).
00739   virtual Bool sizeControl(WorldCanvasHolder& wcHolder, 
00740                            AttributeBuffer& holderBuf) = 0;
00741 
00742   // Delete temporary data. To be called by sub-classe
00743   // that now the filenames.
00744   virtual void delTmpData(String &tmpData);
00745 
00746 
00747   // Retrieve position, motion, refresh and display event handler lists.
00748   // <group>
00749   virtual const List<WCPositionEH*> *positionEventHandlerList()
00750     { return &itsPositionEHList; }
00751   virtual const List<WCMotionEH*> *motionEventHandlerList()
00752     { return &itsMotionEHList; }
00753   virtual const List<WCRefreshEH*> *refreshEventHandlerList()
00754     { return &itsRefreshEHList; }
00755   virtual const List<DisplayEH*> *displayEventHandlerList()
00756     { return &itsDisplayEHList; }
00757   // </group>
00758 
00759   // Position, motion and refresh event handlers that will generally
00760   // be called by a WorldCanvasHolder.
00761   // <group>
00762   virtual void positionEH(const WCPositionEvent &ev);
00763   virtual void motionEH(const WCMotionEvent &ev);
00764   virtual void refreshEH(const WCRefreshEvent& ev) = 0;
00765   // </group>
00766 
00767   // clean up the memory used by this DisplayData
00768   virtual void cleanup() = 0;
00769 
00770   // (Required) copy constructor.
00771   DisplayData(const DisplayData &other);
00772     
00773   // (Required) copy assignment.
00774   void operator=(const DisplayData &other);
00775 
00776 
00777  private:
00778 
00779 
00780   // is this data currently being displayed?
00781   DisplayState displaystate;
00782 
00783   // Colormap for this DisplayData, and its weight.
00784   Colormap *itsColormap;
00785   Float itsColormapWeight;
00786   
00787   // A list of WorldCanvasHolders for which this DisplayData works.
00788   // The list is maintained by the DisplayData itself based on the
00789   // notify routines used by the WorldCanvasHolder.  This can be used,
00790   // for example, to find which WorldCanvas belongs to which
00791   // WorldCanvasHolder.
00792   List<WorldCanvasHolder*> itsWCHList;
00793 
00794   // Lists of position, motion, refresh and display event handlers.
00795   List<WCPositionEH*> itsPositionEHList;
00796   List<WCMotionEH*> itsMotionEHList;
00797   List<WCRefreshEH*> itsRefreshEHList;
00798   List<DisplayEH*> itsDisplayEHList;
00799   
00800   // DD 'Absolute Pixel Coordinates', e.g. channel numbers, are internally
00801   // 0-based (begin numbering at 0), but certain external user-interface
00802   // functions (e.g. showPosition(), used for position tracking) have
00803   // produced 1-based output traditionally for the glish-based viewer.
00804   // uiBase_, and related methods uiBase() and setUIBase(), allow newer
00805   // (python/Qt-based) code to cause external ui functions like showValue()
00806   // report 0-based values instead.  Unless setUIBase(0) is called, the
00807   // traditional 1-based reporting behavior is retained by default.
00808   
00809   Int uiBase_;          // (initialized to 1).
00810 };
00811 
00812 
00813 } //# NAMESPACE CASA - END
00814 
00815 #endif