add int & sub options

This commit is contained in:
2025-11-07 12:44:53 +01:00
parent 8bc465bb8f
commit 909f62d19f
10 changed files with 188 additions and 10 deletions

View File

@@ -2,7 +2,9 @@ package com.kasetoatz.dumbassconfig;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.kasetoatz.dumbassconfig.options.AbstractInputOption;
import com.kasetoatz.dumbassconfig.options.AbstractOption; import com.kasetoatz.dumbassconfig.options.AbstractOption;
import com.kasetoatz.dumbassconfig.ui.ConfigScreen; import com.kasetoatz.dumbassconfig.ui.ConfigScreen;
import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.FabricLoader;
@@ -64,6 +66,12 @@ public class DumbassConfig
{ {
if (data.has(option.getKey())) if (data.has(option.getKey()))
{ {
JsonElement value = data.get(option.getKey());
if (option instanceof AbstractInputOption<?> inputOption && !inputOption.isValid(value))
{
option.reset();
continue;
}
option.fromJson(data.get(option.getKey())); option.fromJson(data.get(option.getKey()));
} }
} }

View File

@@ -2,6 +2,8 @@ package com.kasetoatz.dumbassconfig;
import com.kasetoatz.dumbassconfig.options.BoolOption; import com.kasetoatz.dumbassconfig.options.BoolOption;
import com.kasetoatz.dumbassconfig.options.FloatOption; import com.kasetoatz.dumbassconfig.options.FloatOption;
import com.kasetoatz.dumbassconfig.options.IntOption;
import com.kasetoatz.dumbassconfig.options.SubOption;
import com.terraformersmc.modmenu.api.ConfigScreenFactory; import com.terraformersmc.modmenu.api.ConfigScreenFactory;
import com.terraformersmc.modmenu.api.ModMenuApi; import com.terraformersmc.modmenu.api.ModMenuApi;
import net.minecraft.text.Text; import net.minecraft.text.Text;
@@ -10,9 +12,24 @@ public class Test implements ModMenuApi
{ {
public static final BoolOption TEST_BOOL_OPT = new BoolOption("TEST", "test_bool_opt", false); public static final BoolOption TEST_BOOL_OPT = new BoolOption("TEST", "test_bool_opt", false);
public static final FloatOption TEST_FLOAT_OPT = new FloatOption("TEST", "test_float_opt", 1.F); public static final FloatOption TEST_FLOAT_OPT = new FloatOption("TEST", "test_float_opt", 1.F);
public static final IntOption TEST_INT_OPT = new IntOption("TEST", "test_int_opt", 1);
public static final IntOption SUB_SUB_INT_OPT = new IntOption("SUB SUB", "sub_sub_int_opt", 1);
public static final SubOption SUB_SUB_OPT = SubOption.builder("SUB SUB SCREEN", "sub_sub_opt")
.withOption(SUB_SUB_INT_OPT)
.build();
public static final IntOption SUB_INT_OPT = new IntOption("SUB", "sub_int_opt", 0);
public static final SubOption TEST_SUB_OPT = SubOption.builder("SUB SCREEN", "sub_opt")
.withOption(SUB_INT_OPT)
.withOption(SUB_SUB_OPT)
.build();
DumbassConfig config = DumbassConfig.builder(Text.literal("Test Screen"), "test.json") DumbassConfig config = DumbassConfig.builder(Text.literal("Test Screen"), "test.json")
.withOption(TEST_BOOL_OPT) .withOption(TEST_BOOL_OPT)
.withOption(TEST_FLOAT_OPT) .withOption(TEST_FLOAT_OPT)
.withOption(TEST_INT_OPT)
.withOption(TEST_SUB_OPT)
.build(); .build();
@Override @Override

View File

@@ -1,7 +1,8 @@
package com.kasetoatz.dumbassconfig.options; package com.kasetoatz.dumbassconfig.options;
import com.google.gson.JsonElement;
import com.kasetoatz.dumbassconfig.ui.InputField; import com.kasetoatz.dumbassconfig.ui.InputField;
import com.kasetoatz.dumbassconfig.options.validators.Validator; import com.kasetoatz.dumbassconfig.options.validators.AbstractValidator;
import net.minecraft.client.gui.tooltip.Tooltip; import net.minecraft.client.gui.tooltip.Tooltip;
import net.minecraft.text.Text; import net.minecraft.text.Text;
@@ -11,9 +12,9 @@ import static com.kasetoatz.dumbassconfig.DumbassConfig.VALID_INPUT_COLOR;
public abstract class AbstractInputOption<T> extends AbstractOption<T> public abstract class AbstractInputOption<T> extends AbstractOption<T>
{ {
public InputField textField; public InputField textField;
private Validator<T> validator; private AbstractValidator<T> validator;
public AbstractInputOption(String text, String key, T defaultValue, Validator<T> validator) public AbstractInputOption(String text, String key, T defaultValue, AbstractValidator<T> validator)
{ {
super(text, key, defaultValue); super(text, key, defaultValue);
this.validator = validator; this.validator = validator;
@@ -24,6 +25,15 @@ public abstract class AbstractInputOption<T> extends AbstractOption<T>
super(text, key, defaultValue); super(text, key, defaultValue);
} }
public boolean isValid(JsonElement element)
{
if (!this.predicate(element.getAsString()))
{
return false;
}
return this.validator == null || this.validator.isValid(this.asPrimitive(element));
}
public void onChange(T value) public void onChange(T value)
{ {
if (validator != null && !validator.isValid(value)) if (validator != null && !validator.isValid(value))
@@ -44,6 +54,13 @@ public abstract class AbstractInputOption<T> extends AbstractOption<T>
this.textField.setTooltip(Tooltip.of(Text.literal(message).withColor(INVALID_INPUT_COLOR))); this.textField.setTooltip(Tooltip.of(Text.literal(message).withColor(INVALID_INPUT_COLOR)));
} }
@Override
public void fromJson(JsonElement element)
{
this.setValue(this.asPrimitive(element));
}
public abstract boolean predicate(String value); public abstract boolean predicate(String value);
public abstract void changeListener(String value); public abstract void changeListener(String value);
public abstract T asPrimitive(JsonElement element);
} }

View File

@@ -43,5 +43,10 @@ public abstract class AbstractOption<T>
this.value = value; this.value = value;
} }
public void reset()
{
this.value = this.defaultValue;
}
public abstract void fromJson(JsonElement element); public abstract void fromJson(JsonElement element);
} }

