Search in sources :

Example 6 with Point

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

the class GefAgeDiagram method updateDiagramFromSceneGraph.

/**
 * Triggers a layout of the scene graph nodes and then updates the diagram based on the layout of the scene graph nodes.
 * Updates position and size. Optionally updates bendpoints.
 * Should only be called after the root node has been added to a scene.
 * @param updateBendpoints whether to update bendpoints in addition to the position and size of elements.
 */
public void updateDiagramFromSceneGraph(final boolean updateBendpoints) {
    updatingDiagramFromSceneGraph = true;
    forceSceneGraphLayout();
    diagram.modify("Update Diagram from Scene Graph", m -> {
        for (final Entry<DiagramElement, GefDiagramElement> e : this.diagramElementToGefDiagramElementMap.entrySet()) {
            final DiagramElement de = e.getKey();
            final GefDiagramElement ge = e.getValue();
            final Node sceneNode = ge.sceneNode;
            final DiagramNode parent = de.getParent();
            if (DiagramElementPredicates.isMoveable(de)) {
                if (parent instanceof DiagramElement && DiagramElementPredicates.isConnection((DiagramElement) parent)) {
                    // Store the preferred position.
                    final Point2D p = PreferredPosition.get(sceneNode);
                    m.setPosition(de, GefAgeDiagramUtil.toAgePoint(p));
                } else {
                    final double newX = sceneNode.getLayoutX();
                    final double newY = sceneNode.getLayoutY();
                    if (de.hasPosition() || (newX != 0.0 || newY != 0)) {
                        m.setPosition(de, new Point(newX, newY));
                    }
                }
                if (sceneNode instanceof DockedShape && ge.parentDiagramNodeSceneNode instanceof ContainerShape) {
                    final DockedShape ds = (DockedShape) sceneNode;
                    final DockSide side = ds.getSide();
                    if (side != null) {
                        m.setDockArea(de, GefAgeDiagramUtil.toDockArea(side));
                    }
                }
            }
            // Set the size for all elements. Even for non-resizable elements, the layout engine uses the sizes in the diagram.
            // This is important for secondary labels of connections.
            final Bounds layoutBounds = sceneNode.getLayoutBounds();
            if (de.hasSize() || (layoutBounds.getWidth() != 0.0 || layoutBounds.getHeight() != 0)) {
                m.setSize(de, new Dimension(layoutBounds.getWidth(), layoutBounds.getHeight()));
            }
            if (DiagramElementPredicates.isConnection(de) && sceneNode instanceof BaseConnectionNode) {
                final BaseConnectionNode cn = (BaseConnectionNode) sceneNode;
                // Primary label position
                if (!cn.getPrimaryLabels().isEmpty()) {
                    // Store the preferred position of the connection label
                    final Node primaryLabel = cn.getPrimaryLabels().get(0);
                    final Point2D p = PreferredPosition.get(primaryLabel);
                    m.setConnectionPrimaryLabelPosition(de, GefAgeDiagramUtil.toAgePoint(p));
                }
                // Bendpoints
                if (updateBendpoints) {
                    final List<org.eclipse.gef.geometry.planar.Point> controlPoints = cn.getInnerConnection().getControlPoints();
                    if (!controlPoints.isEmpty() || !de.getBendpoints().isEmpty()) {
                        final Point controlPointOrigin = getControlPointOriginFromSceneGraph(sceneNode);
                        m.setBendpoints(de, cn.getInnerConnection().getControlPoints().stream().map(p -> new Point(p.x + controlPointOrigin.x, p.y + controlPointOrigin.y)).collect(Collectors.toList()));
                    }
                }
            }
        }
    });
    updatingDiagramFromSceneGraph = false;
}
Also used : DiagramNode(org.osate.ge.internal.diagram.runtime.DiagramNode) BaseConnectionNode(org.osate.ge.gef.BaseConnectionNode) DiagramRootNode(org.osate.ge.gef.DiagramRootNode) DiagramNode(org.osate.ge.internal.diagram.runtime.DiagramNode) FeatureGroupNode(org.osate.ge.gef.FeatureGroupNode) LabelNode(org.osate.ge.gef.LabelNode) Node(javafx.scene.Node) ConnectionNode(org.osate.ge.gef.ConnectionNode) FlowIndicatorNode(org.osate.ge.gef.FlowIndicatorNode) DockedShape(org.osate.ge.gef.DockedShape) Bounds(javafx.geometry.Bounds) Point(org.osate.ge.graphics.Point) Dimension(org.osate.ge.graphics.Dimension) DiagramElement(org.osate.ge.internal.diagram.runtime.DiagramElement) DockSide(org.osate.ge.gef.DockSide) Point2D(javafx.geometry.Point2D) ContainerShape(org.osate.ge.gef.ContainerShape) BaseConnectionNode(org.osate.ge.gef.BaseConnectionNode)

Example 7 with Point

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

the class GefAgeDiagram method updateSceneNode.

/**
 * Updates the scene nodes related to the specified GEF diagram element based on the diagram element.
 * Only updates properties which do not effect the structure of the scene graph. Not-recursive
 * @param gefDiagramElement is the GEF diagram element for which scene nodes will be updated.
 */
