use of org.osate.ge.gef.FlowIndicatorNode in project osate2 by osate.
the class GefAgeDiagram method updateConnectionAnchors.
private void updateConnectionAnchors(final DiagramElement de, final BaseConnectionNode node) {
if (node instanceof FlowIndicatorNode) {
final FlowIndicatorNode fi = (FlowIndicatorNode) node;
final IAnchor anchor = GefAgeDiagramUtil.getAnchor(this, de.getStartElement(), null);
if (anchor != null) {
fi.setStartAnchor(anchor);
}
} else if (node instanceof ConnectionNode) {
final ConnectionNode cn = (ConnectionNode) node;
final IAnchor startAnchor = GefAgeDiagramUtil.getAnchor(this, de.getStartElement(), de.getEndElement());
final IAnchor endAnchor = GefAgeDiagramUtil.getAnchor(this, de.getEndElement(), de.getStartElement());
if (startAnchor != null && endAnchor != null) {
cn.setStartAnchor(startAnchor);
cn.setEndAnchor(endAnchor);
}
} else {
throw new AgeGefRuntimeException("Unexpected node: " + node);
}
}
use of org.osate.ge.gef.FlowIndicatorNode in project osate2 by osate.
the class MoveConnectionPointInteraction method onMouseDragged.
@Override
protected Interaction.InteractionState onMouseDragged(final MouseEvent e) {
if (e.getButton() != MouseButton.PRIMARY) {
return super.onMouseDragged(e);
}
final Transform sceneToDiagramTransform = editor.getGefDiagram().getSceneNode().getSceneToLocalTransform();
final Point2D eventInDiagram = sceneToDiagramTransform.transform(e.getSceneX(), e.getSceneY());
final Point2D snappedDiagramPosition = InputEventHandlerUtil.snap(editor, eventInDiagram, false);
if (activeHandle instanceof FlowIndicatorPositionHandle) {
final FlowIndicatorNode c = ((FlowIndicatorPositionHandle) activeHandle).getSceneNode();
final Node positioningReference = c.getPositioningReferenceOrThrow();
// The the position relative to the reference
final Point2D newPoint = getLocalPositionFromDiagram(editor.getGefDiagram(), snappedDiagramPosition, positioningReference);
final Point2D oldPosition = PreferredPosition.get(activeHandle.getSceneNode());
PreferredPosition.set(activeHandle.getSceneNode(), newPoint);
// Adjust positions of control points so that only the ending position of the flow indicator is moved.
if (oldPosition != null) {
final double dx = newPoint.getX() - oldPosition.getX();
final double dy = newPoint.getY() - oldPosition.getY();
c.getInnerConnection().setControlPoints(c.getInnerConnection().getControlPoints().stream().map(p -> new Point(p.x - dx, p.y - dy)).collect(Collectors.toList()));
}
} else if (controlPointIndex != null) {
final BaseConnectionNode c = activeHandle.getSceneNode();
final Connection ic = c.getInnerConnection();
final Point2D newPosition = getLocalPositionFromDiagram(editor.getGefDiagram(), snappedDiagramPosition, ic);
// Get a list of the control points and the start and end points of connection.
final List<Point> allPoints = ic.getPointsUnmodifiable();
final List<org.eclipse.gef.geometry.planar.Point> controlPoints = ic.getControlPoints();
final ArrayList<org.eclipse.gef.geometry.planar.Point> endAndControlPoints = new ArrayList<>(controlPoints.size() + 2);
endAndControlPoints.add(allPoints.get(0));
endAndControlPoints.addAll(controlPoints);
endAndControlPoints.add(allPoints.get(allPoints.size() - 1));
// Determine whether the point should be removed or added
final boolean remove = controlPointExists && distanceToLineSegment(newPosition, endAndControlPoints, controlPointIndex, controlPointIndex + 2) <= REMOVE_POINT_DISTANCE;
final boolean add = !remove && !controlPointExists && distanceToLineSegment(newPosition, endAndControlPoints, controlPointIndex, controlPointIndex + 1) >= ADD_POINT_DISTANCE;
if (remove) {
c.getInnerConnection().removeControlPoint(controlPointIndex);
controlPointExists = false;
} else if (add) {
controlPoints.add(controlPointIndex, FX2Geometry.toPoint(newPosition));
ic.setControlPoints(controlPoints);
controlPointExists = true;
} else if (controlPointExists) {
ic.setControlPoint(controlPointIndex, FX2Geometry.toPoint(newPosition));
}
}
return InteractionState.IN_PROGRESS;
}
use of org.osate.ge.gef.FlowIndicatorNode in project osate2 by osate.
the class MoveConnectionPointInteraction method onMouseReleased.
@Override
protected Interaction.InteractionState onMouseReleased(final MouseEvent e) {
if (e.getButton() != MouseButton.PRIMARY) {
return super.onMouseReleased(e);
}
final BaseConnectionNode connectionNode = activeHandle.getSceneNode();
try {
final Transform sceneToDiagramTransform = editor.getGefDiagram().getSceneNode().getLocalToSceneTransform().createInverse();
final Transform connectionToDiagramTransform = sceneToDiagramTransform.createConcatenation(connectionNode.getLocalToSceneTransform());
editor.getDiagram().modify("Update Control Point", m -> {
final DiagramElement diagramElementToModify = editor.getGefDiagram().getDiagramElement(connectionNode);
if (diagramElementToModify == null) {
throw new AgeGefRuntimeException("Unable to find diagram element");
}
m.setBendpoints(diagramElementToModify, connectionNode.getInnerConnection().getControlPoints().stream().map(p -> GefAgeDiagramUtil.toAgePoint(connectionToDiagramTransform.transform(p.x, p.y))).collect(Collectors.toList()));
if (connectionNode instanceof FlowIndicatorNode) {
m.setPosition(diagramElementToModify, GefAgeDiagramUtil.toAgePoint(PreferredPosition.get(connectionNode)));
}
});
// The scene will be updated based on our modification. No need to update the scene in close().
updateSceneGraphOnComplete = false;
} catch (NonInvertibleTransformException ex) {
throw new AgeGefRuntimeException("Unable to create diagram scene to local transform", ex);
}
return InteractionState.COMPLETE;
}
use of org.osate.ge.gef.FlowIndicatorNode in project osate2 by osate.
the class GefAgeDiagram method ensureSceneNodeExists.
/**
* Ensures that a scene node exists for the specified GEF diagram element.
* Creates or recreates scene nodes and adds to the scene graph as necessary. Updates the specified GEF diagram element.
* @param gefDiagramElement the GEF diagram element for which to ensure that the scene node exists.
* @param parentDiagramElementSceneNode the scene node for the parent of the GEF diagram element. This is specified instead of using
* the value contained in the GEF diagram element because it may not be up to date.
* @return the scene node for the diagram element. This specified GEF diagram element will be updated to hold this value.
*/
private Node ensureSceneNodeExists(GefDiagramElement gefDiagramElement, final Node parentDiagramElementSceneNode) {
Objects.requireNonNull(parentDiagramElementSceneNode, "parentDiagramElementScenenNode must not be null");
final Graphic graphic = Objects.requireNonNull(gefDiagramElement.diagramElement.getGraphic(), "graphic must not be null");
final DiagramElement childDiagramElement = gefDiagramElement.diagramElement;
//
// The following final variables determine the operations that needs to be performed by the remainder of the function.
// They are set by comparing the previous state with the current state of the diagram element.
//
final boolean docked = childDiagramElement.getDockArea() != null;
final boolean parentIsConnection = parentDiagramElementSceneNode instanceof BaseConnectionNode;
final boolean create = !Objects.equals(graphic, gefDiagramElement.sourceGraphic) || docked != gefDiagramElement.sceneNode instanceof DockedShape || parentIsConnection != gefDiagramElement.parentDiagramNodeSceneNode instanceof BaseConnectionNode;
final boolean addToScene = create || gefDiagramElement.parentDiagramNodeSceneNode != parentDiagramElementSceneNode;
final boolean removeFromScene = addToScene && gefDiagramElement.sceneNode != null;
// Update other fields
gefDiagramElement.sourceGraphic = graphic;
// Remove the node for the scene graph
if (removeFromScene) {
removeNode(gefDiagramElement.sceneNode);
}
//
if (create) {
// Remove mapping to old scene node
if (gefDiagramElement.sceneNode != null) {
sceneNodeToGefDiagramElementMap.remove(gefDiagramElement.sceneNode);
}
// Create the new node. Create a graphic and then a wrapper as appropriate
final Node graphicNode = GraphicToFx.createNode(graphic);
if (graphicNode instanceof BaseConnectionNode) {
final BaseConnectionNode newConnectionNode = (BaseConnectionNode) graphicNode;
gefDiagramElement.sceneNode = graphicNode;
// Create the primary label node
final LabelNode primaryLabel = new LabelNode();
newConnectionNode.getPrimaryLabels().add(primaryLabel);
gefDiagramElement.primaryLabel = primaryLabel;
} else if (graphicNode instanceof LabelNode) {
gefDiagramElement.sceneNode = graphicNode;
} else if (parentIsConnection) {
// NOTE: This should only occur for fixed sized graphics
// Rotate midpoint decorations 180.0 degrees because our connection not expects midpoint decorations to be oriented as if
// the connection was left to right and that is not how graphics are specified in the graphical editor.
final Group rotationWrapper = new Group();
rotationWrapper.getChildren().add(graphicNode);
rotationWrapper.setRotate(180.0);
gefDiagramElement.sceneNode = rotationWrapper;
} else {
if (docked) {
final DockedShape newDockedShape = new DockedShape();
newDockedShape.setGraphic(graphicNode);
gefDiagramElement.sceneNode = newDockedShape;
// Create the primary label node
final LabelNode primaryLabel = new LabelNode();
newDockedShape.getPrimaryLabels().add(primaryLabel);
gefDiagramElement.primaryLabel = primaryLabel;
// Create annotation node
final LabelNode annotationLabel = new LabelNode();
newDockedShape.getSecondaryLabels().add(annotationLabel);
gefDiagramElement.annotationLabel = annotationLabel;
} else {
final ContainerShape newContainerShape = new ContainerShape();
newContainerShape.setGraphic(graphicNode);
gefDiagramElement.sceneNode = newContainerShape;
// Create the primary label node
final LabelNode primaryLabel = new LabelNode();
newContainerShape.getPrimaryLabels().add(primaryLabel);
gefDiagramElement.primaryLabel = primaryLabel;
}
}
// Add mapping to scene node
if (gefDiagramElement.sceneNode != null) {
sceneNodeToGefDiagramElementMap.put(gefDiagramElement.sceneNode, gefDiagramElement);
}
StyleRoot.set(gefDiagramElement.sceneNode, true);
}
//
if (addToScene) {
if (gefDiagramElement.sceneNode instanceof BaseConnectionNode) {
diagramNode.getChildren().add(gefDiagramElement.sceneNode);
// Flow indicators are positioned relative to the scene node of the parent diagram element
if (gefDiagramElement.sceneNode instanceof FlowIndicatorNode) {
if (parentDiagramElementSceneNode instanceof ContainerShape) {
((FlowIndicatorNode) gefDiagramElement.sceneNode).setPositioningReference(parentDiagramElementSceneNode);
} else {
throw new AgeGefRuntimeException("Unexpected parent diagram element scene node for flow indicator: " + parentDiagramElementSceneNode);
}
}
} else if (gefDiagramElement.sceneNode instanceof LabelNode) {
// Add label to parent
if (parentDiagramElementSceneNode instanceof ContainerShape) {
((ContainerShape) parentDiagramElementSceneNode).getSecondaryLabels().add(gefDiagramElement.sceneNode);
} else if (parentDiagramElementSceneNode instanceof DockedShape) {
((DockedShape) parentDiagramElementSceneNode).getSecondaryLabels().add(gefDiagramElement.sceneNode);
} else if (parentDiagramElementSceneNode instanceof BaseConnectionNode) {
((BaseConnectionNode) parentDiagramElementSceneNode).getSecondaryLabels().add(gefDiagramElement.sceneNode);
} else {
throw new AgeGefRuntimeException("Unexpected parent node for label: " + parentDiagramElementSceneNode);
}
} else if (parentIsConnection) {
((BaseConnectionNode) parentDiagramElementSceneNode).getMidpointDecorations().add(gefDiagramElement.sceneNode);
} else {
final DockArea dockArea = childDiagramElement.getDockArea();
if (gefDiagramElement.sceneNode instanceof DockedShape) {
final DockedShape dockedShape = (DockedShape) gefDiagramElement.sceneNode;
// Add the docked shape to the appropriate list
if (parentDiagramElementSceneNode instanceof ContainerShape) {
final ContainerShape containerShapeParent = (ContainerShape) parentDiagramElementSceneNode;
containerShapeParent.addOrUpdateDockedChild(dockedShape, GefAgeDiagramUtil.toDockSide(dockArea));
} else if (parentDiagramElementSceneNode instanceof DockedShape) {
final DockedShape dockedShapeParent = (DockedShape) parentDiagramElementSceneNode;
dockedShapeParent.getNestedChildren().add(dockedShape);
} else {
throw new AgeGefRuntimeException("Unexpected parent for docked shape: " + parentDiagramElementSceneNode);
}
} else {
if (parentDiagramElementSceneNode instanceof ContainerShape) {
final ContainerShape containerShapeParent = (ContainerShape) parentDiagramElementSceneNode;
containerShapeParent.getFreeChildren().add(gefDiagramElement.sceneNode);
} else if (parentDiagramElementSceneNode instanceof Group) {
((Group) parentDiagramElementSceneNode).getChildren().add(gefDiagramElement.sceneNode);
} else {
throw new AgeGefRuntimeException("Unexpected parent node for container shape: " + parentDiagramElementSceneNode);
}
}
}
gefDiagramElement.parentDiagramNodeSceneNode = parentDiagramElementSceneNode;
}
return gefDiagramElement.sceneNode;
}
use of org.osate.ge.gef.FlowIndicatorNode 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);
}
}
Aggregations