1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkOrientationMarkerWidget.h
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 // .NAME vtkOrientationMarkerWidget - 2D widget for manipulating a marker prop
16 // .SECTION Description
17 // This class provides support for interactively manipulating the position,
18 // size, and apparent orientation of a prop that represents an orientation
19 // marker.  This class works by adding its internal renderer to an external
20 // "parent" renderer on a different layer.  The input orientation marker is
21 // rendered as an overlay on the parent renderer and, thus, appears superposed
22 // over all props in the parent's scene.  The camera view of the orientation
23 // the marker is made to match that of the parent's by means of an observer
24 // mechanism, giving the illusion that the orientation of the marker reflects
25 // that of the prop(s) in the parent's scene.
26 //
27 // The widget listens to left mouse button and mouse movement events. It will
28 // change the cursor shape based on its location. If the cursor is over the
29 // overlay renderer, it will change the cursor shape to a SIZEALL shape
30 // or to a resize corner shape (e.g., SIZENW) if the cursor is near a corner.
31 // If the left mouse button is pressed and held down while moving, the overlay
32 // renderer, and hence, the orientation marker, is resized or moved.  I the case
33 // of a resize operation, releasing the left mouse button causes the widget
34 // to enforce its renderer to be square.  The diagonally opposite corner to the
35 // one moved is repositioned such that all edges of the renderer have the same
36 // length: the minimum.
37 //
38 // To use this object, there are two key steps: 1) invoke SetInteractor() with
39 // the argument of the method a vtkRenderWindowInteractor, and 2) invoke
40 // SetOrientationMarker with an instance of vtkProp (see caveats below).
41 // Specifically, vtkAxesActor and vtkAnnotatedCubeActor are two classes
42 // designed to work with this class.  A composite orientation marker can be
43 // generated by adding instances of vtkAxesActor and vtkAnnotatedCubeActor to a
44 // vtkPropAssembly, which can then be set as the input orientation marker.
45 // The widget can be also be set up in a non-interactive fashion by setting
46 // Ineractive to Off and sizing/placing the overlay renderer in its parent
47 // renderer by calling the widget's SetViewport method.
48 
49 // .SECTION Thanks
50 // This class was based originally on Paraview's vtkPVAxesWidget.
51 
52 // .SECTION Caveats
53 // The input orientation marker prop should calculate its bounds as though they
54 // are symmetric about it's origin.  This must currently be done to correctly
55 // implement the camera synchronization between the ivar renderer and the
56 // renderer associated with the set interactor.  Importantly, the InteractorStyle
57 // associated with the interactor must be of the type vtkInteractorStyle*Camera.
58 // Where desirable, the parent renderer should be set by the SetDefaultRenderer
59 // method.  The parent renderer's number of layers is modified to 2 where
60 // required.
61 
62 // .SECTION See Also
63 // vtkInteractorObserver vtkXYPlotWidget vtkScalarBarWidget vtkAxesActor
64 // vtkAnnotatedCubeActor
65 
66 #ifndef vtkOrientationMarkerWidget_h
67 #define vtkOrientationMarkerWidget_h
68 
69 #include "vtkInteractionWidgetsModule.h" // For export macro
70 #include "vtkInteractorObserver.h"
71 
72 class vtkActor2D;
73 class vtkPolyData;
74 class vtkProp;
75 class vtkOrientationMarkerWidgetObserver;
76 class vtkRenderer;
77 
78 class VTKINTERACTIONWIDGETS_EXPORT vtkOrientationMarkerWidget : public vtkInteractorObserver
79 {
80 public:
81   static vtkOrientationMarkerWidget* New();
82   vtkTypeMacro(vtkOrientationMarkerWidget, vtkInteractorObserver);
83   void PrintSelf(ostream& os, vtkIndent indent);
84 
85   // Description:
86   // Set/get the orientation marker to be displayed in this widget.
87   virtual void SetOrientationMarker(vtkProp *prop);
88   vtkGetObjectMacro(OrientationMarker, vtkProp);
89 
90   // Description:
91   // Enable/disable the widget. Default is 0 (disabled).
92   virtual void SetEnabled(int);
93 
94   // Description:
95   // Callback to keep the camera for the orientation marker up to date with the
96   // camera in the parent renderer.
97   void ExecuteCameraUpdateEvent(vtkObject *o, unsigned long event, void *calldata);
98 
99   // Description:
100   // Set/get whether to allow this widget to be interactively moved/scaled.
101   // Default is On.
102   void SetInteractive(int state);
103   vtkGetMacro(Interactive, int);
104   vtkBooleanMacro(Interactive, int);
105 
106   // Description:
107   // Set/get the color of the outline of this widget.  The outline is visible
108   // when (in interactive mode) the cursor is over this widget.
109   // Default is white (1,1,1).
110   void SetOutlineColor(double r, double g, double b);
111   double *GetOutlineColor();
112 
113   // Description:
114   // Set/get the viewport to position/size this widget.
115   // Default is bottom left corner (0,0,0.2,0.2).
116   void SetViewport(double minX, double minY, double maxX, double maxY);
117   double* GetViewport();
118 
119   // Description:
120   // The tolerance representing the distance to the widget (in pixels)
121   // in which the cursor is considered to be on the widget, or on a
122   // widget feature (e.g., a corner point or edge).
123   vtkSetClampMacro(Tolerance,int,1,10);
124   vtkGetMacro(Tolerance,int);
125 
126 protected:
127   vtkOrientationMarkerWidget();
128   ~vtkOrientationMarkerWidget();
129 
130   vtkRenderer *Renderer;
131   vtkProp     *OrientationMarker;
132   vtkPolyData *Outline;
133   vtkActor2D  *OutlineActor;
134 
135   unsigned long StartEventObserverId;
136 
137   static void ProcessEvents(vtkObject *object, unsigned long event,
138                             void *clientdata, void *calldata);
139 
140   // ProcessEvents() dispatches to these methods.
141   void OnLeftButtonDown();
142   void OnLeftButtonUp();
143   void OnMouseMove();
144 
145   // observer to update the renderer's camera
146   vtkOrientationMarkerWidgetObserver *Observer;
147 
148   int Interactive;
149   int Tolerance;
150   int Moving;
151 
152   // used to compute relative movements
153   int StartPosition[2];
154 
155 //BTX - manage the state of the widget
156   int State;
157   enum WidgetState
158   {
159     Outside = 0,
160     Inside,
161     Translating,
162     AdjustingP1,
163     AdjustingP2,
164     AdjustingP3,
165     AdjustingP4
166   };
167 //ETX
168 
169 
170   // use to determine what state the mouse is over, edge1 p1, etc.
171   // returns a state from the WidgetState enum above
172   int ComputeStateBasedOnPosition(int X, int Y, int *pos1, int *pos2);
173 
174   // set the cursor to the correct shape based on State argument
175   void SetCursor(int state);
176 
177   // adjust the viewport depending on state
178   void MoveWidget(int X, int Y);
179   void ResizeTopLeft(int X, int Y);
180   void ResizeTopRight(int X, int Y);
181   void ResizeBottomLeft(int X, int Y);
182   void ResizeBottomRight(int X, int Y);
183 
184   void SquareRenderer();
185   void UpdateOutline();
186 
187 private:
188   vtkOrientationMarkerWidget(const vtkOrientationMarkerWidget&);  // Not implemented
189   void operator=(const vtkOrientationMarkerWidget&);  // Not implemented
190 };
191 
192 #endif
193