Search in sources :

Example 11 with KText

use of de.cau.cs.kieler.klighd.krendering.KText in project lingua-franca by lf-lang.

the class LinguaFrancaShapeExtensions method addActionDecorator.

/**
 * Creates the triangular line decorator with text.
 */
public KPolygon addActionDecorator(KPolyline line, String text) {
    final float size = 18;
    // Create action decorator
    KPolygon actionDecorator = _kContainerRenderingExtensions.addPolygon(line);
    _kRenderingExtensions.setBackground(actionDecorator, Colors.WHITE);
    List<KPosition> pointsToAdd = List.of(_kRenderingExtensions.createKPosition(LEFT, 0, 0.5f, TOP, 0, 0), _kRenderingExtensions.createKPosition(RIGHT, 0, 0, BOTTOM, 0, 0), _kRenderingExtensions.createKPosition(LEFT, 0, 0, BOTTOM, 0, 0));
    actionDecorator.getPoints().addAll(pointsToAdd);
    // Set placement data of the action decorator
    KDecoratorPlacementData placementData = _kRenderingFactory.createKDecoratorPlacementData();
    placementData.setRelative(0.5f);
    placementData.setAbsolute(-size / 2);
    placementData.setWidth(size);
    placementData.setHeight(size);
    placementData.setYOffset(-size * 0.66f);
    placementData.setRotateWithLine(true);
    actionDecorator.setPlacementData(placementData);
    // Add text to the action decorator
    KText textToAdd = _kContainerRenderingExtensions.addText(actionDecorator, text);
    _kRenderingExtensions.setFontSize(textToAdd, 8);
    _linguaFrancaStyleExtensions.noSelectionStyle(textToAdd);
    DiagramSyntheses.suppressSelectability(textToAdd);
    _kRenderingExtensions.setPointPlacementData(textToAdd, _kRenderingExtensions.LEFT, 0, 0.5f, _kRenderingExtensions.TOP, size * 0.15f, 0.5f, _kRenderingExtensions.H_CENTRAL, _kRenderingExtensions.V_CENTRAL, 0, 0, size, size);
    return actionDecorator;
}
Also used : KPolygon(de.cau.cs.kieler.klighd.krendering.KPolygon) KDecoratorPlacementData(de.cau.cs.kieler.klighd.krendering.KDecoratorPlacementData) KText(de.cau.cs.kieler.klighd.krendering.KText) KPosition(de.cau.cs.kieler.klighd.krendering.KPosition)

Example 12 with KText

use of de.cau.cs.kieler.klighd.krendering.KText in project lingua-franca by lf-lang.

the class LinguaFrancaShapeExtensions method addActionFigureAndPorts.

/**
 * Creates the triangular action node with text and ports.
 */
