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