Search in sources :

Example 1 with PortAlignment

use of org.eclipse.elk.core.options.PortAlignment in project elk by eclipse.

the class PortPlacementCalculator method placeVerticalFreePorts.

/**
 * Places ports on the eastern and western side for the unconstrained cases.
 */
private static void placeVerticalFreePorts(final NodeContext nodeContext, final PortSide portSide) {
    // If there are no ports on the given side, abort
    if (nodeContext.portContexts.get(portSide).isEmpty()) {
        return;
    }
    // Retrieve the proper inside port label cell, which will give us hints as to where to place our ports
    AtomicCell insidePortLabelCell = nodeContext.insidePortLabelCells.get(portSide);
    ElkRectangle insidePortLabelCellRectangle = insidePortLabelCell.getCellRectangle();
    ElkPadding insidePortLabelCellPadding = insidePortLabelCell.getPadding();
    // Note that we don't have to distinguish any cases here because the port margins already include space
    // required for labels, if such space is to be reserved. Yay!
    PortAlignment portAlignment = nodeContext.getPortAlignment(portSide);
    double availableSpace = insidePortLabelCellRectangle.height - insidePortLabelCellPadding.top - insidePortLabelCellPadding.bottom;
    double calculatedPortPlacementHeight = insidePortLabelCell.getMinimumContentAreaSize().y;
    double currentYPos = insidePortLabelCellRectangle.y + insidePortLabelCellPadding.top;
    double spaceBetweenPorts = nodeContext.portPortSpacing;
    double nodeWidth = nodeContext.nodeSize.x;
    // to center to keep things from looking stupid
    if ((portAlignment == PortAlignment.DISTRIBUTED || portAlignment == PortAlignment.JUSTIFIED) && nodeContext.portContexts.get(portSide).size() == 1) {
        calculatedPortPlacementHeight = modifiedPortPlacementSize(nodeContext, portAlignment, calculatedPortPlacementHeight);
        portAlignment = PortAlignment.CENTER;
    }
    if (availableSpace < calculatedPortPlacementHeight && !nodeContext.sizeOptions.contains(SizeOptions.PORTS_OVERHANG)) {
        // the space between them to cram them into the available space.
        if (portAlignment == PortAlignment.DISTRIBUTED) {
            spaceBetweenPorts += (availableSpace - calculatedPortPlacementHeight) / (nodeContext.portContexts.get(portSide).size() + 1);
            currentYPos += spaceBetweenPorts;
        } else {
            spaceBetweenPorts += (availableSpace - calculatedPortPlacementHeight) / (nodeContext.portContexts.get(portSide).size() - 1);
        }
    } else {
        // case where we should fall back to centered alignment
        if (availableSpace < calculatedPortPlacementHeight) {
            calculatedPortPlacementHeight = modifiedPortPlacementSize(nodeContext, portAlignment, calculatedPortPlacementHeight);
            portAlignment = PortAlignment.CENTER;
        }
        // otherwise expect)
        switch(portAlignment) {
            case BEGIN:
                // There's nothing to do here
                break;
            case CENTER:
                currentYPos += (availableSpace - calculatedPortPlacementHeight) / 2;
                break;
            case END:
                currentYPos += availableSpace - calculatedPortPlacementHeight;
                break;
            case DISTRIBUTED:
                // In this case, if there is not enough space available to place the ports, we are allowed to overhang.
                // We thus need to ensure that we're only ever increasing the port spacing here
                double additionalSpaceBetweenPorts = (availableSpace - calculatedPortPlacementHeight) / (nodeContext.portContexts.get(portSide).size() + 1);
                spaceBetweenPorts += Math.max(0, additionalSpaceBetweenPorts);
                currentYPos += spaceBetweenPorts;
                break;
            case JUSTIFIED:
                // In this case, if there is not enough space available to place the ports, we are allowed to overhang.
                // We thus need to ensure that we're only ever increasing the port spacing here
                additionalSpaceBetweenPorts = (availableSpace - calculatedPortPlacementHeight) / (nodeContext.portContexts.get(portSide).size() - 1);
                spaceBetweenPorts += Math.max(0, additionalSpaceBetweenPorts);
                break;
        }
    }
    // Iterate over all ports and place them
    for (PortContext portContext : nodeContext.portContexts.get(portSide)) {
        portContext.portPosition.x = calculateVerticalPortXCoordinate(portContext, nodeWidth);
        portContext.portPosition.y = currentYPos + portContext.portMargin.top;
        // Update the y coordinate for the next port
        currentYPos += portContext.portMargin.top + portContext.port.getSize().y + portContext.portMargin.bottom + spaceBetweenPorts;
    }
}
Also used : PortAlignment(org.eclipse.elk.core.options.PortAlignment) AtomicCell(org.eclipse.elk.alg.common.nodespacing.cellsystem.AtomicCell) ElkRectangle(org.eclipse.elk.core.math.ElkRectangle) ElkPadding(org.eclipse.elk.core.math.ElkPadding) PortContext(org.eclipse.elk.alg.common.nodespacing.internal.PortContext)

Example 2 with PortAlignment

use of org.eclipse.elk.core.options.PortAlignment in project elk by eclipse.

the class PortPlacementCalculator method placeHorizontalFreePorts.

