Skip to content

Commit b93dd1d

Browse files
committed
wrapping flows
1 parent f35155e commit b93dd1d

12 files changed

Lines changed: 454 additions & 133 deletions

File tree

src/main/java/com/cleanroommc/modularui/api/layout/IResizeable.java

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,25 @@ default void applyPos() {}
4343

4444
void setLayoutDone(boolean done);
4545

46+
default void setAxisResized(GuiAxis axis, boolean pos, boolean size) {
47+
if (axis.isHorizontal()) {
48+
setXAxisResized(pos, size);
49+
} else {
50+
setYAxisResized(pos, size);
51+
}
52+
}
53+
54+
void setXAxisResized(boolean pos, boolean size);
55+
56+
void setYAxisResized(boolean pos, boolean size);
57+
4658
/**
4759
* Marks position and size as calculated.
4860
*/
49-
void setResized(boolean x, boolean y, boolean w, boolean h);
61+
default void setResized(boolean x, boolean y, boolean w, boolean h) {
62+
setXAxisResized(x, w);
63+
setYAxisResized(y, h);
64+
}
5065

5166
default void setPosResized(boolean x, boolean y) {
5267
setResized(x, y, isWidthCalculated(), isHeightCalculated());
@@ -57,11 +72,11 @@ default void setSizeResized(boolean w, boolean h) {
5772
}
5873

5974
default void setXResized(boolean v) {
60-
setResized(v, isYCalculated(), isWidthCalculated(), isHeightCalculated());
75+
setXAxisResized(v, isWidthCalculated());
6176
}
6277

6378
default void setYResized(boolean v) {
64-
setResized(isXCalculated(), v, isWidthCalculated(), isHeightCalculated());
79+
setYAxisResized(v, isHeightCalculated());
6580
}
6681

6782
default void setPosResized(GuiAxis axis, boolean v) {
@@ -73,11 +88,11 @@ default void setPosResized(GuiAxis axis, boolean v) {
7388
}
7489

7590
default void setWidthResized(boolean v) {
76-
setResized(isXCalculated(), isYCalculated(), v, isHeightCalculated());
91+
setXAxisResized(isXCalculated(), v);
7792
}
7893

7994
default void setHeightResized(boolean v) {
80-
setResized(isXCalculated(), isYCalculated(), isWidthCalculated(), v);
95+
setYAxisResized(isYCalculated(), v);
8196
}
8297

8398
default void setSizeResized(GuiAxis axis, boolean v) {

src/main/java/com/cleanroommc/modularui/test/TestGuis.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@
7171
import net.minecraft.util.text.TextFormatting;
7272

7373
import com.google.common.base.CaseFormat;
74+
import it.unimi.dsi.fastutil.ints.IntArrayList;
75+
import it.unimi.dsi.fastutil.ints.IntList;
7476
import org.apache.commons.lang3.tuple.Pair;
7577
import org.jetbrains.annotations.NotNull;
7678

@@ -87,6 +89,13 @@
8789

8890
public class TestGuis extends CustomModularScreen {
8991

92+
public static final IntList LIGHT_COLORS = ColorShade.getAll().stream()
93+
.filter(cs -> !cs.name.contains("accent"))
94+
.filter(cs -> cs.brighterShadeCount() > 1)
95+
.mapToInt(cs -> cs.brighter(1))
96+
.filter(c -> Color.getHSLSaturation(c) > 0.4f)
97+
.collect(IntArrayList::new, IntList::add, IntList::addAll);
98+
9099
public static boolean withCode = false;
91100

92101
public TestGuis() {
@@ -628,6 +637,42 @@ public static ModularPanel buildContextMenu() {
628637
.overlay();
629638
}
630639

640+
public static @NotNull ModularPanel buildWrappedFlowUI() {
641+
IntList colors = new IntArrayList(LIGHT_COLORS);
642+
Random rnd = new Random();
643+
int minRectSize = 10;
644+
int maxRectSize = 40;
645+
return new ModularPanel("wrapped_flow")
646+
.size(150)
647+
.padding(4)
648+
.child(Flow.row()
649+
.name("wrap")
650+
.wrap()
651+
.widthRel(1f)
652+
.coverChildrenHeight()
653+
.padding(2)
654+
.crossAxisAlignment(Alignment.CrossAxis.START)
655+
.mainAxisAlignment(Alignment.MainAxis.CENTER)
656+
.childPadding(2)
657+
.crossAxisChildPadding(2)
658+
.background(rndRect(colors, rnd))
659+
.children(5, i -> {
660+
IWidget widget = rndRect(colors, rnd).asWidget()
661+
.width(rnd.nextInt(maxRectSize - minRectSize) + minRectSize)
662+
.height(rnd.nextInt(maxRectSize - minRectSize) + minRectSize)
663+
.name("rect_" + (i + 1));
664+
if (i % 2 == 1) widget.resizer().expanded();
665+
return widget;
666+
}));
667+
}
668+
669+
private static Rectangle rndRect(IntList colors, Random random) {
670+
int i = random.nextInt(colors.size());
671+
int c = colors.removeInt(i);
672+
if (colors.isEmpty()) colors.addAll(LIGHT_COLORS);
673+
return new Rectangle().color(c);
674+
}
675+
631676
private static class TestPanel extends ModularPanel {
632677

633678
public TestPanel(String name) {

src/main/java/com/cleanroommc/modularui/utils/Alignment.java

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
package com.cleanroommc.modularui.utils;
22

33
import com.google.common.base.CaseFormat;
4-
import com.google.gson.*;
4+
import com.google.gson.JsonDeserializationContext;
5+
import com.google.gson.JsonDeserializer;
6+
import com.google.gson.JsonElement;
7+
import com.google.gson.JsonParseException;
8+
import com.google.gson.JsonPrimitive;
9+
import com.google.gson.JsonSerializationContext;
10+
import com.google.gson.JsonSerializer;
511
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
612

713
import java.lang.reflect.Type;
@@ -60,7 +66,30 @@ private Alignment(float x, float y, String name) {
6066
*/
6167
public enum MainAxis {
6268

63-
START, CENTER, END, SPACE_BETWEEN, SPACE_AROUND
69+
/**
70+
* All children will be put at the start of the Flow next to each other.
71+
*/
72+
START,
73+
/**
74+
* All children will be put in the center of the Flow next to each other.
75+
*/
76+
CENTER,
77+
/**
78+
* All children will be put at the end of the Flow next to each other (this does not reverse children order).
79+
*/
80+
END,
81+
/**
82+
* This maximizes the space between children with the given available space of the Flow. The first widget will be put at the very
83+
* start and the last widget will be put at the very end. If the flow has exactly one child, then this behaves the same as
84+
* {@link #CENTER}.
85+
*/
86+
SPACE_BETWEEN,
87+
/**
88+
* This maximizes the space around the children with the given available space of the Flow. Contrary to {@link #SPACE_BETWEEN} this
89+
* does not put one "space" between every widget, but rather one "space" on both sides of every widget. If the flow has exactly one
90+
* child, then this behaves the same as {@link #CENTER}.
91+
*/
92+
SPACE_AROUND
6493
}
6594

6695
/**
@@ -69,7 +98,18 @@ public enum MainAxis {
6998
*/
7099
public enum CrossAxis {
71100

72-
START, CENTER, END
101+
/**
102+
* All children will be put at the start of the Flow next to each other.
103+
*/
104+
START,
105+
/**
106+
* All children will be put in the center of the Flow next to each other.
107+
*/
108+
CENTER,
109+
/**
110+
* All children will be put at the end of the Flow next to each other (this does not reverse children order).
111+
*/
112+
END
73113
}
74114

75115
public static class Json implements JsonDeserializer<Alignment>, JsonSerializer<Alignment> {

src/main/java/com/cleanroommc/modularui/utils/ColorShade.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ public int darkerSafe(int index) {
5959
return this.darker[MathUtils.clamp(index, 0, this.darker.length - 1)];
6060
}
6161

62+
public int darkerShadeCount() {
63+
return this.darker.length;
64+
}
65+
6266
public int brighter(int index) {
6367
return this.brighter[index];
6468
}
@@ -67,6 +71,10 @@ public int brighterSafe(int index) {
6771
return this.brighter[MathUtils.clamp(index, 0, this.brighter.length - 1)];
6872
}
6973

74+
public int brighterShadeCount() {
75+
return this.brighter.length;
76+
}
77+
7078
@NotNull
7179
@Override
7280
public IntIterator iterator() {

src/main/java/com/cleanroommc/modularui/widget/AbstractWidget.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,14 @@ protected void setName(String name) {
319319
this.name = name;
320320
}
321321

322+
public boolean isName(String name) {
323+
return Objects.equals(name, this.name);
324+
}
325+
326+
public boolean nameContains(String part) {
327+
return this.name != null && this.name.contains(part);
328+
}
329+
322330
/**
323331
* This is only used in {@link #toString()}.
324332
*

src/main/java/com/cleanroommc/modularui/widget/InternalWidgetTree.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ static boolean resize(ResizeNode resizer, boolean init, boolean onOpen, boolean
230230

231231
if (isLayout && shouldLayout) {
232232
layoutSuccessful &= resizer.postLayoutChildren();
233+
if (!selfFullyCalculated) resizer.postResize();
233234
}
234235
if (shouldLayout) resizer.setLayoutDone(layoutSuccessful);
235236
checkFullyCalculated(anotherResize, state, isLayout);

src/main/java/com/cleanroommc/modularui/widget/sizer/Area.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,10 @@ public int requestedSize(GuiAxis axis) {
235235
return axis.isHorizontal() ? requestedWidth() : requestedHeight();
236236
}
237237

238+
public int paddedSize(GuiAxis axis) {
239+
return axis.isHorizontal() ? paddedWidth() : paddedHeight();
240+
}
241+
238242
public int relativeEndX() {
239243
return this.rx + this.width;
240244
}

src/main/java/com/cleanroommc/modularui/widget/sizer/StandardResizer.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ public boolean resize(boolean isParentLayout) {
139139
// calculate x, y, width and height if possible
140140
this.x.apply(area, relativeTo, () -> getWidget().getDefaultWidth());
141141
this.y.apply(area, relativeTo, () -> getWidget().getDefaultHeight());
142-
return isFullyCalculated(isParentLayout);
142+
return isSelfFullyCalculated(isParentLayout);
143143
}
144144

145145
@Override
@@ -355,9 +355,13 @@ public void setLayoutDone(boolean done) {
355355
}
356356

357357
@Override
358-
public void setResized(boolean x, boolean y, boolean w, boolean h) {
359-
this.x.setResized(x, w);
360-
this.y.setResized(y, h);
358+
public void setXAxisResized(boolean pos, boolean size) {
359+
this.x.setResized(pos, size);
360+
}
361+
362+
@Override
363+
public void setYAxisResized(boolean pos, boolean size) {
364+
this.y.setResized(pos, size);
361365
}
362366

363367
@Override

src/main/java/com/cleanroommc/modularui/widget/sizer/StaticResizer.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,10 @@ public void setChildrenResized(boolean resized) {
7878
public void setLayoutDone(boolean done) {}
7979

8080
@Override
81-
public void setResized(boolean x, boolean y, boolean w, boolean h) {}
81+
public void setXAxisResized(boolean pos, boolean size) {}
82+
83+
@Override
84+
public void setYAxisResized(boolean pos, boolean size) {}
8285

8386
@Override
8487
public void setXMarginPaddingApplied(boolean b) {}

src/main/java/com/cleanroommc/modularui/widgets/ListWidget.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@
1414
import com.cleanroommc.modularui.widget.scroll.VerticalScrollData;
1515
import com.cleanroommc.modularui.widget.sizer.Unit;
1616
import com.cleanroommc.modularui.widgets.layout.Flow;
17+
import com.cleanroommc.modularui.widgets.layout.SimpleFlow;
1718

1819
import it.unimi.dsi.fastutil.ints.IntArrayList;
1920
import it.unimi.dsi.fastutil.ints.IntList;
2021

22+
import java.util.Collections;
2123
import java.util.List;
2224
import java.util.function.DoubleSupplier;
2325
import java.util.function.Function;
@@ -112,9 +114,6 @@ public boolean layoutWidgets() {
112114
widget.resizer().setMarginPaddingApplied(true);
113115
this.separatorPositions.add(p);
114116
p += separatorSize;
115-
/*if (isValid()) {
116-
widget.resizer().applyPos();
117-
}*/
118117
}
119118
int size = p + getArea().getPadding().getEnd(axis);
120119
getScrollData().setScrollSize(size);
@@ -133,7 +132,9 @@ public boolean layoutWidgets() {
133132

134133
@Override
135134
public boolean postLayoutWidgets() {
136-
return Flow.layoutCrossAxisListLike(this, getAxis(), this.caa, this.reverseLayout);
135+
SimpleFlow flow = new SimpleFlow();
136+
flow.widgets.addAll(getChildren());
137+
return Flow.layoutCrossAxisListLike(this, Collections.singletonList(flow), getAxis(), this.caa, 0);
137138
}
138139

139140
@Override

0 commit comments

Comments
 (0)