]> SALOME platform Git repositories - modules/yacs.git/blobdiff - src/genericgui/SceneHeaderNodeItem.cxx
Salome HOME
Merge from V6_main_20120808 08Aug12
[modules/yacs.git] / src / genericgui / SceneHeaderNodeItem.cxx
index 9de6b2cd1edf29e8098f04662401fe5f3957474f..723b9f08670dadbfd37a27f3d4478411f8f6232e 100644 (file)
@@ -1,21 +1,22 @@
-//  Copyright (C) 2006-2008  CEA/DEN, EDF R&D
+// Copyright (C) 2006-2012  CEA/DEN, EDF R&D
 //
-//  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.
+// 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.
 //
-//  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.
+// 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
+// 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
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #include "SceneHeaderNodeItem.hxx"
 #include "SceneComposedNodeItem.hxx"
 #include "SceneProcItem.hxx"
@@ -26,6 +27,8 @@
 #include "Scene.hxx"
 
 #include "QtGuiContext.hxx"
+#include "GuiEditor.hxx"
+#include "Resource.hxx"
 #include "Menus.hxx"
 #include <QGraphicsSceneHoverEvent>
 #include <QGraphicsSceneMouseEvent>
@@ -40,43 +43,36 @@ using namespace std;
 using namespace YACS::ENGINE;
 using namespace YACS::HMI;
 
