]> SALOME platform Git repositories - modules/geom.git/commitdiff
Salome HOME
Interactive annotations
authorapl <anton.poletaev@opencascade.com>
Fri, 7 Oct 2016 18:18:28 +0000 (21:18 +0300)
committerapl <anton.poletaev@opencascade.com>
Fri, 7 Oct 2016 18:20:06 +0000 (21:20 +0300)
resources/SalomeApp.xml.in
src/GEOMGUI/GEOM_Displayer.cxx
src/MeasureGUI/CMakeLists.txt
src/MeasureGUI/MeasureGUI_AnnotationDlg.cxx [changed mode: 0644->0755]
src/MeasureGUI/MeasureGUI_AnnotationDlg.h [changed mode: 0644->0755]
src/MeasureGUI/MeasureGUI_AnnotationInteractor.cxx [new file with mode: 0755]
src/MeasureGUI/MeasureGUI_AnnotationInteractor.h [new file with mode: 0755]
src/OBJECT/GEOM_Annotation.cxx
src/OBJECT/GEOM_Annotation.hxx

index 9d522cd69f6a6e5ae57070f380044c991f3efdb2..0256007de2e9d2320b8234bda1648a558f1161d7 100755 (executable)
 
     <!-- Shape annotation presentation properties -->
     <parameter name="shape_annotation_font_color" value="#ffffff" />
-    <parameter name="shape_annotation_font"       value="Y14.5M-2009,14" />
+    <parameter name="shape_annotation_font"       value="Courier 10 Pitch,24" />
     <parameter name="shape_annotation_line_color" value="#ffffff" />
     <parameter name="shape_annotation_line_width" value="1.0" />
     <parameter name="shape_annotation_line_style" value="0" />
