Salome HOME
Synchronize adm files
[modules/gui.git] / src / GraphicsView / GraphicsView_ViewTransformer.cxx
1 // Copyright (C) 2013-2014  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "GraphicsView_ViewTransformer.h"
21
22 #include "GraphicsView_Scene.h"
23 #include "GraphicsView_ViewPort.h"
24 #include "GraphicsView_Viewer.h"
25
26 #include <QGraphicsSceneMouseEvent>
27 #include <QRectF>
28 #include <QRubberBand>
29
30 int GraphicsView_ViewTransformer::panBtn = Qt::MidButton;
31 int GraphicsView_ViewTransformer::zoomBtn = Qt::LeftButton;
32 int GraphicsView_ViewTransformer::fitRectBtn = Qt::LeftButton;
33 int GraphicsView_ViewTransformer::panGlobalBtn = Qt::LeftButton;
34 int GraphicsView_ViewTransformer::acccelKey = Qt::ControlModifier;
35
36 //=======================================================================
37 // Name    : GraphicsView_ViewTransformer
38 // Purpose : Constructor
39 //=======================================================================
40 GraphicsView_ViewTransformer::GraphicsView_ViewTransformer( GraphicsView_Viewer* v, int type )
41 : QObject( 0 ),
42   myViewer( v ),
43   myType( type ),
44   myMajorBtn( Qt::NoButton ),
45   myButtonState( 0 ),
46   myRectBand( 0 )
47 {
48   if( myType == GraphicsView_Viewer::Pan ||
49       myType == GraphicsView_Viewer::Zoom ||
50       myType == GraphicsView_Viewer::PanGlobal ||
51       myType == GraphicsView_Viewer::FitRect )
52     initTransform( true );
53 }
54
55 //=======================================================================
56 // Name    : GraphicsView_ViewTransformer
57 // Purpose : Destructor
58 //=======================================================================
59 GraphicsView_ViewTransformer::~GraphicsView_ViewTransformer()
60 {
61   if( myType == GraphicsView_Viewer::Pan ||
62       myType == GraphicsView_Viewer::Zoom ||
63       myType == GraphicsView_Viewer::PanGlobal ||
64       myType == GraphicsView_Viewer::FitRect )
65     initTransform( false );
66
67   endDrawRect();
68 }
69
70 //================================================================
71 // Function : initTransform
72 // Purpose  : 
73 //================================================================
74 void GraphicsView_ViewTransformer::initTransform( bool init )
75 {
76   if( GraphicsView_ViewPort* aViewPort = myViewer->getActiveViewPort() )
77   {
78     if( GraphicsView_Scene* aScene = aViewPort->getScene() )
79     {
80       if( init )
81       {
82         mySavedCursor = aViewPort->cursor();
83         mySavedMouseTrack = aViewPort->hasMouseTracking();
84         aViewPort->setMouseTracking( false );
85         aScene->installEventFilter( this );
86       }
87       else
88       {
89         aScene->removeEventFilter( this );
90         aViewPort->setMouseTracking( mySavedMouseTrack );
91         aViewPort->setCursor( mySavedCursor );
92       }
93     }
94   }
95 }
96
97 //================================================================
98 // Function : exec
99 // Purpose  : 
100 //================================================================
101 void GraphicsView_ViewTransformer::exec()
102 {
103   GraphicsView_ViewPort* aViewPort = myViewer->getActiveViewPort();
104   if( !aViewPort )
105     return;
106
107   switch( myType )
108   {
109     case GraphicsView_Viewer::Zoom:
110       myMajorBtn = zoomButton();
111       aViewPort->setCursor( *aViewPort->getZoomCursor() );
112       break;
113     case GraphicsView_Viewer::Pan:
114       myMajorBtn = panButton();
115       aViewPort->setCursor( *aViewPort->getPanCursor() );
116       break;
117     case GraphicsView_Viewer::PanGlobal:
118       myMajorBtn = panGlobalButton();
119       aViewPort->setCursor( *aViewPort->getPanglCursor() );
120       aViewPort->fitAll( true );
121       break;
122     case GraphicsView_Viewer::FitRect:
123       myMajorBtn = fitRectButton();
124       aViewPort->setCursor( *aViewPort->getHandCursor() );
125       break;
126     case GraphicsView_Viewer::Reset:
127       aViewPort->reset();
128       onTransform( Finished );
129       break;
130     case GraphicsView_Viewer::FitAll:
131       aViewPort->fitAll();
132       onTransform( Finished );
133       break;
134     case GraphicsView_Viewer::FitSelect:
135       aViewPort->fitSelect();
136       onTransform( Finished );
137       break;
138     case GraphicsView_Viewer::FitWidth:
139       aViewPort->fitWidth();
140       onTransform( Finished );
141       break;
142     default: break;
143   }
144 }
145
146 //================================================================
147 // Function : eventFilter
148 // Purpose  : 
149 //================================================================
150 bool GraphicsView_ViewTransformer::eventFilter( QObject* o, QEvent* e )
151 {
152   switch( e->type() )
153   {
154     case QEvent::GraphicsSceneMouseMove:
155     case QEvent::GraphicsSceneMousePress:
156     case QEvent::GraphicsSceneMouseRelease:
157     {
158       TransformState state = InProcess;
159       QGraphicsSceneMouseEvent* me = ( QGraphicsSceneMouseEvent* )e;
160
161       myButtonState = me->buttons();
162       if ( e->type() == QEvent::GraphicsSceneMousePress )
163         myButtonState |= me->button();
164
165       if ( e->type() == QEvent::GraphicsSceneMouseRelease )
166         myButtonState |= me->button();
167
168       int mouseOnlyState = ( myButtonState & ( Qt::LeftButton | Qt::MidButton | Qt::RightButton ) );
169       if ( myStart.isNull() )
170       {
171         state = Begin;
172         myStart = myViewer->getActiveViewPort()->mapFromScene( me->scenePos() );
173         myMajorBtn = mouseOnlyState;
174       }
175
176       if ( e->type() == QEvent::GraphicsSceneMouseRelease )
177         state = Finished;
178
179       myCurr = myViewer->getActiveViewPort()->mapFromScene( me->scenePos() );
180       onTransform( state );
181       return true;
182     }
183     default: break;
184   }
185   return QObject::eventFilter( o, e );
186 }
187
188 //================================================================
189 // Function : onTransform
190 // Purpose  : 
191 //================================================================
192 void GraphicsView_ViewTransformer::onTransform( TransformState state )
193 {
194   GraphicsView_ViewPort* aViewPort = myViewer->getActiveViewPort();
195   if( !aViewPort || aViewPort->isTransforming() )
196     return;
197
198   bool doTrsf = ( myButtonState & myMajorBtn );
199   switch ( myType )
200   {
201     case GraphicsView_Viewer::Zoom:
202       if ( state != Finished && doTrsf )
203       {
204         aViewPort->zoom( myStart.x(), myStart.y(), myCurr.x(), myCurr.y() );
205         myStart = myCurr;
206       }
207       break;
208     case GraphicsView_Viewer::Pan:
209       if ( state != Finished && doTrsf )
210       {
211         aViewPort->pan( myCurr.x() - myStart.x(), myStart.y() - myCurr.y() );
212         myStart = myCurr;
213       }
214       break;
215     case GraphicsView_Viewer::PanGlobal:
216       if ( state == Finished )
217       {
218         QPointF aPoint = aViewPort->mapToScene( myCurr.toPoint() );
219         aViewPort->setCenter( aPoint.x(), aPoint.y() );
220       }
221       break;
222     case GraphicsView_Viewer::FitRect:
223       if ( doTrsf )
224       {
225         QRectF aRect( qMin( myStart.x(), myCurr.x() ), qMin( myStart.y(), myCurr.y() ),
226                       qAbs( myStart.x() - myCurr.x() ), qAbs( myStart.y() - myCurr.y() ) );
227         if ( !aRect.isEmpty() )
228         {
229           switch ( state )
230           {
231             case Finished:
232               aRect = aViewPort->mapToScene( aRect.toRect() ).boundingRect();
233               aViewPort->fitRect( aRect );
234               break;
235             default:
236               drawRect( aRect );
237               break;
238           }
239         }
240       }
241       break;
242     default:
243       break;
244   }
245
246   if ( state == Finished )
247     myViewer->activateTransform( GraphicsView_Viewer::NoTransform );
248 }
249
250 //================================================================
251 // Function : drawRect
252 // Purpose  : 
253 //================================================================
254 void GraphicsView_ViewTransformer::drawRect(const QRectF& theRect)
255 {
256   if ( !myRectBand )
257   {
258     myRectBand = new QRubberBand( QRubberBand::Rectangle, myViewer->getActiveViewPort() );
259     QPalette palette;
260     palette.setColor(myRectBand->foregroundRole(), Qt::white);
261     myRectBand->setPalette(palette);
262   }
263   myRectBand->hide();
264
265   myRectBand->setGeometry( theRect.toRect() );
266   myRectBand->setVisible( theRect.isValid() );
267 }
268
269 //================================================================
270 // Function : endDrawRect
271 // Purpose  : 
272 //================================================================
273 void GraphicsView_ViewTransformer::endDrawRect()
274 {
275   if ( myRectBand )
276   {
277     myRectBand->hide();
278     delete myRectBand;
279     myRectBand = 0;
280   }
281 }
282
283 //================================================================
284 // Function : GraphicsView_ViewTransformer
285 // Purpose  : 
286 //================================================================
287 int GraphicsView_ViewTransformer::type() const
288 {
289   return myType;
290 }