private void updateSceneNode(final GefDiagramElement gefDiagramElement) {
    final DiagramElement diagramElement = gefDiagramElement.diagramElement;
    final Node sceneNode = gefDiagramElement.sceneNode;
    // Update connections
    if (sceneNode instanceof BaseConnectionNode) {
        final BaseConnectionNode connectionNode = (BaseConnectionNode) sceneNode;
        final Point controlPointOrigin = getControlPointOriginFromDiagram(diagramElement, sceneNode);
        if (sceneNode instanceof FlowIndicatorNode) {
            PreferredPosition.set(sceneNode, convertPoint(diagramElement.getPosition()));
        }
        // Update the connection anchor
        updateConnectionAnchors(diagramElement, (BaseConnectionNode) sceneNode);
        // Set control points. Coordinates are specified in the diagram model relative to the diagram. The need to be specified relative to the
        // connection position. For regular connection this is the same because the node's parent is the diagram node.
        // However, flow indicators have a position and have parent nodes other than the diagram.
        connectionNode.getInnerConnection().setControlPoints(diagramElement.getBendpoints().stream().map(p -> new org.eclipse.gef.geometry.planar.Point(p.x - controlPointOrigin.x, p.y - controlPointOrigin.y)).collect(Collectors.toList()));
        PreferredPosition.set(gefDiagramElement.primaryLabel, convertPoint(diagramElement.getConnectionPrimaryLabelPosition()));
    } else if (sceneNode instanceof LabelNode) {
        // Such a label represents a secondary label
        final LabelNode label = (LabelNode) sceneNode;
        label.setText(Strings.nullToEmpty(diagramElement.getLabelName()));
        setLabelVisibility(label);
        // Update element position
        if (gefDiagramElement.parentDiagramNodeSceneNode instanceof BaseConnectionNode) {
            PreferredPosition.set(label, convertPoint(diagramElement.getPosition()));
        }
    } else if (sceneNode instanceof ContainerShape) {
        final ContainerShape containerShape = (ContainerShape) sceneNode;
        PreferredPosition.set(sceneNode, convertPoint(diagramElement.getPosition()));
        // Set configured size
        final Dimension size = diagramElement.getSize();
        if (size == null) {
            containerShape.setConfiguredWidth(ContainerShape.NOT_SPECIFIED);
            containerShape.setConfiguredHeight(ContainerShape.NOT_SPECIFIED);
        } else {
            containerShape.setConfiguredWidth(size.width);
            containerShape.setConfiguredHeight(size.height);
        }
    } else if (sceneNode instanceof DockedShape) {
        final DockedShape n = (DockedShape) sceneNode;
        PreferredPosition.set(sceneNode, convertPoint(diagramElement.getPosition()));
        // Set configured size
        final Dimension size = diagramElement.getSize();
        if (size == null) {
            n.setConfiguredWidth(ContainerShape.NOT_SPECIFIED);
            n.setConfiguredHeight(ContainerShape.NOT_SPECIFIED);
        } else {
            n.setConfiguredWidth(size.width);
            n.setConfiguredHeight(size.height);
        }
        final DockArea dockArea = diagramElement.getDockArea();
        if (dockArea != null && dockArea != DockArea.GROUP && gefDiagramElement.parentDiagramNodeSceneNode instanceof ContainerShape) {
            final DockSide side = GefAgeDiagramUtil.toDockSide(dockArea);
            final ContainerShape cs = (ContainerShape) gefDiagramElement.parentDiagramNodeSceneNode;
            cs.addOrUpdateDockedChild(n, side);
        }
    }
    // Update the primary label
    if (gefDiagramElement.primaryLabel != null) {
        gefDiagramElement.primaryLabel.setText(getPrimaryLabelText(diagramElement));
        setLabelVisibility(gefDiagramElement.primaryLabel);
        gefDiagramElement.primaryLabel.setWrapText(diagramElement.getGraphicalConfiguration().isPrimaryLabelIsMultiline());
    }
    // Update the secondary label
    if (gefDiagramElement.annotationLabel != null) {
        final String annotation = diagramElement.getGraphicalConfiguration().getAnnotation();
        gefDiagramElement.annotationLabel.setText(Strings.nullToEmpty(annotation));
        setLabelVisibility(gefDiagramElement.annotationLabel);
    }
}
Also used : LabelNode(org.osate.ge.gef.LabelNode) BaseConnectionNode(org.osate.ge.gef.BaseConnectionNode) DiagramRootNode(org.osate.ge.gef.DiagramRootNode) DiagramNode(org.osate.ge.internal.diagram.runtime.DiagramNode) FeatureGroupNode(org.osate.ge.gef.FeatureGroupNode) LabelNode(org.osate.ge.gef.LabelNode) Node(javafx.scene.Node) ConnectionNode(org.osate.ge.gef.ConnectionNode) FlowIndicatorNode(org.osate.ge.gef.FlowIndicatorNode) DockedShape(org.osate.ge.gef.DockedShape) Point(org.osate.ge.graphics.Point) Dimension(org.osate.ge.graphics.Dimension) DiagramElement(org.osate.ge.internal.diagram.runtime.DiagramElement) FlowIndicatorNode(org.osate.ge.gef.FlowIndicatorNode) DockSide(org.osate.ge.gef.DockSide) DockArea(org.osate.ge.internal.diagram.runtime.DockArea) ContainerShape(org.osate.ge.gef.ContainerShape) BaseConnectionNode(org.osate.ge.gef.BaseConnectionNode)

