Search in sources :

Example 6 with Dimension

use of org.osate.ge.graphics.Dimension in project osate2 by osate.

the class DiagramElementLayoutUtil method applyProperties.

/**
 * Sets the ELK properties of elements in the specified layout mapping based on the layout options.
 * @param layoutMapping
 */
private static void applyProperties(final DiagramNode rootDiagramNode, final LayoutMapping layoutMapping) {
    // Set the minimum node size based on the ports and their assigned sides.
    final IGraphElementVisitor minNodeSizeVisitor = element -> {
        if (element instanceof ElkNode) {
            final ElkNode n = (ElkNode) element;
            final double maxLabelWidth = n.getLabels().stream().mapToDouble(l -> l.getWidth()).max().orElse(0.0);
            final double labelHeightSum = n.getLabels().stream().mapToDouble(l -> l.getHeight()).sum();
            // Determine max width for ports on the left and right sides
            final double maxLeftPortWidth = n.getPorts().stream().filter(p -> p.getProperty(CoreOptions.PORT_SIDE) == PortSide.WEST).mapToDouble(p -> p.getWidth()).max().orElse(0.0);
            final double maxRightPortWidth = n.getPorts().stream().filter(p -> p.getProperty(CoreOptions.PORT_SIDE) == PortSide.EAST).mapToDouble(p -> p.getWidth()).max().orElse(0.0);
            final DiagramNode dn = (DiagramNode) layoutMapping.getGraphMap().get(n);
            double minWidth = 0;
            if (n.getProperty(CoreOptions.NODE_LABELS_PLACEMENT).contains(NodeLabelPlacement.H_CENTER)) {
                // Ensure the minimum width is such that the label can be centered without overlapping with ports.
                // This happens because ports are inside the node due to the PORT_BORDER_OFFSET and ELK centers the labels in the remaining space.
                final double widthForPorts = 2 * Math.max(maxLeftPortWidth, maxRightPortWidth);
                minWidth = Math.max(40, maxLabelWidth + widthForPorts + PORT_WIDTH_PADDING);
            } else {
                final double widthForPorts = maxLeftPortWidth + maxRightPortWidth + PORT_WIDTH_PADDING;
                minWidth = Math.max(40, Math.max(maxLabelWidth, widthForPorts));
            }
            double minHeight = Math.max(35, labelHeightSum);
            if (dn instanceof DiagramElement) {
                final DiagramElement de = ((DiagramElement) dn);
                // Special min height handling for initial modes
                final Graphic graphic = de.getGraphic();
                if (graphic instanceof AgeShape && !((AgeShape) graphic).isResizeable() && de.hasSize()) {
                    final Dimension dim = de.getSize();
                    minHeight = dim.height;
                    minWidth = dim.width;
                    // Adjust size constraints for fixed sized shapes which do not have contents.
                    if (n.getChildren().size() == 0 || n.getLabels().size() == 0 && n.getPorts().size() == 0) {
                        final EnumSet<SizeConstraint> nodeSizeConstraints = EnumSet.of(SizeConstraint.MINIMUM_SIZE);
                        n.setProperty(CoreOptions.NODE_SIZE_CONSTRAINTS, nodeSizeConstraints);
                    }
                }
                if (graphic instanceof ModeGraphic && ((ModeGraphic) graphic).isInitialMode) {
                    minHeight += ModeGraphic.INITIAL_MODE_AREA_HEIGHT;
                }
                // Special min size handling for elements shown as image
                final Style style = de.getStyle();
                if (style != null && Boolean.TRUE.equals(style.getShowAsImage())) {
                    final Dimension dim = ((DiagramElement) dn).getSize();
                    minHeight = dim.height;
                    minWidth = dim.width;
                }
            }
            // Increase min width and min height for top level nodes.
            if (dn != null && dn.getParent() instanceof AgeDiagram) {
                minWidth = Math.max(minWidth, 200);
                minHeight = Math.max(minHeight, 100);
            }
            n.setProperty(CoreOptions.NODE_SIZE_MINIMUM, new KVector(minWidth, minHeight));
        }
    };
    ElkUtil.applyVisitors(layoutMapping.getLayoutGraph(), minNodeSizeVisitor);
    // If the top level element has a size set, don't shrink it.
    if (rootDiagramNode instanceof DiagramElement) {
        final DiagramElement rootDiagramElement = (DiagramElement) rootDiagramNode;
        final ElkGraphElement rootGraphElement = layoutMapping.getGraphMap().inverse().get(rootDiagramNode);
        if (rootGraphElement != null && rootDiagramElement.hasSize() && DiagramElementPredicates.isResizeable(rootDiagramElement)) {
            final KVector minSize = rootGraphElement.getProperty(CoreOptions.NODE_SIZE_MINIMUM);
            final double newMinWidth = Math.max(rootDiagramElement.getWidth(), minSize == null ? 0.0 : minSize.x);
            final double newMinHeight = Math.max(rootDiagramElement.getHeight(), minSize == null ? 0.0 : minSize.y);
            rootGraphElement.setProperty(CoreOptions.NODE_SIZE_MINIMUM, new KVector(newMinWidth, newMinHeight));
        }
    }
}
Also used : CoreOptions(org.eclipse.elk.core.options.CoreOptions) ArrayListMultimap(com.google.common.collect.ArrayListMultimap) PortSide(org.eclipse.elk.core.options.PortSide) LayoutMapping(org.eclipse.elk.core.service.LayoutMapping) ElkNode(org.eclipse.elk.graph.ElkNode) ElkPort(org.eclipse.elk.graph.ElkPort) IGraphElementVisitor(org.eclipse.elk.core.util.IGraphElementVisitor) RecursiveGraphLayoutEngine(org.eclipse.elk.core.RecursiveGraphLayoutEngine) DockArea(org.osate.ge.internal.diagram.runtime.DockArea) IStatus(org.eclipse.core.runtime.IStatus) BusinessObjectContext(org.osate.ge.BusinessObjectContext) Graphic(org.osate.ge.graphics.Graphic) DiagramNodePredicates(org.osate.ge.internal.diagram.runtime.DiagramNodePredicates) StatusManager(org.eclipse.ui.statushandlers.StatusManager) IEditorPart(org.eclipse.ui.IEditorPart) EnumSet(java.util.EnumSet) Collection(java.util.Collection) Set(java.util.Set) Status(org.eclipse.core.runtime.Status) SizeConstraint(org.eclipse.elk.core.options.SizeConstraint) Point(org.osate.ge.graphics.Point) Collectors(java.util.stream.Collectors) DiagramElementUtil(org.osate.ge.internal.util.DiagramElementUtil) DockingPosition(org.osate.ge.DockingPosition) Objects(java.util.Objects) List(java.util.List) Stream(java.util.stream.Stream) ElkGraphElement(org.eclipse.elk.graph.ElkGraphElement) NodeLabelPlacement(org.eclipse.elk.core.options.NodeLabelPlacement) GraphicalEditorException(org.osate.ge.internal.GraphicalEditorException) ElkEdgeSection(org.eclipse.elk.graph.ElkEdgeSection) Entry(java.util.Map.Entry) Optional(java.util.Optional) ElkEdge(org.eclipse.elk.graph.ElkEdge) AgeConnection(org.osate.ge.graphics.internal.AgeConnection) DiagramNode(org.osate.ge.internal.diagram.runtime.DiagramNode) DiagramElement(org.osate.ge.internal.diagram.runtime.DiagramElement) Dimension(org.osate.ge.graphics.Dimension) ElkGraphPackage(org.eclipse.elk.graph.ElkGraphPackage) ModeGraphic(org.osate.ge.graphics.internal.ModeGraphic) DiagramModification(org.osate.ge.internal.diagram.runtime.DiagramModification) HashSet(java.util.HashSet) ElkUtil(org.eclipse.elk.core.util.ElkUtil) Style(org.osate.ge.graphics.Style) InternalDiagramEditor(org.osate.ge.internal.ui.editor.InternalDiagramEditor) Lists(com.google.common.collect.Lists) ImmutableList(com.google.common.collect.ImmutableList) AgeShape(org.osate.ge.graphics.internal.AgeShape) LinkedList(java.util.LinkedList) Activator(org.osate.ge.internal.Activator) DiagramElementPredicates(org.osate.ge.internal.diagram.runtime.DiagramElementPredicates) ElkLabel(org.eclipse.elk.graph.ElkLabel) KVector(org.eclipse.elk.core.math.KVector) Label(org.osate.ge.graphics.internal.Label) BasicProgressMonitor(org.eclipse.elk.core.util.BasicProgressMonitor) ElkShape(org.eclipse.elk.graph.ElkShape) Adapters(org.eclipse.core.runtime.Adapters) AgeDiagram(org.osate.ge.internal.diagram.runtime.AgeDiagram) AgeDiagramUtil(org.osate.ge.internal.diagram.runtime.AgeDiagramUtil) Comparator(java.util.Comparator) StyleProvider(org.osate.ge.internal.diagram.runtime.styling.StyleProvider) Collections(java.util.Collections) StyleCalculator(org.osate.ge.internal.diagram.runtime.styling.StyleCalculator) DiagramNode(org.osate.ge.internal.diagram.runtime.DiagramNode) ElkNode(org.eclipse.elk.graph.ElkNode) Graphic(org.osate.ge.graphics.Graphic) ModeGraphic(org.osate.ge.graphics.internal.ModeGraphic) EnumSet(java.util.EnumSet) ModeGraphic(org.osate.ge.graphics.internal.ModeGraphic) AgeShape(org.osate.ge.graphics.internal.AgeShape) Dimension(org.osate.ge.graphics.Dimension) DiagramElement(org.osate.ge.internal.diagram.runtime.DiagramElement) AgeDiagram(org.osate.ge.internal.diagram.runtime.AgeDiagram) Style(org.osate.ge.graphics.Style) KVector(org.eclipse.elk.core.math.KVector) ElkGraphElement(org.eclipse.elk.graph.ElkGraphElement) IGraphElementVisitor(org.eclipse.elk.core.util.IGraphElementVisitor)

