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