public Pair<KPort, KPort> addActionFigureAndPorts(KNode node, String text) {
    final float size = 18;
    _kNodeExtensions.setMinimalNodeSize(node, size, size);
    KPolygon figure = _kRenderingExtensions.addPolygon(node);
    _kRenderingExtensions.setBackground(figure, Colors.WHITE);
    _linguaFrancaStyleExtensions.boldLineSelectionStyle(figure);
    List<KPosition> pointsToAdd = List.of(_kRenderingExtensions.createKPosition(LEFT, 0, 0.5f, TOP, 0, 0), _kRenderingExtensions.createKPosition(RIGHT, 0, 0, BOTTOM, 0, 0), _kRenderingExtensions.createKPosition(LEFT, 0, 0, BOTTOM, 0, 0));
    figure.getPoints().addAll(pointsToAdd);
    // Add text to the action figure
    KText textToAdd = _kContainerRenderingExtensions.addText(figure, text);
    _kRenderingExtensions.setFontSize(textToAdd, 8);
    _linguaFrancaStyleExtensions.noSelectionStyle(textToAdd);
    DiagramSyntheses.suppressSelectability(textToAdd);
    _kRenderingExtensions.setPointPlacementData(textToAdd, _kRenderingExtensions.LEFT, 0, 0.5f, _kRenderingExtensions.TOP, (size * 0.15f), 0.5f, _kRenderingExtensions.H_CENTRAL, _kRenderingExtensions.V_CENTRAL, 0, 0, size, size);
    // Add input port
    KPort in = _kPortExtensions.createPort();
    node.getPorts().add(in);
    in.setSize(0, 0);
    DiagramSyntheses.setLayoutOption(in, CoreOptions.PORT_SIDE, PortSide.WEST);
    DiagramSyntheses.setLayoutOption(in, CoreOptions.PORT_BORDER_OFFSET, -size / ((double) 4));
    // Add output port
    KPort out = _kPortExtensions.createPort();
    node.getPorts().add(out);
    DiagramSyntheses.setLayoutOption(out, CoreOptions.PORT_SIDE, PortSide.EAST);
    DiagramSyntheses.setLayoutOption(out, CoreOptions.PORT_BORDER_OFFSET, -size / ((double) 4));
    return new Pair<KPort, KPort>(in, out);
}
Also used : KPolygon(de.cau.cs.kieler.klighd.krendering.KPolygon) KText(de.cau.cs.kieler.klighd.krendering.KText) KPort(de.cau.cs.kieler.klighd.kgraph.KPort) KPosition(de.cau.cs.kieler.klighd.krendering.KPosition) Pair(org.eclipse.xtext.xbase.lib.Pair)

Example 13 with KText

use of de.cau.cs.kieler.klighd.krendering.KText in project lingua-franca by lf-lang.

the class LinguaFrancaShapeExtensions method addReactionFigure.

/**
 * Creates the visual representation of a reaction node
 */
