getVisualPortPosition method
Offset
getVisualPortPosition(
- String portId, {
- required double portSize,
- EdgeInsets padding = EdgeInsets.zero,
- NodeShape? shape,
Gets the visual position where a port should be rendered within the node container.
This calculates the local position of a port within the node's coordinate space, accounting for the port's edge position and size. The port widget will be centered on this position.
Parameters:
portId- The unique identifier of the portportSize- The size of the port widgetpadding- Optional padding/inset for shaped nodes (to account for shape inset)
Returns the Offset where the port should be positioned relative to the node's top-left corner for rectangular nodes.
For shaped nodes, pass the shape parameter to calculate positions based on the shape's anchors.
Throws ArgumentError if no port with the given portId is found.
Implementation
Offset getVisualPortPosition(
String portId, {
required double portSize,
EdgeInsets padding = EdgeInsets.zero,
NodeShape? shape,
}) {
final port = [
...inputPorts,
...outputPorts,
].cast<Port?>().firstWhere((p) => p?.id == portId, orElse: () => null);
if (port == null) {
throw ArgumentError('Port $portId not found');
}
// If shape is provided, use shape-defined anchors
if (shape != null) {
// Calculate inset size (shape is rendered smaller to leave room for ports)
final insetSize = Size(
size.value.width - padding.left - padding.right,
size.value.height - padding.top - padding.bottom,
);
// Get anchors for the inset shape
final anchors = shape.getPortAnchors(insetSize);
final anchor = anchors.firstWhere(
(a) => a.position == port.position,
orElse: () => _fallbackAnchor(port.position, insetSize),
);
// Translate anchor position to account for padding offset,
// adjust for port size (center the port on the anchor point),
// and add any custom port offset
return Offset(padding.left, padding.top) +
anchor.offset +
port.offset -
Offset(portSize / 2, portSize / 2);
}
// Use rectangular logic
switch (port.position) {
case PortPosition.left:
// Left edge: port protrudes halfway out from left edge
return Offset(
port.offset.dx, // Left edge of padded container
port.offset.dy, // Centered vertically with offset
);
case PortPosition.right:
// Right edge: port protrudes halfway out from right edge
return Offset(
size.value.width -
portSize +
port.offset.dx, // Right edge of padded container minus port size
port.offset.dy, // Centered vertically with offset
);
case PortPosition.top:
// Top edge: port protrudes halfway out from top edge
return Offset(
port.offset.dx, // Centered horizontally with offset
port.offset.dy, // Top edge of padded container
);
case PortPosition.bottom:
// Bottom edge: port protrudes halfway out from bottom edge
return Offset(
port.offset.dx, // Centered horizontally with offset
size.value.height -
portSize +
port.offset.dy, // Bottom edge of container
);
}
}