From dd65110f60aa3e32c2970863a06a7682520cce5e Mon Sep 17 00:00:00 2001 From: Xander Date: Sun, 11 Dec 2022 19:31:56 +0000 Subject: [Feature] Lists (#40) --- .../yacl/gui/controllers/ControllerWidget.java | 4 +- .../yacl/gui/controllers/LabelController.java | 8 +- .../yacl/gui/controllers/ListEntryWidget.java | 132 +++++++++++++++++++++ .../slider/SliderControllerElement.java | 6 +- .../string/StringControllerElement.java | 12 +- 5 files changed, 156 insertions(+), 6 deletions(-) create mode 100644 src/client/java/dev/isxander/yacl/gui/controllers/ListEntryWidget.java (limited to 'src/client/java/dev/isxander/yacl/gui/controllers') diff --git a/src/client/java/dev/isxander/yacl/gui/controllers/ControllerWidget.java b/src/client/java/dev/isxander/yacl/gui/controllers/ControllerWidget.java index 0f49d3d..ae54ca4 100644 --- a/src/client/java/dev/isxander/yacl/gui/controllers/ControllerWidget.java +++ b/src/client/java/dev/isxander/yacl/gui/controllers/ControllerWidget.java @@ -8,6 +8,7 @@ import dev.isxander.yacl.gui.utils.GuiUtils; import net.minecraft.client.font.MultilineText; import net.minecraft.client.gui.DrawableHelper; import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; +import net.minecraft.client.gui.screen.narration.NarrationPart; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.text.Text; import net.minecraft.util.Formatting; @@ -151,6 +152,7 @@ public abstract class ControllerWidget> extends Abstract @Override public void appendNarrations(NarrationMessageBuilder builder) { - + builder.put(NarrationPart.TITLE, control.option().name()); + builder.put(NarrationPart.HINT, control.option().tooltip()); } } diff --git a/src/client/java/dev/isxander/yacl/gui/controllers/LabelController.java b/src/client/java/dev/isxander/yacl/gui/controllers/LabelController.java index 8369680..960c950 100644 --- a/src/client/java/dev/isxander/yacl/gui/controllers/LabelController.java +++ b/src/client/java/dev/isxander/yacl/gui/controllers/LabelController.java @@ -64,7 +64,7 @@ public class LabelController implements Controller { float y = getDimension().y(); for (OrderedText text : wrappedText) { - textRenderer.drawWithShadow(matrices, text, getDimension().x(), y + getYPadding(), option().available() ? -1 : 0xFFA0A0A0); + textRenderer.drawWithShadow(matrices, text, getDimension().x() + getXPadding(), y + getYPadding(), option().available() ? -1 : 0xFFA0A0A0); y += textRenderer.fontHeight; } } @@ -123,12 +123,16 @@ public class LabelController implements Controller { return textRenderer.getTextHandler().getStyleAt(wrappedText.get(line), x); } + private int getXPadding() { + return 4; + } + private int getYPadding() { return 3; } private void updateText() { - wrappedText = textRenderer.wrapLines(formatValue(), getDimension().width()); + wrappedText = textRenderer.wrapLines(formatValue(), getDimension().width() - getXPadding() * 2); setDimension(getDimension().withHeight(wrappedText.size() * textRenderer.fontHeight + getYPadding() * 2)); } diff --git a/src/client/java/dev/isxander/yacl/gui/controllers/ListEntryWidget.java b/src/client/java/dev/isxander/yacl/gui/controllers/ListEntryWidget.java new file mode 100644 index 0000000..a548efb --- /dev/null +++ b/src/client/java/dev/isxander/yacl/gui/controllers/ListEntryWidget.java @@ -0,0 +1,132 @@ +package dev.isxander.yacl.gui.controllers; + +import com.google.common.collect.ImmutableList; +import dev.isxander.yacl.api.ListOption; +import dev.isxander.yacl.api.ListOptionEntry; +import dev.isxander.yacl.api.utils.Dimension; +import dev.isxander.yacl.gui.*; +import net.minecraft.client.gui.Element; +import net.minecraft.client.gui.ParentElement; +import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.text.Text; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class ListEntryWidget extends AbstractWidget implements ParentElement { + private final TooltipButtonWidget removeButton, moveUpButton, moveDownButton; + private final AbstractWidget entryWidget; + + private final ListOption listOption; + private final ListOptionEntry listOptionEntry; + + private final String optionNameString; + + private Element focused; + private boolean dragging; + + public ListEntryWidget(YACLScreen screen, ListOptionEntry listOptionEntry, AbstractWidget entryWidget) { + super(entryWidget.getDimension()); + this.listOptionEntry = listOptionEntry; + this.listOption = listOptionEntry.parentGroup(); + this.optionNameString = listOptionEntry.name().getString().toLowerCase(); + this.entryWidget = entryWidget; + + Dimension dim = entryWidget.getDimension(); + entryWidget.setDimension(dim.clone().move(20 * 2, 0).expand(-20 * 3, 0)); + + removeButton = new TooltipButtonWidget(screen, dim.xLimit() - 20, dim.y(), 20, 20, Text.of("\u274c"), Text.translatable("yacl.list.remove"), btn -> { + listOption.removeEntry(listOptionEntry); + }); + + moveUpButton = new TooltipButtonWidget(screen, dim.x(), dim.y(), 20, 20, Text.of("\u2191"), Text.translatable("yacl.list.move_up"), btn -> { + int index = listOption.indexOf(listOptionEntry) - 1; + if (index >= 0) { + listOption.removeEntry(listOptionEntry); + listOption.insertEntry(index, listOptionEntry); + updateButtonStates(); + } + }); + + moveDownButton = new TooltipButtonWidget(screen, dim.x() + 20, dim.y(), 20, 20, Text.of("\u2193"), Text.translatable("yacl.list.move_down"), btn -> { + int index = listOption.indexOf(listOptionEntry) + 1; + if (index < listOption.options().size()) { + listOption.removeEntry(listOptionEntry); + listOption.insertEntry(index, listOptionEntry); + updateButtonStates(); + } + }); + + updateButtonStates(); + } + + @Override + public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { + updateButtonStates(); // update every render in case option becomes available/unavailable + + removeButton.setY(getDimension().y()); + moveUpButton.setY(getDimension().y()); + moveDownButton.setY(getDimension().y()); + entryWidget.setDimension(entryWidget.getDimension().withY(getDimension().y())); + + removeButton.render(matrices, mouseX, mouseY, delta); + moveUpButton.render(matrices, mouseX, mouseY, delta); + moveDownButton.render(matrices, mouseX, mouseY, delta); + entryWidget.render(matrices, mouseX, mouseY, delta); + } + + @Override + public void postRender(MatrixStack matrices, int mouseX, int mouseY, float delta) { + removeButton.renderHoveredTooltip(matrices); + moveUpButton.renderHoveredTooltip(matrices); + moveDownButton.renderHoveredTooltip(matrices); + } + + protected void updateButtonStates() { + removeButton.active = listOption.available(); + moveUpButton.active = listOption.indexOf(listOptionEntry) > 0 && listOption.available(); + moveDownButton.active = listOption.indexOf(listOptionEntry) < listOption.options().size() - 1 && listOption.available(); + } + + @Override + public void unfocus() { + entryWidget.unfocus(); + } + + @Override + public void appendNarrations(NarrationMessageBuilder builder) { + entryWidget.appendNarrations(builder); + } + + @Override + public boolean matchesSearch(String query) { + return optionNameString.contains(query.toLowerCase()); + } + + @Override + public List children() { + return ImmutableList.of(moveUpButton, moveDownButton, entryWidget, removeButton); + } + + @Override + public boolean isDragging() { + return dragging; + } + + @Override + public void setDragging(boolean dragging) { + this.dragging = dragging; + } + + @Nullable + @Override + public Element getFocused() { + return focused; + } + + @Override + public void setFocused(@Nullable Element focused) { + this.focused = focused; + } +} diff --git a/src/client/java/dev/isxander/yacl/gui/controllers/slider/SliderControllerElement.java b/src/client/java/dev/isxander/yacl/gui/controllers/slider/SliderControllerElement.java index c78e0eb..ea4e262 100644 --- a/src/client/java/dev/isxander/yacl/gui/controllers/slider/SliderControllerElement.java +++ b/src/client/java/dev/isxander/yacl/gui/controllers/slider/SliderControllerElement.java @@ -141,7 +141,11 @@ public class SliderControllerElement extends ControllerWidget dim) { super.setDimension(dim); - sliderBounds = Dimension.ofInt(dim.xLimit() - getXPadding() - getThumbWidth() / 2 - dim.width() / 3, dim.centerY() - 5, dim.width() / 3, 10); + int trackWidth = dim.width() / 3; + if (optionNameString.isEmpty()) + trackWidth = dim.width() / 2; + + sliderBounds = Dimension.ofInt(dim.xLimit() - getXPadding() - getThumbWidth() / 2 - trackWidth, dim.centerY() - 5, trackWidth, 10); } protected int getThumbX() { diff --git a/src/client/java/dev/isxander/yacl/gui/controllers/string/StringControllerElement.java b/src/client/java/dev/isxander/yacl/gui/controllers/string/StringControllerElement.java index ef70341..da33aec 100644 --- a/src/client/java/dev/isxander/yacl/gui/controllers/string/StringControllerElement.java +++ b/src/client/java/dev/isxander/yacl/gui/controllers/string/StringControllerElement.java @@ -49,7 +49,7 @@ public class StringControllerElement extends ControllerWidget