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