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