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