-QColor SceneHeaderNodeItem::_editedNodeBrushColor = QColor(255,255,190);
-QColor SceneHeaderNodeItem::_normalNodeBrushColor = QColor(230,235,255);
-QColor SceneHeaderNodeItem::_runNodeBrushColor    = QColor(205,218,255);
-QColor SceneHeaderNodeItem::_validNodeColor       = QColor(128,255,128);
-QColor SceneHeaderNodeItem::_invalidNodeColor     = QColor(255,128,128);
-
 SceneHeaderNodeItem::SceneHeaderNodeItem(QGraphicsScene *scene, SceneItem *parent,
                                          QString label)
   : SceneHeaderItem(scene, parent, label)
 {
+  _width  = 2*Resource::Corner_Margin + 2*Resource::DataPort_Width + Resource::Space_Margin;
+  _height = Resource::Header_Height;
+  _maxPorts = 0;
+
   _header = 0;
   _controlIn = 0;
   _controlOut = 0;
   _label = "H_" + _label;
+  _hasHeader = true;
+
+  _controlIn = new SceneCtrlInPortItem(_scene, this, "in");
+  _controlIn->setTopLeft(QPointF(Resource::Corner_Margin, Resource::Corner_Margin));
 
-  _header = new SceneHeaderItem(_scene,
-                                this,
-                                "header_"+_label);
+  _header = new SceneHeaderItem(_scene, this, "header_"+_label);
   _header->setText(label);
+  _header->setTopLeft(QPointF(Resource::Corner_Margin + Resource::CtrlPort_Width + Resource::Space_Margin, Resource::Corner_Margin));
+
+  _controlOut = new SceneCtrlOutPortItem(_scene, this, "out");
+  _controlOut->setTopLeft(QPointF(Resource::Corner_Margin + 2*Resource::DataPort_Width + Resource::Space_Margin - Resource::CtrlPort_Width, Resource::Corner_Margin));
 
-  QPointF topLeft(_margin, _margin);
-  _header->setTopLeft(topLeft);
-  _hasHeader = true;
-  _controlIn  = new SceneCtrlInPortItem(_scene,
-                                        this,
-                                        "Ctrl_I");
-  autoPosControl(_controlIn);
-  _controlOut = new SceneCtrlOutPortItem(_scene,
-                                         this,
-                                         "Ctrl_O");
-  autoPosControl(_controlOut);
   if (QtGuiContext::getQtCurrent()->isEdition())
-    _brushColor = _normalNodeBrushColor;
+    _brushColor = Resource::normalNodeBrushColor;
   else
-    _brushColor = _runNodeBrushColor;
+    _brushColor = Resource::runNodeBrushColor;
   _execState = YACS::UNDEFINED;
-  _sc = _validNodeColor;
+  _sc = Resource::validNodeColor;
   _stateDef = "";
   _isProc = dynamic_cast<SceneProcItem*>(_parent);
   _isValid = true;
@@ -91,16 +87,48 @@ void SceneHeaderNodeItem::paint(QPainter *painter,
                                 const QStyleOptionGraphicsItem *option,
                                 QWidget *widget)
 {
-//   DEBTRACE("SceneHeaderNodeItem::paint");
+  //DEBTRACE("SceneHeaderNodeItem::paint");
   painter->save();
-  painter->setPen(getPenColor());
-  painter->setBrush(getBrushColor());
-  painter->drawRect(QRectF(0, 0, _width, _height));
-  painter->setBrush(getValidColor(_isValid));
-  painter->drawEllipse(QRectF((_width - SceneCtrlPortItem::getPortHeight())/2,
-                              getHeaderBottom() + _margin,
-                              SceneCtrlPortItem::getPortHeight(),
-                              SceneCtrlPortItem::getPortHeight()));
+
+  int x = Resource::Border_Margin + 1;
+  int y = Resource::Header_Height - Resource::Line_Space;
+  int w = Resource::Corner_Margin + 2*Resource::DataPort_Width + 2*Resource::Space_Margin;
+  if (_parent->getWidth() > w) w = _parent->getWidth() - Resource::Border_Margin;
+  QPen pen(getPenColor());
+  pen.setWidth(Resource::Line_Width);
+  painter->setPen(pen);
+  painter->drawLine(x, y, w, y);
+
+  x = Resource::Corner_Margin + Resource::CtrlPort_Width + Resource::Space_Margin;
+  y = Resource::Corner_Margin;
+  w = w - 2*Resource::CtrlPort_Width - 3*Resource::Space_Margin - Resource::Corner_Margin;
+  int h = Resource::CtrlPort_Height;
+  pen.setWidth(Resource::Thickness);
+  painter->setPen(pen);
+  
+  SceneNodeItem* father = dynamic_cast<SceneNodeItem*>(_parent);
+  bool expanded = (father && father->isExpanded());
+  QColor baseColor = getBrushColor();
+  if (expanded)
+    painter->setBrush(baseColor);
+  else
+    {
+       int h, s, v, a, h2;
+       baseColor.getHsv(&h, &s, &v, &a);
+       DEBTRACE("h="<<h<<" s="<<s<<" v="<<v);
+       h2 = h+60;
+       if (h>359) h2 = h2-359;
+       QLinearGradient gradient;
+       gradient.setCoordinateMode(QGradient::ObjectBoundingMode);
+       gradient.setColorAt(0, baseColor.darker(200));
+       //gradient.setColorAt(1, baseColor.lighter(150));
+       //gradient.setColorAt(0, QColor::fromHsv(h-60, s, v, a));
+       gradient.setColorAt(1, QColor::fromHsv(h2, s, v, a));
+       QBrush brush(gradient);
+       painter->setBrush(brush);
+    }
+  painter->drawRoundedRect(QRect(x, y, w, h), Resource::Radius, Resource::Radius);
+
   painter->restore();
 }
 
@@ -111,53 +139,84 @@ void SceneHeaderNodeItem::setText(QString label)
 
 qreal SceneHeaderNodeItem::getHeaderBottom() const
 {
-  qreal bottom = 0;
-  if (_hasHeader)
-    bottom = childBoundingRect(_header).bottom();
-  return bottom;
+  if (_hasHeader) {
+    return Resource::Header_Height + _maxPorts * (Resource::DataPort_Height + Resource::Space_Margin);
+  } else {
+    return 0;
+  };
 }
 
 void SceneHeaderNodeItem::autoPosControl(AbstractSceneItem *item)
 {
-  SceneCtrlInPortItem* inPortItem = dynamic_cast<SceneCtrlInPortItem*>(item);
-  bool isInPort = inPortItem;
-
-  qreal xLeft = _margin;
-  if (!isInPort) xLeft += getInternWidth() - SceneCtrlPortItem::getPortWidth();
+}
 
-  qreal yTop  = getHeaderBottom() + _margin;
+void SceneHeaderNodeItem::autoPosNewPort(AbstractSceneItem *item)
+{
+  DEBTRACE("SceneHeaderNodeItem::autoPosNewPort");
+  SceneInPortItem* inPortItem = dynamic_cast<SceneInPortItem*>(item);
 
+  int nbPorts;
+  qreal xLeft;
+  if (inPortItem) {
+    xLeft = Resource::Corner_Margin;
+    nbPorts = _inPorts.size();
+    _inPorts.push_back(inPortItem);
+  } else {
+    if (_parent->getWidth() > (2*Resource::Corner_Margin + 2*Resource::DataPort_Width + Resource::Space_Margin)) {
+      xLeft = _parent->getWidth() - Resource::Corner_Margin - Resource::DataPort_Width;
+    } else {
+      xLeft = Resource::Corner_Margin + Resource::DataPort_Width + Resource::Space_Margin;
+    };
+    nbPorts = _outPorts.size();
+    _outPorts.push_back(dynamic_cast<SceneOutPortItem*>(item));
+  };
+  qreal yTop   = Resource::Header_Height;
+  qreal deltaY = Resource::DataPort_Height + Resource::Space_Margin;
+  yTop += nbPorts * deltaY;
+  if (nbPorts >=_maxPorts) {
+    _maxPorts = nbPorts+1;
+  };
   //DEBTRACE("left, top " << xLeft  << " " << yTop);
   QPointF topLeft(xLeft, yTop);
   item->setTopLeft(topLeft);
-  //adaptComposedNode(getHeaderBottom() + _margin);
+  adaptComposedNode(dynamic_cast<SceneItem*>(item), deltaY);
 }
 
-void SceneHeaderNodeItem::autoPosNewPort(AbstractSceneItem *item)
+void SceneHeaderNodeItem::reorganizePorts(shownState ss)
 {
-  SceneInPortItem* inPortItem = dynamic_cast<SceneInPortItem*>(item);
-  bool isInPort = (inPortItem != 0);
+  DEBTRACE("SceneHeaderNodeItem::reorganizePorts() " << ss << " " << _label.toStdString());
 
+  qreal yTop;
+  qreal href = Resource::Header_Height;
+  bool isShown = (ss != shrinkHidden);
+  if (!isShown) href = Resource::Corner_Margin;
+
+std::list<SceneInPortItem*>::iterator iti = _inPorts.begin();
   int nbPorts = 0;
-  qreal xLeft = _margin;
-  if (!isInPort)
+  for (; iti != _inPorts.end(); ++iti)
     {
-      xLeft += getInternWidth() - ScenePortItem::getPortWidth() -1;
-      nbPorts = _outPorts.size();
-      _outPorts.push_back(dynamic_cast<SceneOutPortItem*>(item));
+      yTop = href + nbPorts * (Resource::DataPort_Height + Resource::Space_Margin);
+      QPointF topLeft(Resource::Corner_Margin, yTop);
+      (*iti)->setTopLeft(topLeft);
+      if (isShown) nbPorts++; // otherwise (shrink from ancestor) put all ports at the same position
     }
-  else
+
+  std::list<SceneOutPortItem*>::iterator ito = _outPorts.begin();
+  nbPorts = 0;
+  qreal xLeft;
+  if (ss == expandShown) {
+    xLeft = _parent->getWidth() - Resource::Corner_Margin - Resource::DataPort_Width;
+  } else {
+    xLeft = Resource::Corner_Margin + Resource::DataPort_Width + Resource::Space_Margin;
+  };
+  for (; ito != _outPorts.end(); ++ito)
     {
-      nbPorts = _inPorts.size();
-      _inPorts.push_back(inPortItem);
+      yTop = href + nbPorts * (Resource::DataPort_Height + Resource::Space_Margin);
+      QPointF topLeft(xLeft, yTop);
+      (*ito)->setTopLeft(topLeft);
+      if (isShown) nbPorts++; // otherwise (shrink from ancestor) put all ports at the same position
     }
-  qreal yTop  = getHeaderBottom() +ScenePortItem::getPortHeight() + 2*_margin;
-  qreal deltaY = ScenePortItem::getPortHeight() + _margin;
-  yTop += nbPorts * deltaY;
-  //DEBTRACE("left, top " << xLeft  << " " << yTop);
-  QPointF topLeft(xLeft, yTop);
-  item->setTopLeft(topLeft);
-  adaptComposedNode(deltaY);
+  //updateLinks();
 }
 
 void SceneHeaderNodeItem::popupMenu(QWidget *caller, const QPoint &globalPos)
@@ -169,43 +228,48 @@ void SceneHeaderNodeItem::popupMenu(QWidget *caller, const QPoint &globalPos)
 
 void SceneHeaderNodeItem::adjustGeometry()
 {
-  _width = _parent->getInternWidth() -1;
+  DEBTRACE("SceneHeaderNodeItem::adjustGeometry() " << _label.toStdString());
+  prepareGeometryChange();
+  _width = _parent->getWidth();
   if (_header) _header->adjustGeometry();
   adjustPosPorts();
+  update();
 }
 
 void SceneHeaderNodeItem::adjustPosPorts()
 {
-  if (_controlOut) autoPosControl(_controlOut);
+  SceneNodeItem* father = dynamic_cast<SceneNodeItem*>(_parent);
+  YASSERT(father);
+  shownState ss = father->getShownState();
+  if (_controlOut)
+    {
+      int x = Resource::Corner_Margin + 2*Resource::DataPort_Width + Resource::Space_Margin;
+      if ((ss == expandShown)  && (_parent->getWidth() > (x + Resource::Corner_Margin)))
+        x = _parent->getWidth() - Resource::Corner_Margin;
+    _controlOut->setTopLeft(QPointF(x - Resource::CtrlPort_Width, Resource::Corner_Margin));
+  };
+  reorganizePorts(ss);
 }
 
 QRectF SceneHeaderNodeItem::getMinimalBoundingRect() const
 {
-  qreal width = 3*_margin;
-  if (_inPorts.size())
-    width += ScenePortItem::getPortWidth();
-  else
-    width += SceneCtrlPortItem::getPortWidth()
-      + SceneCtrlPortItem::getPortHeight() + 2*_margin;
-  if (_outPorts.size())
-    width += ScenePortItem::getPortWidth();
-  else
-    width += SceneCtrlPortItem::getPortWidth();
-  qreal height = getHeaderBottom() + ScenePortItem::getPortHeight() + 2*_margin;
-  int nbPorts = _inPorts.size();
+  qreal width  = 2*Resource::Corner_Margin + 2*Resource::DataPort_Width + Resource::Space_Margin;
+  qreal height = Resource::Header_Height + Resource::Border_Margin;
+  int nbPorts  = _inPorts.size();
   if (_outPorts.size() > nbPorts) nbPorts = _outPorts.size();
-  if (nbPorts) height += nbPorts*(ScenePortItem::getPortHeight() + _margin);
+  if (nbPorts) height += nbPorts*(Resource::DataPort_Height + Resource::Space_Margin);
   //DEBTRACE(nbPorts << " " << width << " " << height);
   return QRectF(x(), y(), width, height);
 }
 
-void SceneHeaderNodeItem::adaptComposedNode(qreal deltaY)
+void SceneHeaderNodeItem::adaptComposedNode(SceneItem* port, qreal deltaY)
 {
+  DEBTRACE("SceneHeaderNodeItem::adaptComposedNode " << deltaY);
   QPointF oldPos(x(),y() - deltaY);
   if (_parent)
     {
       if (SceneComposedNodeItem *bloc = dynamic_cast<SceneComposedNodeItem*>(_parent))
-        bloc->collisionResolv(this, oldPos);
+        bloc->collisionResolv(port, oldPos);
       //_parent->checkGeometryChange();
     }
 }
@@ -214,13 +278,13 @@ void SceneHeaderNodeItem::setEdited(bool isEdited)
 {
   DEBTRACE("SceneHeaderNodeItem::setEdited " << isEdited);
   if (isEdited)
-    _brushColor = _editedNodeBrushColor;
+    _brushColor = Resource::editedNodeBrushColor;
   else
     {
       if (QtGuiContext::getQtCurrent()->isEdition())
-        _brushColor = _normalNodeBrushColor;
+        _brushColor = Resource::normalNodeBrushColor;
       else
-        _brushColor = _runNodeBrushColor;
+        _brushColor = Resource::runNodeBrushColor;
     }
   if (isEdited != _isEdited)
     _parent->update();
@@ -246,37 +310,38 @@ void SceneHeaderNodeItem::setExecState(int execState)
   if (_isProc)
     switch (_execState)
       {
-      case YACS::NOTYETINITIALIZED: _sc.setHsv( 45, 50, 255); _stateDef = "Not Yet Initialized"; break;
-      case YACS::INITIALISED:       _sc.setHsv( 90, 50, 255); _stateDef = "Initialized";         break;
-      case YACS::RUNNING:           _sc.setHsv(135, 50, 255); _stateDef = "Running";             break;
-      case YACS::WAITINGTASKS:      _sc.setHsv(180, 50, 255); _stateDef = "Waiting Tasks";       break;
-      case YACS::PAUSED:            _sc.setHsv(225, 50, 255); _stateDef = "Paused";              break;
-      case YACS::FINISHED:          _sc.setHsv(270, 50, 255); _stateDef = "Finished";            break;
-      case YACS::STOPPED:           _sc.setHsv(315, 50, 255); _stateDef = "Stopped";             break;
-      default:                      _sc.setHsv(360, 50, 255); _stateDef = "Unknown Status";
+      case YACS::NOTYETINITIALIZED: _sc = Resource::NOTYETINITIALIZED; _stateDef = "Not Yet Initialized"; break;
+      case YACS::INITIALISED:       _sc = Resource::INITIALISED      ; _stateDef = "Initialized"        ; break;
+      case YACS::RUNNING:           _sc = Resource::RUNNING          ; _stateDef = "Running"            ; break;
+      case YACS::WAITINGTASKS:      _sc = Resource::WAITINGTASKS     ; _stateDef = "Waiting Tasks"      ; break;
+      case YACS::PAUSED:            _sc = Resource::PAUSED           ; _stateDef = "Paused"             ; break;
+      case YACS::FINISHED:          _sc = Resource::FINISHED         ; _stateDef = "Finished"           ; break;
+      case YACS::STOPPED:           _sc = Resource::STOPPED          ; _stateDef = "Stopped"            ; break;
+      default:                      _sc = Resource::UNKNOWN          ; _stateDef = "Unknown Status"     ;
       }
   else
     switch (_execState)
       {
-      case YACS::UNDEFINED:    _sc=Qt::lightGray;       _stateDef = "UNDEFINED";     break;
-      case YACS::INVALID:      _sc=Qt::red;             _stateDef = "INVALID";       break;
-      case YACS::READY:        _sc=Qt::gray;            _stateDef = "READY";         break;
-      case YACS::TOLOAD:       _sc=Qt::darkYellow;      _stateDef = "TOLOAD";        break;
-      case YACS::LOADED:       _sc=Qt::darkMagenta;     _stateDef = "LOADED";        break;
-      case YACS::TOACTIVATE:   _sc=Qt::darkCyan;        _stateDef = "TOACTIVATE";    break;
-      case YACS::ACTIVATED:    _sc=Qt::darkBlue;        _stateDef = "ACTIVATED";     break;
-      case YACS::DESACTIVATED: _sc=Qt::gray;            _stateDef = "DESACTIVATED";  break;
-      case YACS::DONE:         _sc=Qt::darkGreen;       _stateDef = "DONE";          break;
-      case YACS::SUSPENDED:    _sc=Qt::gray;            _stateDef = "SUSPENDED";     break;
-      case YACS::LOADFAILED:   _sc.setHsv(320,255,255); _stateDef = "LOADFAILED";    break;
-      case YACS::EXECFAILED:   _sc.setHsv( 20,255,255); _stateDef = "EXECFAILED";    break;
-      case YACS::PAUSE:        _sc.setHsv(180,255,255); _stateDef = "PAUSE";         break;
-      case YACS::INTERNALERR:  _sc.setHsv(340,255,255); _stateDef = "INTERNALERR";   break;
-      case YACS::DISABLED:     _sc.setHsv( 40,255,255); _stateDef = "DISABLED";      break;
-      case YACS::FAILED:       _sc.setHsv( 20,255,255); _stateDef = "FAILED";        break;
-      case YACS::ERROR:        _sc.setHsv(  0,255,255); _stateDef = "ERROR";         break;
-      default:                 _sc=Qt::lightGray;       _stateDef = "---";
+      case YACS::UNDEFINED:         _sc = Resource::UNDEFINED        ; _stateDef = "UNDEFINED"          ; break;
+      case YACS::INVALID:           _sc = Resource::INVALID          ; _stateDef = "INVALID"            ; break;
+      case YACS::READY:             _sc = Resource::READY            ; _stateDef = "READY"              ; break;
+      case YACS::TOLOAD:            _sc = Resource::TOLOAD           ; _stateDef = "TOLOAD"             ; break;
+      case YACS::LOADED:            _sc = Resource::LOADED           ; _stateDef = "LOADED"             ; break;
+      case YACS::TOACTIVATE:        _sc = Resource::TOACTIVATE       ; _stateDef = "TOACTIVATE"         ; break;
+      case YACS::ACTIVATED:         _sc = Resource::ACTIVATED        ; _stateDef = "ACTIVATED"          ; break;
+      case YACS::DESACTIVATED:      _sc = Resource::DESACTIVATED     ; _stateDef = "DESACTIVATED"       ; break;
+      case YACS::DONE:              _sc = Resource::DONE             ; _stateDef = "DONE"               ; break;
+      case YACS::SUSPENDED:         _sc = Resource::SUSPENDED        ; _stateDef = "SUSPENDED"          ; break;
+      case YACS::LOADFAILED:        _sc = Resource::LOADFAILED       ; _stateDef = "LOADFAILED"         ; break;
+      case YACS::EXECFAILED:        _sc = Resource::EXECFAILED       ; _stateDef = "EXECFAILED"         ; break;
+      case YACS::PAUSE:             _sc = Resource::PAUSE            ; _stateDef = "PAUSE"              ; break;
+      case YACS::INTERNALERR:       _sc = Resource::INTERNALERR      ; _stateDef = "INTERNALERR"        ; break;
+      case YACS::DISABLED:          _sc = Resource::DISABLED         ; _stateDef = "DISABLED"           ; break;
+      case YACS::FAILED:            _sc = Resource::FAILED           ; _stateDef = "FAILED"             ; break;
+      case YACS::ERROR:             _sc = Resource::ERROR            ; _stateDef = "ERROR"              ; break;
+      default:                      _sc = Resource::DEFAULT          ; _stateDef = "---"                ;
       }
+  DEBTRACE("  - stateDef = " << _stateDef.toStdString());
   if(oldsc != _sc)
     _parent->update();
 }
@@ -298,10 +363,15 @@ void SceneHeaderNodeItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
   event->ignore();
 }
 
-QColor SceneHeaderNodeItem::getValidColor(bool isValid)
+void SceneHeaderNodeItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
+{
+  event->ignore();
+}
+
+QColor SceneHeaderNodeItem::getValidColor()
 {
-  if (isValid)
+  if (_isValid)
     return _sc;
   else
-    return _invalidNodeColor;
+    return Resource::invalidNodeColor;
 }