Example 7 with Dimension

use of org.osate.ge.graphics.Dimension in project osate2 by osate.

the class DiagramElementLayoutUtil method getPortAnchorOffset.

/**
 * Gets the position of a port anchor relative to another point
 * @param element the docked element for which to get the anchor offset
 * @param nonGroupDockArea dock are of the group. Must not be group. For grouped docked elements,
 * it should be the first non group dock area in the hierarchy.
 * @param referencePosition is the absolute position to use as the reference point for the returned position.
 * @param layoutInfoProvider the layout info provider to use to calculate sized.
 * @return the position of the anchor relative to the specified point.
 */
private static Point getPortAnchorOffset(final DiagramElement element, final DockArea nonGroupDockArea, final Point referencePosition, final LayoutInfoProvider layoutInfoProvider) {
    // Find offset based on orientation and nature of the diagram element
    final Dimension labelsSize = layoutInfoProvider.getDockedElementLabelsSize(element);
    final double anchorOffset;
    if (DiagramElementPredicates.isResizeable(element) && element.hasSize()) {
        // Feature groups
        anchorOffset = nonGroupDockArea.isLeftOrRight() ? element.getHeight() - labelsSize.height : element.getWidth() - labelsSize.width;
    } else {
        anchorOffset = layoutInfoProvider.getPortGraphicSize(element).height;
    }
    // Find the position of the element
    final Point elementAbsPosition = getAbsolutePosition(element);
    final Point anchorPosition;
    if (nonGroupDockArea == DockArea.LEFT) {
        anchorPosition = new Point(elementAbsPosition.x - referencePosition.x, elementAbsPosition.y - referencePosition.y + labelsSize.height + anchorOffset / 2.0);
    } else if (nonGroupDockArea == DockArea.RIGHT) {
        anchorPosition = new Point(elementAbsPosition.x - referencePosition.x + element.getWidth(), elementAbsPosition.y - referencePosition.y + labelsSize.height + anchorOffset / 2.0);
    } else if (nonGroupDockArea == DockArea.TOP) {
        anchorPosition = new Point(elementAbsPosition.x - referencePosition.x + labelsSize.width + anchorOffset / 2.0, elementAbsPosition.y - referencePosition.y);
    } else {
        // BOTTOM
        anchorPosition = new Point(elementAbsPosition.x - referencePosition.x + labelsSize.width + anchorOffset / 2.0, elementAbsPosition.y - referencePosition.y + element.getHeight());
    }
    return anchorPosition;
}
Also used : Dimension(org.osate.ge.graphics.Dimension) Point(org.osate.ge.graphics.Point)

