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 <display/Display/DisplayCoordinateSystem.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 DisplayCoordinateSystem' 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                 virtual std::string errorMessage( ) const = 0;
00333 
00334                 // Format a string containing coordinate information at
00335                 // the given world coordinate
00336                 virtual String showPosition(const Vector<Double> &world,
00337                                             const Bool &displayAxesOnly = False) = 0;
00338 
00339                 // Format a string containing value information at the
00340                 // given world coordinate
00341                 virtual String showValue(const Vector<Double> &world) = 0;
00342 
00343 
00344                 virtual void setDisplayState( DisplayState s ) {
00345                         displaystate = s;
00346                 }
00347                 virtual DisplayState getDisplayState( ) const {
00348                         return displaystate;
00349                 }
00350 
00351                 virtual bool isDisplayable( ) const {
00352                         return true;
00353                 }
00354 
00355                 // Some routines that give info on the axes names, units etc. I am not sure
00356                 // this is the right way of doing it.
00357                 // <group>
00358                 virtual Vector<String> worldAxisNames() const = 0;
00359                 virtual Vector<String> worldAxisUnits() const = 0;
00360                 // </group>
00361 
00362                 // Returns the number of elements in this DisplayData (mainly for movie
00363                 // purposes).  First one is no. of elements for specific WCanvas.
00364                 virtual uInt nelements(const WorldCanvasHolder &wcHolder) const = 0;
00365                 // and non-specific
00366                 virtual uInt nelements() const = 0;
00367 
00368                 // Add 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. I am not sure the item versions belong in
00371                 // DisplayData and instead they should only appear in some derived classes.
00372                 // <group>
00373                 virtual void addRestrictions(AttributeBuffer& otherBuf);
00374                 virtual void addRestriction(Attribute& newRestriction, Bool permanent);
00375                 virtual void addElementRestrictions(const uInt itemNum,
00376                                                     AttributeBuffer& other);
00377                 virtual void addElementRestriction(const uInt itemNum,
00378                                                    Attribute& newRestriction,
00379                                                    Bool permanent);
00380                 // </group>
00381 
00382                 // Set general restrictions or a restriction for item <src>itemNum</src> of
00383                 // this DisplayData. Note that the item versions of the restriction
00384                 // interface are not implemented.
00385                 // <group>
00386                 virtual void setRestrictions(AttributeBuffer& otherBuf);
00387                 virtual void setRestriction(Attribute& newRestriction);
00388                 virtual void setElementRestrictions(const uInt itemNum,
00389                                                     AttributeBuffer& other);
00390                 virtual void setElementRestriction(const uInt itemNum,
00391                                                    Attribute& newRestriction);
00392                 // </group>
00393 
00394                 // Remove a general restriction or a restriction from item <src>itemNum</src>
00395                 // <group>
00396                 virtual void removeRestriction(const String& name);
00397                 virtual void removeElementRestriction(const uInt itemNum,
00398                                                       const String& name);
00399                 // </group>
00400 
00401                 // Clear all general restrictions or all restrictions of item
00402                 // <src>itemNum</src> (except the ones that are permanent of course...)
00403                 // <group>
00404                 virtual void clearRestrictions();
00405                 virtual void clearElementRestrictions(const uInt itemNum);
00406                 // </group>
00407 
00408                 // Check if a general restriction or a restriction for item
00409                 // <src>itemNum</src> with name <src>name</src> exists.
00410                 // <group>
00411                 virtual Bool existRestriction(const String& name);
00412                 virtual Bool existElementRestriction(const uInt itemNum,
00413                                                      const String& name);
00414                 // </group>
00415 
00416                 // Get a handle to the buffer of general restrictions or of the buffer of
00417                 // restrictions for item <src>itemNum</src>
00418                 // <group>
00419                 virtual AttributeBuffer *restrictionBuffer();
00420                 virtual AttributeBuffer *elementRestrictionBuffer(const uInt itemNum);
00421                 // </group>
00422 
00423 
00424                 // Check whether the DD is is compatible with all WC[H]
00425                 // state, including its coordinate state, restrictions, and zIndex (if any).
00426                 // It also assures that the DD is 'focused' on this WC[H] and its zindex
00427                 // for purposes of drawing or event handling.
00428                 // <group>
00429                 virtual Bool conformsTo(const WorldCanvas *wCanvas) {
00430                         rstrsConformed_ = csConformed_ = zIndexConformed_ = False;
00431                         return (wCanvas!=0 && conformsTo(*wCanvas));
00432                 }
00433 
00434                 virtual Bool conformsTo(const WorldCanvas& wc) {
00435                         conformsToRstrs(wc);
00436                         conformsToCS(wc);
00437                         conformsToZIndex(wc);
00438                         return conformed();
00439                 }
00440                 // </group>
00441 
00442                 // Determine whether DD restrictions are in conformance with restrictions
00443                 // on the given WCH.  (Note: this will include blink index, if any,
00444                 // but _not_ zIndex.  zIndex is an individual DM restriction, not an
00445                 // overall DD restriction).
00446                 virtual Bool conformsToRstrs(const WorldCanvas& wc) ;
00447 
00448                 // Determine whether DD is compatible with the WC[H]'s current
00449                 // world coordinates.  Derived DDs can override according to their
00450                 // individual capabilities (PADD and ACDD match axis codes).
00451                 // Overriding DDs should set csConformed_ to the value returned.
00452                 virtual Bool conformsToCS(const WorldCanvas& /*wc*/) {
00453                         csConformed_ = True;
00454                         return csConformed_;
00455                 }
00456 
00457                 // Determine whether DD is compatible with the current canvas
00458                 // animation (zIndex) position.  (This usually means that it lies
00459                 // within the current number of DD animation frames).
00460                 // (Generally, DDs should probably override setActiveZIndex_()
00461                 // rather than this method).
00462                 virtual Bool conformsToZIndex(const WorldCanvas& wc) {
00463                         Int zindex = 0; // (default in case no zIndex exists).
00464                         const AttributeBuffer *rstrs = wc.restrictionBuffer();
00465                         if (rstrs->exists("zIndex")) rstrs->getValue("zIndex",zindex);
00466                         return setActiveZIndex_(zindex);
00467                 }
00468 
00469                 // Retrieve 'Active' zIndex.  Not likely to be meaningful/useful
00470                 // unless conformsTo(wch) (or conformsToZIndex(wch)) has been called
00471                 // just prior (and has returned a True result).  Those calls make
00472                 // wch the 'active' one; zIndex varies from one wch to another.
00473                 // You can pass a wch, which will force a call to conformsToZIndex(wch).
00474                 virtual Int activeZIndex(const WorldCanvas* wc=0) {
00475                         if(wc!=0) conformsToZIndex(*wc);
00476                         return activeZIndex_;
00477                 }
00478 
00479 
00480 
00481                 // Set firstZIndex to minimum zIndex setting from all canvases where
00482                 // this DD is registered.  (In the usual case where the DD is registered
00483                 // on one [multi]panel, this will return its animator 'frame #' setting).
00484                 // The routine will return false (and firstZIndex remain unchanged) if
00485                 // there are no registered canvases with zIndex below axZrng--the total
00486                 // number of frames on the Z axis.  axZrng can be supplied; the default
00487                 // means 'use nelements()'.
00488                 // (Note: to get the zindex from the 'currently active' wch instead,
00489                 // a DD should check activeZIndex_.  Or, if the desired wch is known,
00490                 // it can retrieve the zIndex itself from wch.restrictionBuffer()).
00491                 virtual Bool getFirstZIndex(int& firstZIndex, Int axZrng=-1) const {
00492                         Block<Int> zInds = allZIndices(axZrng);
00493                         if(zInds.nelements()==0) return False;
00494                         firstZIndex=zInds[0];
00495                         return True;
00496                 }
00497 
00498 
00499 
00500                 // Add event handlers on the DisplayData. I am not sure there is also a need
00501                 // for a refresh handler on a DisplayData, but allowing for it  makes
00502                 // things 'symmetric'. These member functions throw an AipsError if a null
00503                 // pointer is passed.
00504                 // <group>
00505                 virtual void addPositionEventHandler(WCPositionEH *positionHandler);
00506                 virtual void addMotionEventHandler(WCMotionEH *motionHandler);
00507                 virtual void addRefreshEventHandler(WCRefreshEH *refreshHandler);
00508                 virtual void addDisplayEventHandler(DisplayEH *displayHandler);
00509                 // </group>
00510 
00511                 // Remove eventhandlers
00512                 // <group>
00513                 virtual void removePositionEventHandler(WCPositionEH& positionHandler);
00514                 virtual void removeMotionEventHandler(WCMotionEH& motionHandler);
00515                 virtual void removeRefreshEventHandler(WCRefreshEH& refreshHandler);
00516                 virtual void removeDisplayEventHandler(DisplayEH& displayHandler);
00517                 // </group>
00518 
00519                 // Set/remove/get a ColourMap (sorry, ColorMap) for this DisplayData
00520                 // setColormap() throw an AipsError is a null pointer is passed. colormap()
00521                 // returns 0 if no Colormap is registered.
00522                 // <group>
00523                 virtual void setColormap(Colormap *cmap, Float weight);
00524                 virtual void removeColormap();
00525                 virtual Colormap *colormap() const {
00526                         return itsColormap;
00527                 }
00528                 // </group>
00529 
00530 
00531                 // set an Attribute or Attributes
00532                 // <group>
00533                 void setAttribute(Attribute& at);
00534                 void setAttributes(AttributeBuffer& at);
00535                 // </group>
00536 
00537                 // User interface to get value from the attribute buffer
00538                 // <group>
00539 
00540                 Bool getAttributeValue(const String& name, uInt& newValue) ;
00541                 Bool getAttributeValue(const String& name, Int& newValue) ;
00542                 Bool getAttributeValue(const String& name, Float& newValue) ;
00543                 Bool getAttributeValue(const String& name, Double& newValue) ;
00544                 Bool getAttributeValue(const String& name, Bool& newValue) ;
00545                 Bool getAttributeValue(const String& name, String& newValue) ;
00546                 Bool getAttributeValue(const String& name, Vector<uInt>& newValue) ;
00547                 Bool getAttributeValue(const String& name, Vector<Int>& newValue) ;
00548                 Bool getAttributeValue(const String& name, Vector<Float>& newValue) ;
00549                 Bool getAttributeValue(const String& name, Vector<Double>& newValue) ;
00550                 Bool getAttributeValue(const String& name, Vector<Bool>& newValue) ;
00551                 Bool getAttributeValue(const String& name, Vector<String>& newValue) ;
00552                 // </group>
00553 
00554                 // Check if a certain Attribute exists
00555                 Bool existsAttribute(String& name) ;
00556 
00557                 // Remove an  Attribute
00558                 void removeAttribute(String& name);
00559 
00560                 // Get the type of the Attribute
00561                 AttValue::ValueType attributeType(String& name) ;
00562 
00563                 // Set an attribute on any WorldCanvas for which this DD is CS master
00564                 void setAttributeOnPrimaryWCHs(Attribute &at);
00565 
00566                 // <group>
00567                 virtual void notifyRegister(WorldCanvasHolder *wcHolder) ;
00568                 // <src>ignoreRefresh</src> tells the DD not to refresh just to clean
00569                 // up DMs
00570                 virtual void notifyUnregister(WorldCanvasHolder& wcHolder,
00571                                               Bool ignoreRefresh = False) ;
00572                 // </group>
00573 
00574                 // remove this DD everywhere--will stop any more refresh handling by
00575                 // the DD.  It is a good idea for top-level DDs to call this first
00576                 // in their destructor.
00577                 virtual void removeFromAllWCHs();
00578 
00579                 // install the default options for this DisplayData
00580                 virtual void setDefaultOptions();
00581 
00582                 // apply options stored in val to the DisplayData; return value
00583                 // True means a refresh is needed...
00584                 virtual Bool setOptions(Record &rec, Record &recOut);
00585 
00586                 // retrieve the current and default options and parameter types.
00587                 virtual Record getOptions( bool scrub=false ) const;
00588 
00589                 // an explicit refresh: should be called if the DisplayData is
00590                 // changed such that drawing is required.  If clean is True,
00591                 // the DD is totally rebuilt, in practice.  This is provided
00592                 // for higher level control, even explicit control of refresh
00593                 // where necessary.
00594                 // ..."refresh(True)"... does not seem to work <drs:Mar 21 2013>
00595                 virtual void refresh(Bool clean = False);
00596 
00597                 // an explicit request to draw the axes and/or labels.  Returns
00598                 // True if axes were drawn, otherwise False;
00599                 virtual Bool labelAxes(const WCRefreshEvent &ev);
00600                 virtual Bool canLabelAxes() const{
00601                         return false;
00602                 }
00603 
00604                 // Return the class name of this DisplayData; useful mostly for
00605                 // debugging purposes, and perhaps future use in the glish widget
00606                 // interface.
00607                 virtual String className() const {
00608                         return String("DisplayData");
00609                 }
00610                 virtual String description( ) const {
00611                         return "not available";
00612                 }
00613 
00614                 // Return the DisplayData type; used by the WorldCanvasHolder to
00615                 // determine the order of drawing.
00616                 virtual Display::DisplayDataType classType() = 0;
00617 
00618                 virtual String dataType( ) const = 0;
00619                 virtual const IPosition dataShape( ) const = 0;
00620                 virtual uInt dataDim( ) const = 0;
00621                 virtual const Unit dataUnit( ) const = 0;
00622                 virtual std::vector<int> displayAxes( ) const = 0;
00623 
00624                 // Get image analyis about images... for non-image
00625                 // "DisplayData" this function will return null...
00626                 // Use dataType() to check...
00627                 // Creates a new object (or a null pointer) which may need to be deleted...
00628                 virtual ImageAnalysis *imageanalysis( ) const {
00629                         return 0;
00630                 }
00631                 // Returns a pointer that should *not* be deleted...
00632                 virtual SHARED_PTR<ImageInterface<Float> > imageinterface( ) {
00633                         return SHARED_PTR<ImageInterface<Float> >();
00634                 }
00635 
00636                 virtual void setSubstituteTitleText( const String /*title*/ ){
00637 
00638                 }
00639 
00640                 // Identify the WorldCanvasHolder for the given WorldCanvas.  Return
00641                 // <src>0</src> if the DisplayData does not know of a
00642                 // WorldCanvasHolder for the WorldCanvas.
00643                 const WorldCanvasHolder *findHolder(const WorldCanvas *wCanvas) const;
00644                 WorldCanvasHolder *findHolder(const WorldCanvas *wCanvas);
00645 
00646                 // Return a sorted Block of all animation frame numbers currently set
00647                 // onto all WCHs where this DD is registered.
00648                 // The frame numbers returned are guaranteed to be in the range
00649                 // 0 <= zIndex < axZrng, where axZrng is the total number of frames
00650                 // on the Z axis.  axZrng can be supplied; the default is nelements().
00651                 virtual Block<Int> allZIndices(Int axZrng=-1) const;
00652 
00653                 // Will be called just before registering the [GTk]DD on a [GTk]PanelDisplay
00654                 // which has none registered on it yet.  The DD can set the initial
00655                 // animator position in this case by overriding this method to set
00656                 // preferredZIndex and return True.
00657                 virtual Bool zIndexHint(Int& /*preferredZIndex*/) const {
00658                         return False;
00659                 }
00660 
00661                 // Overide DisplayEH::handleEvent. This base class on forwards the
00662                 // event on to listeners
00663                 virtual void handleEvent(DisplayEvent &ev);
00664 
00665                 // Is this DD the CS master of the passed WCH?
00666                 // Defaulting wch to 0 asks whether this DD is CS master of _some_ WCH
00667                 // on which it is registered.  (That option is mostly a kludge, since the
00668                 // DD may be CS master of some WCHs and not others).
00669                 virtual Bool isCSmaster(const WorldCanvasHolder* wch=0) const;
00670 
00671                 // DD 'Absolute Pixel Coordinates', e.g. channel numbers, are internally
00672                 // 0-based (they begin numbering at 0), but certain external user-interface
00673                 // functions (e.g. showPosition(), used for position tracking) have
00674                 // produced 1-based output traditionally for the glish-based viewer.
00675                 // uiBase_, and related methods uiBase() and setUIBase(), allow newer
00676                 // (python/Qt-based) code to cause external ui functions like showValue()
00677                 // to report 0-based values instead.  Unless setUIBase(0) is called, the
00678                 // traditional 1-based reporting behavior is retained by default.
00679                 //
00680                 // If you are using 0-basing in the user interface, you should call
00681                 // setUIBase(0) right after constructing this DD, before other
00682                 // user interface operations such as getOptions().
00683                 // <group>
00684                 virtual Int uiBase() const {
00685                         return uiBase_;
00686                 }
00687 
00688                 virtual void setUIBase(Int uibase) {
00689                         if(uibase==0 || uibase==1) uiBase_ = uibase;
00690                 }
00691                 // </group>
00692 
00693                 // Get and set method for the flag
00694                 // <group>
00695                 virtual Bool getDelTmpData( ) {
00696                         return delTmpData_;
00697                 }
00698                 virtual void setDelTmpData(Bool delTmpData) {
00699                         delTmpData_ = delTmpData;
00700                 }
00701                 // </group>
00702 
00703                 virtual void setDisplayDataRed( DisplayData* /*dd*/ ){}
00704                 virtual void setDisplayDataBlue( DisplayData* /*dd*/ ){}
00705                 virtual void setDisplayDataGreen( DisplayData* /*dd*/ ){}
00706 
00707                 const static String DATA_MIN;
00708                 const static String DATA_MAX;
00709 
00710         protected:
00711 
00712                 // DDs may override to adjust the internal stored current animation
00713                 // index (activeZIndex_) if necessary, and to set return value False
00714                 // iff the passed zindex won't work for the DD.  zIndexConformed_
00715                 // should be set to the value returned; activeZIndex_ should also
00716                 // be set appropriately.
00717                 virtual Bool setActiveZIndex_(Int zindex) {
00718                         activeZIndex_ = zindex;
00719                         zIndexConformed_ = True;
00720                         return zIndexConformed_;
00721                 }
00722 
00723 
00724                 // The Book says that we should not put data members in class that is
00725                 // supposed to only define an interface, but by putting these here, we can
00726                 // implement some of the restriction & eventhandling stuff so that people do
00727                 // not have to repeat it.
00728 
00729                 // buffer for storing restrictions
00730                 AttributeBuffer  restrictions;
00731 
00732                 // buffer for storing Attributes
00733                 AttributeBuffer attributes;
00734 
00735                 // list of DisplayDataElements, which are of type DisplayMethod or derived
00736                 PtrBlock<void *> DDelement;
00737 
00738                 // Protected interface for WorldCanvasHolder, can be called by the friends
00739                 // of DisplayData, but are nobody else's business. I decided to do this in
00740                 // this way to avoid that the programmer has to both register the
00741                 // DisplayData with the WorldCanvasHolder AND the WorldCanvasHolder with the
00742                 // DisplayData. Now one of the two is done automatically.
00743                 // The WorldCanvasHolder is my friend. This is to hide the eventhandler
00744                 // interfaces listed below from the outside world. The WorldCanvasHolder is
00745                 // the only class that needs them
00746                 friend class WorldCanvasHolder;
00747 
00748                 // Indicates the 'current' animation frame, i.e. the zIndex on the canvas
00749                 // for which confromsTo(wch) was last called.  Intended to be set only
00750                 // by setActiveZIndex_() in this class or derived classes.
00751                 Int activeZIndex_;
00752 
00753                 // Flag indicating that temporary data should be removed when deleting
00754                 // the object.
00755                 Bool delTmpData_;
00756 
00757                 // Somewhat limited-use state, saved here for 'efficiency'.  Indicates
00758                 // that the last call to conformsToRstrs(), conformsToCS(), or
00759                 // conformsToZIndex(), passed the respective compatibility tests.
00760                 // (See conformed(), below).  Intended to be set only in the methods
00761                 // conformsToRstrs(), conformsToCS() and setActiveZIndex_(), respectively.
00762                 Bool rstrsConformed_, csConformed_, zIndexConformed_;
00763 
00764                 // Returns result of last call to conformsTo(WCH&).  Methods like showValue()
00765                 // which don't have access to the wch can use it instead, but that
00766                 // shifts the burden elsewhere of being sure that conformsTo() was called
00767                 // for the current WCH.  When possible, it is generally better and safer
00768                 // to call conformsTo(wch) directly when needed, rather than querying this.
00769                 Bool conformed() {
00770                         return rstrsConformed_ && csConformed_ && zIndexConformed_;
00771                 }
00772                 //Added so that when two images are loaded with no velocity
00773                 //alignment, they can still show their position coordinates without
00774                 //having to be rstrsConformed.
00775                 Bool isCsAndZIndexConformed() {
00776                         return csConformed_ && zIndexConformed_;
00777                 }
00778                 // Set (coordinate) state of WCH's WC.  Called by WCH::executeSizeControl().
00779                 // (See important notes on interface and implementation of this function
00780                 // in the class synopsis above).
00781                 virtual Bool sizeControl(WorldCanvasHolder& wcHolder,
00782                                          AttributeBuffer& holderBuf) = 0;
00783 
00784                 // Delete temporary data. To be called by sub-classe
00785                 // that now the filenames.
00786                 virtual void delTmpData(String &tmpData);
00787 
00788 
00789                 // Retrieve position, motion, refresh and display event handler lists.
00790                 // <group>
00791                 virtual const List<WCPositionEH*> *positionEventHandlerList() {
00792                         return &itsPositionEHList;
00793                 }
00794                 virtual const List<WCMotionEH*> *motionEventHandlerList() {
00795                         return &itsMotionEHList;
00796                 }
00797                 virtual const List<WCRefreshEH*> *refreshEventHandlerList() {
00798                         return &itsRefreshEHList;
00799                 }
00800                 virtual const List<DisplayEH*> *displayEventHandlerList() {
00801                         return &itsDisplayEHList;
00802                 }
00803                 // </group>
00804 
00805                 // Position, motion and refresh event handlers that will generally
00806                 // be called by a WorldCanvasHolder.
00807                 // <group>
00808                 virtual void positionEH(const WCPositionEvent &ev);
00809                 virtual void motionEH(const WCMotionEvent &ev);
00810                 virtual void refreshEH(const WCRefreshEvent& ev) = 0;
00811                 // </group>
00812 
00813                 // clean up the memory used by this DisplayData
00814                 virtual void cleanup() = 0;
00815 
00816                 // (Required) copy constructor.
00817                 DisplayData(const DisplayData &other);
00818 
00819                 // (Required) copy assignment.
00820                 void operator=(const DisplayData &other);
00821 
00822 
00823         private:
00824 
00825                 WorldCanvasHolder* oldWCHolder;
00826 
00827                 // is this data currently being displayed?
00828                 DisplayState displaystate;
00829 
00830                 // Colormap for this DisplayData, and its weight.
00831                 Colormap *itsColormap;
00832                 Float itsColormapWeight;
00833 
00834                 // A list of WorldCanvasHolders for which this DisplayData works.
00835                 // The list is maintained by the DisplayData itself based on the
00836                 // notify routines used by the WorldCanvasHolder.  This can be used,
00837                 // for example, to find which WorldCanvas belongs to which
00838                 // WorldCanvasHolder.
00839                 List<WorldCanvasHolder*> itsWCHList;
00840 
00841                 // Lists of position, motion, refresh and display event handlers.
00842                 List<WCPositionEH*> itsPositionEHList;
00843                 List<WCMotionEH*> itsMotionEHList;
00844                 List<WCRefreshEH*> itsRefreshEHList;
00845                 List<DisplayEH*> itsDisplayEHList;
00846 
00847                 // DD 'Absolute Pixel Coordinates', e.g. channel numbers, are internally
00848                 // 0-based (begin numbering at 0), but certain external user-interface
00849                 // functions (e.g. showPosition(), used for position tracking) have
00850                 // produced 1-based output traditionally for the glish-based viewer.
00851                 // uiBase_, and related methods uiBase() and setUIBase(), allow newer
00852                 // (python/Qt-based) code to cause external ui functions like showValue()
00853                 // report 0-based values instead.  Unless setUIBase(0) is called, the
00854                 // traditional 1-based reporting behavior is retained by default.
00855 
00856                 Int uiBase_;            // (initialized to 1).
00857         };
00858 
00859 
00860 } //# NAMESPACE CASA - END
00861 
00862 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 31 Aug 2016 for casa by  doxygen 1.6.1