casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
MultiPVTool.h
Go to the documentation of this file.
00001 //# MultiPVTool.h: Base class for MultiWorldCanvas event-based rectangle tools
00002 //# Copyright (C) 2013
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 DISPLAY_MULTIPVTOOL_H_
00029 #define DISPLAY_MULTIPVTOOL_H_
00030 
00031 #include <list>
00032 #include <casa/aips.h>
00033 #include <display/DisplayEvents/RegionTool.h>
00034 #include <display/DisplayEvents/DTVisible.h>
00035 #include <display/region/RegionCreator.h>
00036 #include <display/region/RegionSourceFactory.h>
00037 
00038 
00039 namespace casa { //# NAMESPACE CASA - BEGIN
00040 
00041         namespace viewer {
00042                 class QtRegionDock;
00043         }
00044 
00045 // <summary>
00046 // Base class for MultiWorldCanvas event-based rectangle tools
00047 // </summary>
00048 //
00049 // <use visibility=export>
00050 //
00051 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos="">
00052 // </reviewed>
00053 //
00054 // <prerequisites>
00055 //   <li> WCTool
00056 // </prerequisites>
00057 //
00058 // <etymology>
00059 // MultiPVTool stands for MultiWorldCanvas PVLine Tool
00060 // </etymology>
00061 //
00062 // <synopsis>
00063 // This class adds to its base WCTool to provide a tool for drawing,
00064 // resizing and moving rectangles on a WorldCanvas.  While MultiPVTool
00065 // is not abstract, it performs no useful function.  The programmer
00066 // should derive from this class, and implement the functions
00067 // doubleInside and doubleOutside, which are called when the user
00068 // double-clicks the key or mouse button inside or outside an existing
00069 // rectangle respectively.  It is up to the programmer to decide what
00070 // double clicks inside and outside the rectangle correspond to,
00071 // although it is recommended that a double click inside correspond to
00072 // the main action of the tool, and a double click outside correspond
00073 // to a secondary action of the tool, if indeed a secondary action
00074 // exists.
00075 //
00076 // The rectangle is drawn by dragging the mouse from one corner to 
00077 // the diagonally opposite corner.  Once constructed, the rectangle
00078 // can be resized by dragging its corners, or relocated by dragging
00079 // inside the rectangle.  The rectangle is removed from the display 
00080 // when the Esc key is pressed.
00081 // </synopsis>
00082 //
00083 // <example>
00084 // </example>
00085 //
00086 // <motivation>
00087 // Many activities on the WorldCanvas will be based on the user drawing 
00088 // a rectangle, and then proceeding to some action with that rectangle.
00089 // A nice example is zooming.
00090 // </motivation>
00091 
00092     class MultiPVTool : public RegionTool, public DTVisible, public viewer::RegionCreator {
00093   
00094         public:
00095   
00096             // Constructor
00097             MultiPVTool( viewer::RegionSourceFactory *rsf, PanelDisplay* pd,
00098                            Display::KeySym keysym = Display::K_Pointer_Button1, const Bool persistent = False );
00099   
00100             // Destructor
00101             virtual ~MultiPVTool();
00102   
00103             // Switch the tool off - this erases the rectangle, if any,
00104             // and calls the base class disable.
00105             virtual void disable();
00106 
00107             // reset to non-existent, non-active rectangle.
00108             // Refreshes if necessary to erase (unless skipRefresh==True  In
00109             // that case, the caller should do the refresh itself).
00110             // (Does not unregister from WCs or disable future event handling).
00111             virtual void reset(Bool skipRefresh=False);
00112   
00113             // Is a rectangle currently defined?
00114             virtual Bool rectangleDefined() { return itsPVLineExists;  } 
00115  
00116             viewer::RegionSource *getRegionSource( ) { return rfactory; }
00117 
00118             void checkPoint( WorldCanvas *wc, State &state );
00119 
00120             // called when the user (read GUI user) indicates that a region should be deleted...
00121             void revokeRegion( viewer::Region * );
00122 
00123             // returns a set which indicates regions this creator creates...
00124             const std::set<viewer::region::RegionTypes> &regionsCreated( ) const;
00125 
00126             bool create( viewer::region::RegionTypes /*region_type*/, WorldCanvas */*wc*/, const std::vector<std::pair<double,double> > &/*pts*/,
00127                          const std::string &/*label*/, viewer::region::TextPosition /*label_pos*/, const std::vector<int> &/*label_off*/,
00128                          const std::string &/*font*/, int /*font_size*/, int /*font_style*/, const std::string &/*font_color*/,
00129                          const std::string &/*line_color*/, viewer::region::LineStyle /*line_style*/, unsigned int /*line_width*/,
00130                          bool /*annotation*/, VOID */*region_specific_state*/ );
00131 
00132             RegionToolTypes type( ) const { return PVLINETOOL; }
00133 
00134         protected:
00135 
00136             // Functions called by the base class event handling operators--and
00137             // normally only those.  This is the input that controls the rectangle's
00138             // appearance and action.  When the rectangle is ready and double-click
00139             // is received, the doubleInside/Outside routine will be invoked.
00140             // <group>
00141             virtual void keyPressed(const WCPositionEvent &ev);
00142             virtual void keyReleased(const WCPositionEvent &ev);
00143             virtual void otherKeyPressed(const WCPositionEvent &ev);
00144             virtual void moved(const WCMotionEvent &ev, const viewer::region::region_list_type & /*selected_regions*/);
00145             // </group>
00146 
00147             // draw the rectangle (if any) on the object's currently active WC.
00148             // Only to be called by the base class refresh event handler.  Derived
00149             // objects should use refresh() if they need to redraw, but even that
00150             // is normally handled automatically.
00151             virtual void draw(const WCRefreshEvent&/*ev*/, const viewer::region::region_list_type & /*selected_regions*/);
00152 
00153             // Output callback functions--to be overridden in derived class.
00154             // Called when there is a double click inside/outside the rectangle
00155             // <group>
00156             virtual void doubleInside() { };
00157             virtual void doubleOutside() { };
00158             // </group>
00159 
00160             // Called when a rectangle is ready and not being 
00161             // edited.  (Unused so far on the glish level (12/01)).
00162             virtual void rectangleReady() { };
00163 
00164 
00165             // Retrieve the rectangle coordinates, in screen pixels.
00166             // Anchor (if applicable) is (x1,y1).  Valid during the output callbacks;
00167             // to be used by them, as well as internally.
00168             virtual void get(Int &x1, Int &y1, Int &x2, Int &y2) const ;
00169 
00170                 virtual bool checkType( viewer::region::RegionTypes t ) { return t == viewer::region::PVLineRegion; }
00171             virtual std::tr1::shared_ptr<viewer::PVLine> allocate_region( WorldCanvas *wc, double x1, double y1, double x2, double y2, VOID *region_specific_state ) const;
00172 
00173 
00174             viewer::RegionSource *rfactory;
00175 
00176         private:
00177             typedef std::list<std::tr1::shared_ptr<viewer::PVLine> > pvlinelist;
00178 
00179             void update_stats(const WCMotionEvent &ev);
00180             void start_new_rectangle( WorldCanvas *, int x, int y );
00181 
00182             // set the pixel coordinates of the rectangle
00183             virtual void set(const Int &x1, const Int &y1, const Int &x2, const Int &y2);
00184 
00185             // get only the anchor point
00186             virtual void get(Int &x1, Int &y1) const;
00187 
00188             // do we have a rectangle yet? (if True, itsCurrentWC, itsEmitted, P1, and P2 are valid)
00189             Bool itsPVLineExists;
00190 
00191             // was the button pressed in the rectangle (or, if none, in an active WC)
00192             // and not yet released/reset?
00193             Bool itsActive;
00194             // itsActive is being replaced by resizing_region
00195             std::tr1::shared_ptr<viewer::PVLine> resizing_region;
00196             std::tr1::shared_ptr<viewer::PVLine> creating_region;
00197             int resizing_region_handle;
00198 
00199             // (valid only if itsActive==True):
00200             // True = being moved     False = being resized
00201             Bool itsMoving;
00202             // itsMoving is being replaced by moving_regions
00203             pvlinelist moving_regions;
00204             double moving_linx_;
00205             double moving_liny_;
00206 
00207             // (valid only if itsPVLineExists==True)
00208             // Has doubleInside/Outside been called for this rectangle?  If so, a
00209             // key press outside the rectangle will start a new rectangle, as if
00210             // itsPVLineExists were False.
00211             // However, a key press inside the rectangle will reset
00212             // itsEmitted to False, allowing the rectangle to be reused
00213             // (possibly moved or resized, and emitted again).
00214             Bool itsEmitted;
00215 
00216             // (Linear) coordinates of the rectangle (invariant over zooms, but not
00217             // coordinate system changes.  To do: support the WorldCoordinateChange
00218             // refresh reason, and reset this tool when it occurs).
00219             Vector<Double> itsP1, itsP2;
00220 
00221             // storage of the handle (pixel) coordinates
00222             Vector<Int> itsHX, itsHY;
00223 
00224             // position that move started from
00225             Int itsBaseMoveX, itsBaseMoveY;
00226 
00227             // store the times of the last two presses here:
00228             Double itsLastPressTime, its2ndLastPressTime;
00229 
00230             pvlinelist rectangles;
00231             PanelDisplay *pd_;
00232 
00233     };
00234 
00235 } //# NAMESPACE CASA - END
00236 
00237 #endif