Search in sources :

Example 1 with DiagramModification

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

the class DiagramElementLayoutUtil method layoutIncrementally.

/**
 * Performs layout on elements in the specified diagram which have not been laid out.
 * @param diagram the diagram for which to perform the incremental layout
 * @param mod the modification to use to modify the diagram
 * @param layoutInfoProvider the layout info provider which provides additional information required for laying out the diagram
 */
public static void layoutIncrementally(final AgeDiagram diagram, final DiagramModification mod, final LayoutInfoProvider layoutInfoProvider) {
    Objects.requireNonNull(diagram, "diagram must not be null");
    Objects.requireNonNull(mod, "mod must not be null");
    Objects.requireNonNull(layoutInfoProvider, "layoutInfoProvider must not be null");
    final IncrementalLayoutMode currentLayoutMode = LayoutPreferences.getCurrentIncrementalLayoutMode();
    // Get all the nodes that need to be layed out.
    final Set<DiagramNode> unfilteredNodesToLayout = getNodesToLayoutIncrementally(diagram, currentLayoutMode, new HashSet<>());
    if (unfilteredNodesToLayout.size() == 0) {
        return;
    }
    // Lay our flow indicators. In the container is eventually layed out, this will be replaced but in cases where that is not the case,
    // we provide a default layout. Flow indicators are connections and as such will be filtered in the next step.
    layoutFlowIndicators(mod, unfilteredNodesToLayout.stream().filter(DiagramNodePredicates::isFlowIndicator).map(DiagramElement.class::cast), layoutInfoProvider);
    final Collection<DiagramNode> nodesToLayout = DiagramElementLayoutUtil.filterUnnecessaryNodes(unfilteredNodesToLayout, currentLayoutMode == IncrementalLayoutMode.LAYOUT_DIAGRAM);
    if (nodesToLayout.size() == 0) {
        // If the filtered node list is empty then the unfiltered list still contain feature self loop connections that need to be layed out.
        unfilteredNodesToLayout.stream().filter(DiagramElementLayoutUtil::isFeatureSelfLoopConnection).map(DiagramElement.class::cast).forEachOrdered(de -> layoutFeatureSelfLoopConnection(de, mod, layoutInfoProvider));
        return;
    }
    final LayoutOptions layoutOptions = LayoutOptions.createFromPreferences();
    if (currentLayoutMode == IncrementalLayoutMode.LAYOUT_DIAGRAM) {
        layout(INCREMENTAL_LAYOUT_LABEL, diagram, layoutInfoProvider, layoutOptions);
    } else {
        layout(mod, nodesToLayout, new StyleCalculator(diagram.getConfiguration(), StyleProvider.EMPTY), layoutInfoProvider, layoutOptions);
        // Set Positions of elements which do not have a position set.
        for (final DiagramNode dn : nodesToLayout) {
            if (dn instanceof DiagramElement) {
                final DiagramElement de = (DiagramElement) dn;
                if (!de.hasPosition()) {
                    if (de.getDockArea() == null) {
                        mod.setPosition(de, new Point(0.0, 0.0));
                    } else if (de.getDockArea() != DockArea.GROUP && de.getParent() instanceof DiagramElement) {
                        final DiagramElement parent = (DiagramElement) de.getParent();
                        final DockingPosition defaultDockingPosition = de.getGraphicalConfiguration().getDefaultDockingPosition();
                        final DockArea defaultDockArea = DockArea.fromDockingPosition(defaultDockingPosition);
                        if (parent.hasSize()) {
                            final Stream<DiagramElement> otherElementsAlongSide = parent.getChildren().stream().filter(c -> c.hasPosition() && c.hasSize() && c.getDockArea() == defaultDockArea);
                            // Determine the position of the new element along it's preferred docking position.
                            double locationAlongSide;
                            if (defaultDockingPosition == DockingPosition.TOP || defaultDockingPosition == DockingPosition.BOTTOM) {
                                locationAlongSide = otherElementsAlongSide.max(Comparator.comparingDouble(c -> c.getY())).map(c -> c.getX() + c.getWidth()).orElse(0.0);
                            } else {
                                locationAlongSide = otherElementsAlongSide.max(Comparator.comparingDouble(c -> c.getY())).map(c -> c.getY() + c.getHeight()).orElse(0.0);
                            }
                            // Set position based on the docking position
                            switch(defaultDockingPosition) {
                                case TOP:
                                    mod.setPosition(de, new Point(locationAlongSide, 0));
                                    break;
                                case BOTTOM:
                                    mod.setPosition(de, new Point(locationAlongSide, parent.getHeight()));
                                    break;
                                case LEFT:
                                    mod.setPosition(de, new Point(0, locationAlongSide));
                                    break;
                                case RIGHT:
                                    mod.setPosition(de, new Point(parent.getWidth(), locationAlongSide));
                                    break;
                                default:
                                    break;
                            }
                        }
                        mod.setDockArea(de, defaultDockArea);
                    }
                }
            }
        }
    }
}
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) StyleCalculator(org.osate.ge.internal.diagram.runtime.styling.StyleCalculator) DiagramNode(org.osate.ge.internal.diagram.runtime.DiagramNode) Point(org.osate.ge.graphics.Point) DiagramNodePredicates(org.osate.ge.internal.diagram.runtime.DiagramNodePredicates) DiagramElement(org.osate.ge.internal.diagram.runtime.DiagramElement) DockArea(org.osate.ge.internal.diagram.runtime.DockArea) DockingPosition(org.osate.ge.DockingPosition) Stream(java.util.stream.Stream)

Example 2 with DiagramModification

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

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

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

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

the class DiagramUpdater method updateStructure.

