1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkWidgetEventTranslator.cxx
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 #include "vtkWidgetEventTranslator.h"
16 #include "vtkAbstractWidget.h"
17 #include "vtkCallbackCommand.h"
18 #include "vtkCommand.h"
19 #include "vtkEvent.h"
20 #include "vtkEventData.h"
21 #include "vtkObjectFactory.h"
22 #include "vtkRenderWindowInteractor.h"
23 #include "vtkSmartPointer.h"
24 #include "vtkWidgetEvent.h"
25 #include <list>
26 #include <map>
27
28 vtkStandardNewMacro(vtkWidgetEventTranslator);
29
30 // This is what is place in the list
31 struct EventItem
32 {
33 vtkSmartPointer<vtkEvent> VTKEvent;
34 unsigned long WidgetEvent;
35 vtkEventData* EventData = nullptr;
36 bool HasData = false;
37
EventItemEventItem38 EventItem(vtkEvent* e, unsigned long we)
39 {
40 this->VTKEvent = e;
41 this->WidgetEvent = we;
42 this->HasData = false;
43 }
EventItemEventItem44 EventItem(vtkEventData* edata, unsigned long we)
45 {
46 this->EventData = edata;
47 this->EventData->Register(nullptr);
48 this->WidgetEvent = we;
49 this->HasData = true;
50 }
~EventItemEventItem51 ~EventItem()
52 {
53 if (this->HasData && this->EventData)
54 {
55 this->EventData->UnRegister(nullptr);
56 this->EventData = nullptr;
57 }
58 }
59
EventItemEventItem60 EventItem(const EventItem& v)
61 {
62 this->VTKEvent = v.VTKEvent;
63 this->WidgetEvent = v.WidgetEvent;
64 this->HasData = v.HasData;
65 this->EventData = v.EventData;
66 if (this->HasData && this->EventData)
67 {
68 this->EventData->Register(nullptr);
69 }
70 }
71
72 private:
73 EventItem() = delete;
74 };
75
76 // A list of events
77 struct EventList : public std::list<EventItem>
78 {
findEventList79 unsigned long find(unsigned long VTKEvent)
80 {
81 std::list<EventItem>::iterator liter = this->begin();
82 for (; liter != this->end(); ++liter)
83 {
84 if (VTKEvent == liter->VTKEvent->GetEventId())
85 {
86 return liter->WidgetEvent;
87 }
88 }
89 return vtkWidgetEvent::NoEvent;
90 }
91
findEventList92 unsigned long find(vtkEvent* VTKEvent)
93 {
94 std::list<EventItem>::iterator liter = this->begin();
95 for (; liter != this->end(); ++liter)
96 {
97 if (*VTKEvent == liter->VTKEvent)
98 {
99 return liter->WidgetEvent;
100 }
101 }
102 return vtkWidgetEvent::NoEvent;
103 }
104
findEventList105 unsigned long find(vtkEventData* edata)
106 {
107 std::list<EventItem>::iterator liter = this->begin();
108 for (; liter != this->end(); ++liter)
109 {
110 if (liter->HasData && *edata == *liter->EventData)
111 {
112 return liter->WidgetEvent;
113 }
114 }
115 return vtkWidgetEvent::NoEvent;
116 }
117
118 // Remove a mapping
RemoveEventList119 int Remove(vtkEvent* VTKEvent)
120 {
121 std::list<EventItem>::iterator liter = this->begin();
122 for (; liter != this->end(); ++liter)
123 {
124 if (*VTKEvent == liter->VTKEvent)
125 {
126 this->erase(liter);
127 return 1;
128 }
129 }
130 return 0;
131 }
RemoveEventList132 int Remove(vtkEventData* edata)
133 {
134 std::list<EventItem>::iterator liter = this->begin();
135 for (; liter != this->end(); ++liter)
136 {
137 if (liter->HasData && *edata == *liter->EventData)
138 {
139 this->erase(liter);
140 return 1;
141 }
142 }
143 return 0;
144 }
145 };
146
147 // A STL map used to translate VTK events into lists of events. The reason
148 // that we have this list is because of the modifiers on the event. The
149 // VTK event id maps to the list, and then comparisons are done to
150 // determine which event matches.
151 class vtkEventMap : public std::map<unsigned long, EventList>
152 {
153 };
154 typedef std::map<unsigned long, EventList>::iterator EventMapIterator;
155
156 //------------------------------------------------------------------------------
vtkWidgetEventTranslator()157 vtkWidgetEventTranslator::vtkWidgetEventTranslator()
158 {
159 this->EventMap = new vtkEventMap;
160 this->Event = vtkEvent::New();
161 }
162
163 //------------------------------------------------------------------------------
~vtkWidgetEventTranslator()164 vtkWidgetEventTranslator::~vtkWidgetEventTranslator()
165 {
166 delete this->EventMap;
167 this->Event->Delete();
168 }
169
170 //------------------------------------------------------------------------------
SetTranslation(unsigned long VTKEvent,unsigned long widgetEvent)171 void vtkWidgetEventTranslator::SetTranslation(unsigned long VTKEvent, unsigned long widgetEvent)
172 {
173 vtkSmartPointer<vtkEvent> e = vtkSmartPointer<vtkEvent>::New();
174 e->SetEventId(VTKEvent); // default modifiers
175 if (widgetEvent != vtkWidgetEvent::NoEvent)
176 {
177 (*this->EventMap)[VTKEvent].push_back(EventItem(e, widgetEvent));
178 }
179 else
180 {
181 this->RemoveTranslation(e);
182 }
183 }
184
185 //------------------------------------------------------------------------------
SetTranslation(const char * VTKEvent,const char * widgetEvent)186 void vtkWidgetEventTranslator::SetTranslation(const char* VTKEvent, const char* widgetEvent)
187 {
188 this->SetTranslation(
189 vtkCommand::GetEventIdFromString(VTKEvent), vtkWidgetEvent::GetEventIdFromString(widgetEvent));
190 }
191
192 //------------------------------------------------------------------------------
SetTranslation(unsigned long VTKEvent,int modifier,char keyCode,int repeatCount,const char * keySym,unsigned long widgetEvent)193 void vtkWidgetEventTranslator::SetTranslation(unsigned long VTKEvent, int modifier, char keyCode,
194 int repeatCount, const char* keySym, unsigned long widgetEvent)
195 {
196 vtkSmartPointer<vtkEvent> e = vtkSmartPointer<vtkEvent>::New();
197 e->SetEventId(VTKEvent);
198 e->SetModifier(modifier);
199 e->SetKeyCode(keyCode);
200 e->SetRepeatCount(repeatCount);
201 e->SetKeySym(keySym);
202 if (widgetEvent != vtkWidgetEvent::NoEvent)
203 {
204 (*this->EventMap)[VTKEvent].push_back(EventItem(e, widgetEvent));
205 }
206 else
207 {
208 this->RemoveTranslation(e);
209 }
210 }
211
SetTranslation(unsigned long VTKEvent,vtkEventData * edata,unsigned long widgetEvent)212 void vtkWidgetEventTranslator::SetTranslation(
213 unsigned long VTKEvent, vtkEventData* edata, unsigned long widgetEvent)
214 {
215 if (widgetEvent != vtkWidgetEvent::NoEvent)
216 {
217 (*this->EventMap)[VTKEvent].push_back(EventItem(edata, widgetEvent));
218 }
219 else
220 {
221 this->RemoveTranslation(edata);
222 }
223 }
224
225 //------------------------------------------------------------------------------
SetTranslation(vtkEvent * VTKEvent,unsigned long widgetEvent)226 void vtkWidgetEventTranslator::SetTranslation(vtkEvent* VTKEvent, unsigned long widgetEvent)
227 {
228 if (widgetEvent != vtkWidgetEvent::NoEvent)
229 {
230 (*this->EventMap)[VTKEvent->GetEventId()].push_back(EventItem(VTKEvent, widgetEvent));
231 }
232 else
233 {
234 this->RemoveTranslation(VTKEvent);
235 }
236 }
237
238 //------------------------------------------------------------------------------
GetTranslation(unsigned long VTKEvent)239 unsigned long vtkWidgetEventTranslator::GetTranslation(unsigned long VTKEvent)
240 {
241 EventMapIterator iter = this->EventMap->find(VTKEvent);
242 if (iter != this->EventMap->end())
243 {
244 EventList& elist = (*iter).second;
245 return elist.find(VTKEvent);
246 }
247 else
248 {
249 return vtkWidgetEvent::NoEvent;
250 }
251 }
252
253 //------------------------------------------------------------------------------
GetTranslation(const char * VTKEvent)254 const char* vtkWidgetEventTranslator::GetTranslation(const char* VTKEvent)
255 {
256 return vtkWidgetEvent::GetStringFromEventId(
257 this->GetTranslation(vtkCommand::GetEventIdFromString(VTKEvent)));
258 }
259
260 //------------------------------------------------------------------------------
GetTranslation(unsigned long VTKEvent,int modifier,char keyCode,int repeatCount,const char * keySym)261 unsigned long vtkWidgetEventTranslator::GetTranslation(
262 unsigned long VTKEvent, int modifier, char keyCode, int repeatCount, const char* keySym)
263 {
264 EventMapIterator iter = this->EventMap->find(VTKEvent);
265 if (iter != this->EventMap->end())
266 {
267 this->Event->SetEventId(VTKEvent);
268 this->Event->SetModifier(modifier);
269 this->Event->SetKeyCode(keyCode);
270 this->Event->SetRepeatCount(repeatCount);
271 this->Event->SetKeySym(keySym);
272 EventList& elist = (*iter).second;
273 return elist.find(this->Event);
274 }
275 return vtkWidgetEvent::NoEvent;
276 }
277
278 //------------------------------------------------------------------------------
GetTranslation(unsigned long,vtkEventData * edata)279 unsigned long vtkWidgetEventTranslator::GetTranslation(unsigned long, vtkEventData* edata)
280 {
281 EventMapIterator iter = this->EventMap->find(edata->GetType());
282 if (iter != this->EventMap->end())
283 {
284 EventList& elist = (*iter).second;
285 return elist.find(edata);
286 }
287 return vtkWidgetEvent::NoEvent;
288 }
289
290 //------------------------------------------------------------------------------
GetTranslation(vtkEvent * VTKEvent)291 unsigned long vtkWidgetEventTranslator::GetTranslation(vtkEvent* VTKEvent)
292 {
293 EventMapIterator iter = this->EventMap->find(VTKEvent->GetEventId());
294 if (iter != this->EventMap->end())
295 {
296 EventList& elist = (*iter).second;
297 return elist.find(VTKEvent);
298 }
299 else
300 {
301 return vtkWidgetEvent::NoEvent;
302 }
303 }
304
305 //------------------------------------------------------------------------------
RemoveTranslation(unsigned long VTKEvent,int modifier,char keyCode,int repeatCount,const char * keySym)306 int vtkWidgetEventTranslator::RemoveTranslation(
307 unsigned long VTKEvent, int modifier, char keyCode, int repeatCount, const char* keySym)
308 {
309 vtkSmartPointer<vtkEvent> e = vtkSmartPointer<vtkEvent>::New();
310 e->SetEventId(VTKEvent);
311 e->SetModifier(modifier);
312 e->SetKeyCode(keyCode);
313 e->SetRepeatCount(repeatCount);
314 e->SetKeySym(keySym);
315 return this->RemoveTranslation(e);
316 }
317
318 //------------------------------------------------------------------------------
RemoveTranslation(vtkEvent * e)319 int vtkWidgetEventTranslator::RemoveTranslation(vtkEvent* e)
320 {
321 EventMapIterator iter = this->EventMap->find(e->GetEventId());
322 int numTranslationsRemoved = 0;
323 if (iter != this->EventMap->end())
324 {
325 while (iter->second.Remove(e))
326 {
327 ++numTranslationsRemoved;
328 iter = this->EventMap->find(e->GetEventId());
329 if (iter == this->EventMap->end())
330 {
331 break;
332 }
333 }
334 }
335
336 return numTranslationsRemoved;
337 }
338
339 //------------------------------------------------------------------------------
RemoveTranslation(vtkEventData * edata)340 int vtkWidgetEventTranslator::RemoveTranslation(vtkEventData* edata)
341 {
342 EventMapIterator iter = this->EventMap->find(edata->GetType());
343 int numTranslationsRemoved = 0;
344 if (iter != this->EventMap->end())
345 {
346 while (iter->second.Remove(edata))
347 {
348 ++numTranslationsRemoved;
349 iter = this->EventMap->find(edata->GetType());
350 if (iter == this->EventMap->end())
351 {
352 break;
353 }
354 }
355 }
356
357 return numTranslationsRemoved;
358 }
359
360 //------------------------------------------------------------------------------
RemoveTranslation(unsigned long VTKEvent)361 int vtkWidgetEventTranslator::RemoveTranslation(unsigned long VTKEvent)
362 {
363 vtkSmartPointer<vtkEvent> e = vtkSmartPointer<vtkEvent>::New();
364 e->SetEventId(VTKEvent);
365 return this->RemoveTranslation(e);
366 }
367
368 //------------------------------------------------------------------------------
RemoveTranslation(const char * VTKEvent)369 int vtkWidgetEventTranslator::RemoveTranslation(const char* VTKEvent)
370 {
371 vtkSmartPointer<vtkEvent> e = vtkSmartPointer<vtkEvent>::New();
372 e->SetEventId(vtkCommand::GetEventIdFromString(VTKEvent));
373 return this->RemoveTranslation(e);
374 }
375
376 //------------------------------------------------------------------------------
ClearEvents()377 void vtkWidgetEventTranslator::ClearEvents()
378 {
379 EventMapIterator iter = this->EventMap->begin();
380 for (; iter != this->EventMap->end(); ++iter)
381 {
382 EventList& elist = (*iter).second;
383 elist.clear();
384 }
385 this->EventMap->clear();
386 }
387
388 //------------------------------------------------------------------------------
AddEventsToInteractor(vtkRenderWindowInteractor * i,vtkCallbackCommand * command,float priority)389 void vtkWidgetEventTranslator::AddEventsToInteractor(
390 vtkRenderWindowInteractor* i, vtkCallbackCommand* command, float priority)
391 {
392 EventMapIterator iter = this->EventMap->begin();
393 for (; iter != this->EventMap->end(); ++iter)
394 {
395 i->AddObserver((*iter).first, command, priority);
396 }
397 }
398
399 //------------------------------------------------------------------------------
AddEventsToParent(vtkAbstractWidget * w,vtkCallbackCommand * command,float priority)400 void vtkWidgetEventTranslator::AddEventsToParent(
401 vtkAbstractWidget* w, vtkCallbackCommand* command, float priority)
402 {
403 EventMapIterator iter = this->EventMap->begin();
404 for (; iter != this->EventMap->end(); ++iter)
405 {
406 w->AddObserver((*iter).first, command, priority);
407 }
408 }
409
410 //------------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)411 void vtkWidgetEventTranslator::PrintSelf(ostream& os, vtkIndent indent)
412 {
413 // Superclass typedef defined in vtkTypeMacro() found in vtkSetGet.h
414 this->Superclass::PrintSelf(os, indent);
415
416 // List all the events and their translations
417 os << indent << "Event Table:\n";
418 EventMapIterator iter = this->EventMap->begin();
419 for (; iter != this->EventMap->end(); ++iter)
420 {
421 EventList& elist = (*iter).second;
422 std::list<EventItem>::iterator liter = elist.begin();
423 for (; liter != elist.end(); ++liter)
424 {
425 os << "VTKEvent(" << vtkCommand::GetStringFromEventId(liter->VTKEvent->GetEventId()) << ","
426 << liter->VTKEvent->GetModifier() << "," << liter->VTKEvent->GetKeyCode() << ","
427 << liter->VTKEvent->GetRepeatCount() << ",";
428 os << (liter->VTKEvent->GetKeySym() ? liter->VTKEvent->GetKeySym() : "(any)");
429 os << ") maps to " << vtkWidgetEvent::GetStringFromEventId(liter->WidgetEvent) << "\n";
430 }
431 }
432 }
433