diff options
3 files changed, 202 insertions, 5 deletions
diff --git a/src/main/java/io/github/cottonmc/cotton/gui/widget/WListPanel.java b/src/main/java/io/github/cottonmc/cotton/gui/widget/WListPanel.java index d36fb70..5a4c35b 100644 --- a/src/main/java/io/github/cottonmc/cotton/gui/widget/WListPanel.java +++ b/src/main/java/io/github/cottonmc/cotton/gui/widget/WListPanel.java @@ -7,10 +7,13 @@ import net.minecraft.client.gui.DrawContext; import io.github.cottonmc.cotton.gui.GuiDescription; import io.github.cottonmc.cotton.gui.widget.data.Axis; import io.github.cottonmc.cotton.gui.widget.data.InputResult; +import io.github.cottonmc.cotton.gui.widget.data.Insets; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Objects; import java.util.function.BiConsumer; import java.util.function.Supplier; @@ -51,8 +54,16 @@ public class WListPanel<D, W extends WWidget> extends WClippedPanel { */ protected boolean fixedHeight = false; + /** + * @deprecated Replaced with {@link #getInsets() insets} and {@link #getGap() gap}. + */ + @Deprecated(forRemoval = true) protected int margin = 4; + // When the margin field is removed, these should get default values Insets(4, 4) and 4. + private @Nullable Insets insets = null; + private int gap = -1; + /** * The scroll bar of this list. */ @@ -153,8 +164,10 @@ public class WListPanel<D, W extends WWidget> extends WClippedPanel { } if (cellHeight<4) cellHeight=4; - int layoutHeight = this.getHeight()-(margin*2); - int cellsHigh = Math.max((layoutHeight+margin) / (cellHeight + margin), 1); // At least one cell is always visible + Insets insets = getInsets(); + int gap = getGap(); + int layoutHeight = this.getHeight() - insets.top() - insets.bottom(); + int cellsHigh = Math.max((layoutHeight + gap) / (cellHeight + gap), 1); // At least one cell is always visible //System.out.println("Adding children..."); @@ -190,10 +203,10 @@ public class WListPanel<D, W extends WWidget> extends WClippedPanel { //At this point, w is nonnull and configured by d if (w.canResize()) { - w.setSize(this.width-(margin*2) - scrollBar.getWidth(), cellHeight); + w.setSize(this.width - insets.left() - insets.right() - scrollBar.getWidth(), cellHeight); } - w.x = margin; - w.y = margin + ((cellHeight+margin) * i); + w.x = insets.left(); + w.y = insets.top() + ((cellHeight + gap) * i); this.children.add(w); } } @@ -227,4 +240,50 @@ public class WListPanel<D, W extends WWidget> extends WClippedPanel { public WScrollBar getScrollBar() { return scrollBar; } + + /** + * {@return the layout insets used for the contents of this list} + * @since 9.1.0 + */ + public Insets getInsets() { + // Returns the *effective* insets of this list for backwards compat. + return insets != null ? insets : new Insets(margin, margin); + } + + /** + * Sets the layout insets used for the contents of this list. + * + * @param insets the layout insets + * @return this list + * @since 9.1.0 + */ + public WListPanel<D, W> setInsets(Insets insets) { + this.insets = Objects.requireNonNull(insets, "Insets cannot be null"); + return this; + } + + /** + * {@return the gap between list items} + * @since 9.1.0 + */ + public int getGap() { + // Returns the *effective* gap of this list for backwards compat. + return gap >= 0 ? gap : margin; + } + + /** + * Sets the gap between list items. + * + * @param gap the gap, must be non-negative + * @return this list + * @since 9.1.0 + */ + public WListPanel<D, W> setGap(int gap) { + if (gap < 0) { + throw new IllegalArgumentException("Gap cannot be negative (was " + gap + ")"); + } + + this.gap = gap; + return this; + } } diff --git a/src/testMod/java/io/github/cottonmc/test/client/LibGuiTestClient.java b/src/testMod/java/io/github/cottonmc/test/client/LibGuiTestClient.java index 8d44715..aef04ed 100644 --- a/src/testMod/java/io/github/cottonmc/test/client/LibGuiTestClient.java +++ b/src/testMod/java/io/github/cottonmc/test/client/LibGuiTestClient.java @@ -70,6 +70,7 @@ public class LibGuiTestClient implements ClientModInitializer { .then(literal("titlealignment").executes(openScreen(Text.literal("test title"), client -> new TitleAlignmentTestGui()))) .then(literal("texture").executes(openScreen(client -> new TextureTestGui()))) .then(literal("textalignment").executes(openScreen(client -> new TextAlignmentTestGui()))) + .then(literal("list").executes(openScreen(client -> new ListTestGui()))) )); } diff --git a/src/testMod/java/io/github/cottonmc/test/client/ListTestGui.java b/src/testMod/java/io/github/cottonmc/test/client/ListTestGui.java new file mode 100644 index 0000000..42eb8b5 --- /dev/null +++ b/src/testMod/java/io/github/cottonmc/test/client/ListTestGui.java @@ -0,0 +1,137 @@ +package io.github.cottonmc.test.client; + +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; + +import io.github.cottonmc.cotton.gui.client.BackgroundPainter; +import io.github.cottonmc.cotton.gui.client.LightweightGuiDescription; +import io.github.cottonmc.cotton.gui.widget.WGridPanel; +import io.github.cottonmc.cotton.gui.widget.WLabel; +import io.github.cottonmc.cotton.gui.widget.WLabeledSlider; +import io.github.cottonmc.cotton.gui.widget.WListPanel; +import io.github.cottonmc.cotton.gui.widget.data.Axis; +import io.github.cottonmc.cotton.gui.widget.data.Insets; + +import java.util.Arrays; +import java.util.List; +import java.util.Random; + +public class ListTestGui extends LightweightGuiDescription { + private static final String[] LOREM = { + "Eius", + "architecto", + "dolores", + "in", + "delectus", + "omnis", + "Exercitationem", + "fugit", + "dolorem", + "sapiente", + "impedit", + "Occaecati", + "consequatur", + "omnis", + "nam", + "eveniet", + "eius", + "Eos", + "quasi", + "numquam", + "placeat", + "eaque", + "sapiente", + "Dolorum", + "magnam", + "eius", + "labore", + "voluptatem", + "est", + "voluptatem", + "aut", + "qui" + }; + + public ListTestGui() { + WGridPanel root = (WGridPanel) rootPanel; + + List<Formatting> formattings = Arrays.stream(Formatting.values()) + .filter(Formatting::isColor) + .toList(); + Random random = new Random(); + List<Text> data = Arrays.stream(LOREM) + .<Text>map(s -> { + Formatting formatting = formattings.get(random.nextInt(formattings.size())); + return Text.literal(s).formatted(formatting, Formatting.BOLD); + }) + .toList(); + + WListPanel<Text, WLorem> listPanel = new WListPanel<>(data, WLorem::new, (text, widget) -> widget.label.setText(text)); + WLabeledSlider topSlider = new WLabeledSlider(0, 16, Axis.HORIZONTAL, Text.literal("Top insets")); + WLabeledSlider bottomSlider = new WLabeledSlider(0, 16, Axis.HORIZONTAL, Text.literal("Bottom insets")); + WLabeledSlider leftSlider = new WLabeledSlider(0, 16, Axis.HORIZONTAL, Text.literal("Left insets")); + WLabeledSlider rightSlider = new WLabeledSlider(0, 16, Axis.HORIZONTAL, Text.literal("Right insets")); + WLabeledSlider gapSlider = new WLabeledSlider(0, 16, Axis.VERTICAL, Text.literal("Gap")); + + topSlider.setValue(listPanel.getInsets().top()); + topSlider.setValueChangeListener(top -> { + Insets insets = listPanel.getInsets(); + Insets newInsets = new Insets(top, insets.left(), insets.bottom(), insets.right()); + listPanel.setInsets(newInsets); + listPanel.layout(); + }); + + bottomSlider.setValue(listPanel.getInsets().bottom()); + bottomSlider.setValueChangeListener(bottom -> { + Insets insets = listPanel.getInsets(); + Insets newInsets = new Insets(insets.top(), insets.left(), bottom, insets.right()); + listPanel.setInsets(newInsets); + listPanel.layout(); + }); + + leftSlider.setValue(listPanel.getInsets().left()); + leftSlider.setValueChangeListener(left -> { + Insets insets = listPanel.getInsets(); + Insets newInsets = new Insets(insets.top(), left, insets.bottom(), insets.right()); + listPanel.setInsets(newInsets); + listPanel.layout(); + }); + + rightSlider.setValue(listPanel.getInsets().right()); + rightSlider.setValueChangeListener(right -> { + Insets insets = listPanel.getInsets(); + Insets newInsets = new Insets(insets.top(), insets.left(), insets.bottom(), right); + listPanel.setInsets(newInsets); + listPanel.layout(); + }); + + gapSlider.setValue(listPanel.getGap()); + gapSlider.setValueChangeListener(gap -> { + listPanel.setGap(gap); + listPanel.layout(); + }); + + root.setGaps(2, 2); + root.add(topSlider, 0, 0, 3, 1); + root.add(bottomSlider, 3, 0, 3, 1); + root.add(leftSlider, 0, 1, 3, 1); + root.add(rightSlider, 3, 1, 3, 1); + root.add(gapSlider, 6, 0, 1, 2); + root.add(listPanel, 0, 2, 6, 6); + root.validate(this); + } + + private static class WLorem extends WGridPanel { + private final WLabel label = new WLabel(Text.empty()); + + private WLorem() { + setInsets(Insets.ROOT_PANEL); + add(label, 0, 0); + } + + @Override + public void addPainters() { + setBackgroundPainter(BackgroundPainter.VANILLA); + } + } +} |