/**
 * Places ports on the northern and southern side for the unconstrained cases.
 */
private static void placeHorizontalFreePorts(final NodeContext nodeContext, final PortSide portSide) {
    // If there are no ports on the given side, abort
    if (nodeContext.portContexts.get(portSide).isEmpty()) {
        return;
    }
    // Retrieve the proper inside port label cell, which will give us hints as to where to place our ports
    AtomicCell insidePortLabelCell = nodeContext.insidePortLabelCells.get(portSide);
    ElkRectangle insidePortLabelCellRectangle = insidePortLabelCell.getCellRectangle();
    ElkPadding insidePortLabelCellPadding = insidePortLabelCell.getPadding();
    // Note that we don't have to distinguish any cases here because the port margins already include space
    // required for labels, if such space is to be reserved. Yay!
    PortAlignment portAlignment = nodeContext.getPortAlignment(portSide);
    double availableSpace = insidePortLabelCellRectangle.width - insidePortLabelCellPadding.left - insidePortLabelCellPadding.right;
    double calculatedPortPlacementWidth = insidePortLabelCell.getMinimumContentAreaSize().x;
    double currentXPos = insidePortLabelCellRectangle.x + insidePortLabelCellPadding.left;
    double spaceBetweenPorts = nodeContext.portPortSpacing;
    // to center to keep things from looking stupid
    if ((portAlignment == PortAlignment.DISTRIBUTED || portAlignment == PortAlignment.JUSTIFIED) && nodeContext.portContexts.get(portSide).size() == 1) {
        calculatedPortPlacementWidth = modifiedPortPlacementSize(nodeContext, portAlignment, calculatedPortPlacementWidth);
        portAlignment = PortAlignment.CENTER;
    }
    if (availableSpace < calculatedPortPlacementWidth && !nodeContext.sizeOptions.contains(SizeOptions.PORTS_OVERHANG)) {
        // the space between them to cram them into the available space.
        if (portAlignment == PortAlignment.DISTRIBUTED) {
            spaceBetweenPorts += (availableSpace - calculatedPortPlacementWidth) / (nodeContext.portContexts.get(portSide).size() + 1);
            currentXPos += spaceBetweenPorts;
        } else {
            spaceBetweenPorts += (availableSpace - calculatedPortPlacementWidth) / (nodeContext.portContexts.get(portSide).size() - 1);
        }
    } else {
        // case where we should fall back to centered alignment
        if (availableSpace < calculatedPortPlacementWidth) {
            calculatedPortPlacementWidth = modifiedPortPlacementSize(nodeContext, portAlignment, calculatedPortPlacementWidth);
            portAlignment = PortAlignment.CENTER;
        }
        // otherwise expect)
        switch(portAlignment) {
            case BEGIN:
                // There's nothing to do here
                break;
            case CENTER:
                currentXPos += (availableSpace - calculatedPortPlacementWidth) / 2;
                break;
            case END:
                currentXPos += availableSpace - calculatedPortPlacementWidth;
                break;
            case DISTRIBUTED:
                // In this case, if there is not enough space available to place the ports, we are allowed to overhang.
                // We thus need to ensure that we're only ever increasing the port spacing here
                double additionalSpaceBetweenPorts = (availableSpace - calculatedPortPlacementWidth) / (nodeContext.portContexts.get(portSide).size() + 1);
                spaceBetweenPorts += Math.max(0, additionalSpaceBetweenPorts);
                currentXPos += spaceBetweenPorts;
                break;
            case JUSTIFIED:
                // In this case, if there is not enough space available to place the ports, we are allowed to overhang.
                // We thus need to ensure that we're only ever increasing the port spacing here
                additionalSpaceBetweenPorts = (availableSpace - calculatedPortPlacementWidth) / (nodeContext.portContexts.get(portSide).size() - 1);
                spaceBetweenPorts += Math.max(0, additionalSpaceBetweenPorts);
                break;
        }
    }
    // Iterate over all ports and place them
    for (PortContext portContext : nodeContext.portContexts.get(portSide)) {
        portContext.portPosition.x = currentXPos + portContext.portMargin.left;
        portContext.portPosition.y = calculateHorizontalPortYCoordinate(portContext);
        // Update the x coordinate for the next port
        currentXPos += portContext.portMargin.left + portContext.port.getSize().x + portContext.portMargin.right + spaceBetweenPorts;
    }
}
Also used : PortAlignment(org.eclipse.elk.core.options.PortAlignment) AtomicCell(org.eclipse.elk.alg.common.nodespacing.cellsystem.AtomicCell) ElkRectangle(org.eclipse.elk.core.math.ElkRectangle) ElkPadding(org.eclipse.elk.core.math.ElkPadding) PortContext(org.eclipse.elk.alg.common.nodespacing.internal.PortContext)

Aggregations

AtomicCell (org.eclipse.elk.alg.common.nodespacing.cellsystem.AtomicCell)2 PortContext (org.eclipse.elk.alg.common.nodespacing.internal.PortContext)2 ElkPadding (org.eclipse.elk.core.math.ElkPadding)2 ElkRectangle (org.eclipse.elk.core.math.ElkRectangle)2 PortAlignment (org.eclipse.elk.core.options.PortAlignment)2