]> Creatis software - bbtk.git/blob - packages/wxvtk/src/wxVTKRenderWindowInteractor.cxx
#3127 BBTK Feature New Normal - branch changeWx28to30 compilation with wxWidgets3
[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$
32   Language:  C++
33   Date:      $Date$
34   Version:   $Revision$
35
36   Copyright (c) 1993-2002 Ken Martin, Will Schroeder, Bill Lorensen 
37   All rights reserved.
38   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
39
40      This software is distributed WITHOUT ANY WARRANTY; without even 
41      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
42      PURPOSE.  See the above copyright notice for more information.
43
44 =========================================================================*/
45
46 #include <assert.h>
47
48 #include "wxVTKRenderWindowInteractor.h"
49
50 //This is needed for vtk 3.1 :
51 #ifndef VTK_MAJOR_VERSION
52 #  include "vtkVersion.h"
53 #endif
54
55 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
56 #  include "vtkCommand.h"
57 #else
58 #  include "vtkInteractorStyle.h"
59 #endif
60 #include "vtkDebugLeaks.h"
61
62 // AKT: wxOSX 2.9.x defines __WXOSX_COCOA__ rather than __WXCOCOA__
63 #ifdef __WXOSX_COCOA__
64 #define __WXCOCOA__
65 #endif
66
67 #if defined(__WXMAC__) && wxCHECK_VERSION(2,9,0)
68     // ControlDown has been changed to mean Command key down
69     #define ControlDown RawControlDown
70 #endif
71
72 #ifdef __WXMAC__
73 #ifdef __WXCOCOA__
74 #include "vtkCocoaRenderWindow.h"
75 #else
76 #include "vtkCarbonRenderWindow.h"
77 #endif
78 #endif
79
80 //=======================================================================
81 // LG : NAMESPACE IS NECESSARY TO AVOID CONFLICTING SYMBOLS IN DYN LIBS
82 namespace bbwxvtk
83 {
84
85
86 //Keep this for compatibilty reason, this was introduced in wxGTK 2.4.0
87 #if (!wxCHECK_VERSION(2, 4, 0))
88 wxWindow* wxGetTopLevelParent(wxWindow *win)
89 {
90     while ( win && !win->IsTopLevel() )
91          win = win->GetParent();
92     return win;
93 }
94 #endif
95 }
96 // LG : EO namespace bbwxvtk
97 //=======================================================================
98
99 // To access objc calls on cocoa
100 #ifdef __WXCOCOA__
101 #ifdef VTK_USE_COCOA
102 #import <Cocoa/Cocoa.h>
103 // This trick is no longer need in VTK CVS, should get rid of that:
104 #define id Id
105 #else
106 #error Build mismatch you need both wxWidgets and VTK to be configure against Cocoa to work
107 #endif //VTK_USE_COCOA
108 #endif //__WXCOCOA__
109
110 #if wxMAJOR_VERSION <= 2
111
112         #ifdef __WXGTK__
113          #include <gdk/gdkx.h> // GDK_WINDOW_XWINDOW is found here in wxWidgets 2.8.0
114          #include "gdk/gdkprivate.h"
115          #if wxCHECK_VERSION(2, 9, 0)
116           // thanks to: http://thomasfischer.biz/?p=382
117           #include <gtk/gtkfixed.h>
118           #include <gtk/gtkwidget.h>
119           #include <wx/gtk/private/win_gtk.h>
120           #define piz(wxwin) WX_PIZZA((wxwin)->m_wxwindow)
121           #define GetXWindow(wxwin) (wxwin)->m_wxwindow ? \
122                 GDK_WINDOW_XWINDOW(((GtkWidget*)piz(wxwin))->window) : \
123                 GDK_WINDOW_XWINDOW((wxwin)->m_widget->window)
124          #else
125           #if wxCHECK_VERSION(2, 8, 0)
126            #ifdef __WXGTK20__
127             #include <wx/gtk/win_gtk.h>
128            #else
129             #include <wx/gtk1/win_gtk.h>
130            #endif
131           #else
132            #include <wx/gtk/win_gtk.h>
133           #endif
134          
135           #define GetXWindow(wxwin) (wxwin)->m_wxwindow ? \
136                                   GDK_WINDOW_XWINDOW(GTK_PIZZA((wxwin)->m_wxwindow)->bin_window) : \
137                                   GDK_WINDOW_XWINDOW((wxwin)->m_widget->window)
138          #endif
139         #endif
140
141 #else
142         #ifdef __WXGTK__
143             #include <gdk/gdkx.h>
144             #include <gtk/gtk.h>
145 #define GetXWindow(wxwin) (wxwin)->m_wxwindow ? \
146                           GDK_WINDOW_XID(gtk_widget_get_window((wxwin)->m_wxwindow)) :  \
147                          GDK_WINDOW_XID(gtk_widget_get_window((wxwin)->m_widget))
148         #endif
149 #endif
150
151 #ifdef __WXX11__
152 #include "wx/x11/privx.h"
153 #define GetXWindow(wxwin)   ((Window)(wxwin)->GetHandle())
154 #endif
155
156 //For more info on this class please go to:
157 //http://wxvtk.sf.net
158 //This hack is for some buggy wxGTK version:
159 #if wxCHECK_VERSION(2, 3, 2) && !wxCHECK_VERSION(2, 4, 1) && defined(__WXGTK__)
160 #  define WX_USE_X_CAPTURE 0
161 #else
162 #  define WX_USE_X_CAPTURE 1
163 #endif
164
165 #define ID_wxVTKRenderWindowInteractor_TIMER 1001
166
167 //=======================================================================
168 // LG : NAMESPACE IS NECESSARY TO AVOID CONFLICTING SYMBOLS IN DYN LIBS
169 namespace bbwxvtk
170 {
171
172 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
173 #else
174 #endif  //__WXGTK__
175
176 //---------------------------------------------------------------------------
177 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
178                 //EED 2017-09-16 Migration wxWidgets 2.8 to 3.0
179                 #if wxMAJOR_VERSION <= 2
180                         IMPLEMENT_DYNAMIC_CLASS(wxVTKRenderWindowInteractor, wxGLCanvas)
181                         BEGIN_EVENT_TABLE(wxVTKRenderWindowInteractor, wxGLCanvas)
182                 #else
183                         wxIMPLEMENT_DYNAMIC_CLASS(wxVTKRenderWindowInteractor, wxGLCanvas);
184                         wxBEGIN_EVENT_TABLE(wxVTKRenderWindowInteractor, wxGLCanvas)
185                 #endif
186 #else
187                 //EED 2017-09-16 Migration wxWidgets 2.8 to 3.0
188                 #if wxMAJOR_VERSION <= 2
189                         IMPLEMENT_DYNAMIC_CLASS(wxVTKRenderWindowInteractor, wxWindow)
190                         BEGIN_EVENT_TABLE(wxVTKRenderWindowInteractor, wxWindow)
191                 #else
192                         wxIMPLEMENT_DYNAMIC_CLASS(wxVTKRenderWindowInteractor, wxWindow);
193                         wxBEGIN_EVENT_TABLE(wxVTKRenderWindowInteractor, wxWindow)
194                 #endif
195 #endif //__WXGTK__
196   //refresh window by doing a Render
197   EVT_PAINT       (wxVTKRenderWindowInteractor::OnPaint)
198   EVT_ERASE_BACKGROUND(wxVTKRenderWindowInteractor::OnEraseBackground)
199   EVT_MOTION      (wxVTKRenderWindowInteractor::OnMotion)
200
201   //Bind the events to the event converters
202   EVT_LEFT_DOWN   (wxVTKRenderWindowInteractor::OnButtonDown)
203   EVT_MIDDLE_DOWN (wxVTKRenderWindowInteractor::OnButtonDown)
204   EVT_RIGHT_DOWN  (wxVTKRenderWindowInteractor::OnButtonDown)
205   EVT_LEFT_UP     (wxVTKRenderWindowInteractor::OnButtonUp)
206   EVT_MIDDLE_UP   (wxVTKRenderWindowInteractor::OnButtonUp)
207   EVT_RIGHT_UP    (wxVTKRenderWindowInteractor::OnButtonUp)
208 #if !(VTK_MAJOR_VERSION == 3 && VTK_MINOR_VERSION == 1)
209   EVT_ENTER_WINDOW(wxVTKRenderWindowInteractor::OnEnter)
210   EVT_LEAVE_WINDOW(wxVTKRenderWindowInteractor::OnLeave)
211   EVT_MOUSEWHEEL  (wxVTKRenderWindowInteractor::OnMouseWheel)
212 #if wxCHECK_VERSION(2, 8, 0)
213   EVT_MOUSE_CAPTURE_LOST(wxVTKRenderWindowInteractor::OnMouseCaptureLost)
214 #endif
215   EVT_KEY_DOWN    (wxVTKRenderWindowInteractor::OnKeyDown)
216   EVT_KEY_UP      (wxVTKRenderWindowInteractor::OnKeyUp)
217   EVT_CHAR        (wxVTKRenderWindowInteractor::OnChar)
218 #endif
219   EVT_TIMER       (ID_wxVTKRenderWindowInteractor_TIMER, wxVTKRenderWindowInteractor::OnTimer)
220   EVT_SIZE        (wxVTKRenderWindowInteractor::OnSize)
221 END_EVENT_TABLE()
222
223 vtkCxxRevisionMacro(wxVTKRenderWindowInteractor, "$Revision$")
224 vtkInstantiatorNewMacro(wxVTKRenderWindowInteractor)
225
226 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
227 static int wxvtk_attributes[]={
228   WX_GL_DOUBLEBUFFER,
229   WX_GL_RGBA,
230   WX_GL_DEPTH_SIZE,
231   16,
232   0
233 };
234 #endif
235
236 //---------------------------------------------------------------------------
237 wxVTKRenderWindowInteractor::wxVTKRenderWindowInteractor() 
238
239 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
240     #if wxCHECK_VERSION(2, 9, 0) // the order of the parameters to wxGLCanvas::wxGLCanvas has changed
241                 : wxGLCanvas(0, -1, wxvtk_attributes, wxDefaultPosition, wxDefaultSize, 0, wxT("wxVTKRenderWindowInteractor")), 
242         #else
243                 : wxGLCanvas(0, -1, wxDefaultPosition, wxDefaultSize, 0, wxT("wxVTKRenderWindowInteractor"), wxvtk_attributes), 
244         #endif
245 #else
246                 : wxWindow(), 
247 #endif //__WXGTK__
248
249           vtkRenderWindowInteractor()
250       , timer(this, ID_wxVTKRenderWindowInteractor_TIMER)
251       , ActiveButton(wxEVT_NULL)
252       , Stereo(0)
253       , Handle(0)
254       , Created(true)
255       , RenderWhenDisabled(1)
256       , UseCaptureMouse(0)
257 {
258 #ifdef VTK_DEBUG_LEAKS
259   vtkDebugLeaks::ConstructClass("wxVTKRenderWindowInteractor");
260 #endif
261 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
262   this->context = new wxGLContext(this);
263 #endif
264   this->RenderWindow = NULL;
265   this->SetRenderWindow(vtkRenderWindow::New());
266   this->RenderWindow->Delete();
267 }
268 //---------------------------------------------------------------------------
269 wxVTKRenderWindowInteractor::wxVTKRenderWindowInteractor(wxWindow *parent,
270                                                          wxWindowID id,
271                                                          const wxPoint &pos,
272                                                          const wxSize &size,
273                                                          long style,
274                                                          const wxString &name)
275 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
276     #if wxCHECK_VERSION(2, 9, 0) // the order of the parameters to wxGLCanvas::wxGLCanvas has changed
277       : wxGLCanvas(parent, id, wxvtk_attributes, pos, size, style, name)
278     #else
279       : wxGLCanvas(parent, id, pos, size, style, name, wxvtk_attributes)
280     #endif
281 #else
282       : wxWindow(parent, id, pos, size, style, name)
283 #endif //__WXGTK__
284           , vtkRenderWindowInteractor()
285       , timer(this, ID_wxVTKRenderWindowInteractor_TIMER)
286       , ActiveButton(wxEVT_NULL)
287       , Stereo(0)
288       , Handle(0)
289       , Created(true)
290       , RenderWhenDisabled(1)
291       , UseCaptureMouse(0)
292 {
293 #ifdef VTK_DEBUG_LEAKS
294   vtkDebugLeaks::ConstructClass("wxVTKRenderWindowInteractor");
295 #endif
296 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
297   this->context = new wxGLContext(this);
298 #endif
299   this->RenderWindow = NULL;
300   this->SetRenderWindow(vtkRenderWindow::New());
301   this->RenderWindow->Delete();
302 #ifdef __WXMAC__
303   // On Mac (Carbon) we don't get notified of the initial window size with an EVT_SIZE event,
304   // so we update the size information of the interactor/renderwindow here
305   this->UpdateSize(size.x, size.y);
306 #endif
307 }
308 //---------------------------------------------------------------------------
309 wxVTKRenderWindowInteractor::~wxVTKRenderWindowInteractor()
310 {
311   SetRenderWindow(NULL);
312   SetInteractorStyle(NULL);
313 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
314   delete this->context;
315 #endif
316 }
317 //---------------------------------------------------------------------------
318 wxVTKRenderWindowInteractor * wxVTKRenderWindowInteractor::New()
319 {
320   // we don't make use of the objectfactory, because we're not registered
321   return new wxVTKRenderWindowInteractor;
322 }
323 //---------------------------------------------------------------------------
324 void wxVTKRenderWindowInteractor::Initialize()
325 {
326   int *size = RenderWindow->GetSize();
327   // enable everything and start rendering
328   Enable();
329   //RenderWindow->Start();
330
331   // set the size in the render window interactor
332   Size[0] = size[0];
333   Size[1] = size[1];
334
335   // this is initialized
336   Initialized = 1;
337 }
338 //---------------------------------------------------------------------------
339 void wxVTKRenderWindowInteractor::Enable()
340 {
341   // if already enabled then done
342   if (Enabled)
343     return;
344
345   // that's it
346   Enabled = 1;
347 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
348   wxGLCanvas::SetCurrent(*this->context);
349 #endif
350   Modified();
351 }
352 //---------------------------------------------------------------------------
353 bool wxVTKRenderWindowInteractor::Enable(bool enable)
354 {
355 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
356   return wxGLCanvas::Enable(enable);
357 #else
358   return wxWindow::Enable(enable);
359 #endif
360 }
361 //---------------------------------------------------------------------------
362 void wxVTKRenderWindowInteractor::Disable()
363 {
364   // if already disabled then done
365   if (!Enabled)
366     return;
367
368   // that's it (we can't remove the event handler like it should be...)
369   Enabled = 0;
370   Modified();
371 }
372 //---------------------------------------------------------------------------
373 void wxVTKRenderWindowInteractor::Start()
374 {
375   // the interactor cannot control the event loop
376   vtkErrorMacro( << "wxVTKRenderWindowInteractor::Start() "
377     "interactor cannot control event loop.");
378 }
379 //---------------------------------------------------------------------------
380 void wxVTKRenderWindowInteractor::UpdateSize(int x, int y)
381 {
382   if( RenderWindow )
383   {
384     // if the size changed tell render window
385     if ( x != Size[0] || y != Size[1] )
386     {
387       // adjust our (vtkRenderWindowInteractor size)
388       Size[0] = x;
389       Size[1] = y;
390       // and our RenderWindow's size
391       RenderWindow->SetSize(x, y);
392 #if defined(__WXMSW__)
393       this->Refresh();
394 #endif //__WXMSW__
395     }
396   }
397 }
398 //---------------------------------------------------------------------------
399 int wxVTKRenderWindowInteractor::CreateTimer(int WXUNUSED(timertype))
400 {
401   // it's a one shot timer
402   if (!timer.Start(10, TRUE))
403     return 0;
404
405   return 1;
406   
407 }
408 #if VTK_MAJOR_VERSION > 5 || (VTK_MAJOR_VERSION == 5 && VTK_MINOR_VERSION >= 2)
409 //------------------------------------------------------------------
410 int wxVTKRenderWindowInteractor::InternalCreateTimer(int timerId, int timerType,
411                                                      unsigned long duration)
412 {
413   if (!timer.Start(duration, timerType == OneShotTimer))
414     return 0;
415     
416   return ID_wxVTKRenderWindowInteractor_TIMER;
417 }
418 //------------------------------------------------------------------
419 int wxVTKRenderWindowInteractor::InternalDestroyTimer(int platformTimerId)
420 {
421   timer.Stop();
422   return 1;
423 }
424 #endif
425 //---------------------------------------------------------------------------
426 int wxVTKRenderWindowInteractor::DestroyTimer()
427 {
428   // do nothing
429   return 1;
430 }
431 //---------------------------------------------------------------------------
432 void wxVTKRenderWindowInteractor::OnTimer(wxTimerEvent& WXUNUSED(event))
433 {
434   if (!Enabled)
435     return;
436     
437 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
438   // new style
439 #if VTK_MAJOR_VERSION > 5 || (VTK_MAJOR_VERSION == 5 && VTK_MINOR_VERSION >= 2)
440   // pass the right timer id
441   int timerId = this->GetCurrentTimerId();
442   this->InvokeEvent(vtkCommand::TimerEvent, &timerId);
443 #else
444   this->InvokeEvent(vtkCommand::TimerEvent, NULL);
445 #endif
446 #else
447   // old style
448   InteractorStyle->OnTimer();
449 #endif
450 }
451
452 //---------------------------------------------------------------------------
453 // NOTE on implementation:
454 // Bad luck you ended up in the only tricky place of this code.
455 // A few note, wxWidgets still refuse to provide such convenient method
456 // so I have to maintain it myself, eventhough this is completely integrated
457 // in wxPython...
458 // Anyway if this happen to break for you then compare to a recent version of wxPython
459 // and look for the function long wxPyGetWinHandle(wxWindow* win)
460 // in wxPython/src/helpers.cpp
461 long wxVTKRenderWindowInteractor::GetHandleHack()
462 {
463   //helper function to hide the MSW vs GTK stuff
464   long handle_tmp = 0;
465
466 // __WXMSW__ is for Win32
467 // __WXMAC__ is for Carbon or Cocoa builds
468 // __WXGTK__ is for both gtk 1.2.x and gtk 2.x
469 #if defined(__WXMSW__) || defined(__WXMAC__)
470     handle_tmp = (long)this->GetHandle();
471 #endif //__WXMSW__
472
473 // using above GetHandle() works fine with wxOSX 2.9.x
474 #if defined(__WXCOCOA__) && !wxCHECK_VERSION(2, 9, 0)
475    // Here is how to find the NSWindow
476    wxTopLevelWindow* toplevel = dynamic_cast<wxTopLevelWindow*>(wxGetTopLevelParent( this ) );
477    if (toplevel != NULL )
478    {
479       handle_tmp = (long)toplevel->GetNSWindow();
480    }
481    // The NSView will be deducted from 
482    // [(NSWindow*)Handle contentView]
483    // if only I knew how to write that in c++
484 #endif //__WXCOCOA__ && !wxCHECK_VERSION(2, 9, 0)
485
486     // Find and return the actual X-Window.
487 #if defined(__WXGTK__) || defined(__WXX11__)
488     return (long)GetXWindow(this);
489 #endif
490
491 //#ifdef __WXMOTIF__
492 //    handle_tmp = (long)this->GetXWindow();
493 //#endif
494
495   return handle_tmp;
496 }
497 //---------------------------------------------------------------------------
498 void wxVTKRenderWindowInteractor::OnPaint(wxPaintEvent& WXUNUSED(event))
499 {
500   //must always be here
501   wxPaintDC pDC(this);
502
503   //do it here rather than in the cstor: this is safer.
504   if(!Handle)
505   {
506     Handle = GetHandleHack();
507     RenderWindow->SetWindowId(reinterpret_cast<void *>(Handle));
508 // Cocoa
509 // this->GetNSView() <-> DisplayId
510 // this->GetTopLevel()->GetNSWindow() <-> WindowId
511 #ifdef __WXMSW__
512     RenderWindow->SetParentId(reinterpret_cast<void *>(this->GetParent()->GetHWND()));
513 #endif //__WXMSW__
514       
515     // This is another hack to prevent the VTK Render Window from closing the display.
516     // If VTK closes the display, ~wxContext chashes while trying to destroy its
517     // glContext (because the display is closed). The Get -> Set makes this VTK
518     // object think someone else is responsible for the display. 
519     #ifdef __WXCOCOA__
520       // avoid "Method not implemented" messages in Console
521     #else
522       this->RenderWindow->SetDisplayId(this->RenderWindow->GetGenericDisplayId());
523     #endif
524   }
525   // get vtk to render to the wxWindows
526   Render();
527 #ifdef __WXMAC__
528   // This solves a problem with repainting after a window resize
529   // See also: http://sourceforge.net/mailarchive/forum.php?thread_id=31690967&forum_id=41789
530 #ifdef __WXCOCOA__
531   #if !wxCHECK_VERSION(2, 9, 0)
532     // this doesn't seem necessary with wxOSX 2.9.x
533     vtkCocoaRenderWindow * rwin = vtkCocoaRenderWindow::SafeDownCast(RenderWindow);
534     if( rwin )
535     {
536       rwin->UpdateContext();
537     }
538   #endif
539 #else
540   vtkCarbonRenderWindow* rwin = vtkCarbonRenderWindow::SafeDownCast(RenderWindow);
541   if( rwin )
542   {
543 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 4)
544     // Must be somewhere after VTK 4.4
545     rwin->UpdateGLRegion();
546 #endif
547   }
548 #endif
549 #endif
550 }
551 //---------------------------------------------------------------------------
552 void wxVTKRenderWindowInteractor::OnEraseBackground(wxEraseEvent &event)
553 {
554   //turn off background erase to reduce flickering on MSW
555   event.Skip(false);
556 }
557 //---------------------------------------------------------------------------
558 void wxVTKRenderWindowInteractor::OnSize(wxSizeEvent& WXUNUSED(event))
559 {
560   int w, h;
561   GetClientSize(&w, &h);
562   UpdateSize(w, h);
563
564   if (!Enabled) 
565     {
566     return;
567     }
568
569 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
570   InvokeEvent(vtkCommand::ConfigureEvent, NULL);
571 #endif
572   //this will check for Handle
573   //Render();
574 }
575 //---------------------------------------------------------------------------
576 void wxVTKRenderWindowInteractor::OnMotion(wxMouseEvent &event)
577 {
578  if (!Enabled) 
579     {
580     return;
581     }
582 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
583   SetEventInformationFlipY(event.GetX(), event.GetY(), 
584     event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
585
586   InvokeEvent(vtkCommand::MouseMoveEvent, NULL);
587 #else
588   InteractorStyle->OnMouseMove(event.ControlDown(), event.ShiftDown(),
589     event.GetX(), Size[1] - event.GetY() - 1);
590 #endif
591 }
592 //---------------------------------------------------------------------------
593 #if !(VTK_MAJOR_VERSION == 3 && VTK_MINOR_VERSION == 1)
594 void wxVTKRenderWindowInteractor::OnEnter(wxMouseEvent &event)
595 {
596   if (!Enabled) 
597     {
598     return;
599     }
600
601 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
602     // new style
603   SetEventInformationFlipY(event.GetX(), event.GetY(), 
604       event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
605
606   InvokeEvent(vtkCommand::EnterEvent, NULL);
607 #else
608     // old style
609   InteractorStyle->OnEnter(event.ControlDown(), event.ShiftDown(),
610       event.GetX(), Size[1] - event.GetY() - 1);  
611 #endif
612 }
613 //---------------------------------------------------------------------------
614 void wxVTKRenderWindowInteractor::OnLeave(wxMouseEvent &event)
615 {
616   if (!Enabled) 
617     {
618     return;
619     }
620
621 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
622     // new style
623   SetEventInformationFlipY(event.GetX(), event.GetY(), 
624       event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
625
626   InvokeEvent(vtkCommand::LeaveEvent, NULL);
627 #else
628     // old style
629   InteractorStyle->OnLeave(event.ControlDown(), event.ShiftDown(),
630       event.GetX(), Size[1] - event.GetY() - 1);  
631 #endif
632 }
633 //---------------------------------------------------------------------------
634 void wxVTKRenderWindowInteractor::OnKeyDown(wxKeyEvent &event)
635 {
636   if (!Enabled) 
637     {
638     return;
639     }
640
641 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
642     // new style
643   int keycode = event.GetKeyCode();
644   char key = '\0';
645   if (((unsigned int)keycode) < 256)
646   {
647     // TODO: Unicode in non-Unicode mode ??
648     key = (char)keycode;
649   }
650
651   // we don't get a valid mouse position inside the key event on every platform
652   // so we retrieve the mouse position explicitly and pass it along
653   wxPoint mousePos = ScreenToClient(wxGetMousePosition());
654   SetEventInformationFlipY(mousePos.x, mousePos.y, 
655                            event.ControlDown(), event.ShiftDown(), key, 0, NULL);
656   InvokeEvent(vtkCommand::KeyPressEvent, NULL);
657 #else
658   InteractorStyle->OnKeyDown(event.ControlDown(), event.ShiftDown(), 
659     event.GetKeyCode(), 1);
660 #endif
661   event.Skip();
662 }
663 //---------------------------------------------------------------------------
664 void wxVTKRenderWindowInteractor::OnKeyUp(wxKeyEvent &event)
665 {
666   if (!Enabled) 
667     {
668     return;
669     }
670
671 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
672     // new style
673   int keycode = event.GetKeyCode();
674   char key = '\0';
675   if (((unsigned int)keycode) < 256)
676   {
677     // TODO: Unicode in non-Unicode mode ??
678     key = (char)keycode;
679   }
680
681   // we don't get a valid mouse position inside the key event on every platform
682   // so we retrieve the mouse position explicitly and pass it along
683   wxPoint mousePos = ScreenToClient(wxGetMousePosition());
684   SetEventInformationFlipY(mousePos.x, mousePos.y, 
685                            event.ControlDown(), event.ShiftDown(), key, 0, NULL);
686   InvokeEvent(vtkCommand::KeyReleaseEvent, NULL);
687 #else
688   InteractorStyle->OnKeyUp(event.ControlDown(), event.ShiftDown(), 
689     event.GetKeyCode(), 1);
690 #endif
691   event.Skip();
692 }
693 #endif //!(VTK_MAJOR_VERSION == 3 && VTK_MINOR_VERSION == 1)
694  //---------------------------------------------------------------------------
695 void wxVTKRenderWindowInteractor::OnChar(wxKeyEvent &event)
696 {
697   if (!Enabled) 
698     {
699     return;
700     }
701     
702 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
703   // new style
704   int keycode = event.GetKeyCode();
705   char key = '\0';
706   if (((unsigned int)keycode) < 256)
707     {
708     // TODO: Unicode in non-Unicode mode ??
709     key = (char)keycode;
710     }
711
712   // we don't get a valid mouse position inside the key event on every platform
713   // so we retrieve the mouse position explicitly and pass it along
714   wxPoint mousePos = ScreenToClient(wxGetMousePosition());
715   SetEventInformationFlipY(mousePos.x, mousePos.y, 
716                            event.ControlDown(), event.ShiftDown(), key, 0, NULL);
717   InvokeEvent(vtkCommand::CharEvent, NULL);
718 #endif
719   event.Skip();
720 }
721 //---------------------------------------------------------------------------
722 void wxVTKRenderWindowInteractor::OnButtonDown(wxMouseEvent &event)
723 {
724   if (!Enabled || (ActiveButton != wxEVT_NULL))
725     {
726     return;
727     }
728   ActiveButton = event.GetEventType();
729
730     // On Mac (Carbon) and Windows we don't automatically get the focus when
731     // you click inside the window
732     // we therefore set the focus explicitly
733     // Apparently we need that on linux (GTK) too:
734     this->SetFocus();
735
736 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
737   SetEventInformationFlipY(event.GetX(), event.GetY(), 
738     event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
739 #endif
740
741   if(event.RightDown())
742   {
743 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
744     // new style
745     InvokeEvent(vtkCommand::RightButtonPressEvent, NULL);
746 #else            
747     // old style
748     InteractorStyle->OnRightButtonDown(event.ControlDown(), event.ShiftDown(),
749       event.GetX(), Size[1] - event.GetY() - 1);
750 #endif
751   }
752   else if(event.LeftDown())
753   {
754 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
755     // new style
756     InvokeEvent(vtkCommand::LeftButtonPressEvent, NULL);
757 #else            
758     // old style
759     InteractorStyle->OnLeftButtonDown(event.ControlDown(),  event.ShiftDown(),
760       event.GetX(), Size[1] - event.GetY() - 1);
761 #endif
762   }
763   else if(event.MiddleDown())
764   {
765 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
766     // new style
767     InvokeEvent(vtkCommand::MiddleButtonPressEvent, NULL);
768 #else            
769     // old style
770     InteractorStyle->OnMiddleButtonDown(event.ControlDown(), event.ShiftDown(),
771       event.GetX(), Size[1] - event.GetY() - 1);
772 #endif
773   }
774   //save the button and capture mouse until the button is released
775   //Only if :
776   //1. it is possible (WX_USE_X_CAPTURE)
777   //2. user decided to.
778   if ((ActiveButton != wxEVT_NULL) && WX_USE_X_CAPTURE && UseCaptureMouse)
779   {
780     CaptureMouse();
781   }
782 }
783 //---------------------------------------------------------------------------
784 void wxVTKRenderWindowInteractor::OnButtonUp(wxMouseEvent &event)
785 {
786   //EVT_xxx_DOWN == EVT_xxx_UP - 1
787   //This is only needed if two mouse buttons are pressed at the same time.
788   //In wxWindows 2.4 and later: better use of wxMOUSE_BTN_RIGHT or 
789   //wxEVT_COMMAND_RIGHT_CLICK
790   if (!Enabled || (ActiveButton != (event.GetEventType()-1))) 
791     {
792     return;
793     }
794
795   // See report by Shang Mu / Kerry Loux on wxVTK mailing list
796     this->SetFocus();
797
798 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
799   SetEventInformationFlipY(event.GetX(), event.GetY(), 
800     event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
801 #endif
802   
803   if(ActiveButton == wxEVT_RIGHT_DOWN)
804   {
805 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
806     // new style
807     InvokeEvent(vtkCommand::RightButtonReleaseEvent, NULL);
808 #else            
809     // old style
810     InteractorStyle->OnRightButtonUp(event.ControlDown(), event.ShiftDown(),
811       event.GetX(), Size[1] - event.GetY() - 1);
812 #endif
813   }
814   else if(ActiveButton == wxEVT_LEFT_DOWN)
815   {
816 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
817     // new style
818     InvokeEvent(vtkCommand::LeftButtonReleaseEvent, NULL);
819 #else            
820     // old style
821     InteractorStyle->OnLeftButtonUp(event.ControlDown(), event.ShiftDown(),
822       event.GetX(), Size[1] - event.GetY() - 1);
823 #endif
824   }
825   else if(ActiveButton == wxEVT_MIDDLE_DOWN)
826   {
827 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
828     // new style
829     InvokeEvent(vtkCommand::MiddleButtonReleaseEvent, NULL);
830 #else            
831     // old style
832     InteractorStyle->OnMiddleButtonUp(event.ControlDown(), event.ShiftDown(),
833       event.GetX(), Size[1] - event.GetY() - 1);
834 #endif
835   }
836   //if the ActiveButton is realeased, then release mouse capture
837   if ((ActiveButton != wxEVT_NULL) && WX_USE_X_CAPTURE && UseCaptureMouse)
838   {
839     ReleaseMouse();
840   }
841   ActiveButton = wxEVT_NULL;
842 }
843 //---------------------------------------------------------------------------
844 void wxVTKRenderWindowInteractor::OnMouseWheel(wxMouseEvent& event)
845 {
846 // Mouse wheel was only added after VTK 4.4 (I think...)
847 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 4)
848   // new style
849   //Set vtk event information ... The numebr of wheel rotations is stored in
850   //the x varible.  y varible is zero
851   SetEventInformationFlipY(event.GetX() , event.GetY(), 
852                            event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
853   if(event.GetWheelRotation() > 0)
854     {
855       //Send event to VTK
856       InvokeEvent(vtkCommand::MouseWheelForwardEvent, NULL);
857     }
858   else
859     {
860       //Send event to VTK
861       InvokeEvent(vtkCommand::MouseWheelBackwardEvent, NULL);
862     }
863 #endif
864     
865 }
866
867 //---------------------------------------------------------------------------
868 #if wxCHECK_VERSION(2, 8, 0)
869 void wxVTKRenderWindowInteractor::OnMouseCaptureLost(wxMouseCaptureLostEvent& event)
870 {
871    if (ActiveButton != wxEVT_NULL)
872    {
873        //Maybe also invoke the button release event here
874    }
875    // Reset ActiveButton so that
876    // 1. we do not process mouse button up events any more,
877    // 2. the next button down event will be processed and call CaptureMouse().
878    // Otherwise ReleaseMouse() will be called
879    // without a previous CaptureMouse().
880    ActiveButton = wxEVT_NULL;
881 }
882 #endif
883
884 //---------------------------------------------------------------------------
885 void wxVTKRenderWindowInteractor::Render()
886 {
887 #if wxCHECK_VERSION(2, 8, 0)
888   int renderAllowed = !IsFrozen();
889 #else
890   int renderAllowed = 1;
891 #endif
892   if (renderAllowed && !RenderWhenDisabled)
893     {
894     //the user doesn't want us to render when the toplevel frame
895     //is disabled - first find the top level parent
896     wxWindow *topParent = wxGetTopLevelParent(this);
897     if (topParent)
898       {
899       //if it exists, check whether it's enabled
900       //if it's not enabeld, renderAllowed will be false
901       renderAllowed = topParent->IsEnabled();
902       }
903     }
904
905   if (renderAllowed)
906     {
907 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
908     wxGLCanvas::SetCurrent(*(this->context));
909 #endif
910     if(Handle && (Handle == GetHandleHack()) )
911       {
912       RenderWindow->Render();
913       }
914 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 2)
915     else if(GetHandleHack())
916       {
917       //this means the user has reparented us; let's adapt to the
918       //new situation by doing the WindowRemap dance
919       //store the new situation
920       Handle = GetHandleHack();
921       RenderWindow->SetNextWindowId(reinterpret_cast<void *>(Handle));
922       RenderWindow->WindowRemap();
923       RenderWindow->Render();
924       }
925 #endif
926     }
927 }
928 //---------------------------------------------------------------------------
929 void wxVTKRenderWindowInteractor::SetRenderWhenDisabled(int newValue)
930 {
931   //Change value of __RenderWhenDisabled ivar.
932   //If __RenderWhenDisabled is false (the default), this widget will not
933   //call Render() on the RenderWindow if the top level frame (i.e. the
934   //containing frame) has been disabled.
935
936   //This prevents recursive rendering during wxSafeYield() calls.
937   //wxSafeYield() can be called during the ProgressMethod() callback of
938   //a VTK object to have progress bars and other GUI elements updated -
939   //it does this by disabling all windows (disallowing user-input to
940   //prevent re-entrancy of code) and then handling all outstanding
941   //GUI events.
942         
943   //However, this often triggers an OnPaint() method for wxVTKRWIs,
944   //resulting in a Render(), resulting in Update() being called whilst
945   //still in progress.
946
947   RenderWhenDisabled = (bool)newValue;
948 }
949 //---------------------------------------------------------------------------
950 //
951 // Set the variable that indicates that we want a stereo capable window
952 // be created. This method can only be called before a window is realized.
953 //
954 void wxVTKRenderWindowInteractor::SetStereo(int capable)
955 {
956   if (Stereo != capable)
957     {
958     Stereo = capable;
959     RenderWindow->StereoCapableWindowOn();
960     RenderWindow->SetStereoTypeToCrystalEyes();
961     Modified();
962     }
963 }
964
965 //---------------------------------------------------------------------------
966 //
967 //
968 void wxVTKRenderWindowInteractor::PrintSelf(ostream& os, vtkIndent indent)
969 {
970   this->Superclass::PrintSelf(os, indent);
971 }
972
973
974 }
975 // LG : EO namespace bbwxvtk
976 //=======================================================================
977
978