Example 8 with Dimension

use of org.osate.ge.graphics.Dimension in project osate2 by osate.

the class DiagramElementLayoutUtil method applyShapeLayout.

private static void applyShapeLayout(final LayoutMapping mapping, final DiagramModification m) {
    // Modify shapes
    for (Entry<ElkGraphElement, Object> e : mapping.getGraphMap().entrySet()) {
        final ElkGraphElement elkElement = e.getKey();
        final Object mappedValue = e.getValue();
        final boolean isTopLevelElement = isTopLevel(elkElement);
        if (!(elkElement instanceof ElkShape)) {
            continue;
        }
        final ElkShape elkShape = (ElkShape) elkElement;
        if (!(mappedValue instanceof DiagramElement)) {
            continue;
        }
        final DiagramElement de = (DiagramElement) mappedValue;
        if (!(de.getGraphic() instanceof AgeShape)) {
            continue;
        }
        if (de.getGraphic() instanceof Label) {
            continue;
        }
        // Set Position. Don't set the position of top level elements
        if (!isTopLevelElement && DiagramElementPredicates.isMoveableShape(de)) {
            // Determine position for the element
            double x = elkShape.getX();
            double y = elkShape.getY();
            // If the diagram element has a parent port, subtract the parent port position from the ELK port position to determine the relative position
            if (de.getDockArea() == DockArea.GROUP) {
                final ElkPort parentPort = (ElkPort) mapping.getGraphMap().inverse().get(de.getParent());
                if (parentPort != null) {
                    final PortSide side = parentPort.getProperty(CoreOptions.PORT_SIDE);
                    if (PortSide.SIDES_NORTH_SOUTH.contains(side)) {
                        x = elkShape.getX() - parentPort.getX();
                    } else if (PortSide.SIDES_EAST_WEST.contains(side)) {
                        y = elkShape.getY() - parentPort.getY();
                    } else {
                        throw new GraphicalEditorException("Unexpected side: " + side);
                    }
                }
            }
            DiagramElementLayoutUtil.moveElement(m, de, new Point(x, y));
            // Set the dock area
            if (de.getDockArea() != DockArea.GROUP && de.getDockArea() != null) {
                final DockArea newDockArea = PortSideUtil.getDockArea(elkShape.getProperty(CoreOptions.PORT_SIDE));
                if (newDockArea != null) {
                    m.setDockArea(de, newDockArea);
                }
            }
        }
        // Set the size
        if (DiagramElementPredicates.isResizeable(de)) {
            m.setSize(de, new Dimension(elkShape.getWidth(), elkShape.getHeight()));
        }
    }
}
Also used : ElkPort(org.eclipse.elk.graph.ElkPort) AgeShape(org.osate.ge.graphics.internal.AgeShape) ElkLabel(org.eclipse.elk.graph.ElkLabel) Label(org.osate.ge.graphics.internal.Label) Point(org.osate.ge.graphics.Point) Dimension(org.osate.ge.graphics.Dimension) DiagramElement(org.osate.ge.internal.diagram.runtime.DiagramElement) ElkShape(org.eclipse.elk.graph.ElkShape) DockArea(org.osate.ge.internal.diagram.runtime.DockArea) PortSide(org.eclipse.elk.core.options.PortSide) ElkGraphElement(org.eclipse.elk.graph.ElkGraphElement) GraphicalEditorException(org.osate.ge.internal.GraphicalEditorException)

