use of org.eclipse.elk.alg.layered.intermediate.loops.SelfHyperLoopLabels in project elk by eclipse.
the class RoutingSlotAssigner method labelsOverlap.
/**
* Returns {@code true} if the labels of the two loops would overlap if the loops were assigned to the same routing
* slot.
*/
private boolean labelsOverlap(final SelfHyperLoop slLoop1, final SelfHyperLoop slLoop2) {
assert slLoop1 != slLoop2;
SelfHyperLoopLabels slLabels1 = slLoop1.getSLLabels();
SelfHyperLoopLabels slLabels2 = slLoop2.getSLLabels();
// There won't be overlaps unless both loops have labels
if (slLabels1 == null || slLabels2 == null) {
return false;
}
// The labels must be assigned to the same side, and that side (currently) needs to be either north or south
if (slLabels1.getSide() != slLabels2.getSide() || slLabels1.getSide() == PortSide.EAST || slLabels1.getSide() == PortSide.WEST) {
return false;
}
// Check if the labels overlap horizontally (remember that at this point, horizontal coordinates of north and
// south labels have been set by the label placer)
double start1 = slLabels1.getPosition().x;
double end1 = start1 + slLabels1.getSize().x;
double start2 = slLabels2.getPosition().x;
double end2 = start2 + slLabels2.getSize().x;
return start1 <= end2 && end1 >= start2;
}
use of org.eclipse.elk.alg.layered.intermediate.loops.SelfHyperLoopLabels in project elk by eclipse.
the class LabelPlacer method computeCoordinates.
// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Coordinate Computation
private void computeCoordinates(final SelfHyperLoop slLoop) {
// The coordinates really only depend on the alignment since LEFT, CENTER and RIGHT are specific to the north
// and south sides while TOP is specific to the east and west sides
SelfHyperLoopLabels slLabels = slLoop.getSLLabels();
SelfLoopPort alignRef = slLabels.getAlignmentReferenceSLPort();
KVector size = slLabels.getSize();
KVector pos = slLabels.getPosition();
switch(slLabels.getAlignment()) {
case CENTER:
pos.x = (slLoop.getSLHolder().getLNode().getSize().x - size.x) / 2;
break;
case LEFT:
pos.x = alignRef.getLPort().getPosition().x + alignRef.getLPort().getAnchor().x;
break;
case RIGHT:
pos.x = alignRef.getLPort().getPosition().x + alignRef.getLPort().getAnchor().x - size.x;
break;
case TOP:
pos.y = alignRef.getLPort().getPosition().y + alignRef.getLPort().getAnchor().y;
break;
default:
assert false;
}
}
use of org.eclipse.elk.alg.layered.intermediate.loops.SelfHyperLoopLabels in project elk by eclipse.
the class LabelPlacer method assignSideAndAlignment.
private void assignSideAndAlignment(final SelfHyperLoop slLoop, final PortSide side, final Alignment alignment, final SelfLoopPort alignmentReference) {
SelfHyperLoopLabels slLabels = slLoop.getSLLabels();
slLabels.setSide(side);
slLabels.setAlignment(alignment);
slLabels.setAlignmentReferenceSLPort(alignmentReference);
}
use of org.eclipse.elk.alg.layered.intermediate.loops.SelfHyperLoopLabels in project elk by eclipse.
the class LabelPlacer method assignSideAndAlignment.
// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Side and Alignment
private void assignSideAndAlignment(final SelfLoopHolder slHolder) {
// Most loops are straightforward, but the one-sides northern and southern ones may not be. If the loops are
// stacked, we can simply center their labels. If they are sequenced, we want to go from the outer loops to the
// inner loops in pairs, and align their labels away from each other. To do so, we need to collect all of them
// first.
List<SelfHyperLoop> northernOneSidedSLLoops = null;
List<SelfHyperLoop> southernOneSidedSLLoops = null;
SelfLoopOrderingStrategy orderingStrategy = slHolder.getLNode().getProperty(LayeredOptions.EDGE_ROUTING_SELF_LOOP_ORDERING);
if (orderingStrategy == SelfLoopOrderingStrategy.SEQUENCED) {
northernOneSidedSLLoops = new ArrayList<>();
southernOneSidedSLLoops = new ArrayList<>();
}
// Assign sides and alignments; how this works differs for the different kinds of labels
for (SelfHyperLoop slLoop : slHolder.getSLHyperLoops()) {
// If this loop doesn't have any labels, don't bother
SelfHyperLoopLabels slLabels = slLoop.getSLLabels();
if (slLabels == null) {
continue;
}
assert !slLabels.getLLabels().isEmpty();
// How we place labels largely depends on the self loop type
switch(slLoop.getSelfLoopType()) {
case ONE_SIDE:
PortSide loopSide = slLoop.getOccupiedPortSides().iterator().next();
if (orderingStrategy == SelfLoopOrderingStrategy.SEQUENCED && (loopSide == PortSide.NORTH)) {
// Collect for deferred processing
northernOneSidedSLLoops.add(slLoop);
} else if (orderingStrategy == SelfLoopOrderingStrategy.SEQUENCED && (loopSide == PortSide.SOUTH)) {
// Collect for deferred processing
southernOneSidedSLLoops.add(slLoop);
} else {
assignOneSidedSimpleSideAndAlignment(slLoop, loopSide);
}
break;
case TWO_SIDES_CORNER:
assignTwoSidesCornerSideAndAlignment(slLoop);
break;
case TWO_SIDES_OPPOSING:
case THREE_SIDES:
assignTwoSidesOpposingAndThreeSidesSideAndAlignment(slLoop);
break;
case FOUR_SIDES:
assignFourSidesSideAndAlignment(slLoop);
break;
default:
assert false;
}
}
// Process deferred loops
if (northernOneSidedSLLoops != null) {
if (!northernOneSidedSLLoops.isEmpty()) {
assignOneSidedSequencedSideAndAlignment(northernOneSidedSLLoops, PortSide.NORTH);
}
if (!southernOneSidedSLLoops.isEmpty()) {
assignOneSidedSequencedSideAndAlignment(southernOneSidedSLLoops, PortSide.SOUTH);
}
}
}
use of org.eclipse.elk.alg.layered.intermediate.loops.SelfHyperLoopLabels in project elk by eclipse.
the class LabelPlacer method manageLabels.
// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Label Management
private void manageLabels(final SelfHyperLoop slLoop, final ILabelManager labelManager) {
// How much space we have available depends entirely on our alignment since that also determines whether we're
// on the north/south or the east/west sides
SelfHyperLoopLabels slLabels = slLoop.getSLLabels();
SelfLoopPort alignRef = slLabels.getAlignmentReferenceSLPort();
LNode lNode = slLoop.getSLHolder().getLNode();
KVector lNodeSize = lNode.getSize();
LMargin lNodeMargins = slLoop.getSLHolder().getLNode().getMargin();
double targetWidth = 0;
switch(slLabels.getAlignment()) {
case CENTER:
// Clip the label to the extent of the node's bounding box
targetWidth = lNodeMargins.left + lNodeSize.x + lNodeMargins.right;
break;
case LEFT:
targetWidth = lNodeSize.x - alignRef.getLPort().getPosition().x - alignRef.getLPort().getAnchor().x + lNodeMargins.right;
break;
case RIGHT:
targetWidth = lNodeMargins.left + alignRef.getLPort().getPosition().x + alignRef.getLPort().getAnchor().x;
break;
case TOP:
// We have no way of knowing how far to the left / right our self loop will extend on our placement side,
// so we need a default here
targetWidth = LabelManagementProcessor.MIN_WIDTH_EDGE_LABELS;
break;
default:
assert false;
}
slLabels.applyLabelManagement(labelManager, Math.max(targetWidth, LabelManagementProcessor.MIN_WIDTH_EDGE_LABELS));
}
Aggregations