X-Git-Url: https://bilbo.iut-bm.univ-fcomte.fr/and/gitweb/blast.git/blobdiff_plain/1b7818e18ed7bcf3464e307b97c6e0e6d72cc69b..e40a5399ec7887c2606f18575c809b0d05b09278:/BoxItem.cpp diff --git a/BoxItem.cpp b/BoxItem.cpp index a7e1181..ae15002 100644 --- a/BoxItem.cpp +++ b/BoxItem.cpp @@ -17,7 +17,7 @@ BoxItem::BoxItem(AbstractBlock *_refBlock, Dispatcher *_dispatcher, - Parameters *_params, GroupItem *parent, LockType _lock, SpanType _span, Position _hPos, Position _vPos) throw(Exception) : AbstractBoxItem( _refBlock, _dispatcher, _params, _lock, 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 @@ -25,8 +25,7 @@ BoxItem::BoxItem(AbstractBlock *_refBlock, if (_refBlock->isReferenceBlock()) throw(Exception(BLOCK_INVALID_TYPE)); span = _span; - hPos = _hPos; - vPos = _vPos; + position = _position; childGroupItem = NULL; //boxWidth = params->defaultBlockWidth; @@ -38,26 +37,145 @@ BoxItem::BoxItem(AbstractBlock *_refBlock, 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); - initInterfaceItems(); - updateGeometry(InterfaceMove); - resetInterfaceItemsPosition(); - QPointF initPos = QPointF(0.0,0.0) - originPoint; + 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]; + } + + 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, LockType _lock, SpanType _span, Position _hPos, Position _vPos) throw(Exception) : AbstractBoxItem(_dispatcher, _params, _lock, parent) { +BoxItem::BoxItem(Dispatcher *_dispatcher, Parameters *_params, GroupItem *parent, int _lock, SpanType _span, Position _position) throw(Exception) : AbstractBoxItem(_dispatcher, _params, _lock, parent) { span = _span; - hPos = _hPos; - vPos = _vPos; + position = _position; refBlock = NULL; childGroupItem = NULL; @@ -133,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; + } } } @@ -173,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; @@ -221,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(); @@ -246,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; @@ -395,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); + } } } } @@ -453,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(); @@ -516,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); + } + } + } } @@ -813,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