Example 9 with Dimension

use of org.osate.ge.graphics.Dimension in project osate2 by osate.

the class ElkGraphBuilder method createPort.

/**
 * @param parent
 * @param side
 * @param dockedElement
 * @param portBorderOffset additional offset from the border. Used to set the ELK port border offset for nested ports.
 * @param mapping
 * @return
 */
private ElkPort createPort(final ElkNode parent, final PortSide side, final DiagramElement dockedElement, final double portBorderOffset, final LayoutMapping mapping) {
    final List<DiagramElement> dockedChildren = getDockedChildren(dockedElement);
    final Dimension untransformedGraphicSize = layoutInfoProvider.getPortGraphicSize(dockedElement);
    final Dimension transformedGraphicSize = transformDimension(untransformedGraphicSize, side);
    final Dimension untransformedLabelsSize = layoutInfoProvider.getDockedElementLabelsSize(dockedElement);
    final Dimension transformedLabelsSize = transformDimension(untransformedLabelsSize, side);
    // Create child ports and sort them by the size of the dimension parallel to the docked side
    final List<ElkPort> childPorts = dockedChildren.stream().map(ce -> createPort(parent, side, ce, getOrthogonalSize(transformedGraphicSize, side), mapping)).sorted((p1, p2) -> Double.compare(getSize(p1, side), getSize(p1, side))).collect(Collectors.toCollection(ArrayList::new));
    // If the port has child ports, then we assume it is a feature group.
    // The child ports are split into two bins and positioned such that they do not overlap the center of the feature group.
    // The parent port will be sized accordingly.
    final double maxChildBinSize;
    if (childPorts.size() > 0) {
        // Split the ports into two lists which have roughly equal heights/widths(depending on the docked side)
        double[] binSize = { 0.0, 0.0 };
        @SuppressWarnings("unchecked") final List<ElkPort>[] binLists = new ArrayList[] { new ArrayList<>(), new ArrayList<>() };
        for (final ElkPort childPort : childPorts) {
            final double size = getSize(childPort, side);
            final int binIndex = binSize[0] <= binSize[1] ? 0 : 1;
            binLists[binIndex].add(childPort);
            binSize[binIndex] += size + paddingSize;
        }
        // Determine the total size of the feature
        maxChildBinSize = Math.max(binSize[0], binSize[1]);
        // Set the position of the port relative to its parent because the size and position of the parent will be selected after its children are sized.
        for (int i = 0; i < 2; i++) {
            double childPosition = transformedLabelsSize.height + i * (maxChildBinSize + transformedGraphicSize.height);
            for (final ElkPort childPort : binLists[i]) {
                setPositionAlongSide(childPort, side, childPosition);
                childPosition += getSize(childPort, side) + paddingSize;
            }
        }
    } else {
        maxChildBinSize = 0.0;
    }
    // Size the parent port based on the bin size.
    final double newGraphicSize = 2.0 * maxChildBinSize + transformedGraphicSize.height;
    final double totalSize = transformedLabelsSize.height + newGraphicSize;
    final ElkPort newPort = ElkGraphUtil.createPort(parent);
    mapping.getGraphMap().put(newPort, dockedElement);
    newPort.setProperty(CoreOptions.PORT_SIDE, side);
    // Determine max orthogonal size of children
    double maxChildOrthogonalSize = 0;
    for (final ElkPort childPort : childPorts) {
        maxChildOrthogonalSize = Math.max(maxChildOrthogonalSize, getOrthogonalSize(childPort, side));
    }
    // Determine size and position
    final Dimension newSize;
    if (DiagramElementPredicates.isResizeable(dockedElement)) {
        newSize = new Dimension(Math.max(untransformedLabelsSize.width, maxChildOrthogonalSize + getOrthogonalSize(transformedGraphicSize, side)), totalSize);
    } else {
        newSize = new Dimension(Math.max(untransformedLabelsSize.width, untransformedGraphicSize.width), transformedLabelsSize.height + untransformedGraphicSize.height);
    }
    // final graph.
    if (omitNestedPorts) {
        for (final ElkPort childPort : childPorts) {
            mapping.getGraphMap().remove(childPort);
            EcoreUtil.remove(childPort);
        }
    }
    final Dimension transformedNewSize = transformDimension(newSize, side);
    newPort.setWidth(transformedNewSize.width);
    newPort.setHeight(transformedNewSize.height);
    // Set port border offset
    if (PortSide.SIDES_NORTH_SOUTH.contains(side)) {
        newPort.setProperty(CoreOptions.PORT_BORDER_OFFSET, -newPort.getHeight() - portBorderOffset);
    } else {
        newPort.setProperty(CoreOptions.PORT_BORDER_OFFSET, -newPort.getWidth() - portBorderOffset);
    }
    // Set the port anchor based on where the actual graphic will be.
    final Dimension transformedPortAnchor = transformDimension(new Dimension(untransformedGraphicSize.width / 2, transformedLabelsSize.height + maxChildBinSize + untransformedGraphicSize.height / 2.0), side);
    newPort.setProperty(CoreOptions.PORT_ANCHOR, new KVector(transformedPortAnchor.width, transformedPortAnchor.height));
    return newPort;
}
Also used : CoreOptions(org.eclipse.elk.core.options.CoreOptions) DiagramElement(org.osate.ge.internal.diagram.runtime.DiagramElement) PortSide(org.eclipse.elk.core.options.PortSide) Dimension(org.osate.ge.graphics.Dimension) HashMap(java.util.HashMap) LayoutMapping(org.eclipse.elk.core.service.LayoutMapping) ElkNode(org.eclipse.elk.graph.ElkNode) ElkPort(org.eclipse.elk.graph.ElkPort) ArrayList(java.util.ArrayList) Style(org.osate.ge.graphics.Style) DockArea(org.osate.ge.internal.diagram.runtime.DockArea) ElkPadding(org.eclipse.elk.core.math.ElkPadding) Map(java.util.Map) AgeShape(org.osate.ge.graphics.internal.AgeShape) DiagramElementPredicates(org.osate.ge.internal.diagram.runtime.DiagramElementPredicates) HierarchyHandling(org.eclipse.elk.core.options.HierarchyHandling) EnumSet(java.util.EnumSet) PortConstraints(org.eclipse.elk.core.options.PortConstraints) ElkLabel(org.eclipse.elk.graph.ElkLabel) Predicate(java.util.function.Predicate) KVector(org.eclipse.elk.core.math.KVector) Collection(java.util.Collection) Label(org.osate.ge.graphics.internal.Label) SizeOptions(org.eclipse.elk.core.options.SizeOptions) EcoreUtil(org.eclipse.emf.ecore.util.EcoreUtil) SizeConstraint(org.eclipse.elk.core.options.SizeConstraint) Collectors(java.util.stream.Collectors) ElkConnectableShape(org.eclipse.elk.graph.ElkConnectableShape) DiagramElementUtil(org.osate.ge.internal.util.DiagramElementUtil) DockingPosition(org.osate.ge.DockingPosition) Objects(java.util.Objects) AgeDiagram(org.osate.ge.internal.diagram.runtime.AgeDiagram) List(java.util.List) ElkGraphElement(org.eclipse.elk.graph.ElkGraphElement) NodeLabelPlacement(org.eclipse.elk.core.options.NodeLabelPlacement) Direction(org.eclipse.elk.core.options.Direction) Entry(java.util.Map.Entry) Optional(java.util.Optional) ElkEdge(org.eclipse.elk.graph.ElkEdge) AgeConnection(org.osate.ge.graphics.internal.AgeConnection) ElkGraphUtil(org.eclipse.elk.graph.util.ElkGraphUtil) StyleProvider(org.osate.ge.internal.diagram.runtime.styling.StyleProvider) Collections(java.util.Collections) DiagramNode(org.osate.ge.internal.diagram.runtime.DiagramNode) ElkPort(org.eclipse.elk.graph.ElkPort) ArrayList(java.util.ArrayList) Dimension(org.osate.ge.graphics.Dimension) SizeConstraint(org.eclipse.elk.core.options.SizeConstraint) DiagramElement(org.osate.ge.internal.diagram.runtime.DiagramElement) ArrayList(java.util.ArrayList) List(java.util.List) KVector(org.eclipse.elk.core.math.KVector)

