casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
MultiPolylineTool.h
Go to the documentation of this file.
00001 //# Copyright (C) 1999,2000,2001,2002
00002 //# Associated Universities, Inc. Washington DC, USA.
00003 //#
00004 //# This library is free software; you can redistribute it and/or modify it
00005 //# under the terms of the GNU Library General Public License as published by
00006 //# the Free Software Foundation; either version 2 of the License, or (at your
00007 //# option) any later version.
00008 //#
00009 //# This library is distributed in the hope that it will be useful, but WITHOUT
00010 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00011 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00012 //# License for more details.
00013 //#
00014 //# You should have received a copy of the GNU Library General Public License
00015 //# along with this library; if not, write to the Free Software Foundation,
00016 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00017 //#
00018 //# Correspondence concerning AIPS++ should be addressed as follows:
00019 //#        Internet email: aips2-request@nrao.edu.
00020 //#        Postal address: AIPS++ Project Office
00021 //#                        National Radio Astronomy Observatory
00022 //#                        520 Edgemont Road
00023 //#                        Charlottesville, VA 22903-2475 USA
00024 //#
00025 //# $Id$
00026 
00027 #ifndef DISPLAY_MULTIPOLYLINETOOL_H
00028 #define DISPLAY_MULTIPOLYLINETOOL_H
00029 
00030 #include <casa/aips.h>
00031 #include <display/DisplayEvents/RegionTool.h>
00032 #include <display/DisplayEvents/DTVisible.h>
00033 #include <display/region/RegionSourceFactory.h>
00034 
00035 namespace casa { //# NAMESPACE CASA - BEGIN
00036 
00037 // <summary>
00038 // Base class for WorldCanvas event-based polyline tools
00039 // </summary>
00040 //
00041 // <use visibility=export>
00042 //
00043 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos="">
00044 // </reviewed>
00045 //
00046 // <prerequisites>
00047 //   <li><linkto>WCTool</linkto>
00048 // </prerequisites>
00049 //
00050 // <etymology>
00051 // MultiPolylineTool stands for Multi-WorldCanvas Polyline Tool
00052 // </etymology>
00053 //
00054 // <synopsis>
00055 // This class adds to its base MWCTool to provide a tool for drawing,
00056 // reshaping and moving polylines on a WorldCanvas.  While MultiPolylineTool
00057 // is not abstract, it performs no useful function.  The programmer
00058 // should derive from this class and override the functions doubleInside
00059 // and doubleOutside at the very least.  These are called when the user
00060 // double-clicks a particular key or mouse button inside or outside an
00061 // existing polyline respectively.  It is up to the programmer to decide
00062 // what these events mean, but it is recommended that an internal double-
00063 // click correspond to the main action of the tool, eg. emitting the 
00064 // polyline vertices to the application, and that an external double-click
00065 // correspond to a secondary action of the tool, if indeed there are
00066 // additional actions suitable to the tool.
00067 //
00068 // The polyline is drawn by clicking at each of the vertices, and
00069 // clicking again on the last or first vertex to complete the polyline.
00070 // Once drawn, the vertices can be moved by dragging their handles,
00071 // and the entire polyline relocated by dragging inside the polyline.
00072 // The polyline is removed from the display when the Esc key is
00073 // pressed.
00074 // </synopsis>
00075 //
00076 // <example>
00077 // </example>
00078 //
00079 
00080 
00081 
00082 class MultiPolylineTool : public RegionTool, public DTVisible, public viewer::RegionCreator {
00083 
00084 public:
00085 
00086         // Constructor
00087         MultiPolylineTool( viewer::RegionSourceFactory *rsf, PanelDisplay* pd,
00088                         Display::KeySym keysym = Display::K_Pointer_Button1, const Bool persistent = False );
00089 
00090         // Destructor
00091         virtual ~MultiPolylineTool();
00092 
00093         // Switch the tool off - this calls the base class disable,
00094         // and then erases the polyline if it's around
00095         virtual void disable();
00096 
00097         // reset to non-existent, non-active polyline.
00098         // Refreshes if necessary to erase (unless skipRefresh==True).
00099         // (Does not unregister from WCs or disable future event handling).
00100         virtual void reset(Bool skipRefresh=False);
00101 
00102         // Is a polyline currently defined?
00103         virtual Bool polylineDefined() { return itsMode>=Ready;  }
00104 
00105         viewer::RegionSource *getRegionSource( ) { return rfactory; }
00106 
00107         void checkPoint( WorldCanvas *wc, State &state );
00108 
00109         // called when the user (read GUI user) indicates that a region should be deleted...
00110         void revokeRegion( viewer::Region * );
00111 
00112         // returns a set which indicates regions this creator creates...
00113         const std::set<viewer::region::RegionTypes> &regionsCreated( ) const;
00114 
00115         bool create( viewer::region::RegionTypes /*region_type*/, WorldCanvas */*wc*/, const std::vector<std::pair<double,double> > &/*pts*/,
00116                         const std::string &/*label*/, viewer::region::TextPosition /*label_pos*/, const std::vector<int> &/*label_off*/,
00117                         const std::string &/*font*/, int /*font_size*/, int /*font_style*/, const std::string &/*font_color*/,
00118                         const std::string &/*line_color*/, viewer::region::LineStyle /*line_style*/, unsigned int /*line_width*/,
00119                         bool /*annotation*/, VOID */*region_specific_state*/ );
00120 
00121         RegionToolTypes type( ) const { return POLYLINETOOL; }
00122 
00123 protected:
00124 
00125         // Functions called by the base class event handling operators--and
00126         // normally only those.  This is the input that controls the polyline's
00127         // appearance and action.  When the polyline is ready and double-click
00128         // is received, the doubleInside/Outside routine is invoked.
00129         // <group>
00130         virtual void keyPressed(const WCPositionEvent &/*ev*/);
00131         virtual void moved(const WCMotionEvent &/*ev*/, const viewer::region::region_list_type & /*selected_regions*/);
00132         virtual void keyReleased(const WCPositionEvent &/*ev*/);
00133         virtual void otherKeyPressed(const WCPositionEvent &/*ev*/);
00134         // </group>
00135 
00136         // draw the polyline (if any) on the object's currently active WC.
00137         // Only to be called by the base class refresh event handler.  Derived
00138         // objects should use refresh() if they need to redraw, but even that
00139         // is normally handled automatically by this class.
00140         virtual void draw(const WCRefreshEvent&/*ev*/, const viewer::region::region_list_type & /*selected_regions*/);
00141 
00142         // Output callback functions--to be overridden in derived class as needed.
00143         // Called when there is a double click inside/outside the polyline
00144         // <group>
00145         virtual void doubleInside() { };
00146         virtual void doubleOutside() { };
00147         // </group>
00148 
00149         // Function called when a polyline is ready and not being
00150         // edited.  (Unused so far on the glish level (12/01)).
00151         virtual void polylineReady() { };
00152 
00153         // Retrieve polyline vertices, or a single vertex, in screen pixels.
00154         // Valid results during the callback functions; to be used by them,
00155         // as well as internally.
00156         // <group>
00157         virtual void get(Vector<Int> &x, Vector<Int> &y) const;
00158         virtual void get(Int &x, Int &y, const Int pt) const;
00159         // </group>
00160 
00161         virtual bool checkType( viewer::region::RegionTypes t ) { return t == viewer::region::PolylineRegion; }
00162 
00163 private:
00164         typedef std::list<std::tr1::shared_ptr<viewer::Polyline> > polylinelist;
00165         void start_new_polyline( WorldCanvas *, int x, int y );
00166 
00167         // Set the polyline vertices. itsNPoints should already be set, and
00168         // x and y must contain (at least) this many points.
00169         virtual void set(const Vector<Int> &x, const Vector<Int> &y);
00170 
00171         // replace a single vertex.
00172         virtual void set(const Int x, const Int y, const Int pt);
00173 
00174         std::tr1::shared_ptr<viewer::Polyline> resizing_region;
00175         std::tr1::shared_ptr<viewer::Polyline> creating_region;
00176 
00177         // push/pop last vertex
00178         // <group>
00179         void pushPoint(Int x1, Int y1);
00180         void popPoint();
00181         // </group>
00182 
00183         // are we inside the polyline?
00184         Bool inPolyline(const Int &x, const Int &y) const;
00185 
00186         // are we within the specified handle?
00187         Bool inHandle(const Int &pt, const Int &x, const Int &y) const;
00188 
00189 
00190         // should the polyline remain on screen after double clicks?
00191         Bool itsPolylinePersistent;
00192 
00193         // state of the polyline tool
00194         enum AdjustMode {
00195                 Off,    // Nothing exists yet
00196                 Def,    // defining initial polyline
00197                 Ready,  // polyline finished, no current activity
00198                 Move,   // moving entire polyline
00199                 Resize };       // moving single vertex whose handle was pressed
00200         MultiPolylineTool::AdjustMode itsMode;
00201 
00202         // set True on double-click, if the polyline is persistent.
00203         // set False when the polyline is moved, resized or reset.
00204         // If True, a click outside the polyline will erase it and begin
00205         // definition of a new one.
00206         Bool itsEmitted;
00207 
00208         // Number of points
00209         Int itsNPoints;
00210 
00211         // Polyline points (linear).  Not to be used directly.
00212         // use get, set, push, pop instead, which take pixel coordinate arguments.
00213         // It's done this way so that zooms work on the figures.
00214         Vector<Double> itsX, itsY;
00215         // pixel coordinates of the pan vector.  1 = anchor, 2 = new position.
00216         Int itsX1, itsY1, itsX2, itsY2, itsX3, itsY3;
00217 
00218 
00219         // size in pixels of the handles
00220         Int itsHandleSize;
00221 
00222         // vertex being moved
00223         Int itsSelectedHandle;
00224 
00225         // position that move started from
00226         Int itsBaseMoveX, itsBaseMoveY;
00227 
00228         // may not be needed...
00229         int resizing_region_handle;
00230 
00231         polylinelist moving_regions;
00232         double moving_linx_;
00233         double moving_liny_;
00234 
00235         std::tr1::shared_ptr<viewer::Polyline> building_polyline;
00236         viewer::RegionSource *rfactory;
00237         polylinelist polylines;
00238         PanelDisplay *pd_;
00239 };
00240 
00241 } //# NAMESPACE CASA - END
00242 
00243 #endif
00244 
00245