Exemple #1
0
void PortionDrawer::drawNodes(DiagramDrawer &drawer)
    {
    drawer.groupShapes(true, Color(0,0,0), Color(245,245,255));
    for(size_t i=0; i<mNodePositions.size(); i++)
        {
        if(mGraph->getNodes()[i].getNodeType() == PNT_Attribute)
            {
            drawer.drawRect(getNodeRect(drawer, i));
            }
        else
            {
            drawer.drawEllipse(getNodeRect(drawer, i));
            }
        }
    drawer.groupShapes(false, 0, 0);
    drawer.groupShapes(true, Color(0,0,255), Color(245,245,255));
    for(size_t i=0; i<mNodePositions.size(); i++)
        {
        if(mGraph->getNodes()[i].getNodeType() == PNT_NonMemberVariable)
            {
            drawer.drawRect(getNodeRect(drawer, i));
            }
        }
    drawer.groupShapes(false, 0, 0);
    }
GraphSize OperationDrawer::drawClass(DiagramDrawer &drawer, const OperationClass &node,
        const OperationDrawOptions & /*options*/, bool draw)
    {
    GraphPoint startpos = node.getPosition();
    const ModelType *type = node.getType();
    OovStringRef const typeName = type->getName();
    int rectx = 0;
    int recty = 0;
    const ModelClassifier *classifier = type->getClass();
    if(classifier)
        {
        if(draw)
            {
            drawer.groupText(true, false);
            }
        OovStringVec strs;
        std::vector<GraphPoint> positions;
        strs.push_back(typeName);
        splitStrings(strs, 30, 40);

        for(auto const &str : strs)
            {
            recty += mCharHeight + (mPad * 2);
            positions.push_back(GraphPoint(startpos.x+mPad, startpos.y + recty - mPad));
            int curx = static_cast<int>(drawer.getTextExtentWidth(str)) + mPad*2;
            if(curx > rectx)
                rectx = curx;
            }

        if(draw)
            {
            drawer.groupShapes(true, Color(0,0,0), Color(245,245,255));
            drawer.drawRect(GraphRect(startpos.x, startpos.y, rectx, recty));
            drawer.groupShapes(false, Color(0,0,0), Color(245,245,255));

            for(size_t i=0; i<strs.size(); i++)
                {
                drawer.drawText(positions[i], strs[i]);
                }
            drawer.groupText(false, false);
            }
        }
    return GraphSize(rectx, recty);
    }
