diff options
Diffstat (limited to 'src')
9 files changed, 607 insertions, 417 deletions
diff --git a/src/main/java/dev/isxander/yacl/config/ConfigInstance.java b/src/main/java/dev/isxander/yacl/config/ConfigInstance.java new file mode 100644 index 0000000..e85a645 --- /dev/null +++ b/src/main/java/dev/isxander/yacl/config/ConfigInstance.java @@ -0,0 +1,48 @@ +package dev.isxander.yacl.config; + +import dev.isxander.yacl.api.YetAnotherConfigLib; + +import java.lang.reflect.InvocationTargetException; +import java.util.function.BiFunction; + +public abstract class ConfigInstance<T> { + private final Class<T> configClass; + private final T defaultInstance; + private T instance; + + public ConfigInstance(Class<T> configClass) { + this.configClass = configClass; + + try { + this.defaultInstance = this.instance = configClass.getConstructor().newInstance(); + } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) { + throw new IllegalStateException(String.format("Could not create default instance of config for %s. Make sure there is a default constructor!", this.configClass.getSimpleName())); + } + + } + + public T getConfig() { + return this.instance; + } + + protected void setConfig(T instance) { + this.instance = instance; + } + + public T getDefaults() { + return this.defaultInstance; + } + + public Class<T> getConfigClass() { + return this.configClass; + } + + public YetAnotherConfigLib buildConfig(BiFunction<ConfigInstance<T>, YetAnotherConfigLib.Builder, YetAnotherConfigLib.Builder> builder) { + return builder.apply(this, YetAnotherConfigLib.createBuilder()) + .save(this::save) + .build(); + } + + public abstract void save(); + public abstract void load(); +} diff --git a/src/main/java/dev/isxander/yacl/config/GsonConfigInstance.java b/src/main/java/dev/isxander/yacl/config/GsonConfigInstance.java new file mode 100644 index 0000000..732492d --- /dev/null +++ b/src/main/java/dev/isxander/yacl/config/GsonConfigInstance.java @@ -0,0 +1,82 @@ +package dev.isxander.yacl.config; + +import com.google.gson.*; +import dev.isxander.yacl.impl.utils.YaclConstants; +import net.minecraft.text.Style; +import net.minecraft.text.Text; + +import java.awt.*; +import java.io.IOException; +import java.lang.reflect.Modifier; +import java.lang.reflect.Type; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.util.function.UnaryOperator; + +public class GsonConfigInstance<T> extends ConfigInstance<T> { + private final Gson gson; + private final Path path; + + public GsonConfigInstance(Class<T> configClass, Path path, Gson gson) { + this(configClass, path, gson.newBuilder()); + } + + public GsonConfigInstance(Class<T> configClass, Path path, UnaryOperator<GsonBuilder> builder) { + this(configClass, path, builder.apply(new GsonBuilder())); + } + + public GsonConfigInstance(Class<T> configClass, Path path, GsonBuilder builder) { + super(configClass); + this.path = path; + this.gson = builder + .excludeFieldsWithModifiers(Modifier.TRANSIENT) + .registerTypeHierarchyAdapter(Text.class, new Text.Serializer()) + .registerTypeHierarchyAdapter(Style.class, new Style.Serializer()) + .registerTypeHierarchyAdapter(Color.class, new ColorTypeAdapter()) + .serializeNulls() + .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) + .create(); + } + + @Override + public void save() { + try { + YaclConstants.LOGGER.info("Saving {}...", getConfigClass().getSimpleName()); + Files.writeString(path, gson.toJson(getConfig()), StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void load() { + try { + if (Files.notExists(path)) { + save(); + return; + } + + YaclConstants.LOGGER.info("Loading {}...", getConfigClass().getSimpleName()); + setConfig(gson.fromJson(Files.readString(path), getConfigClass())); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public Path getPath() { + return this.path; + } + + public static class ColorTypeAdapter implements JsonSerializer<Color>, JsonDeserializer<Color> { + @Override + public Color deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { + return new Color(jsonElement.getAsInt(), true); + } + + @Override + public JsonElement serialize(Color color, Type type, JsonSerializationContext jsonSerializationContext) { + return new JsonPrimitive(color.getRGB()); + } + } +} diff --git a/src/main/java/dev/isxander/yacl/config/YACLConfigManager.java b/src/main/java/dev/isxander/yacl/config/YACLConfigManager.java new file mode 100644 index 0000000..d91f3f6 --- /dev/null +++ b/src/main/java/dev/isxander/yacl/config/YACLConfigManager.java @@ -0,0 +1,26 @@ +package dev.isxander.yacl.config; + +import java.util.HashMap; +import java.util.Map; + +@SuppressWarnings("unchecked") +public class YACLConfigManager { + private static final Map<Class<?>, ConfigInstance<?>> configs = new HashMap<>(); + + public static <T> void register(ConfigInstance<T> configInstance) { + configs.put(configInstance.getConfigClass(), configInstance); + configInstance.load(); + } + + public static <T> T getConfigData(Class<T> configClass) { + return ((ConfigInstance<T>) configs.get(configClass)).getConfig(); + } + + public static <T> ConfigInstance<T> getConfigInstance(Class<T> configClass) { + return (ConfigInstance<T>) configs.get(configClass); + } + + public static <T, I extends ConfigInstance<T>> I getConfigInstanceType(Class<T> configClass) { + return (I) configs.get(configClass); + } +} diff --git a/src/main/java/dev/isxander/yacl/impl/YetAnotherConfigLibImpl.java b/src/main/java/dev/isxander/yacl/impl/YetAnotherConfigLibImpl.java index 7e2afdb..38112f4 100644 --- a/src/main/java/dev/isxander/yacl/impl/YetAnotherConfigLibImpl.java +++ b/src/main/java/dev/isxander/yacl/impl/YetAnotherConfigLibImpl.java @@ -4,6 +4,7 @@ import com.google.common.collect.ImmutableList; import dev.isxander.yacl.api.ConfigCategory; import dev.isxander.yacl.api.YetAnotherConfigLib; import dev.isxander.yacl.gui.YACLScreen; +import dev.isxander.yacl.impl.utils.YaclConstants; import net.minecraft.client.gui.screen.Screen; import net.minecraft.text.Text; @@ -12,6 +13,7 @@ import java.util.function.Consumer; public record YetAnotherConfigLibImpl(Text title, ImmutableList<ConfigCategory> categories, Runnable saveFunction, Consumer<YACLScreen> initConsumer) implements YetAnotherConfigLib { @Override public Screen generateScreen(Screen parent) { + YaclConstants.LOGGER.info("Generating YACL screen"); return new YACLScreen(this, parent); } } diff --git a/src/main/java/dev/isxander/yacl/impl/utils/YaclConstants.java b/src/main/java/dev/isxander/yacl/impl/utils/YaclConstants.java new file mode 100644 index 0000000..aadeb18 --- /dev/null +++ b/src/main/java/dev/isxander/yacl/impl/utils/YaclConstants.java @@ -0,0 +1,8 @@ +package dev.isxander.yacl.impl.utils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class YaclConstants { + public static final Logger LOGGER = LoggerFactory.getLogger("YetAnotherConfigLib"); +} diff --git a/src/testmod/java/dev/isxander/yacl/test/ModMenuIntegration.java b/src/testmod/java/dev/isxander/yacl/test/ModMenuIntegration.java index d1bd2c5..596a0bf 100644 --- a/src/testmod/java/dev/isxander/yacl/test/ModMenuIntegration.java +++ b/src/testmod/java/dev/isxander/yacl/test/ModMenuIntegration.java @@ -5,13 +5,15 @@ 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.MessageScreen; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.option.GraphicsMode; import net.minecraft.client.toast.SystemToast; @@ -24,439 +26,412 @@ import java.awt.*; public class ModMenuIntegration implements ModMenuApi { @Override public ConfigScreenFactory<?> getModConfigScreenFactory() { - return (parent) -> YetAnotherConfigLib.createBuilder() - .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 -> MinecraftClient.getInstance().setScreen(getFullTestSuite(screen))) - .build()) - .option(ButtonOption.createBuilder() - .name(Text.of("Basic Wiki Suite")) - .controller(ActionController::new) - .action(screen -> MinecraftClient.getInstance().setScreen(getWikiBasic(screen))) - .build()) - .option(ButtonOption.createBuilder() - .name(Text.of("Group Wiki Suite")) - .controller(ActionController::new) - .action(screen -> MinecraftClient.getInstance().setScreen(getWikiGroups(screen))) - .build()) - .option(ButtonOption.createBuilder() - .name(Text.of("Unavailable Test Suite")) - .controller(ActionController::new) - .action(screen -> MinecraftClient.getInstance().setScreen(getDisabledTest(screen))) - .build()) - .build()) - .build().generateScreen(parent); + 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 YetAnotherConfigLib.createBuilder() - .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( - false, - () -> TestSettings.booleanToggle, - (value) -> TestSettings.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( - false, - () -> TestSettings.customBooleanToggle, - (value) -> TestSettings.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( - false, - () -> TestSettings.tickbox, - (value) -> TestSettings.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( - 0, - () -> TestSettings.intSlider, - (value) -> { - TestSettings.intSlider = value; - System.out.println("Set int value!"); - } - ) - .controller(opt -> new IntegerSliderController(opt, 0, 3, 1)) - .build()) - .option(Option.createBuilder(double.class) - .name(Text.of("Double Slider")) - .binding( - 0.0, - () -> TestSettings.doubleSlider, - (value) -> TestSettings.doubleSlider = value - ) - .controller(opt -> new DoubleSliderController(opt, 0, 3, 0.05)) - .build()) - .option(Option.createBuilder(float.class) - .name(Text.of("Float Slider")) - .binding( - 0f, - () -> TestSettings.floatSlider, - (value) -> TestSettings.floatSlider = value - ) - .controller(opt -> new FloatSliderController(opt, 0, 3, 0.1f)) - .build()) - .option(Option.createBuilder(long.class) - .name(Text.of("Long Slider")) - .binding( - 0L, - () -> TestSettings.longSlider, - (value) -> TestSettings.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( - "Hello", - () -> TestSettings.textField, - value -> TestSettings.textField = value - ) - .controller(StringController::new) - .build()) - .option(Option.createBuilder(Color.class) - .name(Text.of("Color Option")) - .binding( - Color.red, - () -> TestSettings.colorOption, - value -> TestSettings.colorOption = value - ) - .controller(ColorController::new) - .build()) - .build()) - .group(OptionGroup.createBuilder() - .name(Text.of("Enum Controllers")) - .option(Option.createBuilder(TestSettings.Alphabet.class) - .name(Text.of("Enum Cycler")) - .binding( - TestSettings.Alphabet.A, - () -> TestSettings.enumOption, - (value) -> TestSettings.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 -> 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( - false, - () -> TestSettings.groupTestRoot, - value -> TestSettings.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( - false, - () -> TestSettings.groupTestFirstGroup, - value -> TestSettings.groupTestFirstGroup = value - ) - .controller(TickBoxController::new) - .build()) - .option(Option.createBuilder(boolean.class) - .name(Text.of("First Group Test 2")) - .binding( - false, - () -> TestSettings.groupTestFirstGroup2, - value -> TestSettings.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( - false, - () -> TestSettings.groupTestSecondGroup, - value -> TestSettings.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( - 0, - () -> TestSettings.scrollingSlider, - (value) -> TestSettings.scrollingSlider = value - ) - .controller(opt -> new IntegerSliderController(opt, 0, 10, 1)) - .build()) - .option(ButtonOption.createBuilder() - .name(Text.of("Option")) - .action(screen -> {}) - .controller(ActionController::new) - .build()) - .option(ButtonOption.createBuilder() - .name(Text.of("Option")) - .action(screen -> {}) - .controller(ActionController::new) - .build()) - .option(ButtonOption.createBuilder() - .name(Text.of("Option")) - .action(screen -> {}) - .controller(ActionController::new) - .build()) - .option(ButtonOption.createBuilder() - .name(Text.of("Option")) - .action(screen -> {}) - .controller(ActionController::new) - .build()) - .option(ButtonOption.createBuilder() - .name(Text.of("Option")) - .action(screen -> {}) - .controller(ActionController::new) - .build()) - .option(ButtonOption.createBuilder() - .name(Text.of("Option")) - .action(screen -> {}) - .controller(ActionController::new) - .build()) - .option(ButtonOption.createBuilder() - .name(Text.of("Option")) - .action(screen -> {}) - .controller(ActionController::new) - .build()) - .option(ButtonOption.createBuilder() - .name(Text.of("Option")) - .action(screen -> {}) - .controller(ActionController::new) - .build()) - .option(ButtonOption.createBuilder() - .name(Text.of("Option")) - .action(screen -> {}) - .controller(ActionController::new) - .build()) - .option(ButtonOption.createBuilder() - .name(Text.of("Option")) - .action(screen -> {}) - .controller(ActionController::new) - .build()) - .option(ButtonOption.createBuilder() - .name(Text.of("Option")) - .action(screen -> {}) - .controller(ActionController::new) - .build()) - .option(ButtonOption.createBuilder() - .name(Text.of("Option")) - .action(screen -> {}) - .controller(ActionController::new) - .build()) - .option(ButtonOption.createBuilder() - .name(Text.of("Option")) - .action(screen -> {}) - .controller(ActionController::new) - .build()) - .build()) - .save(() -> MinecraftClient.getInstance().options.write()) - .build().generateScreen(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 YetAnotherConfigLib.createBuilder() - .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()) - .build().generateScreen(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 YetAnotherConfigLib.createBuilder() - .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( - true, // default - () -> TestSettings.booleanToggle, // getter - newValue -> TestSettings.booleanToggle = newValue // setter - ) - .controller(BooleanController::new) - .build()) - .build()) - .save(TestSettings::save) - .build() + 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 YetAnotherConfigLib.createBuilder() - .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( - true, // default - () -> TestSettings.booleanToggle, // getter - newValue -> TestSettings.booleanToggle = newValue // setter - ) - .controller(BooleanController::new) - .build()) - .build()) - .build()) - .save(TestSettings::save) - .build() + 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) -> YetAnotherConfigLib.createBuilder() - .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()) - .save(TestSettings::save) - .build() + 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); } - - private static class TestSettings { - private static boolean booleanToggle = false; - private static boolean customBooleanToggle = false; - private static boolean tickbox = false; - private static int intSlider = 0; - private static double doubleSlider = 0; - private static float floatSlider = 0; - private static long longSlider = 0; - private static String textField = "Hello"; - private static Color colorOption = Color.red; - private static Alphabet enumOption = Alphabet.A; - - private static boolean groupTestRoot = false; - private static boolean groupTestFirstGroup = false; - private static boolean groupTestFirstGroup2 = false; - private static boolean groupTestSecondGroup = false; - - private static int scrollingSlider = 0; - - public enum Alphabet { - A, B, C - } - - public static void save() { - - } - } } diff --git a/src/testmod/java/dev/isxander/yacl/test/config/ConfigData.java b/src/testmod/java/dev/isxander/yacl/test/config/ConfigData.java new file mode 100644 index 0000000..d0d47b1 --- /dev/null +++ b/src/testmod/java/dev/isxander/yacl/test/config/ConfigData.java @@ -0,0 +1,27 @@ +package dev.isxander.yacl.test.config; + +import java.awt.*; + +public class ConfigData { + public boolean booleanToggle = false; + public boolean customBooleanToggle = false; + public boolean tickbox = false; + public int intSlider = 0; + public double doubleSlider = 0; + public float floatSlider = 0; + public long longSlider = 0; + public String textField = "Hello"; + public Color colorOption = Color.red; + public Alphabet enumOption = Alphabet.A; + + public boolean groupTestRoot = false; + public boolean groupTestFirstGroup = false; + public boolean groupTestFirstGroup2 = false; + public boolean groupTestSecondGroup = false; + + public int scrollingSlider = 0; + + public enum Alphabet { + A, B, C + } +} diff --git a/src/testmod/java/dev/isxander/yacl/test/config/Entrypoint.java b/src/testmod/java/dev/isxander/yacl/test/config/Entrypoint.java new file mode 100644 index 0000000..7875700 --- /dev/null +++ b/src/testmod/java/dev/isxander/yacl/test/config/Entrypoint.java @@ -0,0 +1,19 @@ +package dev.isxander.yacl.test.config; + +import com.google.gson.Gson; +import dev.isxander.yacl.config.ConfigInstance; +import dev.isxander.yacl.config.GsonConfigInstance; +import dev.isxander.yacl.config.YACLConfigManager; +import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.loader.api.FabricLoader; + +public class Entrypoint implements ClientModInitializer { + @Override + public void onInitializeClient() { + YACLConfigManager.register(new GsonConfigInstance<>(ConfigData.class, FabricLoader.getInstance().getConfigDir().resolve("yacl-test.json"), new Gson())); + } + + public static ConfigInstance<ConfigData> getConfig() { + return YACLConfigManager.getConfigInstance(ConfigData.class); + } +} diff --git a/src/testmod/resources/fabric.mod.json b/src/testmod/resources/fabric.mod.json index 333adc3..1360a5e 100644 --- a/src/testmod/resources/fabric.mod.json +++ b/src/testmod/resources/fabric.mod.json @@ -9,6 +9,9 @@ "license": "LGPL-3.0-or-later", "environment": "client", "entrypoints": { + "client": [ + "dev.isxander.yacl.test.config.Entrypoint" + ], "modmenu": [ "dev.isxander.yacl.test.ModMenuIntegration" ] |