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;
}