use of org.osate.ge.graphics.internal.AgeConnection in project osate2 by osate.
the class DiagramElementLayoutUtil method getNodesToLayoutIncrementally.
private static Set<DiagramNode> getNodesToLayoutIncrementally(final DiagramNode node, final IncrementalLayoutMode mode, final Set<DiagramNode> results) {
final boolean alwaysLayoutContainer = mode != IncrementalLayoutMode.LAYOUT_CONTENTS;
for (final DiagramElement child : node.getChildren()) {
if (DiagramElementPredicates.isShape(child)) {
final boolean positionIsSet = child.hasPosition() || !DiagramElementPredicates.isMoveableShape(child);
final boolean sizeIsSet = child.hasSize() || !DiagramElementPredicates.isResizeable(child);
// This occurs when a user has created an element using the palette
if (positionIsSet && !sizeIsSet) {
results.add(child);
} else {
if (sizeIsSet && positionIsSet) {
getNodesToLayoutIncrementally(child, mode, results);
} else {
// If always layout container is specified, layout container
// If container does not have any layed out shapes, layout container.
final boolean layoutContainer = alwaysLayoutContainer || !hasLayedOutShapes(node.getChildren());
if (layoutContainer) {
results.add(node);
break;
} else {
results.add(child);
}
}
}
} else if (DiagramElementPredicates.isConnection(child)) {
final AgeConnection c = (AgeConnection) child.getGraphic();
if (c.isFlowIndicator) {
// Layout the flow indicator's not docked container if its position has not been set
if (child.getStartElement() != null && (!child.isBendpointsSet() || !child.hasPosition())) {
// If we should lay out container than lay out the container of the flow indicator
if (alwaysLayoutContainer) {
DiagramElement undockedContainer = DiagramElementUtil.getUndockedDiagramElement(child.getStartElement().getParent());
if (undockedContainer != null) {
results.add(undockedContainer);
}
} else {
// Otherwise, layout the flow indicator
results.add(child);
}
}
} else if (alwaysLayoutContainer) {
// Only layout the connection if its bendpoints have not been set regardless of whether it has any bendpoints.
if (child.getStartElement() != null && child.getEndElement() != null && !child.isBendpointsSet()) {
final Optional<BusinessObjectContext> ancestor = BusinessObjectContext.getFirstCommonAncestor(child.getStartElement().getParent(), child.getEndElement().getParent());
if (ancestor.isPresent()) {
results.add((DiagramNode) ancestor.get());
}
}
} else if (isFeatureSelfLoopConnection(child) && !child.isBendpointsSet()) {
results.add(child);
}
}
}
return results;
}
use of org.osate.ge.graphics.internal.AgeConnection in project osate2 by osate.
the class DiagramElementLayoutUtil method getConnectionsAffectedByMove.
/**
* Returns the connections which are affected by moving the specified elements
* @param movedElement is the element which to get the affected connections
* @param diagram is the diagram which contains the connections.
* @param checkDescendants whether to check descendants of the specified elements when looking for connections
* @return he connections which are affected by moving the specified elements
*/
public static Stream<DiagramElement> getConnectionsAffectedByMove(final DiagramElement movedElement, final AgeDiagram diagram, final boolean checkDescendants) {
// Build a set containing the moved elements and all of their descendant which are represented as shapes
final Set<BusinessObjectContext> diagramElements = checkDescendants ? movedElement.getAllDescendants().collect(Collectors.toSet()) : Collections.singleton(movedElement);
final Stream<DiagramElement> connections = diagram.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.
return connections.filter(c -> {
final DiagramElement startElement = c.getStartElement();
final DiagramElement endElement = c.getEndElement();
final boolean isFlowIndicator = ((AgeConnection) c.getGraphic()).isFlowIndicator;
return diagramElements.contains(startElement) && (diagramElements.contains(endElement) || isFlowIndicator);
});
}
use of org.osate.ge.graphics.internal.AgeConnection in project osate2 by osate.
the class ElkGraphBuilder method createElkLabels.
private void createElkLabels(final DiagramElement parentElement, final ElkGraphElement parentLayoutElement, final LayoutMapping mapping) {
// Don't create labels for ElkPort. The bounds of the port contain their labels.
if (parentLayoutElement instanceof ElkPort) {
return;
}
final boolean isConnection = parentElement.getGraphic() instanceof AgeConnection;
final Style style = styleProvider.getStyle(parentElement);
if (style.getPrimaryLabelVisible()) {
// Create Primary Label
if (parentElement.getLabelName() != null) {
final ElkLabel elkLabel = createElkLabel(parentLayoutElement, parentElement.getLabelName(), layoutInfoProvider.getPrimaryLabelSize(parentElement));
if (isConnection) {
if (!layoutConnectionLabels) {
elkLabel.setProperty(CoreOptions.NO_LAYOUT, true);
}
mapping.getGraphMap().put(elkLabel, new PrimaryConnectionLabelReference(parentElement));
}
}
}
// Create label for annotations which are part of the graphic configuration. These are only supported by non-connections.
if (!isConnection && parentElement.getGraphicalConfiguration().getAnnotation() != null) {
createElkLabel(parentLayoutElement, parentElement.getGraphicalConfiguration().getAnnotation(), layoutInfoProvider.getAnnotationLabelSize(parentElement));
}
// Create Secondary Labels
parentElement.getChildren().stream().filter(c -> c.getGraphic() instanceof Label).forEachOrdered(labelElement -> {
final ElkLabel elkLabel = createElkLabel(parentLayoutElement, labelElement.getLabelName(), layoutInfoProvider.getPrimaryLabelSize(labelElement));
if (isConnection) {
if (!layoutConnectionLabels) {
elkLabel.setProperty(CoreOptions.NO_LAYOUT, true);
}
mapping.getGraphMap().put(elkLabel, new SecondaryConnectionLabelReference(labelElement));
}
});
if (parentLayoutElement instanceof ElkNode) {
parentLayoutElement.setProperty(CoreOptions.NODE_LABELS_PLACEMENT, getNodeLabelPlacement(style));
}
}
use of org.osate.ge.graphics.internal.AgeConnection 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));
}
}
}
use of org.osate.ge.graphics.internal.AgeConnection 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)));
}
}
}
});
}
Aggregations