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