Salome HOME
Merge branch 'pre/V8_2_BR' of https://git.salome-platform.org/git/modules/gui into...
[modules/gui.git] / src / SVTK / SVTK_RenderWindowInteractor.cxx
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //  SALOME VTKViewer : build VTK viewer into Salome desktop
24 //  File   : 
25 //  Author : 
26
27 #include "SVTK_RenderWindowInteractor.h"
28
29 #include "SVTK_InteractorStyle.h"
30 #include "SVTK_Renderer.h"
31 #include "SVTK_Functor.h"
32 #include "SALOME_Actor.h"
33
34 // QT Includes
35 // Put Qt includes before the X11 includes which #define the symbol None
36 // (see SVTK_SpaceMouse.h) to avoid the compilation error.
37 #if !defined(WIN32) && !defined(__APPLE__)
38 #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
39 #include <xcb/xcb.h>
40 #endif
41 #include <QX11Info>
42 #endif
43 #include <QMouseEvent>
44
45 #include "SVTK_SpaceMouse.h" 
46 #include "SVTK_Event.h" 
47
48 #include "VTKViewer_Algorithm.h"
49
50 // VTK Includes
51 #include <vtkObjectFactory.h>
52 #include <vtkRendererCollection.h>
53 #include <vtkRenderWindow.h>
54 #include <vtkGenericRenderWindowInteractor.h>
55 #include <vtkCallbackCommand.h>
56 #include <vtkCommand.h>
57 #include <vtkPicker.h>
58 #include <vtkCamera.h>
59
60 static bool GENERATE_SUIT_EVENTS = true;
61 static bool FOCUS_UNDER_MOUSE = false;
62
63 // workaround about the bug in vtkImplicitPlaneWidget class
64 // that eats mouse button release event
65 // causing clipping plane preview in SMESH sticking up
66 #define Fix_Of_vtkImplicitPlaneWidget_bug
67
68 /*!
69   Constructor
70 */
71 QVTK_RenderWindowInteractor
72 ::QVTK_RenderWindowInteractor(QWidget* theParent, 
73                               const char* theName):
74   QWidget(theParent),
75   myRenderWindow(vtkRenderWindow::New())
76 {
77   setAttribute( Qt::WA_PaintOnScreen );
78   setAttribute( Qt::WA_NoSystemBackground );
79
80   setObjectName(theName);
81
82   setMouseTracking(true);
83
84   myRenderWindow->Delete();
85   myRenderWindow->DoubleBufferOn();
86
87 #if !defined WIN32 && !defined __APPLE__
88   myRenderWindow->SetDisplayId((void*)QX11Info::display());
89 #endif
90   myRenderWindow->SetWindowId((void*)winId());
91 }
92
93 /*!
94   To initialize by vtkGenericRenderWindowInteractor instance
95 */
96 void 
97 QVTK_RenderWindowInteractor
98 ::Initialize(vtkGenericRenderWindowInteractor* theDevice)
99 {
100   if ( GetDevice() )
101     myDevice->SetRenderWindow( NULL );
102
103   myDevice = theDevice;
104
105   if ( theDevice )
106     theDevice->SetRenderWindow( getRenderWindow() );
107 }
108
109 /*!
110   Destructor
111 */
112 QVTK_RenderWindowInteractor
113 ::~QVTK_RenderWindowInteractor() 
114 {
115 #if !defined WIN32 && !defined __APPLE__
116 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
117   SVTK_SpaceMouseX* aSpaceMouse = SVTK_SpaceMouseX::getInstance();
118   if ( aSpaceMouse && aSpaceMouse->isSpaceMouseOn() )
119     aSpaceMouse->close( QX11Info::display() );
120 #else
121   SVTK_SpaceMouseXCB* aSpaceMouse = SVTK_SpaceMouseXCB::getInstance();
122   if ( aSpaceMouse && aSpaceMouse->isSpaceMouseOn() )
123     aSpaceMouse->close( QX11Info::connection() );
124 #endif
125 #endif
126 }
127
128
129 /*!
130   \return corresponding render window interactor
131 */
132 vtkGenericRenderWindowInteractor* 
133 QVTK_RenderWindowInteractor
134 ::GetDevice()
135 {
136   return myDevice.GetPointer();
137 }
138
139 /*!
140   \return corresponding render window
141 */
142 vtkRenderWindow*
143 QVTK_RenderWindowInteractor
144 ::getRenderWindow()
145 {
146   return myRenderWindow.GetPointer();
147 }
148
149 /*!
150   Just to simplify usage of its device (vtkGenericRenderWindowInteractor)
151 */
152 void
153 QVTK_RenderWindowInteractor
154 ::InvokeEvent(unsigned long theEvent, void* theCallData)
155 {
156   GetDevice()->InvokeEvent(theEvent,theCallData);
157 }
158
159 /*!
160   Get paint engine for the scene
161 */
162 QPaintEngine* QVTK_RenderWindowInteractor::paintEngine() const
163 {
164   return 0;
165 }
166
167 /*!
168   Need for initial contents display on Win32
169 */
170 void
171 QVTK_RenderWindowInteractor
172 ::show()
173 {
174   QWidget::show();
175   update(); // needed for initial contents display on Win32
176 }
177
178 /*!
179   To implement final initialization, just before the widget is displayed
180 */
181 void
182 QVTK_RenderWindowInteractor
183 ::polish()
184 {
185   // Final initialization just before the widget is displayed
186   GetDevice()->SetSize(width(),height());
187   if(!GetDevice()->GetInitialized() && GetDevice()->GetRenderWindow()){
188     GetDevice()->Initialize();
189     GetDevice()->ConfigureEvent();
190   }
191 }
192
193 /*!
194   To adjust widget and vtkRenderWindow size
195 */
196 void
197 QVTK_RenderWindowInteractor
198 ::resize(int w, int h) 
199 {
200   GetDevice()->UpdateSize(w,h);
201 }
202
203 /*!
204   Custom paint event handler
205 */
206 void
207 QVTK_RenderWindowInteractor
208 ::paintEvent( QPaintEvent* theEvent ) 
209 {
210   GetDevice()->CreateTimer(VTKI_TIMER_FIRST);
211 }
212
213
214 /*!
215   Custom resize event handler
216 */
217 void
218 QVTK_RenderWindowInteractor
219 ::resizeEvent( QResizeEvent* theEvent )
220 {
221   int* aSize = getRenderWindow()->GetSize();
222   int aWidth = aSize[0];
223   int aHeight = aSize[1];
224
225   GetDevice()->UpdateSize(width(),height());
226
227   if(isVisible() && aWidth && aHeight){
228     if( aWidth != width() || aHeight != height() ) {
229       vtkRendererCollection * aRenderers = getRenderWindow()->GetRenderers();
230       aRenderers->InitTraversal();
231       double aCoeff = 1.0;
232       if(vtkRenderer *aRenderer = aRenderers->GetNextItem()) {
233         vtkCamera *aCamera = aRenderer->GetActiveCamera();
234         double aScale = aCamera->GetParallelScale();
235         if((aWidth - width())*(aHeight - height()) > 0)
236           aCoeff = sqrt(double(aWidth)/double(width())*double(height())/double(aHeight));
237         else
238           aCoeff = double(aWidth)/double(width());
239         aCamera->SetParallelScale(aScale*aCoeff);
240       }
241     }
242   }
243
244   update(); 
245 }
246
247
248
249 /*!
250   Custom context menu event handler
251 */
252 void
253 QVTK_RenderWindowInteractor
254 ::contextMenuEvent( QContextMenuEvent* event )
255 {}
256
257 /*!
258   Custom mouse move event handler
259 */
260 void
261 QVTK_RenderWindowInteractor
262 ::mouseMoveEvent( QMouseEvent* event ) 
263 {
264   GetDevice()->SetEventInformationFlipY(event->x(), 
265                                         event->y(),
266                                         event->modifiers() & Qt::ControlModifier,
267                                         event->modifiers() & Qt::ShiftModifier);
268   GetDevice()->MouseMoveEvent();
269 }
270
271
272 /*!
273   Custom mouse press event handler
274 */
275 void
276 QVTK_RenderWindowInteractor
277 ::mousePressEvent( QMouseEvent* event ) 
278 {
279   GetDevice()->SetEventInformationFlipY(event->x(), 
280                                         event->y(),
281                                         event->modifiers() & Qt::ControlModifier,
282                                         event->modifiers() & Qt::ShiftModifier);
283   if( event->button() & Qt::LeftButton )
284     GetDevice()->LeftButtonPressEvent();
285   else if( event->button() & Qt::MidButton )
286     GetDevice()->MiddleButtonPressEvent();
287   else if( event->button() & Qt::RightButton )
288     GetDevice()->RightButtonPressEvent();
289 }
290
291
292 /*!
293   Custom mouse release event handler
294 */
295 void
296 QVTK_RenderWindowInteractor
297 ::mouseReleaseEvent( QMouseEvent *event )
298 {
299   GetDevice()->SetEventInformationFlipY(event->x(), 
300                                         event->y(),
301                                         event->modifiers() & Qt::ControlModifier,
302                                         event->modifiers() & Qt::ShiftModifier);
303
304   if( event->button() & Qt::LeftButton )
305     GetDevice()->LeftButtonReleaseEvent();
306   else if( event->button() & Qt::MidButton )
307     GetDevice()->MiddleButtonReleaseEvent();
308   else if( event->button() & Qt::RightButton ) {
309 #if defined(Fix_Of_vtkImplicitPlaneWidget_bug)
310     GetDevice()->SetEventInformationFlipY( -99999, -99999,
311                                            event->modifiers() & Qt::ControlModifier,
312                                            event->modifiers() & Qt::ShiftModifier);
313     bool blocked = blockSignals( true );
314     GetDevice()->LeftButtonPressEvent();
315     GetDevice()->LeftButtonReleaseEvent();
316     blockSignals( blocked );
317     GetDevice()->SetEventInformationFlipY(event->x(),
318                                           event->y(),
319                                           event->modifiers() & Qt::ControlModifier,
320                                           event->modifiers() & Qt::ShiftModifier);
321 #endif
322     GetDevice()->RightButtonReleaseEvent();
323   }
324 }
325
326
327 /*!
328   Custom mouse double click event handler
329 */
330 void
331 QVTK_RenderWindowInteractor
332 ::mouseDoubleClickEvent( QMouseEvent* event )
333 {}
334
335
336 /*!
337   Custom mouse wheel event handler
338 */
339 void
340 QVTK_RenderWindowInteractor
341 ::wheelEvent( QWheelEvent* event )
342 {
343   activateWindow();
344   setFocus();
345   GetDevice()->SetEventInformationFlipY(event->x(), 
346                                         event->y(),
347                                         event->modifiers() & Qt::ControlModifier,
348                                         event->modifiers() & Qt::ShiftModifier);
349   if ( event->delta()>0)
350     GetDevice()->MouseWheelForwardEvent();
351   else
352     GetDevice()->MouseWheelBackwardEvent();
353 }
354
355
356 /*!
357   Custom key press event handler
358 */
359 void
360 QVTK_RenderWindowInteractor
361 ::keyPressEvent( QKeyEvent* event ) 
362 {
363   GetDevice()->SetKeyEventInformation(event->modifiers() & Qt::ControlModifier,
364                                       event->modifiers() & Qt::ShiftModifier,
365                                       event->key());
366   GetDevice()->KeyPressEvent();
367   GetDevice()->CharEvent();
368 }
369
370 /*!
371   Custom key release event handler
372 */
373 void
374 QVTK_RenderWindowInteractor
375 ::keyReleaseEvent( QKeyEvent * event ) 
376 {
377   GetDevice()->SetKeyEventInformation(event->modifiers() & Qt::ControlModifier,
378                                       event->modifiers() & Qt::ShiftModifier,
379                                       event->key());
380   GetDevice()->KeyReleaseEvent();
381 }
382
383
384 /*!
385   Custom enter event handler
386 */
387 void  
388 QVTK_RenderWindowInteractor
389 ::enterEvent( QEvent* event )
390 {
391   if(FOCUS_UNDER_MOUSE){
392     activateWindow();
393     setFocus();
394   }
395   GetDevice()->EnterEvent();
396 }
397
398 /*!
399   Custom leave event handler
400 */
401 void  
402 QVTK_RenderWindowInteractor
403 ::leaveEvent( QEvent * )
404 {
405   GetDevice()->LeaveEvent();
406 }
407
408 /*!
409   Reimplemented from QWidget in order to set window - receiver
410   of space mouse events. 
411 */
412 void  
413 QVTK_RenderWindowInteractor
414 ::focusInEvent( QFocusEvent* event )
415 {
416   QWidget::focusInEvent( event );
417
418 #if !defined WIN32 && !defined __APPLE__
419   // register set space mouse events receiver
420 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
421   SVTK_SpaceMouseX* aSpaceMouse = SVTK_SpaceMouseX::getInstance();
422   if ( aSpaceMouse )
423   {
424     if ( !aSpaceMouse->isSpaceMouseOn() )
425       // initialize 3D space mouse driver 
426       aSpaceMouse->initialize( QX11Info::display(), winId() );
427     else
428       aSpaceMouse->setWindow( QX11Info::display(), winId() );
429   }
430 #else
431   SVTK_SpaceMouseXCB* aSpaceMouse = SVTK_SpaceMouseXCB::getInstance();
432   if ( aSpaceMouse )
433   {
434     if ( !aSpaceMouse->isSpaceMouseOn() )
435       // initialize 3D space mouse driver
436       aSpaceMouse->initialize( QX11Info::connection(), winId() );
437     else
438       aSpaceMouse->setWindow( QX11Info::connection(), winId() );
439   }
440 #endif
441 #endif
442 }
443
444 /*!
445   Reimplemented from QWidget in order to set window - receiver
446   of space mouse events. 
447 */
448 void  
449 QVTK_RenderWindowInteractor
450 ::focusOutEvent ( QFocusEvent* event )
451 {
452   QWidget::focusOutEvent( event );
453
454 #if !defined WIN32 && !defined __APPLE__
455 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
456   // unregister set space mouse events receiver
457   SVTK_SpaceMouseX* aSpaceMouse = SVTK_SpaceMouseX::getInstance();
458   if ( aSpaceMouse && aSpaceMouse->isSpaceMouseOn() )
459     aSpaceMouse->setWindow( QX11Info::display(), 0 );
460 #else
461   SVTK_SpaceMouseXCB* aSpaceMouse = SVTK_SpaceMouseXCB::getInstance();
462   if ( aSpaceMouse && aSpaceMouse->isSpaceMouseOn() )
463     aSpaceMouse->setWindow( QX11Info::connection(), 0 );
464 #endif
465 #endif
466 }
467
468 // TODO (QT5 PORTING) Below is a temporary solution, to allow compiling with Qt 5
469 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
470 #if defined(WIN32)
471
472 /*!
473   To handle native Win32 events (from such devices as SpaceMouse)
474 */
475 bool QVTK_RenderWindowInteractor::winEvent( MSG* msg, long* result )
476 {
477   // TODO: Implement event handling for SpaceMouse
478   return QWidget::winEvent( msg, result);
479 }
480
481 #elif !defined(__APPLE__)
482 /*!
483   To handle native X11 events (from such devices as SpaceMouse)
484 */
485 bool
486 QVTK_RenderWindowInteractor
487 ::x11Event( XEvent *xEvent )
488 {
489   // handle 3d space mouse events
490   if ( SVTK_SpaceMouseX* aSpaceMouse = SVTK_SpaceMouseX::getInstance() )
491   {
492     if ( aSpaceMouse->isSpaceMouseOn() && xEvent->type == ClientMessage )
493     {
494       SVTK_SpaceMouse::MoveEvent anEvent;
495       int type = aSpaceMouse->translateEvent( QX11Info::display(), xEvent, &anEvent, 1.0, 1.0 );
496       switch ( type )
497       {
498       case SVTK_SpaceMouse::SpaceMouseMove:
499               GetDevice()->InvokeEvent( SVTK::SpaceMouseMoveEvent, anEvent.data );
500               break;
501       case SVTK_SpaceMouse::SpaceButtonPress:
502               GetDevice()->InvokeEvent( SVTK::SpaceMouseButtonEvent, &anEvent.button );
503               break;
504       case SVTK_SpaceMouse::SpaceButtonRelease:
505               break;
506       }
507       return true; // stop handling the event
508     }
509   }
510
511   return QWidget::x11Event( xEvent );
512 }
513
514 #endif
515
516 #else // QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
517
518 bool QVTK_RenderWindowInteractor
519 ::nativeEvent(const QByteArray& eventType, void* message, long* result)
520 {
521 #if defined(WIN32)
522   // TODO: WIN32-related implementation
523 #elif !defined(__APPLE__)
524   if ( eventType == "xcb_generic_event_t" )
525   {
526     xcb_generic_event_t* ev = static_cast<xcb_generic_event_t *>(message);
527 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
528     // TODO: this code is never called
529     if ( SVTK_SpaceMouseX* aSpaceMouse = SVTK_SpaceMouseX::getInstance() )
530 #else
531     if ( SVTK_SpaceMouseXCB* aSpaceMouse = SVTK_SpaceMouseXCB::getInstance() )
532 #endif
533     {
534       if ( aSpaceMouse->isSpaceMouseOn() && ev->response_type == XCB_CLIENT_MESSAGE )
535       {
536         SVTK_SpaceMouse::MoveEvent anEvent;
537 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
538         // TODO: this code is never called
539         int type = aSpaceMouse->translateEvent( QX11Info::display(), xEvent, &anEvent, 1.0, 1.0 );
540 #else
541         int type = aSpaceMouse->translateEvent( QX11Info::connection(), (xcb_client_message_event_t*)ev, &anEvent, 1.0, 1.0 );
542 #endif
543         switch ( type )
544         {
545         case SVTK_SpaceMouse::SpaceMouseMove:
546                 GetDevice()->InvokeEvent( SVTK::SpaceMouseMoveEvent, anEvent.data );
547                 break;
548         case SVTK_SpaceMouse::SpaceButtonPress:
549                 GetDevice()->InvokeEvent( SVTK::SpaceMouseButtonEvent, &anEvent.button );
550                 break;
551         case SVTK_SpaceMouse::SpaceButtonRelease:
552                 break;
553         }
554         return true; // stop handling the event
555       }
556     }
557   }
558 #endif
559  return QWidget::nativeEvent( eventType, message, result );
560 }
561 #endif
562 /*!
563   Constructor
564 */
565 SVTK_RenderWindowInteractor
566 ::SVTK_RenderWindowInteractor(QWidget* theParent, 
567                                const char* theName):
568   QVTK_RenderWindowInteractor(theParent,theName),
569   myEventCallbackCommand(vtkCallbackCommand::New())
570 {
571   myEventCallbackCommand->Delete();
572
573   myEventCallbackCommand->SetClientData(this); 
574   myPriority = 0.0;
575
576   myEventCallbackCommand->SetCallback(SVTK_RenderWindowInteractor::ProcessEvents);
577 }
578
579 /*!
580   To initialize properly the class
581 */
582 void
583 SVTK_RenderWindowInteractor
584 ::Initialize(vtkGenericRenderWindowInteractor* theDevice,
585              SVTK_Renderer* theRenderer,
586              SVTK_Selector* theSelector)
587 {
588   QVTK_RenderWindowInteractor::Initialize(theDevice);
589   SetRenderer(theRenderer);
590   SetSelector(theSelector);
591 }
592
593 /*!
594   Destructor
595 */
596 SVTK_RenderWindowInteractor
597 ::~SVTK_RenderWindowInteractor() 
598 {
599   // Sequence of the destruction call are fixed and should be changed.
600   // vtkRenderWindow instance should be destroyed after all vtkRenderer's
601   GetDevice()->SetInteractorStyle(NULL); 
602   while(!myInteractorStyles.empty()){
603     const PInteractorStyle& aStyle = myInteractorStyles.top();
604     aStyle->SetInteractor(NULL);
605     myInteractorStyles.pop();
606   }
607
608   SetRenderer(NULL);
609
610   GetDevice()->SetRenderWindow(NULL);
611 }
612
613 /*!
614   To get corresponding SVTK_Renderer instance
615 */
616 SVTK_Renderer* 
617 SVTK_RenderWindowInteractor
618 ::GetRenderer()
619 {
620   return myRenderer.GetPointer();
621 }
622
623 /*!
624   To get corresponding SVTK_Renderer device (just to simplify collobaration with SVTK_Renderer)
625 */
626 vtkRenderer* 
627 SVTK_RenderWindowInteractor
628 ::getRenderer()
629 {
630   return GetRenderer()->GetDevice();
631 }
632
633 /*!
634   Changes renderer
635   \param theRenderer - new renderer
636 */
637 void
638 SVTK_RenderWindowInteractor
639 ::SetRenderer(SVTK_Renderer* theRenderer)
640 {
641   if(theRenderer == myRenderer.GetPointer())
642     return;
643
644   if(GetRenderer())
645     myRenderWindow->RemoveRenderer(getRenderer());
646
647   myRenderer = theRenderer;
648
649   if(GetRenderer())
650     myRenderWindow->AddRenderer(getRenderer());
651 }
652
653
654 /*!
655   Changes interactor style
656   \param theStyle - new interactor style
657 */
658 void
659 SVTK_RenderWindowInteractor
660 ::InitInteractorStyle(vtkInteractorStyle* theStyle)
661 {
662   GetDevice()->SetInteractorStyle(theStyle); 
663 }
664
665 /*!
666   To change current interactor style by pushing the new one into the container
667 */
668 void
669 SVTK_RenderWindowInteractor
670 ::PushInteractorStyle(vtkInteractorStyle* theStyle)
671 {
672   myInteractorStyles.push(PInteractorStyle(theStyle));
673   InitInteractorStyle(theStyle);
674 }
675
676 /*!
677   To restore previous interactor style
678 */
679 void
680 SVTK_RenderWindowInteractor
681 ::PopInteractorStyle()
682 {
683   if(GetInteractorStyle())
684     myInteractorStyles.pop();
685   
686   if(GetInteractorStyle()) 
687     InitInteractorStyle(GetInteractorStyle());
688 }
689
690 /*!
691   To get current interactor style
692 */
693 vtkInteractorStyle* 
694 SVTK_RenderWindowInteractor
695 ::GetInteractorStyle()
696 {
697   return myInteractorStyles.empty() ? 0 : myInteractorStyles.top().GetPointer();
698 }
699
700
701 /*!
702   To get current selector
703 */
704 SVTK_Selector* 
705 SVTK_RenderWindowInteractor
706 ::GetSelector() 
707
708   return mySelector.GetPointer(); 
709 }
710
711
712 /*!
713   Changes selector
714   \param theSelector - new selector
715 */
716 void
717 SVTK_RenderWindowInteractor
718 ::SetSelector(SVTK_Selector* theSelector)
719
720   if(mySelector.GetPointer())
721     mySelector->RemoveObserver(myEventCallbackCommand.GetPointer());
722
723   mySelector = theSelector; 
724
725   if(mySelector.GetPointer())
726     mySelector->AddObserver(vtkCommand::EndPickEvent, 
727                             myEventCallbackCommand.GetPointer(), 
728                             myPriority);
729 }
730
731 /*!
732   Main process VTK event method
733 */
734 void 
735 SVTK_RenderWindowInteractor
736 ::ProcessEvents(vtkObject* vtkNotUsed(theObject), 
737                 unsigned long theEvent,
738                 void* theClientData, 
739                 void* vtkNotUsed(theCallData))
740 {
741   SVTK_RenderWindowInteractor* self = reinterpret_cast<SVTK_RenderWindowInteractor*>(theClientData);
742
743   switch(theEvent){
744   case vtkCommand::EndPickEvent:
745     self->onEmitSelectionChanged();
746     break;
747   }
748 }
749
750 /*!
751   To change selection mode (just to simplify collobaration with SVTK_Selector)
752 */
753 void
754 SVTK_RenderWindowInteractor
755 ::SetSelectionMode(Selection_Mode theMode)
756 {
757   mySelector->SetSelectionMode(theMode);
758 }
759
760 /*!
761   To get current selection mode (just to simplify collobaration with SVTK_Selector)
762 */
763 Selection_Mode
764 SVTK_RenderWindowInteractor
765 ::SelectionMode() const
766 {
767   return mySelector->SelectionMode();
768 }
769
770
771 /*!
772   Emits signal selectionChanged()
773 */
774 void
775 SVTK_RenderWindowInteractor
776 ::onEmitSelectionChanged()
777 {
778   return emit selectionChanged();
779 }
780
781
782 /*!
783   Custom mouse move event handler
784 */
785 void
786 SVTK_RenderWindowInteractor
787 ::mouseMoveEvent( QMouseEvent* event ) 
788 {
789   QVTK_RenderWindowInteractor::mouseMoveEvent(event);
790
791   if(GENERATE_SUIT_EVENTS)
792     emit MouseMove( event );
793 }
794
795
796 /*!
797   Custom mouse press event handler
798 */
799 void
800 SVTK_RenderWindowInteractor
801 ::mousePressEvent( QMouseEvent* event ) 
802 {
803   QVTK_RenderWindowInteractor::mousePressEvent(event);
804
805   if(GENERATE_SUIT_EVENTS)
806     emit MouseButtonPressed( event );
807 }
808
809
810 /*!
811   Custom mouse release event handler
812 */
813 void
814 SVTK_RenderWindowInteractor
815 ::mouseReleaseEvent( QMouseEvent *event )
816 {
817   SVTK_InteractorStyle* style = 0;
818   bool aRightBtn = event->button() == Qt::RightButton;
819   bool isOperation = false;
820   bool isPolygonalSelection = false;
821   if( aRightBtn && GetInteractorStyle()) {
822     style = dynamic_cast<SVTK_InteractorStyle*>( GetInteractorStyle() );
823     if ( style )
824       isOperation = style->CurrentState() != VTK_INTERACTOR_STYLE_CAMERA_NONE;
825   }
826
827   QVTK_RenderWindowInteractor::mouseReleaseEvent(event);
828
829   if ( style ) {
830     isPolygonalSelection = style->GetPolygonState() == Finished;
831     style->SetPolygonState( Disable );
832   }
833
834   if ( aRightBtn && !isOperation && !isPolygonalSelection &&
835        !( event->modifiers() & Qt::ControlModifier ) &&
836        !( event->modifiers() & Qt::ShiftModifier ) ) {
837     QContextMenuEvent aEvent( QContextMenuEvent::Mouse,
838                               event->pos(), event->globalPos() );
839     emit contextMenuRequested( &aEvent );
840   }
841   if(GENERATE_SUIT_EVENTS)
842     emit MouseButtonReleased( event );
843 }
844
845
846 /*!
847   Custom mouse double click event handler
848 */
849 void
850 SVTK_RenderWindowInteractor
851 ::mouseDoubleClickEvent( QMouseEvent* event )
852 {
853   if( GetInteractorStyle() && event->button() == Qt::LeftButton ) {
854     SVTK_InteractorStyle* style = dynamic_cast<SVTK_InteractorStyle*>( GetInteractorStyle() );
855     if ( style )
856       style->OnMouseButtonDoubleClick();
857   }
858
859   QVTK_RenderWindowInteractor::mouseDoubleClickEvent(event);
860
861   if(GENERATE_SUIT_EVENTS)
862     emit MouseDoubleClicked( event );
863 }
864
865
866 /*!
867   Custom mouse wheel event handler
868 */
869 void
870 SVTK_RenderWindowInteractor
871 ::wheelEvent( QWheelEvent* event )
872 {
873   QVTK_RenderWindowInteractor::wheelEvent(event);
874
875   if(event->delta() > 0)
876     GetDevice()->InvokeEvent(SVTK::ZoomInEvent,NULL);
877   else
878     GetDevice()->InvokeEvent(SVTK::ZoomOutEvent,NULL);
879
880   if(GENERATE_SUIT_EVENTS)
881     emit WheelMoved( event );
882 }
883
884 /*!
885   Custom key press event handler
886 */
887 void
888 SVTK_RenderWindowInteractor
889 ::keyPressEvent( QKeyEvent* event ) 
890 {
891   QVTK_RenderWindowInteractor::keyPressEvent(event);
892
893   if(GENERATE_SUIT_EVENTS)
894     emit KeyPressed( event );
895 }
896
897 /*!
898   Custom key release event handler
899 */
900 void
901 SVTK_RenderWindowInteractor
902 ::keyReleaseEvent( QKeyEvent * event ) 
903 {
904   QVTK_RenderWindowInteractor::keyReleaseEvent(event);
905
906   if(GENERATE_SUIT_EVENTS)
907     emit KeyReleased( event );
908 }
909