index 9bdad8b6bc78428e1230628c61220a6441c346b3..e663241749b9c555f7a4451dd574c3a396632962 100755 (executable)
@@ -1404,7 +1404,7 @@ void GEOM_Displayer::updateShapeAnnotations( const Handle(SALOME_InteractiveObje
 
   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
 
-  const QFont  aFont      = aResMgr->fontValue( "Geometry", "shape_annotation_font", QFont( "Arial", 14 ) );
+  const QFont  aFont      = aResMgr->fontValue( "Geometry", "shape_annotation_font", QFont( "Y14.5M-2009", 24 ) );
   const QColor aFontColor = aResMgr->colorValue( "Geometry", "shape_annotation_font_color", QColor( 255, 255, 255 ) );
   const QColor aLineColor = aResMgr->colorValue( "Geometry", "shape_annotation_line_color", QColor( 255, 255, 255 ) );
   const double aLineWidth = aResMgr->doubleValue( "Geometry", "shape_annotation_line_width", 1.0 );
@@ -1439,7 +1439,8 @@ void GEOM_Displayer::updateShapeAnnotations( const Handle(SALOME_InteractiveObje
       const Quantity_Color aOcctLineColor( aLineColor.redF(), aLineColor.greenF(), aLineColor.blueF(), Quantity_TOC_RGB );
       const Standard_Real aFontHeight = aFont.pixelSize() != -1 ? aFont.pixelSize() : aFont.pointSize();
 
-      aPresentation->SetTextHeight( aFont.pixelSize() != -1 ? aFont.pixelSize() : aFont.pointSize() );
+      aPresentation->SetFont( TCollection_AsciiString( aFont.family().toLatin1().data() ) );
+      aPresentation->SetTextHeight( aFontHeight );
       aPresentation->SetTextColor( Quantity_Color( aFontColor.redF(), aFontColor.greenF(), aFontColor.blueF(), Quantity_TOC_RGB ) );
       aPresentation->SetLineColor( Quantity_Color( aLineColor.redF(), aLineColor.greenF(), aLineColor.blueF(), Quantity_TOC_RGB ) );
       aPresentation->SetLineWidth( aLineWidth );
index a4df3187508072c209c86398577040f4bff7ad08..7bbd751773ab97841ff5ebc1f8e680d16d860068 100755 (executable)
@@ -89,6 +89,7 @@ SET(MeasureGUI_HEADERS
   MeasureGUI_BndBoxDlg.h
   MeasureGUI_DistanceDlg.h
   MeasureGUI_AnnotationDlg.h
+  MeasureGUI_AnnotationInteractor.h
   MeasureGUI_AngleDlg.h
   MeasureGUI_MaxToleranceDlg.h
   MeasureGUI_WhatisDlg.h
@@ -118,6 +119,7 @@ SET(_moc_HEADERS
   MeasureGUI_BndBoxDlg.h
   MeasureGUI_DistanceDlg.h
   MeasureGUI_AnnotationDlg.h
+  MeasureGUI_AnnotationInteractor.h
   MeasureGUI_AngleDlg.h
   MeasureGUI_MaxToleranceDlg.h
   MeasureGUI_WhatisDlg.h
@@ -157,6 +159,7 @@ SET(MeasureGUI_SOURCES
   MeasureGUI_BndBoxDlg.cxx
   MeasureGUI_DistanceDlg.cxx
   MeasureGUI_AnnotationDlg.cxx
+  MeasureGUI_AnnotationInteractor.cxx
   MeasureGUI_AngleDlg.cxx
   MeasureGUI_MaxToleranceDlg.cxx
   MeasureGUI_WhatisDlg.cxx
old mode 100644 (file)
new mode 100755 (executable)
index 705877d..2afd008
@@ -24,6 +24,7 @@
 
 #include "MeasureGUI.h"
 #include "MeasureGUI_AnnotationDlg.h"
+#include "MeasureGUI_AnnotationInteractor.h"
 
 #include <DlgRef.h>
 #include <GEOMBase.h>
@@ -192,6 +193,9 @@ MeasureGUI_AnnotationDlg::MeasureGUI_AnnotationDlg(GeometryGUI* theGeometryGUI,
   connect(buttonOk(), SIGNAL(clicked()), this, SLOT(ClickOnOk()));
   connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply()));
 
+  myInteractor = new MeasureGUI_AnnotationInteractor( theGeometryGUI, parent );
+  myInteractor->Enable();
+
   Init();
   //updateState();
 }
@@ -519,6 +523,26 @@ SALOME_Prs* MeasureGUI_AnnotationDlg::buildPrs()
 {
   Handle (GEOM_Annotation) aPresentation = new GEOM_Annotation();
 
+  SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
+  const QFont  aFont      = aResMgr->fontValue( "Geometry", "shape_annotation_font", QFont( "Y14.5M-2009", 24 ) );
+  const QColor aFontColor = aResMgr->colorValue( "Geometry", "shape_annotation_font_color", QColor( 255, 255, 255 ) );
+  const QColor aLineColor = aResMgr->colorValue( "Geometry", "shape_annotation_line_color", QColor( 255, 255, 255 ) );
+  const double aLineWidth = aResMgr->doubleValue( "Geometry", "shape_annotation_line_width", 1.0 );
+  const int aLineStyle    = aResMgr->integerValue( "Geometry", "shape_annotation_line_style", 0 );
+  const bool isAutoHide   = aResMgr->booleanValue( "Geometry", "shape_annotation_autohide", false );
+
+  const Quantity_Color aOcctFontColor( aFontColor.redF(), aFontColor.greenF(), aFontColor.blueF(), Quantity_TOC_RGB );
+  const Quantity_Color aOcctLineColor( aLineColor.redF(), aLineColor.greenF(), aLineColor.blueF(), Quantity_TOC_RGB );
+  const Standard_Real aFontHeight = aFont.pixelSize() != -1 ? aFont.pixelSize() : aFont.pointSize();
+
+  aPresentation->SetFont( TCollection_AsciiString( aFont.family().toLatin1().data() ) );
+  aPresentation->SetTextHeight( aFontHeight );
+  aPresentation->SetTextColor( Quantity_Color( aFontColor.redF(), aFontColor.greenF(), aFontColor.blueF(), Quantity_TOC_RGB ) );
+  aPresentation->SetLineColor( Quantity_Color( aLineColor.redF(), aLineColor.greenF(), aLineColor.blueF(), Quantity_TOC_RGB ) );
+  aPresentation->SetLineWidth( aLineWidth );
+  aPresentation->SetLineStyle( static_cast<Aspect_TypeOfLine>( aLineStyle ) );
+  aPresentation->SetAutoHide( isAutoHide ? Standard_True : Standard_False );
+
   TopoDS_Shape aShape;
   GEOMBase::GetShape(myShape.get(), aShape);
   gp_Ax3 aShapeLCS = gp_Ax3().Transformed(aShape.Location().Transformation());
old mode 100644 (file)
new mode 100755 (executable)
index 6c613c9..686cee6
@@ -46,6 +46,7 @@ class QLineEdit;
 class QPushButton;
 class QComboBox;
 class SalomeApp_IntSpinBox;
+class MeasureGUI_AnnotationInteractor;
 
 //=================================================================================
 // class    : MeasureGUI_AnnotationDlg
@@ -106,6 +107,8 @@ private:
 
   QPushButton*                        mySubShapeSelBtn;
   QLineEdit*                          mySubShapeName;
+
+  MeasureGUI_AnnotationInteractor*    myInteractor;
 };
 
 #endif
diff --git a/src/MeasureGUI/MeasureGUI_AnnotationInteractor.cxx b/src/MeasureGUI/MeasureGUI_AnnotationInteractor.cxx
new file mode 100755 (executable)
index 0000000..9e1c0e3
--- /dev/null
@@ -0,0 +1,306 @@
+// 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
+//
+// 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
+//
+
+// GEOM GEOMGUI : GUI for Geometry component
+// File   : MeasureGUI_AnnotationInteractor.cxx
+// Author : Anton POLETAEV, Open CASCADE S.A.S.
+
+#include "MeasureGUI_AnnotationInteractor.h"
+
+// SALOME includes
+#include <GeometryGUI.h>
+#include <OCCViewer_ViewManager.h>
+#include <OCCViewer_ViewPort3d.h>
+#include <OCCViewer_ViewWindow.h>
+#include <SUIT_ViewManager.h>
+#include <SUIT_ViewWindow.h>
+#include <SUIT_Desktop.h>
+#include <SalomeApp_Application.h>
+
+// Qt includes
+#include <QMouseEvent>
+
+// OCCT includes
+#include <V3d_View.hxx>
+
+//=================================================================================
+// function : Constructor
+// purpose  : 
+//=================================================================================
+MeasureGUI_AnnotationInteractor::MeasureGUI_AnnotationInteractor( GeometryGUI* theGUI,
+                                                                  QObject* theParent )
+: QObject( theParent ),
+  myGeomGUI( theGUI ),
+  myIsEnabled( false ),
+  myVM( NULL ),
+  myViewer( NULL ),
+  myActiveViewPort( NULL )
+{
+}
+
+//=================================================================================
+// function : Deactivate
+// purpose  : 
+//=================================================================================
+MeasureGUI_AnnotationInteractor::~MeasureGUI_AnnotationInteractor()
+{
+  if ( myActiveViewPort )
+  {
+    myActiveViewPort->releaseMouse();
+    myActiveViewPort = NULL;
+  }
+
+  Disable();
+}
+
+//=================================================================================
+// function : Enable
+// purpose  : Enables event processing and interaction handlers.
+//=================================================================================
+void MeasureGUI_AnnotationInteractor::Enable()
+{
+  if ( myIsEnabled )
+  {
+    return;
+  }
+
+  myIsEnabled = true;
+
+  // install event filtering on viewer windows
+  SalomeApp_Application* anApp = myGeomGUI->getApp();
+  if ( !anApp )
+  {
+    return;
+  }
+
+  myVM     = (OCCViewer_ViewManager*) anApp->getViewManager( OCCViewer_Viewer::Type(), false );
+  myViewer = (OCCViewer_Viewer*) myVM->getViewModel();
+  if ( !myVM || !myViewer )
+  {
+    return;
+  }
+
+  connect( myVM, SIGNAL( viewCreated( SUIT_ViewWindow* ) ), SLOT( OnViewCreated( SUIT_ViewWindow* ) ) );
+  connect( myVM, SIGNAL( deleteView ( SUIT_ViewWindow* ) ), SLOT( OnViewRemoved( SUIT_ViewWindow* ) ) );
+
+  QVector<SUIT_ViewWindow*>           aViews  = myVM->getViews();
+  QVector<SUIT_ViewWindow*>::iterator aViewIt = aViews.begin();
+  for ( ; aViewIt != aViews.end(); ++aViewIt )
+  {
+    ConnectView( *aViewIt );
+  }
+}
+
+//=================================================================================
+// function : Disable
+// purpose  : Disables event processing and interaction handlers.
+//=================================================================================
+void MeasureGUI_AnnotationInteractor::Disable()
+{
+  if ( !myIsEnabled )
+  {
+    return;
+  }
+
+  myIsEnabled = false;
+
+  // remove event filtering from viewer windows
+  QVector<SUIT_ViewWindow*>           aViews  = myVM->getViews();
+  QVector<SUIT_ViewWindow*>::iterator aViewIt = aViews.begin();
+  for ( ; aViewIt != aViews.end(); ++aViewIt )
+  {
+    DisconnectView( *aViewIt );
+  }
+
+  if ( myActiveViewPort )
+  {
+    myActiveViewPort->releaseMouse();
+    myActiveViewPort = NULL;
+  }
+
+  myActiveIO.Nullify();
+}
+
+//=================================================================================
+// function : ConnectView
+// purpose  : Connect interactor's event handler to the view window given.
+//=================================================================================
+void MeasureGUI_AnnotationInteractor::ConnectView( SUIT_ViewWindow* theView )
+{
+  ( (OCCViewer_ViewWindow*) theView )->getViewPort()->installEventFilter( this );
+}
+
+//=================================================================================
+// function : DisconnectView
+// purpose  : Disconnect interactor's event handler from the view window given.
+//=================================================================================
+void MeasureGUI_AnnotationInteractor::DisconnectView( SUIT_ViewWindow* theView )
+{
+  ( (OCCViewer_ViewWindow*) theView )->getViewPort()->removeEventFilter( this );
+}
+
+//=================================================================================
+// function : OnViewCreated
+// purpose  : Handler for signal coming from GUI layer.
+//=================================================================================
+void MeasureGUI_AnnotationInteractor::OnViewCreated( SUIT_ViewWindow* theView )
+{
+  ConnectView( theView );
+}
+
+//=================================================================================
+// function : OnViewRemoved
+// purpose  : Handler for signal coming from GUI layer.
+//=================================================================================
+void MeasureGUI_AnnotationInteractor::OnViewRemoved( SUIT_ViewWindow* theView )
+{
+  DisconnectView( theView );
+}
+
+//=================================================================================
+// function : eventFilter
+// purpose  : Hooks and process events from OCCT viewer prior to their coming into the base viewer class.
+//=================================================================================
+bool MeasureGUI_AnnotationInteractor::eventFilter( QObject* theObject, QEvent* theEvent )
+{
+  OCCViewer_ViewPort3d* aViewPort = (OCCViewer_ViewPort3d*)theObject;
+
+  const Handle(V3d_View) aView3d = aViewPort->getView();
+
+  switch( theEvent->type() )
+  {
+    // ------------------------------------------------------------------------
+    // Start dragging ("grab") event
+    // ------------------------------------------------------------------------
+    case QEvent::MouseButtonPress :
+    {
+      QMouseEvent* aMouseEv = dynamic_cast<QMouseEvent*>( theEvent );
+
+      if ( !( aMouseEv->buttons() & Qt::LeftButton ) )
+      {
+        return false;
+      }
+
+      const Handle(AIS_InteractiveContext) anAISContext = myViewer->getAISContext();
+
+      anAISContext->MoveTo( aMouseEv->x(), aMouseEv->y(), aView3d );
+
+      if ( !anAISContext->HasDetected() )
+      {
+        return false;
+      }
+
+      const Handle(SelectMgr_EntityOwner) aDetected = anAISContext->DetectedOwner();
+
+      if( aDetected.IsNull() )
+      {
+        return false;
+      }
+
+      const Handle(GEOM_Annotation) aAnnotation =
+        Handle(GEOM_Annotation)::DownCast( aDetected->Selectable() );
+
+      if ( aAnnotation.IsNull() )
+      {
+        return false;
+      }
+
+      myStartPoint = aMouseEv->pos();
+      mySelection.Clear();
+
+      for ( anAISContext->InitSelected(); anAISContext->MoreSelected(); anAISContext->NextSelected() )
+      {
+        mySelection.Append( anAISContext->SelectedOwner() );
+      }
+
+      anAISContext->ClearSelected( Standard_False );
+      anAISContext->AddOrRemoveSelected( aDetected );
+
+      myActiveViewPort = aViewPort;
+      myActiveViewPort->grabMouse();
+      myActiveIO = aAnnotation;
+      myActiveIO->BeginDrag();
+
+      return true;
+    }
+
+    // ------------------------------------------------------------------------
+    // Perform dragging operation
+    // ------------------------------------------------------------------------
+    case QEvent::MouseMove :
+    {
+      QMouseEvent* aMouseEv = (QMouseEvent*) theEvent;
+
+      if ( !myActiveIO.IsNull() )
+      {
+        const Handle(AIS_InteractiveContext) anAISContext = myViewer->getAISContext();
+        const QPoint aDelta = aMouseEv->pos() - myStartPoint;
+        myActiveIO->Drag( aDelta.x(), (-aDelta.y()), aView3d );
+        anAISContext->Update( myActiveIO, Standard_False );
+        anAISContext->UpdateCurrentViewer();
+        return true;
+      }
+
+      return false;
+    }
+
+    // ------------------------------------------------------------------------
+    // Stop dragging operation
+    // ------------------------------------------------------------------------
+    case QEvent::FocusOut :
+    case QEvent::MouseButtonRelease :
+    {
+      QMouseEvent* aMouseEv = (QMouseEvent*) theEvent;
+
+      if ( myActiveViewPort )
+      {
+        myActiveViewPort->releaseMouse();
+        myActiveViewPort = NULL;
+      }
+      if ( !myActiveIO.IsNull() )
+      {
+        myActiveIO->EndDrag();
+
+        const Handle(AIS_InteractiveContext) anAISContext = myViewer->getAISContext();
+
+        anAISContext->ClearSelected( Standard_False );
+        SelectMgr_SequenceOfOwner::Iterator anIt( mySelection );
+        for( ; anIt.More(); anIt.Next() )
+        {
+          anAISContext->AddOrRemoveSelected( anIt.Value(), Standard_False );
+        }
+
+        anAISContext->Update( myActiveIO, Standard_False );
+        anAISContext->UpdateCurrentViewer();
+        anAISContext->MoveTo( aMouseEv->pos().x(), aMouseEv->pos().y(), aView3d );
+
+        mySelection.Clear();
+        myActiveIO.Nullify();
+        return (theEvent->type() == QEvent::MouseButtonRelease);
+      }
+
+      return false;
+    }
+
+    default: return false;
+  }
+}
diff --git a/src/MeasureGUI/MeasureGUI_AnnotationInteractor.h b/src/MeasureGUI/MeasureGUI_AnnotationInteractor.h
new file mode 100755 (executable)
index 0000000..ed9bc0b
--- /dev/null
@@ -0,0 +1,110 @@
+// 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
+//
+// 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
+//
+
+// GEOM GEOMGUI : GUI for Geometry component
+// File   : MeasureGUI_AnnotationInteractor.h
+// Author : Anton POLETAEV, Open CASCADE S.A.S.
+//
+#ifndef MEASUREGUI_ANNOTATIONINTERACTOR_H
+#define MEASUREGUI_ANNOTATIONINTERACTOR_H
+
+#include <GEOM_Annotation.hxx>
+#include <SelectMgr_EntityOwner.hxx>
+#include <SelectMgr_SequenceOfOwner.hxx>
+#include <QObject>
+#include <QPoint>
+
+class GeometryGUI;
+class OCCViewer_Viewer;
+class OCCViewer_ViewManager;
+class OCCViewer_ViewPort3d;
+class SUIT_ViewWindow;
+
+/*!
+ * \class MeasureGUI_AnnotationInteractor
+ * \brief Class implementing logical layer for interactive dragging of annotation
+ *        labels. It includes two components: listener for GUI events occuring
+ *        inside of OCCT 3D viewer and processor for hooked events to perform
+ *        interactive modification of the selected annotation within current
+ *        AIS context.
+ */
+class MeasureGUI_AnnotationInteractor : public QObject
+{
+  Q_OBJECT
+
+public:
+
+  //! Constructor.
+  //! Connects to existing viewer/view windows to process events.
+  //! \param theGUI [in] the geometry module's GUI interface.
+  //! \param theOwner [in] the owner of the instance.
+  MeasureGUI_AnnotationInteractor( GeometryGUI* theGUI, QObject* theOwner );
+
+  //! Destructor.
+  virtual ~MeasureGUI_AnnotationInteractor();
+
+public:
+
+  //! Enables event processing and interaction handlers.
+  void Enable();
+
+  //! Disables event processing and interaction handlers.
+  void Disable();
+
+protected:
+
+  //! Connect interactor's event handler to the view window given.
+  void ConnectView( SUIT_ViewWindow* theWindow );
+
+  //! Disconnect interactor's event handler from the view window given.
+  void DisconnectView( SUIT_ViewWindow* theWindow );
+
+protected slots:
+
+  //! Handler for signal coming from GUI layer.
+  void OnViewCreated( SUIT_ViewWindow* );
+
+  //! Handler for signal coming from GUI layer.
+  void OnViewRemoved( SUIT_ViewWindow* );
+
+protected:
+
+  //! Hooks and process events from OCCT viewer prior to their coming into the base viewer class.
+  //! It handles the events coming to viewport and identifies whether the events can
+  //! invoke an interaction operation or not. If yes, the operation is performed within the
+  //! interactor class and events are "accepted". Otherwise, the events are passed to
+  //! viewer's subroutines.
+  virtual bool eventFilter( QObject*, QEvent* );
+
+private:
+
+  GeometryGUI*              myGeomGUI;
+  bool                      myIsEnabled;
+  OCCViewer_ViewManager*    myVM;
+  OCCViewer_Viewer*         myViewer;
+  OCCViewer_ViewPort3d*     myActiveViewPort;
+  Handle(GEOM_Annotation)   myActiveIO;
+  SelectMgr_SequenceOfOwner mySelection;
+  QPoint                    myStartPoint;
+};
+
+#endif
index 92e26b895a8ea7b65b39b9854f0dbe50a5bf5477..9dfdfebd594f365ec0a4c403f91a7881fb080e8f 100755 (executable)
 #include <OpenGl_Text.hxx>
 #include <OpenGl_View.hxx>
 #include <OpenGl_Workspace.hxx>
+#include <Prs3d_PointAspect.hxx>
 #include <Prs3d_Root.hxx>
 #include <Prs3d_Text.hxx>
 #include <Select3D_SensitiveBox.hxx>
 #include <SelectMgr_EntityOwner.hxx>
 #include <V3d_Viewer.hxx>
+#include <V3d_View.hxx>
 
 IMPLEMENT_STANDARD_RTTIEXT( GEOM_Annotation, AIS_InteractiveObject )
 
@@ -64,6 +66,7 @@ GEOM_Annotation::GEOM_Annotation() : AIS_InteractiveObject()
   SetZLayer( Graphic3d_ZLayerId_Top );
   SetAutoHide( Standard_True );
   SetHilightMode( HighlightAll );
+  SetMutable( Standard_True );
 
   Handle(Prs3d_TextAspect) aTextAspect = new Prs3d_TextAspect();
   aTextAspect->SetHeight( 20.0 );
@@ -73,6 +76,10 @@ GEOM_Annotation::GEOM_Annotation() : AIS_InteractiveObject()
   Handle(Prs3d_LineAspect) aLineAspect =
     new Prs3d_LineAspect( Quantity_NOC_WHITE, Aspect_TOL_SOLID, 1.0 );
   myDrawer->SetLineAspect( aLineAspect );
+
+  Handle(Prs3d_PointAspect) aPointAspect =
+    new Prs3d_PointAspect( Aspect_TOM_POINT, Quantity_NOC_WHITE, 4.0 );
+  myDrawer->SetPointAspect( aPointAspect );
 }
 
 // =======================================================================
@@ -94,10 +101,30 @@ void GEOM_Annotation::SetText( const TCollection_ExtendedString& theText )
 // purpose  :
 // =======================================================================
 void GEOM_Annotation::SetPosition( const gp_Pnt& thePosition )
+{
+  SetPosition( thePosition, Standard_True );
+}
+
+// =======================================================================
+// function : SetPosition
+// purpose  :
+// =======================================================================
+void GEOM_Annotation::SetPosition( const gp_Pnt& thePosition, const Standard_Boolean theUpdateSelection )
 {
   myPosition = thePosition;
 
-  UpdatePersistence();
+  Handle(Graphic3d_TransformPers) aPersistence;
+  if ( !myIsScreenFixed )
+  {
+    AIS_InteractiveObject::SetTransformPersistence( Graphic3d_TMF_ZoomPers | Graphic3d_TMF_RotatePers, thePosition );
+  }
+
+  SetToUpdate();
+
+  if( theUpdateSelection )
+  {
+    UpdateSelection();
+  }
 }
 
 // =======================================================================
@@ -108,7 +135,20 @@ void GEOM_Annotation::SetScreenFixed( const Standard_Boolean theIsFixed )
 {
   myIsScreenFixed = theIsFixed;
 
-  UpdatePersistence();
+  if (!myIsScreenFixed)
+  {
+    AIS_InteractiveObject::SetTransformPersistence( Graphic3d_TMF_ZoomPers | Graphic3d_TMF_RotatePers, myPosition );
+  }
+  else
+  {
+    AIS_InteractiveObject::SetTransformPersistence( Graphic3d_TMF_2d );
+  }
+
+  SetZLayer( myIsScreenFixed ? Graphic3d_ZLayerId_Topmost : Graphic3d_ZLayerId_Top );
+
+  SetToUpdate();
+
+  UpdateSelection();
 }
 
 // =======================================================================
@@ -148,6 +188,7 @@ void GEOM_Annotation::SetTextColor( const Quantity_Color& theColor )
 void GEOM_Annotation::SetLineColor( const Quantity_Color& theColor )
 {
   myDrawer->LineAspect()->SetColor( theColor );
+  myDrawer->PointAspect()->SetColor( theColor );
 
   SetToUpdate();
 }
@@ -222,22 +263,6 @@ void GEOM_Annotation::SetLineStyle( const Aspect_TypeOfLine theStyle )
   }
 }
 
-// =======================================================================
-// function : UpdatePersistence
-// purpose  :
-// =======================================================================
-void GEOM_Annotation::UpdatePersistence()
-{
-  if (!myIsScreenFixed)
-  {
-    AIS_InteractiveObject::SetTransformPersistence( Graphic3d_TMF_ZoomPers | Graphic3d_TMF_RotatePers, myPosition );
-  }
-  else
-  {
-    AIS_InteractiveObject::SetTransformPersistence( Graphic3d_TMF_2d, gp_Pnt( 0.0, 0.0, 0.0 ) );
-  }
-}
-
 // =======================================================================
 // function : Compute
 // purpose  :
@@ -267,10 +292,18 @@ void GEOM_Annotation::Compute( const Handle(PrsMgr_PresentationManager3d)& /*the
   aGroup->AddElement( aAnnotationDraw );
   aGroup->SetGroupPrimitivesAspect( myDrawer->TextAspect()->Aspect() );
   aGroup->SetGroupPrimitivesAspect( myDrawer->LineAspect()->Aspect() );
+  aGroup->SetGroupPrimitivesAspect( myDrawer->PointAspect()->Aspect() );
+
+  Bnd_Box aBox = TextBoundingBox();
+  if ( myIsScreenFixed )
+  {
+    gp_Trsf aOffset2d;
+    aOffset2d.SetTranslation( gp_Vec( myPosition.X(), myPosition.Y(), 0.0 ) );
+    aBox = aBox.Transformed( aOffset2d );
+  }
 
-  const NCollection_Handle<Bnd_Box> aBoundingBox = TextBoundingBox();
-  const gp_Pnt aBoxMin = aBoundingBox->CornerMin();
-  const gp_Pnt aBoxMax = aBoundingBox->CornerMax();
+  const gp_Pnt aBoxMin = aBox.CornerMin();
+  const gp_Pnt aBoxMax = aBox.CornerMax();
   aGroup->ChangeBoundingBox() = Graphic3d_BndBox4f (
     Graphic3d_Vec4( static_cast<Standard_ShortReal>( aBoxMin.X() ),
                     static_cast<Standard_ShortReal>( aBoxMin.Y() ),
@@ -287,16 +320,23 @@ void GEOM_Annotation::Compute( const Handle(PrsMgr_PresentationManager3d)& /*the
 void GEOM_Annotation::ComputeSelection( const Handle(SelectMgr_Selection)& theSelection,
                                         const Standard_Integer             theMode )
 {
-  if (theMode != 0)
+  if (theMode != GlobalSelectionMode())
   {
     return;
   }
 
   theSelection->Clear();
 
-  const NCollection_Handle<Bnd_Box> aBoundingBox = TextBoundingBox();
-  const Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner( this, 10 );
-  const Handle(Select3D_SensitiveBox) aSensitive = new Select3D_SensitiveBox( anEntityOwner, *aBoundingBox.get() );
+  Bnd_Box aBox = TextBoundingBox();
+  if ( myIsScreenFixed )
+  {
+    gp_Trsf aOffset2d;
+    aOffset2d.SetTranslation( gp_Vec( myPosition.X(), myPosition.Y(), 0.0 ) );
+    aBox = aBox.Transformed( aOffset2d );
+  }
+
+  const Handle(GEOM_AnnotationOwner) anEntityOwner = new GEOM_AnnotationOwner( this, 10 );
+  const Handle(Select3D_SensitiveBox) aSensitive = new Select3D_SensitiveBox( anEntityOwner, aBox );
   theSelection->Add( aSensitive );
 }
 
@@ -304,10 +344,9 @@ void GEOM_Annotation::ComputeSelection( const Handle(SelectMgr_Selection)& theSe
 // function : TextBoundingBox
 // purpose  :
 // =======================================================================
-NCollection_Handle<Bnd_Box> GEOM_Annotation::TextBoundingBox() const
+Bnd_Box GEOM_Annotation::TextBoundingBox() const
 {
   Handle(Prs3d_TextAspect) anAsp = myDrawer->TextAspect();
-  Bnd_Box aBox;
   Font_FTFont aFont;
   unsigned int aResolution = GetContext()->CurrentViewer()->DefaultRenderingParams().Resolution;
   if ( aFont.Init( anAsp->Aspect()->Font().ToCString(),
@@ -317,13 +356,66 @@ NCollection_Handle<Bnd_Box> GEOM_Annotation::TextBoundingBox() const
   {
     const NCollection_String aText( (Standard_Utf16Char* )myText.ToExtString() );
     const Font_Rect aFontRect = aFont.BoundingBox( aText, Graphic3d_HTA_LEFT, Graphic3d_VTA_BOTTOM );
-    NCollection_Handle<Bnd_Box> aBox = new Bnd_Box();
-    aBox->Add( gp_Pnt( 0.0, 0.0, 0.0 ) );
-    aBox->Add( gp_Pnt( aFontRect.Width(), aFontRect.Height(), 0.0 ) );
+    Bnd_Box aBox;
+    aBox.Add( gp_Pnt( 0.0, 0.0, 0.0 ) );
+    aBox.Add( gp_Pnt( aFontRect.Width(), aFontRect.Height(), 0.0 ) );
     return aBox;
   }
 
-  return NCollection_Handle<Bnd_Box>();
+  return Bnd_Box();
+}
+
+// =======================================================================
+// function : BeginDrag
+// purpose  :
+// =======================================================================
+void GEOM_Annotation::BeginDrag()
+{
+  myStartPosition = myPosition;
+}
+
+// =======================================================================
+// function : Drag
+// purpose  :
+// =======================================================================
+void GEOM_Annotation::Drag( const Standard_Integer theDx,
+                            const Standard_Integer theDy,
+                            const Handle(V3d_View)& theView )
+{
+  if (myIsScreenFixed)
+  {
+    SetPosition( myStartPosition.Translated( gp_Vec( theDx, theDy, 0.0 ) ), Standard_False );
+  }
+  else
+  {
+    Standard_Integer aWidth, aHeight;
+    theView->Window()->Size( aWidth, aHeight );
+    gp_Pnt aNormalized = theView->Camera()->Project( myStartPosition );
+    gp_Pnt aNormalizedDrag =
+      aNormalized.Translated( gp_Vec( static_cast<Standard_Real>(theDx) * 2.0 / aWidth,
+                                      static_cast<Standard_Real>(theDy) * 2.0 / aHeight,
+                                      0.0 ) );
+
+    SetPosition( theView->Camera()->UnProject( aNormalizedDrag ), Standard_False );
+  }
+}
+
+// =======================================================================
+// function : EndDrag
+// purpose  :
+// =======================================================================
+void GEOM_Annotation::EndDrag()
+{
+  UpdateSelection();
+}
+
+// =======================================================================
+// function : UndoDrag
+// purpose  :
+// =======================================================================
+void GEOM_Annotation::UndoDrag()
+{
+  SetPosition( myStartPosition, Standard_True );
 }
 
 // =======================================================================
@@ -404,21 +496,25 @@ void GEOM_Annotation::OpenGl_Annotation::Render( const Handle(OpenGl_Workspace)&
   // ---------------------------------------------------------------------
   // initialize text's font and configure some properties when DPI changes
   // ---------------------------------------------------------------------
+
   const unsigned int aDPI = theWorkspace->View()->RenderingParams().Resolution;
   if (myTextDPI != aDPI)
   {
     const OpenGl_AspectText* anAspect = theWorkspace->AspectText();
 
     // getting string size will also initialize font library
-    Standard_ShortReal aWidth, aHeight, aDescent;
-    myTextDraw->StringSize( aContext, myText, *anAspect, myTextParams, aDPI, aWidth, aHeight, aDescent );
+    myTextDraw->StringSize( aContext,
+      myText, *anAspect, myTextParams, aDPI,
+      myTextSize.x(), myTextSize.y(), myTextSize.z() );
+
     myTextDPI = aDPI;
-    myTextLineY = ceil( aHeight * -0.2f );
+    myTextUnderline.x() = 0.f;
+    myTextUnderline.y() = ceil( myTextSize.y() * -0.2f );
 
     Handle(Graphic3d_ArrayOfSegments)
     aVertexArray = new Graphic3d_ArrayOfSegments( 2 );
-    aVertexArray->AddVertex( 0.0f, myTextLineY, 0.0f );
-    aVertexArray->AddVertex( aWidth, myTextLineY, 0.0f );
+    aVertexArray->AddVertex( 0.0f, myTextUnderline.y(), 0.0f );
+    aVertexArray->AddVertex( myTextSize.x(), myTextUnderline.y(), 0.0f );
     myTextLineDraw->InitBuffers( aContext, Graphic3d_TOPA_SEGMENTS,
       aVertexArray->Indices(), aVertexArray->Attributes(), aVertexArray->Bounds() );
   }
@@ -426,6 +522,7 @@ void GEOM_Annotation::OpenGl_Annotation::Render( const Handle(OpenGl_Workspace)&
   // ---------------------------------------------
   // perform view culling test by attachment point
   // ---------------------------------------------
+
   const OpenGl_Vec4 aAttach( static_cast<float>( myAISObject->myAttach.X() ),
                              static_cast<float>( myAISObject->myAttach.Y() ),
                              static_cast<float>( myAISObject->myAttach.Z() ), 1.F );
@@ -437,35 +534,72 @@ void GEOM_Annotation::OpenGl_Annotation::Render( const Handle(OpenGl_Workspace)&
   if (myAISObject->myIsAutoHide)
   {
     const OpenGl_Vec4 aAttachClip = aCameraProjMat * aAttachView;
-    if (abs( aAttachClip.x() ) > aAttachClip.w()
-     || abs( aAttachClip.y() ) > aAttachClip.w()
-     || abs( aAttachClip.z() ) > aAttachClip.w())
+    if (Abs( aAttachClip.x() ) > aAttachClip.w()
+     || Abs( aAttachClip.y() ) > aAttachClip.w()
+     || Abs( aAttachClip.z() ) > aAttachClip.w())
     {
       return;
     }
   }
 
+  const bool toHighlight = theWorkspace->ToHighlight();
+
+  if (toHighlight && myAISObject->myHilightMode == HighlightLabel)
+  {
+    theWorkspace->SetHighlight( false );
+    theWorkspace->ApplyAspectLine();
+  }
+
   // -------------------------------------------------------------
   // render text label in current persistence matrix and underline
   // -------------------------------------------------------------
+
+  if ( myAISObject->myIsScreenFixed )
+  {
+    myTextDraw->SetPosition( OpenGl_Vec3( static_cast<float>( myAISObject->myPosition.X() ),
+                                          static_cast<float>( myAISObject->myPosition.Y() ),
+                                          static_cast<float>( myAISObject->myPosition.Z() ) ) );
+  }
+
   myTextDraw->Render( theWorkspace );
 
-  // ----------------------------------------------
-  // render underline in current persistence matrix
-  // ----------------------------------------------
-  const bool toHighlight = theWorkspace->ToHighlight();
-  if (toHighlight && myAISObject->myHilightMode == HighlightLabel)
+  // ------------------------------------------------------------
+  // render annotation text's underline
+  // ------------------------------------------------------------
+
+  if ( myAISObject->myIsScreenFixed )
   {
-    theWorkspace->SetHighlight( false );
-    theWorkspace->ApplyAspectLine();
+    // setup local transformation (in 2D persistence reference)
+    // to represent position of annotation label on screen
+    const OpenGl_Mat4& aViewMat = aContext->WorldViewState.Current();
+    OpenGl_Mat4 aPositionMat;
+    aPositionMat.SetValue( 0, 3, static_cast<float>( myAISObject->myPosition.X() ) );
+    aPositionMat.SetValue( 1, 3, static_cast<float>( myAISObject->myPosition.Y() ) );
+    aPositionMat.SetValue( 2, 3, static_cast<float>( myAISObject->myPosition.Z() ) );
+    OpenGl_Mat4 aPosViewMat = aViewMat * aPositionMat;
+    aContext->WorldViewState.Push();
+    aContext->WorldViewState.SetCurrent( aPosViewMat );
+    aContext->ApplyModelViewMatrix();
   }
+
   myTextLineDraw->Render( theWorkspace );
 
   // ------------------------------------------------------------
   // render dynamic extension line using synthetic transformation
   // ------------------------------------------------------------
+
+  // compute label's center in view coordinate space
   const OpenGl_Mat4& aViewMat = aContext->WorldViewState.Current();
-  const OpenGl_Vec4  aHingeView = aViewMat * OpenGl_Vec4( 0.0f, myTextLineY, 0.0f, 1.0f );
+  const OpenGl_Vec4 aCenterView =
+    aViewMat * OpenGl_Vec4( myTextSize.x() / 2.0f, myTextSize.y() / 2.0f, 0.0f, 1.0f );
+
+  // the value below defines whether the extension line should be hanging
+  // on the left side of the label or on the right
+  const bool isLeftHanded = aAttachView.x() < aCenterView.x();
+
+  // compute extension line point at the text label in view coordinate space
+  const OpenGl_Vec4 aHingeView = aViewMat * OpenGl_Vec4(
+    ( isLeftHanded ? myTextUnderline.x() : myTextUnderline.x() + myTextSize.x() ), myTextUnderline.y(), 0.0f, 1.0f );
 
   // prepare matrix to specify geometry of extension line in view space
   // by multiplication of unit z coordinate vector on given matrix.
@@ -473,6 +607,7 @@ void GEOM_Annotation::OpenGl_Annotation::Render( const Handle(OpenGl_Workspace)&
   aExtGeometryMat.SetColumn( 2, aAttachView - aHingeView );
   aExtGeometryMat.SetColumn( 3, aHingeView );
 
+  // setup and draw
   aContext->ModelWorldState.Push();
   aContext->ModelWorldState.SetIdentity();
   aContext->WorldViewState.Push();
@@ -482,8 +617,18 @@ void GEOM_Annotation::OpenGl_Annotation::Render( const Handle(OpenGl_Workspace)&
   myExtLineDraw->Render( theWorkspace );
   myExtMarkerDraw->Render( theWorkspace );
 
+  // ------------------------------------------------------------
+  // restore original state
+  // ------------------------------------------------------------
+
   aContext->ModelWorldState.Pop();
   aContext->WorldViewState.Pop();
+
+  if (myAISObject->myIsScreenFixed)
+  {
+    aContext->WorldViewState.Pop();
+  }
+
   aContext->ApplyModelViewMatrix();
 
   if (toHighlight != theWorkspace->ToHighlight())
@@ -492,3 +637,14 @@ void GEOM_Annotation::OpenGl_Annotation::Render( const Handle(OpenGl_Workspace)&
   }
 }
 
+// =======================================================================
+// subclass : GEOM_AnnotationOwner
+// function : HilightWithColor
+// purpose  : Perform highlighting of the presentation.
+// =======================================================================
+void GEOM_Annotation::GEOM_AnnotationOwner::HilightWithColor( const Handle(PrsMgr_PresentationManager3d)& thePresentationMgr,
+                                                              const Quantity_NameOfColor theColor,
+                                                              const Standard_Integer theMode )
+{
+  thePresentationMgr->Color( Selectable(), theColor, theMode, NULL, Selectable()->ZLayer() );
+}
index ac6b2890453c5f3b2ef35b34c7f744e417d22ea8..ef7fcc57e60327c7e664a538dadfcb5a88841dc4 100755 (executable)
@@ -45,6 +45,7 @@
 class OpenGl_GraphicDriver;
 class OpenGl_PrimitiveArray;
 class OpenGl_Text;
+class V3d_View;
 
 /*!
  * \class GEOM_Annotation
@@ -171,9 +172,26 @@ public:
   //! Returns highlight mode
   HighlightMode GetHilightMode() const { return myHilightMode; }
 
-private:
+// Interactive dragging:
+public:
+
+  //! Prepares necessary data to perform dragging.
+  Standard_EXPORT void BeginDrag();
+
+  //! Drags annotation presentation in the screen plane using the given pixel delta.
+  //! \param theDx, theDy [in] the drag offset in pixels (from beginning of dragging).
+  //! \param theView [in] the current view for evaluating drag with 3D position mode.
+  Standard_EXPORT void Drag( const Standard_Integer theDx,
+                             const Standard_Integer theDy,
+                             const Handle(V3d_View)& theView );
 
-  void UpdatePersistence();
+  //! Perform necessary update when dragging is finished.
+  Standard_EXPORT void EndDrag();
+
+  //! Perform necessary update when dragging need undo.
+  Standard_EXPORT void UndoDrag();
+
+private:
 
   virtual void Compute( const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
                         const Handle(Prs3d_Presentation)& thePresentation,
@@ -182,17 +200,20 @@ private:
   virtual void ComputeSelection( const Handle(SelectMgr_Selection)& theSelection,
                                  const Standard_Integer theMode ) Standard_OVERRIDE;
 
-  virtual void SetLocalTransformation( const gp_Trsf& theTransformation ) Standard_OVERRIDE {}
+  virtual void SetLocalTransformation( const gp_Trsf& /*theTransformation*/ ) Standard_OVERRIDE {}
+
+  virtual void SetTransformPersistence( const Graphic3d_TransModeFlags& /*theFlag*/,
+                                        const gp_Pnt& /*thePoint*/ ) Standard_OVERRIDE {}
 
-  virtual void SetTransformPersistence( const Graphic3d_TransModeFlags& theFlag,
-                                        const gp_Pnt& thePoint = gp_Pnt (0.0, 0.0, 0.0) ) Standard_OVERRIDE {}
+  Bnd_Box TextBoundingBox() const;
 
-  NCollection_Handle<Bnd_Box> TextBoundingBox() const;
+  void SetPosition( const gp_Pnt& thePosition, const Standard_Boolean theUpdateSelection );
 
 private:
 
   gp_Pnt myAttach; //!< Attachment point of extension line.
   gp_Pnt myPosition; //!< Position of text label.
+  gp_Pnt myStartPosition; //!< Position before starting dragging operation.
   Standard_Boolean myIsScreenFixed; //!< Flag indicating whether "screen fixed" positioning mode is turned on or off.
   Standard_Boolean myIsAutoHide; //!< Flag indicating whether "auto-hiding" option is turned on.
   HighlightMode myHilightMode; //!< Highlight mode for presentation.
@@ -234,10 +255,34 @@ private:
     OpenGl_PrimitiveArray* myExtLineDraw;   //!< Extension line draw element.
     OpenGl_PrimitiveArray* myExtMarkerDraw; //!< Extension marker draw element.
     mutable float myTextLineY;              //!< Text's underlines relative position.
+    mutable Graphic3d_Vec3 myTextSize;      //!< Text's width, height and descent.
+    mutable Graphic3d_Vec2 myTextUnderline; //!< Text's underline position.
     mutable unsigned int myTextDPI;         //!< Text's DPI scale used for last rendering.
   };
 
   friend class OpenGl_Annotation; // allow opengl element to get private data and invoke callback methods
+
+private:
+
+  //! Custom entity owner implementing correct highlight for topmost mode.
+  class GEOM_AnnotationOwner : public SelectMgr_EntityOwner
+  {
+  public:
+
+    //! Constructor.
+    GEOM_AnnotationOwner( const Handle(SelectMgr_SelectableObject)& theSelectable,
+                          const Standard_Integer thePriority = 0 )
+      : SelectMgr_EntityOwner( theSelectable, thePriority ) {}
+
+    //! Perform highlighting of the presentation.
+    //! \param thePresentationMgr [in] the presentation manager.
+    //! \param theColor [in] the highlighting color.
+    //! \param theMode [in] the display mode.
+    virtual void
+      HilightWithColor( const Handle(PrsMgr_PresentationManager3d)& thePresentationMgr,
+                        const Quantity_NameOfColor theColor,
+                        const Standard_Integer theMode = 0 ) Standard_OVERRIDE;
+  };
 };
 
 DEFINE_STANDARD_HANDLE( GEOM_Annotation, AIS_InteractiveObject )