]> Creatis software - creaMaracasVisu.git/blob - lib/maracasVisuLib/src/interface/wxWindows/widgets/wxVTKRenderWindowInteractor.cxx
#3128 creaMaracasVisu Feature New Normal - branch changeWx28to30 compilation with...
[creaMaracasVisu.git] / lib / maracasVisuLib / src / interface / wxWindows / widgets / wxVTKRenderWindowInteractor.cxx
1 /*# ---------------------------------------------------------------------
2 #
3 # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image
4 #                        pour la Sant�)
5 # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton
6 # Previous Authors : Laurent Guigues, Jean-Pierre Roux
7 # CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil
8 #
9 #  This software is governed by the CeCILL-B license under French law and
10 #  abiding by the rules of distribution of free software. You can  use,
11 #  modify and/ or redistribute the software under the terms of the CeCILL-B
12 #  license as circulated by CEA, CNRS and INRIA at the following URL
13 #  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
14 #  or in the file LICENSE.txt.
15 #
16 #  As a counterpart to the access to the source code and  rights to copy,
17 #  modify and redistribute granted by the license, users are provided only
18 #  with a limited warranty  and the software's author,  the holder of the
19 #  economic rights,  and the successive licensors  have only  limited
20 #  liability.
21 #
22 #  The fact that you are presently reading this means that you have had
23 #  knowledge of the CeCILL-B license and that you accept its terms.
24 # ------------------------------------------------------------------------ */
25
26 /*=========================================================================
27
28   Program:   Visualization Toolkit
29   Module:    $RCSfile: wxVTKRenderWindowInteractor.cxx,v $
30   Language:  C++
31   Date:      $Date: 2012/11/15 14:14:35 $
32   Version:   $Revision: 1.7 $
33
34   Copyright (c) 1993-2002 Ken Martin, Will Schroeder, Bill Lorensen 
35   All rights reserved.
36   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
37
38      This software is distributed WITHOUT ANY WARRANTY; without even 
39      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
40      PURPOSE.  See the above copyright notice for more information.
41
42 =========================================================================*/
43
44 #include <assert.h>
45
46 #include "wxVTKRenderWindowInteractor.h"
47
48 //This is needed for vtk 3.1 :
49 #ifndef VTK_MAJOR_VERSION
50 #  include "vtkVersion.h"
51 #endif
52
53 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
54 #  include "vtkCommand.h"
55 #else
56 #  include "vtkInteractorStyle.h"
57 #endif
58 #include "vtkDebugLeaks.h"
59
60 #ifdef __WXMAC__
61 #include "vtkCarbonRenderWindow.h"
62 #endif
63
64 //Keep this for compatibilty reason, this was introduced in wxGTK 2.4.0
65 #if (!wxCHECK_VERSION(2, 4, 0))
66 wxWindow* wxGetTopLevelParent(wxWindow *win)
67 {
68     while ( win && !win->IsTopLevel() )
69          win = win->GetParent();
70     return win;
71 }
72 #endif
73
74 // To access objc calls on cocoa
75 #ifdef __WXCOCOA__
76 #ifdef VTK_USE_COCOA
77 #import <Cocoa/Cocoa.h>
78 // This trick is no longer need in VTK CVS, should get rid of that:
79 #define id Id
80 #else
81 #error Build mismatch you need both wxWidgets and VTK to be configure against Cocoa to work
82 #endif //VTK_USE_COCOA
83 #endif //__WXCOCOA__
84
85
86
87 //EED 2017-09-16 Migration wxWidgets 2.8 to 3.0
88 #if wxMAJOR_VERSION <= 2
89         #ifdef __WXGTK__
90                 #    include <gdk/gdkx.h> // GDK_WINDOW_XWINDOW is found here in wxWidgets 2.8.0
91                 #    include "gdk/gdkprivate.h"
92                 #if wxCHECK_VERSION(2, 8, 0)
93                         #ifdef __WXGTK20__
94                                 #include <wx/gtk/win_gtk.h>
95                         #else
96                                 #include <wx/gtk1/win_gtk.h>
97                         #endif
98                 #else
99                         #include <wx/gtk/win_gtk.h>
100                 #endif
101                 #define GetXWindow(wxwin) (wxwin)->m_wxwindow ? \
102                                           GDK_WINDOW_XWINDOW(GTK_PIZZA((wxwin)->m_wxwindow)->bin_window) : \
103                                           GDK_WINDOW_XWINDOW((wxwin)->m_widget->window)
104         #endif
105 #else
106         #ifdef __WXGTK__
107             #include <gdk/gdkx.h>
108             #include <gtk/gtk.h>
109         #endif
110 #endif
111
112
113
114
115
116 #ifdef __WXX11__
117 #include "wx/x11/privx.h"
118 #define GetXWindow(wxwin)   ((Window)(wxwin)->GetHandle())
119 #endif
120
121
122 //For more info on this class please go to:
123 //http://wxvtk.sf.net
124 //This hack is for some buggy wxGTK version:
125 #if wxCHECK_VERSION(2, 3, 2) && !wxCHECK_VERSION(2, 4, 1) && defined(__WXGTK__)
126 #  define WX_USE_X_CAPTURE 0
127 #else
128 #  define WX_USE_X_CAPTURE 1
129 #endif
130
131 #define ID_wxVTKRenderWindowInteractor_TIMER 1001
132
133 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
134 IMPLEMENT_DYNAMIC_CLASS(wxVTKRenderWindowInteractor, wxGLCanvas)
135 #else
136 IMPLEMENT_DYNAMIC_CLASS(wxVTKRenderWindowInteractor, wxWindow)
137 #endif  //__WXGTK__
138
139 //---------------------------------------------------------------------------
140 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
141 BEGIN_EVENT_TABLE(wxVTKRenderWindowInteractor, wxGLCanvas)
142 #else
143 BEGIN_EVENT_TABLE(wxVTKRenderWindowInteractor, wxWindow)
144 #endif //__WXGTK__
145   //refresh window by doing a Render
146   EVT_PAINT       (wxVTKRenderWindowInteractor::OnPaint)
147   EVT_ERASE_BACKGROUND(wxVTKRenderWindowInteractor::OnEraseBackground)
148   EVT_MOTION      (wxVTKRenderWindowInteractor::OnMotion)
149
150   //Bind the events to the event converters
151   EVT_LEFT_DOWN   (wxVTKRenderWindowInteractor::OnButtonDown)
152   EVT_MIDDLE_DOWN (wxVTKRenderWindowInteractor::OnButtonDown)
153   EVT_RIGHT_DOWN  (wxVTKRenderWindowInteractor::OnButtonDown)
154   EVT_LEFT_UP     (wxVTKRenderWindowInteractor::OnButtonUp)
155   EVT_MIDDLE_UP   (wxVTKRenderWindowInteractor::OnButtonUp)
156   EVT_RIGHT_UP    (wxVTKRenderWindowInteractor::OnButtonUp)
157 #if !(VTK_MAJOR_VERSION == 3 && VTK_MINOR_VERSION == 1)
158   EVT_ENTER_WINDOW(wxVTKRenderWindowInteractor::OnEnter)
159   EVT_LEAVE_WINDOW(wxVTKRenderWindowInteractor::OnLeave)
160   EVT_MOUSEWHEEL  (wxVTKRenderWindowInteractor::OnMouseWheel)
161   EVT_KEY_DOWN    (wxVTKRenderWindowInteractor::OnKeyDown)
162   EVT_KEY_UP      (wxVTKRenderWindowInteractor::OnKeyUp)
163   EVT_CHAR        (wxVTKRenderWindowInteractor::OnChar)
164 #endif
165   EVT_TIMER       (ID_wxVTKRenderWindowInteractor_TIMER, wxVTKRenderWindowInteractor::OnTimer)
166   EVT_SIZE        (wxVTKRenderWindowInteractor::OnSize)
167 END_EVENT_TABLE()
168
169 vtkCxxRevisionMacro(wxVTKRenderWindowInteractor, "$Revision: 1.7 $")
170 vtkInstantiatorNewMacro(wxVTKRenderWindowInteractor)
171
172 //---------------------------------------------------------------------------
173 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
174 #if (wxCHECK_VERSION(2, 8, 0))
175 wxVTKRenderWindowInteractor::wxVTKRenderWindowInteractor() : wxGLCanvas(0, -1, wxDefaultPosition), vtkRenderWindowInteractor()
176 #else
177 wxVTKRenderWindowInteractor::wxVTKRenderWindowInteractor() : wxGLCanvas(), vtkRenderWindowInteractor()
178 #endif
179 #else
180 wxVTKRenderWindowInteractor::wxVTKRenderWindowInteractor() : wxWindow(), vtkRenderWindowInteractor()
181 #endif //__WXGTK__
182       , timer(this, ID_wxVTKRenderWindowInteractor_TIMER)
183       , ActiveButton(wxEVT_NULL)
184       , RenderAllowed(0)
185       , Stereo(0)
186       , Handle(0)
187       , Created(true)
188       , RenderWhenDisabled(1)
189       , UseCaptureMouse(0)
190 {
191 #ifdef VTK_DEBUG_LEAKS
192   vtkDebugLeaks::ConstructClass("wxVTKRenderWindowInteractor");
193 #endif
194   this->RenderWindow = NULL;
195   this->SetRenderWindow(vtkRenderWindow::New());
196   this->RenderWindow->Delete();
197 }
198 //---------------------------------------------------------------------------
199 wxVTKRenderWindowInteractor::wxVTKRenderWindowInteractor(wxWindow *parent,
200                                                          wxWindowID id,
201                                                          const wxPoint &pos,
202                                                          const wxSize &size,
203                                                          long style,
204                                                          const wxString &name)
205 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
206       : wxGLCanvas(parent, id, pos, size, style, name), vtkRenderWindowInteractor()
207 #else
208       : wxWindow(parent, id, pos, size, style, name), vtkRenderWindowInteractor()
209 #endif //__WXGTK__
210       , timer(this, ID_wxVTKRenderWindowInteractor_TIMER)
211       , ActiveButton(wxEVT_NULL)
212       , RenderAllowed(0)
213       , Stereo(0)
214       , Handle(0)
215       , Created(true)
216       , RenderWhenDisabled(1)
217       , UseCaptureMouse(0)
218 {
219 #ifdef VTK_DEBUG_LEAKS
220   vtkDebugLeaks::ConstructClass("wxVTKRenderWindowInteractor");
221 #endif
222   this->RenderWindow = NULL;
223   this->SetRenderWindow(vtkRenderWindow::New());
224   this->RenderWindow->Delete();
225 #ifdef __WXMAC__
226   // On Mac (Carbon) we don't get notified of the initial window size with an EVT_SIZE event,
227   // so we update the size information of the interactor/renderwindow here
228   this->UpdateSize(size.x, size.y);
229 #endif
230 }
231 //---------------------------------------------------------------------------
232 wxVTKRenderWindowInteractor::~wxVTKRenderWindowInteractor()
233 {
234   SetRenderWindow(NULL);
235   SetInteractorStyle(NULL);
236 }
237 //---------------------------------------------------------------------------
238 wxVTKRenderWindowInteractor * wxVTKRenderWindowInteractor::New()
239 {
240   // we don't make use of the objectfactory, because we're not registered
241   return new wxVTKRenderWindowInteractor;
242 }
243 //---------------------------------------------------------------------------
244 void wxVTKRenderWindowInteractor::Initialize()
245 {
246   int *size = RenderWindow->GetSize();
247   // enable everything and start rendering
248   Enable();
249   //RenderWindow->Start();
250
251   // set the size in the render window interactor
252   Size[0] = size[0];
253   Size[1] = size[1];
254
255   // this is initialized
256   Initialized = 1;
257 }
258 //---------------------------------------------------------------------------
259 void wxVTKRenderWindowInteractor::Enable()
260 {
261   // if already enabled then done
262   if (Enabled)
263     return;
264
265   // that's it
266   Enabled = 1;
267 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
268   SetCurrent();
269 #endif
270   Modified();
271 }
272 //---------------------------------------------------------------------------
273 bool wxVTKRenderWindowInteractor::Enable(bool enable)
274 {
275 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
276   return wxGLCanvas::Enable(enable);
277 #else
278   return wxWindow::Enable(enable);
279 #endif
280 }
281 //---------------------------------------------------------------------------
282 void wxVTKRenderWindowInteractor::Disable()
283 {
284   // if already disabled then done
285   if (!Enabled)
286     return;
287
288   // that's it (we can't remove the event handler like it should be...)
289   Enabled = 0;
290   Modified();
291 }
292 //---------------------------------------------------------------------------
293 void wxVTKRenderWindowInteractor::Start()
294 {
295   // the interactor cannot control the event loop
296   vtkErrorMacro( << "wxVTKRenderWindowInteractor::Start() "
297     "interactor cannot control event loop.");
298 }
299 //---------------------------------------------------------------------------
300 void wxVTKRenderWindowInteractor::UpdateSize(int x, int y)
301 {
302   if( RenderWindow )
303   {
304     // if the size changed tell render window
305     if ( x != Size[0] || y != Size[1] )
306     {
307       // adjust our (vtkRenderWindowInteractor size)
308       Size[0] = x;
309       Size[1] = y;
310       // and our RenderWindow's size
311       RenderWindow->SetSize(x, y);
312     }
313   }
314 }
315 //---------------------------------------------------------------------------
316 int wxVTKRenderWindowInteractor::CreateTimer(int WXUNUSED(timertype))
317 {
318   // it's a one shot timer
319   if (!timer.Start(10, TRUE))
320     assert(false);
321
322   return 1;
323   
324 }
325 //---------------------------------------------------------------------------
326 int wxVTKRenderWindowInteractor::DestroyTimer()
327 {
328   // do nothing
329   return 1;
330 }
331 //---------------------------------------------------------------------------
332 void wxVTKRenderWindowInteractor::OnTimer(wxTimerEvent& WXUNUSED(event))
333 {
334   if (!Enabled)
335     return;
336     
337 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
338     // new style
339     InvokeEvent(vtkCommand::TimerEvent, NULL);
340 #else
341     // old style
342     InteractorStyle->OnTimer();
343 #endif
344 }
345
346 //---------------------------------------------------------------------------
347 // NOTE on implementation:
348 // Bad luck you ended up in the only tricky place of this code.
349 // A few note, wxWidgets still refuse to provide such convenient method
350 // so I have to maintain it myself, eventhough this is completely integrated
351 // in wxPython...
352 // Anyway if this happen to break for you then compare to a recent version of wxPython
353 // and look for the function long wxPyGetWinHandle(wxWindow* win)
354 // in wxPython/src/helpers.cpp
355 long wxVTKRenderWindowInteractor::GetHandleHack()
356 {
357   //helper function to hide the MSW vs GTK stuff
358   long handle_tmp = 0;
359
360 // __WXMSW__ is for Win32
361 //__WXMAC__ stands for using Carbon C-headers, using either the CarbonLib/CFM or the native Mach-O builds (which then also use the latest features available)
362 // __WXGTK__ is for both gtk 1.2.x and gtk 2.x
363 #if defined(__WXMSW__) || defined(__WXMAC__)
364     handle_tmp = (long)this->GetHandle();
365 #endif //__WXMSW__
366
367 //__WXCOCOA__ stands for using the objective-c Cocoa API
368 #ifdef __WXCOCOA__
369    // Here is how to find the NSWindow
370    wxTopLevelWindow* toplevel = dynamic_cast<wxTopLevelWindow*>(
371      wxGetTopLevelParent( this ) );
372    if (toplevel != NULL )    
373    {
374      handle_tmp = (long)toplevel->GetNSWindow();
375    }
376    // The NSView will be deducted from 
377    // [(NSWindow*)Handle contentView]
378    // if only I knew how to write that in c++
379 #endif //__WXCOCOA__
380
381     // Find and return the actual X-Window.
382 #if defined(__WXGTK__) || defined(__WXX11__)
383
384         //EED 2017-09-16 Migration wxWidgets 2.8 to 3.0
385         #if wxMAJOR_VERSION <= 2
386                 return (long)GetXWindow(this);
387         #else
388                 GdkWindow* Win = gtk_widget_get_window( (GtkWidget *) GetHandle() );
389                 return (long int)GDK_WINDOW_XDISPLAY(Win);
390         #endif
391
392 #endif
393
394 //#ifdef __WXMOTIF__
395 //    handle_tmp = (long)this->GetXWindow();
396 //#endif
397
398   return handle_tmp;
399 }
400 //---------------------------------------------------------------------------
401 void wxVTKRenderWindowInteractor::OnPaint(wxPaintEvent& WXUNUSED(event))
402 {
403   //must always be here
404   wxPaintDC pDC(this);
405
406   //do it here rather than in the cstor: this is safer.
407   if(!Handle)
408   {
409     Handle = GetHandleHack();
410     RenderWindow->SetWindowId(reinterpret_cast<void *>(Handle));
411 #ifdef __WXMSW__
412     RenderWindow->SetParentId(reinterpret_cast<void *>(this->GetParent()->GetHWND()));
413 #endif //__WXMSW__
414   }
415   // get vtk to render to the wxWindows
416   Render();
417 #ifdef __WXMAC__
418   // This solves a problem with repainting after a window resize
419   // See also: http://sourceforge.net/mailarchive/forum.php?thread_id=31690967&forum_id=41789
420   vtkCarbonRenderWindow* rwin = vtkCarbonRenderWindow::SafeDownCast(RenderWindow);
421   if( rwin )
422   {
423     rwin->UpdateGLRegion();
424   }
425 #endif
426 }
427 //---------------------------------------------------------------------------
428 void wxVTKRenderWindowInteractor::OnEraseBackground(wxEraseEvent &event)
429 {
430   //turn off background erase to reduce flickering on MSW
431   event.Skip(false);
432 }
433 //---------------------------------------------------------------------------
434 void wxVTKRenderWindowInteractor::OnSize(wxSizeEvent& WXUNUSED(event))
435 {
436   int w, h;
437   GetClientSize(&w, &h);
438   UpdateSize(w, h);
439
440   if (!Enabled) 
441     {
442     return;
443     }
444
445 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
446   InvokeEvent(vtkCommand::ConfigureEvent, NULL);
447 #endif
448   //this will check for Handle
449   //Render();
450 }
451 //---------------------------------------------------------------------------
452 void wxVTKRenderWindowInteractor::OnMotion(wxMouseEvent &event)
453 {
454  if (!Enabled) 
455     {
456     return;
457     }
458 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
459   SetEventInformationFlipY(event.GetX(), event.GetY(), 
460     event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
461
462   InvokeEvent(vtkCommand::MouseMoveEvent, NULL);
463 #else
464   InteractorStyle->OnMouseMove(event.ControlDown(), event.ShiftDown(),
465     event.GetX(), Size[1] - event.GetY() - 1);
466 #endif
467 }
468 //---------------------------------------------------------------------------
469 #if !(VTK_MAJOR_VERSION == 3 && VTK_MINOR_VERSION == 1)
470 void wxVTKRenderWindowInteractor::OnEnter(wxMouseEvent &event)
471 {
472   if (!Enabled) 
473     {
474     return;
475     }
476
477 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
478     // new style
479   SetEventInformationFlipY(event.GetX(), event.GetY(), 
480       event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
481
482   InvokeEvent(vtkCommand::EnterEvent, NULL);
483 #else
484     // old style
485   InteractorStyle->OnEnter(event.ControlDown(), event.ShiftDown(),
486       event.GetX(), Size[1] - event.GetY() - 1);  
487 #endif
488 }
489 //---------------------------------------------------------------------------
490 void wxVTKRenderWindowInteractor::OnLeave(wxMouseEvent &event)
491 {
492   if (!Enabled) 
493     {
494     return;
495     }
496
497 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
498     // new style
499   SetEventInformationFlipY(event.GetX(), event.GetY(), 
500       event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
501
502   InvokeEvent(vtkCommand::LeaveEvent, NULL);
503 #else
504     // old style
505   InteractorStyle->OnLeave(event.ControlDown(), event.ShiftDown(),
506       event.GetX(), Size[1] - event.GetY() - 1);  
507 #endif
508 }
509 //---------------------------------------------------------------------------
510 void wxVTKRenderWindowInteractor::OnKeyDown(wxKeyEvent &event)
511 {
512   if (!Enabled) 
513     {
514     return;
515     }
516
517 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
518     // new style
519   int keycode = event.GetKeyCode();
520   char key = '\0';
521   if (((unsigned int)keycode) < 256)
522   {
523     // TODO: Unicode in non-Unicode mode ??
524     key = (char)keycode;
525   }
526
527   // we don't get a valid mouse position inside the key event on every platform
528   // so we retrieve the mouse position explicitly and pass it along
529   wxPoint mousePos = ScreenToClient(wxGetMousePosition());
530   SetEventInformationFlipY(mousePos.x, mousePos.y, 
531                            event.ControlDown(), event.ShiftDown(), key, 0, NULL);
532   InvokeEvent(vtkCommand::KeyPressEvent, NULL);
533 #else
534   InteractorStyle->OnKeyDown(event.ControlDown(), event.ShiftDown(), 
535     event.GetKeyCode(), 1);
536 #endif
537   event.Skip();
538 }
539 //---------------------------------------------------------------------------
540 void wxVTKRenderWindowInteractor::OnKeyUp(wxKeyEvent &event)
541 {
542   if (!Enabled) 
543     {
544     return;
545     }
546
547 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
548     // new style
549   int keycode = event.GetKeyCode();
550   char key = '\0';
551   if (((unsigned int)keycode) < 256)
552   {
553     // TODO: Unicode in non-Unicode mode ??
554     key = (char)keycode;
555   }
556
557   // we don't get a valid mouse position inside the key event on every platform
558   // so we retrieve the mouse position explicitly and pass it along
559   wxPoint mousePos = ScreenToClient(wxGetMousePosition());
560   SetEventInformationFlipY(mousePos.x, mousePos.y, 
561                            event.ControlDown(), event.ShiftDown(), key, 0, NULL);
562   InvokeEvent(vtkCommand::KeyReleaseEvent, NULL);
563 #else
564   InteractorStyle->OnKeyUp(event.ControlDown(), event.ShiftDown(), 
565     event.GetKeyCode(), 1);
566 #endif
567   event.Skip();
568 }
569 #endif //!(VTK_MAJOR_VERSION == 3 && VTK_MINOR_VERSION == 1)
570  //---------------------------------------------------------------------------
571 void wxVTKRenderWindowInteractor::OnChar(wxKeyEvent &event)
572 {
573   if (!Enabled) 
574     {
575     return;
576     }
577     
578 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
579   // new style
580   int keycode = event.GetKeyCode();
581   char key = '\0';
582   if (((unsigned int)keycode) < 256)
583     {
584     // TODO: Unicode in non-Unicode mode ??
585     key = (char)keycode;
586     }
587
588   // we don't get a valid mouse position inside the key event on every platform
589   // so we retrieve the mouse position explicitly and pass it along
590   wxPoint mousePos = ScreenToClient(wxGetMousePosition());
591   SetEventInformationFlipY(mousePos.x, mousePos.y, 
592                            event.ControlDown(), event.ShiftDown(), key, 0, NULL);
593   InvokeEvent(vtkCommand::CharEvent, NULL);
594 #endif
595   event.Skip();
596 }
597 //---------------------------------------------------------------------------
598 void wxVTKRenderWindowInteractor::OnButtonDown(wxMouseEvent &event)
599 {
600   if (!Enabled || (ActiveButton != wxEVT_NULL))
601     {
602     return;
603     }
604   ActiveButton = event.GetEventType();
605
606     // On Mac (Carbon) and Windows we don't automatically get the focus when
607     // you click inside the window
608     // we therefore set the focus explicitly
609     // Apparently we need that on linux (GTK) too:
610     this->SetFocus();
611
612 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
613   SetEventInformationFlipY(event.GetX(), event.GetY(), 
614     event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
615 #endif
616
617   if(event.RightDown())
618   {
619 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
620     // new style
621     InvokeEvent(vtkCommand::RightButtonPressEvent, NULL);
622 #else            
623     // old style
624     InteractorStyle->OnRightButtonDown(event.ControlDown(), event.ShiftDown(),
625       event.GetX(), Size[1] - event.GetY() - 1);
626 #endif
627   }
628   else if(event.LeftDown())
629   {
630 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
631     // new style
632     InvokeEvent(vtkCommand::LeftButtonPressEvent, NULL);
633 #else            
634     // old style
635     InteractorStyle->OnLeftButtonDown(event.ControlDown(),  event.ShiftDown(),
636       event.GetX(), Size[1] - event.GetY() - 1);
637 #endif
638   }
639   else if(event.MiddleDown())
640   {
641 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
642     // new style
643     InvokeEvent(vtkCommand::MiddleButtonPressEvent, NULL);
644 #else            
645     // old style
646     InteractorStyle->OnMiddleButtonDown(event.ControlDown(), event.ShiftDown(),
647       event.GetX(), Size[1] - event.GetY() - 1);
648 #endif
649   }
650   //save the button and capture mouse until the button is released
651   //Only if :
652   //1. it is possible (WX_USE_X_CAPTURE)
653   //2. user decided to.
654   if ((ActiveButton != wxEVT_NULL) && WX_USE_X_CAPTURE && UseCaptureMouse)
655   {
656     CaptureMouse();
657   }
658 }
659 //---------------------------------------------------------------------------
660 void wxVTKRenderWindowInteractor::OnButtonUp(wxMouseEvent &event)
661 {
662   //EVT_xxx_DOWN == EVT_xxx_UP - 1
663   //This is only needed if two mouse buttons are pressed at the same time.
664   //In wxWindows 2.4 and later: better use of wxMOUSE_BTN_RIGHT or 
665   //wxEVT_COMMAND_RIGHT_CLICK
666   if (!Enabled || (ActiveButton != (event.GetEventType()-1))) 
667     {
668     return;
669     }
670
671 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
672   SetEventInformationFlipY(event.GetX(), event.GetY(), 
673     event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
674 #endif
675   
676   if(ActiveButton == wxEVT_RIGHT_DOWN)
677   {
678 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
679     // new style
680     InvokeEvent(vtkCommand::RightButtonReleaseEvent, NULL);
681 #else            
682     // old style
683     InteractorStyle->OnRightButtonUp(event.ControlDown(), event.ShiftDown(),
684       event.GetX(), Size[1] - event.GetY() - 1);
685 #endif
686   }
687   else if(ActiveButton == wxEVT_LEFT_DOWN)
688   {
689 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
690     // new style
691     InvokeEvent(vtkCommand::LeftButtonReleaseEvent, NULL);
692 #else            
693     // old style
694     InteractorStyle->OnLeftButtonUp(event.ControlDown(), event.ShiftDown(),
695       event.GetX(), Size[1] - event.GetY() - 1);
696 #endif
697   }
698   else if(ActiveButton == wxEVT_MIDDLE_DOWN)
699   {
700 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
701     // new style
702     InvokeEvent(vtkCommand::MiddleButtonReleaseEvent, NULL);
703 #else            
704     // old style
705     InteractorStyle->OnMiddleButtonUp(event.ControlDown(), event.ShiftDown(),
706       event.GetX(), Size[1] - event.GetY() - 1);
707 #endif
708   }
709   //if the ActiveButton is realeased, then release mouse capture
710   if ((ActiveButton != wxEVT_NULL) && WX_USE_X_CAPTURE && UseCaptureMouse)
711   {
712     ReleaseMouse();
713   }
714   ActiveButton = wxEVT_NULL;
715 }
716 //---------------------------------------------------------------------------
717 void wxVTKRenderWindowInteractor::OnMouseWheel(wxMouseEvent& event)
718 {
719 // Mouse wheel was only added after VTK 4.4 (I think...)
720 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 2)
721   // new style
722   //Set vtk event information ... The numebr of wheel rotations is stored in
723   //the x varible.  y varible is zero
724   SetEventInformationFlipY(event.GetWheelRotation() / event.GetWheelDelta(), 0, 
725                            event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
726   if(event.GetWheelRotation() > 0)
727     {
728       //Send event to VTK
729       InvokeEvent(vtkCommand::MouseWheelForwardEvent, NULL);
730     }
731   else
732     {
733       //Send event to VTK
734       InvokeEvent(vtkCommand::MouseWheelBackwardEvent, NULL);
735     }
736 #endif
737     
738 }
739
740 //---------------------------------------------------------------------------
741 void wxVTKRenderWindowInteractor::Render()
742 {
743   RenderAllowed = 1;
744   if (!RenderWhenDisabled)
745     {
746     //the user doesn't want us to render when the toplevel frame
747     //is disabled - first find the top level parent
748     wxWindow *topParent = wxGetTopLevelParent(this);
749     if (topParent)
750       {
751       //if it exists, check whether it's enabled
752       //if it's not enabeld, RenderAllowed will be false
753       RenderAllowed = topParent->IsEnabled();
754       }
755     }
756
757   if (RenderAllowed)
758     {
759     if(Handle && (Handle == GetHandleHack()) )
760       {
761       RenderWindow->Render();
762       }
763 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 2)
764     else if(GetHandleHack())
765       {
766       //this means the user has reparented us; let's adapt to the
767       //new situation by doing the WindowRemap dance
768       //store the new situation
769       Handle = GetHandleHack();
770       RenderWindow->SetNextWindowId(reinterpret_cast<void *>(Handle));
771       RenderWindow->WindowRemap();
772       RenderWindow->Render();
773       }
774 #endif
775     }
776 }
777 //---------------------------------------------------------------------------
778 void wxVTKRenderWindowInteractor::SetRenderWhenDisabled(int newValue)
779 {
780   //Change value of __RenderWhenDisabled ivar.
781   //If __RenderWhenDisabled is false (the default), this widget will not
782   //call Render() on the RenderWindow if the top level frame (i.e. the
783   //containing frame) has been disabled.
784
785   //This prevents recursive rendering during wxSafeYield() calls.
786   //wxSafeYield() can be called during the ProgressMethod() callback of
787   //a VTK object to have progress bars and other GUI elements updated -
788   //it does this by disabling all windows (disallowing user-input to
789   //prevent re-entrancy of code) and then handling all outstanding
790   //GUI events.
791         
792   //However, this often triggers an OnPaint() method for wxVTKRWIs,
793   //resulting in a Render(), resulting in Update() being called whilst
794   //still in progress.
795
796   RenderWhenDisabled = (bool)newValue;
797 }
798 //---------------------------------------------------------------------------
799 //
800 // Set the variable that indicates that we want a stereo capable window
801 // be created. This method can only be called before a window is realized.
802 //
803 void wxVTKRenderWindowInteractor::SetStereo(int capable)
804 {
805   if (Stereo != capable)
806     {
807     Stereo = capable;
808     RenderWindow->StereoCapableWindowOn();
809     RenderWindow->SetStereoTypeToCrystalEyes();
810     Modified();
811     }
812 }
813
814 //---------------------------------------------------------------------------
815 //
816 //
817 void wxVTKRenderWindowInteractor::PrintSelf(ostream& os, vtkIndent indent)
818 {
819   this->Superclass::PrintSelf(os, indent);
820 }
821