예제 #1
0
TransitionGraphic::TransitionGraphic(StateBoxGraphic *parentGraphic, StateBoxGraphic *targetGraphic, SCTransition * t) :
    QGraphicsObject(NULL),
    _transitionDM(t),
    _lineSegments(),
    _parentStateGraphic(parentGraphic),
    _targetStateGraphic(targetGraphic)
{
    this->setFlag(QGraphicsItem::ItemIsMovable, false);

    TransitionAttributes::TransitionPathAttribute * p =
            dynamic_cast<TransitionAttributes::TransitionPathAttribute *> (  t->attributes.value("path"));

    QList<QPointF> pointList = p->asQPointFList();

    if (  pointList.count() < 2 && targetGraphic != NULL )
    {
        // this path is new, anchor each end to the source and target states
        // find the orientation of the parent and target graphics to determine which sides to anchor to.

        int sourceSide=0;
        int targetSide=0;

        getClosestSides( & sourceSide, & targetSide);

        QPointF sourceAnchor = _parentStateGraphic->mapFromScene( _parentStateGraphic->getSideCenterPointInSceneCoord(sourceSide));
        QPointF targetAnchor = _parentStateGraphic->mapFromScene( _targetStateGraphic->getSideCenterPointInSceneCoord(targetSide));

        SelectableLineSegmentGraphic * segment  = new SelectableLineSegmentGraphic(sourceAnchor,sourceAnchor, targetAnchor, t);
        segment->setParentItem(_parentStateGraphic);
        _lineSegments.append(segment);
        connect ( segment, SIGNAL(startEndMoved(QPointF)), parentGraphic, SLOT(handleTransitionLineStartMoved(QPointF)));
        connect(segment, SIGNAL(updateModel()), this, SLOT(updateModel()));


        segment->setTerminator(true);

    }
    else if ( pointList.count() == 2 )
    {

        SelectableLineSegmentGraphic * segment   = new SelectableLineSegmentGraphic(pointList[0], pointList[0], pointList[1], t);
        segment->setParentItem(parentGraphic);
        _lineSegments.append(segment);

        // connect the parent state-graphic's slots to the new transition graphic's signals

        connect ( segment, SIGNAL(startEndMoved(QPointF)), parentGraphic, SLOT(handleTransitionLineStartMoved(QPointF)));
        connect(segment, SIGNAL(updateModel()), this, SLOT(updateModel()));

        segment->setTerminator(true);

    }
    else
    {
        SelectableLineSegmentGraphic * lastSegment=NULL;

        for (int i = 0 ; i < pointList.count() - 1 ; i ++)
        {
            SelectableLineSegmentGraphic * segment   = new SelectableLineSegmentGraphic( pointList[i+0], pointList[i+0], pointList[i+1], t);
            segment->setParentItem(parentGraphic);
            _lineSegments.append(segment);
            connect ( segment, SIGNAL(startEndMoved(QPointF)), parentGraphic, SLOT(handleTransitionLineStartMoved(QPointF)));
            connect(segment, SIGNAL(updateModel()), this, SLOT(updateModel()));

            lastSegment = segment;
        }

        lastSegment->setTerminator(true);

    }
}
예제 #2
0
/**
 * @brief SCGraphicsView::connectTransition
 * @param trans
 *
 * calls all graphics related connects for transition graphics, their elbows, and the transition deconstructors
 * calls all data model/attribute connects for sctransition to transitiongraphics
 * calls all data model/attribute connects for sctextblock of the transition to the selectable text block of the transition
 * additionally, repositions the anchors to their target states
 *
 */
