From f7b963f81999515e1afce2a08472119d60516e60 Mon Sep 17 00:00:00 2001 From: covers1624 Date: Wed, 3 Jul 2024 18:01:45 +0930 Subject: [PATCH] Move some static helpers from Constraints to ConstrainedGeometry. --- .../lib/gui/modular/lib/Constraints.java | 68 +++-------- .../lib/geometry/ConstrainedGeometry.java | 107 +++++++++++++++++- 2 files changed, 114 insertions(+), 61 deletions(-) diff --git a/src/main/java/codechicken/lib/gui/modular/lib/Constraints.java b/src/main/java/codechicken/lib/gui/modular/lib/Constraints.java index 91c84555..6399df5e 100644 --- a/src/main/java/codechicken/lib/gui/modular/lib/Constraints.java +++ b/src/main/java/codechicken/lib/gui/modular/lib/Constraints.java @@ -2,6 +2,7 @@ import codechicken.lib.gui.modular.lib.geometry.Borders; import codechicken.lib.gui.modular.lib.geometry.ConstrainedGeometry; +import net.covers1624.quack.annotation.ReplaceWithExpr; import java.util.function.Supplier; @@ -64,7 +65,6 @@ public static void bind(ConstrainedGeometry element, ConstrainedGeometry r element.constrain(RIGHT, relative(reference.get(RIGHT), () -> -borders.right())); } - public static void size(ConstrainedGeometry element, double width, double height) { element.constrain(WIDTH, literal(width)); element.constrain(HEIGHT, literal(height)); @@ -104,8 +104,10 @@ public static void center(ConstrainedGeometry element, ConstrainedGeometry * @param reference The reference element, the element that target will be placed inside. * @param position The layout position. */ + @Deprecated + @ReplaceWithExpr ("target.placeInside") public static void placeInside(ConstrainedGeometry target, ConstrainedGeometry reference, LayoutPos position) { - placeInside(target, reference, position, 0, 0); + target.placeInside(reference, position); } /** @@ -119,33 +121,10 @@ public static void placeInside(ConstrainedGeometry target, ConstrainedGeometr * @param xOffset Optional X offset to be applied to the final position. * @param yOffset Optional Y offset to be applied to the final position. */ + @Deprecated + @ReplaceWithExpr ("target.placeInside") public static void placeInside(ConstrainedGeometry target, ConstrainedGeometry reference, LayoutPos position, double xOffset, double yOffset) { - switch (position) { - case TOP_LEFT -> target - .constrain(TOP, relative(reference.get(TOP), yOffset)) - .constrain(LEFT, relative(reference.get(LEFT), xOffset)); - case TOP_CENTER -> target - .constrain(TOP, relative(reference.get(TOP), yOffset)) - .constrain(LEFT, midPoint(reference.get(LEFT), reference.get(RIGHT), () -> (target.xSize() / -2) + xOffset)); - case TOP_RIGHT -> target - .constrain(TOP, relative(reference.get(TOP), yOffset)) - .constrain(RIGHT, relative(reference.get(RIGHT), xOffset)); - case MIDDLE_RIGHT -> target - .constrain(TOP, midPoint(reference.get(TOP), reference.get(BOTTOM), () -> (target.ySize() / -2) + yOffset)) - .constrain(RIGHT, relative(reference.get(RIGHT), xOffset)); - case BOTTOM_RIGHT -> target - .constrain(BOTTOM, relative(reference.get(BOTTOM), yOffset)) - .constrain(RIGHT, relative(reference.get(RIGHT), xOffset)); - case BOTTOM_CENTER -> target - .constrain(BOTTOM, relative(reference.get(BOTTOM), yOffset)) - .constrain(LEFT, midPoint(reference.get(LEFT), reference.get(RIGHT), () -> (target.xSize() / -2) + xOffset)); - case BOTTOM_LEFT -> target - .constrain(BOTTOM, relative(reference.get(BOTTOM), yOffset)) - .constrain(LEFT, relative(reference.get(LEFT), xOffset)); - case MIDDLE_LEFT -> target - .constrain(TOP, midPoint(reference.get(TOP), reference.get(BOTTOM), () -> (target.ySize() / -2) + yOffset)) - .constrain(LEFT, relative(reference.get(LEFT), xOffset)); - } + target.placeInside(reference, position, xOffset, yOffset); } /** @@ -157,8 +136,10 @@ public static void placeInside(ConstrainedGeometry target, ConstrainedGeometr * @param reference The reference element, the element that target will be placed outside of. * @param position The layout position. */ + @Deprecated + @ReplaceWithExpr ("target.placeOutside") public static void placeOutside(ConstrainedGeometry target, ConstrainedGeometry reference, LayoutPos position) { - placeOutside(target, reference, position, 0, 0); + target.placeOutside(reference, position); } /** @@ -172,33 +153,10 @@ public static void placeOutside(ConstrainedGeometry target, ConstrainedGeomet * @param xOffset Optional X offset to be applied to the final position. * @param yOffset Optional Y offset to be applied to the final position. */ + @Deprecated + @ReplaceWithExpr ("target.placeOutside") public static void placeOutside(ConstrainedGeometry target, ConstrainedGeometry reference, LayoutPos position, double xOffset, double yOffset) { - switch (position) { - case TOP_LEFT -> target - .constrain(BOTTOM, relative(reference.get(TOP), yOffset)) - .constrain(RIGHT, relative(reference.get(LEFT), xOffset)); - case TOP_CENTER -> target - .constrain(BOTTOM, relative(reference.get(TOP), yOffset)) - .constrain(LEFT, midPoint(reference.get(LEFT), reference.get(RIGHT), () -> (target.xSize() / -2) + xOffset)); - case TOP_RIGHT -> target - .constrain(BOTTOM, relative(reference.get(TOP), yOffset)) - .constrain(LEFT, relative(reference.get(RIGHT), xOffset)); - case MIDDLE_RIGHT -> target - .constrain(TOP, midPoint(reference.get(TOP), reference.get(BOTTOM), () -> (target.ySize() / -2) + yOffset)) - .constrain(LEFT, relative(reference.get(RIGHT), xOffset)); - case BOTTOM_RIGHT -> target - .constrain(TOP, relative(reference.get(BOTTOM), yOffset)) - .constrain(LEFT, relative(reference.get(RIGHT), xOffset)); - case BOTTOM_CENTER -> target - .constrain(TOP, relative(reference.get(BOTTOM), yOffset)) - .constrain(LEFT, midPoint(reference.get(LEFT), reference.get(RIGHT), () -> (target.xSize() / -2) + xOffset)); - case BOTTOM_LEFT -> target - .constrain(TOP, relative(reference.get(BOTTOM), yOffset)) - .constrain(RIGHT, relative(reference.get(LEFT), xOffset)); - case MIDDLE_LEFT -> target - .constrain(TOP, midPoint(reference.get(TOP), reference.get(BOTTOM), () -> (target.ySize() / -2) + yOffset)) - .constrain(RIGHT, relative(reference.get(LEFT), xOffset)); - } + target.placeOutside(reference, position, xOffset, yOffset); } public enum LayoutPos { diff --git a/src/main/java/codechicken/lib/gui/modular/lib/geometry/ConstrainedGeometry.java b/src/main/java/codechicken/lib/gui/modular/lib/geometry/ConstrainedGeometry.java index b0c62353..17f5a19a 100644 --- a/src/main/java/codechicken/lib/gui/modular/lib/geometry/ConstrainedGeometry.java +++ b/src/main/java/codechicken/lib/gui/modular/lib/geometry/ConstrainedGeometry.java @@ -1,11 +1,14 @@ package codechicken.lib.gui.modular.lib.geometry; import codechicken.lib.gui.modular.elements.GuiElement; +import codechicken.lib.gui.modular.lib.Constraints; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.function.Supplier; +import static codechicken.lib.gui.modular.lib.geometry.Constraint.midPoint; +import static codechicken.lib.gui.modular.lib.geometry.Constraint.relative; import static codechicken.lib.gui.modular.lib.geometry.GeoParam.*; /** @@ -213,12 +216,16 @@ public GeoRef get(GeoParam param) { return new GeoRef(this, param); } + @SuppressWarnings ("unchecked") + private T self() { + return (T) this; + } + /** * @param param The geometry parameter to be constrained. * @param constraint The constraint to apply * @return This Element. */ - @SuppressWarnings ("unchecked") public T constrain(GeoParam param, @Nullable Constraint constraint) { if (constraint != null && constraint.axis() != null && constraint.axis() != param.axis) { throw new IllegalStateException("Attempted to apply constraint for axis: " + constraint.axis() + ", to Parameter: " + param); @@ -228,7 +235,7 @@ public T constrain(GeoParam param, @Nullable Constraint constraint) { } else if (param.axis == Axis.Y) { constrainY(param, constraint); } - return (T) this; + return self(); } /** @@ -236,11 +243,10 @@ public T constrain(GeoParam param, @Nullable Constraint constraint) { * Convenient when reconfiguring an elements constraints or applying constraints to an element * with an existing, unknown constraint configuration. */ - @SuppressWarnings ("unchecked") public T clearConstraints() { xMin = xMax = xSize = yMin = yMax = ySize = null; xAxis = yAxis = AxisConfig.NONE; - return (T) this; + return self(); } private void constrainX(GeoParam param, @Nullable Constraint constraint) { @@ -279,11 +285,10 @@ private void constrainY(GeoParam param, @Nullable Constraint constraint) { * @param strictMode Enable strict mode. * @return the geometry object. */ - @SuppressWarnings ("unchecked") public T strictMode(boolean strictMode) { this.strictMode = strictMode; //TODO Propagate to children (Will be handled in the base GuiElement) - return (T) this; + return self(); } //TODO This needs to be called from the parent element somewhere. Possibly on tick or render @@ -373,4 +378,94 @@ public Rectangle.Mutable getChildBounds() { if (!set) childBounds.setPos(xMin(), yMin()).setSize(0, 0); return childBounds; } + + //=== Layout Utilities ===// + + /** + * Constrain this element to a position inside the specified targetElement. + * See the following image for an example of what each LayoutPos does: + * https://ss.brandon3055.com/e89a6 + * + * @param reference The reference element, the element that target will be placed inside. + * @param position The layout position. + */ + public T placeInside(ConstrainedGeometry reference, Constraints.LayoutPos position) { + return placeInside(reference, position, 0, 0); + } + + /** + * Constrain this element to a position inside the specified targetElement. + * See the following image for an example of what each LayoutPos does: + * https://ss.brandon3055.com/e89a6 + * + * @param reference The reference element, the element that target will be placed inside. + * @param position The layout position. + * @param xOffset Optional X offset to be applied to the final position. + * @param yOffset Optional Y offset to be applied to the final position. + */ + public T placeInside(ConstrainedGeometry reference, Constraints.LayoutPos position, double xOffset, double yOffset) { + switch (position) { + case TOP_LEFT -> constrain(TOP, relative(reference.get(TOP), yOffset)) + .constrain(LEFT, relative(reference.get(LEFT), xOffset)); + case TOP_CENTER -> constrain(TOP, relative(reference.get(TOP), yOffset)) + .constrain(LEFT, midPoint(reference.get(LEFT), reference.get(RIGHT), () -> (xSize() / -2) + xOffset)); + case TOP_RIGHT -> constrain(TOP, relative(reference.get(TOP), yOffset)) + .constrain(RIGHT, relative(reference.get(RIGHT), xOffset)); + case MIDDLE_RIGHT -> constrain(TOP, midPoint(reference.get(TOP), reference.get(BOTTOM), () -> (ySize() / -2) + yOffset)) + .constrain(RIGHT, relative(reference.get(RIGHT), xOffset)); + case BOTTOM_RIGHT -> constrain(BOTTOM, relative(reference.get(BOTTOM), yOffset)) + .constrain(RIGHT, relative(reference.get(RIGHT), xOffset)); + case BOTTOM_CENTER -> constrain(BOTTOM, relative(reference.get(BOTTOM), yOffset)) + .constrain(LEFT, midPoint(reference.get(LEFT), reference.get(RIGHT), () -> (xSize() / -2) + xOffset)); + case BOTTOM_LEFT -> constrain(BOTTOM, relative(reference.get(BOTTOM), yOffset)) + .constrain(LEFT, relative(reference.get(LEFT), xOffset)); + case MIDDLE_LEFT -> constrain(TOP, midPoint(reference.get(TOP), reference.get(BOTTOM), () -> (ySize() / -2) + yOffset)) + .constrain(LEFT, relative(reference.get(LEFT), xOffset)); + } + return self(); + } + + /** + * Constrain this element to a position outside the specified targetElement. + * See the following image for an example of what each LayoutPos does: + * https://ss.brandon3055.com/baa7c + * + * @param reference The reference element, the element that target will be placed outside of. + * @param position The layout position. + */ + public T placeOutside(ConstrainedGeometry reference, Constraints.LayoutPos position) { + return placeOutside(reference, position, 0, 0); + } + + /** + * Constrain this element to a position outside the specified targetElement. + * See the following image for an example of what each LayoutPos does: + * https://ss.brandon3055.com/baa7c + * + * @param reference The reference element, the element that target will be placed outside of. + * @param position The layout position. + * @param xOffset Optional X offset to be applied to the final position. + * @param yOffset Optional Y offset to be applied to the final position. + */ + public T placeOutside(ConstrainedGeometry reference, Constraints.LayoutPos position, double xOffset, double yOffset) { + switch (position) { + case TOP_LEFT -> constrain(BOTTOM, relative(reference.get(TOP), yOffset)) + .constrain(RIGHT, relative(reference.get(LEFT), xOffset)); + case TOP_CENTER -> constrain(BOTTOM, relative(reference.get(TOP), yOffset)) + .constrain(LEFT, midPoint(reference.get(LEFT), reference.get(RIGHT), () -> (xSize() / -2) + xOffset)); + case TOP_RIGHT -> constrain(BOTTOM, relative(reference.get(TOP), yOffset)) + .constrain(LEFT, relative(reference.get(RIGHT), xOffset)); + case MIDDLE_RIGHT -> constrain(TOP, midPoint(reference.get(TOP), reference.get(BOTTOM), () -> (ySize() / -2) + yOffset)) + .constrain(LEFT, relative(reference.get(RIGHT), xOffset)); + case BOTTOM_RIGHT -> constrain(TOP, relative(reference.get(BOTTOM), yOffset)) + .constrain(LEFT, relative(reference.get(RIGHT), xOffset)); + case BOTTOM_CENTER -> constrain(TOP, relative(reference.get(BOTTOM), yOffset)) + .constrain(LEFT, midPoint(reference.get(LEFT), reference.get(RIGHT), () -> (xSize() / -2) + xOffset)); + case BOTTOM_LEFT -> constrain(TOP, relative(reference.get(BOTTOM), yOffset)) + .constrain(RIGHT, relative(reference.get(LEFT), xOffset)); + case MIDDLE_LEFT -> constrain(TOP, midPoint(reference.get(TOP), reference.get(BOTTOM), () -> (ySize() / -2) + yOffset)) + .constrain(RIGHT, relative(reference.get(LEFT), xOffset)); + } + return self(); + } }