Medical Imaging Interaction Toolkit  2016.11.0
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,
6  Division of Medical and Biological Informatics.
7  All rights reserved.
8 
9  This software is distributed WITHOUT ANY WARRANTY; without
10  even the implied warranty of MERCHANTABILITY or FITNESS FOR
11  A PARTICULAR PURPOSE.
12 
13  See LICENSE.txt or http://www.mitk.org for details.
14 
15  ===================================================================*/
16 
17 #include "mitkVtkEventProvider.h"
18 #include "mitkVtkEventAdapter.h"
19 #include <mbilog.h>
20 
21 #include <vtkCallbackCommand.h>
22 #include <vtkInteractorStyle.h>
23 #include <vtkObjectFactory.h>
24 #include <vtkRenderWindowInteractor.h>
25 
26 #include "mitkInteractionEvent.h"
27 
28 #define VTKEVENTPROVIDER_INFO MBI_INFO("mitk.core.vtkeventprovider")
29 #define VTKEVENTPROVIDER_WARN MBI_WARN("mitk.core.vtkeventprovider")
30 #define VTKEVENTPROVIDER_ERROR MBI_ERROR("mitk.core.vtkeventprovider")
31 #define VTKEVENTPROVIDER_DEBUG MBI_DEBUG("mitk.core.vtkeventprovider")
32 
33 namespace mitk
34 {
35  vtkStandardNewMacro(vtkEventProvider);
36 }
37 //----------------------------------------------------------------------------
39 {
40  // priority of the observer/command; we want MITK events processed in the very beginning
41  this->Priority = 99999.99;
42 
43  // take over the processing of delete and keypress events from the superclass
44  this->EventCallbackCommand->SetCallback(vtkEventProvider::ProcessEvents);
45 
46  // Set/Get the passive observer flag. If this is set to true, this
47  // indicates that this command does not change the state of the
48  // system in any way. Passive observers are processed first, and
49  // are not called even when another command has focus.
50  this->EventCallbackCommand->SetPassiveObserver(1); // get events first
51 
52  // mouse move
53  AddInteractionEvent(vtkCommand::MouseMoveEvent);
54  // mouse press
55  AddInteractionEvent(vtkCommand::LeftButtonPressEvent);
56  AddInteractionEvent(vtkCommand::MiddleButtonPressEvent);
57  AddInteractionEvent(vtkCommand::RightButtonPressEvent);
58  // mouse release
59  AddInteractionEvent(vtkCommand::LeftButtonReleaseEvent);
60  AddInteractionEvent(vtkCommand::MiddleButtonReleaseEvent);
61  AddInteractionEvent(vtkCommand::RightButtonReleaseEvent);
62  // wheel event
63  AddInteractionEvent(vtkCommand::MouseWheelBackwardEvent);
64  AddInteractionEvent(vtkCommand::MouseWheelForwardEvent);
65  // key press event
66  AddInteractionEvent(vtkCommand::KeyPressEvent);
67 }
68 
70 {
71  this->SetInteractor(0);
72 }
73 
75 {
76  m_RenderWindow = renWin;
77 }
78 
80 {
81  return m_RenderWindow;
82 }
83 
85 {
86  if (!this->Interactor)
87  {
88  VTKEVENTPROVIDER_ERROR << "The interactor must be set prior to enabling/disabling widget";
89  return;
90  }
91 
92  if (enabling) //----------------------------------------------------------
93  {
94  VTKEVENTPROVIDER_DEBUG << "Enabling widget";
95 
96  if (this->Enabled) // already enabled, just return
97  {
98  return;
99  }
100 
101  this->Enabled = 1;
102 
103  // listen to all event types specified in m_InteractionEventsVector
104  vtkRenderWindowInteractor *i = this->Interactor;
105 
106  InteractionEventsVectorType::iterator it;
107  for (it = m_InteractionEventsVector.begin(); it != m_InteractionEventsVector.end(); ++it)
108  {
109  // add observer to interactorStyle
110  i->GetInteractorStyle()->AddObserver((vtkCommand::EventIds)(*it), this->EventCallbackCommand, this->Priority);
111  }
112 
113  this->InvokeEvent(vtkCommand::EnableEvent, NULL);
114  }
115 
116  else // disabling-----------------------------------------------------------
117  {
118  VTKEVENTPROVIDER_DEBUG << "Disabling widget";
119 
120  if (!this->Enabled) // already disabled, just return
121  {
122  return;
123  }
124 
125  this->Enabled = 0;
126 
127  // don't listen for events any more
128  this->Interactor->RemoveObserver(this->EventCallbackCommand);
129  // this->Interactor->HandleEventLoop = 0;
130 
131  this->InvokeEvent(vtkCommand::DisableEvent, NULL);
132  }
133 }
134 
135 //----------------------------------------------------------------------------
136 // This adds the keypress event observer and the delete event observer
137 void mitk::vtkEventProvider::SetInteractor(vtkRenderWindowInteractor *i)
138 {
139  if (i == this->Interactor)
140  {
141  return;
142  }
143  // if we already have an Interactor then stop observing it
144  if (this->Interactor)
145  this->SetEnabled(0); // disable the old interactor
146 
147  this->Interactor = i;
148 
149  this->Modified();
150 }
151 
152 //----------------------------------------------------------------------------
154  unsigned long event,
155  void *clientData,
156  void *vtkNotUsed(callData))
157 {
158  vtkEventProvider *self = reinterpret_cast<vtkEventProvider *>(clientData);
159  vtkRenderWindowInteractor *rwi = static_cast<vtkInteractorStyle *>(object)->GetInteractor();
160 
161  // base renderer
162  mitk::BaseRenderer *baseRenderer = mitk::BaseRenderer::GetInstance(self->GetRenderWindow()->GetVtkRenderWindow());
163  switch (event)
164  {
165  // key press
166  case vtkCommand::KeyPressEvent:
167  {
168  VTKEVENTPROVIDER_DEBUG << "key press event";
169  InteractionEvent::Pointer adaptedEvent =
170  VtkEventAdapter::AdaptInteractionKeyEvent(baseRenderer, event, rwi).GetPointer();
171  self->GetRenderWindow()->HandleEvent(adaptedEvent.GetPointer());
172  break;
173  }
174 
175  // mouse events
176  case vtkCommand::MouseMoveEvent:
177  {
178  VTKEVENTPROVIDER_DEBUG << "mouse move event";
179  InteractionEvent::Pointer adaptedEvent =
180  VtkEventAdapter::AdaptMouseMoveEvent(baseRenderer, event, rwi).GetPointer();
181  self->GetRenderWindow()->HandleEvent(adaptedEvent.GetPointer());
182  break;
183  }
184 
185  case vtkCommand::LeftButtonPressEvent:
186  case vtkCommand::MiddleButtonPressEvent:
187  case vtkCommand::RightButtonPressEvent:
188  {
189  VTKEVENTPROVIDER_DEBUG << "mouse press event";
190  InteractionEvent::Pointer adaptedEvent =
191  VtkEventAdapter::AdaptMousePressEvent(baseRenderer, event, rwi).GetPointer();
192  self->GetRenderWindow()->HandleEvent(adaptedEvent.GetPointer());
193  break;
194  }
195 
196  case vtkCommand::LeftButtonReleaseEvent:
197  case vtkCommand::MiddleButtonReleaseEvent:
198  case vtkCommand::RightButtonReleaseEvent:
199  {
200  VTKEVENTPROVIDER_DEBUG << "mouse release event";
201  InteractionEvent::Pointer adaptedEvent =
202  VtkEventAdapter::AdaptMouseReleaseEvent(baseRenderer, event, rwi).GetPointer();
203  self->GetRenderWindow()->HandleEvent(adaptedEvent.GetPointer());
204  break;
205  }
206 
207  // mouse WHEEL
208  case vtkCommand::MouseWheelForwardEvent:
209  case vtkCommand::MouseWheelBackwardEvent:
210  {
211  VTKEVENTPROVIDER_DEBUG << "mouse wheel event";
212  InteractionEvent::Pointer adaptedEvent =
213  VtkEventAdapter::AdaptMouseWheelEvent(baseRenderer, event, rwi).GetPointer();
214  self->GetRenderWindow()->HandleEvent(adaptedEvent.GetPointer());
215  break;
216  }
217 
218  default:
219  VTKEVENTPROVIDER_INFO << "VTK event not mapped properly.";
220  break;
221  }
222 }
223 
225 {
226  InteractionEventsVectorType::iterator it;
227  if (m_InteractionEventsVector.size() > 0)
228  {
229  it = std::find(m_InteractionEventsVector.begin(), m_InteractionEventsVector.end(), ievent);
230  if (it != m_InteractionEventsVector.end())
231  {
232  m_InteractionEventsVector.erase(it);
233  return;
234  }
235  }
236 }
237 
239 {
240  // Remove event if it already exists
241  RemoveInteractionEvent(ievent);
242 
243  m_InteractionEventsVector.push_back(ievent);
244 }
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.
virtual 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...
virtual 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)