X-Git-Url: https://bilbo.iut-bm.univ-fcomte.fr/and/gitweb/blast.git/blobdiff_plain/6e2b3026c6a496e81642c373796bd39dad33d2a6..a13795fc34cd1e74f94695d35253c3d00abec9bc:/BoxItem.cpp?ds=sidebyside

diff --git a/BoxItem.cpp b/BoxItem.cpp
index 85a1c9f..ae15002 100644
--- a/BoxItem.cpp
+++ b/BoxItem.cpp
@@ -17,12 +17,15 @@
 
 BoxItem::BoxItem(AbstractBlock *_refBlock,
                      Dispatcher *_dispatcher,
-                     Parameters *_params, GroupItem *parent) throw(Exception) : AbstractBoxItem( _refBlock, _dispatcher, _params, parent) {
+                     Parameters *_params, GroupItem *parent, int _lock, SpanType _span, Position _position) throw(Exception) : AbstractBoxItem( _refBlock, _dispatcher, _params, _lock, parent) {
 
   /*  NOTE :
      _refBlock : mandatory a FunctionalBlock or a GroupBlock
   */
-  if (_refBlock->isReferenceBlock()) throw(Exception(BLOCK_INVALID_TYPE));
+  if (_refBlock->isReferenceBlock()) throw(Exception(BLOCK_INVALID_TYPE));  
+
+  span = _span;
+  position = _position;
 
   childGroupItem = NULL;
   //boxWidth = params->defaultBlockWidth;
@@ -31,18 +34,148 @@ BoxItem::BoxItem(AbstractBlock *_refBlock,
   selected = false;
 
   setZValue(100);
-  setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges);
+  QGraphicsItem::GraphicsItemFlags flags = QGraphicsItem::ItemIsSelectable;
+  if (!isPositionLock()) {
+    flags |= QGraphicsItem::ItemIsMovable;
+    cout << "item " << qPrintable(refBlock->getName()) << "is movable" << endl;
+  }
+  if (!isDimensionLock()) {
+    flags |= QGraphicsItem::ItemSendsGeometryChanges;
+    cout << "item " << qPrintable(refBlock->getName()) << "is resizable" << endl;
+  }
+  setFlags(flags);
+
+  bool freeBorder[4]; // 0 = east, 1 = north, 2 = west, 3 = south
+  Parameters::Direction dirs[4];
+  for(int i=0;i<4;i++) {
+    freeBorder[i] = true;
+  }
+  dirs[0] = Parameters::East;
+  dirs[1] = Parameters::North;
+  dirs[2] = Parameters::West;
+  dirs[3] = Parameters::South;
+
 
-  initInterfaceItems();
-  updateGeometry(InterfaceMove);
-  resetInterfaceItemsPosition();
-  QPointF initPos = QPointF(0.0,0.0) - originPoint;
+  if (position == Top) {
+    freeBorder[1] = false;
+  }
+  if (position == Bottom) {
+    freeBorder[3] = false;
+  }
+  if (position == Left) {
+    freeBorder[2] = false;
+  }
+  if (position == Right) {
+    freeBorder[0] = false;
+  }
+  if (span == HSpan) {
+    freeBorder[2] = false;
+    freeBorder[0] = false;
+  }
+  if (span == VSpan) {
+    freeBorder[1] = false;
+    freeBorder[3] = false;
+  }
+  Parameters::Direction dIn = Parameters::West;
+  Parameters::Direction dOut = Parameters::East;
+  Parameters::Direction dBi = Parameters::South;
+  if (freeBorder[2] == false) {
+    int i=3;
+    while (freeBorder[i] == false) {
+      i = (i+1)%4;
+    }
+    dIn = dirs[i];
+  }
+  if (freeBorder[0] == false) {
+    int i=1;
+    while (freeBorder[i] == false) {
+      i = (i+1)%4;
+    }
+    dOut = dirs[i];
+  }
+  if (freeBorder[3] == false) {
+    int i=0;
+    while (freeBorder[i] == false) {
+      i = (i+1)%4;
+    }
+    dBi = dirs[i];
+  }
+
+  createInterfaceItems(dIn,dOut,dBi);
+  updateGeometry(Creation);
+
+  // position the item
+  int groupWidth = getScene()->getGroupItem()->getWidth();
+  int groupHeight = getScene()->getGroupItem()->getHeight();
+  double xx = 0.0,yy = 0.0;
+  if ((position == BoxItem::Left) || (position == BoxItem::TopLeft) || (position == BoxItem::BottomLeft)) {
+    xx = 0;
+    if ((span == VSpan) || (position == BoxItem::TopLeft)) {
+      yy = 0;
+    }
+    else if (position == BoxItem::BottomLeft) {
+      yy = groupHeight-totalHeight;
+    }
+    else {
+      yy = (groupHeight-totalHeight)/2.0;
+    }
+  }
+  else if ((position == BoxItem::Right) || (position == BoxItem::TopRight) || (position == BoxItem::BottomRight)) {
+    xx = groupWidth-totalWidth;
+    if (xx < 0) xx = 0;
+    if ((span == VSpan) || (position == BoxItem::TopRight)) {
+      yy = 0;
+    }
+    else if (position == BoxItem::BottomRight) {
+      yy = groupHeight-totalHeight;
+    }
+    else {
+      yy = (groupHeight-totalHeight)/2.0;
+    }
+  }
+  else if ((position == BoxItem::Top) || (position == BoxItem::TopLeft) || (position == BoxItem::TopRight)) {
+    yy = 0;
+    if ((span == HSpan) || (position == BoxItem::TopLeft)) {
+      xx = 0;
+    }
+    else if (position == BoxItem::TopRight) {
+      xx = groupWidth-totalWidth;
+    }
+    else {
+      xx = (groupWidth-totalWidth)/2.0;
+    }    
+  }
+  else if ((position == BoxItem::Bottom) || (position == BoxItem::BottomLeft) || (position == BoxItem::BottomRight)) {
+    yy = groupHeight-totalHeight;
+    if ((span == HSpan) || (position == BoxItem::BottomLeft)) {
+      xx = 0;
+    }
+    else if (position == BoxItem::BottomRight) {
+      xx = groupWidth-totalWidth;
+    }
+    else {
+      xx = (groupWidth-totalWidth)/2.0;
+    }    
+  }
+  else {
+    int marginConn = 2*(params->arrowWidth+params->arrowLineLength);
+    xx = (groupWidth-totalWidth)/2.0;
+    if (xx < marginConn) xx = marginConn;
+    yy = (groupHeight-totalHeight)/2.0;
+    if (yy < marginConn) yy = marginConn;
+  }
+  cout << "setting raw pos to " << xx << "," << yy << endl;
+  QPointF initPos(xx,yy);
+  initPos = initPos-originPoint;
   setPos(initPos);
-  //cout << "total size of block: " << totalWidth << "," << totalHeight << endl;
-  //cout << "pos in group: " << x() << "," << y() << endl;
+  cout << "total size of block: " << totalWidth << "," << totalHeight << endl;
+  cout << "pos in group: " << x() << "," << y() << endl;
 }
 