Example 10 with Dimension

use of org.osate.ge.graphics.Dimension in project osate2 by osate.

the class ElkGraphBuilder method createElkGraphElementsForConnections.

/**
 * Creates ELK edges for connection diagram nodes which are descendants of the specified node.
 * Even though the results of the ELK edge routing are not used, it is still important because it affects the placements of shapes.
 */
private void createElkGraphElementsForConnections(final DiagramNode dn, final LayoutMapping mapping) {
    for (final DiagramElement de : dn.getChildren()) {
        if (de.getGraphic() instanceof AgeConnection) {
            final AgeConnection connection = (AgeConnection) de.getGraphic();
            // Flow indicators are represented by a node in the container which has a port and an edge connecting that port to the starting element
            final ElkConnectableShape edgeStart = getConnectableShape(de.getStartElement(), mapping);
            ElkConnectableShape edgeEnd = null;
            if (connection.isFlowIndicator) {
                // Find the first undocked ancestor for the flow indicator
                final DiagramElement undockedContainer = DiagramElementUtil.getUndockedDiagramElement(de.getParent());
                if (undockedContainer == null) {
                    // Ignore the flow indicator if unable to find a containing element which isn't docked.
                    continue;
                }
                // Find the ELK shape for the ancestor
                final ElkConnectableShape endContainer = getConnectableShape(undockedContainer, mapping);
                if (!(endContainer instanceof ElkNode)) {
                    // Ignore the flow indicator if the container isn't a node.
                    continue;
                }
                // Create the node for the end of the flow indicator
                final ElkNode endNode = ElkGraphUtil.createNode((ElkNode) endContainer);
                endContainer.setDimensions(0, 0);
                endNode.setProperty(CoreOptions.NODE_SIZE_CONSTRAINTS, EnumSet.noneOf(SizeConstraint.class));
                endNode.setProperty(CoreOptions.NODE_SIZE_OPTIONS, EnumSet.noneOf(SizeOptions.class));
                // Create port
                final ElkPort endPort = ElkGraphUtil.createPort(endNode);
                endPort.setProperty(CoreOptions.PORT_SIDE, PortSide.WEST);
                endPort.setX(0);
                endPort.setY(0);
                endPort.setWidth(0);
                endPort.setHeight(0);
                edgeEnd = endPort;
            } else {
                edgeEnd = getConnectableShape(de.getEndElement(), mapping);
            }
            if (edgeStart != null && edgeEnd != null) {
                final ElkConnectableShape start = edgeStart;
                final ElkConnectableShape end = edgeEnd;
                boolean insideSelfLoopsYo = true;
                // An example of this sort of edge is a steady state state transition in the EMV2
                if (start == end) {
                    insideSelfLoopsYo = false;
                }
                final ElkEdge newEdge = ElkGraphUtil.createSimpleEdge(start, end);
                // Allow edges with the same start and end shape because they layout as intended.
                if (start == end && start instanceof ElkPort) {
                    continue;
                }
                // Ensure the edge has at least one section. Fixes NPE that can occur when laying out connections
                // with the same source and destination port.
                ElkGraphUtil.createEdgeSection(newEdge);
                newEdge.setProperty(CoreOptions.INSIDE_SELF_LOOPS_YO, insideSelfLoopsYo);
                mapping.getGraphMap().put(newEdge, de);
                createElkLabels(de, newEdge, mapping);
                // along with other edges
                if (connection.isFlowIndicator && newEdge.getLabels().isEmpty()) {
                    final ElkLabel spacingLabel = createElkLabel(newEdge, "<Spacing>", new Dimension(10, 10));
                    if (!layoutConnectionLabels) {
                        spacingLabel.setProperty(CoreOptions.NO_LAYOUT, true);
                    }
                }
            }
        }
        createElkGraphElementsForConnections(de, mapping);
    }
}
Also used : DiagramElement(org.osate.ge.internal.diagram.runtime.DiagramElement) AgeConnection(org.osate.ge.graphics.internal.AgeConnection) ElkNode(org.eclipse.elk.graph.ElkNode) SizeOptions(org.eclipse.elk.core.options.SizeOptions) ElkLabel(org.eclipse.elk.graph.ElkLabel) ElkPort(org.eclipse.elk.graph.ElkPort) Dimension(org.osate.ge.graphics.Dimension) ElkConnectableShape(org.eclipse.elk.graph.ElkConnectableShape) SizeConstraint(org.eclipse.elk.core.options.SizeConstraint) ElkEdge(org.eclipse.elk.graph.ElkEdge)