public KPolygon addReactionFigure(KNode node, ReactionInstance reaction) {
    int minHeight = 22;
    int minWidth = 45;
    ReactorInstance reactor = reaction.getParent();
    _kNodeExtensions.setMinimalNodeSize(node, minWidth, minHeight);
    // Create base shape
    KPolygon baseShape = _kRenderingExtensions.addPolygon(node);
    associateWith(baseShape, reaction);
    _kRenderingExtensions.setLineWidth(baseShape, 1);
    _kRenderingExtensions.setForeground(baseShape, Colors.GRAY_45);
    _kRenderingExtensions.setBackground(baseShape, Colors.GRAY_65);
    _linguaFrancaStyleExtensions.boldLineSelectionStyle(baseShape);
    baseShape.getPoints().addAll(List.of(_kRenderingExtensions.createKPosition(LEFT, 0, 0, TOP, 0, 0), _kRenderingExtensions.createKPosition(RIGHT, REACTION_POINTINESS, 0, TOP, 0, 0), _kRenderingExtensions.createKPosition(RIGHT, 0, 0, TOP, 0, 0.5f), _kRenderingExtensions.createKPosition(RIGHT, REACTION_POINTINESS, 0, BOTTOM, 0, 0), _kRenderingExtensions.createKPosition(LEFT, 0, 0, BOTTOM, 0, 0), _kRenderingExtensions.createKPosition(LEFT, REACTION_POINTINESS, 0, BOTTOM, 0, 0.5f)));
    IterableExtensions.head(baseShape.getStyles()).setModifierId(ReactionPortAdjustment.ID);
    KRectangle contentContainer = _kContainerRenderingExtensions.addRectangle(baseShape);
    associateWith(contentContainer, reaction);
    _kRenderingExtensions.setInvisible(contentContainer, true);
    _kRenderingExtensions.<KRectangle>setPointPlacementData(contentContainer, _kRenderingExtensions.LEFT, REACTION_POINTINESS, 0, _kRenderingExtensions.TOP, 0, 0, _kRenderingExtensions.H_LEFT, _kRenderingExtensions.V_TOP, REACTION_POINTINESS, 0, minWidth - REACTION_POINTINESS * 2, minHeight);
    _kContainerRenderingExtensions.setGridPlacement(contentContainer, 1);
    if (reactor.reactions.size() > 1) {
        KText textToAdd = _kContainerRenderingExtensions.addText(contentContainer, Integer.toString(reactor.reactions.indexOf(reaction) + 1));
        _kRenderingExtensions.setFontBold(textToAdd, true);
        _linguaFrancaStyleExtensions.noSelectionStyle(textToAdd);
        DiagramSyntheses.suppressSelectability(textToAdd);
    }
    // optional reaction level
    if (getBooleanValue(LinguaFrancaSynthesis.SHOW_REACTION_LEVEL)) {
        // then some reactions will have level -1.
        try {
            String levels = IterableExtensions.join(reaction.getLevels(), ", ");
            KText levelsText = _kContainerRenderingExtensions.addText(contentContainer, ("level: " + levels));
            _kRenderingExtensions.setFontBold(levelsText, false);
            _linguaFrancaStyleExtensions.noSelectionStyle(levelsText);
            DiagramSyntheses.suppressSelectability(levelsText);
        } catch (Exception ex) {
        // If the graph has cycles, the above fails. Continue without showing levels.
        }
    }
    // optional code content
    boolean hasCode = getBooleanValue(LinguaFrancaSynthesis.SHOW_REACTION_CODE) && !StringExtensions.isNullOrEmpty(reaction.getDefinition().getCode().getBody());
    if (hasCode) {
        KText hasCodeText = _kContainerRenderingExtensions.addText(contentContainer, _utilityExtensions.trimCode(reaction.getDefinition().getCode()));
        associateWith(hasCodeText, reaction);
        _kRenderingExtensions.setFontSize(hasCodeText, 6);
        _kRenderingExtensions.setFontName(hasCodeText, KlighdConstants.DEFAULT_MONOSPACE_FONT_NAME);
        _linguaFrancaStyleExtensions.noSelectionStyle(hasCodeText);
        _kRenderingExtensions.setHorizontalAlignment(hasCodeText, HorizontalAlignment.LEFT);
        _kRenderingExtensions.setVerticalAlignment(hasCodeText, VerticalAlignment.TOP);
        setGridPlacementDataFromPointToPoint(hasCodeText, _kRenderingExtensions.LEFT, 5, 0, _kRenderingExtensions.TOP, 5, 0, _kRenderingExtensions.RIGHT, 5, 0, _kRenderingExtensions.BOTTOM, 5, 0);
    }
    if (reaction.declaredDeadline != null) {
        boolean hasDeadlineCode = getBooleanValue(LinguaFrancaSynthesis.SHOW_REACTION_CODE) && !StringExtensions.isNullOrEmpty(reaction.getDefinition().getDeadline().getCode().getBody());
        if (hasCode || hasDeadlineCode) {
            KPolyline line = _kContainerRenderingExtensions.addHorizontalLine(contentContainer, 0);
            setGridPlacementDataFromPointToPoint(line, _kRenderingExtensions.LEFT, 5, 0, _kRenderingExtensions.TOP, 3, 0, _kRenderingExtensions.RIGHT, 5, 0, _kRenderingExtensions.BOTTOM, 6, 0);
        }
        // delay with stopwatch
        KRectangle labelContainer = _kContainerRenderingExtensions.addRectangle(contentContainer);
        _kRenderingExtensions.setInvisible(labelContainer, true);
        KRendering placement = setGridPlacementDataFromPointToPoint(labelContainer, _kRenderingExtensions.LEFT, hasDeadlineCode ? 0 : -REACTION_POINTINESS * 0.5f, 0, _kRenderingExtensions.TOP, 0, reactor.reactions.size() > 1 || hasCode || hasDeadlineCode ? 0 : 0.5f, _kRenderingExtensions.RIGHT, 0, 0, _kRenderingExtensions.BOTTOM, 0, 0);
        _kRenderingExtensions.setHorizontalAlignment(placement, HorizontalAlignment.LEFT);
        KRectangle stopWatchFigure = addStopwatchFigure(labelContainer);
        _kRenderingExtensions.setLeftTopAlignedPointPlacementData(stopWatchFigure, 0, 0, 0, 0);
        KText stopWatchText = _kContainerRenderingExtensions.addText(labelContainer, reaction.declaredDeadline.maxDelay.toString());
        associateWith(stopWatchText, reaction.getDefinition().getDeadline().getDelay());
        _kRenderingExtensions.setForeground(stopWatchText, Colors.BROWN);
        _kRenderingExtensions.setFontBold(stopWatchText, true);
        _kRenderingExtensions.setFontSize(stopWatchText, 7);
        _linguaFrancaStyleExtensions.underlineSelectionStyle(stopWatchText);
        _kRenderingExtensions.setLeftTopAlignedPointPlacementData(stopWatchText, 15, 0, 0, 0);
        // optional code content
        if (hasDeadlineCode) {
            KText contentContainerText = _kContainerRenderingExtensions.addText(contentContainer, _utilityExtensions.trimCode(reaction.getDefinition().getDeadline().getCode()));
            associateWith(contentContainerText, reaction.deadline);
            _kRenderingExtensions.setForeground(contentContainerText, Colors.BROWN);
            _kRenderingExtensions.setFontSize(contentContainerText, 6);
            _kRenderingExtensions.setFontName(contentContainerText, KlighdConstants.DEFAULT_MONOSPACE_FONT_NAME);
            setGridPlacementDataFromPointToPoint(contentContainerText, _kRenderingExtensions.LEFT, 5, 0, _kRenderingExtensions.TOP, 0, 0, _kRenderingExtensions.RIGHT, 5, 0, _kRenderingExtensions.BOTTOM, 5, 0);
            _kRenderingExtensions.setHorizontalAlignment(contentContainerText, HorizontalAlignment.LEFT);
            _linguaFrancaStyleExtensions.noSelectionStyle(contentContainerText);
        }
    }
    return baseShape;
}
Also used : KPolygon(de.cau.cs.kieler.klighd.krendering.KPolygon) KText(de.cau.cs.kieler.klighd.krendering.KText) ReactorInstance(org.lflang.generator.ReactorInstance) KRendering(de.cau.cs.kieler.klighd.krendering.KRendering) KPolyline(de.cau.cs.kieler.klighd.krendering.KPolyline) KRectangle(de.cau.cs.kieler.klighd.krendering.KRectangle)