GraphSize OperationDrawer::drawOperationNoText(DiagramDrawer &drawer, GraphPoint pos,
        OperationDefinition &operDef, const OperationGraph &graph,
        const OperationDrawOptions &options,
        std::set<const OperationDefinition*> &drawnOperations,
        std::vector<DrawString> &drawStrings, bool draw, int callDepth)
    {
    GraphPoint startpos = pos;
    // Add space between bottom of class and operation name
    int starty = startpos.y+(mPad*2);
    int y=starty;
    size_t sourceIndex = operDef.getOperClassIndex();
    int arrowLen = mCharHeight * 7 / 10;
    std::vector<int> condStartPosY;

    drawnOperations.insert(&operDef);
    const OperationClass &cls = graph.getClass(sourceIndex);
    if(callDepth == 0)
        {
        // Reinit all polys to initial conditions.
        mLifelinePolygons.clear();
        mLifelinePolygons.resize(graph.getClasses().size());
        }
    BlockPolygon &poly = mLifelinePolygons[sourceIndex];
    poly.setup(cls.getLifelinePosX(), mPad);

    if(!graph.isOperCalled(operDef))
        {
        // Show starting operation
        operDef.setRect(GraphPoint(cls.getPosition().x, y),
                GraphSize(mCharHeight*50, mCharHeight+mPad));
        y += mCharHeight;
        drawStrings.push_back(DrawString(GraphPoint(
                cls.getPosition().x, y), operDef.getName()));
        // Add space between operation name and called operations.
        y += (mPad * 2);
        int lineY = y + mPad*2;
        if(draw)
            {
            drawCall(drawer, GraphPoint(cls.getPosition().x, lineY),
                GraphPoint(cls.getLifelinePosX(), lineY),
                operDef.isConst(), arrowLen);
            }
        }
    for(const auto &stmt : operDef.getStatements())
        {
        int condOffset = poly.getDepth() * mPad;
        switch(stmt->getStatementType())
            {
            case ST_Call:
                {
                OperationCall *call = stmt->getCall();

                size_t targetIndex = call->getOperClassIndex();
                int lineY = y + mCharHeight + mPad*2;
                int sourcex = cls.getLifelinePosX();
                sourcex += condOffset;
                const OperationClass &targetCls = graph.getClass(targetIndex);
                int targetx = targetCls.getLifelinePosX();
                if(targetIndex == NO_INDEX)
                    {
                    // Handle [else]
//                  int len = mCharHeight*3;
//                  mDrawer.drawLine(GraphPoint(sourcex, lineY),
//                          GraphPoint(sourcex+len, lineY), call->isConst());
                    }
                else if(targetIndex != sourceIndex)
                    {
                    if(draw)
                        {
                        drawCall(drawer, GraphPoint(sourcex, lineY),
                            GraphPoint(targetx, lineY), call->isConst(), arrowLen);
                        }
                    }
                else
                    {
                    // Draw line back to same class
                    int len = mCharHeight*3;
                    int height = 3;
                    if(draw)
                        {
                        drawer.drawLine(GraphPoint(sourcex, lineY),
                            GraphPoint(sourcex+len, lineY), call->isConst());
                        drawer.drawLine(GraphPoint(sourcex+len, lineY),
                            GraphPoint(sourcex+len, lineY+height));
                        drawer.drawLine(GraphPoint(sourcex, lineY+height),
                            GraphPoint(sourcex+len, lineY+height), call->isConst());
                        }
                    y += height;
                    }
                int textX = (sourceIndex < targetIndex) ? cls.getLifelinePosX() :
                        targetCls.getLifelinePosX();
                GraphPoint callPos(textX+condOffset+mPad, y+mCharHeight);
                drawStrings.push_back(DrawString(callPos, call->getName()));
                call->setRect(GraphPoint(callPos.x, callPos.y-mCharHeight),
                        GraphSize(mCharHeight*50, mCharHeight+mPad));
                y += mCharHeight*2;

                // Draw child definition.
                OperationDefinition *childDef = graph.getOperDefinition(*call);
                if(childDef)
                    {
//                    poly.startChildBlock(condDepth, y);
                    if(drawnOperations.find(childDef) == drawnOperations.end())
                        {
                        poly.incDepth(y);
                        GraphSize childSize = drawOperationNoText(drawer,
                            GraphPoint(pos.x, y), *childDef, graph, options,
                            drawnOperations, drawStrings, draw, callDepth+1);
                        y += childSize.y + mPad * 2;
                        poly.decDepth(y);
                        }
                    else
                        {
                        // This draws a rectangle to signify that it is defined
                        // elsewhere in the diagram.
                        GraphRect rect(targetx + mPad*2, callPos.y + mPad*2,
                            mCharHeight+mPad, mCharHeight+mPad);
                        if(draw)
                            {
                            drawer.drawRect(rect);
                            }
                        y += mCharHeight+mPad;
                        }
//                    poly.endChildBlock(condDepth, y);
                    }
                }
                break;

            case ST_VarRef:
                {
                OperationVarRef *ref = stmt->getVarRef();

                size_t targetIndex = ref->getOperClassIndex();
                int lineY = y + mCharHeight + mPad*2;
                int sourcex = cls.getLifelinePosX();
                sourcex += condOffset;
                const OperationClass &targetCls = graph.getClass(targetIndex);
                int targetx = targetCls.getLifelinePosX();
                if(targetIndex == NO_INDEX)
                    {
                    int len = mCharHeight*3;
                    if(draw)
                        {
                        drawer.drawLine(GraphPoint(sourcex, lineY),
                            GraphPoint(sourcex+len, lineY), ref->isConst());
                        }
                    }
                else if(targetIndex != sourceIndex)
                    {
                    if(draw)
                        {
                        drawCall(drawer, GraphPoint(sourcex, lineY),
                            GraphPoint(targetx, lineY), ref->isConst(), arrowLen);
                        }
                    }
                else
                    {
                    // Draw line back to same class
                    int len = mCharHeight*3;
                    int height = 3;
                    if(draw)
                        {
                        drawer.drawLine(GraphPoint(sourcex, lineY),
                            GraphPoint(sourcex+len, lineY), ref->isConst());
                        drawer.drawLine(GraphPoint(sourcex+len, lineY),
                            GraphPoint(sourcex+len, lineY+height));
                        drawer.drawLine(GraphPoint(sourcex, lineY+height),
                            GraphPoint(sourcex+len, lineY+height), ref->isConst());
                        }
                    y += height;
                    }
                int textX = (sourceIndex < targetIndex) ? cls.getLifelinePosX() :
                        targetCls.getLifelinePosX();
                GraphPoint callPos(textX+condOffset+mPad, y+mCharHeight);
                if(draw)
                    {
                    drawStrings.push_back(DrawString(callPos, ref->getName()));
                    }
                ref->setRect(GraphPoint(callPos.x, callPos.y-mCharHeight),
                        GraphSize(mCharHeight*50, mCharHeight+mPad));
                y += mCharHeight*2;
                }
                break;

            case ST_OpenNest:
                {
                GraphPoint lifePos(cls.getLifelinePosX()+condOffset+
                        mPad, y+mCharHeight);
                const OperationNestStart *cond = stmt->getNestStart();
                if(draw)
                    {
                    drawStrings.push_back(DrawString(lifePos, cond->getExpr()));
                    }
                condStartPosY.push_back(y);
                y += mCharHeight*2;

                poly.incDepth(y);
                }
                break;

            case ST_CloseNest:
                {
                poly.decDepth(y);
                }
                break;
            }
        }
    if(callDepth == 0)
        {
        for(auto &poly : mLifelinePolygons)
            {
            poly.finishBlock();
            if(draw)
                {
                drawer.drawPoly(poly, Color(245,245,255));
                }
            }
        }

    return GraphSize(0, y - startpos.y);
    }