List layoutPorts()

in diagram/src/main/java/jetbrains/jetpad/projectional/diagram/view/block/BlockViewPortLayouter.java [36:96]


  List<Vector> layoutPorts(List<Vector> portDimensions, GridDirection dir) {
    List<Vector> portOrigins = new ArrayList<>(portDimensions.size());

    Vector borderDir = dir.turnCounterclockwise().dir();
    Segment border = null;
    for (Segment s: myRect.getBoundSegments()) {
      Vector sDir = s.end.sub(s.start);
      if (borderDir.isParallel(sDir) && borderDir.dotProduct(sDir) > 0) {
        border = s;
        break;
      }
    }
    if (border == null) {
      throw new IllegalStateException();
    }

    boolean reverted = false;
    if (border.start.x > border.end.x || border.start.y > border.end.y) {
      border = new Segment(border.end, border.start);
      borderDir = dir.turnClockwise().dir();
      reverted = true;
    }

    if (portDimensions.size() == 1) {
      Vector dim = portDimensions.get(0);
      Vector borderShift = border.end.sub(border.start).sub(mulCoord(dim, borderDir));
      borderShift = new Vector(borderShift.x / 2, borderShift.y / 2);

      Vector portLoc = border.start.add(borderShift);
      portOrigins.add(portLoc.add(mulCoord(SHIFT_TO_ORIGIN[dir.ordinal()], dim)));
    } else if (portDimensions.size() > 1) {
      Vector childrenLen = Vector.ZERO;
      for (Vector dim: portDimensions) {
        childrenLen = childrenLen.add(mulCoord(dim, borderDir));
      }
      Vector space = border.end.sub(border.start).sub(childrenLen);
      space = new Vector(space.x / (portDimensions.size() - 1), space.y / (portDimensions.size() - 1));

      Vector offset = Vector.ZERO;
      Vector fullOffset = new Vector(border.end.x - border.start.x, border.end.y - border.start.y);
      for (int i = 0; i < portDimensions.size(); i++) {
        Vector dim = portDimensions.get(i);
        Vector portLocation = border.start.add(offset);

        offset = offset.add(mulCoord(dim, borderDir));

        if (i == portDimensions.size() - 1 && !offset.equals(fullOffset)) {
          portLocation = portLocation.add(fullOffset.sub(offset));
        }

        offset = offset.add(space);

        portOrigins.add(portLocation.add(mulCoord(SHIFT_TO_ORIGIN[dir.ordinal()], dim)));

      }
    }
    if (reverted) {
      Collections.reverse(portOrigins);
    }
    return portOrigins;
  }