-BoxItem::BoxItem(Dispatcher *_dispatcher, Parameters *_params, GroupItem *parent) throw(Exception) : AbstractBoxItem(_dispatcher, _params, parent) {
+BoxItem::BoxItem(Dispatcher *_dispatcher, Parameters *_params, GroupItem *parent, int _lock, SpanType _span, Position _position) throw(Exception) : AbstractBoxItem(_dispatcher, _params, _lock, parent) {
+
+  span = _span;
+  position = _position;
 
   refBlock = NULL;
   childGroupItem = NULL;
@@ -50,7 +183,14 @@ BoxItem::BoxItem(Dispatcher *_dispatcher, Parameters *_params, GroupItem *parent
   selected = false;
 
   setZValue(100);
-  setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges);
+  QGraphicsItem::GraphicsItemFlags flags = QGraphicsItem::ItemIsSelectable;
+  if (!isPositionLock()) {
+    flags |= QGraphicsItem::ItemIsMovable;
+  }
+  if (!isDimensionLock()) {
+    flags |= QGraphicsItem::ItemSendsGeometryChanges;
+  }
+  setFlags(flags);
 
   boxWidth = params->defaultBlockWidth;
   boxHeight = params->defaultBlockHeight;
@@ -111,19 +251,22 @@ void BoxItem::updateMinimumSize() {
   int ifaceHeight = 0;
 
   foreach(InterfaceItem* iface, interfaces) {
-    ifaceWidth = iface->getNameWidth();
-    ifaceHeight = iface->getNameHeight();
-    if (iface->getOrientation() == Parameters::South) {
-      if (ifaceWidth > maxSouth) maxSouth = ifaceWidth;
-    }
-    else if (iface->getOrientation() == Parameters::North) {
-      if (ifaceWidth > maxNorth) maxNorth = ifaceWidth;
-    }
-    else if (iface->getOrientation() == Parameters::East) {
-      if (ifaceWidth > maxEast) maxEast = ifaceWidth;
-    }
-    else if (iface->getOrientation() == Parameters::West) {
-      if (ifaceWidth > maxWest) maxWest = ifaceWidth;
+
+    if (iface->visible) {
+      ifaceWidth = iface->getNameWidth();
+      ifaceHeight = iface->getNameHeight();
+      if (iface->getOrientation() == Parameters::South) {
+        if (ifaceWidth > maxSouth) maxSouth = ifaceWidth;
+      }
+      else if (iface->getOrientation() == Parameters::North) {
+        if (ifaceWidth > maxNorth) maxNorth = ifaceWidth;
+      }
+      else if (iface->getOrientation() == Parameters::East) {
+        if (ifaceWidth > maxEast) maxEast = ifaceWidth;
+      }
+      else if (iface->getOrientation() == Parameters::West) {
+        if (ifaceWidth > maxWest) maxWest = ifaceWidth;
+      }
     }
   }
 
@@ -151,34 +294,58 @@ bool BoxItem::updateGeometry(ChangeType type) {
   //cout << "current pos of block: " << currentPosition.x() << "," << currentPosition.y() << endl;
   QPointF oldOrigin = originPoint;
   QSize oldSize(totalWidth,totalHeight);
-
   bool boxSizeChanged = false;
 
   // whatever the change, the minimum size may have changed
   updateMinimumSize();
 
-  if (type == Resize) {
+  int groupWidth = getScene()->getGroupItem()->getWidth();
+  int groupHeight = getScene()->getGroupItem()->getHeight();
+
+  cout << "minimum box size is " << minimumBoxWidth << "x" << minimumBoxHeight << endl;
+  cout << "group size is " << groupWidth << "x" << groupHeight << endl;
+
+  if (type == Creation) {
+
+    boxSizeChanged = true;
+    boxWidth = minimumBoxWidth;
+    boxHeight = minimumBoxHeight;
+    /* reset and update interfaces positions
+     * in case of spanning, the interface are positionned
+     * only on free borders.
+     */
+    resetInterfaceItemsPosition();
+    /* must test if the GroupItem must be resized */
+    if ((span == HSpan) && (boxWidth < groupWidth)) {
+      boxWidth = groupWidth; // no interfaces in east/west (done in constructor)
+    }
+    else if ((span == VSpan) && (boxHeight < groupHeight)) {
+      boxHeight = groupHeight;
+    }
+  }
+  else if (type == Resize) {
     // resize implies to move interfaces and to update connections
     boxSizeChanged = true;
+    updateInterfaceAndConnectionItems();
   }
   else if (type == InterfaceMove) {
     // if an interface moves, it may change the box size
     if (boxWidth < minimumBoxWidth) {
       boxWidth = minimumBoxWidth;
       boxSizeChanged = true;
+      updateInterfaceAndConnectionItems();
     }
     if (boxHeight < minimumBoxHeight) {
       boxHeight = minimumBoxHeight;
       boxSizeChanged = true;
+      updateInterfaceAndConnectionItems();
     }
   }
-  if (boxSizeChanged) {
-    updateInterfaceAndConnectionItems();
-  }
-
 
+  // update total size
   double x = 0.0;
   double y = 0.0;
+
   totalWidth = boxWidth;
   totalHeight = boxHeight;
 
@@ -199,6 +366,9 @@ bool BoxItem::updateGeometry(ChangeType type) {
   QSizeF newSize(totalWidth,totalHeight);
   originPoint.setX(x);
   originPoint.setY(y);
+  cout << "change orig pos of " << qPrintable(refBlock->getName()) << "to " << x << "," << y << endl;
+  cout << "box size is " << boxWidth << "x" << boxHeight << endl;
+  cout << "total size is " << totalWidth << "x" << totalHeight << endl;
 
   if ((boxSizeChanged) || (newSize != oldSize) || (originPoint != oldOrigin)) {
     prepareGeometryChange();
@@ -224,37 +394,54 @@ void BoxItem::nameChanged() {
 void BoxItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
 
   if(params->editState == Parameters::EditBlockMove) {
+
+    if (isPositionLock()) return;
     QPointF absPos = currentPosition + originPoint;
     int marginConn = 2*(params->arrowWidth+params->arrowLineLength);
     int gapX = event->scenePos().x() - cursorPosition.x();
     int gapY = event->scenePos().y() - cursorPosition.y();
+    // update cursor position
+    cursorPosition = event->scenePos();
 
     //cout << "block abs. pos: " << absPos.x() << "," << absPos.y() << " | ";
     //cout << "block current. pos: " << currentPosition.x() << "," << currentPosition.y() << " | ";
 
-    if (absPos.x()+gapX < marginConn) {
+    if ((position == Left) || (position == Right)) {
+      gapX = 0;
+    }
+    else if ((gapX < 0) && (absPos.x() == marginConn)) {
+      gapX = 0;
+    }
+    else if (absPos.x()+gapX < marginConn) {
       gapX = marginConn-absPos.x();
     }
-    if (absPos.y()+gapY < marginConn) {
+    if ((position == Top) || (position == Bottom)) {
+      gapY = 0;
+    }
+    else if ((gapY < 0) && (absPos.y() == marginConn)) {
+      gapY = 0;
+    }
+    else if (absPos.y()+gapY < marginConn) {
       gapY = marginConn-absPos.y();
     }
     //cout << "gap: " << gapX << "," << gapY << endl;
-    QPointF gap(gapX,gapY);
-    currentPosition = currentPosition+gap;
-    setPos(currentPosition);
-    // update all connections from/to this block
-    foreach(ConnectionItem *item, getScene()->getConnectionItems()){
-      if ((item->getFromInterfaceItem()->getOwner() == this) || (item->getToInterfaceItem()->getOwner() == this)) {
-        item->setPath();
+    if ((gapX != 0) || (gapY != 0)) {
+      QPointF gap(gapX,gapY);
+      currentPosition = currentPosition+gap;
+      setPos(currentPosition);
+      // update all connections from/to this block
+      foreach(ConnectionItem *item, getScene()->getConnectionItems()){
+        if ((item->getFromInterfaceItem()->getOwner() == this) || (item->getToInterfaceItem()->getOwner() == this)) {
+          item->setPath();
+        }
       }
+      // udpate the groupitem
+      (getScene()->getGroupItem())->updateShape();
     }
-    cursorPosition = event->scenePos();
-
-    // udpate the groupitem
-    (getScene()->getGroupItem())->updateShape();
   }
   else if(params->editState == Parameters::EditBlockResize) {
 
+    if (isDimensionLock()) return;
     int gapX = event->scenePos().x() - cursorPosition.x();
     int gapY = event->scenePos().y() - cursorPosition.y();
     //cout << "gap: " << gapX << "," << gapY << endl;
@@ -329,7 +516,7 @@ void BoxItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
 
   int mode = getScene()->getEditionMode();
 
-  dispatcher->setCurrentGroupWidget(getScene()->getGroupWidget());
+  dispatcher->setCurrentGroupWidget(Dispatcher::Design, getScene()->getGroupWidget());
 
   if ((mode == GroupScene::AddConnection) && (params->cursorState == Parameters::CursorOnInterface)) {
     InterfaceItem *inter = getInterfaceItemFromCursor(x,y);
@@ -373,9 +560,16 @@ void BoxItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
       update();
     }
     else if (params->cursorState == Parameters::CursorOnBorder) {
-      setFlag(ItemIsMovable, false);
-      cursorPosition = event->scenePos();
-      params->setEditState(Parameters::EditBlockResize);
+      if (isDimensionLock()) {
+        if ((position == Bottom)||(position == Right)) {
+          event->ignore();
+        }
+      }
+      else {
+        setFlag(ItemIsMovable, false);
+        cursorPosition = event->scenePos();
+        params->setEditState(Parameters::EditBlockResize);
+      }
     }
   }
 }
@@ -403,7 +597,7 @@ void BoxItem::mouseReleaseEvent(QGraphicsSceneMouseEvent  *event) {
     else if (params->editState == Parameters::EditCloseConnection) {
       InterfaceItem* iface1 = getScene()->getSelectedInterface(1);
       InterfaceItem* iface2 = getScene()->getSelectedInterface(2);
-      bool ok = dispatcher->createConnection(iface1,iface2);
+      bool ok = dispatcher->createConnection(Dispatcher::Design, iface1,iface2);
       if (ok) {
         iface1->selected = false;
         update(iface1->boundingRect());
@@ -431,9 +625,9 @@ void BoxItem::mouseReleaseEvent(QGraphicsSceneMouseEvent  *event) {
 
 void BoxItem::hoverMoveEvent(QGraphicsSceneHoverEvent * event) {
 
-  QPointF pos = event->pos();
-  qreal x = pos.x();
-  qreal y = pos.y();
+  QPointF evPos = event->pos();
+  qreal x = evPos.x();
+  qreal y = evPos.y();
   currentBorder = NoBorder;
   int mode = getScene()->getEditionMode();
 
@@ -494,8 +688,14 @@ void BoxItem::hoverMoveEvent(QGraphicsSceneHoverEvent * event) {
       }
     }
   }
-  //QGraphicsItem::hoverMoveEvent(event);
-  event->ignore();
+  if (params->cursorState == Parameters::CursorOnBorder) {
+    if (isDimensionLock()) {
+      if ((position == Bottom)||(position == Right)) {
+        event->setPos(evPos+pos());
+        getScene()->getGroupItem()->hoverMoveEvent(event);
+      }
+    }
+  }
 }
 
 
@@ -617,60 +817,60 @@ void BoxItem::contextMenuEvent(QGraphicsSceneContextMenuEvent * event) {
 
   if (selectedAction == removeAction) {
     if(ifaceItem != NULL) {
-     dispatcher->removeFunctionalInterface(ifaceItem);
+     dispatcher->removeFunctionalInterface(Dispatcher::Design, ifaceItem);
     }
     else {
-      dispatcher->removeBoxItem(this);
+      dispatcher->removeBoxItem(Dispatcher::Design, this);
     }
   }
   else if (selectedAction == duplicateAction) {
-    dispatcher->duplicateBoxItem(this);
+    dispatcher->duplicateBoxItem(Dispatcher::Design, this);
   }
   else if(selectedAction == renameAction){
     if(ifaceItem != NULL) {
-      dispatcher->renameInterface(ifaceItem);
+      dispatcher->renameInterface(Dispatcher::Design, ifaceItem);
     }
     else {
       if (refBlock->isFunctionalBlock()) {          
-        dispatcher->renameFunctionalBlock(this);
+        dispatcher->renameFunctionalBlock(Dispatcher::Design, this);
       }
       else if (refBlock->isGroupBlock()) {        
-        dispatcher->renameGroupBlock(childGroupItem);
+        dispatcher->renameGroupBlock(Dispatcher::Design, childGroupItem);
       }
     }   
   }
   else if(selectedAction == showProperties){
-    dispatcher->showProperties(ifaceItem);
+    dispatcher->showProperties(Dispatcher::Design, ifaceItem);
   }
   else if (selectedAction == connectToGroup){
-    dispatcher->connectInterToGroup(ifaceItem);
+    dispatcher->connectInterToGroup(Dispatcher::Design, ifaceItem);
   }
   else if (selectedAction == cloneInterface){
-    dispatcher->duplicateInterfaceItem(ifaceItem);
+    dispatcher->duplicateInterfaceItem(Dispatcher::Design, ifaceItem);
   }
   else if (selectedAction == openWindow){
-    dispatcher->showRaiseWindow(this);
+    dispatcher->showRaiseWindow(Dispatcher::Design, this);
   }
   else if(selectedAction == showRstClkIface) {
-    dispatcher->showRstClkIface(this);
+    dispatcher->showRstClkIface(Dispatcher::Design, this);
   }
   else if(selectedAction == showWishboneIface) {
-    dispatcher->showWishboneIface(this);
+    dispatcher->showWishboneIface(Dispatcher::Design, this);
   }
   else if(selectedAction == showParameters) {    
     new ParametersWindow(refBlock, params, NULL);
   }
   else if(selectedAction == showPatterns) {    
-    dispatcher->showPatterns(ifaceItem);
+    dispatcher->showPatterns(Dispatcher::Design, ifaceItem);
   }
   else if(selectedAction == removeModifier) {
-    dispatcher->removeModifier(ifaceItem);
+    dispatcher->removeModifier(Dispatcher::Design, ifaceItem);
   }
   else if(selectedAction == showModifier) {
-    dispatcher->showModifier(ifaceItem);
+    dispatcher->showModifier(Dispatcher::Design, ifaceItem);
   }
   else if(selectedAction == generateVHDL) {
-    dispatcher->generateBlockVHDL(this);
+    dispatcher->generateBlockVHDL(Dispatcher::Design, this);
   }
 
 }
@@ -793,7 +993,7 @@ void BoxItem::loadFunctional(QDomElement funcElement) throw(Exception) {
   }
   
   // creating InterfaceItem
-  initInterfaceItems();
+  createInterfaceItems();
   // setting them with saved values
   for(int i=0; i<interfaceNodes.length(); i++){