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