void SCGraphicsView::connectTransition(SCTransition* trans)
{

    SCState* parentState = trans->parentSCState();
    SCState* targetState = trans->targetState();

    StateBoxGraphic* parentGraphic = _hashStateToGraphic.value(parentState);
    StateBoxGraphic* targetGraphic = _hashStateToGraphic.value(targetState);
    TransitionGraphic* transGraphic = _hashTransitionToGraphic.value(trans);

    // set the connects for the transition graphic
    connect(trans, SIGNAL(markedForDeletion(QObject*)), this, SLOT(handleTransitionDeleted(QObject*)));
    connect(transGraphic, SIGNAL(destroyed(QObject*)), this, SLOT(handleTransitionGraphicDeleted(QObject*)));

    // create the connection to automatically move anchor elbows when state graphics are moved.
    connect(parentGraphic, SIGNAL(stateBoxMoved(QPointF)), transGraphic, SLOT(handleParentStateGraphicMoved(QPointF)));
    connect(targetGraphic, SIGNAL(stateBoxMoved(QPointF)), transGraphic, SLOT(handleTargetStateGraphicMoved(QPointF)));



    // additionally snap the anchors when done moving the source and sink
    connect(parentGraphic, SIGNAL(stateBoxReleased()), transGraphic, SLOT(handleParentStateGraphicReleased()));
    connect(targetGraphic, SIGNAL(stateBoxReleased()), transGraphic, SLOT(handleTargetStateGraphicReleased()));

    // snap the anchors when done RESIZING
    connect(parentGraphic, SIGNAL(cornerReleased()), transGraphic, SLOT(handleParentStateGraphicResizedReleased()));
    connect(targetGraphic, SIGNAL(cornerReleased()), transGraphic, SLOT(handleTargetStateGraphicResizedReleased()));

    connect(transGraphic->getSourceAnchor(),SIGNAL(anchorMoved(QPointF)),parentGraphic,SLOT(handleTransitionLineStartMoved(QPointF)));  // state box will handle snapping the source elbow/anchor to its border instead of standard movement
    connect(transGraphic->getSinkAnchor(),SIGNAL(anchorMoved(QPointF)),targetGraphic,SLOT(handleTransitionLineEndMoved(QPointF)));  // state box will handle snapping the source elbow/anchor to its border instead of standard movement
    //qDebug() << "hooking anchor to state graphic: " << _targetStateGraphic->objectName();

    // do this to set closest wall from default
    emit transGraphic->getSourceAnchor()->anchorMoved(parentGraphic->mapToScene(transGraphic->getSourceAnchor()->pos()));
    emit transGraphic->getSinkAnchor()->anchorMoved(parentGraphic->mapToScene(transGraphic->getSinkAnchor()->pos()));

    // create the connect to automatically move anchor elbows when state graphics are moved.
    connect(parentGraphic, SIGNAL(stateBoxResized(QRectF, QRectF, int)),transGraphic, SLOT(handleParentStateGraphicResized(QRectF, QRectF, int)));
    connect(targetGraphic, SIGNAL(stateBoxResized(QRectF, QRectF, int)),transGraphic, SLOT(handleTargetStateGraphicResized(QRectF, QRectF, int)));

    // connect this state box's grand parents update anchors when they are resized
    StateBoxGraphic* grandParentGraphic = parentGraphic->parentItemAsStateBoxGraphic();
    bool isSibling = false;
    while(grandParentGraphic)
    {
        connect(grandParentGraphic, SIGNAL(stateBoxResized(QRectF, QRectF, int)),transGraphic, SLOT(handleGrandParentStateGraphicResized(QRectF, QRectF, int)));
        connect(grandParentGraphic, SIGNAL(stateBoxReleased()), transGraphic, SLOT(handleParentStateGraphicReleased()));


        // this is a special case of connect for the transition
        // we connect a sink anchor to stay in place, unless the target graphic is a sibling of the source graphic
        // if the two are siblings, the anchor is already updated because the source and target are moving together
        if(grandParentGraphic->childItems().contains(transGraphic->getTargetStateGraphic()) && !isSibling)
        {
            isSibling = true;
        }

        if(!isSibling)
        {
            connect(grandParentGraphic, SIGNAL(stateBoxMoved(QPointF)), transGraphic, SLOT(handleParentStateGraphicMoved(QPointF)));
        }

        grandParentGraphic = grandParentGraphic->parentItemAsStateBoxGraphic();
    }

    // connect the target state box's grand parents to update the target anchors when they are resized
    StateBoxGraphic* grandParentTargetGraphic = targetGraphic->parentItemAsStateBoxGraphic();
    while(grandParentTargetGraphic)
    {
        connect(grandParentTargetGraphic, SIGNAL(stateBoxResized(QRectF, QRectF, int)),transGraphic, SLOT(handleGrandParentTargetStateGraphicResized(QRectF, QRectF, int)));
        grandParentTargetGraphic = grandParentTargetGraphic->parentItemAsStateBoxGraphic();
    }

    // connect the event name data model to the text block
    TransitionStringAttribute* eventName = trans->getTransStringAttr("event");
    connect(eventName, SIGNAL(changed(TransitionStringAttribute*)), transGraphic, SLOT(handleAttributeChanged(TransitionStringAttribute*)));

    // when the transition graphic emits clicked, also emit it for the sctransition
    connect(transGraphic, SIGNAL(clicked(SCTransition*)), trans, SIGNAL(clicked(SCTransition*)));

    // connect the text block graphic of this transition to the data model
    connect(trans->getEventTextBlock()->getFontFamilyAttr(), SIGNAL(changed(FontFamilyAttribute*)), transGraphic->getEventTextGraphic(), SLOT(handleFontChanged(FontFamilyAttribute*)));
    connect(trans->getEventTextBlock()->getFontSizeAttr(), SIGNAL(changed(FontSizeAttribute*)), transGraphic->getEventTextGraphic(), SLOT(handleFontChanged(FontSizeAttribute*)));

    connect(trans->getEventTextBlock()->getFontBoldAttr(), SIGNAL(changed(FontBoldAttribute*)), transGraphic->getEventTextGraphic(), SLOT(handleFontChanged(FontBoldAttribute*)));


}