1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkFinitePlaneWidget.cxx
5
6 Copyright (c)
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 #include "vtkFinitePlaneWidget.h"
16 #include "vtkCallbackCommand.h"
17 #include "vtkCommand.h"
18 #include "vtkEvent.h"
19 #include "vtkFinitePlaneRepresentation.h"
20 #include "vtkObjectFactory.h"
21 #include "vtkRenderWindow.h"
22 #include "vtkRenderWindowInteractor.h"
23 #include "vtkRenderer.h"
24 #include "vtkWidgetCallbackMapper.h"
25 #include "vtkWidgetEvent.h"
26 #include "vtkWidgetEventTranslator.h"
27
28 vtkStandardNewMacro(vtkFinitePlaneWidget);
29
30 //------------------------------------------------------------------------------
vtkFinitePlaneWidget()31 vtkFinitePlaneWidget::vtkFinitePlaneWidget()
32 {
33 this->WidgetState = vtkFinitePlaneWidget::Start;
34 this->ManagesCursor = 1;
35
36 // Define widget events
37 this->CallbackMapper->SetCallbackMethod(vtkCommand::LeftButtonPressEvent, vtkWidgetEvent::Select,
38 this, vtkFinitePlaneWidget::SelectAction);
39 this->CallbackMapper->SetCallbackMethod(vtkCommand::LeftButtonReleaseEvent,
40 vtkWidgetEvent::EndSelect, this, vtkFinitePlaneWidget::EndSelectAction);
41
42 this->CallbackMapper->SetCallbackMethod(
43 vtkCommand::MouseMoveEvent, vtkWidgetEvent::Move, this, vtkFinitePlaneWidget::MoveAction);
44 }
45
46 //------------------------------------------------------------------------------
47 vtkFinitePlaneWidget::~vtkFinitePlaneWidget() = default;
48
49 //------------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)50 void vtkFinitePlaneWidget::PrintSelf(ostream& os, vtkIndent indent)
51 {
52 this->Superclass::PrintSelf(os, indent);
53 }
54
55 //------------------------------------------------------------------------------
SetRepresentation(vtkFinitePlaneRepresentation * r)56 void vtkFinitePlaneWidget::SetRepresentation(vtkFinitePlaneRepresentation* r)
57 {
58 this->Superclass::SetWidgetRepresentation(r);
59 }
60
61 //------------------------------------------------------------------------------
SelectAction(vtkAbstractWidget * w)62 void vtkFinitePlaneWidget::SelectAction(vtkAbstractWidget* w)
63 {
64 // We are in a static method, cast to ourself
65 vtkFinitePlaneWidget* self = reinterpret_cast<vtkFinitePlaneWidget*>(w);
66
67 // Get the event position
68 int X = self->Interactor->GetEventPosition()[0];
69 int Y = self->Interactor->GetEventPosition()[1];
70
71 // We want to compute an orthogonal vector to the plane that has been selected
72 reinterpret_cast<vtkFinitePlaneRepresentation*>(self->WidgetRep)
73 ->SetInteractionState(vtkFinitePlaneRepresentation::Moving);
74 int interactionState = self->WidgetRep->ComputeInteractionState(X, Y);
75 self->UpdateCursorShape(interactionState);
76
77 if (self->WidgetRep->GetInteractionState() == vtkFinitePlaneRepresentation::Outside)
78 {
79 return;
80 }
81
82 // We are definitely selected
83 self->GrabFocus(self->EventCallbackCommand);
84 double eventPos[2];
85 eventPos[0] = static_cast<double>(X);
86 eventPos[1] = static_cast<double>(Y);
87 self->WidgetState = vtkFinitePlaneWidget::Active;
88 self->WidgetRep->StartWidgetInteraction(eventPos);
89
90 self->EventCallbackCommand->SetAbortFlag(1);
91 self->StartInteraction();
92 self->InvokeEvent(vtkCommand::StartInteractionEvent, nullptr);
93 self->Render();
94 }
95
96 //------------------------------------------------------------------------------
MoveAction(vtkAbstractWidget * w)97 void vtkFinitePlaneWidget::MoveAction(vtkAbstractWidget* w)
98 {
99 vtkFinitePlaneWidget* self = reinterpret_cast<vtkFinitePlaneWidget*>(w);
100
101 // So as to change the cursor shape when the mouse is poised over
102 // the widget. Unfortunately, this results in a few extra picks
103 // due to the cell picker. However given that its picking planes
104 // and the handles/arrows, this should be very quick
105 int X = self->Interactor->GetEventPosition()[0];
106 int Y = self->Interactor->GetEventPosition()[1];
107 int changed = 0;
108
109 vtkFinitePlaneRepresentation* repr =
110 reinterpret_cast<vtkFinitePlaneRepresentation*>(self->WidgetRep);
111
112 if (self->ManagesCursor && self->WidgetState != vtkFinitePlaneWidget::Active)
113 {
114 int oldInteractionState = repr->GetInteractionState();
115
116 repr->SetInteractionState(vtkFinitePlaneRepresentation::Moving);
117 int state = self->WidgetRep->ComputeInteractionState(X, Y);
118 changed = self->UpdateCursorShape(state);
119 repr->SetInteractionState(oldInteractionState);
120 changed = (changed || state != oldInteractionState) ? 1 : 0;
121 }
122
123 // See whether we're active
124 if (self->WidgetState == vtkFinitePlaneWidget::Start)
125 {
126 if (changed && self->ManagesCursor)
127 {
128 self->Render();
129 }
130 return;
131 }
132
133 // Adjust the representation
134 double e[2];
135 e[0] = static_cast<double>(X);
136 e[1] = static_cast<double>(Y);
137 self->WidgetRep->WidgetInteraction(e);
138
139 // Moving something
140 self->EventCallbackCommand->SetAbortFlag(1);
141 self->InvokeEvent(vtkCommand::InteractionEvent, nullptr);
142 self->Render();
143 }
144
145 //------------------------------------------------------------------------------
EndSelectAction(vtkAbstractWidget * w)146 void vtkFinitePlaneWidget::EndSelectAction(vtkAbstractWidget* w)
147 {
148 vtkFinitePlaneWidget* self = reinterpret_cast<vtkFinitePlaneWidget*>(w);
149
150 if (self->WidgetState != vtkFinitePlaneWidget::Active ||
151 self->WidgetRep->GetInteractionState() == vtkFinitePlaneRepresentation::Outside)
152 {
153 return;
154 }
155
156 // Return state to not selected
157 double e[2];
158 self->WidgetRep->EndWidgetInteraction(e);
159 self->WidgetState = vtkFinitePlaneWidget::Start;
160 self->ReleaseFocus();
161
162 // Update cursor if managed
163 self->UpdateCursorShape(
164 reinterpret_cast<vtkFinitePlaneRepresentation*>(self->WidgetRep)->GetRepresentationState());
165
166 self->EventCallbackCommand->SetAbortFlag(1);
167 self->EndInteraction();
168 self->InvokeEvent(vtkCommand::EndInteractionEvent, nullptr);
169 self->Render();
170 }
171
172 //------------------------------------------------------------------------------
CreateDefaultRepresentation()173 void vtkFinitePlaneWidget::CreateDefaultRepresentation()
174 {
175 if (!this->WidgetRep)
176 {
177 this->WidgetRep = vtkFinitePlaneRepresentation::New();
178 }
179 }
180
181 //------------------------------------------------------------------------------
UpdateCursorShape(int state)182 int vtkFinitePlaneWidget::UpdateCursorShape(int state)
183 {
184 // So as to change the cursor shape when the mouse is poised over
185 // the widget.
186 if (this->ManagesCursor)
187 {
188 if (state == vtkFinitePlaneRepresentation::Outside)
189 {
190 return this->RequestCursorShape(VTK_CURSOR_DEFAULT);
191 }
192 else
193 {
194 return this->RequestCursorShape(VTK_CURSOR_HAND);
195 }
196 }
197
198 return 0;
199 }
200