casa
$Rev:20696$
|
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