Search in sources :

Example 6 with LayoutMapping

use of org.eclipse.elk.core.service.LayoutMapping in project elk by eclipse.

the class GmfDiagramLayoutConnector method buildLayoutGraph.

@Override
public LayoutMapping buildLayoutGraph(final IWorkbenchPart workbenchPart, final Object diagramPart) {
    // get the diagram editor part
    DiagramEditor diagramEditor = getDiagramEditor(workbenchPart);
    // choose the layout root edit part
    IGraphicalEditPart layoutRootPart = null;
    List<ShapeNodeEditPart> selectedParts = null;
    if (diagramPart instanceof ShapeNodeEditPart || diagramPart instanceof DiagramEditPart) {
        layoutRootPart = (IGraphicalEditPart) diagramPart;
    } else if (diagramPart instanceof IGraphicalEditPart) {
        EditPart tgEditPart = ((IGraphicalEditPart) diagramPart).getTopGraphicEditPart();
        if (tgEditPart instanceof ShapeNodeEditPart) {
            layoutRootPart = (IGraphicalEditPart) tgEditPart;
        }
    } else if (diagramPart instanceof Collection) {
        Collection<?> selection = (Collection<?>) diagramPart;
        // determine the layout root part from the selection
        for (Object object : selection) {
            if (object instanceof IGraphicalEditPart) {
                if (layoutRootPart != null) {
                    EditPart parent = commonParent(layoutRootPart, (EditPart) object);
                    if (parent != null && !(parent instanceof RootEditPart)) {
                        layoutRootPart = (IGraphicalEditPart) parent;
                    }
                } else if (!(object instanceof ConnectionEditPart)) {
                    layoutRootPart = (IGraphicalEditPart) object;
                }
            }
        }
        // build a list of edit parts that shall be layouted completely
        if (layoutRootPart != null) {
            selectedParts = new ArrayList<ShapeNodeEditPart>(selection.size());
            for (Object object : selection) {
                if (object instanceof IGraphicalEditPart) {
                    EditPart editPart = (EditPart) object;
                    while (editPart != null && editPart.getParent() != layoutRootPart) {
                        editPart = editPart.getParent();
                    }
                    if (editPart instanceof ShapeNodeEditPart && editPartFilter.filter(editPart) && !selectedParts.contains(editPart)) {
                        selectedParts.add((ShapeNodeEditPart) editPart);
                    }
                }
            }
        }
    }
    if (layoutRootPart == null && diagramEditor != null) {
        layoutRootPart = diagramEditor.getDiagramEditPart();
    }
    if (layoutRootPart == null) {
        throw new IllegalArgumentException("Not supported by this layout connector: Workbench part " + workbenchPart + ", Edit part " + diagramPart);
    }
    // create the mapping
    LayoutMapping mapping = buildLayoutGraph(layoutRootPart, selectedParts, workbenchPart);
    return mapping;
}
Also used : IGraphicalEditPart(org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart) ShapeNodeEditPart(org.eclipse.gmf.runtime.diagram.ui.editparts.ShapeNodeEditPart) DiagramEditor(org.eclipse.gmf.runtime.diagram.ui.parts.DiagramEditor) ConnectionEditPart(org.eclipse.gmf.runtime.diagram.ui.editparts.ConnectionEditPart) ResizableCompartmentEditPart(org.eclipse.gmf.runtime.diagram.ui.editparts.ResizableCompartmentEditPart) ShapeNodeEditPart(org.eclipse.gmf.runtime.diagram.ui.editparts.ShapeNodeEditPart) RootEditPart(org.eclipse.gef.RootEditPart) CompartmentEditPart(org.eclipse.gmf.runtime.diagram.ui.editparts.CompartmentEditPart) RenderedDiagramRootEditPart(org.eclipse.gmf.runtime.diagram.ui.render.editparts.RenderedDiagramRootEditPart) EditPart(org.eclipse.gef.EditPart) IGraphicalEditPart(org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart) AbstractBorderItemEditPart(org.eclipse.gmf.runtime.diagram.ui.editparts.AbstractBorderItemEditPart) LabelEditPart(org.eclipse.gmf.runtime.diagram.ui.editparts.LabelEditPart) ConnectionEditPart(org.eclipse.gmf.runtime.diagram.ui.editparts.ConnectionEditPart) DiagramEditPart(org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart) DiagramEditPart(org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart) Collection(java.util.Collection) EObject(org.eclipse.emf.ecore.EObject) LayoutMapping(org.eclipse.elk.core.service.LayoutMapping) RootEditPart(org.eclipse.gef.RootEditPart) RenderedDiagramRootEditPart(org.eclipse.gmf.runtime.diagram.ui.render.editparts.RenderedDiagramRootEditPart)

