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