Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
mitkVtkEventProvider.cpp
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #include "mitkVtkEventProvider.h"
14 #include "mitkVtkEventAdapter.h"
15 #include <mbilog.h>
16 
17 #include <vtkCallbackCommand.h>
18 #include <vtkInteractorStyle.h>
19 #include <vtkObjectFactory.h>
20 #include <vtkRenderWindowInteractor.h>
21 
22 #include "mitkInteractionEvent.h"
23 
24 #define VTKEVENTPROVIDER_INFO MBI_INFO("mitk.core.vtkeventprovider")
25 #define VTKEVENTPROVIDER_WARN MBI_WARN("mitk.core.vtkeventprovider")
26 #define VTKEVENTPROVIDER_ERROR MBI_ERROR("mitk.core.vtkeventprovider")
27 #define VTKEVENTPROVIDER_DEBUG MBI_DEBUG("mitk.core.vtkeventprovider")
28 
29 namespace mitk
30 {
31  vtkStandardNewMacro(vtkEventProvider);
32 }
33 //----------------------------------------------------------------------------
35 {
36  // priority of the observer/command; we want MITK events processed in the very beginning
37  this->Priority = 99999.99;
38 
39  // take over the processing of delete and keypress events from the superclass
40  this->EventCallbackCommand->SetCallback(vtkEventProvider::ProcessEvents);
41 
42  // Set/Get the passive observer flag. If this is set to true, this
43  // indicates that this command does not change the state of the
44  // system in any way. Passive observers are processed first, and
45  // are not called even when another command has focus.
46  this->EventCallbackCommand->SetPassiveObserver(1); // get events first
47 
48  // mouse move
49  AddInteractionEvent(vtkCommand::MouseMoveEvent);
50  // mouse press
51  AddInteractionEvent(vtkCommand::LeftButtonPressEvent);
52  AddInteractionEvent(vtkCommand::MiddleButtonPressEvent);
53  AddInteractionEvent(vtkCommand::RightButtonPressEvent);
54  // mouse release
55  AddInteractionEvent(vtkCommand::LeftButtonReleaseEvent);
56  AddInteractionEvent(vtkCommand::MiddleButtonReleaseEvent);
57  AddInteractionEvent(vtkCommand::RightButtonReleaseEvent);
58  // wheel event
59  AddInteractionEvent(vtkCommand::MouseWheelBackwardEvent);
60  AddInteractionEvent(vtkCommand::MouseWheelForwardEvent);
61  // key press event
62  AddInteractionEvent(vtkCommand::KeyPressEvent);
63 }
64 
66 {
67  this->SetInteractor(nullptr);
68 }
69 
71 {
72  m_RenderWindow = renWin;
73 }
74 
76 {
77  return m_RenderWindow;
78 }
79 
81 {
82  if (!this->Interactor)
83  {
84  VTKEVENTPROVIDER_ERROR << "The interactor must be set prior to enabling/disabling widget";
85  return;
86  }
87 
88  if (enabling) //----------------------------------------------------------
89  {
90  VTKEVENTPROVIDER_DEBUG << "Enabling widget";
91 
92  if (this->Enabled) // already enabled, just return
93  {
94  return;
95  }
96 
97  this->Enabled = 1;
98 
99  // listen to all event types specified in m_InteractionEventsVector
100  vtkRenderWindowInteractor *i = this->Interactor;
101 
102  InteractionEventsVectorType::iterator it;
103  for (it = m_InteractionEventsVector.begin(); it != m_InteractionEventsVector.end(); ++it)
104  {
105  // add observer to interactorStyle
106  i->GetInteractorStyle()->AddObserver((vtkCommand::EventIds)(*it), this->EventCallbackCommand, this->Priority);
107  }
108 
109  this->InvokeEvent(vtkCommand::EnableEvent, nullptr);
110  }
111 
112  else // disabling-----------------------------------------------------------
113  {
114  VTKEVENTPROVIDER_DEBUG << "Disabling widget";
115 
116  if (!this->Enabled) // already disabled, just return
117  {
118  return;
119  }
120 
121  this->Enabled = 0;
122 
123  // don't listen for events any more
124  this->Interactor->RemoveObserver(this->EventCallbackCommand);
125  // this->Interactor->HandleEventLoop = 0;
126 
127  this->InvokeEvent(vtkCommand::DisableEvent, nullptr);
128  }
129 }
130 
131 //----------------------------------------------------------------------------
132 // This adds the keypress event observer and the delete event observer
133 void mitk::vtkEventProvider::SetInteractor(vtkRenderWindowInteractor *i)
134 {
135  if (i == this->Interactor)
136  {
137  return;
138  }
139  // if we already have an Interactor then stop observing it
140  if (this->Interactor)
141  this->SetEnabled(0); // disable the old interactor
142 
143  this->Interactor = i;
144 
145  this->Modified();
146 }
147 
148 //----------------------------------------------------------------------------
150  unsigned long event,
151  void *clientData,
152  void *vtkNotUsed(callData))
153 {
154  auto *self = reinterpret_cast<vtkEventProvider *>(clientData);
155  vtkRenderWindowInteractor *rwi = static_cast<vtkInteractorStyle *>(object)->GetInteractor();
156 
157  // base renderer
158  mitk::BaseRenderer *baseRenderer = mitk::BaseRenderer::GetInstance(self->GetRenderWindow()->GetVtkRenderWindow());
159  switch (event)
160  {
161  // key press
162  case vtkCommand::KeyPressEvent:
163  {
164  VTKEVENTPROVIDER_DEBUG << "key press event";
165  InteractionEvent::Pointer adaptedEvent =
166  VtkEventAdapter::AdaptInteractionKeyEvent(baseRenderer, event, rwi).GetPointer();
167  self->GetRenderWindow()->HandleEvent(adaptedEvent.GetPointer());
168  break;
169  }
170 
171  // mouse events
172  case vtkCommand::MouseMoveEvent:
173  {
174  VTKEVENTPROVIDER_DEBUG << "mouse move event";
175  InteractionEvent::Pointer adaptedEvent =
176  VtkEventAdapter::AdaptMouseMoveEvent(baseRenderer, event, rwi).GetPointer();
177  self->GetRenderWindow()->HandleEvent(adaptedEvent.GetPointer());
178  break;
179  }
180 
181  case vtkCommand::LeftButtonPressEvent:
182  case vtkCommand::MiddleButtonPressEvent:
183  case vtkCommand::RightButtonPressEvent:
184  {
185  VTKEVENTPROVIDER_DEBUG << "mouse press event";
186  InteractionEvent::Pointer adaptedEvent =
187  VtkEventAdapter::AdaptMousePressEvent(baseRenderer, event, rwi).GetPointer();
188  self->GetRenderWindow()->HandleEvent(adaptedEvent.GetPointer());
189  break;
190  }
191 
192  case vtkCommand::LeftButtonReleaseEvent:
193  case vtkCommand::MiddleButtonReleaseEvent:
194  case vtkCommand::RightButtonReleaseEvent:
195  {
196  VTKEVENTPROVIDER_DEBUG << "mouse release event";
197  InteractionEvent::Pointer adaptedEvent =
198  VtkEventAdapter::AdaptMouseReleaseEvent(baseRenderer, event, rwi).GetPointer();
199  self->GetRenderWindow()->HandleEvent(adaptedEvent.GetPointer());
200  break;
201  }
202 
203  // mouse WHEEL
204  case vtkCommand::MouseWheelForwardEvent:
205  case vtkCommand::MouseWheelBackwardEvent:
206  {
207  VTKEVENTPROVIDER_DEBUG << "mouse wheel event";
208  InteractionEvent::Pointer adaptedEvent =
209  VtkEventAdapter::AdaptMouseWheelEvent(baseRenderer, event, rwi).GetPointer();
210  self->GetRenderWindow()->HandleEvent(adaptedEvent.GetPointer());
211  break;
212  }
213 
214  default:
215  VTKEVENTPROVIDER_INFO << "VTK event not mapped properly.";
216  break;
217  }
218 }
219 
221 {
222  InteractionEventsVectorType::iterator it;
223  if (m_InteractionEventsVector.size() > 0)
224  {
225  it = std::find(m_InteractionEventsVector.begin(), m_InteractionEventsVector.end(), ievent);
226  if (it != m_InteractionEventsVector.end())
227  {
228  m_InteractionEventsVector.erase(it);
229  return;
230  }
231  }
232 }
233 
235 {
236  // Remove event if it already exists
237  RemoveInteractionEvent(ievent);
238 
239  m_InteractionEventsVector.push_back(ievent);
240 }
static BaseRenderer * GetInstance(vtkRenderWindow *renWin)
#define VTKEVENTPROVIDER_ERROR
static mitk::InteractionKeyEvent::Pointer AdaptInteractionKeyEvent(mitk::BaseRenderer *sender, unsigned long vtkCommandEventId, vtkRenderWindowInteractor *rwi)
static mitk::MouseReleaseEvent::Pointer AdaptMouseReleaseEvent(mitk::BaseRenderer *sender, unsigned long vtkCommandEventId, vtkRenderWindowInteractor *rwi)
Organizes the rendering process.
void SetInteractor(vtkRenderWindowInteractor *iren) override
DataCollection - Class to facilitate loading/accessing structured data.
#define VTKEVENTPROVIDER_INFO
static mitk::MousePressEvent::Pointer AdaptMousePressEvent(mitk::BaseRenderer *sender, unsigned long vtkCommandEventId, vtkRenderWindowInteractor *rwi)
void AddInteractionEvent(unsigned long ievent)
Integrates into the VTK event mechanism to generate MITK specific events. This class is NON-QT depend...
void SetEnabled(int) override
void RemoveInteractionEvent(unsigned long ievent)
virtual void SetMitkRenderWindow(mitk::RenderWindow *renWin)
vtkStandardNewMacro(AnatomicalStructureColorPresets)
#define VTKEVENTPROVIDER_DEBUG
mitk::RenderWindow * GetRenderWindow()
static mitk::MouseMoveEvent::Pointer AdaptMouseMoveEvent(mitk::BaseRenderer *sender, unsigned long vtkCommandEventId, vtkRenderWindowInteractor *rwi)
mitkRenderWindow integrates the MITK rendering mechanism into VTK and is NOT QT dependent ...
static mitk::MouseWheelEvent::Pointer AdaptMouseWheelEvent(mitk::BaseRenderer *sender, unsigned long vtkCommandEventId, vtkRenderWindowInteractor *rwi)
static void ProcessEvents(vtkObject *object, unsigned long event, void *clientdata, void *calldata)