View File

@@ -1,11 +1,11 @@
package com.kasetoatz.dumbassconfig.options; package com.kasetoatz.dumbassconfig.options;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.kasetoatz.dumbassconfig.options.validators.Validator; import com.kasetoatz.dumbassconfig.options.validators.AbstractValidator;
public class FloatOption extends AbstractInputOption<Float> public class FloatOption extends AbstractInputOption<Float>
{ {
public FloatOption(String text, String key, Float defaultValue, Validator<Float> validator) public FloatOption(String text, String key, Float defaultValue, AbstractValidator<Float> validator)
{ {
super(text, key, defaultValue, validator); super(text, key, defaultValue, validator);
} }
@@ -40,8 +40,8 @@ public class FloatOption extends AbstractInputOption<Float>
} }
@Override @Override
public void fromJson(JsonElement element) public Float asPrimitive(JsonElement element)
{ {
this.setValue(element.getAsFloat()); return element.getAsFloat();
} }
} }

View File

@@ -0,0 +1,46 @@
package com.kasetoatz.dumbassconfig.options;
import com.google.gson.JsonElement;
import com.kasetoatz.dumbassconfig.options.validators.AbstractValidator;
public class IntOption extends AbstractInputOption<Integer>
{
public IntOption(String text, String key, Integer defaultValue, AbstractValidator<Integer> validator)
{
super(text, key, defaultValue, validator);
}
public IntOption(String text, String key, Integer defaultValue)
{
super(text, key, defaultValue);
}
@Override
public boolean predicate(String text)
{
if (text.isEmpty() || text.equals("-")) {
return true;
}
try
{
Integer.parseInt(text);
return true;
}
catch (NumberFormatException exc)
{
return false;
}
}
@Override
public void changeListener(String text)
{
this.onChange((text.isEmpty() || text.equals("-")) ? 0 : Integer.parseInt(text));
}
@Override
public Integer asPrimitive(JsonElement element)
{
return element.getAsInt();
}
}

View File

@@ -0,0 +1,85 @@
package com.kasetoatz.dumbassconfig.options;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.kasetoatz.dumbassconfig.ui.ConfigScreen;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.text.Text;
import java.util.ArrayList;
public class SubOption extends AbstractButtonOption<JsonObject>
{
private final ArrayList<AbstractOption<?>> options = new ArrayList<>();
private final Gson gson = new GsonBuilder().setPrettyPrinting().create();
private ConfigScreen ui;
private SubOption(String text, String key)
{
super(text, key, null);
}
@Override
public Text getButtonText()
{
return Text.literal("Open");
}
@Override
public void onClick(ButtonWidget button)
{
this.ui.setParent(MinecraftClient.getInstance().currentScreen);
MinecraftClient.getInstance().setScreen(this.ui);
}
@Override
public JsonObject getValue()
{
JsonObject data = new JsonObject();
for (AbstractOption<?> option : this.options)
{
data.add(option.getKey(), this.gson.toJsonTree(option.getValue()));
}
return data;
}
@Override
public void fromJson(JsonElement element)
{
JsonObject data = element.getAsJsonObject();
for (AbstractOption<?> option : this.options)
{
option.fromJson(data.get(option.getKey()));
}
}
public static Builder builder(String text, String key)
{
return new Builder(text, key);
}
public static class Builder
{
private final SubOption option;
private Builder(String text, String key)
{
this.option = new SubOption(text, key);
}
public Builder withOption(AbstractOption<?> option)
{
this.option.options.add(option);
return this;
}
public SubOption build()
{
this.option.ui = new ConfigScreen(this.option.getText(), this.option.options);
return this.option;
}
}
}

View File

@@ -1,6 +1,6 @@
package com.kasetoatz.dumbassconfig.options.validators; package com.kasetoatz.dumbassconfig.options.validators;
public abstract class Validator<T> public abstract class AbstractValidator<T>
{ {
public abstract boolean isValid(T value); public abstract boolean isValid(T value);
public abstract String getErrorMessage(); public abstract String getErrorMessage();

View File

@@ -1,6 +1,6 @@
package com.kasetoatz.dumbassconfig.options.validators; package com.kasetoatz.dumbassconfig.options.validators;
public class RangeValidator<T extends Number & Comparable<T>> extends Validator<T> public class RangeValidator<T extends Number & Comparable<T>> extends AbstractValidator<T>
{ {
private final T min; private final T min;
private final T max; private final T max;

View File

@@ -18,7 +18,7 @@ public class ConfigScreen extends Screen
private final List<AbstractOption<?>> options; private final List<AbstractOption<?>> options;
private final ThreePartsLayoutWidget layout = new ThreePartsLayoutWidget(this); private final ThreePartsLayoutWidget layout = new ThreePartsLayoutWidget(this);
private ConfigEntryList body; private ConfigEntryList body;
private Runnable saveCallback; private Runnable saveCallback = () -> {};
public ConfigScreen(Text title, List<AbstractOption<?>> options) public ConfigScreen(Text title, List<AbstractOption<?>> options)
{ {