]> SALOME platform Git repositories - modules/yacs.git/blob - src/genericgui/SceneItem.cxx
Salome HOME
Fix make check with Python 2.7
[modules/yacs.git] / src / genericgui / SceneItem.cxx
1 // Copyright (C) 2006-2012  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.
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 "SceneItem.hxx"
21 #include "Scene.hxx"
22 #include "SceneNodeItem.hxx"
23 #include "SceneHeaderNodeItem.hxx"
24 #include "SceneProcItem.hxx"
25 #include "SceneElementaryNodeItem.hxx"
26 #include "SceneComposedNodeItem.hxx"
27 #include "GuiEditor.hxx"
28
29 #include "QtGuiContext.hxx"
30 #include "Menus.hxx"
31 #include <QGraphicsSceneHoverEvent>
32 #include <QPointF>
33
34 #include <cassert>
35 #include <cmath>
36
37 #include "Resource.hxx"
38
39 //#define _DEVDEBUG_
40 #include "YacsTrace.hxx"
41
42 using namespace std;
43 using namespace YACS::ENGINE;
44 using namespace YACS::HMI;
45
46 // ============================================================================
47
48 RootSceneItem::RootSceneItem(YACS::HMI::Subject *context)
49 {
50   _context=context;
51   _context->attach(this);
52 }
53
54 RootSceneItem::~RootSceneItem()
55 {
56 }
57
58 void RootSceneItem::update(GuiEvent event, int type, Subject* son)
59 {
60   DEBTRACE("RootSceneItem::update "<<eventName(event)<<" "<<type<<" "<<son);
61   GuiEditor *guiEditor = 0;
62   switch (event)
63     {
64     case YACS::HMI::NEWROOT:
65       setNewRoot(son);
66       break;
67     case YACS::HMI::ENDLOAD:
68       guiEditor = QtGuiContext::getQtCurrent()->getGMain()->_guiEditor;
69       GuiContext::getCurrent()->getSubjectProc()->select(true);
70       //guiEditor->rebuildLinks();
71       break;
72     }
73 }
74
75 void RootSceneItem::setNewRoot(YACS::HMI::Subject *root)
76 {
77   DEBTRACE("RootSceneItem::setNewRoot");
78   _root = root;
79   QString name = _root->getName().c_str();
80   QGraphicsScene* scene = QtGuiContext::getQtCurrent()->getScene();
81   SceneProcItem *procItem = new SceneProcItem(scene, 0, name, root);
82   scene->addItem(procItem);
83   procItem->addHeader();
84 }
85
86 // ============================================================================
87
88 AbstractSceneItem::AbstractSceneItem(QGraphicsScene *scene, SceneItem *parent,
89                                      QString label)
90 {
91   _scene = dynamic_cast<Scene*>(scene);
92   _parent = parent;
93   _label = label;
94   _level = 1;
95   _width = 6;
96   _height = 4;
97   _incHeight = 0; // used in elementaryNode when ports added
98   _penColor     = Resource::Scene_pen;
99   _hiPenColor   = Resource::Scene_hiPen;
100   _brushColor   = Resource::Scene_brush;
101   _hiBrushColor = Resource::Scene_hiBrush;
102   _hasHeader = false;
103   _optimize = true; // to be set individually or globally by user (shrink items)
104   _dragable = false;
105   _dragButton = Qt::LeftButton;
106   if (_parent) 
107     _level = _parent->getLevel() +1;
108   DEBTRACE("AbstractSceneItem::AbstractSceneItem "<<label.toStdString()
109            <<" "<<this<<" "<<_parent<<" "<< _level); 
110 }
111
112 AbstractSceneItem::~AbstractSceneItem()
113 {
114 }
115
116 int AbstractSceneItem::getLevel()
117 {
118   return  _level;
119 }
120
121 void AbstractSceneItem::setLevel()
122 {
123   if (_parent) 
124     _level = _parent->getLevel() +1;
125   if (SceneItem *item = dynamic_cast<SceneItem*>(this))
126     foreach (QGraphicsItem *child, item->childItems())
127       if (AbstractSceneItem *sci = dynamic_cast<AbstractSceneItem*>(child))
128         sci->setLevel();
129 }
130
131 void AbstractSceneItem::reorganize()
132 {
133 }
134
135 QString AbstractSceneItem::getLabel()
136 {
137   return _label;
138 }
139
140 void AbstractSceneItem::addHeader()
141 {
142 }
143
144 qreal AbstractSceneItem::getHeaderBottom()
145 {
146   return 0;
147 }
148 qreal AbstractSceneItem::getWidth()
149 {
150   return _width;
151 }
152
153 qreal AbstractSceneItem::getHeight()
154 {
155   return _height;
156 }
157
158 //! AbstractSceneItem cannot be resized (only ComposedNodeItem can)
159 void AbstractSceneItem::setWidth(qreal width)
160 {
161 }
162
163 //! AbstractSceneItem cannot be resized (only ComposedNodeItem can)
164 void AbstractSceneItem::setHeight(qreal height)
165 {
166 }
167
168 QRectF AbstractSceneItem::childBoundingRect(AbstractSceneItem *child) const
169 {
170   QGraphicsItem *item = dynamic_cast<QGraphicsItem*>(child);
171   YASSERT(item);
172   return (item->mapToParent(item->boundingRect())).boundingRect();
173 }
174
175 void AbstractSceneItem::activateSelection(bool selected)
176 {
177   if (_parent) _parent->activateSelection(selected);
178 }
179
180 void AbstractSceneItem::setGeometryOptimization(bool optimize)
181 {
182   _optimize = optimize;
183 }
184 // ============================================================================
185
186 SceneItem::SceneItem(QGraphicsScene *scene, SceneItem *parent,
187                      QString label)
188   : QGraphicsItem(parent), AbstractSceneItem(scene, parent, label)
189 {
190   _hover = false;
191   _ancestorShrinked = false;
192   setToolTip(_label);
193   DEBTRACE("SceneItem::SceneItem "<<label.toStdString()<<" "<<this<<" "<<_parent<<" "<< _level); 
194   setFlag(QGraphicsItem::ItemIsSelectable);
195   setAcceptsHoverEvents(true);
196 }
197
198 SceneItem::~SceneItem()
199 {
200 }
201
202 void SceneItem::setParent(SceneItem* parent)
203 {
204   setParentItem(parent);
205   _parent = parent;
206   if (_parent) 
207     _level = _parent->getLevel() +1;
208 }
209
210 QRectF SceneItem::boundingRect() const
211 {
212 //   DEBTRACE("SceneItem::boundingRect " <<_label.toStdString()
213 //            <<" "<<_width<<" "<< _height);
214   qreal penWidth = 1;
215   return QRectF(- penWidth/2, - penWidth/2,
216                 _width + penWidth/2, _height + penWidth/2);
217 }
218
219 QRectF SceneItem::childrenBoundingRect() const
220 {
221   return QGraphicsItem::childrenBoundingRect();
222 }
223
224 void SceneItem::paint(QPainter *painter,
225                       const QStyleOptionGraphicsItem *option,
226                       QWidget *widget)
227 {
228   //DEBTRACE("SceneItem::paint");
229 //   painter->save();
230 //   painter->setPen(getPenColor());
231 //   painter->setBrush(getBrushColor());
232 //   painter->drawRoundRect(QRectF(0, 0, _width, _height), 33*_height/_width, 33);
233 //   painter->restore();
234 }
235
236 void SceneItem::setTopLeft(QPointF topLeft)
237 {
238   setPos(int(topLeft.x()), int(topLeft.y()));
239   if (_parent)
240     _parent->checkGeometryChange();
241 }
242
243 void SceneItem::checkGeometryChange()
244 {
245   DEBTRACE("SceneItem::checkGeometryChange: enter : " << _label.toStdString() << " width= " << _width <<  " height= " << _height);
246   qreal newWidth;
247   qreal newHeight;
248   bool resize = false;
249   SceneElementaryNodeItem* aElemNode = dynamic_cast<SceneElementaryNodeItem*>(this);
250   if (QtGuiContext::getQtCurrent()->isLoadingPresentation())
251     {
252       newWidth  = _width;
253       newHeight = _height;
254       resize    = true;
255     }
256   else
257     {
258       if (aElemNode)
259         {
260           newWidth  = _width;
261           newHeight = _height;
262           resize    = true;
263           DEBTRACE("elementaryNode resize true");
264         }
265       else
266         {
267           QRectF childrenBox = childrenBoundingRect();
268           newWidth  = childrenBox.width();
269           newHeight = childrenBox.height();
270           DEBTRACE("composedNode newWidth= " << newWidth << " newHeight=" << newHeight);
271         }
272     }
273   bool wider = (newWidth > _width + 0.5);
274   qreal deltaW = 0;
275   bool higher = (newHeight > _height + 0.5);
276   qreal deltaH = 0;
277   bool changeWidth = (fabs(newWidth - _width) > 0.5);
278
279   if (wider || (_optimize && (newWidth < _width)))
280     {
281       deltaW = newWidth - _width;
282       resize = true;
283     }
284   if (higher || (_optimize && (newHeight < _height)))
285     {
286       deltaH = newHeight - _height;
287       resize = true;
288     }
289   if (_incHeight >0) //when a port has been added in an elementaryNode, force the collision resolv
290     {
291       higher = true;
292       deltaH = _incHeight;
293       resize = true;      
294     }
295   _incHeight = 0;
296   DEBTRACE("SceneItem::checkGeometryChange "<<_label.toStdString() <<
297            " " << wider << " " << higher << " " << changeWidth <<  " " << resize);
298
299   if (resize)
300     { 
301       prepareGeometryChange();
302       _width = newWidth;
303       _height = newHeight;
304     }
305   SceneNodeItem *aNode = dynamic_cast<SceneNodeItem*>(this);
306   if (aNode)
307     {
308       if (changeWidth) aNode->adjustHeader();
309       if (wider || higher)
310         {
311           QPointF oldPos(pos().x() - deltaW, pos().y() - deltaH);
312           if (SceneComposedNodeItem *bloc = dynamic_cast<SceneComposedNodeItem*>(_parent))
313             bloc->collisionResolv(aNode, oldPos);
314         }  
315       if (changeWidth) aNode->updateLinks();
316     }
317   if (resize)
318     { 
319       update();
320       if (_parent)
321         _parent->checkGeometryChange();
322     }
323   if(resize && aNode)
324       aNode->setExpandedWH();
325 }
326
327 /*! generic behaviour for headers:
328  *  obtain the tooltip from parent.
329  *  Method to be redefined in derived classes.
330  */
331 QString SceneItem::getToolTip()
332 {
333   QString tooltip = _label;
334   SceneItem *parent = getParent();
335   if (parent)
336     tooltip = parent->getToolTip();
337   return tooltip;
338 }
339
340 // /*!
341 //  * When Zooming, filter all mouse events to items: 
342 //  * do not work, scene do not receive...
343 //  */
344 // bool SceneItem::sceneEvent(QEvent *event)
345 // {
346 //   if (_scene->isZooming())
347 //     return false;
348 //   else
349 //     return QGraphicsItem::sceneEvent(event);
350 // }
351
352 void SceneItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
353 {
354   DEBTRACE("SceneItem::mousePressEvent " << _label.toStdString()
355            << " " << acceptedMouseButtons () << " " << _scene->isZooming());
356   if (!_scene->isZooming()) activateSelection(true);
357 }
358
359 QColor SceneItem::getPenColor()
360 {
361   if (isSelected())
362     return _hiPenColor;
363   else 
364     return _penColor;
365 }
366
367 QColor SceneItem::hoverColor(QColor origColor)
368 {
369   qreal r, g, b, a;
370   origColor.getRgbF(&r, &g, &b, &a);
371   r = 0.96*r;
372   g = 0.96*g;
373   b = 0.96*b;
374   return QColor::fromRgbF(r, g, b, a);
375
376    // qreal h, s, v, a;
377    // origColor.getHsvF(&h, &s, &v, &a);
378    // s = 1.05*s;
379    // if (s>254.0) s=255.0;
380    // return QColor::fromHsvF(h, s, v, a);
381 }
382
383 void SceneItem::hoverEnterEvent(QGraphicsSceneHoverEvent * event)
384 {
385   _hover = true;
386   update();
387 }
388
389 void SceneItem::hoverMoveEvent(QGraphicsSceneHoverEvent * event)
390 {
391 }
392
393 void SceneItem::hoverLeaveEvent(QGraphicsSceneHoverEvent * event)
394 {
395   _hover = false;
396   update();
397 }
398
399 QColor SceneItem::getBrushColor()
400 {
401   QColor color;
402   if (isSelected())
403     color = _hiBrushColor;
404   else 
405     color = _brushColor;
406   if (_hover)
407     color = hoverColor(color);
408   return color;
409 }
410
411 void SceneItem::popupMenu(QWidget *caller, const QPoint &globalPos)
412 {
413   MenusBase m;
414   m.popupMenu(caller, globalPos);
415 }
416
417 void SceneItem::setEventPos(QPointF point)
418 {
419   QPointF localPoint = mapFromScene(point);
420   if (localPoint.y() <= getHeaderBottom())
421     localPoint.setY(getHeaderBottom()+1);
422   _eventPos = localPoint;
423 }
424
425 void SceneItem::updateChildItems()
426 {
427 }
428
429 void SceneItem::shrinkExpandLink(bool se)
430 {
431 }
432
433
434 void SceneItem::shrinkExpandRecursive(bool isExpanding, bool fromHere)
435 {
436 }
437
438 void SceneItem::updateLinks()
439 {
440 }