use of org.osate.ge.graphics.internal.AgeShape in project osate2 by osate.
the class DiagramElementLayoutUtil method getAbsolutePosition.
/**
* Gets the absolute position of a node. This absolute position only considers the positions of shapes.
* Connections are ignored.
* @param dn the node for which to get the absolute position.
* @return the absolute position.
*/
public static Point getAbsolutePosition(final DiagramNode dn) {
int x = 0;
int y = 0;
for (DiagramNode tmp = dn; tmp instanceof DiagramElement; tmp = tmp.getParent()) {
final DiagramElement tmpDe = (DiagramElement) tmp;
if (tmpDe.getGraphic() instanceof AgeShape) {
// Ignore connections in case the X and Y values are not 0.
x += tmpDe.getX();
y += tmpDe.getY();
}
}
return new Point(x, y);
}
use of org.osate.ge.graphics.internal.AgeShape in project osate2 by osate.
the class DiagramElementLayoutUtil method applyProperties.
/**
* Sets the ELK properties of elements in the specified layout mapping based on the layout options.
* @param layoutMapping
*/
private static void applyProperties(final DiagramNode rootDiagramNode, final LayoutMapping layoutMapping) {
// Set the minimum node size based on the ports and their assigned sides.
final IGraphElementVisitor minNodeSizeVisitor = element -> {
if (element instanceof ElkNode) {
final ElkNode n = (ElkNode) element;
final double maxLabelWidth = n.getLabels().stream().mapToDouble(l -> l.getWidth()).max().orElse(0.0);
final double labelHeightSum = n.getLabels().stream().mapToDouble(l -> l.getHeight()).sum();
// Determine max width for ports on the left and right sides
final double maxLeftPortWidth = n.getPorts().stream().filter(p -> p.getProperty(CoreOptions.PORT_SIDE) == PortSide.WEST).mapToDouble(p -> p.getWidth()).max().orElse(0.0);
final double maxRightPortWidth = n.getPorts().stream().filter(p -> p.getProperty(CoreOptions.PORT_SIDE) == PortSide.EAST).mapToDouble(p -> p.getWidth()).max().orElse(0.0);
final DiagramNode dn = (DiagramNode) layoutMapping.getGraphMap().get(n);
double minWidth = 0;
if (n.getProperty(CoreOptions.NODE_LABELS_PLACEMENT).contains(NodeLabelPlacement.H_CENTER)) {
// Ensure the minimum width is such that the label can be centered without overlapping with ports.
// This happens because ports are inside the node due to the PORT_BORDER_OFFSET and ELK centers the labels in the remaining space.
final double widthForPorts = 2 * Math.max(maxLeftPortWidth, maxRightPortWidth);
minWidth = Math.max(40, maxLabelWidth + widthForPorts + PORT_WIDTH_PADDING);
} else {
final double widthForPorts = maxLeftPortWidth + maxRightPortWidth + PORT_WIDTH_PADDING;
minWidth = Math.max(40, Math.max(maxLabelWidth, widthForPorts));
}
double minHeight = Math.max(35, labelHeightSum);
if (dn instanceof DiagramElement) {
final DiagramElement de = ((DiagramElement) dn);
// Special min height handling for initial modes
final Graphic graphic = de.getGraphic();
if (graphic instanceof AgeShape && !((AgeShape) graphic).isResizeable() && de.hasSize()) {
final Dimension dim = de.getSize();
minHeight = dim.height;
minWidth = dim.width;
// Adjust size constraints for fixed sized shapes which do not have contents.
if (n.getChildren().size() == 0 || n.getLabels().size() == 0 && n.getPorts().size() == 0) {
final EnumSet<SizeConstraint> nodeSizeConstraints = EnumSet.of(SizeConstraint.MINIMUM_SIZE);
n.setProperty(CoreOptions.NODE_SIZE_CONSTRAINTS, nodeSizeConstraints);
}
}
if (graphic instanceof ModeGraphic && ((ModeGraphic) graphic).isInitialMode) {
minHeight += ModeGraphic.INITIAL_MODE_AREA_HEIGHT;
}
// Special min size handling for elements shown as image
final Style style = de.getStyle();
if (style != null && Boolean.TRUE.equals(style.getShowAsImage())) {
final Dimension dim = ((DiagramElement) dn).getSize();
minHeight = dim.height;
minWidth = dim.width;
}
}
// Increase min width and min height for top level nodes.
if (dn != null && dn.getParent() instanceof AgeDiagram) {
minWidth = Math.max(minWidth, 200);
minHeight = Math.max(minHeight, 100);
}
n.setProperty(CoreOptions.NODE_SIZE_MINIMUM, new KVector(minWidth, minHeight));
}
};
ElkUtil.applyVisitors(layoutMapping.getLayoutGraph(), minNodeSizeVisitor);
// If the top level element has a size set, don't shrink it.
if (rootDiagramNode instanceof DiagramElement) {
final DiagramElement rootDiagramElement = (DiagramElement) rootDiagramNode;
final ElkGraphElement rootGraphElement = layoutMapping.getGraphMap().inverse().get(rootDiagramNode);
if (rootGraphElement != null && rootDiagramElement.hasSize() && DiagramElementPredicates.isResizeable(rootDiagramElement)) {
final KVector minSize = rootGraphElement.getProperty(CoreOptions.NODE_SIZE_MINIMUM);
final double newMinWidth = Math.max(rootDiagramElement.getWidth(), minSize == null ? 0.0 : minSize.x);
final double newMinHeight = Math.max(rootDiagramElement.getHeight(), minSize == null ? 0.0 : minSize.y);
rootGraphElement.setProperty(CoreOptions.NODE_SIZE_MINIMUM, new KVector(newMinWidth, newMinHeight));
}
}
}
use of org.osate.ge.graphics.internal.AgeShape in project osate2 by osate.
the class DiagramElementLayoutUtil method applyShapeLayout.
private static void applyShapeLayout(final LayoutMapping mapping, final DiagramModification m) {
// Modify shapes
for (Entry<ElkGraphElement, Object> e : mapping.getGraphMap().entrySet()) {
final ElkGraphElement elkElement = e.getKey();
final Object mappedValue = e.getValue();
final boolean isTopLevelElement = isTopLevel(elkElement);
if (!(elkElement instanceof ElkShape)) {
continue;
}
final ElkShape elkShape = (ElkShape) elkElement;
if (!(mappedValue instanceof DiagramElement)) {
continue;
}
final DiagramElement de = (DiagramElement) mappedValue;
if (!(de.getGraphic() instanceof AgeShape)) {
continue;
}
if (de.getGraphic() instanceof Label) {
continue;
}
// Set Position. Don't set the position of top level elements
if (!isTopLevelElement && DiagramElementPredicates.isMoveableShape(de)) {
// Determine position for the element
double x = elkShape.getX();
double y = elkShape.getY();
// If the diagram element has a parent port, subtract the parent port position from the ELK port position to determine the relative position
if (de.getDockArea() == DockArea.GROUP) {
final ElkPort parentPort = (ElkPort) mapping.getGraphMap().inverse().get(de.getParent());
if (parentPort != null) {
final PortSide side = parentPort.getProperty(CoreOptions.PORT_SIDE);
if (PortSide.SIDES_NORTH_SOUTH.contains(side)) {
x = elkShape.getX() - parentPort.getX();
} else if (PortSide.SIDES_EAST_WEST.contains(side)) {
y = elkShape.getY() - parentPort.getY();
} else {
throw new GraphicalEditorException("Unexpected side: " + side);
}
}
}
DiagramElementLayoutUtil.moveElement(m, de, new Point(x, y));
// Set the dock area
if (de.getDockArea() != DockArea.GROUP && de.getDockArea() != null) {
final DockArea newDockArea = PortSideUtil.getDockArea(elkShape.getProperty(CoreOptions.PORT_SIDE));
if (newDockArea != null) {
m.setDockArea(de, newDockArea);
}
}
}
// Set the size
if (DiagramElementPredicates.isResizeable(de)) {
m.setSize(de, new Dimension(elkShape.getWidth(), elkShape.getHeight()));
}
}
}
use of org.osate.ge.graphics.internal.AgeShape in project osate2 by osate.
the class ElkGraphBuilder method addPositionOffsets.
/**
* Adds position offset along axis for the specified port, graphic port, and children
* @param de
* @param offset
* @param side
* @param mapping
*/
private void addPositionOffsets(final DiagramElement de, final double offset, final PortSide side, final LayoutMapping mapping) {
final ElkPort childPort = (ElkPort) mapping.getGraphMap().inverse().get(de);
final double newPosition = addPositionOffset(childPort, side, offset);
// Only attempt to update child ports if nested ports are not being omitted.
if (!omitNestedPorts) {
de.getChildren().stream().filter(child -> child.getGraphic() instanceof AgeShape && !(child.getGraphic() instanceof Label) && child.getDockArea() != null).forEach(childDiagramElement -> addPositionOffsets(childDiagramElement, newPosition, side, mapping));
}
}
use of org.osate.ge.graphics.internal.AgeShape in project osate2 by osate.
the class DiagramElementPredicates method isMoveableShape.
/**
* Returns true if the specified diagram element is a shape that can be moved. This includes regular shapes and secondary labels for
* connections and flow indicators.
* @param de the diagram element to check
* @return true if the specified diagram element is a shape that can be moved.
*/
public static boolean isMoveableShape(final DiagramElement de) {
final Graphic graphic = de.getGraphic();
final boolean shapeSecondaryLabel = graphic instanceof Label && de.getParent() instanceof DiagramElement && ((DiagramElement) de.getParent()).getGraphic() instanceof AgeShape;
return graphic instanceof AgeShape && !shapeSecondaryLabel;
}
Aggregations