Search in sources :

Example 16 with DiagramNode

use of org.osate.ge.internal.diagram.runtime.DiagramNode 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 17 with DiagramNode

use of org.osate.ge.internal.diagram.runtime.DiagramNode in project osate2 by osate.

the class DiagramElementLayoutUtil method layoutFlowIndicators.

/**
 * Sets the position and bendpoints of all specified flow indicators. Intended to provide a default position for flow indicators in cases
 * where only contents are being layed out. This layout will be replaced by the ELK produced layout when the flow indicator's container
 * is layed out.
 *
 * This function simply positions flow indicators such that they are in a after existing indicators.
 * @param m is the modification to use to modify the diagram.
 * @param flowIndicatorsToLayout is the stream of flow indicators to layout.
 * @param layoutInfoProvider is the source for layout info needed to determine source anchor points.
 */
public static void layoutFlowIndicators(final DiagramModification m, final Stream<DiagramElement> flowIndicatorsToLayout, final LayoutInfoProvider layoutInfoProvider) {
    Objects.requireNonNull(flowIndicatorsToLayout, "flowIndicators must not be null");
    // Create set of a start elements in which we are interested.
    final Set<DiagramNode> startElements = flowIndicatorsToLayout.map(n -> n.getStartElement()).collect(Collectors.toSet());
    if (startElements.isEmpty()) {
        return;
    }
    // Search diagram and build a multimap mapping start elements to the flow indicators which reference them.
    final ArrayListMultimap<DiagramElement, DiagramElement> startElementToFlowIndicators = ArrayListMultimap.create();
    m.getDiagram().getAllDescendants().filter(q -> q instanceof DiagramElement && DiagramElementPredicates.isFlowIndicator((DiagramElement) q)).forEachOrdered(q -> {
        final DiagramElement e = (DiagramElement) q;
        final DiagramElement start = e.getStartElement();
        if (startElements.contains(start)) {
            startElementToFlowIndicators.put(start, e);
        }
    });
    // Process each start element
    for (DiagramElement startElement : startElementToFlowIndicators.keySet()) {
        // Skip start elements that haven't been positioned
        if (!startElement.hasPosition()) {
            continue;
        }
        // Skip if unable to determine what side the start element is on. Flow indicators are only supported when there is a source element which is docked.
        final DockArea dockArea = getNonGroupDockArea(startElement);
        if (dockArea == null) {
            continue;
        }
        // Sort by X or Y based on dock area. Flow indicators without a position are sorted at the end.
        final List<DiagramElement> flowIndicatorsForStartElement = startElementToFlowIndicators.get(startElement);
        flowIndicatorsForStartElement.sort((e1, e2) -> {
            if (e1.hasPosition() && e2.hasPosition()) {
                if (dockArea.isLeftOrRight()) {
                    return Double.compare(e1.getY(), e2.getY());
                } else {
                    return Double.compare(e1.getX(), e2.getX());
                }
            } else if (e1.hasPosition()) {
                return -1;
            } else if (e2.hasPosition()) {
                return 1;
            } else {
                return 0;
            }
        });
        // Flow indicators are positions based on the first undocked container. Need to find that container.
        final DiagramElement indicatorContainer = DiagramElementUtil.getUndockedDiagramElement(flowIndicatorsForStartElement.get(0).getParent());
        // Skip if we are unable to determine the container or if the container doesn't have a size.
        if (indicatorContainer == null || !indicatorContainer.hasSize()) {
            continue;
        }
        final Point containerAbsPosition = getAbsolutePosition(indicatorContainer);
        // 
        // Determine how to adjust position of bendpoints and indicator positions based on the dock area
        // 
        final Point startAnchorPosition = getPortAnchorOffset(startElement, dockArea, containerAbsPosition, layoutInfoProvider);
        final double initialPositionOffsetX;
        final double initialPositionOffsetY;
        final double positionIncrementX;
        final double positionIncrementY;
        switch(dockArea) {
            case LEFT:
                initialPositionOffsetX = INCREMENTAL_FLOW_INDICATOR_PRIMARY_OFFSET;
                initialPositionOffsetY = 0;
                positionIncrementX = 0.0;
                positionIncrementY = INCREMENTAL_FLOW_INDICATOR_SECONDARY_INCREMENT;
                break;
            case RIGHT:
                initialPositionOffsetX = -INCREMENTAL_FLOW_INDICATOR_PRIMARY_OFFSET;
                initialPositionOffsetY = 0;
                positionIncrementX = 0;
                positionIncrementY = INCREMENTAL_FLOW_INDICATOR_SECONDARY_INCREMENT;
                break;
            case TOP:
                initialPositionOffsetX = 0;
                initialPositionOffsetY = INCREMENTAL_FLOW_INDICATOR_PRIMARY_OFFSET;
                positionIncrementX = INCREMENTAL_FLOW_INDICATOR_SECONDARY_INCREMENT;
                positionIncrementY = 0;
                break;
            case BOTTOM:
                initialPositionOffsetX = 0;
                initialPositionOffsetY = -INCREMENTAL_FLOW_INDICATOR_PRIMARY_OFFSET;
                positionIncrementX = INCREMENTAL_FLOW_INDICATOR_SECONDARY_INCREMENT;
                positionIncrementY = 0;
                break;
            case GROUP:
            default:
                // Our dock area should never have the group value and all other values should be handled
                throw new GraphicalEditorException("Unexpected case: " + dockArea);
        }
        // Calculate absolute position for the start anchor. Used for bendpoints
        final Point startAnchorAbsPosition = new Point(containerAbsPosition.x + startAnchorPosition.x, containerAbsPosition.y + startAnchorPosition.y);
        // Determine initial of the first flow indicator relative to it's container.
        // This is only used when there all flow indicators do not have a position
        final Point firstPosition = new Point(startAnchorPosition.x + initialPositionOffsetX, startAnchorPosition.y + initialPositionOffsetY);
        Point nextPosition = firstPosition;
        for (DiagramElement indicator : flowIndicatorsForStartElement) {
            final Point currentPosition;
            if (indicator.hasPosition()) {
                currentPosition = indicator.getPosition();
            } else {
                // Set the position
                currentPosition = nextPosition;
                m.setPosition(indicator, nextPosition);
                // The first flow indicator should not need bendpoints, to reset them
                if (nextPosition.equals(firstPosition)) {
                    m.setBendpoints(indicator, ImmutableList.of());
                } else {
                    // Set bendpoints
                    final Point bp1 = new Point(startAnchorAbsPosition.x + (initialPositionOffsetX * INCREMENTAL_FLOW_INDICATOR_BENDPOINT_OFFSET_SCALING), startAnchorAbsPosition.y + (initialPositionOffsetY * INCREMENTAL_FLOW_INDICATOR_BENDPOINT_OFFSET_SCALING));
                    final Point positionAbs = new Point(containerAbsPosition.x + nextPosition.x, +containerAbsPosition.y + nextPosition.y);
                    final Point bp2 = new Point(positionAbs.x - (initialPositionOffsetX * (1.0 - INCREMENTAL_FLOW_INDICATOR_BENDPOINT_OFFSET_SCALING)), positionAbs.y - (initialPositionOffsetY * (1.0 - INCREMENTAL_FLOW_INDICATOR_BENDPOINT_OFFSET_SCALING)));
                    m.setBendpoints(indicator, ImmutableList.of(bp1, bp2));
                }
            }
            // Determine the next position
            nextPosition = new Point(currentPosition.x + positionIncrementX, currentPosition.y + positionIncrementY);
        }
    }
}
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) DiagramElement(org.osate.ge.internal.diagram.runtime.DiagramElement) DiagramNode(org.osate.ge.internal.diagram.runtime.DiagramNode) DockArea(org.osate.ge.internal.diagram.runtime.DockArea) Point(org.osate.ge.graphics.Point) GraphicalEditorException(org.osate.ge.internal.GraphicalEditorException)