Example 14 with KText

use of de.cau.cs.kieler.klighd.krendering.KText in project lingua-franca by lf-lang.

the class LinguaFrancaShapeExtensions method addMainReactorFigure.

/**
 * Creates the main reactor frame.
 */
public KRoundedRectangle addMainReactorFigure(KNode node, ReactorInstance reactorInstance, String text) {
    int padding = getBooleanValue(LinguaFrancaSynthesis.SHOW_HYPERLINKS) ? 8 : 6;
    KRoundedRectangle figure = _kRenderingExtensions.addRoundedRectangle(node, 8, 8, 1);
    _kContainerRenderingExtensions.setGridPlacement(figure, 1);
    _kRenderingExtensions.setLineWidth(figure, 1);
    _kRenderingExtensions.setForeground(figure, Colors.GRAY);
    _kRenderingExtensions.setBackground(figure, Colors.WHITE);
    _linguaFrancaStyleExtensions.boldLineSelectionStyle(figure);
    // Create parent container
    KRectangle parentContainer = _kContainerRenderingExtensions.addRectangle(figure);
    _kRenderingExtensions.setInvisible(parentContainer, true);
    setGridPlacementDataFromPointToPoint(parentContainer, LEFT, padding, 0, TOP, padding, 0, RIGHT, padding, 0, BOTTOM, 4, 0);
    // Create child container
    KRectangle childContainer = _kContainerRenderingExtensions.addRectangle(parentContainer);
    _kRenderingExtensions.setInvisible(childContainer, true);
    _kRenderingExtensions.setPointPlacementData(childContainer, _kRenderingExtensions.LEFT, 0, 0.5f, _kRenderingExtensions.TOP, 0, 0.5f, _kRenderingExtensions.H_CENTRAL, _kRenderingExtensions.V_CENTRAL, 0, 0, 0, 0);
    KGridPlacement placement = _kContainerRenderingExtensions.setGridPlacement(childContainer, 1);
    // Add text to the child container
    KText childText = _kContainerRenderingExtensions.addText(childContainer, text);
    DiagramSyntheses.suppressSelectability(childText);
    _linguaFrancaStyleExtensions.underlineSelectionStyle(childText);
    if (reactorInstance.reactorDefinition.isFederated()) {
        KContainerRendering cloudIcon = _linguaFrancaStyleExtensions.addCloudIcon(childContainer);
        setGridPlacementDataFromPointToPoint(cloudIcon, LEFT, 3, 0, TOP, 0, 0, RIGHT, 0, 0, BOTTOM, 0, 0);
        placement.setNumColumns(2);
        if (reactorInstance.reactorDefinition.getHost() != null && getBooleanValue(LinguaFrancaSynthesis.SHOW_REACTOR_HOST)) {
            KText hostNameText = _kContainerRenderingExtensions.addText(childContainer, _utilityExtensions.toText(reactorInstance.reactorDefinition.getHost()));
            DiagramSyntheses.suppressSelectability(hostNameText);
            _linguaFrancaStyleExtensions.underlineSelectionStyle(hostNameText);
            setGridPlacementDataFromPointToPoint(hostNameText, LEFT, 3, 0, TOP, 0, 0, RIGHT, 0, 0, BOTTOM, 0, 0);
            placement.setNumColumns(3);
        }
    }
    return figure;
}
Also used : KText(de.cau.cs.kieler.klighd.krendering.KText) KContainerRendering(de.cau.cs.kieler.klighd.krendering.KContainerRendering) KRoundedRectangle(de.cau.cs.kieler.klighd.krendering.KRoundedRectangle) KGridPlacement(de.cau.cs.kieler.klighd.krendering.KGridPlacement) KRectangle(de.cau.cs.kieler.klighd.krendering.KRectangle)