/**
 * Updates the structure of the diagram based on the business object tree.
 * Creates/Unghosts elements to match the business object tree. Ghosts diagram elements which are not in the diagram element tree.
 * @param m
 * @param container
 * @param bos
 */
private void updateStructure(final DiagramModification m, final DiagramNode container, final Collection<BusinessObjectNode> bos) {
    for (final BusinessObjectNode n : bos) {
        // Get existing element if it exists.
        DiagramElement element = container.getChildByRelativeReference(n.getRelativeReference());
        // Create the element if it does not exist
        if (element == null) {
            final DiagramElement removedGhost = removeGhost(container, n.getRelativeReference());
            if (removedGhost == null) {
                final BusinessObjectHandler boh = infoProvider.getApplicableBusinessObjectHandler(n.getBusinessObject());
                if (boh == null) {
                    // Ignore the object
                    continue;
                }
                element = new DiagramElement(container, n.getBusinessObject(), boh, n.getRelativeReference(), n.getId());
            } else {
                element = removedGhost;
                m.updateBusinessObject(element, n.getBusinessObject(), n.getRelativeReference());
            }
            m.addElement(element);
        } else {
            // Update the business object and relative reference. Although the reference matches. The business object may be new and the
            // relative reference may have case differences.
            m.updateBusinessObject(element, n.getBusinessObject(), n.getRelativeReference());
        }
        // Set the business object handler if it is null
        if (element.getBusinessObjectHandler() == null) {
            final BusinessObjectHandler boh = infoProvider.getApplicableBusinessObjectHandler(n.getBusinessObject());
            if (boh == null) {
                ghostAndRemove(m, element);
                continue;
            } else {
                m.setBusinessObjectHandler(element, boh);
            }
        }
        // Update the element's children
        updateStructure(m, element, n.getChildren());
    }
    // If the collections are the same size, there is nothing to remove
    if (bos.size() != container.getChildren().size()) {
        // Build Set of Relative References of All the Objects in the Business Object Tree
        final Set<RelativeBusinessObjectReference> boTreeRelativeReferenceSet = bos.stream().map((n) -> n.getRelativeReference()).collect(Collectors.toCollection(HashSet::new));
        Iterator<DiagramElement> childrenIt = container.getChildren().iterator();
        while (childrenIt.hasNext()) {
            final DiagramElement child = childrenIt.next();
            if (!boTreeRelativeReferenceSet.contains(child.getRelativeReference())) {
                ghostAndRemove(m, child);
            }
        }
    }
}
Also used : DiagramElement(org.osate.ge.internal.diagram.runtime.DiagramElement) DiagramElement(org.osate.ge.internal.diagram.runtime.DiagramElement) BusinessObjectHandler(org.osate.ge.businessobjecthandling.BusinessObjectHandler) DiagramConfigurationBuilder(org.osate.ge.internal.diagram.runtime.DiagramConfigurationBuilder) DiagramModification(org.osate.ge.internal.diagram.runtime.DiagramModification) HashMap(java.util.HashMap) EmbeddedBusinessObject(org.osate.ge.internal.model.EmbeddedBusinessObject) GraphicalConfiguration(org.osate.ge.GraphicalConfiguration) HashSet(java.util.HashSet) DockArea(org.osate.ge.internal.diagram.runtime.DockArea) Map(java.util.Map) ReferenceResolutionService(org.osate.ge.services.ReferenceResolutionService) LinkedList(java.util.LinkedList) RelativeBusinessObjectReference(org.osate.ge.RelativeBusinessObjectReference) DiagramElementPredicates(org.osate.ge.internal.diagram.runtime.DiagramElementPredicates) ActionExecutor(org.osate.ge.internal.services.ActionExecutor) Iterator(java.util.Iterator) ReferenceBuilderService(org.osate.ge.services.ReferenceBuilderService) Collection(java.util.Collection) Set(java.util.Set) Point(org.osate.ge.graphics.Point) Collectors(java.util.stream.Collectors) CanonicalBusinessObjectReference(org.osate.ge.CanonicalBusinessObjectReference) DockingPosition(org.osate.ge.DockingPosition) Objects(java.util.Objects) PropertyValueGroup(org.osate.ge.aadl2.internal.model.PropertyValueGroup) AgeDiagram(org.osate.ge.internal.diagram.runtime.AgeDiagram) List(java.util.List) AgeAction(org.osate.ge.internal.services.AgeAction) AgeConnection(org.osate.ge.graphics.internal.AgeConnection) Collections(java.util.Collections) DiagramNode(org.osate.ge.internal.diagram.runtime.DiagramNode) RelativeBusinessObjectReference(org.osate.ge.RelativeBusinessObjectReference) BusinessObjectHandler(org.osate.ge.businessobjecthandling.BusinessObjectHandler)

Aggregations

Collection (java.util.Collection)6 Collections (java.util.Collections)6 List (java.util.List)6 Objects (java.util.Objects)6 HashSet (java.util.HashSet)5 LinkedList (java.util.LinkedList)5 Set (java.util.Set)5 Collectors (java.util.stream.Collectors)5 Point (org.osate.ge.graphics.Point)5 AgeDiagram (org.osate.ge.internal.diagram.runtime.AgeDiagram)5 DiagramElement (org.osate.ge.internal.diagram.runtime.DiagramElement)5 DiagramModification (org.osate.ge.internal.diagram.runtime.DiagramModification)5 DiagramNode (org.osate.ge.internal.diagram.runtime.DiagramNode)5 ArrayListMultimap (com.google.common.collect.ArrayListMultimap)4 ImmutableList (com.google.common.collect.ImmutableList)4 Lists (com.google.common.collect.Lists)4 Comparator (java.util.Comparator)4 EnumSet (java.util.EnumSet)4 Entry (java.util.Map.Entry)4 Optional (java.util.Optional)4