Example 7 with LayoutMapping

use of org.eclipse.elk.core.service.LayoutMapping in project elk by eclipse.

the class GmfDiagramLayoutConnector method buildLayoutGraph.

/**
 * Creates the actual mapping given an edit part which functions as the root for the layout.
 *
 * @param layoutRootPart the layout root edit part
 * @param selection a selection of contained edit parts to process, or {@code null} if the whole
 *          content shall be processed
 * @param workbenchPart the workbench part, or {@code null}
 * @return a layout graph mapping
 */
protected LayoutMapping buildLayoutGraph(final IGraphicalEditPart layoutRootPart, final List<ShapeNodeEditPart> selection, final IWorkbenchPart workbenchPart) {
    LayoutMapping mapping = new LayoutMapping(workbenchPart);
    mapping.setProperty(CONNECTIONS, new LinkedList<ConnectionEditPart>());
    mapping.setParentElement(layoutRootPart);
    // find the diagram edit part
    mapping.setProperty(DIAGRAM_EDIT_PART, getDiagramEditPart(layoutRootPart));
    ElkNode topNode;
    if (layoutRootPart instanceof ShapeNodeEditPart) {
        // start with a specific node as root for layout
        topNode = createNode(mapping, (ShapeNodeEditPart) layoutRootPart, null, null, null);
    } else {
        // start with the whole diagram as root for layout
        topNode = ElkGraphUtil.createGraph();
        Rectangle rootBounds = layoutRootPart.getFigure().getBounds();
        if (layoutRootPart instanceof DiagramEditPart) {
            String labelText = ((DiagramEditPart) layoutRootPart).getDiagramView().getName();
            if (labelText.length() > 0) {
                ElkLabel label = ElkGraphUtil.createLabel(topNode);
                label.setText(labelText);
            }
        } else {
            topNode.setLocation(rootBounds.x, rootBounds.y);
        }
        topNode.setDimensions(rootBounds.width, rootBounds.height);
        mapping.getGraphMap().put(topNode, layoutRootPart);
    }
    mapping.setLayoutGraph(topNode);
    if (selection != null && !selection.isEmpty()) {
        // layout only the selected elements
        double minx = Integer.MAX_VALUE;
        double miny = Integer.MAX_VALUE;
        Maybe<ElkPadding> kinsets = new Maybe<>();
        for (ShapeNodeEditPart editPart : selection) {
            ElkNode node = createNode(mapping, editPart, layoutRootPart, topNode, kinsets);
            minx = Math.min(minx, node.getX());
            miny = Math.min(miny, node.getY());
            buildLayoutGraphRecursively(mapping, editPart, node, editPart);
        }
        mapping.setProperty(COORDINATE_OFFSET, new KVector(minx, miny));
    } else {
        // traverse all children of the layout root part
        buildLayoutGraphRecursively(mapping, layoutRootPart, topNode, layoutRootPart);
    }
    // transform all connections in the selected area
    processConnections(mapping);
    return mapping;
}
Also used : ShapeNodeEditPart(org.eclipse.gmf.runtime.diagram.ui.editparts.ShapeNodeEditPart) Maybe(org.eclipse.elk.core.util.Maybe) ConnectionEditPart(org.eclipse.gmf.runtime.diagram.ui.editparts.ConnectionEditPart) ElkNode(org.eclipse.elk.graph.ElkNode) Rectangle(org.eclipse.draw2d.geometry.Rectangle) DiagramEditPart(org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart) ElkLabel(org.eclipse.elk.graph.ElkLabel) KVector(org.eclipse.elk.core.math.KVector) LayoutMapping(org.eclipse.elk.core.service.LayoutMapping) ElkPadding(org.eclipse.elk.core.math.ElkPadding)

