X-Git-Url: https://bilbo.iut-bm.univ-fcomte.fr/and/gitweb/blast.git/blobdiff_plain/8f0bedf735fe2b306c11c3f4a168245a05e37ccd..e40a5399ec7887c2606f18575c809b0d05b09278:/BoxItem.cpp?ds=sidebyside diff --git a/BoxItem.cpp b/BoxItem.cpp index 9ff42a8..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; + + + 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]; + } - initInterfaceItems(); - updateGeometry(InterfaceMove); - resetInterfaceItemsPosition(); - QPointF initPos = QPointF(0.0,0.0) - originPoint; + 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); } } @@ -791,20 +991,9 @@ void BoxItem::loadFunctional(QDomElement funcElement) throw(Exception) { functionalBlock->addInterface(ctlIface); } } - // connect clk and rst to group clk/rst or to clkrstgen - if ((name != "clkrstgen") && (parentGroupBlock != NULL)) { - try { - functionalBlock->connectClkReset(); - } - catch(Exception e) { - AbstractBlock* source = (AbstractBlock *)(e.getSource()); - cerr << qPrintable(source->getName()) << ":" << qPrintable(e.getMessage()) << endl; - throw(e); - } - } // creating InterfaceItem - initInterfaceItems(); + createInterfaceItems(); // setting them with saved values for(int i=0; i