]> Creatis software - crea.git/blob - src/creawxVTKRenderWindowInteractor.cxx
#3169 creaFeature New Normal - branch vtk7itk4wx3-mxecc
[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 // LG : NAMESPACE IS NECESSARY TO AVOID CONFLICTING SYMBOLS IN DYN LIBS
82 namespace crea
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 crea
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 //EED win Compilation why??:  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 int 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 // EED 2018-01-17
471 //    handle_tmp = (long)this->GetHandle();
472     handle_tmp = (long long)this->GetHandle();
473 #endif //__WXMSW__
474
475 // using above GetHandle() works fine with wxOSX 2.9.x
476 #if defined(__WXCOCOA__) && !wxCHECK_VERSION(2, 9, 0)
477    // Here is how to find the NSWindow
478    wxTopLevelWindow* toplevel = dynamic_cast<wxTopLevelWindow*>(wxGetTopLevelParent( this ) );
479    if (toplevel != NULL )
480    {
481       handle_tmp = (long)toplevel->GetNSWindow();
482    }
483    // The NSView will be deducted from 
484    // [(NSWindow*)Handle contentView]
485    // if only I knew how to write that in c++
486 #endif //__WXCOCOA__ && !wxCHECK_VERSION(2, 9, 0)
487
488     // Find and return the actual X-Window.
489 #if defined(__WXGTK__) || defined(__WXX11__)
490     return (long)GetXWindow(this);
491 #endif
492
493 //#ifdef __WXMOTIF__
494 //    handle_tmp = (long)this->GetXWindow();
495 //#endif
496
497   return handle_tmp;
498 }
499 //---------------------------------------------------------------------------
500 void wxVTKRenderWindowInteractor::OnPaint(wxPaintEvent& WXUNUSED(event))
501 {
502   //must always be here
503   wxPaintDC pDC(this);
504
505   //do it here rather than in the cstor: this is safer.
506   if(!Handle)
507     Handle = GetHandleHack();
508   {
509     RenderWindow->SetWindowId(reinterpret_cast<void *>(Handle));
510
511 // Cocoa
512 // this->GetNSView() <-> DisplayId
513 // this->GetTopLevel()->GetNSWindow() <-> WindowId
514 #ifdef __WXMSW__
515     RenderWindow->SetParentId(reinterpret_cast<void *>(this->GetParent()->GetHWND()));
516 #endif //__WXMSW__
517       
518     // This is another hack to prevent the VTK Render Window from closing the display.
519     // If VTK closes the display, ~wxContext chashes while trying to destroy its
520     // glContext (because the display is closed). The Get -> Set makes this VTK
521     // object think someone else is responsible for the display. 
522     #ifdef __WXCOCOA__
523       // avoid "Method not implemented" messages in Console
524     #else
525       this->RenderWindow->SetDisplayId(this->RenderWindow->GetGenericDisplayId());
526     #endif
527   }
528   // get vtk to render to the wxWindows
529   Render();
530 #ifdef __WXMAC__
531   // This solves a problem with repainting after a window resize
532   // See also: http://sourceforge.net/mailarchive/forum.php?thread_id=31690967&forum_id=41789
533 #ifdef __WXCOCOA__
534   #if !wxCHECK_VERSION(2, 9, 0)
535     // this doesn't seem necessary with wxOSX 2.9.x
536     vtkCocoaRenderWindow * rwin = vtkCocoaRenderWindow::SafeDownCast(RenderWindow);
537     if( rwin )
538     {
539       rwin->UpdateContext();
540     }
541   #endif
542 #else
543   vtkCarbonRenderWindow* rwin = vtkCarbonRenderWindow::SafeDownCast(RenderWindow);
544   if( rwin )
545   {
546 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 4)
547     // Must be somewhere after VTK 4.4
548     rwin->UpdateGLRegion();
549 #endif
550   }
551 #endif
552 #endif
553 }
554 //---------------------------------------------------------------------------
555 void wxVTKRenderWindowInteractor::OnEraseBackground(wxEraseEvent &event)
556 {
557   //turn off background erase to reduce flickering on MSW
558   event.Skip(false);
559 }
560 //---------------------------------------------------------------------------
561 void wxVTKRenderWindowInteractor::OnSize(wxSizeEvent& WXUNUSED(event))
562 {
563   int w, h;
564   GetClientSize(&w, &h);
565   UpdateSize(w, h);
566
567   if (!Enabled) 
568     {
569     return;
570     }
571
572 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
573   InvokeEvent(vtkCommand::ConfigureEvent, NULL);
574 #endif
575   //this will check for Handle
576   //Render();
577 }
578 //---------------------------------------------------------------------------
579 void wxVTKRenderWindowInteractor::OnMotion(wxMouseEvent &event)
580 {
581  if (!Enabled) 
582     {
583     return;
584     }
585 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
586   SetEventInformationFlipY(event.GetX(), event.GetY(), 
587     event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
588
589   InvokeEvent(vtkCommand::MouseMoveEvent, NULL);
590 #else
591   InteractorStyle->OnMouseMove(event.ControlDown(), event.ShiftDown(),
592     event.GetX(), Size[1] - event.GetY() - 1);
593 #endif
594 }
595 //---------------------------------------------------------------------------
596 #if !(VTK_MAJOR_VERSION == 3 && VTK_MINOR_VERSION == 1)
597 void wxVTKRenderWindowInteractor::OnEnter(wxMouseEvent &event)
598 {
599   if (!Enabled) 
600     {
601     return;
602     }
603
604 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
605     // new style
606   SetEventInformationFlipY(event.GetX(), event.GetY(), 
607       event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
608
609   InvokeEvent(vtkCommand::EnterEvent, NULL);
610 #else
611     // old style
612   InteractorStyle->OnEnter(event.ControlDown(), event.ShiftDown(),
613       event.GetX(), Size[1] - event.GetY() - 1);  
614 #endif
615 }
616 //---------------------------------------------------------------------------
617 void wxVTKRenderWindowInteractor::OnLeave(wxMouseEvent &event)
618 {
619   if (!Enabled) 
620     {
621     return;
622     }
623
624 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
625     // new style
626   SetEventInformationFlipY(event.GetX(), event.GetY(), 
627       event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
628
629   InvokeEvent(vtkCommand::LeaveEvent, NULL);
630 #else
631     // old style
632   InteractorStyle->OnLeave(event.ControlDown(), event.ShiftDown(),
633       event.GetX(), Size[1] - event.GetY() - 1);  
634 #endif
635 }
636 //---------------------------------------------------------------------------
637 void wxVTKRenderWindowInteractor::OnKeyDown(wxKeyEvent &event)
638 {
639   if (!Enabled) 
640     {
641     return;
642     }
643
644 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
645     // new style
646   int keycode = event.GetKeyCode();
647   char key = '\0';
648   if (((unsigned int)keycode) < 256)
649   {
650     // TODO: Unicode in non-Unicode mode ??
651     key = (char)keycode;
652   }
653
654   // we don't get a valid mouse position inside the key event on every platform
655   // so we retrieve the mouse position explicitly and pass it along
656   wxPoint mousePos = ScreenToClient(wxGetMousePosition());
657   SetEventInformationFlipY(mousePos.x, mousePos.y, 
658                            event.ControlDown(), event.ShiftDown(), key, 0, NULL);
659   InvokeEvent(vtkCommand::KeyPressEvent, NULL);
660 #else
661   InteractorStyle->OnKeyDown(event.ControlDown(), event.ShiftDown(), 
662     event.GetKeyCode(), 1);
663 #endif
664   event.Skip();
665 }
666 //---------------------------------------------------------------------------
667 void wxVTKRenderWindowInteractor::OnKeyUp(wxKeyEvent &event)
668 {
669   if (!Enabled) 
670     {
671     return;
672     }
673
674 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
675     // new style
676   int keycode = event.GetKeyCode();
677   char key = '\0';
678   if (((unsigned int)keycode) < 256)
679   {
680     // TODO: Unicode in non-Unicode mode ??
681     key = (char)keycode;
682   }
683
684   // we don't get a valid mouse position inside the key event on every platform
685   // so we retrieve the mouse position explicitly and pass it along
686   wxPoint mousePos = ScreenToClient(wxGetMousePosition());
687   SetEventInformationFlipY(mousePos.x, mousePos.y, 
688                            event.ControlDown(), event.ShiftDown(), key, 0, NULL);
689   InvokeEvent(vtkCommand::KeyReleaseEvent, NULL);
690 #else
691   InteractorStyle->OnKeyUp(event.ControlDown(), event.ShiftDown(), 
692     event.GetKeyCode(), 1);
693 #endif
694   event.Skip();
695 }
696 #endif //!(VTK_MAJOR_VERSION == 3 && VTK_MINOR_VERSION == 1)
697  //---------------------------------------------------------------------------
698 void wxVTKRenderWindowInteractor::OnChar(wxKeyEvent &event)
699 {
700   if (!Enabled) 
701     {
702     return;
703     }
704     
705 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
706   // new style
707   int keycode = event.GetKeyCode();
708   char key = '\0';
709   if (((unsigned int)keycode) < 256)
710     {
711     // TODO: Unicode in non-Unicode mode ??
712     key = (char)keycode;
713     }
714
715   // we don't get a valid mouse position inside the key event on every platform
716   // so we retrieve the mouse position explicitly and pass it along
717   wxPoint mousePos = ScreenToClient(wxGetMousePosition());
718   SetEventInformationFlipY(mousePos.x, mousePos.y, 
719                            event.ControlDown(), event.ShiftDown(), key, 0, NULL);
720   InvokeEvent(vtkCommand::CharEvent, NULL);
721 #endif
722   event.Skip();
723 }
724 //---------------------------------------------------------------------------
725 void wxVTKRenderWindowInteractor::OnButtonDown(wxMouseEvent &event)
726 {
727   if (!Enabled || (ActiveButton != wxEVT_NULL))
728     {
729     return;
730     }
731   ActiveButton = event.GetEventType();
732
733     // On Mac (Carbon) and Windows we don't automatically get the focus when
734     // you click inside the window
735     // we therefore set the focus explicitly
736     // Apparently we need that on linux (GTK) too:
737     this->SetFocus();
738
739 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
740   SetEventInformationFlipY(event.GetX(), event.GetY(), 
741     event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
742 #endif
743
744   if(event.RightDown())
745   {
746 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
747     // new style
748     InvokeEvent(vtkCommand::RightButtonPressEvent, NULL);
749 #else            
750     // old style
751     InteractorStyle->OnRightButtonDown(event.ControlDown(), event.ShiftDown(),
752       event.GetX(), Size[1] - event.GetY() - 1);
753 #endif
754   }
755   else if(event.LeftDown())
756   {
757 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
758     // new style
759     InvokeEvent(vtkCommand::LeftButtonPressEvent, NULL);
760 #else            
761     // old style
762     InteractorStyle->OnLeftButtonDown(event.ControlDown(),  event.ShiftDown(),
763       event.GetX(), Size[1] - event.GetY() - 1);
764 #endif
765   }
766   else if(event.MiddleDown())
767   {
768 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
769     // new style
770     InvokeEvent(vtkCommand::MiddleButtonPressEvent, NULL);
771 #else            
772     // old style
773     InteractorStyle->OnMiddleButtonDown(event.ControlDown(), event.ShiftDown(),
774       event.GetX(), Size[1] - event.GetY() - 1);
775 #endif
776   }
777   //save the button and capture mouse until the button is released
778   //Only if :
779   //1. it is possible (WX_USE_X_CAPTURE)
780   //2. user decided to.
781   if ((ActiveButton != wxEVT_NULL) && WX_USE_X_CAPTURE && UseCaptureMouse)
782   {
783     CaptureMouse();
784   }
785 }
786 //---------------------------------------------------------------------------
787 void wxVTKRenderWindowInteractor::OnButtonUp(wxMouseEvent &event)
788 {
789   //EVT_xxx_DOWN == EVT_xxx_UP - 1
790   //This is only needed if two mouse buttons are pressed at the same time.
791   //In wxWindows 2.4 and later: better use of wxMOUSE_BTN_RIGHT or 
792   //wxEVT_COMMAND_RIGHT_CLICK
793   if (!Enabled || (ActiveButton != (event.GetEventType()-1))) 
794     {
795     return;
796     }
797
798   // See report by Shang Mu / Kerry Loux on wxVTK mailing list
799     this->SetFocus();
800
801 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
802   SetEventInformationFlipY(event.GetX(), event.GetY(), 
803     event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
804 #endif
805   
806   if(ActiveButton == wxEVT_RIGHT_DOWN)
807   {
808 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
809     // new style
810     InvokeEvent(vtkCommand::RightButtonReleaseEvent, NULL);
811 #else            
812     // old style
813     InteractorStyle->OnRightButtonUp(event.ControlDown(), event.ShiftDown(),
814       event.GetX(), Size[1] - event.GetY() - 1);
815 #endif
816   }
817   else if(ActiveButton == wxEVT_LEFT_DOWN)
818   {
819 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
820     // new style
821     InvokeEvent(vtkCommand::LeftButtonReleaseEvent, NULL);
822 #else            
823     // old style
824     InteractorStyle->OnLeftButtonUp(event.ControlDown(), event.ShiftDown(),
825       event.GetX(), Size[1] - event.GetY() - 1);
826 #endif
827   }
828   else if(ActiveButton == wxEVT_MIDDLE_DOWN)
829   {
830 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
831     // new style
832     InvokeEvent(vtkCommand::MiddleButtonReleaseEvent, NULL);
833 #else            
834     // old style
835     InteractorStyle->OnMiddleButtonUp(event.ControlDown(), event.ShiftDown(),
836       event.GetX(), Size[1] - event.GetY() - 1);
837 #endif
838   }
839   //if the ActiveButton is realeased, then release mouse capture
840   if ((ActiveButton != wxEVT_NULL) && WX_USE_X_CAPTURE && UseCaptureMouse)
841   {
842     ReleaseMouse();
843   }
844   ActiveButton = wxEVT_NULL;
845 }
846 //---------------------------------------------------------------------------
847 void wxVTKRenderWindowInteractor::OnMouseWheel(wxMouseEvent& event)
848 {
849 // Mouse wheel was only added after VTK 4.4 (I think...)
850 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 4)
851   // new style
852   //Set vtk event information ... The numebr of wheel rotations is stored in
853   //the x varible.  y varible is zero
854   SetEventInformationFlipY(event.GetX() , event.GetY(), 
855                            event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
856   if(event.GetWheelRotation() > 0)
857     {
858       //Send event to VTK
859       InvokeEvent(vtkCommand::MouseWheelForwardEvent, NULL);
860     }
861   else
862     {
863       //Send event to VTK
864       InvokeEvent(vtkCommand::MouseWheelBackwardEvent, NULL);
865     }
866 #endif
867     
868 }
869
870 //---------------------------------------------------------------------------
871 #if wxCHECK_VERSION(2, 8, 0)
872 void wxVTKRenderWindowInteractor::OnMouseCaptureLost(wxMouseCaptureLostEvent& event)
873 {
874    if (ActiveButton != wxEVT_NULL)
875    {
876        //Maybe also invoke the button release event here
877    }
878    // Reset ActiveButton so that
879    // 1. we do not process mouse button up events any more,
880    // 2. the next button down event will be processed and call CaptureMouse().
881    // Otherwise ReleaseMouse() will be called
882    // without a previous CaptureMouse().
883    ActiveButton = wxEVT_NULL;
884 }
885 #endif
886
887 //---------------------------------------------------------------------------
888 void wxVTKRenderWindowInteractor::Render()
889 {
890 #if wxCHECK_VERSION(2, 8, 0)
891   int renderAllowed = !IsFrozen();
892 #else
893   int renderAllowed = 1;
894 #endif
895   if (renderAllowed && !RenderWhenDisabled)
896     {
897     //the user doesn't want us to render when the toplevel frame
898     //is disabled - first find the top level parent
899     wxWindow *topParent = wxGetTopLevelParent(this);
900     if (topParent)
901       {
902       //if it exists, check whether it's enabled
903       //if it's not enabeld, renderAllowed will be false
904       renderAllowed = topParent->IsEnabled();
905       }
906     }
907
908   if (renderAllowed)
909     {
910 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
911     wxGLCanvas::SetCurrent(*(this->context));
912 #endif
913     if(Handle && (Handle == GetHandleHack()) )
914       {
915       RenderWindow->Render();
916       }
917 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 2)
918     else if(GetHandleHack())
919       {
920       //this means the user has reparented us; let's adapt to the
921       //new situation by doing the WindowRemap dance
922       //store the new situation
923       Handle = GetHandleHack();
924       RenderWindow->SetNextWindowId(reinterpret_cast<void *>(Handle));
925       RenderWindow->WindowRemap();
926       RenderWindow->Render();
927       }
928 #endif
929     }
930 }
931 //---------------------------------------------------------------------------
932 void wxVTKRenderWindowInteractor::SetRenderWhenDisabled(int newValue)
933 {
934   //Change value of __RenderWhenDisabled ivar.
935   //If __RenderWhenDisabled is false (the default), this widget will not
936   //call Render() on the RenderWindow if the top level frame (i.e. the
937   //containing frame) has been disabled.
938
939   //This prevents recursive rendering during wxSafeYield() calls.
940   //wxSafeYield() can be called during the ProgressMethod() callback of
941   //a VTK object to have progress bars and other GUI elements updated -
942   //it does this by disabling all windows (disallowing user-input to
943   //prevent re-entrancy of code) and then handling all outstanding
944   //GUI events.
945         
946   //However, this often triggers an OnPaint() method for wxVTKRWIs,
947   //resulting in a Render(), resulting in Update() being called whilst
948   //still in progress.
949
950   RenderWhenDisabled = (bool)newValue;
951 }
952 //---------------------------------------------------------------------------
953 //
954 // Set the variable that indicates that we want a stereo capable window
955 // be created. This method can only be called before a window is realized.
956 //
957 void wxVTKRenderWindowInteractor::SetStereo(int capable)
958 {
959   if (Stereo != capable)
960     {
961     Stereo = capable;
962     RenderWindow->StereoCapableWindowOn();
963     RenderWindow->SetStereoTypeToCrystalEyes();
964     Modified();
965     }
966 }
967
968 //---------------------------------------------------------------------------
969 //
970 //
971 void wxVTKRenderWindowInteractor::PrintSelf(ostream& os, vtkIndent indent)
972 {
973   this->Superclass::PrintSelf(os, indent);
974 }
975
976
977 }
978 // LG : EO namespace bbwxvtk
979 //=======================================================================
980
981