Animator.h

Go to the documentation of this file.
00001 //# Animator.h: movie control for one or more WorldCanvasHolders
00002 //# Copyright (C) 1996,1997,1999,2000
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_ANIMATOR_H
00029 #define TRIALDISPLAY_ANIMATOR_H
00030 
00031 //# aips includes
00032 #include <casa/aips.h>
00033 #include <casa/Containers/List.h>
00034 
00035 //# display library includes
00036 #include <display/DisplayEvents/WCRefreshEH.h>
00037 
00038 namespace casa { //# NAMESPACE CASA - BEGIN
00039 
00040 //# forwards
00041         class WorldCanvasHolder;
00042         class Animator;
00043 
00044 // <summary>
00045 // WorldCanvas refresh event handler for Animator class.
00046 // </summary>
00047 //
00048 // <synopsis>
00049 // This class is a simple implementation of a WCRefreshEH which
00050 // passes WorldCanvas refresh events on to an Animator object.
00051 // </synopsis>
00052 
00053         class AnimatorRefEH : public WCRefreshEH {
00054         public:
00055                 AnimatorRefEH(Animator *animator);
00056                 virtual ~AnimatorRefEH() {};
00057                 virtual void operator()(const WCRefreshEvent &ev);
00058         private:
00059                 Animator *itsAnimator;
00060         };
00061 
00062 // <summary>
00063 // Animation controller for WorldCanvasHolders.
00064 // </summary>
00065 // <use visibility=export>
00066 //
00067 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos="">
00068 // </reviewed>
00069 //
00070 // <prerequisite>
00071 //   <li> Attribute
00072 //   <li> AttributeBuffer
00073 //   <li> WorldCanvasHolder
00074 //   <li> DisplayData
00075 // </prerequisite>
00076 //
00077 // <etymology>
00078 // An Animator animates animations
00079 // </etymology>
00080 //
00081 // <synopsis>
00082 //  TBW
00083 // </synopsis>
00084 // <example>
00085 //
00086 // First example is making a simple movie of all the
00087 // channels in a data cube
00088 //
00089 // <srcblock>
00090 // // Create a PixelCanvas for X11 to draw on
00091 // X11PixelCanvas(parent, xpcctbl, width, height) ;
00092 // // and a World Coordinate  interface for this PixelCanvas
00093 // WorldCanvas  wCnvs(&pixelCnvs);
00094 //
00095 // // Create a WorldCanvasHolder
00096 // WorldCanvasHolder wCnvsHldr(&wCnvs);
00097 //
00098 // // Create an ImageDisplayData object of the data cube to display the
00099 // // channels (assuming 3rd axis is velocity in this cube)
00100 // ImageDisplayData cube(myDataSet, 0, 1, 2);
00101 // // and register this with the WorldCanvasHolder
00102 // wCnvsHldr.addDisplayData(&cube);
00103 //
00104 // // Create an Animator for the WorldCanvasHolder and register the
00105 // // WorldCanvasHolder
00106 // Animator animator;
00107 // animator.addWorldCanvasHolder(&wCnvsHldr);
00108 //
00109 // // start with first channel
00110 // animator.setMin(0.0);
00111 // // last channel of cube (assuming it has 30 channels)
00112 // animator.setMax(29.0);
00113 // // go in steps of one channel
00114 // animator.setStep(1.0);
00115 // // only one channel at a time, so tolerance must be less than 1.0
00116 // anomator.setTolerance(0.1);
00117 // // display new channel every 0.2 sec
00118 // animator.setUpdateInterval(0.2);
00119 // // we want a normal boring movie
00120 // animator.setNextMode(animator::NEXT_FORWARD);
00121 // // and we define the channel (ie index)
00122 // animator.setMatchMode(Animator::MATCH_INDEX);
00123 // // set the Update method
00124 // animator.setUpdateMode(Animator::UPDATE_DIRECT);
00125 // // and start the movie
00126 // animator.startMovie();
00127 //       .
00128 //       .
00129 //       .
00130 // // After a while we want to change to Rock & Roll mode:
00131 // animator.setMovieMode(Animator::NEXT_ROCKandROLL);
00132 //       .
00133 //       .
00134 //       .
00135 // // and after another while we stop
00136 // animator.stopMovie();
00137 // </srcblock>
00138 // Second example is that we want to blink between channel 20 of the previous
00139 // cube and an optical image
00140 // <srcblock>
00141 // // Create an ImageDataDisplay of the image and register with
00142 // // the WorldCanvasHolder
00143 // ImageDataDisplay image(myImage, 0, 2);
00144 // wCnvsHldr.addDisplayData(&image);
00145 //
00146 // // Create a List to contain the AttributeBuffers
00147 // List<void *> buffList;
00148 // // and an iterator for this list
00149 // ListIter<void *> it(&buffList);
00150 //
00151 // // Create AttributeBuffers and fill them
00152 // AttributeBuffer atBuff1;
00153 // // This is to mark the cube. The name and value of the Attribute or
00154 // // Attributes that can be used is arbitrary, as long as the different
00155 // // AttributeBuffers in the List select different datasets (even that is
00156 // // not really necessary, but you will be blinking between the same frames
00157 // // and not many people will get excited about that....)
00158 // atBuff1.add("AjaxWordtKampioen", "yes");
00159 // it.addRight((void *) &attBuff1);
00160 //
00161 // // the buffer for the image
00162 // AttributeBuffer atBuff2;
00163 // atBuff2.add("AjaxWordtKampioen", "of course");
00164 // at.addRight((void *) &attBuff2);
00165 //
00166 // // and set this list on the Animator
00167 // animator.setBlinkList(&buffList);
00168 //
00169 // // Set the same attributes on the DisplayDatas so the Attribute matching
00170 // // mechanism between the WorldCanvasHolder and the DisplayDatas will select
00171 // // the right data at the right time automatically
00172 // cube.addAttribute(attBuff1);
00173 // image.addAttribute(attBuff2);
00174 //
00175 // // Tell animator to use channel 20
00176 // animator.gotoCoord(20.0);
00177 // // The Animator should write "zIndex" to select channel 20
00178 // animator.setMatchMode(Animator::MATCH_INDEX);
00179 // // Because we set the UpdateMode to UPDATE_BLINK, the zIndex does
00180 // // not change each time the timer goes off.
00181 // animator.setUpdateMode(Animator::UPDATE_BLINK);
00182 // // and the blinking can start:
00183 // animator.startMovie();
00184 //       .
00185 //       .
00186 //       .
00187 // // After a while we want to blink between channel 19 and the optical image.
00188 // // this is done by setting NextMode to NEXT_BACKWARD and invoke nextCoord().
00189 // // Of course we could also have used only animator.prevCoord(), but just
00190 // // to show the principle...
00191 // animator.setNextMode(Animator::NEXT_BACKWARD);
00192 // animator.nextCoord();
00193 
00194 //
00195 // // We can add a third data set, set "AjaxWordtKampioen" to "always" for that data,
00196 // // and the blinking is between 3 datasets:
00197 //
00198 // // stop the blinking
00199 // animator.stopMovie();
00200 //
00201 // // Create DisplayData from data
00202 // ImageDataDisplay image2(mySecondImage, 0, 2);
00203 //
00204 // // Add to WorldCanvasHolder
00205 // wCnvsHldr.addDisplayData(&image2);
00206 //
00207 // //Setup AttributeBuffer
00208 // AttributeBuffer atBuff3;
00209 // atBuff3.add("AjaxWordtKampioen", "always");
00210 //
00211 // // add to data
00212 // image2.addAttribute(attBuff3);
00213 //
00214 // // and add to List
00215 // at.addRight((void *) &attBuff3);
00216 //
00217 // // set the updated list on the animator (strictly speaking not neseccary
00218 // // here, because animator already has the address of this List, but...)
00219 // animator.setBlinkList(&buffList);
00220 //
00221 // //and go!!!
00222 // animator.startMovie();
00223 // </srcblock>
00224 // The third example is to run movies, selected on world coordinates on two
00225 // WorldCanvasHolders in synch:
00226 // <srcblock>
00227 // // Create a PixelCanvas for X11 to draw on
00228 // X11PixelCanvas(parent, xpcctbl, width, height) ;
00229 // // and two  WorldCanvases side by side on the same PixelCanvas
00230 // WorldCanvas wCnvs1(&pixelCanvas, 0.0, 0.25, 0.5, 0.5);
00231 // WorldCanvas wCnvs2(&pixelCanvas, 0.5, 0.25, 0.5, 0.5);
00232 //
00233 // // A WorldCanvasHolder for each WorldCanvas
00234 // WorldCanvasHolder wCnvsHldr1(&wCnvs1);
00235 // WorldCanvasHolder wCnvsHldr2(&wCnvs2);
00236 //
00237 // // We have an HI data cube of an object
00238 // ImageDisplayData HIcube(HIdata, 0, 1, 2);
00239 // // that we display on the first WorldCanvas
00240 // wCnvsHldr1.addDisplayData(HIcube);
00241 //
00242 // // and we have a CO cube of the same object that we display on the second
00243 // // WorldCanvas
00244 // ImageDisplayData COcube(COdata, 0, 1, 2);
00245 // wCnvsHldr2.addDisplayData(COcube);
00246 //
00247 // // Create an animator and register the two WorldCanvasHolders
00248 // Animator animator;
00249 // animator.addWorldCanvasHolder(wCnvsHldr1);
00250 // animator.addWorldCanvasHolder(wCnvsHldr2);
00251 //
00252 // // Set the movie parameters:
00253 // // Select on world coordinate (ie velocity)
00254 // animator.setMatchMode(Animator::MATCH_WORLD);
00255 // // start and end velocities
00256 // animator.setMinAndMax(1200.0, 1400.0);
00257 // // and the tolerance to 10.0 and the step to 20.0
00258 // animator.setTolerance(10.0):
00259 // animator.setStep(20.0);
00260 //
00261 // // Set speed of movies and the mode
00262 // animator.setUpdateInterval(0.2);
00263 // animator.setNextMode(Animator::ROCKandROLL);
00264 //
00265 // // Now, on the first canvas a movie will be played of the HI data, and on
00266 // // the second canvas a movie of the CO data. Because the selection is done
00267 // // on world coordinate, the two movies display the data of the same
00268 // // velocity (within the tolerance of 10.0), in steps of 20.0, synchronized,
00269 // // regardless of the channel separation of the two datasets:
00270 // animator.startMovie();
00271 //
00272 // </srcblock>
00273 // </example>
00274 //
00275 //
00276 // <motivation> To allow for easy control of movies, possibly synchonous on
00277 // more than one WorldCanvas, as well as lay the basis for the userinterface
00278 // for this, a central class is needed that controls sequences of DisplayData.
00279 // </motivation>
00280 //
00281 // <todo>
00282 //   <li> make Animator know about Units
00283 // </todo>
00284 
00285         class Animator {
00286 
00287         public:
00288 
00289                 // Defines the way the Animator calculates the Z coordinate of the next
00290                 // frame in the sequence. This defines the behaviour of the member
00291                 // nextCoord().
00292                 enum NextMode {
00293                     // Movie in forward direction. Step is added, if the Z coordinate is larger
00294                     // than maximum then display minimum, increment again until maximum, etc.
00295                     // This is the default.
00296                     NEXT_FORWARD,
00297                     // Movie in backward direction. Step is subtracted, if Z coordinate is
00298                     // smaller than mimnimum then display maximum, decrement until minimum,
00299                     // etc etc
00300                     NEXT_BACKWARD,
00301                     // Movie goes up and down the sequence. Step is added until the Z
00302                     // coordinate is larger than maximum, then step is subtracted until the Z
00303                     // coordinate is smaller than minimum, then step is added, and so on, and
00304                     // so on
00305                     NEXT_ROCKANDROLL
00306                 };
00307 
00308                 // Defines wheter the sequence is defined using the index in the sequence or
00309                 // by the world coordinate of the 'Z-axis' (the "zValue" or "zIndex" used by the
00310                 // WorldCanvasHolders and the DisplayDatas), or only by the AttributeBuffers
00311                 enum MatchMode {
00312                     // Sequence is defined by writing Attribute "zIndex" with the value of the
00313                     // Z coordinate to WorldCanvasHolders, plus the ones from the List of
00314                     // AttributeBuffers.
00315                     // This is the default
00316                     MATCH_INDEX,
00317                     // Sequence is defined by writing Attribute "zValue"with the value of the
00318                     // Z coordinate to WorldCanvasHolders, plus the ones from the List of
00319                     // AttributeBuffers
00320                     MATCH_WORLD,
00321                     // Only the Attributes from the List of AttributeBuffers are written
00322                     MATCH_LIST_ONLY
00323                 };
00324 
00325                 // Decides whether the Z coordinate should be changed according to the
00326                 // NextMode before each update or not
00327                 enum UpdateMode {
00328                     // Do change the Z coordinate before each update. Use this for 'normal
00329                     // movies'.
00330                     // This is the default.
00331                     UPDATE_DIRECT,
00332                     // Do not change Z coordinate, but rely on the AttributeBuffers to change
00333                     // what is displayed. Use this for blinking.
00334                     UPDATE_BLINK
00335                 };
00336 
00337 
00338 
00339                 // Constructor
00340                 Animator();
00341 
00342                 //Destrutor
00343                 virtual ~Animator();
00344 
00345                 // Go to next Z coordinate in sequence
00346                 virtual void nextCoord();
00347 
00348                 // Go to previous Z coordinate in sequence
00349                 virtual void prevCoord();
00350 
00351                 // Go to  Z coordinate zCoord
00352                 virtual void gotoCoord(Double zCoord);
00353 
00354                 // Set increment in the Z coordinate for the movie
00355                 // <group>
00356                 virtual void setStep(uInt zIncrement);
00357                 virtual void setStep(Double zIncrement);
00358                 // </group>
00359 
00360                 // Set the tolerance in the Z coordinate
00361                 // <group>
00362                 virtual void setTolerance(uInt tolerance);
00363                 virtual void setTolerance(Double tolerance);
00364                 // </group>
00365 
00366                 // Set the minimum and maximum Z coordinate for the movie
00367                 virtual void setMinAndMaxCoord(Double zMin, Double zMax);
00368 
00369                 // Set whether "zIndex", "zValue" or none of the two should be written
00370                 // additionally to the AttributeBuffers.
00371                 virtual void setMatchMode(Animator::MatchMode match);
00372 
00373 
00374                 // Set the way the increments are done, ie. it defines the action of
00375                 // nextCoord() (options NEXT_FORWARD, NEXT_BACKWARD, UPDATE_ROCKANDROLL)
00376                 virtual void setNextMode(Animator::NextMode  mode);
00377 
00378 
00379                 // Set whether an increment should be done before each update (UPDATE_DIRECT or
00380                 // UPDATE_BLINK)
00381                 virtual void setUpdateMode(Animator::UpdateMode mode);
00382 
00383                 // Set update interval of movie in milliseconds
00384                 virtual void setUpdateInterval(Double interval);
00385 
00386                 // Set the list of additional Attributes that the Animator  places on the
00387                 // WorldCanvasHolders before each update.
00388                 virtual void setBlinkRestrictions(List<void *> *attBuffers);
00389 
00390                 // Remove the List with AttributeBuffers
00391                 virtual void clearBlinkRestrictions();
00392 
00393                 // Stop and start movie
00394                 // <group>
00395                 virtual void startMovie();
00396                 virtual void stopMovie();
00397                 // </group>
00398 
00399                 // Return the length of the movie. In UpdateMode UPDATE_DIRECT this is the
00400                 // number of frames that follow from the minimum and maximum Z coordiante
00401                 // and the step. In UPDATE_BLINK mode this is the length of the List of
00402                 // AttributeBuffers set on the Animator using setBlinkAttributes
00403                 virtual uInt getMovieLength();
00404 
00405                 // Return the current position in the movie.  This is really a bad
00406                 // thing, but needed in the interim for the viewer.
00407                 virtual Int getCurrentPosition();
00408 
00409                 // Reset the Animator. This will set the minimum coordiante to 0, the
00410                 // maximum to the number of elements registered with the WorldCanvasHolders,
00411                 // the step to 1.0 and the update mode to MATCH_INDEX
00412                 virtual void reset();
00413 
00414                 // Add a WorldCanvasHolder to the list controlled by this Animator
00415                 virtual void addWorldCanvasHolder(WorldCanvasHolder *newHolder);
00416 
00417                 // Remove a WorldCanvasHolder from the list controlled by this Animator
00418                 virtual void removeWorldCanvasHolder(WorldCanvasHolder& holder);
00419 
00420                 // Refresh event handler - just used to see if resetCoordinates was
00421                 // set.  If so, then we should partially reset the animator.
00422                 virtual void operator()(const WCRefreshEvent& ev);
00423 
00424         private:
00425 
00426                 // List of WorldCanvasHolders
00427                 List<void *> holderList;
00428 
00429                 // List of the AttributeBuffers
00430                 List<void *> *attBufList;
00431 
00432                 // parameters of movies
00433                 Double minCoord;
00434                 Double maxCoord;
00435 
00436                 // Increment for computing currentCoord. Always postive
00437                 Double movieStep;
00438 
00439                 // State variables
00440                 // Tolerance for coordinate Restriction
00441                 Double coordTolerance;
00442                 // Current Z coordiante
00443                 Double currentCoord;
00444                 // the MatchMode
00445                 Animator::MatchMode matchMode;
00446                 // the NextMode
00447                 Animator::NextMode nextMode;
00448                 // The UpdateMode
00449                 Animator::UpdateMode updateMode;
00450                 // and the interval of the timer
00451                 Double updateInterval;
00452 
00453                 // The number of the AttributeBuffer to use. Computed by computeNewCoord()
00454                 // Has to be Int, not uInt! (because I sometimes subtract 1!)
00455                 Int numberInList;
00456 
00457                 // In which direction the movie is currently going
00458                 Int movieDirection;
00459 
00460                 // Compute, based on the UPDATE_MODE and NEXT_MODE, the Z coordinate of the
00461                 // new frame to display (ie. the new currentCoord). If the updateMode ==
00462                 // UPDATE_BLINK, nothing happens. If the updateMode == UPDATE_DIRECT, the
00463                 // value of currentCoord is incremented or decremented with the absolute
00464                 // value of movieStep, depending in whether the next_Mode is NEXT_FORWARD,
00465                 // NEXT_BACKWARD or NEXT_ROCKANDROLL and whether the new value goes outside
00466                 // the bounds set by minCoord and maxCoord.
00467                 void computeNextCoord(Int addOrSubtract);
00468 
00469                 // Helper routine for computeNewCoord(). If addOrSubtract > 0, 1 is added to
00470                 // number, if addOrSubtract < 0, 1 is subtracted
00471                 void increment(Int& number, Int addOrSubtract);
00472 
00473                 // Helper routine for computeNewCoord(). The inverse of <src>increment(Int&,
00474                 // Int)</src>
00475                 void decrement(Int& number, Int addOrSubtract);
00476 
00477                 // Helper routine for computeNewCoord(). If addOrSubtract > 0, movieStep is added to
00478                 // number, if addOrSubtract < 0, movieStep is subtracted
00479                 void increment(Double& number, Int addOrSubtract);
00480 
00481                 // Helper routine for computeNewCoord(). The inverse of <src>increment(Double&,
00482                 // Int)</src>
00483                 void decrement(Double& number, Int addOrSubtract);
00484 
00485 
00486                 // Write the necessary Attributes to all the WorldCanvasHolders. The content
00487                 // of one of the registered AttributeBuffer is always written. If the
00488                 // updateMode == UPDATE_DIRECT the n-th AttributeBuffer is written, where n
00489                 // is the sequence number of the frame, based on minCoord and movieStep. If
00490                 // the updateMode == UPDATE_BLINK the Animator just loops through the list
00491                 // of AttributeBuffers based on numberInList.
00492                 // If MatchMode == MATCH_INDEX also an Attribute is written with name
00493                 // "zIndex" and with the value of currentCoord.
00494                 // If MatchMode == MATCH_COORD also an Attribute is written with name
00495                 // "zValue" and with the value of currentCoord.
00496                 void writeRestrictions();
00497 
00498                 // Invoke refresh() on all the WorldCanvasHolders registered with the
00499                 // Animator
00500                 void refresh();
00501 
00502                 // Return the number of AttributeBuffers in the List of AttributeBuffer
00503                 Int listLen();
00504 
00505                 // refresh event handler
00506                 AnimatorRefEH *itsAnimatorRefEH;
00507 
00508         };
00509 
00510 
00511 } //# NAMESPACE CASA - END
00512 
00513 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 31 Aug 2016 for casa by  doxygen 1.6.1