Example 8 with LayoutMapping

use of org.eclipse.elk.core.service.LayoutMapping in project osate2 by osate.

the class DiagramElementLayoutUtil method applyConnectionLayout.

private static void applyConnectionLayout(final LayoutMapping mapping, final DiagramModification m) {
    // Modify Connections
    for (Entry<ElkGraphElement, Object> e : mapping.getGraphMap().entrySet()) {
        final ElkGraphElement elkElement = e.getKey();
        final Object mappedValue = e.getValue();
        if (!(elkElement instanceof ElkEdge)) {
            continue;
        }
        final ElkEdge edge = (ElkEdge) elkElement;
        // Ignore edges which do not have exactly one section. This is usually the case where it is a long hierarchical connection that has 0 sections
        if (edge.getSections().size() != 1) {
            continue;
        }
        final ElkEdgeSection edgeSection = edge.getSections().get(0);
        if (!(mappedValue instanceof DiagramElement)) {
            continue;
        }
        final DiagramElement de = (DiagramElement) mappedValue;
        if (!(de.getGraphic() instanceof AgeConnection)) {
            continue;
        }
        final AgeConnection connection = (AgeConnection) de.getGraphic();
        // Flow indicators have a position representing where the indicator ends.
        if (connection.isFlowIndicator && edge.getTargets().size() == 1) {
            final ElkPort flowIndicatorEndPort = (ElkPort) edge.getTargets().get(0);
            final ElkShape flowIndicatorEndPortShape = (ElkShape) flowIndicatorEndPort.eContainer();
            m.setPosition(de, new Point(flowIndicatorEndPortShape.getX(), flowIndicatorEndPortShape.getY()));
        }
        // Don't update connections if it wasn't updated. This prevents updating bendpoints to invalid values if an edge is not layed out.
        if (edgeSection.eIsSet(ElkGraphPackage.eINSTANCE.getElkEdgeSection_StartX()) && edgeSection.eIsSet(ElkGraphPackage.eINSTANCE.getElkEdgeSection_EndX())) {
            final List<Point> bendpointsInParentCoordinateSystem = edgeSection.getBendPoints().stream().map(bp -> new Point(bp.getX(), bp.getY())).collect(Collectors.toCollection(LinkedList::new));
            // 
            // Set bendpoints
            // 
            // Add the start and end points to the bendpoints list if the the start/end element is not a port.
            // For ports the start and end points are unnecessary and will actually be located inside the port graphic.
            final boolean srcIsPort = edge.getSources().size() == 1 ? edge.getSources().get(0) instanceof ElkPort : false;
            final boolean dstIsPort = edge.getTargets().size() == 1 ? edge.getTargets().get(0) instanceof ElkPort : false;
            if (!srcIsPort) {
                bendpointsInParentCoordinateSystem.add(0, new Point(edgeSection.getStartX(), edgeSection.getStartY()));
            }
            if (!dstIsPort) {
                bendpointsInParentCoordinateSystem.add(new Point(edgeSection.getEndX(), edgeSection.getEndY()));
            }
            // Adjust newly added bendpoints so that the connection arrows will face the appropriate direction
            if (!srcIsPort && bendpointsInParentCoordinateSystem.size() >= 2) {
                bendpointsInParentCoordinateSystem.set(0, getAdjacentPoint(bendpointsInParentCoordinateSystem.get(0), bendpointsInParentCoordinateSystem.get(1), START_AND_END_BENDPOINT_DISTANCE));
            }
            if (!dstIsPort && bendpointsInParentCoordinateSystem.size() >= 2) {
                bendpointsInParentCoordinateSystem.set(bendpointsInParentCoordinateSystem.size() - 1, getAdjacentPoint(bendpointsInParentCoordinateSystem.get(bendpointsInParentCoordinateSystem.size() - 1), bendpointsInParentCoordinateSystem.get(bendpointsInParentCoordinateSystem.size() - 2), START_AND_END_BENDPOINT_DISTANCE));
            }
            // Get the absolute coordinate in the diagram of the edge's ELK container.
            final Point elkContainerPosition;
            if (edge.getContainingNode() == mapping.getLayoutGraph()) {
                // Node available. Use the first and only child of the top level ELK node.
                if (mapping.getLayoutGraph().getChildren().size() == 1) {
                    final ElkNode topLayoutElkNode = mapping.getLayoutGraph().getChildren().get(0);
                    final Point topLayoutElkNodePosition = getAbsolutePosition((DiagramNode) mapping.getGraphMap().get(topLayoutElkNode));
                    elkContainerPosition = new Point(topLayoutElkNodePosition.x - topLayoutElkNode.getX(), topLayoutElkNodePosition.y - topLayoutElkNode.getY());
                } else {
                    elkContainerPosition = new Point(0, 0);
                }
            } else {
                elkContainerPosition = getAbsolutePosition((DiagramNode) mapping.getGraphMap().get(edge.getContainingNode()));
            }
            final List<Point> bendpointsInAbsoluteCoordinateSystem = bendpointsInParentCoordinateSystem.stream().map(p -> new Point(p.x + elkContainerPosition.x, p.y + elkContainerPosition.y)).collect(Collectors.toList());
            m.setBendpoints(de, bendpointsInAbsoluteCoordinateSystem);
            // For the midpoint calculation, the start and end points are needed. Add them if they have not already been added.
            if (srcIsPort) {
                bendpointsInParentCoordinateSystem.add(0, new Point(edgeSection.getStartX(), edgeSection.getStartY()));
            }
            if (dstIsPort) {
                bendpointsInParentCoordinateSystem.add(new Point(edgeSection.getEndX(), edgeSection.getEndY()));
            }
            // Set Label Positions
            setLabelPositionsForEdge(mapping, m, edge, findMidpoint(bendpointsInParentCoordinateSystem));
        }
    }
}
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) ElkPort(org.eclipse.elk.graph.ElkPort) Point(org.osate.ge.graphics.Point) ElkEdgeSection(org.eclipse.elk.graph.ElkEdgeSection) DiagramElement(org.osate.ge.internal.diagram.runtime.DiagramElement) AgeConnection(org.osate.ge.graphics.internal.AgeConnection) ElkShape(org.eclipse.elk.graph.ElkShape) ElkGraphElement(org.eclipse.elk.graph.ElkGraphElement) ElkEdge(org.eclipse.elk.graph.ElkEdge)