Example 15 with KText

use of de.cau.cs.kieler.klighd.krendering.KText in project lingua-franca by lf-lang.

the class ModeDiagrams method handleModes.

public void handleModes(List<KNode> nodes, ReactorInstance reactor) {
    if (!reactor.modes.isEmpty()) {
        var modeNodes = new LinkedHashMap<ModeInstance, KNode>();
        var modeDefinitionMap = new LinkedHashMap<Mode, ModeInstance>();
        for (ModeInstance mode : reactor.modes) {
            var node = _kNodeExtensions.createNode();
            associateWith(node, mode.getDefinition());
            NamedInstanceUtil.linkInstance(node, mode);
            _utilityExtensions.setID(node, mode.uniqueID());
            modeNodes.put(mode, node);
            modeDefinitionMap.put(mode.getDefinition(), mode);
            if (mode.isInitial()) {
                DiagramSyntheses.setLayoutOption(node, LayeredOptions.LAYERING_LAYER_CONSTRAINT, LayerConstraint.FIRST);
            }
            DiagramSyntheses.setLayoutOption(node, LayeredOptions.CROSSING_MINIMIZATION_SEMI_INTERACTIVE, true);
            var expansionState = MemorizingExpandCollapseAction.getExpansionState(mode);
            DiagramSyntheses.setLayoutOption(node, KlighdProperties.EXPAND, expansionState != null ? expansionState : !this.getBooleanValue(INITIALLY_COLLAPSE_MODES));
            // Expanded Rectangle
            var expandFigure = addModeFigure(node, mode, true);
            expandFigure.setProperty(KlighdProperties.EXPANDED_RENDERING, true);
            _kRenderingExtensions.addDoubleClickAction(expandFigure, MemorizingExpandCollapseAction.ID);
            if (getBooleanValue(LinguaFrancaSynthesis.SHOW_HYPERLINKS)) {
                // Collapse button
                KText textButton = _linguaFrancaShapeExtensions.addTextButton(expandFigure, LinguaFrancaSynthesis.TEXT_HIDE_ACTION);
                _kRenderingExtensions.to(_kRenderingExtensions.from(_kRenderingExtensions.setGridPlacementData(textButton), _kRenderingExtensions.LEFT, 8, 0, _kRenderingExtensions.TOP, 0, 0), _kRenderingExtensions.RIGHT, 8, 0, _kRenderingExtensions.BOTTOM, 0, 0);
                _kRenderingExtensions.addSingleClickAction(textButton, MemorizingExpandCollapseAction.ID);
                _kRenderingExtensions.addDoubleClickAction(textButton, MemorizingExpandCollapseAction.ID);
            }
            _kContainerRenderingExtensions.addChildArea(expandFigure);
            // Collapse Rectangle
            var collapseFigure = addModeFigure(node, mode, false);
            collapseFigure.setProperty(KlighdProperties.COLLAPSED_RENDERING, true);
            if (this.hasContent(mode)) {
                _kRenderingExtensions.addDoubleClickAction(collapseFigure, MemorizingExpandCollapseAction.ID);
                if (getBooleanValue(LinguaFrancaSynthesis.SHOW_HYPERLINKS)) {
                    // Expand button
                    KText textButton = _linguaFrancaShapeExtensions.addTextButton(collapseFigure, LinguaFrancaSynthesis.TEXT_SHOW_ACTION);
                    _kRenderingExtensions.to(_kRenderingExtensions.from(_kRenderingExtensions.setGridPlacementData(textButton), _kRenderingExtensions.LEFT, 8, 0, _kRenderingExtensions.TOP, 0, 0), _kRenderingExtensions.RIGHT, 8, 0, _kRenderingExtensions.BOTTOM, 8, 0);
                    _kRenderingExtensions.addSingleClickAction(textButton, MemorizingExpandCollapseAction.ID);
                    _kRenderingExtensions.addDoubleClickAction(textButton, MemorizingExpandCollapseAction.ID);
                }
            }
        }
        var modeChildren = HashMultimap.<ModeInstance, KNode>create();
        var nodeModes = new HashMap<KNode, ModeInstance>();
        for (var node : nodes) {
            var instance = NamedInstanceUtil.getLinkedInstance(node);
            if (instance == null && node.getProperty(CoreOptions.COMMENT_BOX)) {
                var firstEdge = IterableExtensions.<KEdge>head(node.getOutgoingEdges());
                if (firstEdge != null && firstEdge.getTarget() != null) {
                    instance = NamedInstanceUtil.getLinkedInstance(firstEdge.getTarget());
                }
            }
            if (instance != null) {
                var mode = instance.getMode(true);
                modeChildren.put(mode, node);
                nodeModes.put(node, mode);
            } else {
                modeChildren.put(null, node);
            }
        }
        var modeContainer = _kNodeExtensions.createNode();
        modeContainer.getChildren().addAll(modeNodes.values());
        var fig = addModeContainerFigure(modeContainer);
        _kRenderingExtensions.addDoubleClickAction(fig, MemorizingExpandCollapseAction.ID);
        if (modeChildren.get(null).isEmpty()) {
            _kRenderingExtensions.setInvisible(fig, true);
            DiagramSyntheses.setLayoutOption(modeContainer, CoreOptions.PADDING, new ElkPadding());
        }
        DiagramSyntheses.setLayoutOption(modeContainer, CoreOptions.NODE_SIZE_CONSTRAINTS, SizeConstraint.minimumSizeWithPorts());
        DiagramSyntheses.setLayoutOption(modeContainer, CoreOptions.EDGE_ROUTING, EdgeRouting.SPLINES);
        DiagramSyntheses.setLayoutOption(modeContainer, CoreOptions.DIRECTION, Direction.DOWN);
        DiagramSyntheses.setLayoutOption(modeContainer, CoreOptions.PORT_CONSTRAINTS, PortConstraints.FIXED_ORDER);
        var modeContainerPorts = new HashMap<KPort, KPort>();
        for (var mode : ListExtensions.reverseView(reactor.modes)) {
            var modeNode = modeNodes.get(mode);
            var edges = new HashSet<KEdge>();
            // add children
            for (var child : modeChildren.get(mode)) {
                nodes.remove(child);
                modeNode.getChildren().add(child);
                edges.addAll(child.getIncomingEdges());
                edges.addAll(child.getOutgoingEdges());
            }
            // add transitions
            var representedTargets = new HashSet<Pair<ModeInstance, ModeInstance.ModeTransitionType>>();
            for (var transition : ListExtensions.reverseView(mode.transitions)) {
                if (!representedTargets.contains(new Pair<ModeInstance, ModeInstance.ModeTransitionType>(transition.target, transition.type))) {
                    var edge = _kEdgeExtensions.createEdge();
                    edge.setSource(modeNode);
                    edge.setTarget(modeNodes.get(transition.target));
                    addTransitionFigure(edge, transition);
                    if (getBooleanValue(SHOW_TRANSITION_LABELS)) {
                        associateWith(edge, transition.getDefinition());
                    } else {
                        // Bundle similar transitions
                        representedTargets.add(new Pair<ModeInstance, ModeInstance.ModeTransitionType>(transition.target, transition.type));
                    }
                }
            }
            // handle cross hierarchy edges
            var portCopies = new HashMap<KPort, KPort>();
            for (var edge : edges) {
                if (!edge.getProperty(CoreOptions.NO_LAYOUT)) {
                    var sourceNodeMode = nodeModes.get(edge.getSource());
                    if (sourceNodeMode == null) {
                        sourceNodeMode = nodeModes.get(edge.getSource().getParent());
                    }
                    var sourceIsInMode = sourceNodeMode != null;
                    var targetNodeMode = nodeModes.get(edge.getTarget());
                    if (targetNodeMode == null) {
                        targetNodeMode = nodeModes.get(edge.getTarget().getParent());
                    }
                    var targetIsInMode = targetNodeMode != null;
                    if (!sourceIsInMode || !targetIsInMode) {
                        var node = sourceIsInMode ? edge.getTarget() : edge.getSource();
                        var port = sourceIsInMode ? edge.getTargetPort() : edge.getSourcePort();
                        var isLocal = modeChildren.get(null).contains(node);
                        if (isLocal) {
                            // Add port to mode container
                            if (modeContainerPorts.containsKey(port)) {
                                node = modeContainer;
                                port = modeContainerPorts.get(port);
                            } else {
                                var containerPort = _kPortExtensions.createPort();
                                modeContainerPorts.put(port, containerPort);
                                modeContainer.getPorts().add(containerPort);
                                _kPortExtensions.setPortSize(containerPort, 8, 4);
                                KRectangle rect = _kRenderingExtensions.addRectangle(containerPort);
                                _kRenderingExtensions.setBackground(rect, Colors.BLACK);
                                DiagramSyntheses.setLayoutOption(containerPort, CoreOptions.PORT_BORDER_OFFSET, -4.0);
                                DiagramSyntheses.setLayoutOption(containerPort, CoreOptions.PORT_SIDE, sourceIsInMode ? PortSide.EAST : PortSide.WEST);
                                var source = _utilityExtensions.sourceElement(node);
                                var label = "";
                                if (source instanceof Action) {
                                    label = ((Action) source).getName();
                                } else if (source instanceof Timer) {
                                    label = ((Timer) source).getName();
                                }
                                _kLabelExtensions.addOutsidePortLabel(containerPort, label, 8);
                                // new connection
                                var copy = EcoreUtil.copy(edge);
                                if (sourceIsInMode) {
                                    copy.setSource(modeContainer);
                                    copy.setSourcePort(containerPort);
                                    copy.setTarget(edge.getTarget());
                                } else {
                                    copy.setTarget(modeContainer);
                                    copy.setTargetPort(containerPort);
                                    copy.setSource(edge.getSource());
                                }
                                node = modeContainer;
                                port = containerPort;
                            }
                        }
                        // Duplicate port
                        if (!portCopies.containsKey(port)) {
                            var copy = EcoreUtil.copy(port);
                            portCopies.put(port, copy);
                            var dummyNode = _kNodeExtensions.createNode();
                            var newID = mode.uniqueID() + "_";
                            if (!port.getLabels().isEmpty()) {
                                newID += IterableExtensions.head(port.getLabels()).getText();
                            }
                            _utilityExtensions.setID(dummyNode, newID);
                            _kRenderingExtensions.addInvisibleContainerRendering(dummyNode);
                            dummyNode.getPorts().add(copy);
                            DiagramSyntheses.setLayoutOption(dummyNode, LayeredOptions.LAYERING_LAYER_CONSTRAINT, port.getProperty(CoreOptions.PORT_SIDE) == PortSide.WEST ? LayerConstraint.FIRST : LayerConstraint.LAST);
                            modeNode.getChildren().add(dummyNode);
                        }
                        var newPort = portCopies.get(port);
                        if (sourceIsInMode) {
                            edge.setTarget(newPort.getNode());
                            edge.setTargetPort(newPort);
                        } else {
                            edge.setSource(newPort.getNode());
                            edge.setSourcePort(newPort);
                        }
                    }
                }
            }
        }
        nodes.add(modeContainer);
    }
}
Also used : ModeInstance(org.lflang.generator.ModeInstance) MemorizingExpandCollapseAction(org.lflang.diagram.synthesis.action.MemorizingExpandCollapseAction) Action(org.lflang.lf.Action) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) KEdge(de.cau.cs.kieler.klighd.kgraph.KEdge) KNode(de.cau.cs.kieler.klighd.kgraph.KNode) LinkedHashMap(java.util.LinkedHashMap) KRectangle(de.cau.cs.kieler.klighd.krendering.KRectangle) KText(de.cau.cs.kieler.klighd.krendering.KText) Timer(org.lflang.lf.Timer) ElkPadding(org.eclipse.elk.core.math.ElkPadding) HashSet(java.util.HashSet) ModeTransitionType(org.lflang.generator.ModeInstance.ModeTransitionType) Pair(org.eclipse.xtext.xbase.lib.Pair)

