Skip to content

Commit

Permalink
Move some static helpers from Constraints to ConstrainedGeometry.
Browse files Browse the repository at this point in the history
  • Loading branch information
covers1624 committed Jul 3, 2024
1 parent d0dedce commit f7b963f
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 61 deletions.
68 changes: 13 additions & 55 deletions src/main/java/codechicken/lib/gui/modular/lib/Constraints.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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);
}

/**
Expand All @@ -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);
}

/**
Expand All @@ -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);
}

/**
Expand All @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
@@ -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.*;

/**
Expand Down Expand Up @@ -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);
Expand All @@ -228,19 +235,18 @@ public T constrain(GeoParam param, @Nullable Constraint constraint) {
} else if (param.axis == Axis.Y) {
constrainY(param, constraint);
}
return (T) this;
return self();
}

/**
* Clear any configured constraints and reset this element to default unconstrained state.
* 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) {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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:
* <a href="https://ss.brandon3055.com/e89a6">https://ss.brandon3055.com/e89a6</a>
*
* @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:
* <a href="https://ss.brandon3055.com/e89a6">https://ss.brandon3055.com/e89a6</a>
*
* @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:
* <a href="https://ss.brandon3055.com/baa7c">https://ss.brandon3055.com/baa7c</a>
*
* @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:
* <a href="https://ss.brandon3055.com/baa7c">https://ss.brandon3055.com/baa7c</a>
*
* @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();
}
}

0 comments on commit f7b963f

Please sign in to comment.