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