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