Salome HOME
Copyright update 2022
[modules/geom.git] / src / MeasureGUI / MeasureGUI_AnnotationInteractor.cxx
1 // Copyright (C) 2007-2022  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 // GEOM GEOMGUI : GUI for Geometry component
24 // File   : MeasureGUI_AnnotationInteractor.cxx
25 // Author : Anton POLETAEV, Open CASCADE S.A.S.
26
27 #include "MeasureGUI_AnnotationInteractor.h"
28
29 // SALOME includes
30 #include <GeometryGUI.h>
31 #include <OCCViewer_ViewManager.h>
32 #include <OCCViewer_ViewPort3d.h>
33 #include <OCCViewer_ViewWindow.h>
34 #include <SUIT_ViewManager.h>
35 #include <SUIT_ViewWindow.h>
36 #include <SUIT_Desktop.h>
37 #include <SalomeApp_Application.h>
38
39 // Qt includes
40 #include <QMouseEvent>
41
42 // OCCT includes
43 #include <V3d_View.hxx>
44
45 //=================================================================================
46 // function : Constructor
47 // purpose  : 
48 //=================================================================================
49 MeasureGUI_AnnotationInteractor::MeasureGUI_AnnotationInteractor( GeometryGUI* theGUI,
50                                                                   QObject* theParent )
51 : QObject( theParent ),
52   myGeomGUI( theGUI ),
53   myIsEnabled( false ),
54   myVM( NULL ),
55   myViewer( NULL ),
56   myActiveViewPort( NULL )
57 {
58 }
59
60 //=================================================================================
61 // function : Deactivate
62 // purpose  : 
63 //=================================================================================
64 MeasureGUI_AnnotationInteractor::~MeasureGUI_AnnotationInteractor()
65 {
66   if ( myActiveViewPort )
67   {
68     myActiveViewPort->releaseMouse();
69     myActiveViewPort = NULL;
70   }
71
72   Disable();
73 }
74
75 //=================================================================================
76 // function : Enable
77 // purpose  : Enables event processing and interaction handlers.
78 //=================================================================================
79 void MeasureGUI_AnnotationInteractor::Enable()
80 {
81   if ( myIsEnabled )
82   {
83     return;
84   }
85
86   myIsEnabled = true;
87
88   // install event filtering on viewer windows
89   SalomeApp_Application* anApp = myGeomGUI->getApp();
90   if ( !anApp )
91   {
92     return;
93   }
94
95   myVM     = (OCCViewer_ViewManager*) anApp->getViewManager( OCCViewer_Viewer::Type(), false );
96   myViewer = (OCCViewer_Viewer*) myVM->getViewModel();
97   if ( !myVM || !myViewer )
98   {
99     return;
100   }
101
102   connect( myVM, SIGNAL( viewCreated( SUIT_ViewWindow* ) ), SLOT( OnViewCreated( SUIT_ViewWindow* ) ) );
103   connect( myVM, SIGNAL( deleteView ( SUIT_ViewWindow* ) ), SLOT( OnViewRemoved( SUIT_ViewWindow* ) ) );
104
105   QVector<SUIT_ViewWindow*>           aViews  = myVM->getViews();
106   QVector<SUIT_ViewWindow*>::iterator aViewIt = aViews.begin();
107   for ( ; aViewIt != aViews.end(); ++aViewIt )
108   {
109     ConnectView( *aViewIt );
110   }
111 }
112
113 //=================================================================================
114 // function : Disable
115 // purpose  : Disables event processing and interaction handlers.
116 //=================================================================================
117 void MeasureGUI_AnnotationInteractor::Disable()
118 {
119   if ( !myIsEnabled )
120   {
121     return;
122   }
123
124   myIsEnabled = false;
125
126   // remove event filtering from viewer windows
127   QVector<SUIT_ViewWindow*>           aViews  = myVM->getViews();
128   QVector<SUIT_ViewWindow*>::iterator aViewIt = aViews.begin();
129   for ( ; aViewIt != aViews.end(); ++aViewIt )
130   {
131     DisconnectView( *aViewIt );
132   }
133
134   if ( myActiveViewPort )
135   {
136     myActiveViewPort->releaseMouse();
137     myActiveViewPort = NULL;
138   }
139
140   if ( !myActiveIO.IsNull() )
141   {
142     emit SignalInteractionFinished( myActiveIO );
143     myActiveIO.Nullify();
144   }
145 }
146
147 //=================================================================================
148 // function : ConnectView
149 // purpose  : Connect interactor's event handler to the view window given.
150 //=================================================================================
151 void MeasureGUI_AnnotationInteractor::ConnectView( SUIT_ViewWindow* theView )
152 {
153   ( (OCCViewer_ViewWindow*) theView )->getViewPort()->installEventFilter( this );
154 }
155
156 //=================================================================================
157 // function : DisconnectView
158 // purpose  : Disconnect interactor's event handler from the view window given.
159 //=================================================================================
160 void MeasureGUI_AnnotationInteractor::DisconnectView( SUIT_ViewWindow* theView )
161 {
162   ( (OCCViewer_ViewWindow*) theView )->getViewPort()->removeEventFilter( this );
163 }
164
165 //=================================================================================
166 // function : OnViewCreated
167 // purpose  : Handler for signal coming from GUI layer.
168 //=================================================================================
169 void MeasureGUI_AnnotationInteractor::OnViewCreated( SUIT_ViewWindow* theView )
170 {
171   ConnectView( theView );
172 }
173
174 //=================================================================================
175 // function : OnViewRemoved
176 // purpose  : Handler for signal coming from GUI layer.
177 //=================================================================================
178 void MeasureGUI_AnnotationInteractor::OnViewRemoved( SUIT_ViewWindow* theView )
179 {
180   DisconnectView( theView );
181 }
182
183 //=================================================================================
184 // function : eventFilter
185 // purpose  : Hooks and process events from OCCT viewer prior to their coming into the base viewer class.
186 //=================================================================================
187 bool MeasureGUI_AnnotationInteractor::eventFilter( QObject* theObject, QEvent* theEvent )
188 {
189   OCCViewer_ViewPort3d* aViewPort = (OCCViewer_ViewPort3d*)theObject;
190
191   const Handle(V3d_View) aView3d = aViewPort->getView();
192
193   switch( theEvent->type() )
194   {
195     // ------------------------------------------------------------------------
196     // Start dragging ("grab") event
197     // ------------------------------------------------------------------------
198     case QEvent::MouseButtonPress :
199     {
200       QMouseEvent* aMouseEv = dynamic_cast<QMouseEvent*>( theEvent );
201
202       if ( myEditEntry.isEmpty() )
203       {
204         return false;
205       }
206
207       if ( !( aMouseEv->buttons() & Qt::LeftButton ) )
208       {
209         return false;
210       }
211
212       const Handle(AIS_InteractiveContext) anAISContext = myViewer->getAISContext();
213
214       anAISContext->MoveTo( aMouseEv->x(), aMouseEv->y(), aView3d, Standard_True );
215
216       if ( !anAISContext->HasDetected() )
217       {
218         return false;
219       }
220
221       const Handle(SelectMgr_EntityOwner) aDetected = anAISContext->DetectedOwner();
222
223       if( aDetected.IsNull() )
224       {
225         return false;
226       }
227
228       const Handle(GEOM_Annotation) aAnnotation =
229         Handle(GEOM_Annotation)::DownCast( aDetected->Selectable() );
230
231       if ( aAnnotation.IsNull() )
232       {
233         return false;
234       }
235
236       const Handle(SALOME_InteractiveObject) anIO = 
237         Handle(SALOME_InteractiveObject)::DownCast( aAnnotation->GetOwner() );
238
239       if ( anIO.IsNull() || anIO->getEntry() != myEditEntry )
240       {
241         return false;
242       }
243
244       myStartPoint = aMouseEv->pos();
245       mySelection.Clear();
246
247       for ( anAISContext->InitSelected(); anAISContext->MoreSelected(); anAISContext->NextSelected() )
248       {
249         mySelection.Append( anAISContext->SelectedOwner() );
250       }
251
252       anAISContext->ClearSelected( Standard_False );
253       anAISContext->Unhilight( myActiveIO, Standard_True );
254
255       myActiveViewPort = aViewPort;
256       myActiveViewPort->grabMouse();
257       myActiveIO = aAnnotation;
258       myActiveIO->BeginDrag();
259
260       emit SignalInteractionStarted( myActiveIO );
261
262       return true;
263     }
264
265     // ------------------------------------------------------------------------
266     // Perform dragging operation
267     // ------------------------------------------------------------------------
268     case QEvent::MouseMove :
269     {
270       QMouseEvent* aMouseEv = (QMouseEvent*) theEvent;
271
272       if ( !myActiveIO.IsNull() )
273       {
274         const Handle(AIS_InteractiveContext) anAISContext = myViewer->getAISContext();
275
276         if ( anAISContext->IsHilighted( myActiveIO ) )
277         {
278           anAISContext->Unhilight( myActiveIO, Standard_False );
279         }
280
281         const QPoint aDelta = aMouseEv->pos() - myStartPoint;
282         myActiveIO->Drag( aDelta.x(), (-aDelta.y()), aView3d );
283         anAISContext->Update( myActiveIO, Standard_False );
284         anAISContext->UpdateCurrentViewer();
285         return true;
286       }
287
288       return false;
289     }
290
291     // ------------------------------------------------------------------------
292     // Stop dragging operation
293     // ------------------------------------------------------------------------
294     case QEvent::FocusOut :
295     case QEvent::MouseButtonRelease :
296     {
297       QMouseEvent* aMouseEv = (QMouseEvent*) theEvent;
298
299       if ( myActiveViewPort )
300       {
301         myActiveViewPort->releaseMouse();
302         myActiveViewPort = NULL;
303       }
304       if ( !myActiveIO.IsNull() )
305       {
306         myActiveIO->EndDrag();
307
308         const Handle(AIS_InteractiveContext) anAISContext = myViewer->getAISContext();
309
310         anAISContext->ClearSelected( Standard_False );
311         SelectMgr_SequenceOfOwner::Iterator anIt( mySelection );
312         for( ; anIt.More(); anIt.Next() )
313         {
314           anAISContext->AddOrRemoveSelected( anIt.Value(), Standard_False );
315         }
316
317         anAISContext->Update( myActiveIO, Standard_False );
318         anAISContext->UpdateCurrentViewer();
319         anAISContext->MoveTo( aMouseEv->pos().x(), aMouseEv->pos().y(), aView3d, Standard_True );
320
321         emit SignalInteractionFinished( myActiveIO );
322
323         mySelection.Clear();
324         myActiveIO.Nullify();
325         return (theEvent->type() == QEvent::MouseButtonRelease);
326       }
327
328       return false;
329     }
330
331     default: return false;
332   }
333 }