Search in sources :

Example 11 with Point

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

the class DistributeHorizontallyHandler method execute.

/**
 * Distributes shapes along the X axis so each shape has an equal distance between them
 */
@Override
public Object execute(final ExecutionEvent event) throws ExecutionException {
    final List<DiagramElement> selectedDiagramElements = AgeHandlerUtil.getSelectedDiagramElements();
    final AgeDiagram diagram = UiUtil.getDiagram(selectedDiagramElements);
    if (diagram == null) {
        throw new RuntimeException("Unable to get diagram");
    }
    diagram.modify("Distribute Horizontally", m -> {
        selectedDiagramElements.sort(XValueComparator);
        // Distribute the shapes horizontally
        final double xDistribution = getXDistribution(selectedDiagramElements);
        for (int i = 1; i < selectedDiagramElements.size() - 1; i++) {
            final DiagramElement de = selectedDiagramElements.get(i);
            final double x = getXValue(selectedDiagramElements.get(i - 1), xDistribution);
            final double y = de.getY();
            DiagramElementLayoutUtil.moveElement(m, de, new Point(x, y));
        }
    });
    return null;
}
Also used : DiagramElement(org.osate.ge.internal.diagram.runtime.DiagramElement) AgeDiagram(org.osate.ge.internal.diagram.runtime.AgeDiagram) Point(org.osate.ge.graphics.Point) Point(org.osate.ge.graphics.Point)

Example 12 with Point

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

the class DistributeVerticallyHandler method execute.

/**
 * Distributes shapes along the Y axis so each shape has an equal distance between them
 */
@Override
public Object execute(final ExecutionEvent event) throws ExecutionException {
    final List<DiagramElement> selectedDiagramElements = AgeHandlerUtil.getSelectedDiagramElements();
    final AgeDiagram diagram = UiUtil.getDiagram(selectedDiagramElements);
    if (diagram == null) {
        throw new RuntimeException("Unable to get diagram");
    }
    diagram.modify("Distribute Vertically", m -> {
        selectedDiagramElements.sort(YValueComparator);
        // Distribute the shapes horizontally
        final double yDistribution = getYDistribution(selectedDiagramElements);
        for (int i = 1; i < selectedDiagramElements.size() - 1; i++) {
            final DiagramElement de = selectedDiagramElements.get(i);
            final double x = de.getX();
            final double y = getYValue(selectedDiagramElements.get(i - 1), yDistribution);
            DiagramElementLayoutUtil.moveElement(m, de, new Point(x, y));
        }
    });
    return null;
}
Also used : DiagramElement(org.osate.ge.internal.diagram.runtime.DiagramElement) AgeDiagram(org.osate.ge.internal.diagram.runtime.AgeDiagram) Point(org.osate.ge.graphics.Point) Point(org.osate.ge.graphics.Point)

Example 13 with Point

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

the class AgeFxTest method start.

