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