Aggregations

KText (de.cau.cs.kieler.klighd.krendering.KText)19 KContainerRendering (de.cau.cs.kieler.klighd.krendering.KContainerRendering)8 KRectangle (de.cau.cs.kieler.klighd.krendering.KRectangle)8 KPolygon (de.cau.cs.kieler.klighd.krendering.KPolygon)7 KPolyline (de.cau.cs.kieler.klighd.krendering.KPolyline)7 KLabel (de.cau.cs.kieler.klighd.kgraph.KLabel)6 KRoundedRectangle (de.cau.cs.kieler.klighd.krendering.KRoundedRectangle)6 ElkPadding (org.eclipse.elk.core.math.ElkPadding)6 KEdge (de.cau.cs.kieler.klighd.kgraph.KEdge)5 KNode (de.cau.cs.kieler.klighd.kgraph.KNode)5 KRendering (de.cau.cs.kieler.klighd.krendering.KRendering)5 KPort (de.cau.cs.kieler.klighd.kgraph.KPort)4 LayerConstraint (org.eclipse.elk.alg.layered.options.LayerConstraint)4 SizeConstraint (org.eclipse.elk.core.options.SizeConstraint)4 Pair (org.eclipse.xtext.xbase.lib.Pair)4 Iterables (com.google.common.collect.Iterables)3 Colors (de.cau.cs.kieler.klighd.krendering.Colors)3 HorizontalAlignment (de.cau.cs.kieler.klighd.krendering.HorizontalAlignment)3 KPosition (de.cau.cs.kieler.klighd.krendering.KPosition)3 LineStyle (de.cau.cs.kieler.klighd.krendering.LineStyle)3