From 3a86e9d2ba89466f7f9ef51c29eb5879bcb8a98e Mon Sep 17 00:00:00 2001 From: isXander Date: Thu, 17 Nov 2022 17:18:19 +0000 Subject: 22w46a --- .../java/dev/isxander/yacl/gui/AbstractWidget.java | 2 +- .../dev/isxander/yacl/gui/CategoryListWidget.java | 4 +- .../isxander/yacl/gui/LowProfileButtonWidget.java | 10 +- .../dev/isxander/yacl/gui/OptionListWidget.java | 6 +- .../dev/isxander/yacl/gui/SearchFieldWidget.java | 2 +- .../isxander/yacl/gui/TextScaledButtonWidget.java | 11 +- .../dev/isxander/yacl/gui/TooltipButtonWidget.java | 4 +- .../java/dev/isxander/yacl/gui/YACLScreen.java | 9 +- src/main/resources/fabric.mod.json | 5 +- .../java/dev/isxander/yacl/test/GuiTest.java | 417 ++++++++++++++++++++ .../dev/isxander/yacl/test/ModMenuIntegration.java | 437 --------------------- .../yacl/test/mixins/TitleScreenMixin.java | 26 ++ src/testmod/resources/fabric.mod.json | 13 +- .../yet-another-config-lib.test.mixins.json | 11 + 14 files changed, 487 insertions(+), 470 deletions(-) create mode 100644 src/testmod/java/dev/isxander/yacl/test/GuiTest.java delete mode 100644 src/testmod/java/dev/isxander/yacl/test/ModMenuIntegration.java create mode 100644 src/testmod/java/dev/isxander/yacl/test/mixins/TitleScreenMixin.java create mode 100644 src/testmod/resources/yet-another-config-lib.test.mixins.json (limited to 'src') diff --git a/src/main/java/dev/isxander/yacl/gui/AbstractWidget.java b/src/main/java/dev/isxander/yacl/gui/AbstractWidget.java index 03dc9b9..bede0ae 100644 --- a/src/main/java/dev/isxander/yacl/gui/AbstractWidget.java +++ b/src/main/java/dev/isxander/yacl/gui/AbstractWidget.java @@ -82,7 +82,7 @@ public abstract class AbstractWidget implements Element, Drawable, Selectable { int width = x2 - x1; int height = y2 - y1; - RenderSystem.setShader(GameRenderer::getPositionTexShader); + RenderSystem.setShader(GameRenderer::getPositionTexProgram); RenderSystem.setShaderTexture(0, ClickableWidget.WIDGETS_TEXTURE); RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); int i = !enabled ? 0 : hovered ? 2 : 1; diff --git a/src/main/java/dev/isxander/yacl/gui/CategoryListWidget.java b/src/main/java/dev/isxander/yacl/gui/CategoryListWidget.java index 2cb6bb6..46a9fdf 100644 --- a/src/main/java/dev/isxander/yacl/gui/CategoryListWidget.java +++ b/src/main/java/dev/isxander/yacl/gui/CategoryListWidget.java @@ -15,7 +15,7 @@ public class CategoryListWidget extends ElementListWidget widget.render(matrices, mouseX, mouseY, tickDelta); if (resetButton != null) { - resetButton.y = y; + resetButton.setY(y); resetButton.render(matrices, mouseX, mouseY, tickDelta); } } @@ -402,8 +402,8 @@ public class OptionListWidget extends ElementListWidget public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { this.y = y; - expandMinimizeButton.x = x; - expandMinimizeButton.y = y + entryHeight / 2 - expandMinimizeButton.getHeight() / 2; + expandMinimizeButton.setX(x); + expandMinimizeButton.setY(y + entryHeight / 2 - expandMinimizeButton.getHeight() / 2); expandMinimizeButton.render(matrices, mouseX, mouseY, tickDelta); wrappedName.drawCenterWithShadow(matrices, x + entryWidth / 2, y + getYPadding()); diff --git a/src/main/java/dev/isxander/yacl/gui/SearchFieldWidget.java b/src/main/java/dev/isxander/yacl/gui/SearchFieldWidget.java index 6184405..5b7c9dc 100644 --- a/src/main/java/dev/isxander/yacl/gui/SearchFieldWidget.java +++ b/src/main/java/dev/isxander/yacl/gui/SearchFieldWidget.java @@ -25,7 +25,7 @@ public class SearchFieldWidget extends TextFieldWidget { public void renderButton(MatrixStack matrices, int mouseX, int mouseY, float delta) { super.renderButton(matrices, mouseX, mouseY, delta); if (isVisible() && isEmpty()) { - textRenderer.drawWithShadow(matrices, emptyText, x + 4, this.y + (this.height - 8) / 2f, 0x707070); + textRenderer.drawWithShadow(matrices, emptyText, getX() + 4, this.getY() + (this.height - 8) / 2f, 0x707070); } } diff --git a/src/main/java/dev/isxander/yacl/gui/TextScaledButtonWidget.java b/src/main/java/dev/isxander/yacl/gui/TextScaledButtonWidget.java index d588d52..197a162 100644 --- a/src/main/java/dev/isxander/yacl/gui/TextScaledButtonWidget.java +++ b/src/main/java/dev/isxander/yacl/gui/TextScaledButtonWidget.java @@ -2,6 +2,7 @@ package dev.isxander.yacl.gui; import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.screen.Tooltip; import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.text.OrderedText; @@ -12,13 +13,13 @@ public class TextScaledButtonWidget extends ButtonWidget { public float textScale; public TextScaledButtonWidget(int x, int y, int width, int height, float textScale, Text message, PressAction onPress) { - super(x, y, width, height, message, onPress); + super(x, y, width, height, message, onPress, ButtonWidget.DEFAULT_NARRATION_SUPPLIER); this.textScale = textScale; } - public TextScaledButtonWidget(int x, int y, int width, int height, float textScale, Text message, PressAction onPress, TooltipSupplier tooltipSupplier) { - super(x, y, width, height, message, onPress, tooltipSupplier); - this.textScale = textScale; + public TextScaledButtonWidget(int x, int y, int width, int height, float textScale, Text message, PressAction onPress, Tooltip tooltip) { + this(x, y, width, height, textScale, message, onPress); + setTooltip(tooltip); } @Override @@ -35,7 +36,7 @@ public class TextScaledButtonWidget extends ButtonWidget { TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; matrices.push(); - matrices.translate(((this.x + this.width / 2f) - textRenderer.getWidth(orderedText) * textScale / 2), (float)this.y + (this.height - 8 * textScale) / 2f / textScale, 0); + matrices.translate(((this.getX() + this.width / 2f) - textRenderer.getWidth(orderedText) * textScale / 2), (float)this.getY() + (this.height - 8 * textScale) / 2f / textScale, 0); matrices.scale(textScale, textScale, 1); textRenderer.drawWithShadow(matrices, orderedText, 0, 0, j | MathHelper.ceil(this.alpha * 255.0F) << 24); matrices.pop(); diff --git a/src/main/java/dev/isxander/yacl/gui/TooltipButtonWidget.java b/src/main/java/dev/isxander/yacl/gui/TooltipButtonWidget.java index d105f7b..706765a 100644 --- a/src/main/java/dev/isxander/yacl/gui/TooltipButtonWidget.java +++ b/src/main/java/dev/isxander/yacl/gui/TooltipButtonWidget.java @@ -13,14 +13,14 @@ public class TooltipButtonWidget extends ButtonWidget { protected MultilineText wrappedDescription; public TooltipButtonWidget(Screen screen, int x, int y, int width, int height, Text message, Text tooltip, PressAction onPress) { - super(x, y, width, height, message, onPress); + super(x, y, width, height, message, onPress, ButtonWidget.DEFAULT_NARRATION_SUPPLIER); this.screen = screen; setTooltip(tooltip); } public void renderHoveredTooltip(MatrixStack matrices) { if (isHovered()) { - YACLScreen.renderMultilineTooltip(matrices, MinecraftClient.getInstance().textRenderer, wrappedDescription, x + width / 2, y - 4, y + height + 4, screen.width, screen.height); + YACLScreen.renderMultilineTooltip(matrices, MinecraftClient.getInstance().textRenderer, wrappedDescription, getX() + width / 2, getY() - 4, getY() + height + 4, screen.width, screen.height); } } diff --git a/src/main/java/dev/isxander/yacl/gui/YACLScreen.java b/src/main/java/dev/isxander/yacl/gui/YACLScreen.java index 629fd4c..e36c8e8 100644 --- a/src/main/java/dev/isxander/yacl/gui/YACLScreen.java +++ b/src/main/java/dev/isxander/yacl/gui/YACLScreen.java @@ -13,8 +13,7 @@ import net.minecraft.client.render.*; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.text.Text; import net.minecraft.util.Formatting; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.Matrix4f; +import org.joml.Matrix4f; import java.util.HashSet; import java.util.Set; @@ -85,7 +84,7 @@ public class YACLScreen extends Screen { OptionUtils.forEachOptions(config, Option::forgetPendingValue); }); - searchFieldWidget = new SearchFieldWidget(this, textRenderer, width / 3 / 2 - paddedWidth / 2 + 1, undoButton.y - 22, paddedWidth - 2, 18, Text.translatable("gui.recipebook.search_hint"), Text.translatable("gui.recipebook.search_hint")); + searchFieldWidget = new SearchFieldWidget(this, textRenderer, width / 3 / 2 - paddedWidth / 2 + 1, undoButton.getY() - 22, paddedWidth - 2, 18, Text.translatable("gui.recipebook.search_hint"), Text.translatable("gui.recipebook.search_hint")); categoryList = new CategoryListWidget(client, this, width, height); addSelectableChild(categoryList); @@ -241,7 +240,7 @@ public class YACLScreen extends Screen { matrices.push(); Tessellator tessellator = Tessellator.getInstance(); BufferBuilder bufferBuilder = tessellator.getBuffer(); - RenderSystem.setShader(GameRenderer::getPositionColorShader); + RenderSystem.setShader(GameRenderer::getPositionColorProgram); bufferBuilder.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR); Matrix4f matrix4f = matrices.peek().getPositionMatrix(); fillGradient(matrix4f, bufferBuilder, drawX - 3, drawY - 4, drawX + maxWidth + 3, drawY - 3, 400, -267386864, -267386864); @@ -257,7 +256,7 @@ public class YACLScreen extends Screen { RenderSystem.disableTexture(); RenderSystem.enableBlend(); RenderSystem.defaultBlendFunc(); - BufferRenderer.drawWithShader(bufferBuilder.end()); + BufferRenderer.drawWithGlobalProgram(bufferBuilder.end()); RenderSystem.disableBlend(); RenderSystem.enableTexture(); matrices.translate(0.0, 0.0, 400.0); diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index fc5a14f..37b150e 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -20,8 +20,9 @@ }, "depends": { "fabricloader": ">=0.14.0", - "minecraft": "1.19.x", - "java": ">=17" + "minecraft": "~1.19.3-alpha.22.46.a", + "java": ">=17", + "fabric-resource-loader-v0": "*" }, "mixins": [ "yet-another-config-lib.mixins.json" diff --git a/src/testmod/java/dev/isxander/yacl/test/GuiTest.java b/src/testmod/java/dev/isxander/yacl/test/GuiTest.java new file mode 100644 index 0000000..449a081 --- /dev/null +++ b/src/testmod/java/dev/isxander/yacl/test/GuiTest.java @@ -0,0 +1,417 @@ +package dev.isxander.yacl.test; + +import dev.isxander.yacl.api.*; +import dev.isxander.yacl.gui.RequireRestartScreen; +import dev.isxander.yacl.gui.controllers.*; +import dev.isxander.yacl.gui.controllers.cycling.EnumController; +import dev.isxander.yacl.gui.controllers.slider.DoubleSliderController; +import dev.isxander.yacl.gui.controllers.slider.FloatSliderController; +import dev.isxander.yacl.gui.controllers.slider.IntegerSliderController; +import dev.isxander.yacl.gui.controllers.slider.LongSliderController; +import dev.isxander.yacl.gui.controllers.string.StringController; +import dev.isxander.yacl.test.config.ConfigData; +import dev.isxander.yacl.test.config.Entrypoint; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.option.GraphicsMode; +import net.minecraft.client.toast.SystemToast; +import net.minecraft.text.ClickEvent; +import net.minecraft.text.HoverEvent; +import net.minecraft.text.Text; + +import java.awt.*; + +public class GuiTest { + public static Screen getModConfigScreenFactory(Screen parent) { + return Entrypoint.getConfig().buildConfig((config, builder) -> builder + .title(Text.of("Test Suites")) + .category(ConfigCategory.createBuilder() + .name(Text.of("Suites")) + .option(ButtonOption.createBuilder() + .name(Text.of("Full Test Suite")) + .controller(ActionController::new) + .action((screen, opt) -> MinecraftClient.getInstance().setScreen(getFullTestSuite(screen))) + .build()) + .option(ButtonOption.createBuilder() + .name(Text.of("Basic Wiki Suite")) + .controller(ActionController::new) + .action((screen, opt) -> MinecraftClient.getInstance().setScreen(getWikiBasic(screen))) + .build()) + .option(ButtonOption.createBuilder() + .name(Text.of("Group Wiki Suite")) + .controller(ActionController::new) + .action((screen, opt) -> MinecraftClient.getInstance().setScreen(getWikiGroups(screen))) + .build()) + .option(ButtonOption.createBuilder() + .name(Text.of("Unavailable Test Suite")) + .controller(ActionController::new) + .action((screen, opt) -> MinecraftClient.getInstance().setScreen(getDisabledTest(screen))) + .build()) + .build()) + ) + .generateScreen(parent); + } + + private static Screen getFullTestSuite(Screen parent) { + return Entrypoint.getConfig().buildConfig((config, builder) -> builder + .title(Text.of("Test GUI")) + .category(ConfigCategory.createBuilder() + .name(Text.of("Control Examples")) + .tooltip(Text.of("Example Category Description")) + .group(OptionGroup.createBuilder() + .name(Text.of("Boolean Controllers")) + .tooltip(Text.of("Test!")) + .collapsed(true) + .option(Option.createBuilder(boolean.class) + .name(Text.of("Boolean Toggle")) + .tooltip(value -> Text.of("A simple toggle button that contains the value '" + value + "'")) + .binding( + config.getDefaults().booleanToggle, + () -> config.getConfig().booleanToggle, + (value) -> config.getConfig().booleanToggle = value + ) + .controller(BooleanController::new) + .flag(OptionFlag.GAME_RESTART) + .available(false) + .build()) + .option(Option.createBuilder(boolean.class) + .name(Text.of("Custom Boolean Toggle")) + .tooltip(Text.of("You can customize these controllers like this!")) + .binding( + config.getDefaults().customBooleanToggle, + () -> config.getConfig().customBooleanToggle, + (value) -> config.getConfig().customBooleanToggle = value + ) + .controller(opt -> new BooleanController(opt, state -> state ? Text.of("Amazing") : Text.of("Not Amazing"), true)) + .build()) + .option(Option.createBuilder(boolean.class) + .name(Text.of("Tick Box")) + .tooltip(Text.of("There are even alternate methods of displaying the same data type!")) + .binding( + config.getDefaults().tickbox, + () -> config.getConfig().tickbox, + (value) -> config.getConfig().tickbox = value + ) + .controller(TickBoxController::new) + .build()) + .build()) + .group(OptionGroup.createBuilder() + .name(Text.of("Slider Controllers")) + .option(Option.createBuilder(int.class) + .name(Text.of("Int Slider that is cut off because the slider")) + .instant(true) + .binding( + config.getDefaults().intSlider, + () -> config.getConfig().intSlider, + value -> config.getConfig().intSlider = value + + ) + .controller(opt -> new IntegerSliderController(opt, 0, 3, 1)) + .build()) + .option(Option.createBuilder(double.class) + .name(Text.of("Double Slider")) + .binding( + config.getDefaults().doubleSlider, + () -> config.getConfig().doubleSlider, + (value) -> config.getConfig().doubleSlider = value + ) + .controller(opt -> new DoubleSliderController(opt, 0, 3, 0.05)) + .build()) + .option(Option.createBuilder(float.class) + .name(Text.of("Float Slider")) + .binding( + config.getDefaults().floatSlider, + () -> config.getConfig().floatSlider, + (value) -> config.getConfig().floatSlider = value + ) + .controller(opt -> new FloatSliderController(opt, 0, 3, 0.1f)) + .build()) + .option(Option.createBuilder(long.class) + .name(Text.of("Long Slider")) + .binding( + config.getDefaults().longSlider, + () -> config.getConfig().longSlider, + (value) -> config.getConfig().longSlider = value + ) + .controller(opt -> new LongSliderController(opt, 0, 1_000_000, 100)) + .build()) + .build()) + .group(OptionGroup.createBuilder() + .name(Text.of("Input Field Controllers")) + .option(Option.createBuilder(String.class) + .name(Text.of("Text Option")) + .binding( + config.getDefaults().textField, + () -> config.getConfig().textField, + value -> config.getConfig().textField = value + ) + .controller(StringController::new) + .build()) + .option(Option.createBuilder(Color.class) + .name(Text.of("Color Option")) + .binding( + config.getDefaults().colorOption, + () -> config.getConfig().colorOption, + value -> config.getConfig().colorOption = value + ) + .controller(ColorController::new) + .build()) + .build()) + .group(OptionGroup.createBuilder() + .name(Text.of("Enum Controllers")) + .option(Option.createBuilder(ConfigData.Alphabet.class) + .name(Text.of("Enum Cycler")) + .binding( + config.getDefaults().enumOption, + () -> config.getConfig().enumOption, + (value) -> config.getConfig().enumOption = value + ) + .controller(EnumController::new) + .build()) + .build()) + .group(OptionGroup.createBuilder() + .name(Text.of("Options that aren't really options")) + .option(ButtonOption.createBuilder() + .name(Text.of("Button \"Option\"")) + .action((screen, opt) -> SystemToast.add(MinecraftClient.getInstance().getToastManager(), SystemToast.Type.TUTORIAL_HINT, Text.of("Button Pressed"), Text.of("Button option was invoked!"))) + .controller(ActionController::new) + .build()) + .option(Option.createBuilder(Text.class) + .binding(Binding.immutable(Text.empty() + .append(Text.literal("a").styled(style -> style.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.of("a"))))) + .append(Text.literal("b").styled(style -> style.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.of("b"))))) + .append(Text.literal("c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c").styled(style -> style.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.of("c"))))) + .append(Text.literal("e").styled(style -> style.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.of("e"))))) + .styled(style -> style.withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://isxander.dev"))) + )) + .controller(LabelController::new) + .build()) + .build()) + .group(OptionGroup.createBuilder() + .name(Text.of("Minecraft Bindings")) + .tooltip(Text.of("YACL can also bind Minecraft options!")) + .option(Option.createBuilder(boolean.class) + .name(Text.of("Minecraft AutoJump")) + .tooltip(Text.of("You can even bind minecraft options!")) + .binding(Binding.minecraft(MinecraftClient.getInstance().options.getAutoJump())) + .controller(TickBoxController::new) + .build()) + .option(Option.createBuilder(GraphicsMode.class) + .name(Text.of("Minecraft Graphics Mode")) + .binding(Binding.minecraft(MinecraftClient.getInstance().options.getGraphicsMode())) + .controller(EnumController::new) + .build()) + .build()) + .build()) + .category(PlaceholderCategory.createBuilder() + .name(Text.of("Placeholder Category")) + .screen((client, yaclScreen) -> new RequireRestartScreen(yaclScreen)) + .build()) + .category(ConfigCategory.createBuilder() + .name(Text.of("Group Test")) + .option(Option.createBuilder(boolean.class) + .name(Text.of("Root Test")) + .binding( + config.getDefaults().groupTestRoot, + () -> config.getConfig().groupTestRoot, + value -> config.getConfig().groupTestRoot = value + ) + .controller(TickBoxController::new) + .build()) + .group(OptionGroup.createBuilder() + .name(Text.of("First Group")) + .option(Option.createBuilder(boolean.class) + .name(Text.of("First Group Test 1")) + .binding( + config.getDefaults().groupTestFirstGroup, + () -> config.getConfig().groupTestFirstGroup, + value -> config.getConfig().groupTestFirstGroup = value + ) + .controller(TickBoxController::new) + .build()) + .option(Option.createBuilder(boolean.class) + .name(Text.of("First Group Test 2")) + .binding( + config.getDefaults().groupTestFirstGroup2, + () -> config.getConfig().groupTestFirstGroup2, + value -> config.getConfig().groupTestFirstGroup2 = value + ) + .controller(TickBoxController::new) + .build()) + .build()) + .group(OptionGroup.createBuilder() + .name(Text.empty()) + .option(Option.createBuilder(boolean.class) + .name(Text.of("Second Group Test")) + .binding( + config.getDefaults().groupTestSecondGroup, + () -> config.getConfig().groupTestSecondGroup, + value -> config.getConfig().groupTestSecondGroup = value + ) + .controller(TickBoxController::new) + .build()) + .build()) + .build()) + .category(ConfigCategory.createBuilder() + .name(Text.of("Scroll Test")) + .option(Option.createBuilder(int.class) + .name(Text.of("Int Slider that is cut off because the slider")) + .binding( + config.getDefaults().scrollingSlider, + () -> config.getConfig().scrollingSlider, + (value) -> config.getConfig().scrollingSlider = value + ) + .controller(opt -> new IntegerSliderController(opt, 0, 10, 1)) + .build()) + .option(ButtonOption.createBuilder() + .name(Text.of("Option")) + .action((screen, opt) -> {}) + .controller(ActionController::new) + .build()) + .option(ButtonOption.createBuilder() + .name(Text.of("Option")) + .action((screen, opt) -> {}) + .controller(ActionController::new) + .build()) + .option(ButtonOption.createBuilder() + .name(Text.of("Option")) + .action((screen, opt) -> {}) + .controller(ActionController::new) + .build()) + .option(ButtonOption.createBuilder() + .name(Text.of("Option")) + .action((screen, opt) -> {}) + .controller(ActionController::new) + .build()) + .option(ButtonOption.createBuilder() + .name(Text.of("Option")) + .action((screen, opt) -> {}) + .controller(ActionController::new) + .build()) + .option(ButtonOption.createBuilder() + .name(Text.of("Option")) + .action((screen, opt) -> {}) + .controller(ActionController::new) + .build()) + .option(ButtonOption.createBuilder() + .name(Text.of("Option")) + .action((screen, opt) -> {}) + .controller(ActionController::new) + .build()) + .option(ButtonOption.createBuilder() + .name(Text.of("Option")) + .action((screen, opt) -> {}) + .controller(ActionController::new) + .build()) + .option(ButtonOption.createBuilder() + .name(Text.of("Option")) + .action((screen, opt) -> {}) + .controller(ActionController::new) + .build()) + .option(ButtonOption.createBuilder() + .name(Text.of("Option")) + .action((screen, opt) -> {}) + .controller(ActionController::new) + .build()) + .option(ButtonOption.createBuilder() + .name(Text.of("Option")) + .action((screen, opt) -> {}) + .controller(ActionController::new) + .build()) + .option(ButtonOption.createBuilder() + .name(Text.of("Option")) + .action((screen, opt) -> {}) + .controller(ActionController::new) + .build()) + .option(ButtonOption.createBuilder() + .name(Text.of("Option")) + .action((screen, opt) -> {}) + .controller(ActionController::new) + .build()) + .build()) + .save(() -> { + MinecraftClient.getInstance().options.write(); + config.save(); + }) + ) + .generateScreen(parent); + } + + private static Screen getDisabledTest(Screen parent) { + return Entrypoint.getConfig().buildConfig((config, builder) -> builder + .title(Text.empty()) + .category(ConfigCategory.createBuilder() + .name(Text.of("Disabled Test")) + .option(Option.createBuilder(int.class) + .name(Text.of("Slider")) + .binding(Binding.immutable(0)) + .controller(opt -> new IntegerSliderController(opt, 0, 5, 1)) + .available(false) + .build()) + .option(Option.createBuilder(boolean.class) + .name(Text.of("Tick Box")) + .binding(Binding.immutable(true)) + .controller(TickBoxController::new) + .available(false) + .build()) + .option(Option.createBuilder(boolean.class) + .name(Text.of("Tick Box (Enabled)")) + .binding(Binding.immutable(true)) + .controller(TickBoxController::new) + .build()) + .option(Option.createBuilder(String.class) + .name(Text.of("Text Field")) + .binding(Binding.immutable("hi")) + .controller(StringController::new) + .available(false) + .build()) + .build()) + ) + .generateScreen(parent); + } + + private static Screen getWikiBasic(Screen parent) { + return Entrypoint.getConfig().buildConfig((config, builder) -> builder + .title(Text.of("Mod Name")) + .category(ConfigCategory.createBuilder() + .name(Text.of("My Category")) + .tooltip(Text.of("This displays when you hover over a category button")) // optional + .option(Option.createBuilder(boolean.class) + .name(Text.of("My Boolean Option")) + .tooltip(Text.of("This option displays the basic capabilities of YetAnotherConfigLib")) // optional + .binding( + config.getDefaults().booleanToggle, // default + () -> config.getConfig().booleanToggle, // getter + newValue -> config.getConfig().booleanToggle = newValue // setter + ) + .controller(BooleanController::new) + .build()) + .build()) + ) + .generateScreen(parent); + } + + private static Screen getWikiGroups(Screen parent) { + return Entrypoint.getConfig().buildConfig((config, builder) -> builder + .title(Text.of("Mod Name")) + .category(ConfigCategory.createBuilder() + .name(Text.of("My Category")) + .tooltip(Text.of("This displays when you hover over a category button")) // optional + .group(OptionGroup.createBuilder() + .name(Text.of("Option Group")) + .option(Option.createBuilder(boolean.class) + .name(Text.of("My Boolean Option")) + .tooltip(Text.of("This option displays the basic capabilities of YetAnotherConfigLib")) // optional + .binding( + config.getDefaults().booleanToggle, // default + () -> config.getConfig().booleanToggle, // getter + newValue -> config.getConfig().booleanToggle = newValue // setter + ) + .controller(BooleanController::new) + .build()) + .build()) + .build()) + ) + .generateScreen(parent); + } +} diff --git a/src/testmod/java/dev/isxander/yacl/test/ModMenuIntegration.java b/src/testmod/java/dev/isxander/yacl/test/ModMenuIntegration.java deleted file mode 100644 index 596a0bf..0000000 --- a/src/testmod/java/dev/isxander/yacl/test/ModMenuIntegration.java +++ /dev/null @@ -1,437 +0,0 @@ -package dev.isxander.yacl.test; - -import com.terraformersmc.modmenu.api.ConfigScreenFactory; -import com.terraformersmc.modmenu.api.ModMenuApi; -import dev.isxander.yacl.api.*; -import dev.isxander.yacl.gui.RequireRestartScreen; -import dev.isxander.yacl.gui.controllers.*; -import dev.isxander.yacl.gui.controllers.cycling.EnumController; -import dev.isxander.yacl.gui.controllers.slider.DoubleSliderController; -import dev.isxander.yacl.gui.controllers.slider.FloatSliderController; -import dev.isxander.yacl.gui.controllers.slider.IntegerSliderController; -import dev.isxander.yacl.gui.controllers.slider.LongSliderController; -import dev.isxander.yacl.gui.controllers.string.StringController; -import dev.isxander.yacl.test.config.ConfigData; -import dev.isxander.yacl.test.config.Entrypoint; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.option.GraphicsMode; -import net.minecraft.client.toast.SystemToast; -import net.minecraft.text.ClickEvent; -import net.minecraft.text.HoverEvent; -import net.minecraft.text.Text; - -import java.awt.*; - -public class ModMenuIntegration implements ModMenuApi { - @Override - public ConfigScreenFactory getModConfigScreenFactory() { - return (parent) -> Entrypoint.getConfig().buildConfig((config, builder) -> builder - .title(Text.of("Test Suites")) - .category(ConfigCategory.createBuilder() - .name(Text.of("Suites")) - .option(ButtonOption.createBuilder() - .name(Text.of("Full Test Suite")) - .controller(ActionController::new) - .action((screen, opt) -> MinecraftClient.getInstance().setScreen(getFullTestSuite(screen))) - .build()) - .option(ButtonOption.createBuilder() - .name(Text.of("Basic Wiki Suite")) - .controller(ActionController::new) - .action((screen, opt) -> MinecraftClient.getInstance().setScreen(getWikiBasic(screen))) - .build()) - .option(ButtonOption.createBuilder() - .name(Text.of("Group Wiki Suite")) - .controller(ActionController::new) - .action((screen, opt) -> MinecraftClient.getInstance().setScreen(getWikiGroups(screen))) - .build()) - .option(ButtonOption.createBuilder() - .name(Text.of("Unavailable Test Suite")) - .controller(ActionController::new) - .action((screen, opt) -> MinecraftClient.getInstance().setScreen(getDisabledTest(screen))) - .build()) - .build()) - ) - .generateScreen(parent); - } - - private Screen getFullTestSuite(Screen parent) { - return Entrypoint.getConfig().buildConfig((config, builder) -> builder - .title(Text.of("Test GUI")) - .category(ConfigCategory.createBuilder() - .name(Text.of("Control Examples")) - .tooltip(Text.of("Example Category Description")) - .group(OptionGroup.createBuilder() - .name(Text.of("Boolean Controllers")) - .tooltip(Text.of("Test!")) - .collapsed(true) - .option(Option.createBuilder(boolean.class) - .name(Text.of("Boolean Toggle")) - .tooltip(value -> Text.of("A simple toggle button that contains the value '" + value + "'")) - .binding( - config.getDefaults().booleanToggle, - () -> config.getConfig().booleanToggle, - (value) -> config.getConfig().booleanToggle = value - ) - .controller(BooleanController::new) - .flag(OptionFlag.GAME_RESTART) - .available(false) - .build()) - .option(Option.createBuilder(boolean.class) - .name(Text.of("Custom Boolean Toggle")) - .tooltip(Text.of("You can customize these controllers like this!")) - .binding( - config.getDefaults().customBooleanToggle, - () -> config.getConfig().customBooleanToggle, - (value) -> config.getConfig().customBooleanToggle = value - ) - .controller(opt -> new BooleanController(opt, state -> state ? Text.of("Amazing") : Text.of("Not Amazing"), true)) - .build()) - .option(Option.createBuilder(boolean.class) - .name(Text.of("Tick Box")) - .tooltip(Text.of("There are even alternate methods of displaying the same data type!")) - .binding( - config.getDefaults().tickbox, - () -> config.getConfig().tickbox, - (value) -> config.getConfig().tickbox = value - ) - .controller(TickBoxController::new) - .build()) - .build()) - .group(OptionGroup.createBuilder() - .name(Text.of("Slider Controllers")) - .option(Option.createBuilder(int.class) - .name(Text.of("Int Slider that is cut off because the slider")) - .instant(true) - .binding( - config.getDefaults().intSlider, - () -> config.getConfig().intSlider, - value -> config.getConfig().intSlider = value - - ) - .controller(opt -> new IntegerSliderController(opt, 0, 3, 1)) - .build()) - .option(Option.createBuilder(double.class) - .name(Text.of("Double Slider")) - .binding( - config.getDefaults().doubleSlider, - () -> config.getConfig().doubleSlider, - (value) -> config.getConfig().doubleSlider = value - ) - .controller(opt -> new DoubleSliderController(opt, 0, 3, 0.05)) - .build()) - .option(Option.createBuilder(float.class) - .name(Text.of("Float Slider")) - .binding( - config.getDefaults().floatSlider, - () -> config.getConfig().floatSlider, - (value) -> config.getConfig().floatSlider = value - ) - .controller(opt -> new FloatSliderController(opt, 0, 3, 0.1f)) - .build()) - .option(Option.createBuilder(long.class) - .name(Text.of("Long Slider")) - .binding( - config.getDefaults().longSlider, - () -> config.getConfig().longSlider, - (value) -> config.getConfig().longSlider = value - ) - .controller(opt -> new LongSliderController(opt, 0, 1_000_000, 100)) - .build()) - .build()) - .group(OptionGroup.createBuilder() - .name(Text.of("Input Field Controllers")) - .option(Option.createBuilder(String.class) - .name(Text.of("Text Option")) - .binding( - config.getDefaults().textField, - () -> config.getConfig().textField, - value -> config.getConfig().textField = value - ) - .controller(StringController::new) - .build()) - .option(Option.createBuilder(Color.class) - .name(Text.of("Color Option")) - .binding( - config.getDefaults().colorOption, - () -> config.getConfig().colorOption, - value -> config.getConfig().colorOption = value - ) - .controller(ColorController::new) - .build()) - .build()) - .group(OptionGroup.createBuilder() - .name(Text.of("Enum Controllers")) - .option(Option.createBuilder(ConfigData.Alphabet.class) - .name(Text.of("Enum Cycler")) - .binding( - config.getDefaults().enumOption, - () -> config.getConfig().enumOption, - (value) -> config.getConfig().enumOption = value - ) - .controller(EnumController::new) - .build()) - .build()) - .group(OptionGroup.createBuilder() - .name(Text.of("Options that aren't really options")) - .option(ButtonOption.createBuilder() - .name(Text.of("Button \"Option\"")) - .action((screen, opt) -> SystemToast.add(MinecraftClient.getInstance().getToastManager(), SystemToast.Type.TUTORIAL_HINT, Text.of("Button Pressed"), Text.of("Button option was invoked!"))) - .controller(ActionController::new) - .build()) - .option(Option.createBuilder(Text.class) - .binding(Binding.immutable(Text.empty() - .append(Text.literal("a").styled(style -> style.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.of("a"))))) - .append(Text.literal("b").styled(style -> style.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.of("b"))))) - .append(Text.literal("c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c").styled(style -> style.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.of("c"))))) - .append(Text.literal("e").styled(style -> style.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.of("e"))))) - .styled(style -> style.withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://isxander.dev"))) - )) - .controller(LabelController::new) - .build()) - .build()) - .group(OptionGroup.createBuilder() - .name(Text.of("Minecraft Bindings")) - .tooltip(Text.of("YACL can also bind Minecraft options!")) - .option(Option.createBuilder(boolean.class) - .name(Text.of("Minecraft AutoJump")) - .tooltip(Text.of("You can even bind minecraft options!")) - .binding(Binding.minecraft(MinecraftClient.getInstance().options.getAutoJump())) - .controller(TickBoxController::new) - .build()) - .option(Option.createBuilder(GraphicsMode.class) - .name(Text.of("Minecraft Graphics Mode")) - .binding(Binding.minecraft(MinecraftClient.getInstance().options.getGraphicsMode())) - .controller(EnumController::new) - .build()) - .build()) - .build()) - .category(PlaceholderCategory.createBuilder() - .name(Text.of("Placeholder Category")) - .screen((client, yaclScreen) -> new RequireRestartScreen(yaclScreen)) - .build()) - .category(ConfigCategory.createBuilder() - .name(Text.of("Group Test")) - .option(Option.createBuilder(boolean.class) - .name(Text.of("Root Test")) - .binding( - config.getDefaults().groupTestRoot, - () -> config.getConfig().groupTestRoot, - value -> config.getConfig().groupTestRoot = value - ) - .controller(TickBoxController::new) - .build()) - .group(OptionGroup.createBuilder() - .name(Text.of("First Group")) - .option(Option.createBuilder(boolean.class) - .name(Text.of("First Group Test 1")) - .binding( - config.getDefaults().groupTestFirstGroup, - () -> config.getConfig().groupTestFirstGroup, - value -> config.getConfig().groupTestFirstGroup = value - ) - .controller(TickBoxController::new) - .build()) - .option(Option.createBuilder(boolean.class) - .name(Text.of("First Group Test 2")) - .binding( - config.getDefaults().groupTestFirstGroup2, - () -> config.getConfig().groupTestFirstGroup2, - value -> config.getConfig().groupTestFirstGroup2 = value - ) - .controller(TickBoxController::new) - .build()) - .build()) - .group(OptionGroup.createBuilder() - .name(Text.empty()) - .option(Option.createBuilder(boolean.class) - .name(Text.of("Second Group Test")) - .binding( - config.getDefaults().groupTestSecondGroup, - () -> config.getConfig().groupTestSecondGroup, - value -> config.getConfig().groupTestSecondGroup = value - ) - .controller(TickBoxController::new) - .build()) - .build()) - .build()) - .category(ConfigCategory.createBuilder() - .name(Text.of("Scroll Test")) - .option(Option.createBuilder(int.class) - .name(Text.of("Int Slider that is cut off because the slider")) - .binding( - config.getDefaults().scrollingSlider, - () -> config.getConfig().scrollingSlider, - (value) -> config.getConfig().scrollingSlider = value - ) - .controller(opt -> new IntegerSliderController(opt, 0, 10, 1)) - .build()) - .option(ButtonOption.createBuilder() - .name(Text.of("Option")) - .action((screen, opt) -> {}) - .controller(ActionController::new) - .build()) - .option(ButtonOption.createBuilder() - .name(Text.of("Option")) - .action((screen, opt) -> {}) - .controller(ActionController::new) - .build()) - .option(ButtonOption.createBuilder() - .name(Text.of("Option")) - .action((screen, opt) -> {}) - .controller(ActionController::new) - .build()) - .option(ButtonOption.createBuilder() - .name(Text.of("Option")) - .action((screen, opt) -> {}) - .controller(ActionController::new) - .build()) - .option(ButtonOption.createBuilder() - .name(Text.of("Option")) - .action((screen, opt) -> {}) - .controller(ActionController::new) - .build()) - .option(ButtonOption.createBuilder() - .name(Text.of("Option")) - .action((screen, opt) -> {}) - .controller(ActionController::new) - .build()) - .option(ButtonOption.createBuilder() - .name(Text.of("Option")) - .action((screen, opt) -> {}) - .controller(ActionController::new) - .build()) - .option(ButtonOption.createBuilder() - .name(Text.of("Option")) - .action((screen, opt) -> {}) - .controller(ActionController::new) - .build()) - .option(ButtonOption.createBuilder() - .name(Text.of("Option")) - .action((screen, opt) -> {}) - .controller(ActionController::new) - .build()) - .option(ButtonOption.createBuilder() - .name(Text.of("Option")) - .action((screen, opt) -> {}) - .controller(ActionController::new) - .build()) - .option(ButtonOption.createBuilder() - .name(Text.of("Option")) - .action((screen, opt) -> {}) - .controller(ActionController::new) - .build()) - .option(ButtonOption.createBuilder() - .name(Text.of("Option")) - .action((screen, opt) -> {}) - .controller(ActionController::new) - .build()) - .option(ButtonOption.createBuilder() - .name(Text.of("Option")) - .action((screen, opt) -> {}) - .controller(ActionController::new) - .build()) - .build()) - .save(() -> { - MinecraftClient.getInstance().options.write(); - config.save(); - }) - ) - .generateScreen(parent); - } - - private Screen getDisabledTest(Screen parent) { - return Entrypoint.getConfig().buildConfig((config, builder) -> builder - .title(Text.empty()) - .category(ConfigCategory.createBuilder() - .name(Text.of("Disabled Test")) - .option(Option.createBuilder(int.class) - .name(Text.of("Slider")) - .binding(Binding.immutable(0)) - .controller(opt -> new IntegerSliderController(opt, 0, 5, 1)) - .available(false) - .build()) - .option(Option.createBuilder(boolean.class) - .name(Text.of("Tick Box")) - .binding(Binding.immutable(true)) - .controller(TickBoxController::new) - .available(false) - .build()) - .option(Option.createBuilder(boolean.class) - .name(Text.of("Tick Box (Enabled)")) - .binding(Binding.immutable(true)) - .controller(TickBoxController::new) - .build()) - .option(Option.createBuilder(String.class) - .name(Text.of("Text Field")) - .binding(Binding.immutable("hi")) - .controller(StringController::new) - .available(false) - .build()) - .build()) - ) - .generateScreen(parent); - } - - private Screen getWikiBasic(Screen parent) { - return Entrypoint.getConfig().buildConfig((config, builder) -> builder - .title(Text.of("Mod Name")) - .category(ConfigCategory.createBuilder() - .name(Text.of("My Category")) - .tooltip(Text.of("This displays when you hover over a category button")) // optional - .option(Option.createBuilder(boolean.class) - .name(Text.of("My Boolean Option")) - .tooltip(Text.of("This option displays the basic capabilities of YetAnotherConfigLib")) // optional - .binding( - config.getDefaults().booleanToggle, // default - () -> config.getConfig().booleanToggle, // getter - newValue -> config.getConfig().booleanToggle = newValue // setter - ) - .controller(BooleanController::new) - .build()) - .build()) - ) - .generateScreen(parent); - } - - private Screen getWikiGroups(Screen parent) { - return Entrypoint.getConfig().buildConfig((config, builder) -> builder - .title(Text.of("Mod Name")) - .category(ConfigCategory.createBuilder() - .name(Text.of("My Category")) - .tooltip(Text.of("This displays when you hover over a category button")) // optional - .group(OptionGroup.createBuilder() - .name(Text.of("Option Group")) - .option(Option.createBuilder(boolean.class) - .name(Text.of("My Boolean Option")) - .tooltip(Text.of("This option displays the basic capabilities of YetAnotherConfigLib")) // optional - .binding( - config.getDefaults().booleanToggle, // default - () -> config.getConfig().booleanToggle, // getter - newValue -> config.getConfig().booleanToggle = newValue // setter - ) - .controller(BooleanController::new) - .build()) - .build()) - .build()) - ) - .generateScreen(parent); - } - - private ConfigScreenFactory getWikiButton() { - return (parent) -> Entrypoint.getConfig().buildConfig((config, builder) -> builder - .title(Text.of("Mod Name")) - .category(ConfigCategory.createBuilder() - .name(Text.of("My Category")) - .tooltip(Text.of("This displays when you hover over a category button")) // optional - .option(ButtonOption.createBuilder() - .name(Text.of("Pressable Button")) - .tooltip(Text.of("This is so easy!")) // optional - .action(screen -> {}) - .controller(ActionController::new) - .build()) - .build()) - ) - .generateScreen(parent); - } -} diff --git a/src/testmod/java/dev/isxander/yacl/test/mixins/TitleScreenMixin.java b/src/testmod/java/dev/isxander/yacl/test/mixins/TitleScreenMixin.java new file mode 100644 index 0000000..b32a392 --- /dev/null +++ b/src/testmod/java/dev/isxander/yacl/test/mixins/TitleScreenMixin.java @@ -0,0 +1,26 @@ +package dev.isxander.yacl.test.mixins; + +import dev.isxander.yacl.test.GuiTest; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.TitleScreen; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.text.Text; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(TitleScreen.class) +public abstract class TitleScreenMixin extends Screen { + protected TitleScreenMixin(Text title) { + super(title); + } + + @Inject(method = "init", at = @At("RETURN")) + private void injectTestButton(CallbackInfo ci) { + addDrawableChild(ButtonWidget.createBuilder(Text.of("YACL"), button -> client.setScreen(GuiTest.getModConfigScreenFactory(client.currentScreen))) + .setPosition(0, 0) + .setWidth(50) + .build()); + } +} diff --git a/src/testmod/resources/fabric.mod.json b/src/testmod/resources/fabric.mod.json index 1360a5e..5fe0919 100644 --- a/src/testmod/resources/fabric.mod.json +++ b/src/testmod/resources/fabric.mod.json @@ -11,15 +11,12 @@ "entrypoints": { "client": [ "dev.isxander.yacl.test.config.Entrypoint" - ], - "modmenu": [ - "dev.isxander.yacl.test.ModMenuIntegration" ] }, "depends": { - "fabricloader": ">=0.14.0", - "minecraft": "1.19.x", - "java": ">=17", - "fabric-resource-loader-v0": "*" - } + "yet-another-config-lib": "*" + }, + "mixins": [ + "yet-another-config-lib.test.mixins.json" + ] } diff --git a/src/testmod/resources/yet-another-config-lib.test.mixins.json b/src/testmod/resources/yet-another-config-lib.test.mixins.json new file mode 100644 index 0000000..9287cdd --- /dev/null +++ b/src/testmod/resources/yet-another-config-lib.test.mixins.json @@ -0,0 +1,11 @@ +{ + "required": true, + "package": "dev.isxander.yacl.test.mixins", + "compatibilityLevel": "JAVA_17", + "injectors": { + "defaultRequire": 1 + }, + "client": [ + "TitleScreenMixin" + ] +} -- cgit