Example 8 with Point

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

the class AgeDiagramTest method testElementUpdatedEventMultiple.

// Ensure that a single event is received when the same element is updated multiple times.
@Test
public void testElementUpdatedEventMultiple() {
    final DiagramElement e = addRootElementAndResetCounter(1);
    // Test the update event
    diagram.modify("Set Dock Area nd Position", m -> {
        m.setDockArea(e, DockArea.TOP);
        m.setPosition(e, new Point(100, 100));
    });
    assertThat(ml.elementUpdatedEventsReceived, is(equalTo(1)));
    assertThat(ml.modificationsCompletedEventsReceived, is(equalTo(1)));
    assertThat(ml.getTotalEventsReceived(), is(equalTo(2)));
    assertThat(ml.lastUpdateEvent.updatedFields, is(equalTo(EnumSet.of(ModifiableField.DOCK_AREA, ModifiableField.POSITION))));
}
Also used : DiagramElement(org.osate.ge.internal.diagram.runtime.DiagramElement) Point(org.osate.ge.graphics.Point) Test(org.junit.Test)

Example 9 with Point

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

the class AgeDiagramTest method testElementUpdatedEventSingle.

// Ensure that the element updated event is received.
@Test
public void testElementUpdatedEventSingle() {
    final DiagramElement e = addRootElementAndResetCounter(1);
    // Test the update event
    diagram.modify("Set Position", m -> m.setPosition(e, new Point(100, 100)));
    assertThat(ml.elementUpdatedEventsReceived, is(equalTo(1)));
    assertThat(ml.modificationsCompletedEventsReceived, is(equalTo(1)));
    assertThat(ml.getTotalEventsReceived(), is(equalTo(2)));
    assertThat(ml.lastUpdateEvent.updatedFields, is(equalTo(EnumSet.of(ModifiableField.POSITION))));
}
Also used : DiagramElement(org.osate.ge.internal.diagram.runtime.DiagramElement) Point(org.osate.ge.graphics.Point) Test(org.junit.Test)

Example 10 with Point

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

the class OperationResultsProcessor method processResults.

/**
 * @param editor the editor which is displaying the diagram for which the operation was executed
 * @param targetNode is the node to which the targetPosition is relative.
 * @param targetPosition the position at which the operation was executed. Relative to the target node. This is used to position
 * a newly created diagram element.
 * @param results the results to process
 */
public static void processResults(final InternalDiagramEditor editor, final DiagramNode targetNode, final Point targetPosition, final OperationResults results) {
    Objects.requireNonNull(editor, "diagram must not be null");
    boolean update = false;
    // Notify the diagram updater to add the element on the next update
    for (final Entry<BusinessObjectContext, OperationResults.BusinessObjectToShowDetails> containerToBoEntry : results.getContainerToBoToShowDetailsMap().entries()) {
        if (containerToBoEntry.getKey() instanceof DiagramNode) {
            final DiagramNode containerNode = (DiagramNode) containerToBoEntry.getKey();
            final OperationResults.BusinessObjectToShowDetails newValue = containerToBoEntry.getValue();
            // Don't set the position if multiple items are being added.
            // Don't set the position if the incremental layout mode is set to diagram.
            // This will ensure the shape is laid out even if it is a docked shape.
            final Point position;
            if (results.getContainerToBoToShowDetailsMap().size() == 1 && LayoutPreferences.getCurrentIncrementalLayoutMode() != IncrementalLayoutMode.LAYOUT_DIAGRAM && containerNode == targetNode) {
                position = targetPosition;
            } else {
                position = null;
            }
            // If the BO being added is an embedded business object, it must be provided to the diagram updater.
            final EmbeddedBusinessObject embeddedBo = (newValue.bo instanceof EmbeddedBusinessObject) ? (EmbeddedBusinessObject) newValue.bo : null;
            editor.getDiagramUpdater().addToNextUpdate(containerNode, newValue.ref, new FutureElementInfo(position, embeddedBo));
            if (embeddedBo != null) {
                update = true;
            }
        }
    }
    // If an embedded business object was added, then update the diagram to ensure it was updated.
    if (update) {
        editor.updateDiagram();
    }
}
Also used : DiagramNode(org.osate.ge.internal.diagram.runtime.DiagramNode) FutureElementInfo(org.osate.ge.internal.diagram.runtime.updating.FutureElementInfo) OperationResults(org.osate.ge.internal.operations.OperationResults) EmbeddedBusinessObject(org.osate.ge.internal.model.EmbeddedBusinessObject) Point(org.osate.ge.graphics.Point) BusinessObjectContext(org.osate.ge.BusinessObjectContext)

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