Salome HOME
Upgrade to paraview 5.4
[modules/gui.git] / src / SVTK / SVTK_RenderWindowInteractor.cxx
index 647fbc5548f9f6f30cba258da30982a255c21bb8..c6278f7c2665cbe197a689dd12bafa7907d2a69f 100644 (file)
@@ -1,39 +1,47 @@
-//  SALOME VTKViewer : build VTK viewer into Salome desktop
+// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
-// 
-//  This library is free software; you can redistribute it and/or 
-//  modify it under the terms of the GNU Lesser General Public 
-//  License as published by the Free Software Foundation; either 
-//  version 2.1 of the License. 
-// 
-//  This library is distributed in the hope that it will be useful, 
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
-//  Lesser General Public License for more details. 
-// 
-//  You should have received a copy of the GNU Lesser General Public 
-//  License along with this library; if not, write to the Free Software 
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
-// 
-// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
 //
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
 //
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
+//  SALOME VTKViewer : build VTK viewer into Salome desktop
 //  File   : 
 //  Author : 
-//  Module : SALOME
-//  $Header$
 
 #include "SVTK_RenderWindowInteractor.h"
-#include "SVTK_GenericRenderWindowInteractor.h"
 
 #include "SVTK_InteractorStyle.h"
 #include "SVTK_Renderer.h"
 #include "SVTK_Functor.h"
 #include "SALOME_Actor.h"
 
+// QT Includes
+// Put Qt includes before the X11 includes which #define the symbol None
+// (see SVTK_SpaceMouse.h) to avoid the compilation error.
+#if !defined(WIN32) && !defined(__APPLE__)
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+#include <xcb/xcb.h>
+#endif
+#include <QX11Info>
+#endif
+#include <QMouseEvent>
+
 #include "SVTK_SpaceMouse.h" 
 #include "SVTK_Event.h" 
 
 #include <vtkPicker.h>
 #include <vtkCamera.h>
 
-// QT Includes
-#include <qtimer.h>
-#include <qapplication.h>
-#include <qcolordialog.h>
-#include <qpaintdevice.h>
-
-using namespace std;
-
-static bool GENERATE_SUIT_EVENTS = false;
+static bool GENERATE_SUIT_EVENTS = true;
 static bool FOCUS_UNDER_MOUSE = false;
 
+// workaround about the bug in vtkImplicitPlaneWidget class
+// that eats mouse button release event
+// causing clipping plane preview in SMESH sticking up
+#define Fix_Of_vtkImplicitPlaneWidget_bug
 
 /*!
   Constructor
 */
 QVTK_RenderWindowInteractor
 ::QVTK_RenderWindowInteractor(QWidget* theParent, 
-                             const char* theName):
-  QWidget(theParent,theName,Qt::WNoAutoErase),
+                              const char* theName):
+  QWidget(theParent),
   myRenderWindow(vtkRenderWindow::New())
 {
+  setAttribute( Qt::WA_PaintOnScreen );
+  setAttribute( Qt::WA_NoSystemBackground );
+
+  setObjectName(theName);
+
   setMouseTracking(true);
 
   myRenderWindow->Delete();
   myRenderWindow->DoubleBufferOn();
 
-#ifndef WNT
-  myRenderWindow->SetDisplayId((void*)x11Display());
+#if !defined WIN32 && !defined __APPLE__
+  myRenderWindow->SetDisplayId((void*)QX11Info::display());
 #endif
   myRenderWindow->SetWindowId((void*)winId());
 }
@@ -103,10 +112,16 @@ QVTK_RenderWindowInteractor
 QVTK_RenderWindowInteractor
 ::~QVTK_RenderWindowInteractor() 
 {
-#ifndef WIN32
-  SVTK_SpaceMouse* aSpaceMouse = SVTK_SpaceMouse::getInstance();
+#if !defined WIN32 && !defined __APPLE__
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+  SVTK_SpaceMouseX* aSpaceMouse = SVTK_SpaceMouseX::getInstance();
+  if ( aSpaceMouse && aSpaceMouse->isSpaceMouseOn() )
+    aSpaceMouse->close( QX11Info::display() );
+#else
+  SVTK_SpaceMouseXCB* aSpaceMouse = SVTK_SpaceMouseXCB::getInstance();
   if ( aSpaceMouse && aSpaceMouse->isSpaceMouseOn() )
-    aSpaceMouse->close( x11Display() );
+    aSpaceMouse->close( QX11Info::connection() );
+#endif
 #endif
 }
 
