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