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