@@ -141,6 +156,14 @@ QVTK_RenderWindowInteractor
   GetDevice()->InvokeEvent(theEvent,theCallData);
 }
 
+/*!
+  Get paint engine for the scene
+*/
+QPaintEngine* QVTK_RenderWindowInteractor::paintEngine() const
+{
+  return 0;
+}
+
 /*!
   Need for initial contents display on Win32
 */
@@ -207,13 +230,13 @@ QVTK_RenderWindowInteractor
       aRenderers->InitTraversal();
       double aCoeff = 1.0;
       if(vtkRenderer *aRenderer = aRenderers->GetNextItem()) {
-       vtkCamera *aCamera = aRenderer->GetActiveCamera();
-       double aScale = aCamera->GetParallelScale();
-       if((aWidth - width())*(aHeight - height()) > 0)
-         aCoeff = sqrt(double(aWidth)/double(width())*double(height())/double(aHeight));
-       else
-         aCoeff = double(aWidth)/double(width());
-       aCamera->SetParallelScale(aScale*aCoeff);
+        vtkCamera *aCamera = aRenderer->GetActiveCamera();
+        double aScale = aCamera->GetParallelScale();
+        if((aWidth - width())*(aHeight - height()) > 0)
+          aCoeff = sqrt(double(aWidth)/double(width())*double(height())/double(aHeight));
+        else
+          aCoeff = double(aWidth)/double(width());
+        aCamera->SetParallelScale(aScale*aCoeff);
       }
     }
   }
@@ -239,9 +262,9 @@ QVTK_RenderWindowInteractor
 ::mouseMoveEvent( QMouseEvent* event ) 
 {
   GetDevice()->SetEventInformationFlipY(event->x(), 
-                                       event->y(),
-                                       event->state() & ControlButton,
-                                       event->state() & ShiftButton);
+                                        event->y(),
+                                        event->modifiers() & Qt::ControlModifier,
+                                        event->modifiers() & Qt::ShiftModifier);
   GetDevice()->MouseMoveEvent();
 }
 
@@ -254,14 +277,14 @@ QVTK_RenderWindowInteractor
 ::mousePressEvent( QMouseEvent* event ) 
 {
   GetDevice()->SetEventInformationFlipY(event->x(), 
-                                       event->y(),
-                                       event->state() & ControlButton,
-                                       event->state() & ShiftButton);
-  if( event->button() & LeftButton )
+                                        event->y(),
+                                        event->modifiers() & Qt::ControlModifier,
+                                        event->modifiers() & Qt::ShiftModifier);
+  if( event->button() & Qt::LeftButton )
     GetDevice()->LeftButtonPressEvent();
-  else if( event->button() & MidButton )
+  else if( event->button() & Qt::MidButton )
     GetDevice()->MiddleButtonPressEvent();
-  else if( event->button() & RightButton )
+  else if( event->button() & Qt::RightButton )
     GetDevice()->RightButtonPressEvent();
 }
 
@@ -274,16 +297,30 @@ QVTK_RenderWindowInteractor
 ::mouseReleaseEvent( QMouseEvent *event )
 {
   GetDevice()->SetEventInformationFlipY(event->x(), 
-                                       event->y(),
-                                       event->state() & ControlButton,
-                                       event->state() & ShiftButton);
+                                        event->y(),
+                                        event->modifiers() & Qt::ControlModifier,
+                                        event->modifiers() & Qt::ShiftModifier);
 
-  if( event->button() & LeftButton )
+  if( event->button() & Qt::LeftButton )
     GetDevice()->LeftButtonReleaseEvent();
-  else if( event->button() & MidButton )
+  else if( event->button() & Qt::MidButton )
     GetDevice()->MiddleButtonReleaseEvent();
-  else if( event->button() & RightButton )
+  else if( event->button() & Qt::RightButton ) {
+#if defined(Fix_Of_vtkImplicitPlaneWidget_bug)
+    GetDevice()->SetEventInformationFlipY( -99999, -99999,
+                                           event->modifiers() & Qt::ControlModifier,
+                                           event->modifiers() & Qt::ShiftModifier);
+    bool blocked = blockSignals( true );
+    GetDevice()->LeftButtonPressEvent();
+    GetDevice()->LeftButtonReleaseEvent();
+    blockSignals( blocked );
+    GetDevice()->SetEventInformationFlipY(event->x(),
+                                          event->y(),
+                                          event->modifiers() & Qt::ControlModifier,
+                                          event->modifiers() & Qt::ShiftModifier);
+#endif
     GetDevice()->RightButtonReleaseEvent();
+  }
 }
 
 
