Salome HOME
Copyright update: 2016
[modules/yacs.git] / src / genericgui / GraphicsView.cxx
1 // Copyright (C) 2006-2016  CEA/DEN, EDF R&D
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.hxx"
21 #include "SchemaModel.hxx"
22 #include "SceneItem.hxx"
23 #include "SceneTextItem.hxx"
24 #include "Scene.hxx"
25 #include "QtGuiContext.hxx"
26 #include "guiObservers.hxx"
27
28 #include <cmath>
29 #include <QMenu>
30 #include <QGraphicsView>
31 #include <QWheelEvent>
32
33 #include <cmath>
34
35 //#define _DEVDEBUG_
36 #include "YacsTrace.hxx"
37
38 using namespace std;
39 using namespace YACS::HMI;
40
41 GraphicsView::GraphicsView(QWidget *parent)
42   : WrapGraphicsView(parent)
43 {
44   _zooming = false;
45   _fittingArea = false;
46   _panning = false;
47   _rect = 0;
48   setTransformationAnchor(QGraphicsView::AnchorViewCenter);
49 }
50
51 GraphicsView::~GraphicsView()
52 {
53 }
54
55 void GraphicsView::onViewFitAll()
56 {
57   DEBTRACE("GraphicsView::onViewFitAll");
58   SubjectProc *sProc = QtGuiContext::getQtCurrent()->getSubjectProc();
59   SceneItem *item = QtGuiContext::getQtCurrent()->_mapOfSceneItem[sProc];
60   //SceneProcItem *procItem = dynamic_cast<SceneProcItem*>(item);
61   fitInView(item->boundingRect(),  Qt::KeepAspectRatio);
62 }
63
64 void GraphicsView::onViewFitArea()
65 {
66   DEBTRACE("GraphicsView::onViewFitArea");
67   Scene* myScene = dynamic_cast<Scene*>(scene());
68   myScene->setZoom(true);
69   _fittingArea = true;
70 }
71
72 void GraphicsView::onViewZoom()
73 {
74   DEBTRACE("GraphicsView::onViewZoom");
75   Scene* myScene = dynamic_cast<Scene*>(scene());
76   myScene->setZoom(true);
77   _zooming =true;
78   _scale = 1;
79 }
80
81 void GraphicsView::onViewPan()
82 {
83   DEBTRACE("GraphicsView::onViewPan");
84   Scene* myScene = dynamic_cast<Scene*>(scene());
85   myScene->setZoom(true);
86   _panning = true;
87   //setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
88   setTransformationAnchor(QGraphicsView::NoAnchor);
89 }
90
91 void GraphicsView::onViewGlobalPan()
92 {
93   DEBTRACE("GraphicsView::onViewGlobalPan");
94 }
95
96 void GraphicsView::onViewReset()
97 {
98   DEBTRACE("GraphicsView::onViewReset");
99   resetTransform();
100 }
101
102
103 void GraphicsView::contextMenuEvent(QContextMenuEvent *event)
104 {
105   QGraphicsItem *qgitem = itemAt(event->pos());
106   if (qgitem)
107     {
108       SceneItem *item = dynamic_cast<SceneItem*>(qgitem);
109       if (item)
110         {
111           QPointF point = mapToScene(event->pos());
112           item->setEventPos(point);
113           item->popupMenu(this, event->globalPos());
114         }
115       else
116         {
117           SceneTextItem *item = dynamic_cast<SceneTextItem*>(qgitem);
118           if (item)
119             {
120               QPointF point = mapToScene(event->pos());
121               item->setEventPos(point);
122               item->popupMenu(this, event->globalPos());
123             }
124         }
125     }
126 }
127
128 void GraphicsView::mouseMoveEvent(QMouseEvent *e)
129 {
130   WrapGraphicsView::mouseMoveEvent(e);
131   if (e->buttons()==Qt::LeftButton)
132     {
133       QPoint current = e->pos();
134       if (_zooming)
135         {
136           qreal currentX = e->globalX();
137           qreal currentY = e->globalY();
138           qreal delta = sqrt((currentX - _prevX)*(currentX - _prevX) + (currentY - _prevY)*(currentY - _prevY));
139           if ((currentX*currentX + currentY*currentY) < (_prevX*_prevX + _prevY*_prevY))
140             delta = -delta;
141           _prevX = currentX;
142           _prevY = currentY;
143           //       if (delta < -30) delta = -30;
144           //       if (delta >  30) delta =  30;
145           double deltax = delta/900.;
146           double zoom = exp(deltax);
147           _scale = _scale*zoom;
148           scale(zoom,zoom);
149           //DEBTRACE("move zooming " << delta << " " << deltax << " " << zoom);
150         }
151       else if (_panning)
152         {
153           translate(current.x() - _prevPos.x(), current.y() - _prevPos.y());
154           //DEBTRACE(current.x()<<"-"<<_prevPos.x()<<" "<<current.y()<<"-"<<_prevPos.y());
155           _prevPos = current;
156         }
157       else if (_fittingArea)
158         {
159           if (!_rect)
160             {
161               _rect = scene()->addRect(QGraphicsView::mapToScene(QRect(_prevPos, current)).boundingRect());
162               _rect->setZValue(100000);
163               _rect->setParentItem(0);
164             }
165           else
166             {
167               _rect->setRect(QGraphicsView::mapToScene(QRect(_prevPos, current)).boundingRect());
168               _rect->show();
169             }
170         }
171     }
172 }
173
174 void GraphicsView::mousePressEvent(QMouseEvent *e)
175 {
176   DEBTRACE("GraphicsView::mousePressEvent");
177   if (QtGuiContext::getQtCurrent()->getView() != this)
178     {
179       DEBTRACE("Switch context before selection");
180       QtGuiContext::getQtCurrent()->getGMain()->switchContext(this->parentWidget());
181     }
182   WrapGraphicsView::mousePressEvent(e);
183   if (_zooming)
184     {
185       _prevX = e->globalX();
186       _prevY = e->globalY();
187     }
188   else if (_fittingArea)
189     {
190       _prevPos = e->pos();
191     }
192     else if (_panning)
193       {
194         _prevPos = e->pos();
195         //setDragMode(QGraphicsView::ScrollHandDrag);
196       }
197 }
198
199 void GraphicsView::mouseReleaseEvent(QMouseEvent *e)
200 {
201   _zooming = false;
202   _panning = false;
203   setDragMode(QGraphicsView::NoDrag);
204   setTransformationAnchor(QGraphicsView::AnchorViewCenter);
205   if( _fittingArea)
206     {
207       _fittingArea = false;
208       QPoint current = e->pos();
209       fitInView(QGraphicsView::mapToScene(QRect(_prevPos, current)).boundingRect(), Qt::KeepAspectRatio);
210       if (_rect)
211         _rect->hide();
212     }
213
214   QTransform q = transform();
215   DEBTRACE(q.m11()<<" "<<q.m12()<<" "<<q.m21()<<" "<<q.m22()<<" "<<q.dx()<<" "<<q.dy());
216   WrapGraphicsView::mouseReleaseEvent(e);
217 }
218
219 void GraphicsView::wheelEvent(QWheelEvent *e)
220 {
221   DEBTRACE("GraphicsView::wheelEvent " << e->delta());
222   double zoom = exp(0.1*e->delta()/120);
223   _scale = _scale*zoom;
224   setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
225   scale(zoom,zoom);
226 }
227
228 void GraphicsView::onZoomToBloc()
229 {
230   Subject *sub = QtGuiContext::getQtCurrent()->getSelectedSubject();
231   SubjectNode *snode = dynamic_cast<SubjectNode*>(sub);
232   if (!snode)
233     return;
234   SubjectComposedNode *scnode = dynamic_cast<SubjectComposedNode*>(sub);
235   if (!scnode)
236     scnode = dynamic_cast<SubjectComposedNode*>(snode->getParent());
237   YASSERT(scnode);
238   SceneItem *item = QtGuiContext::getQtCurrent()->_mapOfSceneItem[scnode];
239   YASSERT(item);
240   QRectF rect = item->mapToScene(item->boundingRect().toRect()).boundingRect();
241   fitInView(rect.toRect(), Qt::KeepAspectRatio);
242 }
243
244 void GraphicsView::onCenterOnNode()
245 {
246   Subject *sub =QtGuiContext::getQtCurrent()->getSelectedSubject();
247   SubjectNode *snode = dynamic_cast<SubjectNode*>(sub);
248   if (!snode)
249     return;
250   SceneItem *item = QtGuiContext::getQtCurrent()->_mapOfSceneItem[sub];
251   centerOn(item);
252 }