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