@@ -303,8 +340,16 @@ void
 QVTK_RenderWindowInteractor
 ::wheelEvent( QWheelEvent* event )
 {
-  setActiveWindow();
+  activateWindow();
   setFocus();
+  GetDevice()->SetEventInformationFlipY(event->x(), 
+                                        event->y(),
+                                        event->modifiers() & Qt::ControlModifier,
+                                        event->modifiers() & Qt::ShiftModifier);
+  if ( event->delta()>0)
+    GetDevice()->MouseWheelForwardEvent();
+  else
+    GetDevice()->MouseWheelBackwardEvent();
 }
 
 
@@ -315,9 +360,9 @@ void
 QVTK_RenderWindowInteractor
 ::keyPressEvent( QKeyEvent* event ) 
 {
-  GetDevice()->SetKeyEventInformation(event->state() & ControlButton,
-                                     event->state() & ShiftButton,
-                                     event->key());
+  GetDevice()->SetKeyEventInformation(event->modifiers() & Qt::ControlModifier,
+                                      event->modifiers() & Qt::ShiftModifier,
+                                      event->key());
   GetDevice()->KeyPressEvent();
   GetDevice()->CharEvent();
 }
@@ -329,9 +374,9 @@ void
 QVTK_RenderWindowInteractor
 ::keyReleaseEvent( QKeyEvent * event ) 
 {
-  GetDevice()->SetKeyEventInformation(event->state() & ControlButton,
-                                     event->state() & ShiftButton,
-                                     event->key());
+  GetDevice()->SetKeyEventInformation(event->modifiers() & Qt::ControlModifier,
+                                      event->modifiers() & Qt::ShiftModifier,
+                                      event->key());
   GetDevice()->KeyReleaseEvent();
 }
 
