use of org.osate.ge.graphics.internal.AgeConnection in project osate2 by osate.
the class ElkGraphBuilder method createElkGraphElementsForConnections.
/**
* Creates ELK edges for connection diagram nodes which are descendants of the specified node.
* Even though the results of the ELK edge routing are not used, it is still important because it affects the placements of shapes.
*/
private void createElkGraphElementsForConnections(final DiagramNode dn, final LayoutMapping mapping) {
for (final DiagramElement de : dn.getChildren()) {
if (de.getGraphic() instanceof AgeConnection) {
final AgeConnection connection = (AgeConnection) de.getGraphic();
// Flow indicators are represented by a node in the container which has a port and an edge connecting that port to the starting element
final ElkConnectableShape edgeStart = getConnectableShape(de.getStartElement(), mapping);
ElkConnectableShape edgeEnd = null;
if (connection.isFlowIndicator) {
// Find the first undocked ancestor for the flow indicator
final DiagramElement undockedContainer = DiagramElementUtil.getUndockedDiagramElement(de.getParent());
if (undockedContainer == null) {
// Ignore the flow indicator if unable to find a containing element which isn't docked.
continue;
}
// Find the ELK shape for the ancestor
final ElkConnectableShape endContainer = getConnectableShape(undockedContainer, mapping);
if (!(endContainer instanceof ElkNode)) {
// Ignore the flow indicator if the container isn't a node.
continue;
}
// Create the node for the end of the flow indicator
final ElkNode endNode = ElkGraphUtil.createNode((ElkNode) endContainer);
endContainer.setDimensions(0, 0);
endNode.setProperty(CoreOptions.NODE_SIZE_CONSTRAINTS, EnumSet.noneOf(SizeConstraint.class));
endNode.setProperty(CoreOptions.NODE_SIZE_OPTIONS, EnumSet.noneOf(SizeOptions.class));
// Create port
final ElkPort endPort = ElkGraphUtil.createPort(endNode);
endPort.setProperty(CoreOptions.PORT_SIDE, PortSide.WEST);
endPort.setX(0);
endPort.setY(0);
endPort.setWidth(0);
endPort.setHeight(0);
edgeEnd = endPort;
} else {
edgeEnd = getConnectableShape(de.getEndElement(), mapping);
}
if (edgeStart != null && edgeEnd != null) {
final ElkConnectableShape start = edgeStart;
final ElkConnectableShape end = edgeEnd;
boolean insideSelfLoopsYo = true;
// An example of this sort of edge is a steady state state transition in the EMV2
if (start == end) {
insideSelfLoopsYo = false;
}
final ElkEdge newEdge = ElkGraphUtil.createSimpleEdge(start, end);
// Allow edges with the same start and end shape because they layout as intended.
if (start == end && start instanceof ElkPort) {
continue;
}
// Ensure the edge has at least one section. Fixes NPE that can occur when laying out connections
// with the same source and destination port.
ElkGraphUtil.createEdgeSection(newEdge);
newEdge.setProperty(CoreOptions.INSIDE_SELF_LOOPS_YO, insideSelfLoopsYo);
mapping.getGraphMap().put(newEdge, de);
createElkLabels(de, newEdge, mapping);
// along with other edges
if (connection.isFlowIndicator && newEdge.getLabels().isEmpty()) {
final ElkLabel spacingLabel = createElkLabel(newEdge, "<Spacing>", new Dimension(10, 10));
if (!layoutConnectionLabels) {
spacingLabel.setProperty(CoreOptions.NO_LAYOUT, true);
}
}
}
}
createElkGraphElementsForConnections(de, mapping);
}
}
use of org.osate.ge.graphics.internal.AgeConnection in project osate2 by osate.
the class DiagramUpdater method removeInvalidConnections.
/**
* Removes invalid connections.
*/
private void removeInvalidConnections(final DiagramModification m, final Collection<DiagramElement> connectionElements) {
// Build Collection of All Invalid Connections
final Set<DiagramElement> invalidConnectionElements = new HashSet<>();
Iterator<DiagramElement> connectionElementsIt = connectionElements.iterator();
while (connectionElementsIt.hasNext()) {
final DiagramElement e = connectionElementsIt.next();
if (e.getStartElement() == null || (e.getEndElement() == null && !((AgeConnection) e.getGraphic()).isFlowIndicator)) {
invalidConnectionElements.add(e);
// Remove the connection from the connection collection and the diagram
connectionElementsIt.remove();
ghostAndRemove(m, e);
}
}
// Loop through the connections repeatedly until there are no longer any invalid connections referenced.
for (int lastSize = 0; (invalidConnectionElements.size() - lastSize) > 0; lastSize = invalidConnectionElements.size()) {
connectionElementsIt = connectionElements.iterator();
while (connectionElementsIt.hasNext()) {
final DiagramElement e = connectionElementsIt.next();
if (invalidConnectionElements.contains(e.getStartElement()) || invalidConnectionElements.contains(e.getEndElement())) {
invalidConnectionElements.add(e);
// Remove the connection from the connection collection and the diagram
removeConnectionAndDescendantConnections(e, connectionElements);
ghostAndRemove(m, e);
}
}
}
}
use of org.osate.ge.graphics.internal.AgeConnection in project osate2 by osate.
the class DiagramUpdater method updateElements.
/**
* @param container is the container for which to update the elements
* @param bos
* @param connectionElements is a collection to populate with connection elements.
*/
private void updateElements(final DiagramModification m, final DiagramNode container, final Collection<BusinessObjectNode> bos, final Collection<DiagramElement> connectionElements) {
for (final BusinessObjectNode n : bos) {
// Get existing element. The updateStructure() pass should have ensured that it exists if a valid element could be created.
final DiagramElement element = container.getChildByRelativeReference(n.getRelativeReference());
if (element == null) {
continue;
}
// Set fields
m.setCompleteness(element, n.getCompleteness());
// Set name fields
m.setLabelName(element, infoProvider.getLabelName(element));
m.setUserInterfaceName(element, infoProvider.getUserInterfaceName(element));
// Set the graphical Configuration
final GraphicalConfiguration graphicalConfiguration = infoProvider.getGraphicalConfiguration(element);
if (graphicalConfiguration == null) {
ghostAndRemove(m, element);
} else {
// Reset position of flow indicators if the start element has changed. This can occur when feature groups are expanded for example.
if (element.hasPosition() && DiagramElementPredicates.isFlowIndicator(element) && graphicalConfiguration.getConnectionSource() != element.getStartElement()) {
m.setPosition(element, null);
}
m.setGraphicalConfiguration(element, graphicalConfiguration);
// Set the dock area based on the default docking position
final DockingPosition defaultDockingPosition = graphicalConfiguration.getDefaultDockingPosition();
final boolean dockable = defaultDockingPosition != DockingPosition.NOT_DOCKABLE;
if (dockable) {
// If parent is docked, the child should use the group docking area
if (container instanceof DiagramElement && ((DiagramElement) container).getDockArea() != null) {
m.setDockArea(element, DockArea.GROUP);
} else if (element.getDockArea() == null) {
m.setDockArea(element, DockArea.fromDockingPosition(defaultDockingPosition));
}
} else {
// Ensure the dock area is null
m.setDockArea(element, null);
}
// Set the initial position if there is a value in the future element position map
// Set the position after the dock area so that setPosition() will know whether the element is dockable.
final Map<RelativeBusinessObjectReference, FutureElementInfo> futureElementInfos = futureElementInfoMap.get(container);
final FutureElementInfo futureElementInfo = futureElementInfos == null ? null : futureElementInfos.get(n.getRelativeReference());
final Point initialPosition = futureElementInfo != null ? futureElementInfo.position : null;
if (initialPosition != null) {
m.setPosition(element, initialPosition);
}
if (element.getGraphic() instanceof AgeConnection) {
// Add connection elements to the list so that they can be access later.
connectionElements.add(element);
}
// Update the element's children
updateElements(m, element, n.getChildren(), connectionElements);
}
}
}
Aggregations