Salome HOME
Upgrade to paraview 5.4
[modules/gui.git] / src / SVTK / SVTK_RenderWindowInteractor.cxx
index 5493554750fb3faf98e0680230fe2deaa7ed679a..c6278f7c2665cbe197a689dd12bafa7907d2a69f 100644 (file)
@@ -1,32 +1,30 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// 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.
+// 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.
+// 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
+// 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
+// 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"
 // QT Includes
 // Put Qt includes before the X11 includes which #define the symbol None
 // (see SVTK_SpaceMouse.h) to avoid the compilation error.
-#ifndef WIN32
-# include <QX11Info>
+#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 <vtkPicker.h>
 #include <vtkCamera.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):
+                              const char* theName):
   QWidget(theParent),
   myRenderWindow(vtkRenderWindow::New())
 {
@@ -81,7 +84,7 @@ QVTK_RenderWindowInteractor
   myRenderWindow->Delete();
   myRenderWindow->DoubleBufferOn();
 
-#ifndef WIN32
+#if !defined WIN32 && !defined __APPLE__
   myRenderWindow->SetDisplayId((void*)QX11Info::display());
 #endif
   myRenderWindow->SetWindowId((void*)winId());
@@ -109,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( QX11Info::connection() );
+#endif
 #endif
 }
 
@@ -147,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
 */
@@ -213,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);
       }
     }
   }
@@ -245,9 +262,9 @@ QVTK_RenderWindowInteractor
 ::mouseMoveEvent( QMouseEvent* event ) 
 {
   GetDevice()->SetEventInformationFlipY(event->x(), 
-                                       event->y(),
-                                       event->modifiers() & Qt::ControlModifier,
-                                       event->modifiers() & Qt::ShiftModifier);
+                                        event->y(),
+                                        event->modifiers() & Qt::ControlModifier,
+                                        event->modifiers() & Qt::ShiftModifier);
   GetDevice()->MouseMoveEvent();
 }
 
@@ -260,9 +277,9 @@ QVTK_RenderWindowInteractor
 ::mousePressEvent( QMouseEvent* event ) 
 {
   GetDevice()->SetEventInformationFlipY(event->x(), 
-                                       event->y(),
-                                       event->modifiers() & Qt::ControlModifier,
-                                       event->modifiers() & Qt::ShiftModifier);
+                                        event->y(),
+                                        event->modifiers() & Qt::ControlModifier,
+                                        event->modifiers() & Qt::ShiftModifier);
   if( event->button() & Qt::LeftButton )
     GetDevice()->LeftButtonPressEvent();
   else if( event->button() & Qt::MidButton )
@@ -280,16 +297,30 @@ QVTK_RenderWindowInteractor
 ::mouseReleaseEvent( QMouseEvent *event )
 {
   GetDevice()->SetEventInformationFlipY(event->x(), 
-                                       event->y(),
-                                       event->modifiers() & Qt::ControlModifier,
-                                       event->modifiers() & Qt::ShiftModifier);
+                                        event->y(),
+                                        event->modifiers() & Qt::ControlModifier,
+                                        event->modifiers() & Qt::ShiftModifier);
 
   if( event->button() & Qt::LeftButton )
     GetDevice()->LeftButtonReleaseEvent();
   else if( event->button() & Qt::MidButton )
     GetDevice()->MiddleButtonReleaseEvent();
-  else if( event->button() & Qt::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();
+  }
 }
 
 
@@ -311,6 +342,14 @@ QVTK_RenderWindowInteractor
 {
   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();
 }
 
 
@@ -322,8 +361,8 @@ QVTK_RenderWindowInteractor
 ::keyPressEvent( QKeyEvent* event ) 
 {
   GetDevice()->SetKeyEventInformation(event->modifiers() & Qt::ControlModifier,
-                                     event->modifiers() & Qt::ShiftModifier,
-                                     event->key());
+                                      event->modifiers() & Qt::ShiftModifier,
+                                      event->key());
   GetDevice()->KeyPressEvent();
   GetDevice()->CharEvent();
 }
@@ -336,8 +375,8 @@ QVTK_RenderWindowInteractor
 ::keyReleaseEvent( QKeyEvent * event ) 
 {
   GetDevice()->SetKeyEventInformation(event->modifiers() & Qt::ControlModifier,
-                                     event->modifiers() & Qt::ShiftModifier,
-                                     event->key());
+                                      event->modifiers() & Qt::ShiftModifier,
+                                      event->key());
   GetDevice()->KeyReleaseEvent();
 }
 
@@ -376,10 +415,10 @@ 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() )
@@ -388,6 +427,17 @@ QVTK_RenderWindowInteractor
     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( QX11Info::connection(), winId() );
+  }
+#endif
 #endif
 }
 
@@ -401,16 +451,23 @@ 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( 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)
@@ -421,17 +478,16 @@ bool QVTK_RenderWindowInteractor::winEvent( MSG* msg, long* result )
   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 )
     {
@@ -440,13 +496,13 @@ QVTK_RenderWindowInteractor
       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
     }
@@ -457,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())
 {
@@ -480,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);
@@ -622,8 +724,8 @@ SVTK_RenderWindowInteractor
 
   if(mySelector.GetPointer())
     mySelector->AddObserver(vtkCommand::EndPickEvent, 
-                           myEventCallbackCommand.GetPointer(), 
-                           myPriority);
+                            myEventCallbackCommand.GetPointer(), 
+                            myPriority);
 }
 
 /*!
@@ -632,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);
 
@@ -712,17 +814,25 @@ 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()) {
-    SVTK_InteractorStyle* style = dynamic_cast<SVTK_InteractorStyle*>( GetInteractorStyle() );
+    style = dynamic_cast<SVTK_InteractorStyle*>( GetInteractorStyle() );
     if ( style )
       isOperation = style->CurrentState() != VTK_INTERACTOR_STYLE_CAMERA_NONE;
   }
 
   QVTK_RenderWindowInteractor::mouseReleaseEvent(event);
 
-  if ( aRightBtn && !isOperation && !( event->modifiers() & Qt::ControlModifier ) &&
+  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() );
@@ -740,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)