@@ -344,7 +389,7 @@ QVTK_RenderWindowInteractor
 ::enterEvent( QEvent* event )
 {
   if(FOCUS_UNDER_MOUSE){
-    setActiveWindow();
+    activateWindow();
     setFocus();
   }
   GetDevice()->EnterEvent();
@@ -370,19 +415,30 @@ QVTK_RenderWindowInteractor
 {
   QWidget::focusInEvent( event );
 
-#ifndef WIN32
+#if !defined WIN32 && !defined __APPLE__
   // register set space mouse events receiver
-  SVTK_SpaceMouse* aSpaceMouse = SVTK_SpaceMouse::getInstance();
-
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+  SVTK_SpaceMouseX* aSpaceMouse = SVTK_SpaceMouseX::getInstance();
   if ( aSpaceMouse )
   {
     if ( !aSpaceMouse->isSpaceMouseOn() )
       // initialize 3D space mouse driver 
-      aSpaceMouse->initialize( x11Display(), winId() );
+      aSpaceMouse->initialize( QX11Info::display(), winId() );
+    else
+      aSpaceMouse->setWindow( QX11Info::display(), winId() );
+  }
+#else
+  SVTK_SpaceMouseXCB* aSpaceMouse = SVTK_SpaceMouseXCB::getInstance();
+  if ( aSpaceMouse )
+  {
+    if ( !aSpaceMouse->isSpaceMouseOn() )
+      // initialize 3D space mouse driver
+      aSpaceMouse->initialize( QX11Info::connection(), winId() );
     else
-      aSpaceMouse->setWindow( x11Display(), winId() );
+      aSpaceMouse->setWindow( QX11Info::connection(), winId() );
   }
 #endif
+#endif
 }
 
 /*!
@@ -395,52 +451,58 @@ QVTK_RenderWindowInteractor
 {
   QWidget::focusOutEvent( event );
 
-#ifndef WIN32
+#if !defined WIN32 && !defined __APPLE__
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
   // unregister set space mouse events receiver
-  SVTK_SpaceMouse* aSpaceMouse = SVTK_SpaceMouse::getInstance();
+  SVTK_SpaceMouseX* aSpaceMouse = SVTK_SpaceMouseX::getInstance();
+  if ( aSpaceMouse && aSpaceMouse->isSpaceMouseOn() )
+    aSpaceMouse->setWindow( QX11Info::display(), 0 );
+#else
+  SVTK_SpaceMouseXCB* aSpaceMouse = SVTK_SpaceMouseXCB::getInstance();
   if ( aSpaceMouse && aSpaceMouse->isSpaceMouseOn() )
-    aSpaceMouse->setWindow( x11Display(), 0 );
+    aSpaceMouse->setWindow( QX11Info::connection(), 0 );
+#endif
 #endif
 }
 
-
-#ifdef WIN32
+// TODO (QT5 PORTING) Below is a temporary solution, to allow compiling with Qt 5
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+#if defined(WIN32)
 
 /*!
   To handle native Win32 events (from such devices as SpaceMouse)
 */
-bool QVTK_RenderWindowInteractor::winEvent( MSG* msg )
+bool QVTK_RenderWindowInteractor::winEvent( MSG* msg, long* result )
 {
   // TODO: Implement event handling for SpaceMouse
-  return QWidget::winEvent( msg );
+  return QWidget::winEvent( msg, result);
 }
 
-#else
-
+#elif !defined(__APPLE__)
 /*!
   To handle native X11 events (from such devices as SpaceMouse)
 */
-bool 
+bool
 QVTK_RenderWindowInteractor
 ::x11Event( XEvent *xEvent )
 {
   // handle 3d space mouse events
-  if ( SVTK_SpaceMouse* aSpaceMouse = SVTK_SpaceMouse::getInstance() )
+  if ( SVTK_SpaceMouseX* aSpaceMouse = SVTK_SpaceMouseX::getInstance() )
   {
     if ( aSpaceMouse->isSpaceMouseOn() && xEvent->type == ClientMessage )
     {
       SVTK_SpaceMouse::MoveEvent anEvent;
-      int type = aSpaceMouse->translateEvent( x11Display(), xEvent, &anEvent, 1.0, 1.0 );
+      int type = aSpaceMouse->translateEvent( QX11Info::display(), xEvent, &anEvent, 1.0, 1.0 );
       switch ( type )
       {
       case SVTK_SpaceMouse::SpaceMouseMove:
-             GetDevice()->InvokeEvent( SVTK::SpaceMouseMoveEvent, anEvent.data );
-             break;
+              GetDevice()->InvokeEvent( SVTK::SpaceMouseMoveEvent, anEvent.data );
+              break;
       case SVTK_SpaceMouse::SpaceButtonPress:
-             GetDevice()->InvokeEvent( SVTK::SpaceMouseButtonEvent, &anEvent.button );
-             break;
+              GetDevice()->InvokeEvent( SVTK::SpaceMouseButtonEvent, &anEvent.button );
+              break;
       case SVTK_SpaceMouse::SpaceButtonRelease:
-             break;
+              break;
       }
       return true; // stop handling the event
     }
@@ -451,12 +513,58 @@ QVTK_RenderWindowInteractor
 
 #endif
 
+#else // QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+
+bool QVTK_RenderWindowInteractor
+::nativeEvent(const QByteArray& eventType, void* message, long* result)
+{
+#if defined(WIN32)
+  // TODO: WIN32-related implementation
+#elif !defined(__APPLE__)
+  if ( eventType == "xcb_generic_event_t" )
+  {
+    xcb_generic_event_t* ev = static_cast<xcb_generic_event_t *>(message);
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+    // TODO: this code is never called
+    if ( SVTK_SpaceMouseX* aSpaceMouse = SVTK_SpaceMouseX::getInstance() )
+#else
+    if ( SVTK_SpaceMouseXCB* aSpaceMouse = SVTK_SpaceMouseXCB::getInstance() )
+#endif
+    {
+      if ( aSpaceMouse->isSpaceMouseOn() && ev->response_type == XCB_CLIENT_MESSAGE )
+      {
+        SVTK_SpaceMouse::MoveEvent anEvent;
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+        // TODO: this code is never called
+        int type = aSpaceMouse->translateEvent( QX11Info::display(), xEvent, &anEvent, 1.0, 1.0 );
+#else
+        int type = aSpaceMouse->translateEvent( QX11Info::connection(), (xcb_client_message_event_t*)ev, &anEvent, 1.0, 1.0 );
+#endif
+        switch ( type )
+        {
+        case SVTK_SpaceMouse::SpaceMouseMove:
+                GetDevice()->InvokeEvent( SVTK::SpaceMouseMoveEvent, anEvent.data );
+                break;
+        case SVTK_SpaceMouse::SpaceButtonPress:
+                GetDevice()->InvokeEvent( SVTK::SpaceMouseButtonEvent, &anEvent.button );
+                break;
+        case SVTK_SpaceMouse::SpaceButtonRelease:
+                break;
+        }
+        return true; // stop handling the event
+      }
+    }
+  }
+#endif
+ return QWidget::nativeEvent( eventType, message, result );
+}
+#endif
 /*!
   Constructor
 */
 SVTK_RenderWindowInteractor
 ::SVTK_RenderWindowInteractor(QWidget* theParent, 
-                              const char* theName):
+                               const char* theName):
   QVTK_RenderWindowInteractor(theParent,theName),
   myEventCallbackCommand(vtkCallbackCommand::New())
 {
@@ -474,8 +582,8 @@ SVTK_RenderWindowInteractor
 void
 SVTK_RenderWindowInteractor
 ::Initialize(vtkGenericRenderWindowInteractor* theDevice,
-            SVTK_Renderer* theRenderer,
-            SVTK_Selector* theSelector)
+             SVTK_Renderer* theRenderer,
+             SVTK_Selector* theSelector)
 {
   QVTK_RenderWindowInteractor::Initialize(theDevice);
   SetRenderer(theRenderer);
@@ -616,8 +724,8 @@ SVTK_RenderWindowInteractor
 
   if(mySelector.GetPointer())
     mySelector->AddObserver(vtkCommand::EndPickEvent, 
-                           myEventCallbackCommand.GetPointer(), 
-                           myPriority);
+                            myEventCallbackCommand.GetPointer(), 
+                            myPriority);
 }
 
 /*!
@@ -626,9 +734,9 @@ SVTK_RenderWindowInteractor
 void 
 SVTK_RenderWindowInteractor
 ::ProcessEvents(vtkObject* vtkNotUsed(theObject), 
-               unsigned long theEvent,
-               void* theClientData, 
-               void* vtkNotUsed(theCallData))
+                unsigned long theEvent,
+                void* theClientData, 
+                void* vtkNotUsed(theCallData))
 {
   SVTK_RenderWindowInteractor* self = reinterpret_cast<SVTK_RenderWindowInteractor*>(theClientData);
 
@@ -706,8 +814,30 @@ void
 SVTK_RenderWindowInteractor
 ::mouseReleaseEvent( QMouseEvent *event )
 {
+  SVTK_InteractorStyle* style = 0;
+  bool aRightBtn = event->button() == Qt::RightButton;
+  bool isOperation = false;
+  bool isPolygonalSelection = false;
+  if( aRightBtn && GetInteractorStyle()) {
+    style = dynamic_cast<SVTK_InteractorStyle*>( GetInteractorStyle() );
+    if ( style )
+      isOperation = style->CurrentState() != VTK_INTERACTOR_STYLE_CAMERA_NONE;
+  }
+
   QVTK_RenderWindowInteractor::mouseReleaseEvent(event);
 
+  if ( style ) {
+    isPolygonalSelection = style->GetPolygonState() == Finished;
+    style->SetPolygonState( Disable );
+  }
+
+  if ( aRightBtn && !isOperation && !isPolygonalSelection &&
+       !( event->modifiers() & Qt::ControlModifier ) &&
+       !( event->modifiers() & Qt::ShiftModifier ) ) {
+    QContextMenuEvent aEvent( QContextMenuEvent::Mouse,
+                              event->pos(), event->globalPos() );
+    emit contextMenuRequested( &aEvent );
+  }
   if(GENERATE_SUIT_EVENTS)
     emit MouseButtonReleased( event );
 }
@@ -720,6 +850,12 @@ void
 SVTK_RenderWindowInteractor
 ::mouseDoubleClickEvent( QMouseEvent* event )
 {
+  if( GetInteractorStyle() && event->button() == Qt::LeftButton ) {
+    SVTK_InteractorStyle* style = dynamic_cast<SVTK_InteractorStyle*>( GetInteractorStyle() );
+    if ( style )
+      style->OnMouseButtonDoubleClick();
+  }
+
   QVTK_RenderWindowInteractor::mouseDoubleClickEvent(event);
 
   if(GENERATE_SUIT_EVENTS)
@@ -771,13 +907,3 @@ SVTK_RenderWindowInteractor
     emit KeyReleased( event );
 }
 
-/*!
-  Custom context menu event handler
-*/
-void
-SVTK_RenderWindowInteractor
-::contextMenuEvent( QContextMenuEvent* event )
-{
-  if( !( event->state() & KeyButtonMask ) )
-    emit contextMenuRequested( event );
-}