Aggregations

Dimension (org.osate.ge.graphics.Dimension)14 DiagramElement (org.osate.ge.internal.diagram.runtime.DiagramElement)9 Point (org.osate.ge.graphics.Point)5 AgeDiagram (org.osate.ge.internal.diagram.runtime.AgeDiagram)5 DiagramNode (org.osate.ge.internal.diagram.runtime.DiagramNode)5 ElkLabel (org.eclipse.elk.graph.ElkLabel)4 ElkPort (org.eclipse.elk.graph.ElkPort)4 DockArea (org.osate.ge.internal.diagram.runtime.DockArea)4 IStatus (org.eclipse.core.runtime.IStatus)3 Status (org.eclipse.core.runtime.Status)3 PortSide (org.eclipse.elk.core.options.PortSide)3 SizeConstraint (org.eclipse.elk.core.options.SizeConstraint)3 ElkEdge (org.eclipse.elk.graph.ElkEdge)3 ElkGraphElement (org.eclipse.elk.graph.ElkGraphElement)3 ElkNode (org.eclipse.elk.graph.ElkNode)3 IEditorPart (org.eclipse.ui.IEditorPart)3 AgeConnection (org.osate.ge.graphics.internal.AgeConnection)3 AgeShape (org.osate.ge.graphics.internal.AgeShape)3 Label (org.osate.ge.graphics.internal.Label)3 InternalDiagramEditor (org.osate.ge.internal.ui.editor.InternalDiagramEditor)3