calculatePanelRects static method

Map<String, Rect> calculatePanelRects({
  1. required ElectricalNode root,
  2. required Map<String, Offset> positions,
  3. double nodeWidth = kNodeWidth,
  4. double nodeHeight = kNodeHeight,
})

Calculate rectangles for panel containers based on node positions

Implementation

static Map<String, Rect> calculatePanelRects({
  required ElectricalNode root,
  required Map<String, Offset> positions,
  double nodeWidth = kNodeWidth,
  double nodeHeight = kNodeHeight,
}) {
  final Map<String, Rect> panelRects = {};

  void computeRects(ElectricalNode node) {
    final isPanel = node.maybeMap(
      panel: (_) => true,
      orElse: () => false,
    );

    if (isPanel) {
      // Panels don't have positions, but need rectangles around their children
      final allChildren = _getChildren(node);

      // First process children recursively
      for (var c in allChildren) {
        computeRects(c);
      }

      // Then calculate this Panel's rectangle from children bounds
      if (allChildren.isNotEmpty) {
        double minX = double.infinity;
        double maxX = -double.infinity;
        double maxY = -double.infinity;
        double minY = double.infinity;

        for (var c in allChildren) {
          // Check direct children positions/bounds
          // Logic simplified: Get bounds of all children recursively
          final bounds =
              _getSubtreeBounds(c, positions, nodeWidth, nodeHeight);
          if (bounds != Rect.zero) {
            if (bounds.left < minX) minX = bounds.left;
            if (bounds.right > maxX) maxX = bounds.right;
            if (bounds.bottom > maxY) maxY = bounds.bottom;
            if (bounds.top < minY) minY = bounds.top;
          }
        }

        if (minX != double.infinity) {
          const double padding = 20.0;
          panelRects[node.id] = Rect.fromLTRB(
            minX - padding,
            minY - padding - kPanelHeaderHeight,
            maxX + padding,
            maxY + padding,
          );
        }
      }
    } else {
      // Not a panel (Source, Protection, etc.)
      // Just process children
      final allChildren = _getChildren(node);
      for (var c in allChildren) {
        computeRects(c);
      }
    }
  }

  computeRects(root);
  return panelRects;
}