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

Generated on Thu Aug 27 21:08:43 2009 for NRAOCASA by  doxygen 1.5.1