MultiPolyTool.h

Go to the documentation of this file.
00001 //# MultiPolyTool.h: Base class for MultiWorldCanvas event-based polygon tools
00002 //# Copyright (C) 1999,2000,2001,2002
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_MULTIPOLYTOOL_H
00029 #define DISPLAY_MULTIPOLYTOOL_H
00030 
00031 #include <casa/aips.h>
00032 #include <display/DisplayEvents/RegionTool.h>
00033 #include <display/DisplayEvents/DTVisible.h>
00034 #include <display/region/RegionSourceFactory.h>
00035 
00036 namespace casa { //# NAMESPACE CASA - BEGIN
00037 
00038 // <summary>
00039 // Base class for WorldCanvas event-based polygon tools
00040 // </summary>
00041 //
00042 // <use visibility=export>
00043 //
00044 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos="">
00045 // </reviewed>
00046 //
00047 // <prerequisites>
00048 //   <li><linkto>WCTool</linkto>
00049 // </prerequisites>
00050 //
00051 // <etymology>
00052 // MultiPolyTool stands for Multi-WorldCanvas Polygon Tool
00053 // </etymology>
00054 //
00055 // <synopsis>
00056 // This class adds to its base MWCTool to provide a tool for drawing,
00057 // reshaping and moving polygons on a WorldCanvas.  While MultiPolyTool
00058 // is not abstract, it performs no useful function.  The programmer
00059 // should derive from this class and override the functions doubleInside
00060 // and doubleOutside at the very least.  These are called when the user
00061 // double-clicks a particular key or mouse button inside or outside an
00062 // existing polygon respectively.  It is up to the programmer to decide
00063 // what these events mean, but it is recommended that an internal double-
00064 // click correspond to the main action of the tool, eg. emitting the
00065 // polygon vertices to the application, and that an external double-click
00066 // correspond to a secondary action of the tool, if indeed there are
00067 // additional actions suitable to the tool.
00068 //
00069 // The polygon is drawn by clicking at each of the vertices, and
00070 // clicking again on the last or first vertex to complete the polygon.
00071 // Once drawn, the vertices can be moved by dragging their handles,
00072 // and the entire polygon relocated by dragging inside the polygon.
00073 // The polygon is removed from the display when the Esc key is
00074 // pressed.
00075 // </synopsis>
00076 //
00077 // <example>
00078 // </example>
00079 //
00080 // <motivation>
00081 // Many activities on the WorldCanvas will be based on the user drawing
00082 // a polygon and using the polygon in some operation.
00083 // </motivation>
00084 //
00085 // <todo asof="1999/02/24">
00086 //   <li> Add time constraint to double click detection
00087 // </todo>
00088 
00089         class MultiPolyTool : public RegionTool, public DTVisible, public viewer::RegionCreator {
00090 
00091         public:
00092 
00093                 // Constructor
00094                 MultiPolyTool( viewer::RegionSourceFactory *rsf, PanelDisplay* pd,
00095                                Display::KeySym keysym = Display::K_Pointer_Button1, const Bool persistent = False );
00096 
00097                 // Destructor
00098                 virtual ~MultiPolyTool();
00099 
00100                 // Switch the tool off - this calls the base class disable,
00101                 // and then erases the polygon if it's around
00102                 virtual void disable();
00103 
00104                 // reset to non-existent, non-active polygon.
00105                 // Refreshes if necessary to erase (unless skipRefresh==True).
00106                 // (Does not unregister from WCs or disable future event handling).
00107                 virtual void reset(Bool skipRefresh=False);
00108 
00109                 // Is a polygon currently defined?
00110                 virtual Bool polygonDefined() {
00111                         return itsMode>=Ready;
00112                 }
00113 
00114                 viewer::RegionSource *getRegionSource( ) {
00115                         return rfactory;
00116                 }
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 {
00133                         return POLYTOOL;
00134                 }
00135 
00136         protected:
00137 
00138                 // Functions called by the base class event handling operators--and
00139                 // normally only those.  This is the input that controls the polygon's
00140                 // appearance and action.  When the polygon is ready and double-click
00141                 // is received, the doubleInside/Outside routine is invoked.
00142                 // <group>
00143                 virtual void keyPressed(const WCPositionEvent &/*ev*/);
00144                 virtual void moved(const WCMotionEvent &/*ev*/, const viewer::region::region_list_type & /*selected_regions*/);
00145                 virtual void keyReleased(const WCPositionEvent &/*ev*/);
00146                 virtual void otherKeyPressed(const WCPositionEvent &/*ev*/);
00147                 // </group>
00148 
00149                 // draw the polygon (if any) on the object's currently active WC.
00150                 // Only to be called by the base class refresh event handler.  Derived
00151                 // objects should use refresh() if they need to redraw, but even that
00152                 // is normally handled automatically by this class.
00153                 virtual void draw(const WCRefreshEvent&/*ev*/, const viewer::region::region_list_type & /*selected_regions*/);
00154 
00155                 // Output callback functions--to be overridden in derived class as needed.
00156                 // Called when there is a double click inside/outside the polygon
00157                 // <group>
00158                 virtual void doubleInside() { };
00159                 virtual void doubleOutside() { };
00160                 // </group>
00161 
00162                 // Function called when a polygon is ready and not being
00163                 // edited.  (Unused so far on the glish level (12/01)).
00164                 virtual void polygonReady() { };
00165 
00166                 // Retrieve polygon vertices, or a single vertex, in screen pixels.
00167                 // Valid results during the callback functions; to be used by them,
00168                 // as well as internally.
00169                 // <group>
00170                 virtual void get(Vector<Int> &x, Vector<Int> &y) const;
00171                 virtual void get(Int &x, Int &y, const Int pt) const;
00172                 // </group>
00173 
00174                 virtual bool checkType( viewer::region::RegionTypes t ) {
00175                         return t == viewer::region::PolyRegion;
00176                 }
00177 
00178         private:
00179                 typedef std::list<SHARED_PTR<viewer::Polygon> > polygonlist;
00180 
00181                 void start_new_polygon( WorldCanvas *, int x, int y );
00182 
00183                 // Set the polygon vertices. itsNPoints should already be set, and
00184                 // x and y must contain (at least) this many points.
00185                 virtual void set(const Vector<Int> &x, const Vector<Int> &y);
00186 
00187                 // replace a single vertex.
00188                 virtual void set(const Int x, const Int y, const Int pt);
00189 
00190                 SHARED_PTR<viewer::Polygon> resizing_region;
00191                 SHARED_PTR<viewer::Polygon> creating_region;
00192 
00193                 // push/pop last vertex
00194                 // <group>
00195                 void pushPoint(Int x1, Int y1);
00196                 void popPoint();
00197                 // </group>
00198 
00199                 // are we inside the polygon?
00200                 Bool inPolygon(const Int &x, const Int &y) const;
00201 
00202                 // are we within the specified handle?
00203                 Bool inHandle(const Int &pt, const Int &x, const Int &y) const;
00204 
00205 
00206                 // should the polygon remain on screen after double clicks?
00207                 Bool itsPolygonPersistent;
00208 
00209                 // state of the polyline tool
00210                 enum AdjustMode {
00211                     Off,        // Nothing exists yet
00212                     Def,        // defining initial polygon
00213                     Ready,      // polygon finished, no current activity
00214                     Move,       // moving entire polygon
00215                     Resize
00216                 };      // moving single vertex whose handle was pressed
00217                 MultiPolyTool::AdjustMode itsMode;
00218 
00219                 // set True on double-click, if the polygon is persistent.
00220                 // set False when the polygon is moved, resized or reset.
00221                 // If True, a click outside the polygon will erase it and begin
00222                 // definition of a new one.
00223                 Bool itsEmitted;
00224 
00225                 // Number of points
00226                 Int itsNPoints;
00227 
00228                 // Polygon points (linear).  Not to be used directly.
00229                 // use get, set, push, pop instead, which take pixel coordinate arguments.
00230                 // It's done this way so that zooms work on the figures.
00231                 Vector<Double> itsX, itsY;
00232 
00233                 // size in pixels of the handles
00234                 Int itsHandleSize;
00235 
00236                 // vertex being moved
00237                 Int itsSelectedHandle;
00238 
00239                 // position that move started from
00240                 Int itsBaseMoveX, itsBaseMoveY;
00241 
00242                 // may not be needed...
00243                 int resizing_region_handle;
00244 
00245                 polygonlist moving_regions;
00246                 double moving_linx_;
00247                 double moving_liny_;
00248 
00249                 SHARED_PTR<viewer::Polygon> building_polygon;
00250                 viewer::RegionSource *rfactory;
00251                 polygonlist polygons;
00252                 PanelDisplay *pd_;
00253         };
00254 
00255 } //# NAMESPACE CASA - END
00256 
00257 #endif
00258 
00259 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 31 Aug 2016 for casa by  doxygen 1.6.1