@Override
public void start(final Stage primaryStage) throws Exception {
    container = new GridPane();
    container.setHgap(10.0);
    container.setVgap(10.0);
    container.setBackground(new Background(new BackgroundFill(Color.LIGHTGRAY, CornerRadii.EMPTY, Insets.EMPTY)));
    final Graphic[] graphics = new Graphic[] { RectangleBuilder.create().build(), RectangleBuilder.create().rounded().build(), EllipseBuilder.create().build(), FolderGraphicBuilder.create().build(), DeviceGraphicBuilder.create().build(), ParallelogramBuilder.create().horizontalOffset(20).build(), BusGraphicBuilder.create().build(), PolyBuilder.create().polygon().points(new Point(0.0, 1.0), new Point(1.0, 1.0), new Point(0.5, 0.0)).build(), PolyBuilder.create().polyline().points(new Point(0.0, 0.0), new Point(1.0, 0.5), new Point(0.0, 1.0)).build(), ProcessorGraphicBuilder.create().build(), MemoryGraphicBuilder.create().build(), FeatureGroupTypeGraphicBuilder.create().build(), ModeGraphicBuilder.create().build(), ModeGraphicBuilder.create().initialMode().build(), NoteGraphicBuilder.create().build(), LabelBuilder.create().build(), FeatureGraphicBuilder.create().abstractFeature().bidirectional().build(), FeatureGraphicBuilder.create().abstractFeature().input().build(), FeatureGraphicBuilder.create().abstractFeature().output().build(), FeatureGraphicBuilder.create().eventPort().bidirectional().build(), FeatureGraphicBuilder.create().eventPort().input().build(), FeatureGraphicBuilder.create().eventPort().output().build(), FeatureGraphicBuilder.create().dataPort().bidirectional().build(), FeatureGraphicBuilder.create().dataPort().input().build(), FeatureGraphicBuilder.create().dataPort().output().build(), FeatureGraphicBuilder.create().eventDataPort().bidirectional().build(), FeatureGraphicBuilder.create().eventDataPort().input().build(), FeatureGraphicBuilder.create().eventDataPort().output().build(), FeatureGraphicBuilder.create().subprogramAccess().input().build(), FeatureGraphicBuilder.create().subprogramAccess().output().build(), FeatureGraphicBuilder.create().subprogramGroupAccess().input().build(), FeatureGraphicBuilder.create().subprogramGroupAccess().output().build(), FeatureGraphicBuilder.create().dataAccess().input().build(), FeatureGraphicBuilder.create().dataAccess().output().build(), FeatureGraphicBuilder.create().featureGroup().build(), ConnectionBuilder.create().build(), ConnectionBuilder.create().sourceTerminator(OrthogonalLineBuilder.create().build()).build(), ConnectionBuilder.create().sourceTerminator(ArrowBuilder.create().filled().build()).destinationTerminator(ArrowBuilder.create().filled().small().build()).build(), ConnectionBuilder.create().destinationTerminator(ArrowBuilder.create().line().build()).build(), FlowIndicatorBuilder.create().build(), FlowIndicatorBuilder.create().sourceTerminator(ArrowBuilder.create().small().reverse().build()).destinationTerminator(OrthogonalLineBuilder.create().build()).build() };
    final List<Node> nodes = Arrays.stream(graphics).map(GraphicToFx::createNode).collect(Collectors.toList());
    // Create a container shape. This is useful for ensuring image in style is applied,.
    final ContainerShape cs = new ContainerShape();
    cs.setGraphic(new EllipseNode());
    nodes.add(cs);
    final CheckBox dashedCheckBox = new CheckBox("Dashed");
    nodes.add(dashedCheckBox);
    dashedCheckBox.selectedProperty().addListener((ChangeListener<Boolean>) (observable, oldValue, newValue) -> {
        dashed = newValue;
        refreshStyle();
    });
    // Finish additional configuraton for labels and connections
    for (final Node n : nodes) {
        if (n instanceof LabelNode) {
            ((LabelNode) n).setText("This is a test");
        } else if (n instanceof ConnectionNode) {
            final ConnectionNode cn = (ConnectionNode) n;
            final StaticAnchor start = new StaticAnchor(new org.eclipse.gef.geometry.planar.Point(0, 5));
            final StaticAnchor end = new StaticAnchor(new org.eclipse.gef.geometry.planar.Point(100, 5));
            cn.setStartAnchor(start);
            cn.setEndAnchor(end);
        } else if (n instanceof FlowIndicatorNode) {
            final FlowIndicatorNode fi = (FlowIndicatorNode) n;
            final StaticAnchor startAnchor = new StaticAnchor(new org.eclipse.gef.geometry.planar.Point(0, 5));
            fi.setTranslateX(100.0);
            fi.setTranslateY(5.0);
            fi.setStartAnchor(startAnchor);
        }
    }
    final List<String> args = getParameters().getRaw();
    final IPath imagePath = args.size() > 0 ? new Path(args.get(0)) : null;
    baseStyle = StyleBuilder.create(Style.DEFAULT).fontSize(20.0).outlineColor(org.osate.ge.graphics.Color.BLUE).backgroundColor(org.osate.ge.graphics.Color.CYAN).imagePath(imagePath).build();
    // Add Nodes and Assign them to Rows and Columns
    final int numberOfColumns = 4;
    int row = 0, col = -1;
    for (final Node node : nodes) {
        // Increment the row and column first so that the final values will be the indices of the last node
        col++;
        if (col > (numberOfColumns - 1)) {
            col = 0;
            row++;
        }
        container.add(node, col, row);
    }
    // Create Row and Column Constraints
    for (int i = 0; i < numberOfColumns; i++) {
        ColumnConstraints c = new ColumnConstraints(100, 100, Double.MAX_VALUE);
        c.setHgrow(Priority.SOMETIMES);
        container.getColumnConstraints().add(c);
    }
    for (int i = 0; i <= row; i++) {
        RowConstraints rc = new RowConstraints(20, 20, Double.MAX_VALUE);
        rc.setVgrow(Priority.SOMETIMES);
        container.getRowConstraints().add(rc);
    }
    // Style the nodes
    refreshStyle();
    primaryStage.setScene(new Scene(container));
    // Setup the stage
    primaryStage.setResizable(true);
    primaryStage.setWidth(1920);
    primaryStage.setHeight(1080);
    primaryStage.setTitle("GEF Graphics");
    primaryStage.show();
}
Also used : Arrays(java.util.Arrays) PolyBuilder(org.osate.ge.graphics.PolyBuilder) StaticAnchor(org.eclipse.gef.fx.anchors.StaticAnchor) FxStyleApplier(org.osate.ge.gef.FxStyleApplier) NoteGraphicBuilder(org.osate.ge.graphics.internal.NoteGraphicBuilder) Application(javafx.application.Application) IPath(org.eclipse.core.runtime.IPath) Graphic(org.osate.ge.graphics.Graphic) ConnectionBuilder(org.osate.ge.graphics.ConnectionBuilder) LineStyle(org.osate.ge.graphics.LineStyle) ContainerShape(org.osate.ge.gef.ContainerShape) Point(org.osate.ge.graphics.Point) ModeGraphicBuilder(org.osate.ge.graphics.internal.ModeGraphicBuilder) Collectors(java.util.stream.Collectors) ArrowBuilder(org.osate.ge.graphics.ArrowBuilder) ParallelogramBuilder(org.osate.ge.graphics.internal.ParallelogramBuilder) StyleBuilder(org.osate.ge.graphics.StyleBuilder) EllipseNode(org.osate.ge.gef.EllipseNode) Priority(javafx.scene.layout.Priority) List(java.util.List) Path(org.eclipse.core.runtime.Path) BusGraphicBuilder(org.osate.ge.graphics.internal.BusGraphicBuilder) DeviceGraphicBuilder(org.osate.ge.graphics.internal.DeviceGraphicBuilder) ProcessorGraphicBuilder(org.osate.ge.graphics.internal.ProcessorGraphicBuilder) FxStyle(org.osate.ge.gef.FxStyle) OrthogonalLineBuilder(org.osate.ge.graphics.internal.OrthogonalLineBuilder) CornerRadii(javafx.scene.layout.CornerRadii) Scene(javafx.scene.Scene) ColumnConstraints(javafx.scene.layout.ColumnConstraints) RowConstraints(javafx.scene.layout.RowConstraints) LabelNode(org.osate.ge.gef.LabelNode) FeatureGraphicBuilder(org.osate.ge.graphics.internal.FeatureGraphicBuilder) FeatureGroupTypeGraphicBuilder(org.osate.ge.graphics.internal.FeatureGroupTypeGraphicBuilder) Style(org.osate.ge.graphics.Style) Insets(javafx.geometry.Insets) BackgroundFill(javafx.scene.layout.BackgroundFill) GridPane(javafx.scene.layout.GridPane) LabelBuilder(org.osate.ge.graphics.LabelBuilder) Color(javafx.scene.paint.Color) FolderGraphicBuilder(org.osate.ge.graphics.internal.FolderGraphicBuilder) EllipseBuilder(org.osate.ge.graphics.EllipseBuilder) FlowIndicatorBuilder(org.osate.ge.graphics.FlowIndicatorBuilder) Node(javafx.scene.Node) CheckBox(javafx.scene.control.CheckBox) ConnectionNode(org.osate.ge.gef.ConnectionNode) MemoryGraphicBuilder(org.osate.ge.graphics.internal.MemoryGraphicBuilder) RectangleBuilder(org.osate.ge.graphics.RectangleBuilder) FlowIndicatorNode(org.osate.ge.gef.FlowIndicatorNode) Background(javafx.scene.layout.Background) Stage(javafx.stage.Stage) ImageManager(org.osate.ge.gef.ImageManager) ChangeListener(javafx.beans.value.ChangeListener) LabelNode(org.osate.ge.gef.LabelNode) ColumnConstraints(javafx.scene.layout.ColumnConstraints) EllipseNode(org.osate.ge.gef.EllipseNode) LabelNode(org.osate.ge.gef.LabelNode) Node(javafx.scene.Node) ConnectionNode(org.osate.ge.gef.ConnectionNode) FlowIndicatorNode(org.osate.ge.gef.FlowIndicatorNode) RowConstraints(javafx.scene.layout.RowConstraints) FlowIndicatorNode(org.osate.ge.gef.FlowIndicatorNode) ContainerShape(org.osate.ge.gef.ContainerShape) ConnectionNode(org.osate.ge.gef.ConnectionNode) IPath(org.eclipse.core.runtime.IPath) Path(org.eclipse.core.runtime.Path) GridPane(javafx.scene.layout.GridPane) Background(javafx.scene.layout.Background) IPath(org.eclipse.core.runtime.IPath) EllipseNode(org.osate.ge.gef.EllipseNode) Graphic(org.osate.ge.graphics.Graphic) BackgroundFill(javafx.scene.layout.BackgroundFill) Point(org.osate.ge.graphics.Point) Scene(javafx.scene.Scene) Point(org.osate.ge.graphics.Point) CheckBox(javafx.scene.control.CheckBox) StaticAnchor(org.eclipse.gef.fx.anchors.StaticAnchor)