Example 9 with LayoutMapping

use of org.eclipse.elk.core.service.LayoutMapping 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 10 with LayoutMapping

use of org.eclipse.elk.core.service.LayoutMapping 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)

Aggregations

LayoutMapping (org.eclipse.elk.core.service.LayoutMapping)11 ElkNode (org.eclipse.elk.graph.ElkNode)9 DiagramElement (org.osate.ge.internal.diagram.runtime.DiagramElement)8 Collection (java.util.Collection)7 KVector (org.eclipse.elk.core.math.KVector)7 PortSide (org.eclipse.elk.core.options.PortSide)7 ElkGraphElement (org.eclipse.elk.graph.ElkGraphElement)7 ElkLabel (org.eclipse.elk.graph.ElkLabel)7 ElkPort (org.eclipse.elk.graph.ElkPort)7 AgeDiagram (org.osate.ge.internal.diagram.runtime.AgeDiagram)7 DiagramNode (org.osate.ge.internal.diagram.runtime.DiagramNode)7 Collections (java.util.Collections)6 EnumSet (java.util.EnumSet)6 List (java.util.List)6 Entry (java.util.Map.Entry)6 Objects (java.util.Objects)6 Optional (java.util.Optional)6 Collectors (java.util.stream.Collectors)6 CoreOptions (org.eclipse.elk.core.options.CoreOptions)6 NodeLabelPlacement (org.eclipse.elk.core.options.NodeLabelPlacement)6