]> Creatis software - bbtk.git/blob - packages/wxvtk/src/wxVTKRenderWindowInteractor.cxx
7668c982f11ca38264a55da20ccea5bfa1eeba8d
[bbtk.git] / packages / wxvtk / src / wxVTKRenderWindowInteractor.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: wxVTKRenderWindowInteractor.cxx,v $
32   Language:  C++
33   Date:      $Date: 2012/11/16 08:52:36 $
34   Version:   $Revision: 1.5 $
35
36 =========================================================================*/
37
38 #include <assert.h>
39
40 #include "wxVTKRenderWindowInteractor.h"
41
42 //This is needed for vtk 3.1 :
43 #ifndef VTK_MAJOR_VERSION
44 #  include "vtkVersion.h"
45 #endif
46
47 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
48 #  include "vtkCommand.h"
49 #else
50 #  include "vtkInteractorStyle.h"
51 #endif
52 #include "vtkDebugLeaks.h"
53
54 #ifdef __WXMAC__
55 #include "vtkCarbonRenderWindow.h"
56 #endif
57
58 //=======================================================================
59 // LG : NAMESPACE IS NECESSARY TO AVOID CONFLICTING SYMBOLS IN DYN LIBS
60 namespace bbwxvtk
61 {
62
63
64 //Keep this for compatibilty reason, this was introduced in wxGTK 2.4.0
65 #if (!wxCHECK_VERSION(2, 4, 0))
66 wxWindow* wxGetTopLevelParent(wxWindow *win)
67 {
68     while ( win && !win->IsTopLevel() )
69          win = win->GetParent();
70     return win;
71 }
72 #endif
73 }
74 // LG : EO namespace bbwxvtk
75 //=======================================================================
76
77 // To access objc calls on cocoa
78 #ifdef __WXCOCOA__
79 #ifdef VTK_USE_COCOA
80 #import <Cocoa/Cocoa.h>
81 // This trick is no longer need in VTK CVS, should get rid of that:
82 #define id Id
83 #else
84 #error Build mismatch you need both wxWidgets and VTK to be configure against Cocoa to work
85 #endif //VTK_USE_COCOA
86 #endif //__WXCOCOA__
87
88
89 //EED 2017-09-16 Migration wxWidgets 2.8 to 3.0
90 #if wxMAJOR_VERSION <= 2
91         #ifdef __WXGTK__
92                 #include <gdk/gdkx.h> // GDK_WINDOW_XWINDOW is found here in wxWidgets 2.8.0
93                 #include "gdk/gdkprivate.h"
94                 #if wxCHECK_VERSION(2, 8, 0)
95                         #ifdef __WXGTK20__
96                                 #include <wx/gtk/win_gtk.h>
97                         #else
98                                 #include <wx/gtk1/win_gtk.h>
99                         #endif
100                 #else
101                         #include <wx/gtk/win_gtk.h>
102                 #endif
103                 #define GetXWindow(wxwin) (wxwin)->m_wxwindow ? \
104                                           GDK_WINDOW_XWINDOW(GTK_PIZZA((wxwin)->m_wxwindow)->bin_window) : \
105                                           GDK_WINDOW_XWINDOW((wxwin)->m_widget->window)
106         #endif
107 #else
108         #ifdef __WXGTK__
109             #include <gdk/gdkx.h>
110             #include <gtk/gtk.h>
111         #endif
112 #endif
113
114
115
116 #ifdef __WXX11__
117 #include "wx/x11/privx.h"
118 #define GetXWindow(wxwin)   ((Window)(wxwin)->GetHandle())
119 #endif
120
121
122 //For more info on this class please go to:
123 //http://wxvtk.sf.net
124 //This hack is for some buggy wxGTK version:
125 #if wxCHECK_VERSION(2, 3, 2) && !wxCHECK_VERSION(2, 4, 1) && defined(__WXGTK__)
126 #  define WX_USE_X_CAPTURE 0
127 #else
128 #  define WX_USE_X_CAPTURE 1
129 #endif
130
131 #define ID_wxVTKRenderWindowInteractor_TIMER 1001
132
133 //=======================================================================
134 // LG : NAMESPACE IS NECESSARY TO AVOID CONFLICTING SYMBOLS IN DYN LIBS
135 namespace bbwxvtk
136 {
137
138 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
139 IMPLEMENT_DYNAMIC_CLASS(wxVTKRenderWindowInteractor, wxGLCanvas)
140 #else
141 IMPLEMENT_DYNAMIC_CLASS(wxVTKRenderWindowInteractor, wxWindow)
142 #endif  //__WXGTK__
143
144 //---------------------------------------------------------------------------
145 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
146 BEGIN_EVENT_TABLE(wxVTKRenderWindowInteractor, wxGLCanvas)
147 #else
148 BEGIN_EVENT_TABLE(wxVTKRenderWindowInteractor, wxWindow)
149 #endif //__WXGTK__
150   //refresh window by doing a Render
151   EVT_PAINT       (wxVTKRenderWindowInteractor::OnPaint)
152   EVT_ERASE_BACKGROUND(wxVTKRenderWindowInteractor::OnEraseBackground)
153   EVT_MOTION      (wxVTKRenderWindowInteractor::OnMotion)
154
155   //Bind the events to the event converters
156   EVT_LEFT_DOWN   (wxVTKRenderWindowInteractor::OnButtonDown)
157   EVT_MIDDLE_DOWN (wxVTKRenderWindowInteractor::OnButtonDown)
158   EVT_RIGHT_DOWN  (wxVTKRenderWindowInteractor::OnButtonDown)
159   EVT_LEFT_UP     (wxVTKRenderWindowInteractor::OnButtonUp)
160   EVT_MIDDLE_UP   (wxVTKRenderWindowInteractor::OnButtonUp)
161   EVT_RIGHT_UP    (wxVTKRenderWindowInteractor::OnButtonUp)
162 #if !(VTK_MAJOR_VERSION == 3 && VTK_MINOR_VERSION == 1)
163   EVT_ENTER_WINDOW(wxVTKRenderWindowInteractor::OnEnter)
164   EVT_LEAVE_WINDOW(wxVTKRenderWindowInteractor::OnLeave)
165   EVT_MOUSEWHEEL  (wxVTKRenderWindowInteractor::OnMouseWheel)
166   EVT_KEY_DOWN    (wxVTKRenderWindowInteractor::OnKeyDown)
167   EVT_KEY_UP      (wxVTKRenderWindowInteractor::OnKeyUp)
168   EVT_CHAR        (wxVTKRenderWindowInteractor::OnChar)
169 #endif
170   EVT_TIMER       (ID_wxVTKRenderWindowInteractor_TIMER, wxVTKRenderWindowInteractor::OnTimer)
171   EVT_SIZE        (wxVTKRenderWindowInteractor::OnSize)
172 END_EVENT_TABLE()
173
174 vtkCxxRevisionMacro(wxVTKRenderWindowInteractor, "$Revision: 1.5 $")
175 vtkInstantiatorNewMacro(wxVTKRenderWindowInteractor)
176
177 //---------------------------------------------------------------------------
178 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
179 #if (wxCHECK_VERSION(2, 8, 0))
180 wxVTKRenderWindowInteractor::wxVTKRenderWindowInteractor() : wxGLCanvas(0, -1, wxDefaultPosition), vtkRenderWindowInteractor()
181 #else
182 wxVTKRenderWindowInteractor::wxVTKRenderWindowInteractor() : wxGLCanvas(), vtkRenderWindowInteractor()
183 #endif
184 #else
185 wxVTKRenderWindowInteractor::wxVTKRenderWindowInteractor() : wxWindow(), vtkRenderWindowInteractor()
186 #endif //__WXGTK__
187       , timer(this, ID_wxVTKRenderWindowInteractor_TIMER)
188       , ActiveButton(wxEVT_NULL)
189       , RenderAllowed(0)
190       , Stereo(0)
191       , Handle(0)
192       , Created(true)
193       , RenderWhenDisabled(1)
194       , UseCaptureMouse(0)
195 {
196 #ifdef VTK_DEBUG_LEAKS
197   vtkDebugLeaks::ConstructClass("wxVTKRenderWindowInteractor");
198 #endif
199   this->RenderWindow = NULL;
200   this->SetRenderWindow(vtkRenderWindow::New());
201   this->RenderWindow->Delete();
202 }
203 //---------------------------------------------------------------------------
204 wxVTKRenderWindowInteractor::wxVTKRenderWindowInteractor(wxWindow *parent,
205                                                          wxWindowID id,
206                                                          const wxPoint &pos,
207                                                          const wxSize &size,
208                                                          long style,
209                                                          const wxString &name)
210 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
211       : wxGLCanvas(parent, id, pos, size, style, name), vtkRenderWindowInteractor()
212 #else
213       : wxWindow(parent, id, pos, size, style, name), vtkRenderWindowInteractor()
214 #endif //__WXGTK__
215       , timer(this, ID_wxVTKRenderWindowInteractor_TIMER)
216       , ActiveButton(wxEVT_NULL)
217       , RenderAllowed(0)
218       , Stereo(0)
219       , Handle(0)
220       , Created(true)
221       , RenderWhenDisabled(1)
222       , UseCaptureMouse(0)
223 {
224 #ifdef VTK_DEBUG_LEAKS
225   vtkDebugLeaks::ConstructClass("wxVTKRenderWindowInteractor");
226 #endif
227   this->RenderWindow = NULL;
228   this->SetRenderWindow(vtkRenderWindow::New());
229   this->RenderWindow->Delete();
230 #ifdef __WXMAC__
231   // On Mac (Carbon) we don't get notified of the initial window size with an EVT_SIZE event,
232   // so we update the size information of the interactor/renderwindow here
233   this->UpdateSize(size.x, size.y);
234 #endif
235 }
236 //---------------------------------------------------------------------------
237 wxVTKRenderWindowInteractor::~wxVTKRenderWindowInteractor()
238 {
239   SetRenderWindow(NULL);
240   SetInteractorStyle(NULL);
241 }
242 //---------------------------------------------------------------------------
243 wxVTKRenderWindowInteractor * wxVTKRenderWindowInteractor::New()
244 {
245   // we don't make use of the objectfactory, because we're not registered
246   return new wxVTKRenderWindowInteractor;
247 }
248 //---------------------------------------------------------------------------
249 void wxVTKRenderWindowInteractor::Initialize()
250 {
251   int *size = RenderWindow->GetSize();
252   // enable everything and start rendering
253   Enable();
254   //RenderWindow->Start();
255
256   // set the size in the render window interactor
257   Size[0] = size[0];
258   Size[1] = size[1];
259
260   // this is initialized
261   Initialized = 1;
262 }
263 //---------------------------------------------------------------------------
264 void wxVTKRenderWindowInteractor::Enable()
265 {
266   // if already enabled then done
267   if (Enabled)
268     return;
269
270   // that's it
271   Enabled = 1;
272 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
273   SetCurrent();
274 #endif
275   Modified();
276 }
277 //---------------------------------------------------------------------------
278 bool wxVTKRenderWindowInteractor::Enable(bool enable)
279 {
280 #if defined(__WXGTK__) && defined(USE_WXGLCANVAS)
281   return wxGLCanvas::Enable(enable);
282 #else
283   return wxWindow::Enable(enable);
284 #endif
285 }
286 //---------------------------------------------------------------------------
287 void wxVTKRenderWindowInteractor::Disable()
288 {
289   // if already disabled then done
290   if (!Enabled)
291     return;
292
293   // that's it (we can't remove the event handler like it should be...)
294   Enabled = 0;
295   Modified();
296 }
297 //---------------------------------------------------------------------------
298 void wxVTKRenderWindowInteractor::Start()
299 {
300   // the interactor cannot control the event loop
301   vtkErrorMacro( << "wxVTKRenderWindowInteractor::Start() "
302     "interactor cannot control event loop.");
303 }
304 //---------------------------------------------------------------------------
305 void wxVTKRenderWindowInteractor::UpdateSize(int x, int y)
306 {
307   if( RenderWindow )
308   {
309     // if the size changed tell render window
310     if ( x != Size[0] || y != Size[1] )
311     {
312       // adjust our (vtkRenderWindowInteractor size)
313       Size[0] = x;
314       Size[1] = y;
315       // and our RenderWindow's size
316       RenderWindow->SetSize(x, y);
317     }
318   }
319 }
320 //---------------------------------------------------------------------------
321 int wxVTKRenderWindowInteractor::CreateTimer(int WXUNUSED(timertype))
322 {
323   // it's a one shot timer
324   if (!timer.Start(10, TRUE))
325     assert(false);
326
327   return 1;
328   
329 }
330 //---------------------------------------------------------------------------
331 int wxVTKRenderWindowInteractor::DestroyTimer()
332 {
333   // do nothing
334   return 1;
335 }
336 //---------------------------------------------------------------------------
337 void wxVTKRenderWindowInteractor::OnTimer(wxTimerEvent& WXUNUSED(event))
338 {
339   if (!Enabled)
340     return;
341     
342 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
343     // new style
344     InvokeEvent(vtkCommand::TimerEvent, NULL);
345 #else
346     // old style
347     InteractorStyle->OnTimer();
348 #endif
349 }
350
351 //---------------------------------------------------------------------------
352 // NOTE on implementation:
353 // Bad luck you ended up in the only tricky place of this code.
354 // A few note, wxWidgets still refuse to provide such convenient method
355 // so I have to maintain it myself, eventhough this is completely integrated
356 // in wxPython...
357 // Anyway if this happen to break for you then compare to a recent version of wxPython
358 // and look for the function long wxPyGetWinHandle(wxWindow* win)
359 // in wxPython/src/helpers.cpp
360 long wxVTKRenderWindowInteractor::GetHandleHack()
361 {
362   //helper function to hide the MSW vs GTK stuff
363   long handle_tmp = 0;
364
365 // __WXMSW__ is for Win32
366 //__WXMAC__ stands for using Carbon C-headers, using either the CarbonLib/CFM or the native Mach-O builds (which then also use the latest features available)
367 // __WXGTK__ is for both gtk 1.2.x and gtk 2.x
368 #if defined(__WXMSW__) || defined(__WXMAC__)
369     handle_tmp = (long)this->GetHandle();
370 #endif //__WXMSW__
371
372 //__WXCOCOA__ stands for using the objective-c Cocoa API
373 #ifdef __WXCOCOA__
374    // Here is how to find the NSWindow
375    wxTopLevelWindow* toplevel = dynamic_cast<wxTopLevelWindow*>(
376      wxGetTopLevelParent( this ) );
377    if (toplevel != NULL )    
378    {
379      handle_tmp = (long)toplevel->GetNSWindow();
380    }
381    // The NSView will be deducted from 
382    // [(NSWindow*)Handle contentView]
383    // if only I knew how to write that in c++
384 #endif //__WXCOCOA__
385
386     // Find and return the actual X-Window.
387 #if defined(__WXGTK__) || defined(__WXX11__)
388
389         //EED 2017-09-16 Migration wxWidgets 2.8 to 3.0
390         #if wxMAJOR_VERSION <= 2
391                 return (long)GetXWindow(this);
392         #else
393                 GdkWindow* Win = gtk_widget_get_window( (GtkWidget *) GetHandle() );
394                 return (long int)GDK_WINDOW_XDISPLAY(Win);
395         #endif
396
397 #endif
398
399 //#ifdef __WXMOTIF__
400 //    handle_tmp = (long)this->GetXWindow();
401 //#endif
402
403   return handle_tmp;
404 }
405 //---------------------------------------------------------------------------
406 void wxVTKRenderWindowInteractor::OnPaint(wxPaintEvent& WXUNUSED(event))
407 {
408   //must always be here
409   wxPaintDC pDC(this);
410
411   //do it here rather than in the cstor: this is safer.
412   if(!Handle)
413   {
414     Handle = GetHandleHack();
415     RenderWindow->SetWindowId(reinterpret_cast<void *>(Handle));
416 #ifdef __WXMSW__
417     RenderWindow->SetParentId(reinterpret_cast<void *>(this->GetParent()->GetHWND()));
418 #endif //__WXMSW__
419   }
420   // get vtk to render to the wxWindows
421   Render();
422 #ifdef __WXMAC__
423   // This solves a problem with repainting after a window resize
424   // See also: http://sourceforge.net/mailarchive/forum.php?thread_id=31690967&forum_id=41789
425   vtkCarbonRenderWindow* rwin = vtkCarbonRenderWindow::SafeDownCast(RenderWindow);
426   if( rwin )
427   {
428     rwin->UpdateGLRegion();
429   }
430 #endif
431 }
432 //---------------------------------------------------------------------------
433 void wxVTKRenderWindowInteractor::OnEraseBackground(wxEraseEvent &event)
434 {
435   //turn off background erase to reduce flickering on MSW
436   event.Skip(false);
437 }
438 //---------------------------------------------------------------------------
439 void wxVTKRenderWindowInteractor::OnSize(wxSizeEvent& WXUNUSED(event))
440 {
441   int w, h;
442   GetClientSize(&w, &h);
443   UpdateSize(w, h);
444
445   if (!Enabled) 
446     {
447     return;
448     }
449
450 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
451   InvokeEvent(vtkCommand::ConfigureEvent, NULL);
452 #endif
453   //this will check for Handle
454   //Render();
455 }
456 //---------------------------------------------------------------------------
457 void wxVTKRenderWindowInteractor::OnMotion(wxMouseEvent &event)
458 {
459  if (!Enabled) 
460     {
461     return;
462     }
463 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
464   SetEventInformationFlipY(event.GetX(), event.GetY(), 
465     event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
466
467   InvokeEvent(vtkCommand::MouseMoveEvent, NULL);
468 #else
469   InteractorStyle->OnMouseMove(event.ControlDown(), event.ShiftDown(),
470     event.GetX(), Size[1] - event.GetY() - 1);
471 #endif
472 }
473 //---------------------------------------------------------------------------
474 #if !(VTK_MAJOR_VERSION == 3 && VTK_MINOR_VERSION == 1)
475 void wxVTKRenderWindowInteractor::OnEnter(wxMouseEvent &event)
476 {
477   if (!Enabled) 
478     {
479     return;
480     }
481
482 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
483     // new style
484   SetEventInformationFlipY(event.GetX(), event.GetY(), 
485       event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
486
487   InvokeEvent(vtkCommand::EnterEvent, NULL);
488 #else
489     // old style
490   InteractorStyle->OnEnter(event.ControlDown(), event.ShiftDown(),
491       event.GetX(), Size[1] - event.GetY() - 1);  
492 #endif
493 }
494 //---------------------------------------------------------------------------
495 void wxVTKRenderWindowInteractor::OnLeave(wxMouseEvent &event)
496 {
497   if (!Enabled) 
498     {
499     return;
500     }
501
502 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
503     // new style
504   SetEventInformationFlipY(event.GetX(), event.GetY(), 
505       event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
506
507   InvokeEvent(vtkCommand::LeaveEvent, NULL);
508 #else
509     // old style
510   InteractorStyle->OnLeave(event.ControlDown(), event.ShiftDown(),
511       event.GetX(), Size[1] - event.GetY() - 1);  
512 #endif
513 }
514 //---------------------------------------------------------------------------
515 void wxVTKRenderWindowInteractor::OnKeyDown(wxKeyEvent &event)
516 {
517   if (!Enabled) 
518     {
519     return;
520     }
521
522 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
523     // new style
524   int keycode = event.GetKeyCode();
525   char key = '\0';
526   if (((unsigned int)keycode) < 256)
527   {
528     // TODO: Unicode in non-Unicode mode ??
529     key = (char)keycode;
530   }
531
532   // we don't get a valid mouse position inside the key event on every platform
533   // so we retrieve the mouse position explicitly and pass it along
534   wxPoint mousePos = ScreenToClient(wxGetMousePosition());
535   SetEventInformationFlipY(mousePos.x, mousePos.y, 
536                            event.ControlDown(), event.ShiftDown(), key, 0, NULL);
537   InvokeEvent(vtkCommand::KeyPressEvent, NULL);
538 #else
539   InteractorStyle->OnKeyDown(event.ControlDown(), event.ShiftDown(), 
540     event.GetKeyCode(), 1);
541 #endif
542   event.Skip();
543 }
544 //---------------------------------------------------------------------------
545 void wxVTKRenderWindowInteractor::OnKeyUp(wxKeyEvent &event)
546 {
547   if (!Enabled) 
548     {
549     return;
550     }
551
552 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
553     // new style
554   int keycode = event.GetKeyCode();
555   char key = '\0';
556   if (((unsigned int)keycode) < 256)
557   {
558     // TODO: Unicode in non-Unicode mode ??
559     key = (char)keycode;
560   }
561
562   // we don't get a valid mouse position inside the key event on every platform
563   // so we retrieve the mouse position explicitly and pass it along
564   wxPoint mousePos = ScreenToClient(wxGetMousePosition());
565   SetEventInformationFlipY(mousePos.x, mousePos.y, 
566                            event.ControlDown(), event.ShiftDown(), key, 0, NULL);
567   InvokeEvent(vtkCommand::KeyReleaseEvent, NULL);
568 #else
569   InteractorStyle->OnKeyUp(event.ControlDown(), event.ShiftDown(), 
570     event.GetKeyCode(), 1);
571 #endif
572   event.Skip();
573 }
574 #endif //!(VTK_MAJOR_VERSION == 3 && VTK_MINOR_VERSION == 1)
575  //---------------------------------------------------------------------------
576 void wxVTKRenderWindowInteractor::OnChar(wxKeyEvent &event)
577 {
578   if (!Enabled) 
579     {
580     return;
581     }
582     
583 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
584   // new style
585   int keycode = event.GetKeyCode();
586   char key = '\0';
587   if (((unsigned int)keycode) < 256)
588     {
589     // TODO: Unicode in non-Unicode mode ??
590     key = (char)keycode;
591     }
592
593   // we don't get a valid mouse position inside the key event on every platform
594   // so we retrieve the mouse position explicitly and pass it along
595   wxPoint mousePos = ScreenToClient(wxGetMousePosition());
596   SetEventInformationFlipY(mousePos.x, mousePos.y, 
597                            event.ControlDown(), event.ShiftDown(), key, 0, NULL);
598   InvokeEvent(vtkCommand::CharEvent, NULL);
599 #endif
600   event.Skip();
601 }
602 //---------------------------------------------------------------------------
603 void wxVTKRenderWindowInteractor::OnButtonDown(wxMouseEvent &event)
604 {
605   if (!Enabled || (ActiveButton != wxEVT_NULL))
606     {
607     return;
608     }
609   ActiveButton = event.GetEventType();
610
611     // On Mac (Carbon) and Windows we don't automatically get the focus when
612     // you click inside the window
613     // we therefore set the focus explicitly
614     // Apparently we need that on linux (GTK) too:
615     this->SetFocus();
616
617 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
618   SetEventInformationFlipY(event.GetX(), event.GetY(), 
619     event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
620 #endif
621
622   if(event.RightDown())
623   {
624 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
625     // new style
626     InvokeEvent(vtkCommand::RightButtonPressEvent, NULL);
627 #else            
628     // old style
629     InteractorStyle->OnRightButtonDown(event.ControlDown(), event.ShiftDown(),
630       event.GetX(), Size[1] - event.GetY() - 1);
631 #endif
632   }
633   else if(event.LeftDown())
634   {
635 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
636     // new style
637     InvokeEvent(vtkCommand::LeftButtonPressEvent, NULL);
638 #else            
639     // old style
640     InteractorStyle->OnLeftButtonDown(event.ControlDown(),  event.ShiftDown(),
641       event.GetX(), Size[1] - event.GetY() - 1);
642 #endif
643   }
644   else if(event.MiddleDown())
645   {
646 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
647     // new style
648     InvokeEvent(vtkCommand::MiddleButtonPressEvent, NULL);
649 #else            
650     // old style
651     InteractorStyle->OnMiddleButtonDown(event.ControlDown(), event.ShiftDown(),
652       event.GetX(), Size[1] - event.GetY() - 1);
653 #endif
654   }
655   //save the button and capture mouse until the button is released
656   //Only if :
657   //1. it is possible (WX_USE_X_CAPTURE)
658   //2. user decided to.
659   if ((ActiveButton != wxEVT_NULL) && WX_USE_X_CAPTURE && UseCaptureMouse)
660   {
661     CaptureMouse();
662   }
663 }
664 //---------------------------------------------------------------------------
665 void wxVTKRenderWindowInteractor::OnButtonUp(wxMouseEvent &event)
666 {
667   //EVT_xxx_DOWN == EVT_xxx_UP - 1
668   //This is only needed if two mouse buttons are pressed at the same time.
669   //In wxWindows 2.4 and later: better use of wxMOUSE_BTN_RIGHT or 
670   //wxEVT_COMMAND_RIGHT_CLICK
671   if (!Enabled || (ActiveButton != (event.GetEventType()-1))) 
672     {
673     return;
674     }
675
676 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
677   SetEventInformationFlipY(event.GetX(), event.GetY(), 
678     event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
679 #endif
680   
681   if(ActiveButton == wxEVT_RIGHT_DOWN)
682   {
683 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
684     // new style
685     InvokeEvent(vtkCommand::RightButtonReleaseEvent, NULL);
686 #else            
687     // old style
688     InteractorStyle->OnRightButtonUp(event.ControlDown(), event.ShiftDown(),
689       event.GetX(), Size[1] - event.GetY() - 1);
690 #endif
691   }
692   else if(ActiveButton == wxEVT_LEFT_DOWN)
693   {
694 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
695     // new style
696     InvokeEvent(vtkCommand::LeftButtonReleaseEvent, NULL);
697 #else            
698     // old style
699     InteractorStyle->OnLeftButtonUp(event.ControlDown(), event.ShiftDown(),
700       event.GetX(), Size[1] - event.GetY() - 1);
701 #endif
702   }
703   else if(ActiveButton == wxEVT_MIDDLE_DOWN)
704   {
705 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 0)
706     // new style
707     InvokeEvent(vtkCommand::MiddleButtonReleaseEvent, NULL);
708 #else            
709     // old style
710     InteractorStyle->OnMiddleButtonUp(event.ControlDown(), event.ShiftDown(),
711       event.GetX(), Size[1] - event.GetY() - 1);
712 #endif
713   }
714   //if the ActiveButton is realeased, then release mouse capture
715   if ((ActiveButton != wxEVT_NULL) && WX_USE_X_CAPTURE && UseCaptureMouse)
716   {
717     ReleaseMouse();
718   }
719   ActiveButton = wxEVT_NULL;
720 }
721 //---------------------------------------------------------------------------
722 void wxVTKRenderWindowInteractor::OnMouseWheel(wxMouseEvent& event)
723 {
724 // Mouse wheel was only added after VTK 4.4 (I think...)
725 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 2)
726   // new style
727   //Set vtk event information ... The numebr of wheel rotations is stored in
728   //the x varible.  y varible is zero
729   SetEventInformationFlipY(event.GetWheelRotation() / event.GetWheelDelta(), 0, 
730                            event.ControlDown(), event.ShiftDown(), '\0', 0, NULL);
731   if(event.GetWheelRotation() > 0)
732     {
733       //Send event to VTK
734       InvokeEvent(vtkCommand::MouseWheelForwardEvent, NULL);
735     }
736   else
737     {
738       //Send event to VTK
739       InvokeEvent(vtkCommand::MouseWheelBackwardEvent, NULL);
740     }
741 #endif
742     
743 }
744
745 //---------------------------------------------------------------------------
746 void wxVTKRenderWindowInteractor::Render()
747 {
748   RenderAllowed = 1;
749   if (!RenderWhenDisabled)
750     {
751     //the user doesn't want us to render when the toplevel frame
752     //is disabled - first find the top level parent
753     wxWindow *topParent = wxGetTopLevelParent(this);
754     if (topParent)
755       {
756       //if it exists, check whether it's enabled
757       //if it's not enabeld, RenderAllowed will be false
758       RenderAllowed = topParent->IsEnabled();
759       }
760     }
761
762   if (RenderAllowed)
763     {
764     if(Handle && (Handle == GetHandleHack()) )
765       {
766       RenderWindow->Render();
767       }
768 #if VTK_MAJOR_VERSION > 4 || (VTK_MAJOR_VERSION == 4 && VTK_MINOR_VERSION > 2)
769     else if(GetHandleHack())
770       {
771       //this means the user has reparented us; let's adapt to the
772       //new situation by doing the WindowRemap dance
773       //store the new situation
774       Handle = GetHandleHack();
775       RenderWindow->SetNextWindowId(reinterpret_cast<void *>(Handle));
776       RenderWindow->WindowRemap();
777       RenderWindow->Render();
778       }
779 #endif
780     }
781 }
782 //---------------------------------------------------------------------------
783 void wxVTKRenderWindowInteractor::SetRenderWhenDisabled(int newValue)
784 {
785   //Change value of __RenderWhenDisabled ivar.
786   //If __RenderWhenDisabled is false (the default), this widget will not
787   //call Render() on the RenderWindow if the top level frame (i.e. the
788   //containing frame) has been disabled.
789
790   //This prevents recursive rendering during wxSafeYield() calls.
791   //wxSafeYield() can be called during the ProgressMethod() callback of
792   //a VTK object to have progress bars and other GUI elements updated -
793   //it does this by disabling all windows (disallowing user-input to
794   //prevent re-entrancy of code) and then handling all outstanding
795   //GUI events.
796         
797   //However, this often triggers an OnPaint() method for wxVTKRWIs,
798   //resulting in a Render(), resulting in Update() being called whilst
799   //still in progress.
800
801   RenderWhenDisabled = (bool)newValue;
802 }
803 //---------------------------------------------------------------------------
804 //
805 // Set the variable that indicates that we want a stereo capable window
806 // be created. This method can only be called before a window is realized.
807 //
808 void wxVTKRenderWindowInteractor::SetStereo(int capable)
809 {
810   if (Stereo != capable)
811     {
812     Stereo = capable;
813     RenderWindow->StereoCapableWindowOn();
814     RenderWindow->SetStereoTypeToCrystalEyes();
815     Modified();
816     }
817 }
818
819 //---------------------------------------------------------------------------
820 //
821 //
822 void wxVTKRenderWindowInteractor::PrintSelf(ostream& os, vtkIndent indent)
823 {
824   this->Superclass::PrintSelf(os, indent);
825 }
826
827
828 }
829 // LG : EO namespace bbwxvtk
830 //=======================================================================
831
832