diff --git a/src/main/java/com/cleanroommc/modularui/test/TestTile.java b/src/main/java/com/cleanroommc/modularui/test/TestTile.java index f41ff6348..bbf45897e 100644 --- a/src/main/java/com/cleanroommc/modularui/test/TestTile.java +++ b/src/main/java/com/cleanroommc/modularui/test/TestTile.java @@ -297,6 +297,7 @@ public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager syncManager, UI .texture(GuiTextures.PROGRESS_CYCLE, 20) .direction(ProgressWidget.Direction.CIRCULAR_CW)) .child(new Row().coverChildrenWidth().height(18) + .reverseLayout(false) .child(new ToggleButton() .value(new BoolValue.Dynamic(() -> cycleStateValue.getIntValue() == 0, val -> cycleStateValue.setIntValue(0))) .overlay(GuiTextures.CYCLE_BUTTON_DEMO.getSubArea(0, 0, 1, 1 / 3f))) diff --git a/src/main/java/com/cleanroommc/modularui/utils/ReversedList.java b/src/main/java/com/cleanroommc/modularui/utils/ReversedList.java new file mode 100644 index 000000000..7d6f3cbf8 --- /dev/null +++ b/src/main/java/com/cleanroommc/modularui/utils/ReversedList.java @@ -0,0 +1,42 @@ +package com.cleanroommc.modularui.utils; + +import java.util.AbstractList; +import java.util.List; + +public class ReversedList extends AbstractList { + + private final List delegate; + + public ReversedList(List delegate) { + this.delegate = delegate; + } + + public int inverseIndex(int i) { + return size() - 1 - i; + } + + @Override + public T get(int index) { + return this.delegate.get(inverseIndex(index)); + } + + @Override + public int size() { + return this.delegate.size(); + } + + @Override + public T set(int index, T element) { + return this.delegate.set(inverseIndex(index), element); + } + + @Override + public T remove(int index) { + return this.delegate.remove(inverseIndex(index)); + } + + @Override + public void add(int index, T element) { + this.delegate.add(inverseIndex(index), element); + } +} diff --git a/src/main/java/com/cleanroommc/modularui/widgets/layout/Flow.java b/src/main/java/com/cleanroommc/modularui/widgets/layout/Flow.java index b8a7e209d..608910e51 100644 --- a/src/main/java/com/cleanroommc/modularui/widgets/layout/Flow.java +++ b/src/main/java/com/cleanroommc/modularui/widgets/layout/Flow.java @@ -4,9 +4,11 @@ import com.cleanroommc.modularui.api.layout.ILayoutWidget; import com.cleanroommc.modularui.api.widget.IWidget; import com.cleanroommc.modularui.utils.Alignment; +import com.cleanroommc.modularui.utils.ReversedList; import com.cleanroommc.modularui.widget.ParentWidget; import com.cleanroommc.modularui.widget.sizer.Box; +import java.util.List; import java.util.function.IntFunction; public class Flow extends ParentWidget implements ILayoutWidget, IExpander { @@ -41,6 +43,11 @@ public static Flow column() { */ private boolean collapseDisabledChild = false; + /** + * Whether the children list should be read in reverse or not + */ + private boolean reverseChildren = false; + public Flow(GuiAxis axis) { this.axis = axis; sizeRel(1f, 1f); @@ -105,6 +112,7 @@ public boolean layoutWidgets() { return false; } } + List childrenList = reverseChildren ? new ReversedList<>(getChildren()) : getChildren(); int space = this.spaceBetween; int childrenSize = 0; @@ -112,7 +120,7 @@ public boolean layoutWidgets() { int amount = 0; // calculate total size - for (IWidget widget : getChildren()) { + for (IWidget widget : childrenList) { // ignore disabled child if configured as such if (shouldIgnoreChildSize(widget)) continue; // exclude children whose position of main axis is fixed @@ -144,7 +152,7 @@ public boolean layoutWidgets() { if (expandedAmount > 0 && hasSize) { int newSize = (size - childrenSize) / expandedAmount; - for (IWidget widget : getChildren()) { + for (IWidget widget : childrenList) { // ignore disabled child if configured as such if (shouldIgnoreChildSize(widget)) continue; // exclude children whose position of main axis is fixed @@ -166,7 +174,7 @@ public boolean layoutWidgets() { } } - for (IWidget widget : getChildren()) { + for (IWidget widget : childrenList) { // ignore disabled child if configured as such if (shouldIgnoreChildSize(widget)) { widget.resizer().updateResized(); @@ -205,7 +213,12 @@ public static boolean layoutCrossAxisListLike(IWidget parent, GuiAxis axis, Alig Box padding = parent.getArea().getPadding(); boolean hasWidth = parent.resizer().isSizeCalculated(other); if (!hasWidth && caa != Alignment.CrossAxis.START) return false; - for (IWidget widget : parent.getChildren()) { + List childrenList = parent.getChildren(); + if(parent instanceof Flow flow && flow.reverseChildren) { + childrenList = new ReversedList<>(parent.getChildren()); + } + + for (IWidget widget : childrenList) { // exclude children whose position of main axis is fixed if (widget.flex().hasPos(axis)) continue; Box margin = widget.getArea().getMargin(); @@ -299,6 +312,17 @@ public Flow collapseDisabledChild(boolean doCollapse) { return this; } + /** + * Sets if the children list should be reversed or not. + * This is useful when using a MainAxisAlignment of END and want the children to be added in the same order they are read in. + * @param doReverse true if the children list should be read in reverse + * @return this + */ + public Flow reverseLayout(boolean doReverse) { + this.reverseChildren = doReverse; + return this; + } + public GuiAxis getAxis() { return axis; }