]> Creatis software - creaMaracasVisu.git/blob - lib/maracasVisuLib/src/interface/wxWindows/widgets/wxVTKRenderWindowInteractor.cxx
changes in viewers
[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/08/25 17:51:12 $
7   Version:   $Revision: 1.4 $
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   if (!Enabled || (ActiveButton != wxEVT_NULL))
545     {
546     return;
547     }
548   ActiveButton = event.GetEventType();
549
550 #if VTK_MAJOR_VERSION == 5 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
551   SetEventInformationFlipY(event.GetX(), event.GetY(), 
552     event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
553 #endif
554
555   if(event.RightDown())
556   {
557 #if VTK_MAJOR_VERSION == 5 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
558     // new style
559     InvokeEvent(vtkCommand::RightButtonPressEvent, NULL);
560 #else            
561     // old style
562     InteractorStyle->OnRightButtonDown(event.ControlDown(), event.ShiftDown(),
563       event.GetX(), Size[1] - event.GetY() - 1);
564 #endif
565   }
566   else if(event.LeftDown())
567   {
568 #if VTK_MAJOR_VERSION == 5 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
569     // new style
570     InvokeEvent(vtkCommand::LeftButtonPressEvent, NULL);
571 #else            
572     // old style
573     InteractorStyle->OnLeftButtonDown(event.ControlDown(),  event.ShiftDown(),
574       event.GetX(), Size[1] - event.GetY() - 1);
575 #endif
576   }
577   else if(event.MiddleDown())
578   {
579 #if VTK_MAJOR_VERSION == 5 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
580     // new style
581     InvokeEvent(vtkCommand::MiddleButtonPressEvent, NULL);
582 #else            
583     // old style
584     InteractorStyle->OnMiddleButtonDown(event.ControlDown(), event.ShiftDown(),
585       event.GetX(), Size[1] - event.GetY() - 1);
586 #endif
587   }
588   //save the button and capture mouse until the button is released
589   //Only if :
590   //1. it is possible (WX_USE_X_CAPTURE)
591   //2. user decided to.
592   if ((ActiveButton != wxEVT_NULL) && WX_USE_X_CAPTURE && UseCaptureMouse)
593   {
594     CaptureMouse();
595   }
596 }
597 //---------------------------------------------------------------------------
598 void wxVTKRenderWindowInteractor::OnButtonUp(wxMouseEvent &event)
599 {
600   //EVT_xxx_DOWN == EVT_xxx_UP - 1
601   //This is only needed if two mouse buttons are pressed at the same time.
602   //In wxWindows 2.4 and later: better use of wxMOUSE_BTN_RIGHT or 
603   //wxEVT_COMMAND_RIGHT_CLICK
604   if (!Enabled || (ActiveButton != (event.GetEventType()-1))) 
605     {
606     return;
607     }
608
609 #if VTK_MAJOR_VERSION == 5 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
610   SetEventInformationFlipY(event.GetX(), event.GetY(), 
611     event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
612 #endif
613   
614   if(ActiveButton == wxEVT_RIGHT_DOWN)
615   {
616 #if VTK_MAJOR_VERSION == 5 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
617     // new style
618     InvokeEvent(vtkCommand::RightButtonReleaseEvent, NULL);
619 #else            
620     // old style
621     InteractorStyle->OnRightButtonUp(event.ControlDown(), event.ShiftDown(),
622       event.GetX(), Size[1] - event.GetY() - 1);
623 #endif
624   }
625   else if(ActiveButton == wxEVT_LEFT_DOWN)
626   {
627 #if VTK_MAJOR_VERSION == 5 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
628     // new style
629     InvokeEvent(vtkCommand::LeftButtonReleaseEvent, NULL);
630 #else            
631     // old style
632     InteractorStyle->OnLeftButtonUp(event.ControlDown(), event.ShiftDown(),
633       event.GetX(), Size[1] - event.GetY() - 1);
634 #endif
635   }
636   else if(ActiveButton == wxEVT_MIDDLE_DOWN)
637   {
638 #if VTK_MAJOR_VERSION == 5 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
639     // new style
640     InvokeEvent(vtkCommand::MiddleButtonReleaseEvent, NULL);
641 #else            
642     // old style
643     InteractorStyle->OnMiddleButtonUp(event.ControlDown(), event.ShiftDown(),
644       event.GetX(), Size[1] - event.GetY() - 1);
645 #endif
646   }
647   //if the ActiveButton is realeased, then release mouse capture
648   if ((ActiveButton != wxEVT_NULL) && WX_USE_X_CAPTURE && UseCaptureMouse)
649   {
650     ReleaseMouse();
651   }
652   ActiveButton = wxEVT_NULL;
653 }
654 //---------------------------------------------------------------------------
655 void wxVTKRenderWindowInteractor::OnMouseWheel(wxMouseEvent& event)
656 {
657 // Mouse wheel was only added after VTK 4.4 (I think...)
658 #if VTK_MAJOR_VERSION == 5 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 2)
659   // new style
660   //Set vtk event information ... The numebr of wheel rotations is stored in
661   //the x varible.  y varible is zero
662   SetEventInformationFlipY(event.GetWheelRotation() / event.GetWheelDelta(), 0, 
663                            event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
664   if(event.GetWheelRotation() > 0)
665     {
666       //Send event to VTK
667 // EED
668 //      InvokeEvent(vtkCommand::MouseWheelForwardEvent, NULL);
669     }
670   else
671     {
672       //Send event to VTK
673 // EED
674 //      InvokeEvent(vtkCommand::MouseWheelBackwardEvent, NULL);
675     }
676 #endif
677     
678 }
679
680 //---------------------------------------------------------------------------
681 void wxVTKRenderWindowInteractor::Render() throw (char*)
682 {
683   RenderAllowed = 1;
684   if (!RenderWhenDisabled)
685     {
686     //the user doesn't want us to render when the toplevel frame
687     //is disabled - first find the top level parent
688     wxWindow *topParent = wxGetTopLevelParent(this);
689     if (topParent)
690       {
691       //if it exists, check whether it's enabled
692       //if it's not enabeld, RenderAllowed will be false
693       RenderAllowed = topParent->IsEnabled();
694       }
695     }
696
697   if (RenderAllowed)
698     {
699     if(Handle && (Handle == GetHandleHack()) )
700       {
701                   if(RenderWindow!=NULL){
702                         RenderWindow->Render();
703                   }else{
704                           throw "wxVTKRenderWindowInteractor::Render(){RenderWindow not set}";
705                   }
706       }
707 #if VTK_MAJOR_VERSION == 5 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 2)
708     else if(GetHandleHack())
709       {
710       //this means the user has reparented us; let's adapt to the
711       //new situation by doing the WindowRemap dance
712       //store the new situation
713                   if(RenderWindow!=NULL){
714                         Handle = GetHandleHack();
715                         RenderWindow->SetNextWindowId(reinterpret_cast<void *>(Handle));
716                         RenderWindow->WindowRemap();
717                         RenderWindow->Render();
718                   }
719       }
720 #endif
721     }
722 }
723 //---------------------------------------------------------------------------
724 void wxVTKRenderWindowInteractor::SetRenderWhenDisabled(int newValue)
725 {
726   //Change value of __RenderWhenDisabled ivar.
727   //If __RenderWhenDisabled is false (the default), this widget will not
728   //call Render() on the RenderWindow if the top level frame (i.e. the
729   //containing frame) has been disabled.
730
731   //This prevents recursive rendering during wxSafeYield() calls.
732   //wxSafeYield() can be called during the ProgressMethod() callback of
733   //a VTK object to have progress bars and other GUI elements updated -
734   //it does this by disabling all windows (disallowing user-input to
735   //prevent re-entrancy of code) and then handling all outstanding
736   //GUI events.
737         
738   //However, this often triggers an OnPaint() method for wxVTKRWIs,
739   //resulting in a Render(), resulting in Update() being called whilst
740   //still in progress.
741
742   RenderWhenDisabled = (bool)newValue;
743 }
744 //---------------------------------------------------------------------------
745 //
746 // Set the variable that indicates that we want a stereo capable window
747 // be created. This method can only be called before a window is realized.
748 //
749 void wxVTKRenderWindowInteractor::SetStereo(int capable)
750 {
751   if (Stereo != capable)
752     {
753     Stereo = capable;
754     RenderWindow->StereoCapableWindowOn();
755     RenderWindow->SetStereoTypeToCrystalEyes();
756     Modified();
757     }
758 }
759
760 //---------------------------------------------------------------------------
761 //
762 //
763 void wxVTKRenderWindowInteractor::PrintSelf(ostream& os, vtkIndent indent)
764 {
765   this->Superclass::PrintSelf(os, indent);
766 }
767
768
769 #if defined(_WIN32)
770 const char * wxVTKRenderWindowInteractor::GetClassName() const
771 {
772   return "wxVTKRenderWindowInteractor";
773 }
774 #endif //_WIN32
775