casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
PlotTool.h
Go to the documentation of this file.
00001 //# PlotTool.h: Tool class definitions (higher-level event handlers).
00002 //# Copyright (C) 2008
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 #ifndef PLOTTOOL_H_
00028 #define PLOTTOOL_H_
00029 
00030 #include <graphics/GenericPlotter/PlotEventHandler.h>
00031 #include <graphics/GenericPlotter/PlotOptions.h>
00032 #include <graphics/GenericPlotter/PlotShape.h>
00033 #include <graphics/GenericPlotter/PlotAnnotation.h>
00034 
00035 #include <casa/namespace.h>
00036 
00037 namespace casa {
00038 
00039 //# Forward Declarations
00040 class PlotCanvas;
00041 class PlotFactory;
00042 class PlotPanToolNotifier;
00043 class PlotSelectToolNotifier;
00044 class PlotTrackerToolNotifier;
00045 class PlotZoomToolNotifier;
00046 
00047 
00048 
00050 // ABSTRACT TOOL CLASSES //
00052 
00053 
00054 // A PlotTool is a higher-level event handler for a PlotCanvas.  The idea is to
00055 // take common tasks which may require multiple events and put them in one
00056 // place.  PlotTools also provide additional functionality in that they can be
00057 // 1) active/inactive, and 2) blocking/non-blocking.  The PlotCanvas will only
00058 // send events to active tools, and will not send events to later tools or
00059 // event handlers if the latest tool was blocking.  In this way a single tool
00060 // can be used to handle ALL user interaction via the GUI at one time, if
00061 // desired.  The PlotTool class itself is abstract and deliberately non-binding
00062 // as it is mainly meant for specialization in its children classes.  PlotTools
00063 // can also specify which coordinate system and two axes they work on, and the
00064 // PlotCanvas is expected to obey these constraints.
00065 class PlotTool {
00066     friend class PlotCanvas;
00067     friend class PlotMouseToolGroup;
00068     
00069 public:
00070     // Constructor which takes which coordinate system events should be
00071     // processed in.
00072     PlotTool(PlotCoordinate::System sys = PlotCoordinate::WORLD);
00073     
00074     // Constructor which takes the two axes and the coordinate system which
00075     // events should be processed in.
00076     PlotTool(PlotAxis xAxis, PlotAxis yAxis,
00077             PlotCoordinate::System sys = PlotCoordinate::WORLD);
00078     
00079     // Destructor.
00080     virtual ~PlotTool();
00081     
00082     
00083     // Returns whether this tool is currently active or not.
00084     virtual bool isActive() const;
00085     
00086     // Sets whether this tool is currently active or not.
00087     virtual void setActive(bool isActive = true);
00088     
00089     // Returns whether this tool is blocking or not.  When a PlotCanvas
00090     // encounters a blocking tool, it is expected to not send events to any
00091     // other handlers further in the chain.
00092     virtual bool isBlocking() const;
00093     
00094     // Sets whether this tool is blocking or not.
00095     virtual void setBlocking(bool blocking = true);
00096     
00097     // Gets the axes on which the tool operates.
00098     // <group>
00099     virtual PlotAxis getXAxis() const;
00100     virtual PlotAxis getYAxis() const;
00101     // </group>
00102     
00103     // Gets the coordinate system in which the tool wants to process events.
00104     // Events passed to this tool should use this coordinate system.
00105     virtual PlotCoordinate::System getCoordinateSystem() const;
00106     
00107     // Returns whether the last event was handled or not.  Mostly used for
00108     // blocking tools so that unused events can be passed along.
00109     virtual bool lastEventWasHandled() const;
00110     
00111     // Resets any internal state such as history/stacks.  Should be called by
00112     // the PlotCanvas when the state of the canvases changes (axes ranges,
00113     // adding/deleting items, etc.) and would thus invalidate tool states.
00114     virtual void reset() { }
00115     
00116 protected:
00117     // Attached canvas (or NULL for none).
00118     PlotCanvas* m_canvas;
00119     
00120     // Factory for creating implementation-specific objects.
00121     PlotFactory* m_factory;
00122     
00123     // Whether this tool is active.
00124     bool m_active;
00125     
00126     // Whether this tool is blocking.
00127     bool m_blocking;
00128     
00129     // The tool axes.
00130     PlotAxis m_xAxis, m_yAxis;
00131     
00132     // The tool coordinate system.
00133     PlotCoordinate::System m_coordSystem;
00134     
00135     // Last event handled flag.
00136     bool m_lastEventHandled;
00137     
00138     
00139     // Returns the canvas this tool is attached to, or NULL for none.
00140     virtual PlotCanvas* canvas() const;
00141     
00142     // Returns a factory that can be used for generating
00143     // implementation-specific classes, or NULL for none.
00144     virtual PlotFactory* factory() const;
00145     
00146     // Returns true if this tool is attached to a canvas, false otherwise.
00147     virtual bool isAttached() const;
00148     
00149     // Attaches this tool to the given canvas.  Detaches from current canvas
00150     // if necessary.
00151     virtual void attach(PlotCanvas* canvas);
00152     
00153     // Detaches this tool from its canvas.
00154     virtual void detach();
00155 };
00156 
00157 typedef CountedPtr<PlotTool> PlotToolPtr;
00158 
00159 
00160 
00161 
00162 // A PlotMouseTool is a specialization of PlotTool that handles all mouse
00163 // events.  It is abstract, and combines all mouse event handling methods into
00164 // one for convenience.
00165 class PlotMouseTool : public virtual PlotTool,
00166                       public virtual PlotSelectEventHandler,
00167                       public virtual PlotClickEventHandler, 
00168                       public virtual PlotMousePressEventHandler,
00169                       public virtual PlotMouseReleaseEventHandler,
00170                       public virtual PlotMouseDragEventHandler,
00171                       public virtual PlotMouseMoveEventHandler,
00172                       public virtual PlotWheelEventHandler {
00173 public:
00174     // Constructor which takes the tool's coordinate system.
00175     PlotMouseTool(PlotCoordinate::System coordSys = PlotCoordinate::WORLD) :
00176             PlotTool(coordSys) { }
00177     
00178     // Constructor which takes the tool's axes and coordinate system.
00179     PlotMouseTool(PlotAxis xAxis, PlotAxis yAxis,
00180             PlotCoordinate::System coordSys = PlotCoordinate::WORLD) :
00181             PlotTool(xAxis, yAxis, coordSys) { }
00182     
00183     // Destructor.
00184     virtual ~PlotMouseTool() { }
00185 
00186 
00187     // Event handling methods.
00188     // <group>
00189     virtual void handleSelect(const PlotSelectEvent& event) {
00190         handleMouseEvent(event); }
00191     virtual void handleClick(const PlotClickEvent& event) {
00192         handleMouseEvent(event); }
00193     virtual void handleMousePress(const PlotMousePressEvent& event) {
00194         handleMouseEvent(event); }
00195     virtual void handleMouseRelease(const PlotMouseReleaseEvent& event) {
00196         handleMouseEvent(event); }
00197     virtual void handleMouseDrag(const PlotMouseDragEvent& event) {
00198         handleMouseEvent(event); }
00199     virtual void handleMouseMove(const PlotMouseMoveEvent& event) {
00200         handleMouseEvent(event); }
00201     virtual void handleWheel(const PlotWheelEvent& event) {
00202         handleMouseEvent(event); }
00203     // </group>
00204     
00205     
00206     // ABSTRACT METHODS //
00207     
00208     // Handles the given mouse event.  Guaranteed to be one of the mouse
00209     // events (select, click, press, release, drag, move, wheel).  The
00210     // implementing class should also update the last event handled flag as
00211     // necessary.
00212     virtual void handleMouseEvent(const PlotEvent& event) = 0;
00213 };
00214 INHERITANCE_POINTER2(PlotMouseTool, PlotMouseToolPtr, PlotTool, PlotToolPtr)
00215 
00216 
00217 
00218 
00219 
00220 
00221 
00222 // CONCRETE TOOL CLASSES //
00224 
00225 
00226 
00227 
00228 // Was in PlotStandardMouseToolGroup, but needed here, so it can be  passed
00229 // to setActiveTool, which needs it to adjust the Select tool to either work
00230 // normal or as Subtraction tool.
00231 
00232 // Enum for standard tools in group.
00233 enum ToolCode {
00234     SELECT_TOOL,   
00235     SUBTRACT_TOOL,   
00236     ZOOM_TOOL, 
00237     PAN_TOOL, 
00238     NONE_TOOL
00239 };
00240     
00241 
00242 
00243 
00244 
00245 // A PlotSelectTool is a concrete subclass of PlotMouseTool that mainly handles
00246 // select events.  Note that plotting implementations may wish to override
00247 // this class with an implementation-specific version that may be more
00248 // efficient.  PlotSelectTool is responsible for:
00249 // 1) managing the select line (the line show while the user is click-dragging
00250 //    to select a region on the canvas) and cursors,
00251 // 2) keeping track of selected regions,
00252 // 3) showing/hiding the regions on the canvas, and
00253 // 4) notifying any interested classes whenever the selected regions changes.
00254 class PlotSelectTool : public virtual PlotMouseTool {
00255 public:
00256     // Constructor which takes the tool's coordinate system.
00257     PlotSelectTool(PlotCoordinate::System system = PlotCoordinate::WORLD);
00258     
00259     // Constructor which takes the tool's axes and coordinate system.
00260     PlotSelectTool(PlotAxis xAxis, PlotAxis yAxis,
00261                    PlotCoordinate::System system = PlotCoordinate::WORLD);
00262     
00263     // Destructor.
00264     virtual ~PlotSelectTool();
00265     
00266     // Adds the given notifier.  This object will be notified when the list
00267     // of selected regions changes (either by adding one from the mouse, or
00268     // clearing them).
00269     virtual void addNotifier(PlotSelectToolNotifier* notifier);
00270     
00271     // Sets the selection line to the given.
00272     // <group>
00273     virtual void setSelectLine(PlotLinePtr line);
00274     virtual void setSubtractLine(PlotLinePtr line);
00275     virtual void setSelectLine(bool on = true);
00276     // </group>
00277     
00278     // Sets the attributes for drawing selected regions.
00279     // <group>
00280     virtual void setDrawRects(bool on = true);
00281     virtual void setRectLine(PlotLinePtr line);
00282     virtual void setRectFill(PlotAreaFillPtr fill);
00283     // </group>
00284     
00285     // Selected regions.
00286     // <group>
00287     virtual unsigned int numSelectedRects() const;
00288     virtual void getSelectedRects( 
00289                 vector<double>& upperLeftXs,
00290                 vector<double>& upperLeftYs, 
00291                 vector<double>& lowerRightXs,
00292                 vector<double>& lowerRightYs,
00293                 PlotCoordinate::System system = PlotCoordinate::WORLD)  const;
00294     virtual vector<PlotRegion> getSelectedRects(
00295                 PlotCoordinate::System system = PlotCoordinate::WORLD)  const;
00296     virtual void clearSelectedRects();
00297     // </group>
00298     
00299     // Overrides PlotTool::setActive().
00300     virtual void setActive(bool active = true);
00301     
00302     // Implements PlotMouseTool::handleMouseEvent().
00303     virtual void handleMouseEvent(const PlotEvent& event);
00304     
00305     bool inSubtractionMode()      { return m_subtraction_mode; }
00306 
00307 
00308 
00309     bool m_subtraction_mode;
00310 
00311 
00312 protected:
00313     // Notifiers.
00314     vector<PlotSelectToolNotifier*> m_notifiers;
00315     
00316     // Copy of selection line to set on the canvas, or NULL if none has been
00317     // set.
00318     PlotLinePtr m_selLine;
00319     PlotLinePtr m_subLine;
00320     
00321     // Whether or not to draw selected regions on the canvas.
00322     bool m_drawRects;
00323     
00324     // Line for drawing selected regions, or NULL if none has been set.
00325     PlotLinePtr m_rectLine;
00326     
00327     // Area fill for drawing selected regions, or NULL if none has been set.
00328     PlotAreaFillPtr m_rectFill;
00329     
00330     // Selected regions.
00331     vector<PlotShapeRectanglePtr> m_rects;
00332     
00333 
00334     
00335     // Overrides PlotTool::attach().
00336     virtual void attach(PlotCanvas* canvas);
00337     
00338     // Overrides PlotTool::detach().
00339     virtual void detach();
00340 };
00341 
00342 
00343 INHERITANCE_POINTER(PlotSelectTool, PlotSelectToolPtr, PlotMouseTool,
00344                     PlotMouseToolPtr, PlotTool, PlotToolPtr)
00345 
00346 
00347 
00348 
00349 
00350 
00351 
00352 
00353 
00354 // A PlotZoomTool is a concrete subclass of PlotMouseTool that provides
00355 // convenient zooming functionality.  Standard behavior is to zoom on a
00356 // select event, go through the zoom stack on a wheel event, go to the zoom
00357 // stack base on a right click, and zoom in 50% centered on a double-click.
00358 // Note that plotting implementations may wish to override this class with an
00359 // implementation-specific version that may be more efficient.  A PlotZoomTool
00360 // is responsible for:
00361 // 1) managing behavior described above,
00362 // 2) managing a zoom stack,
00363 // 3) managing the canvas's select line/cursor, and
00364 // 3) notifying interested objects when the zoom changes.
00365 class PlotZoomTool : public virtual PlotMouseTool {
00366 public:
00367     // Constructor which takes the tool's coordinate system.
00368     PlotZoomTool(PlotCoordinate::System sys = PlotCoordinate::WORLD);
00369     
00370     // Constructor which takes the tool's axes and coordinate system.
00371     PlotZoomTool(PlotAxis xAxis, PlotAxis yAxis,
00372                  PlotCoordinate::System sys = PlotCoordinate::WORLD);
00373     
00374     // Destructor.
00375     virtual ~PlotZoomTool();
00376     
00377     // Adds the given notifier.  This object will be notified when the zoom
00378     // changes.
00379     virtual void addNotifier(PlotZoomToolNotifier* notifier);
00380     
00381     // Sets the selection line to the given.
00382     // <group>
00383     virtual void setSelectLine(PlotLinePtr line);
00384     virtual void setSelectLine(bool on = true);
00385     // </group>
00386     
00387     // Gets the zoom stack.
00388     virtual vector<PlotRegion> getZoomStack(PlotCoordinate::System sytem =
00389                                             PlotCoordinate::WORLD) const;
00390     
00391     // Gets the zoom stack index.
00392     virtual unsigned int getStackIndex() const;
00393     
00394     // Overrides PlotTool::setActive().
00395     virtual void setActive(bool active = true);
00396     
00397     // Implements PlotMouseTool::handleMouseEvent().
00398     virtual void handleMouseEvent(const PlotEvent& event);
00399     
00400     // Overrides PlotTool::reset().
00401     virtual void reset();
00402     
00403 protected:
00404     // Notifiers.
00405     vector<PlotZoomToolNotifier*> m_notifiers;
00406     
00407     // Copy of canvas selection line, or NULL if none has been set.
00408     PlotLinePtr m_selLine;
00409     
00410     // Common canvas stack.
00411     PlotAxesStack* m_stack;
00412     
00413     
00414     // Overrides PlotTool::attach().
00415     virtual void attach(PlotCanvas* canvas);
00416     
00417     // Overrides PlotTool::detach().
00418     virtual void detach();
00419     
00420     // Notifies all registered listeners that the zoom has changed.
00421     virtual void notifyWatchers();
00422 };
00423 INHERITANCE_POINTER(PlotZoomTool, PlotZoomToolPtr, PlotMouseTool,
00424                     PlotMouseToolPtr, PlotTool, PlotToolPtr)
00425 
00426 
00427 
00428 
00429 // A PlotPanTool is a concrete subclass of PlotMouseTool that provides
00430 // convenient panning functionality.  Standard behavior is to pan the canvas
00431 // on a drag event, go through the pan stack on a wheel event, and go to the
00432 // pan stack base on a right click.  Note that plotting implementations may
00433 // wish to override this class with an implementation-specific version that may
00434 // be more efficient.  A PlotPanTool is responsible for:
00435 // 1) managing behavior described above,
00436 // 2) managing a pan stack,
00437 // 3) managing the canvas's cursor, and
00438 // 4) notifying interested objects when the pan changes.
00439 class PlotPanTool : public virtual PlotMouseTool {
00440 public:
00441     // Constructor which takes the tool's coordinate system.
00442     PlotPanTool(PlotCoordinate::System sys = PlotCoordinate::WORLD);
00443     
00444     // Constructor which takes the tool's axes and coordinate system.
00445     PlotPanTool(PlotAxis xAxis, PlotAxis yAxis,
00446                 PlotCoordinate::System sys = PlotCoordinate::WORLD);
00447     
00448     // Destructor.
00449     virtual ~PlotPanTool();
00450     
00451     // Adds the given notifier.  This object will be notified when the pan
00452     // changes.
00453     virtual void addNotifier(PlotPanToolNotifier* notifier);
00454     
00455     // Gets the pan stack.
00456     virtual vector<PlotRegion> getPanStack(PlotCoordinate::System system =
00457                                            PlotCoordinate::WORLD) const;
00458     
00459     // Gets the pan stack index.
00460     virtual unsigned int getStackIndex() const;
00461     
00462     // Overrides PlotTool::setActive().
00463     virtual void setActive(bool active = true);
00464     
00465     // Implements PlotMouseTool::handleMouseEvent().
00466     virtual void handleMouseEvent(const PlotEvent& event);
00467     
00468     // Overrides PlotTool::reset().
00469     virtual void reset();
00470     
00471 protected:
00472     // Notifiers.
00473     vector<PlotPanToolNotifier*> m_notifiers;
00474     
00475     // Whether we're in dragging mode or not.
00476     bool m_inDraggingMode;
00477     
00478     // Last coordinate in dragging mode.
00479     PlotCoordinate m_lastCoord;
00480     
00481     // Common canvas stack.
00482     PlotAxesStack* m_stack;
00483     
00484     
00485     // Overrides PlotTool::attach().
00486     virtual void attach(PlotCanvas* canvas);
00487     
00488     // Overrides PlotTool::detach().
00489     virtual void detach();
00490     
00491     // Notifies all registered listeners that the pan has changed.
00492     virtual void notifyWatchers();
00493 };
00494 INHERITANCE_POINTER(PlotPanTool, PlotPanToolPtr, PlotMouseTool,
00495                     PlotMouseToolPtr, PlotTool, PlotToolPtr)
00496 
00497 
00498 
00499 
00500 // A PlotTrackerTool is a concrete subclass of PlotMouseTool that provides
00501 // convenient tracker functionality.  Note that plotting implementations may
00502 // wish to override this class with an implementation-specific version that may
00503 // be more efficient.  A PlotTrackerTool can:
00504 // 1) show a label with the current position hovering over the mouse,
00505 // 2) let an external class handle the tracking via notifications, or
00506 // 3) both.
00507 class PlotTrackerTool : public virtual PlotMouseTool {
00508     friend class PlotStandardMouseToolGroup; // Why is this necessary to access
00509                                              // attach() and detach()? >:(
00510     
00511 public:
00512     // Static //
00513     
00514     // Returns a String for the given position in the given format, with the
00515     // given canvas and axes.
00516     static String formattedString(const String& format, double x, double y,
00517                        PlotCanvas* canvas, PlotAxis xAxis, PlotAxis yAxis);
00518     
00519     
00520     // Non-Static //
00521     
00522     // Constructor which takes the tool's coordinate system.
00523     PlotTrackerTool(PlotCoordinate::System sys = PlotCoordinate::WORLD);
00524         
00525     // Constructor which takes the tool's axes and coordinate system.
00526     PlotTrackerTool(PlotAxis xAxis, PlotAxis yAxis,
00527                     PlotCoordinate::System sys = PlotCoordinate::WORLD);
00528     
00529     // Destructor.
00530     virtual ~PlotTrackerTool();
00531     
00532     // Adds the given notifier.  This object will be notified when the tracker
00533     // changes (and a new coordinate is ready for display).
00534     virtual void addNotifier(PlotTrackerToolNotifier* notifier);
00535     
00536     // Returns true if the tracker text is drawn on the canvas, false otherwise.
00537     virtual bool drawsText() const;
00538     
00539     // Sets whether the tracker will draw the text on the canvas or not.
00540     virtual void setDrawText(bool draw = true);
00541     
00542     // Sets the tracker text format to the given.  The following tags can be
00543     // used in the format:
00544     // * %%x%% : x value
00545     // * %%y%% : y values
00546     // * %%pX%% : sets the precision to X for any following numbers.
00547     // NOTICE: if the x or y value is a date, the date format set on the
00548     // canvas this tool is attached to will be used to display the value.
00549     // Default format is "(%%x%%, %%y%%)".
00550     virtual void setFormat(const String& format);
00551     
00552     // Returns the formatted tracker text for the given position.
00553     virtual String formattedString(double x, double y) {
00554         return formattedString(m_format, x, y, m_canvas, m_xAxis, m_yAxis); }
00555     
00556     // Returns the annotation used to store the coordinates/text.
00557     virtual PlotAnnotationPtr getAnnotation();
00558     
00559     // Gets the tracker's current position.
00560     virtual PlotCoordinate getCoordinate(PlotCoordinate::System =
00561                                          PlotCoordinate::WORLD) const;
00562     
00563     // Overrides PlotTool::setActive().
00564     virtual void setActive(bool active = true);
00565     
00566     // Implements PlotMouseTool::handleMouseEvent().
00567     virtual void handleMouseEvent(const PlotEvent& event);
00568     
00569 protected:
00570     // Notifiers.
00571     vector<PlotTrackerToolNotifier*> m_notifiers;
00572     
00573     // Annotation that holds current position (even if not drawn on canvas).
00574     PlotAnnotationPtr m_annotation;
00575     
00576     // Whether to draw the annotation or not.
00577     bool m_drawText;
00578     
00579     // Tracker text format.
00580     String m_format;
00581     
00582     // Overrides PlotTool::attach().
00583     virtual void attach(PlotCanvas* canvas);
00584     
00585     // Overrides PlotTool::detach().
00586     virtual void detach();
00587     
00588     // Notifies all registered listeners that the tracker has changed.
00589     virtual void notifyWatchers();
00590     
00591     
00592     // Static //
00593     
00594     // Format constants.
00595     // <group>
00596     static const String FORMAT_DIVIDER;
00597     static const String FORMAT_X, FORMAT_Y;
00598     static const String FORMAT_PRECISION;
00599     static const String DEFAULT_FORMAT;
00600     // </group>
00601 };
00602 INHERITANCE_POINTER(PlotTrackerTool, PlotTrackerToolPtr, PlotMouseTool,
00603                     PlotMouseToolPtr, PlotTool, PlotToolPtr)
00604 
00605 
00606 
00607 // TOOL NOTIFICATION CLASSES //
00609 
00610 
00611 // Interface for objects that want to be notified when the selection tool
00612 // changes.
00613 class PlotSelectToolNotifier {
00614     friend class PlotSelectTool;
00615     
00616 public:
00617     PlotSelectToolNotifier() { }
00618     virtual ~PlotSelectToolNotifier() { }
00619     
00620 protected:
00621     // This method is called AFTER the selection has been added.
00622     virtual void notifySelectionAdded(PlotSelectTool& tool) = 0;
00623 };
00624 
00625 
00626 // Interface for objects that want to be notified when the zoom tool
00627 // changes.
00628 class PlotZoomToolNotifier {
00629     friend class PlotZoomTool;
00630     
00631 public:
00632     PlotZoomToolNotifier() { }
00633     virtual ~PlotZoomToolNotifier() { }
00634     
00635 protected:
00636     // This method is called AFTER the canvas has been zoomed.
00637     virtual void notifyZoomChanged(PlotZoomTool& tool) = 0;
00638 };
00639 
00640 
00641 // Interface for objects that want to be notified when the pan tool
00642 // changes.
00643 class PlotPanToolNotifier {
00644     friend class PlotPanTool;
00645     
00646 public:
00647     PlotPanToolNotifier() { }
00648     virtual ~PlotPanToolNotifier() { }
00649     
00650 protected:
00651     // This method is called AFTER the canvas has been panned.
00652     virtual void notifyPanChanged(PlotPanTool& tool) = 0;
00653 };
00654 
00655 
00656 // Interface for objects that want to be notified when the tracker tool
00657 // changes.
00658 class PlotTrackerToolNotifier {
00659     friend class PlotTrackerTool;
00660     
00661 public:
00662     PlotTrackerToolNotifier() { }
00663     virtual ~PlotTrackerToolNotifier() { }
00664     
00665 protected:
00666     // This method is called AFTER the tracker has been updated.
00667     virtual void notifyTrackerChanged(PlotTrackerTool& tool) = 0;
00668 };
00669 
00670 
00672 // TOOL GROUP CLASSES //
00674 
00675 
00676 // A PlotMouseToolGroup provides an interface for a group of PlotMouseTools
00677 // where only one (or none) is active at a time.
00678 class PlotMouseToolGroup : public virtual PlotMouseTool {
00679 public:
00680     // Constructor for empty group.
00681     PlotMouseToolGroup();
00682     
00683     // Destructor.
00684     virtual ~PlotMouseToolGroup();    
00685        
00686     // Returns the number of tools in the group.
00687     unsigned int numTools() const;    
00688     
00689     // Returns the tools in the group.
00690     vector<PlotMouseToolPtr> tools() const;
00691     
00692     // Adds the given tool to the group and returns its index.  If makeActive
00693     // is true, the given tool becomes the group's active tool.
00694     // Note (dec 2010): used to take 2nd arg, boolean, to make tool active.
00695     // This is confusing design.  Caller of addTool should just call  setActiveTool(tool)
00696     // after calling addTool() if it wants the tool to become active.
00697     // In practice, source code does not anywhere call addTool with make_active=true.
00698     unsigned int addTool(PlotMouseToolPtr tool);
00699     
00700     // Removes the given tool from the group, and returns true on success.
00701     // <group>
00702     bool removeTool(PlotMouseToolPtr tool);    
00703     bool removeTool(unsigned int index) { return removeTool(toolAt(index)); }
00704     // </group>
00705     
00706     // Returns the tool at the given index, or NULL for invalid.
00707     PlotMouseToolPtr toolAt(unsigned int index) const;
00708     
00709     // Returns the index of the given tool, or numTools() for invalid.
00710     unsigned int indexOf(PlotMouseToolPtr tool) const;
00711     
00712     // Returns true if the given tool is in this group, false otherwise.
00713     bool containsTool(PlotMouseToolPtr tool) const {
00714         return indexOf(tool) < m_tools.size(); }
00715     
00716     // Returns the currently active tool, or NULL for none.
00717     PlotMouseToolPtr activeTool() const { return m_activeTool; }
00718     
00719     // Sets the active tool to the given.  If the given tool is not in the
00720     // group it is first added.
00721     // Toolcode is optional - meaningful only if tool has double usage, like
00722     // Select tool which doubles as the Subtraction tool.  Otherwise, just stuff NONE_TOOL
00723     // in for that arg.
00724     void setActiveTool(PlotMouseToolPtr tool,  ToolCode toolcode=NONE_TOOL);
00725     
00726     // Sets the active tool to the one at the given index.
00727     void setActiveTool(unsigned int index, ToolCode c=NONE_TOOL)   { 
00728             setActiveTool(toolAt(index), c); 
00729             }
00730     
00731     // Overrides PlotTool::setActive().
00732     void setActive(bool isActive = true);
00733     
00734     // Overrides PlotTool::setBlocking().
00735     void setBlocking(bool blocking = true);    
00736     
00737     // Implements PlotMouseTool::handleMouseEvent().
00738     void handleMouseEvent(const PlotEvent& event);
00739     
00740     // Overrides PlotMouseTool's event handling methods.
00741     // <group>
00742     void handleSelect(const PlotSelectEvent& event);
00743     void handleClick(const PlotClickEvent& event);
00744     void handleMousePress(const PlotMousePressEvent& event);
00745     void handleMouseRelease(const PlotMouseReleaseEvent& event);
00746     void handleMouseDrag(const PlotMouseDragEvent& event);
00747     void handleMouseMove(const PlotMouseMoveEvent& event);
00748     void handleWheel(const PlotWheelEvent& event);
00749     // </group>
00750     
00751     // Overrides PlotTool::getXAxis().
00752     PlotAxis getXAxis() const;
00753     
00754     // Overrides PlotTool::getYAxis().
00755     PlotAxis getYAxis() const;
00756     
00757     // Overrides PlotTool::getCoordinateSystem().
00758     PlotCoordinate::System getCoordinateSystem() const;
00759     
00760     // Overrides PlotTool::lastEventWasHandled().
00761     bool lastEventWasHandled() const;
00762     
00763     // Overrides PlotTool::reset().
00764     void reset();
00765     
00766 protected:
00767     // All tools.
00768     vector<PlotMouseToolPtr> m_tools;
00769     
00770     // Active tool (or NULL for no active tool).
00771     PlotMouseToolPtr m_activeTool;
00772     
00773     // Overrides PlotTool::attach().
00774     virtual void attach(PlotCanvas* canvas);
00775     
00776     // Overrides PlotTool::detach().
00777     virtual void detach();
00778 };
00779 INHERITANCE_POINTER(PlotMouseToolGroup, PlotMouseToolGroupPtr, PlotMouseTool,
00780                     PlotMouseToolPtr, PlotTool, PlotToolPtr)
00781 
00782 
00783 // PlotStandardMouseToolGroup is a specialized PlotMouseToolGroup where the
00784 // tools in the group are:
00785 // 1) select,
00786 // 2) zoom, and
00787 // 3) pan.
00788 // A tracker is also provided that is not in the group so that it can be active
00789 // at the same time other tools are active.
00790 class PlotStandardMouseToolGroup : public PlotMouseToolGroup {
00791 public:
00792     // Static //
00793     
00794     // Non-Static //
00795     
00796     // Constructor which creates default tools with the given coordinate
00797     // system, and sets the active tool to the given.
00798     PlotStandardMouseToolGroup(ToolCode activeTool = NONE_TOOL,
00799             PlotCoordinate::System system = PlotCoordinate::WORLD);
00800     
00801     // Constructor which creates default tools with the given coordinate
00802     // system and axes, and sets the active tool to the given.
00803     PlotStandardMouseToolGroup(PlotAxis xAxis, PlotAxis yAxis,
00804             ToolCode activeTool = NONE_TOOL,
00805             PlotCoordinate::System system = PlotCoordinate::WORLD);
00806     
00807     // Constructor which uses the given tools (or creates default tools if the
00808     // given ones are invalid), and sets the active tool to the given.
00809     PlotStandardMouseToolGroup(PlotSelectToolPtr selectTool,
00810                                PlotZoomToolPtr zoomTool,
00811                                PlotPanToolPtr panTool,
00812                                PlotTrackerToolPtr trackerTool,
00813                                ToolCode activeTool = NONE_TOOL);
00814     
00815     // Destructor.
00816     ~PlotStandardMouseToolGroup();
00817     
00818     // Gets/sets the active standard tool.
00819     // <group>
00820     void setActiveTool(ToolCode tool);
00821     ToolCode activeToolType() const;
00822     // </group>
00823     
00824     // Provides access to the tracker.
00825     // <group>
00826     void turnTracker(bool on);
00827     bool trackerIsOn() const;
00828     void turnTrackerDrawText(bool on);
00829     bool trackerDrawsText() const;
00830     // </group>
00831     
00832     // Provides access to the individual tools.  Note: this should be avoided
00833     // if possible.
00834     // <group>
00835     PlotSelectToolPtr selectTool();
00836     PlotZoomToolPtr zoomTool();
00837     PlotPanToolPtr panTool();
00838     PlotTrackerToolPtr trackerTool();
00839     // </group>
00840     
00841     // Overrides PlotMouseToolGroup handler methods to give events to the
00842     // tracker first.
00843     // <group>
00844     void handleMouseEvent(const PlotEvent& event) {
00845         if(m_tracker->isActive()) m_tracker->handleMouseEvent(event);
00846         PlotMouseToolGroup::handleMouseEvent(event); }
00847         
00848     void handleSelect(const PlotSelectEvent& event) {
00849         if(m_tracker->isActive()) m_tracker->handleSelect(event);
00850         PlotMouseToolGroup::handleSelect(event); }
00851         
00852     void handleClick(const PlotClickEvent& event) {
00853         if(m_tracker->isActive()) m_tracker->handleClick(event);
00854         PlotMouseToolGroup::handleClick(event); }
00855         
00856     void handleMousePress(const PlotMousePressEvent& event) {
00857         if(m_tracker->isActive()) m_tracker->handleMousePress(event);
00858         PlotMouseToolGroup::handleMousePress(event); }
00859         
00860     void handleMouseRelease(const PlotMouseReleaseEvent& event) {
00861         if(m_tracker->isActive()) m_tracker->handleMouseRelease(event);
00862         PlotMouseToolGroup::handleMouseRelease(event); }
00863         
00864     void handleMouseDrag(const PlotMouseDragEvent& event) {
00865         if(m_tracker->isActive()) m_tracker->handleMouseDrag(event);
00866         PlotMouseToolGroup::handleMouseDrag(event); }
00867         
00868     void handleMouseMove(const PlotMouseMoveEvent& event) {
00869         if(m_tracker->isActive()) m_tracker->handleMouseMove(event);
00870         PlotMouseToolGroup::handleMouseMove(event); }
00871         
00872     void handleWheel(const PlotWheelEvent& event) {
00873         if(m_tracker->isActive()) m_tracker->handleWheel(event);
00874         PlotMouseToolGroup::handleWheel(event); }
00875     // </group>
00876     
00877 protected:
00878     // Overrides PlotMouseToolGroup::attach().
00879     void attach(PlotCanvas* canvas);
00880     
00881     // Overrides PlotMouseToolGroup::detach().
00882     void detach();
00883     
00884 private:
00885     // Tracker.
00886     PlotTrackerToolPtr m_tracker;
00887 };
00888 INHERITANCE_POINTER(PlotStandardMouseToolGroup, PlotStandardMouseToolGroupPtr,
00889                     PlotMouseToolGroup, PlotMouseToolGroupPtr,
00890                     PlotTool, PlotToolPtr)
00891 
00892 }
00893 
00894 #endif /* PLOTTOOL_H_ */