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