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