Example 18 with DiagramNode

use of org.osate.ge.internal.diagram.runtime.DiagramNode in project osate2 by osate.

the class DiagramElementLayoutUtil method shiftRelatedConnections.

/**
 * Shifts the bendpoints of all connections for which both endpoints are contained within the specified elements.
 * Shifts bendpoints of flow indicators if start elements are contained within the specified elements.
 * Shifts position of flow indicators if start elements are contained within the specified elements and the flow indicator container is not
 * is not in movedElements.
 *
 * @param movedElements are the element which have been moved.
 * @param delta the amount to shift the bendpoints
 * @param m the modification that will be used to update the bendpoints
 * @param shiftBendpoints whether to shift bendpoints
 * @param shiftFlowIndicatorPositions whether to shift flow indicator positions.
 * @param checkDescendants whether to check descendants of the specified elements when looking for connections
 */
public static void shiftRelatedConnections(final Stream<DiagramElement> movedElements, final org.osate.ge.graphics.Point delta, final DiagramModification m, boolean shiftBendpoints, boolean shiftFlowIndicatorPositions, final boolean checkDescendants) {
    final Set<BusinessObjectContext> movedElementsSet = movedElements.collect(Collectors.toSet());
    // Build a set containing the moved elements and all of their descendant which are represented as shapes
    final Set<BusinessObjectContext> diagramElements = checkDescendants ? movedElementsSet.stream().flatMap(de -> Stream.concat(Stream.of(de), de.getAllDescendants())).collect(Collectors.toSet()) : movedElementsSet;
    final Stream<DiagramElement> connections = m.getDiagram().getAllDiagramNodes().filter(q -> q instanceof DiagramElement && DiagramElementPredicates.isConnection((DiagramElement) q)).map(DiagramElement.class::cast);
    // Iterate over all the connections in the diagram and update their bendpoints if their ends are in the set above.
    connections.forEachOrdered(connection -> {
        final DiagramElement startElement = connection.getStartElement();
        final DiagramElement endElement = connection.getEndElement();
        final boolean isFlowIndicator = ((AgeConnection) connection.getGraphic()).isFlowIndicator;
        if (diagramElements.contains(startElement) && (diagramElements.contains(endElement) || isFlowIndicator)) {
            if (shiftBendpoints) {
                shiftBendpoints(connection, delta, m);
            }
            // Shift flow indicator positions
            if (shiftFlowIndicatorPositions && isFlowIndicator && connection.hasPosition()) {
                // Flow indicator positions are relative to the container of the flow indicator.
                // If the flow indicator's ancestor has moved, then do not shift the flow indicator's position
                boolean ancestorHasMoved = false;
                for (DiagramNode tmp = connection.getParent(); tmp != null; tmp = tmp.getParent()) {
                    if (movedElementsSet.contains(tmp)) {
                        ancestorHasMoved = true;
                    }
                }
                if (!ancestorHasMoved) {
                    final DockArea startDockArea = getNonGroupDockArea(startElement);
                    m.setPosition(connection, new org.osate.ge.graphics.Point(connection.getX() + (startDockArea == null || !startDockArea.isLeftOrRight() ? delta.x : 0), connection.getY() + (startDockArea == null || startDockArea.isLeftOrRight() ? delta.y : 0)));
                }
            }
        }
    });
}
Also used : DiagramElement(org.osate.ge.internal.diagram.runtime.DiagramElement) 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) AgeConnection(org.osate.ge.graphics.internal.AgeConnection) DiagramNode(org.osate.ge.internal.diagram.runtime.DiagramNode) DockArea(org.osate.ge.internal.diagram.runtime.DockArea) Point(org.osate.ge.graphics.Point) BusinessObjectContext(org.osate.ge.BusinessObjectContext)