Example 14 with Point

use of org.osate.ge.graphics.Point 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 15 with Point

use of org.osate.ge.graphics.Point 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)

Aggregations

Point (org.osate.ge.graphics.Point)27 DiagramElement (org.osate.ge.internal.diagram.runtime.DiagramElement)19 DiagramNode (org.osate.ge.internal.diagram.runtime.DiagramNode)9 AgeDiagram (org.osate.ge.internal.diagram.runtime.AgeDiagram)8 Dimension (org.osate.ge.graphics.Dimension)7 DockArea (org.osate.ge.internal.diagram.runtime.DockArea)7 List (java.util.List)5 ElkLabel (org.eclipse.elk.graph.ElkLabel)5 Style (org.osate.ge.graphics.Style)5 AgeShape (org.osate.ge.graphics.internal.AgeShape)5 GraphicalEditorException (org.osate.ge.internal.GraphicalEditorException)5 ArrayList (java.util.ArrayList)4 Collection (java.util.Collection)4 Collections (java.util.Collections)4 Objects (java.util.Objects)4 Collectors (java.util.stream.Collectors)4 ArrayListMultimap (com.google.common.collect.ArrayListMultimap)3 ImmutableList (com.google.common.collect.ImmutableList)3 Lists (com.google.common.collect.Lists)3 Comparator (java.util.Comparator)3