diff --git a/docs/libjf-config-v0.md b/docs/libjf-config-v0.md index 45c9a78..94ff8ea 100644 --- a/docs/libjf-config-v0.md +++ b/docs/libjf-config-v0.md @@ -31,8 +31,40 @@ To register a config, add a `libjf:config` entrypoint pointing to its class to y To manually register a config or save changes, use `io.gitlab.jfronny.libjf.config.api.ConfigHolder` For example, to save a config for a mod titled `yourmod`: ```java -ConfigHolder.getInstance().getRegistered().get("yourmod").write(); +ConfigHolder.getInstance().get("yourmod").write(); ``` LibJF config is only intended for simple config screens, it does not support nested classes, multiple pages or controls like sliders. -Use something else for those \ No newline at end of file +Use something else for those + +## Presets +libjf-config-v0 provides a preset system to automatically fill in certain values based on a function. +To add a snippet, add a public static method to your config class and annotate it with @Preset. +If your preset is selected, the method will be executed. +You may assign a name by using your language file, the format for names is `.jfconfig.` + +Example: +```java +@Preset +public static void moskau() { + disablePacks = true; + disablePacks2 = true; + intTest = -5; + floatTest = -6; + doubleTest = 4; + dieStr = "Moskau"; +} +``` + +## Verifiers +If you need to manually validate config values outside of minimums or maximums, you may add a public static method +and annotate it with @Verifier. This method will be executed whenever your config changes, which might happen often. +Be careful to write performant code here! + +Example: +```java +@Verifier +public static void setIntTestIfDisable() { + if (disablePacks) intTest = 0; +} +``` diff --git a/docs/libjf-devutil-v0.md b/docs/libjf-devutil-v0.md index 2bec2a5..c9f425a 100644 --- a/docs/libjf-devutil-v0.md +++ b/docs/libjf-devutil-v0.md @@ -1,6 +1,7 @@ # libjf-devutil-v0 LibJF devutil is intended to be used as `runtimeOnly`. -It marks the running minecraft instance as a development instance and disables the UserApi (removing that Yggdrasil error message) +It marks the running minecraft instance as a development instance (for example, this removes the need for eula.txt) +and disables the UserApi (removing that Yggdrasil error message) It does not provide any useful functionality to end users It depends on libjf-base \ No newline at end of file diff --git a/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/api/ConfigHolder.java b/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/api/ConfigHolder.java index 81e1803..45d08c8 100644 --- a/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/api/ConfigHolder.java +++ b/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/api/ConfigHolder.java @@ -11,5 +11,7 @@ public interface ConfigHolder { } void register(String modId, Class config); Map getRegistered(); + Config get(Class configClass); + Config get(String configClass); boolean isRegistered(Class config); } diff --git a/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/api/Preset.java b/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/api/Preset.java new file mode 100644 index 0000000..0bc0083 --- /dev/null +++ b/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/api/Preset.java @@ -0,0 +1,11 @@ +package io.gitlab.jfronny.libjf.config.api; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface Preset { +} diff --git a/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/api/Verifier.java b/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/api/Verifier.java new file mode 100644 index 0000000..b60131c --- /dev/null +++ b/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/api/Verifier.java @@ -0,0 +1,11 @@ +package io.gitlab.jfronny.libjf.config.api; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface Verifier { +} diff --git a/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/Config.java b/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/Config.java index 59f564f..d015d8c 100644 --- a/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/Config.java +++ b/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/Config.java @@ -2,20 +2,27 @@ package io.gitlab.jfronny.libjf.config.impl; import io.gitlab.jfronny.libjf.LibJf; import io.gitlab.jfronny.libjf.config.api.Entry; +import io.gitlab.jfronny.libjf.config.api.Preset; +import io.gitlab.jfronny.libjf.config.api.Verifier; import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.util.math.MathHelper; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.nio.file.Files; import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; +import java.util.*; +import java.util.logging.Logger; /** Based on https://github.com/TeamMidnightDust/MidnightLib which is based on https://github.com/Minenash/TinyConfig * Credits to TeamMidnightDust and Minenash */ public class Config { public final List entries = new ArrayList<>(); - public Path path; + public final Map presets = new LinkedHashMap<>(); + public final Set verifiers = new LinkedHashSet<>(); + public final Path path; public final String modid; public final Class configClass; @@ -27,19 +34,106 @@ public class Config { for (Field field : config.getFields()) { EntryInfo info = new EntryInfo(); info.field = field; - if (field.isAnnotationPresent(Entry.class)) + if (field.isAnnotationPresent(Entry.class)) { + info.entry = field.getAnnotation(Entry.class); try { info.defaultValue = field.get(null); } catch (IllegalAccessException ignored) {} + } entries.add(info); } + presets.put("libjf-config-v0.default", () -> { + for (EntryInfo entry : entries) { + try { + entry.field.set(null, entry.defaultValue); + } catch (IllegalAccessException e) { + LibJf.LOGGER.error("Could not reload default values", e); + } + } + }); + for (Method method : config.getMethods()) { + if (method.isAnnotationPresent(Preset.class)) { + presets.put(modid + ".jfconfig." + method.getName(), () -> { + try { + method.invoke(null); + } catch (IllegalAccessException | InvocationTargetException e) { + LibJf.LOGGER.error("Could not apply preset", e); + } + }); + } + else if (method.isAnnotationPresent(Verifier.class)) { + verifiers.add(() -> { + try { + method.invoke(null); + } catch (IllegalAccessException | InvocationTargetException e) { + LibJf.LOGGER.error("Could not run verifier", e); + } + }); + } + } + verifiers.add(() -> { + for (EntryInfo entry : entries) { + Object value; + try { + value = entry.field.get(null); + } catch (IllegalAccessException e) { + LibJf.LOGGER.error("Could not read value", e); + continue; + } + final Object valueOriginal = value; + if (value instanceof final Integer v) { + if (v < entry.entry.min()) value = (int)entry.entry.min(); + if (v > entry.entry.max()) value = (int)entry.entry.max(); + } else if (value instanceof final Float v) { + if (v < entry.entry.min()) value = (float)entry.entry.min(); + if (v > entry.entry.max()) value = (float)entry.entry.max(); + } else if (value instanceof final Double v) { + if (v < entry.entry.min()) value = entry.entry.min(); + if (v > entry.entry.max()) value = entry.entry.max(); + } + if (valueOriginal != value) { + try { + entry.field.set(null, value); + } catch (IllegalAccessException e) { + LibJf.LOGGER.error("Could not write value", e); + } + } + } + }); try { - LibJf.GSON.fromJson(Files.newBufferedReader(path), config); } - catch (Exception e) { write(); } + LibJf.GSON.fromJson(Files.newBufferedReader(path), config); + syncFromClass(); + } + catch (Exception e) { + write(); + } + } + + public void syncToClass() { + for (EntryInfo info : entries) { + try { + info.field.set(null, info.value); + } catch (IllegalAccessException e) { + LibJf.LOGGER.error("Could not write value", e); + } + } + syncFromClass(); + } + + public void syncFromClass() { + for (Runnable verifier : verifiers) { + verifier.run(); + } + for (EntryInfo info : entries) { + try { + info.value = info.field.get(null); + } catch (IllegalAccessException e) { + LibJf.LOGGER.error("Could not read value", e); + } + } } public void write() { - path = FabricLoader.getInstance().getConfigDir().resolve(modid + ".json"); try { if (!Files.exists(path)) Files.createFile(path); Files.write(path, LibJf.GSON.toJson(configClass.getDeclaredConstructor().newInstance()).getBytes()); diff --git a/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/ConfigHolderImpl.java b/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/ConfigHolderImpl.java index ea4c37a..92f129a 100644 --- a/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/ConfigHolderImpl.java +++ b/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/ConfigHolderImpl.java @@ -2,12 +2,14 @@ package io.gitlab.jfronny.libjf.config.impl; import com.google.common.collect.ImmutableMap; import io.gitlab.jfronny.libjf.config.api.ConfigHolder; +import org.jetbrains.annotations.ApiStatus; import java.util.HashMap; import java.util.Map; public class ConfigHolderImpl implements ConfigHolder { - @Deprecated public static final ConfigHolderImpl INSTANCE = new ConfigHolderImpl(); + @ApiStatus.Internal + public static final ConfigHolderImpl INSTANCE = new ConfigHolderImpl(); private ConfigHolderImpl() {} private final Map configs = new HashMap<>(); @@ -22,6 +24,20 @@ public class ConfigHolderImpl implements ConfigHolder { return ImmutableMap.copyOf(configs); } + @Override + public Config get(Class configClass) { + for (Config value : configs.values()) { + if (value.configClass.equals(configClass)) + return value; + } + return null; + } + + @Override + public Config get(String configClass) { + return configs.get(configClass); + } + public boolean isRegistered(Class config) { for (Config value : configs.values()) { if (value.configClass.equals(config)) diff --git a/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/EntryInfo.java b/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/EntryInfo.java index cf07d0c..38c5490 100644 --- a/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/EntryInfo.java +++ b/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/EntryInfo.java @@ -1,5 +1,6 @@ package io.gitlab.jfronny.libjf.config.impl; +import io.gitlab.jfronny.libjf.config.api.Entry; import net.minecraft.client.gui.widget.TextFieldWidget; import net.minecraft.text.Text; @@ -15,4 +16,5 @@ public class EntryInfo { public Object value; public String tempValue; public boolean inLimits = true; + public Entry entry; } diff --git a/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/gui/ButtonEntry.java b/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/gui/ConfigScreenEntry.java similarity index 86% rename from libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/gui/ButtonEntry.java rename to libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/gui/ConfigScreenEntry.java index ed78f8b..1eb7547 100644 --- a/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/gui/ButtonEntry.java +++ b/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/gui/ConfigScreenEntry.java @@ -18,7 +18,7 @@ import java.util.List; import java.util.Map; @Environment(EnvType.CLIENT) -public class ButtonEntry extends ElementListWidget.Entry { +public class ConfigScreenEntry extends ElementListWidget.Entry { private static final TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; public final List buttons = new ArrayList<>(); private final List resetButtons = new ArrayList<>(); @@ -26,7 +26,7 @@ public class ButtonEntry extends ElementListWidget.Entry { private final List buttonsWithResetButtons = new ArrayList<>(); public static final Map buttonsWithText = new HashMap<>(); - private ButtonEntry(ClickableWidget button, Text text, ClickableWidget resetButton) { + private ConfigScreenEntry(ClickableWidget button, Text text, ClickableWidget resetButton) { buttonsWithText.put(button,text); this.buttons.add(button); this.resetButtons.add(resetButton); @@ -34,8 +34,8 @@ public class ButtonEntry extends ElementListWidget.Entry { this.buttonsWithResetButtons.add(button); this.buttonsWithResetButtons.add(resetButton); } - public static ButtonEntry create(ClickableWidget button, Text text, ClickableWidget resetButton) { - return new ButtonEntry(button, text, resetButton); + public static ConfigScreenEntry create(ClickableWidget button, Text text, ClickableWidget resetButton) { + return new ConfigScreenEntry(button, text, resetButton); } public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { this.buttons.forEach((button) -> { diff --git a/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/gui/EntryInfoWidgetBuilder.java b/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/gui/EntryInfoWidgetBuilder.java index a41ed2f..fb7f8cb 100644 --- a/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/gui/EntryInfoWidgetBuilder.java +++ b/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/gui/EntryInfoWidgetBuilder.java @@ -39,15 +39,14 @@ public class EntryInfoWidgetBuilder { private static void initEntry(Config config, EntryInfo info) { if (!(info.field.isAnnotationPresent(io.gitlab.jfronny.libjf.config.api.Entry.class) || info.field.isAnnotationPresent(GsonHidden.class))) return; Class type = info.field.getType(); - io.gitlab.jfronny.libjf.config.api.Entry e = info.field.getAnnotation(Entry.class); - info.width = e != null ? e.width() : 0; + info.width = info.entry != null ? info.entry.width() : 0; - if (e == null) return; + if (info.entry == null) return; - if (type == int.class || type == Integer.class) textField(config, info, Integer::parseInt, INTEGER_ONLY, e.min(), e.max(), true); - else if (type == float.class || type == Float.class) textField(config, info, Float::parseFloat, DECIMAL_ONLY, e.min(), e.max(),false); - else if (type == double.class || type == Double.class) textField(config, info, Double::parseDouble, DECIMAL_ONLY, e.min(), e.max(),false); - else if (type == String.class) textField(config, info, String::length, null, Math.min(e.min(),0), Math.max(e.max(),1),true); + if (type == int.class || type == Integer.class) textField(config, info, Integer::parseInt, INTEGER_ONLY, info.entry.min(), info.entry.max(), true); + else if (type == float.class || type == Float.class) textField(config, info, Float::parseFloat, DECIMAL_ONLY, info.entry.min(), info.entry.max(),false); + else if (type == double.class || type == Double.class) textField(config, info, Double::parseDouble, DECIMAL_ONLY, info.entry.min(), info.entry.max(),false); + else if (type == String.class) textField(config, info, String::length, null, Math.min(info.entry.min(),0), Math.max(info.entry.max(),1),true); else if (type == boolean.class || type == Boolean.class) { Function func = value -> new LiteralText((Boolean) value ? "True" : "False").formatted((Boolean) value ? Formatting.GREEN : Formatting.RED); info.widget = new AbstractMap.SimpleEntry>(button -> { diff --git a/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/gui/MidnightConfigListWidget.java b/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/gui/MidnightConfigListWidget.java index 4d975dd..e6b8241 100644 --- a/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/gui/MidnightConfigListWidget.java +++ b/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/gui/MidnightConfigListWidget.java @@ -11,7 +11,7 @@ import net.minecraft.text.Text; import java.util.Optional; @Environment(EnvType.CLIENT) -public class MidnightConfigListWidget extends ElementListWidget { +public class MidnightConfigListWidget extends ElementListWidget { TextRenderer textRenderer; public MidnightConfigListWidget(MinecraftClient minecraftClient, int i, int j, int k, int l, int m) { @@ -23,12 +23,13 @@ public class MidnightConfigListWidget extends ElementListWidget { public int getScrollbarPositionX() { return this.width -7; } public void addButton(ClickableWidget button, ClickableWidget resetButton, Text text) { - this.addEntry(ButtonEntry.create(button, text, resetButton)); + this.addEntry(ConfigScreenEntry.create(button, text, resetButton)); } @Override public int getRowWidth() { return 10000; } + public Optional getHoveredButton(double mouseY) { - for (ButtonEntry buttonEntry : this.children()) { + for (ConfigScreenEntry buttonEntry : this.children()) { for (ClickableWidget button : buttonEntry.buttons) { if (button.visible && mouseY >= button.y && mouseY < button.y + itemHeight) { return Optional.of(button); diff --git a/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/gui/TinyConfigScreen.java b/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/gui/TinyConfigScreen.java index 00f16ed..98c353d 100644 --- a/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/gui/TinyConfigScreen.java +++ b/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/gui/TinyConfigScreen.java @@ -4,8 +4,10 @@ import io.gitlab.jfronny.libjf.LibJf; import io.gitlab.jfronny.libjf.config.impl.Config; import io.gitlab.jfronny.libjf.config.api.Entry; import io.gitlab.jfronny.libjf.config.impl.EntryInfo; +import io.gitlab.jfronny.libjf.config.impl.gui.presets.PresetsScreen; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; +import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.ScreenTexts; import net.minecraft.client.gui.widget.ButtonWidget; @@ -40,15 +42,19 @@ public class TinyConfigScreen extends Screen { // Real Time config update // @Override public void tick() { - for (EntryInfo info : config.entries) - try { info.field.set(null, info.value); } - catch (IllegalAccessException ignored) {} + config.syncToClass(); } @Override protected void init() { super.init(); + config.syncFromClass(); + + this.addDrawableChild(new ButtonWidget(4, 6, 80, 20, new TranslatableText("libjf-config-v0.presets"), button -> { + MinecraftClient.getInstance().setScreen(new PresetsScreen(this, config)); + })); + this.addDrawableChild(new ButtonWidget(this.width / 2 - 154, this.height - 28, 150, 20, ScreenTexts.CANCEL, button -> { try { LibJf.GSON.fromJson(Files.newBufferedReader(config.path), config.configClass); } @@ -67,10 +73,7 @@ public class TinyConfigScreen extends Screen { })); ButtonWidget done = this.addDrawableChild(new ButtonWidget(this.width / 2 + 4, this.height - 28, 150, 20, ScreenTexts.DONE, (button) -> { - for (EntryInfo info : config.entries) - try { - info.field.set(null, info.value); - } catch (IllegalAccessException ignored) {} + config.syncToClass(); config.write(); Objects.requireNonNull(client).setScreen(parent); })); @@ -103,8 +106,8 @@ public class TinyConfigScreen extends Screen { this.list.addButton(dummy,dummy,name); } } - } + @Override public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { this.renderBackground(matrices); @@ -116,7 +119,7 @@ public class TinyConfigScreen extends Screen { if (widget.isPresent()) { for (EntryInfo info : config.entries) { ClickableWidget buttonWidget = widget.get(); - Text text = ButtonEntry.buttonsWithText.get(buttonWidget); + Text text = ConfigScreenEntry.buttonsWithText.get(buttonWidget); TranslatableText name = new TranslatableText(this.translationPrefix + info.field.getName()); boolean showTooltip = text.equals(name); String tooltipKey = translationPrefix + info.field.getName() + ".tooltip"; @@ -135,4 +138,9 @@ public class TinyConfigScreen extends Screen { } super.render(matrices,mouseX,mouseY,delta); } + + @Override + public void onClose() { + MinecraftClient.getInstance().setScreen(parent); + } } diff --git a/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/gui/presets/PresetEntry.java b/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/gui/presets/PresetEntry.java new file mode 100644 index 0000000..582b6c2 --- /dev/null +++ b/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/gui/presets/PresetEntry.java @@ -0,0 +1,32 @@ +package io.gitlab.jfronny.libjf.config.impl.gui.presets; + +import net.minecraft.client.gui.Element; +import net.minecraft.client.gui.Selectable; +import net.minecraft.client.gui.widget.ClickableWidget; +import net.minecraft.client.gui.widget.ElementListWidget; +import net.minecraft.client.util.math.MatrixStack; + +import java.util.List; + +public class PresetEntry extends ElementListWidget.Entry { + private final ClickableWidget button; + public PresetEntry(ClickableWidget button) { + this.button = button; + } + + @Override + public List selectableChildren() { + return List.of(button); + } + + @Override + public List children() { + return List.of(button); + } + + @Override + public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { + button.y = y; + button.render(matrices, mouseX, mouseY, tickDelta); + } +} diff --git a/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/gui/presets/PresetListWidget.java b/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/gui/presets/PresetListWidget.java new file mode 100644 index 0000000..5adff9e --- /dev/null +++ b/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/gui/presets/PresetListWidget.java @@ -0,0 +1,20 @@ +package io.gitlab.jfronny.libjf.config.impl.gui.presets; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.widget.ClickableWidget; +import net.minecraft.client.gui.widget.ElementListWidget; + +public class PresetListWidget extends ElementListWidget { + public PresetListWidget(MinecraftClient client, int i, int j, int k, int l, int m) { + super(client, i, j, k, l, m); + } + + public void addButton(ClickableWidget button) { + addEntry(new PresetEntry(button)); + } + + @Override + public int getScrollbarPositionX() { return this.width -7; } + @Override + public int getRowWidth() { return 10000; } +} diff --git a/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/gui/presets/PresetsScreen.java b/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/gui/presets/PresetsScreen.java new file mode 100644 index 0000000..1101387 --- /dev/null +++ b/libjf-config-v0/src/main/java/io/gitlab/jfronny/libjf/config/impl/gui/presets/PresetsScreen.java @@ -0,0 +1,58 @@ +package io.gitlab.jfronny.libjf.config.impl.gui.presets; + +import io.gitlab.jfronny.libjf.LibJf; +import io.gitlab.jfronny.libjf.config.impl.Config; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.text.TranslatableText; + +import java.util.Map; + +@Environment(EnvType.CLIENT) +public class PresetsScreen extends Screen { + private final Screen parent; + private final Config config; + private PresetListWidget list; + + public PresetsScreen(Screen parent, Config config) { + super(new TranslatableText("libjf-config-v0.presets")); + this.parent = parent; + this.config = config; + } + + @Override + protected void init() { + super.init(); + this.list = new PresetListWidget(this.client, this.width, this.height, 32, this.height - 32, 25); + for (Map.Entry entry : config.presets.entrySet()) { + this.list.addButton(new ButtonWidget(width / 2 - 100, 0, 200, 20, + new TranslatableText(entry.getKey()), + button -> { + LibJf.LOGGER.info("Preset selected: " + entry.getKey()); + entry.getValue().run(); + config.syncFromClass(); + MinecraftClient.getInstance().setScreen(parent); + })); + } + this.addSelectableChild(this.list); + } + + @Override + public void onClose() { + MinecraftClient.getInstance().setScreen(parent); + } + + @Override + public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { + this.renderBackground(matrices); + this.list.render(matrices, mouseX, mouseY, delta); + + drawCenteredText(matrices, textRenderer, title, width / 2, 15, 0xFFFFFF); + + super.render(matrices, mouseX, mouseY, delta); + } +} diff --git a/libjf-config-v0/src/main/resources/assets/libjf-config-v0/lang/en_us.json b/libjf-config-v0/src/main/resources/assets/libjf-config-v0/lang/en_us.json new file mode 100644 index 0000000..8acc0be --- /dev/null +++ b/libjf-config-v0/src/main/resources/assets/libjf-config-v0/lang/en_us.json @@ -0,0 +1,4 @@ +{ + "libjf-config-v0.presets": "Presets", + "libjf-config-v0.default": "Default" +} \ No newline at end of file diff --git a/libjf-config-v0/src/testmod/java/io/gitlab/jfronny/libjf/config/test/TestConfig.java b/libjf-config-v0/src/testmod/java/io/gitlab/jfronny/libjf/config/test/TestConfig.java index fd977da..8084213 100644 --- a/libjf-config-v0/src/testmod/java/io/gitlab/jfronny/libjf/config/test/TestConfig.java +++ b/libjf-config-v0/src/testmod/java/io/gitlab/jfronny/libjf/config/test/TestConfig.java @@ -2,6 +2,8 @@ package io.gitlab.jfronny.libjf.config.test; import io.gitlab.jfronny.libjf.config.api.JfConfig; import io.gitlab.jfronny.libjf.config.api.Entry; +import io.gitlab.jfronny.libjf.config.api.Preset; +import io.gitlab.jfronny.libjf.config.api.Verifier; import io.gitlab.jfronny.libjf.gson.GsonHidden; public class TestConfig implements JfConfig { @@ -15,6 +17,21 @@ public class TestConfig implements JfConfig { public static String gsonOnlyStr = "lolz"; @Entry public static Test enumTest = Test.Test; + @Preset + public static void moskau() { + disablePacks = true; + disablePacks2 = true; + intTest = -5; + floatTest = -6; + doubleTest = 4; + dieStr = "Moskau"; + } + + @Verifier + public static void setIntTestIfDisable() { + if (disablePacks) intTest = 0; + } + public enum Test { Test, ER } diff --git a/libjf-config-v0/src/testmod/resources/assets/libjf-config-v0-testmod/lang/en_us.json b/libjf-config-v0/src/testmod/resources/assets/libjf-config-v0-testmod/lang/en_us.json index 474212c..36cb2cd 100644 --- a/libjf-config-v0/src/testmod/resources/assets/libjf-config-v0-testmod/lang/en_us.json +++ b/libjf-config-v0/src/testmod/resources/assets/libjf-config-v0-testmod/lang/en_us.json @@ -8,5 +8,6 @@ "libjf-config-v0-testmod.jfconfig.enumTest": "Enum Test", "libjf-config-v0-testmod.jfconfig.enumTest.tooltip": "Enum Test Tooltip", "libjf-config-v0-testmod.jfconfig.enum.Test.Test": "Test", - "libjf-config-v0-testmod.jfconfig.enum.Test.ER": "ER" + "libjf-config-v0-testmod.jfconfig.enum.Test.ER": "ER", + "libjf-config-v0-testmod.jfconfig.moskau": "Moskau" } \ No newline at end of file diff --git a/libjf-data-manipulation-v0/src/main/java/io/gitlab/jfronny/libjf/data/manipulation/api/UserResourceEvents.java b/libjf-data-manipulation-v0/src/main/java/io/gitlab/jfronny/libjf/data/manipulation/api/UserResourceEvents.java index a38ec0c..824449b 100644 --- a/libjf-data-manipulation-v0/src/main/java/io/gitlab/jfronny/libjf/data/manipulation/api/UserResourceEvents.java +++ b/libjf-data-manipulation-v0/src/main/java/io/gitlab/jfronny/libjf/data/manipulation/api/UserResourceEvents.java @@ -39,7 +39,7 @@ public class UserResourceEvents { public static final Event CONTAINS = EventFactory.createArrayBacked(Contains.class, (listeners) -> (type, id, previous, pack) -> { - LazySupplier lazy = new LazySupplier<>(previous); //TODO make initial value lazy properly + LazySupplier lazy = new LazySupplier<>(previous); for (Contains listener : listeners) { lazy = lazy.andThen(supplier -> listener.contains(type, id, supplier, pack)); } @@ -48,7 +48,7 @@ public class UserResourceEvents { public static final Event FIND_RESOURCE = EventFactory.createArrayBacked(FindResource.class, (listeners) -> ((type, namespace, prefix, maxDepth, pathFilter, previous, pack) -> { - LazySupplier> lazy = new LazySupplier<>(previous); //TODO make initial value lazy properly + LazySupplier> lazy = new LazySupplier<>(previous); for (FindResource listener : listeners) { lazy = lazy.andThen(supplier -> listener.findResources(type, namespace, prefix, maxDepth, pathFilter, supplier, pack)); } @@ -57,7 +57,7 @@ public class UserResourceEvents { public static final Event OPEN = EventFactory.createArrayBacked(Open.class, (listeners) -> ((type, id, previous, pack) -> { - LazySupplier lazy = new LazySupplier<>(previous); //TODO make initial value lazy properly + LazySupplier lazy = new LazySupplier<>(previous); for (Open listener : listeners) { lazy = lazy.andThen(supplier -> { try { @@ -73,7 +73,7 @@ public class UserResourceEvents { public static final Event OPEN_ROOT = EventFactory.createArrayBacked(OpenRoot.class, (listeners) -> ((fileName, previous, pack) -> { - LazySupplier lazy = new LazySupplier<>(previous); //TODO make initial value lazy properly + LazySupplier lazy = new LazySupplier<>(previous); for (OpenRoot listener : listeners) { lazy = lazy.andThen(supplier -> { try { diff --git a/libjf-devutil-v0/src/main/resources/libjf-devutil-v0.mixins.json b/libjf-devutil-v0/src/main/resources/libjf-devutil-v0.mixins.json index 134904b..e7b5b77 100644 --- a/libjf-devutil-v0/src/main/resources/libjf-devutil-v0.mixins.json +++ b/libjf-devutil-v0/src/main/resources/libjf-devutil-v0.mixins.json @@ -4,9 +4,9 @@ "package": "io.gitlab.jfronny.libjf.devutil.mixin", "compatibilityLevel": "JAVA_16", "mixins": [ - "MinecraftClientMixin" ], "client": [ + "MinecraftClientMixin" ], "injectors": { "defaultRequire": 1