Example 19 with DiagramNode

use of org.osate.ge.internal.diagram.runtime.DiagramNode 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 20 with DiagramNode

use of org.osate.ge.internal.diagram.runtime.DiagramNode in project osate2 by osate.

the class DiagramElementLayoutUtil method moveElement.

/**
 * Sets the position of a diagram element
 * @param modification the diagram modification to use to modify the diagram
 * @param e the element for which to set the position
 * @param value the new position of the element
 * @param updateDockArea whether the dock area should be updated based on the set position.
 * @param updateBendpoints whether to shift bendpoints of related connections
 * @param updateFlowIndicators if related flow indicators should be moved. If dock area has changed the position of the dock areas will be reset to allow for a new layout.
 */
public static void moveElement(final DiagramModification modification, final DiagramElement e, final Point value, final boolean updateDockArea, final boolean updateBendpoints, final boolean updateFlowIndicators) {
    if (!Objects.equals(e.getPosition(), value)) {
        // Determine the different between X and Y
        final Point delta = value == null ? null : new Point(value.x - e.getX(), value.y - e.getY());
        modification.setPosition(e, value);
        // Only update dock area and bendpoints if position is being set to an actual value
        if (delta != null) {
            final DockArea originalDockArea = e.getDockArea();
            if (updateDockArea) {
                // Update the dock area based on the position
                if (originalDockArea != null) {
                    if (originalDockArea != DockArea.GROUP) {
                        modification.setDockArea(e, calculateDockArea(e));
                    }
                }
            }
            if (updateBendpoints || updateFlowIndicators) {
                DiagramElementLayoutUtil.shiftRelatedConnections(Stream.of(e), new Point(delta.x, delta.y), modification, updateBendpoints, updateFlowIndicators, true);
            }
            // Reset flow indicators entirely if dock area has changed
            if (updateFlowIndicators && originalDockArea != e.getDockArea()) {
                final Stream<DiagramNode> affectedStartElements = e.getAllDiagramNodes();
                DiagramElementLayoutUtil.resetFlowIndicatorsWithStartElementsPositions(modification, affectedStartElements);
            }
        }
    }
}
Also used : DiagramNode(org.osate.ge.internal.diagram.runtime.DiagramNode) DockArea(org.osate.ge.internal.diagram.runtime.DockArea) Point(org.osate.ge.graphics.Point)

Aggregations

DiagramNode (org.osate.ge.internal.diagram.runtime.DiagramNode)29 DiagramElement (org.osate.ge.internal.diagram.runtime.DiagramElement)18 List (java.util.List)13 Point (org.osate.ge.graphics.Point)13 AgeDiagram (org.osate.ge.internal.diagram.runtime.AgeDiagram)13 InternalDiagramEditor (org.osate.ge.internal.ui.editor.InternalDiagramEditor)13 Objects (java.util.Objects)12 IEditorPart (org.eclipse.ui.IEditorPart)11 Collection (java.util.Collection)10 Collections (java.util.Collections)10 BusinessObjectContext (org.osate.ge.BusinessObjectContext)9 LinkedList (java.util.LinkedList)8 Collectors (java.util.stream.Collectors)8 DiagramModification (org.osate.ge.internal.diagram.runtime.DiagramModification)8 Stream (java.util.stream.Stream)7 Node (javafx.scene.Node)7 IStatus (org.eclipse.core.runtime.IStatus)7 Status (org.eclipse.core.runtime.Status)7 DiagramNodePredicates (org.osate.ge.internal.diagram.runtime.DiagramNodePredicates)7 DiagramElementUtil (org.osate.ge.internal.util.DiagramElementUtil)7