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