package org.expeditee.core; import org.expeditee.core.bounds.AxisAlignedBoxBounds; /** * Class for anchoring the position of items within the frame. Anchoring is when * the position of the item is defined relative to the edge of the frame instead * of being defined in absolute coordinates. Can't be anchored to the left and * right edge at the same time, nor the top and bottom edge at the same time. * * @author cts16 */ public class Anchoring { private enum VerticalDirection { left, center, right } private enum HorizontalDirection { top, center, bottom } /** * The relative distance from the left, center or right edge (null means unanchored). */ private Integer _xAnchor = null; /** * The relative distance from the top, center or bottom edge (null means unanchored). */ private Integer _yAnchor = null; /** Whether the x-anchor is relative to the left or right edge. */ private VerticalDirection verticalDirection = VerticalDirection.left; /** Whether the y-anchor is relative to the top or bottom edge. */ private HorizontalDirection horizonalDirection = HorizontalDirection.top; public Anchoring() { } public void setXAnchor(Anchoring other) { if (other == null) { return; } setXAnchor(other._xAnchor, other.verticalDirection); } public void setYAnchor(Anchoring other) { if (other == null) return; setYAnchor(other._yAnchor, other.horizonalDirection); } public void setLeftAnchor(Integer offset) { setXAnchor(offset, VerticalDirection.left); } public void setCenterXAnchor(Integer offset) { setXAnchor(offset, VerticalDirection.center); } public void setRightAnchor(Integer offset) { setXAnchor(offset, VerticalDirection.right); } public void setTopAnchor(Integer offset) { setYAnchor(offset, HorizontalDirection.top); } public void setCenterYAnchor(Integer offset) { setYAnchor(offset, HorizontalDirection.center); } public void setBottomAnchor(Integer offset) { setYAnchor(offset, HorizontalDirection.bottom); } public void removeXAnchor() { setXAnchor(null, verticalDirection); } public void removeYAnchor() { setYAnchor(null, horizonalDirection); } public void removeAllAnchors() { removeXAnchor(); removeYAnchor(); } public Point getPositionInBox(AxisAlignedBoxBounds box) { Integer x = getXPositionInBox(box); Integer y = getYPositionInBox(box); if (x == null || y == null) return null; return new Point(x, y); } public boolean isXAnchored() { return _xAnchor != null; } public boolean isYAnchored() { return _yAnchor != null; } public boolean isAnchored() { return isXAnchored() || isYAnchored(); } public Integer getLeftAnchor() { return verticalDirection.equals(VerticalDirection.left) ? _xAnchor : null; } public Integer getCenterXAnchor() { return verticalDirection.equals(VerticalDirection.center) ? _xAnchor : null; } public Integer getRightAnchor() { return verticalDirection.equals(VerticalDirection.right) ? _xAnchor : null; } public Integer getTopAnchor() { return horizonalDirection.equals(HorizontalDirection.top) ? _yAnchor : null; } public Integer getCenterYAnchor() { return horizonalDirection.equals(HorizontalDirection.center) ? _yAnchor : null; } public Integer getBottomAnchor() { return horizonalDirection.equals(HorizontalDirection.bottom) ? _yAnchor : null; } private void setXAnchor(Integer offset, VerticalDirection left) { _xAnchor = offset; verticalDirection = left; } private void setYAnchor(Integer offset, HorizontalDirection top) { _yAnchor = offset; horizonalDirection = top; } private Integer getXPositionInBox(AxisAlignedBoxBounds box) { if (box == null || _xAnchor == null) return null; switch (verticalDirection) { case left: return box.getMinX() + _xAnchor; case center: return box.getCentreX() + _xAnchor; case right: return box.getMaxX() - _xAnchor; default: System.err.println("Anchoring::getXPositionInBox::VerticalDirection does not match available options. Has the enum been updated without this function being updated?"); return null; } } private Integer getYPositionInBox(AxisAlignedBoxBounds box) { if (box == null || _yAnchor == null) { return null; } switch (horizonalDirection) { case top: return box.getMinY() + _yAnchor; case center: return box.getCentreY() + _yAnchor; case bottom: return box.getMaxY() - _yAnchor; default: System.err.println("Anchoring::getYPositionInBox::HorizonalDirection does not match available options. Has the enum been updated without this function being updated?"); return null; } } }