aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/dev/isxander/yacl/api
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/dev/isxander/yacl/api')
-rw-r--r--src/main/java/dev/isxander/yacl/api/Binding.java2
-rw-r--r--src/main/java/dev/isxander/yacl/api/ButtonOption.java75
-rw-r--r--src/main/java/dev/isxander/yacl/api/ConfigCategory.java31
-rw-r--r--src/main/java/dev/isxander/yacl/api/Control.java8
-rw-r--r--src/main/java/dev/isxander/yacl/api/NameableEnum.java7
-rw-r--r--src/main/java/dev/isxander/yacl/api/Option.java21
-rw-r--r--src/main/java/dev/isxander/yacl/api/OptionGroup.java52
-rw-r--r--src/main/java/dev/isxander/yacl/api/YetAnotherConfigLib.java31
-rw-r--r--src/main/java/dev/isxander/yacl/api/utils/Dimension.java21
-rw-r--r--src/main/java/dev/isxander/yacl/api/utils/OptionUtils.java28
10 files changed, 255 insertions, 21 deletions
diff --git a/src/main/java/dev/isxander/yacl/api/Binding.java b/src/main/java/dev/isxander/yacl/api/Binding.java
index 67ff822..74120a0 100644
--- a/src/main/java/dev/isxander/yacl/api/Binding.java
+++ b/src/main/java/dev/isxander/yacl/api/Binding.java
@@ -10,7 +10,7 @@ public interface Binding<T> {
T getValue();
- void resetValue();
+ T defaultValue();
static <T> Binding<T> of(T def, Supplier<T> getter, Consumer<T> setter) {
return new GenericBindingImpl<>(def, getter, setter);
diff --git a/src/main/java/dev/isxander/yacl/api/ButtonOption.java b/src/main/java/dev/isxander/yacl/api/ButtonOption.java
new file mode 100644
index 0000000..08436b3
--- /dev/null
+++ b/src/main/java/dev/isxander/yacl/api/ButtonOption.java
@@ -0,0 +1,75 @@
+package dev.isxander.yacl.api;
+
+import dev.isxander.yacl.impl.ButtonOptionImpl;
+import net.minecraft.text.MutableText;
+import net.minecraft.text.Text;
+import org.apache.commons.lang3.Validate;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Function;
+
+public interface ButtonOption extends Option<Runnable> {
+ Runnable action();
+
+ static Builder createBuilder() {
+ return new Builder();
+ }
+
+ class Builder {
+ private Text name;
+ private final List<Text> tooltipLines = new ArrayList<>();
+ private Function<ButtonOption, Control<Runnable>> controlGetter;
+ private Runnable action;
+
+ private Builder() {
+
+ }
+
+ public Builder name(@NotNull Text name) {
+ Validate.notNull(name, "`name` cannot be null");
+
+ this.name = name;
+ return this;
+ }
+
+ public Builder tooltip(@NotNull Text... tooltips) {
+ Validate.notEmpty(tooltips, "`tooltips` cannot be empty");
+
+ tooltipLines.addAll(List.of(tooltips));
+ return this;
+ }
+
+ public Builder action(@NotNull Runnable action) {
+ Validate.notNull(action, "`action` cannot be null");
+
+ this.action = action;
+ return this;
+ }
+
+ public Builder controller(@NotNull Function<ButtonOption, Control<Runnable>> control) {
+ Validate.notNull(control, "`control` cannot be null");
+
+ this.controlGetter = control;
+ return this;
+ }
+
+ public ButtonOption build() {
+ Validate.notNull(name, "`name` must not be null when building `Option`");
+ Validate.notNull(controlGetter, "`control` must not be null when building `Option`");
+ Validate.notNull(action, "`action` must not be null when building `Option`");
+
+ MutableText concatenatedTooltip = Text.empty();
+ boolean first = true;
+ for (Text line : tooltipLines) {
+ if (!first) concatenatedTooltip.append("\n");
+ first = false;
+
+ concatenatedTooltip.append(line);
+ }
+
+ return new ButtonOptionImpl(name, concatenatedTooltip, action, controlGetter);
+ }
+ }
+}
diff --git a/src/main/java/dev/isxander/yacl/api/ConfigCategory.java b/src/main/java/dev/isxander/yacl/api/ConfigCategory.java
index ee2fbc7..13552d6 100644
--- a/src/main/java/dev/isxander/yacl/api/ConfigCategory.java
+++ b/src/main/java/dev/isxander/yacl/api/ConfigCategory.java
@@ -1,18 +1,22 @@
package dev.isxander.yacl.api;
import com.google.common.collect.ImmutableList;
+import dev.isxander.yacl.gui.YACLScreen;
import dev.isxander.yacl.impl.ConfigCategoryImpl;
+import dev.isxander.yacl.impl.OptionGroupImpl;
+import net.minecraft.client.gui.widget.ClickableWidget;
import net.minecraft.text.Text;
import org.apache.commons.lang3.Validate;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
+import java.util.function.Function;
public interface ConfigCategory {
@NotNull Text name();
- @NotNull ImmutableList<Option<?>> options();
+ @NotNull ImmutableList<OptionGroup> groups();
static Builder createBuilder() {
return new Builder();
@@ -20,31 +24,44 @@ public interface ConfigCategory {
class Builder {
private Text name;
- private final List<Option<?>> options = new ArrayList<>();
+ private final List<Option<?>> rootOptions = new ArrayList<>();
+
+ private final List<OptionGroup> groups = new ArrayList<>();
private Builder() {
}
- public Builder setName(@NotNull Text name) {
+ public Builder name(@NotNull Text name) {
Validate.notNull(name, "`name` cannot be null");
this.name = name;
return this;
}
- public Builder addOption(@NotNull Option<?> option) {
+ public Builder option(@NotNull Option<?> option) {
Validate.notNull(option, "`option` must not be null");
- this.options.add(option);
+ this.rootOptions.add(option);
+ return this;
+ }
+
+ public Builder group(@NotNull OptionGroup group) {
+ Validate.notNull(group, "`group` must not be null");
+
+ this.groups.add(group);
return this;
}
public ConfigCategory build() {
Validate.notNull(name, "`name` must not be null to build `ConfigCategory`");
- Validate.notEmpty(options, "`at least one option must be added to build `ConfigCategory`");
+ Validate.notEmpty(rootOptions, "`at least one option must be added to build `ConfigCategory`");
+
+ List<OptionGroup> combinedGroups = new ArrayList<>();
+ combinedGroups.add(new OptionGroupImpl(Text.empty(), ImmutableList.copyOf(rootOptions), true));
+ combinedGroups.addAll(groups);
- return new ConfigCategoryImpl(name, ImmutableList.copyOf(options));
+ return new ConfigCategoryImpl(name, ImmutableList.copyOf(combinedGroups));
}
}
}
diff --git a/src/main/java/dev/isxander/yacl/api/Control.java b/src/main/java/dev/isxander/yacl/api/Control.java
index 0733c4f..242b2c8 100644
--- a/src/main/java/dev/isxander/yacl/api/Control.java
+++ b/src/main/java/dev/isxander/yacl/api/Control.java
@@ -1,10 +1,14 @@
package dev.isxander.yacl.api;
import dev.isxander.yacl.api.utils.Dimension;
-import dev.isxander.yacl.gui.AbstractWidget;
+import dev.isxander.yacl.gui.controllers.ControlWidget;
+import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.text.Text;
public interface Control<T> {
Option<T> option();
- AbstractWidget provideWidget(Dimension<Integer> widgetDimension);
+ Text formatValue();
+
+ ControlWidget<?> provideWidget(Screen screen, Dimension<Integer> widgetDimension);
}
diff --git a/src/main/java/dev/isxander/yacl/api/NameableEnum.java b/src/main/java/dev/isxander/yacl/api/NameableEnum.java
new file mode 100644
index 0000000..12a58c3
--- /dev/null
+++ b/src/main/java/dev/isxander/yacl/api/NameableEnum.java
@@ -0,0 +1,7 @@
+package dev.isxander.yacl.api;
+
+import net.minecraft.text.Text;
+
+public interface NameableEnum {
+ Text getDisplayName();
+}
diff --git a/src/main/java/dev/isxander/yacl/api/Option.java b/src/main/java/dev/isxander/yacl/api/Option.java
index 1c7a8a1..5a98d50 100644
--- a/src/main/java/dev/isxander/yacl/api/Option.java
+++ b/src/main/java/dev/isxander/yacl/api/Option.java
@@ -10,6 +10,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
+import java.util.function.Function;
import java.util.function.Supplier;
public interface Option<T> {
@@ -23,11 +24,17 @@ public interface Option<T> {
boolean changed();
+ T pendingValue();
+
void requestSet(T value);
void applyValue();
- static <T> Builder<T> createBuilder() {
+ void forgetPendingValue();
+
+ void requestSetDefault();
+
+ static <T> Builder<T> createBuilder(Class<T> clazz) {
return new Builder<>();
}
@@ -36,7 +43,7 @@ public interface Option<T> {
private final List<Text> tooltipLines = new ArrayList<>();
- private Control<T> control;
+ private Function<Option<T>, Control<T>> controlGetter;
private Binding<T> binding;
@@ -58,10 +65,10 @@ public interface Option<T> {
return this;
}
- public Builder<T> controller(@NotNull Control<T> control) {
+ public Builder<T> controller(@NotNull Function<Option<T>, Control<T>> control) {
Validate.notNull(control, "`control` cannot be null");
- this.control = control;
+ this.controlGetter = control;
return this;
}
@@ -73,7 +80,7 @@ public interface Option<T> {
}
public Builder<T> binding(@NotNull T def, @NotNull Supplier<@NotNull T> getter, @NotNull Consumer<@NotNull T> setter) {
- Validate.notNull(def, "`default` must not be null");
+ Validate.notNull(def, "`def` must not be null");
Validate.notNull(getter, "`getter` must not be null");
Validate.notNull(setter, "`setter` must not be null");
@@ -83,7 +90,7 @@ public interface Option<T> {
public Option<T> build() {
Validate.notNull(name, "`name` must not be null when building `Option`");
- Validate.notNull(control, "`control` must not be null when building `Option`");
+ Validate.notNull(controlGetter, "`control` must not be null when building `Option`");
Validate.notNull(binding, "`binding` must not be null when building `Option`");
MutableText concatenatedTooltip = Text.empty();
@@ -95,7 +102,7 @@ public interface Option<T> {
concatenatedTooltip.append(line);
}
- return new OptionImpl<>(name, concatenatedTooltip, control, binding);
+ return new OptionImpl<>(name, concatenatedTooltip, controlGetter, binding);
}
}
}
diff --git a/src/main/java/dev/isxander/yacl/api/OptionGroup.java b/src/main/java/dev/isxander/yacl/api/OptionGroup.java
new file mode 100644
index 0000000..bedbc82
--- /dev/null
+++ b/src/main/java/dev/isxander/yacl/api/OptionGroup.java
@@ -0,0 +1,52 @@
+package dev.isxander.yacl.api;
+
+import com.google.common.collect.ImmutableList;
+import dev.isxander.yacl.impl.OptionGroupImpl;
+import net.minecraft.text.Text;
+import org.apache.commons.lang3.Validate;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public interface OptionGroup {
+ Text name();
+
+ @NotNull ImmutableList<Option<?>> options();
+
+ boolean isRoot();
+
+ static Builder createBuilder() {
+ return new Builder();
+ }
+
+ class Builder {
+ private Text name = Text.empty();
+ private final List<Option<?>> options = new ArrayList<>();
+
+ private Builder() {
+
+ }
+
+ public Builder name(@NotNull Text name) {
+ Validate.notNull(name, "`name` must not be null");
+
+ this.name = name;
+ return this;
+ }
+
+ public Builder option(@NotNull Option<?> option) {
+ Validate.notNull(option, "`option` must not be null");
+
+ this.options.add(option);
+ return this;
+ }
+
+ public OptionGroup build() {
+ Validate.notEmpty(options, "`options` must not be empty to build `OptionGroup`");
+
+ return new OptionGroupImpl(name, ImmutableList.copyOf(options), false);
+ }
+ }
+}
diff --git a/src/main/java/dev/isxander/yacl/api/YetAnotherConfigLib.java b/src/main/java/dev/isxander/yacl/api/YetAnotherConfigLib.java
index d7f8416..a598e27 100644
--- a/src/main/java/dev/isxander/yacl/api/YetAnotherConfigLib.java
+++ b/src/main/java/dev/isxander/yacl/api/YetAnotherConfigLib.java
@@ -1,14 +1,17 @@
package dev.isxander.yacl.api;
import com.google.common.collect.ImmutableList;
+import dev.isxander.yacl.gui.YACLScreen;
import dev.isxander.yacl.impl.YetAnotherConfigLibImpl;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.text.Text;
import org.apache.commons.lang3.Validate;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
+import java.util.function.Consumer;
public interface YetAnotherConfigLib {
@@ -16,7 +19,11 @@ public interface YetAnotherConfigLib {
ImmutableList<ConfigCategory> categories();
- Screen generateScreen();
+ Runnable saveFunction();
+
+ Consumer<YACLScreen> initConsumer();
+
+ Screen generateScreen(@Nullable Screen parent);
static Builder createBuilder(Text title) {
return new Builder(title);
@@ -25,31 +32,47 @@ public interface YetAnotherConfigLib {
class Builder {
private Text title;
private final List<ConfigCategory> categories = new ArrayList<>();
+ private Runnable saveFunction = () -> {};
+ private Consumer<YACLScreen> initConsumer = screen -> {};
private Builder(@NotNull Text title) {
Validate.notNull(title, "`title` cannot be null");
this.title = title;
}
- public Builder setTitle(@NotNull Text title) {
+ public Builder title(@NotNull Text title) {
Validate.notNull(title, "`title` cannot be null");
this.title = title;
return this;
}
- public Builder addCategory(@NotNull ConfigCategory category) {
+ public Builder category(@NotNull ConfigCategory category) {
Validate.notNull(category, "`category` cannot be null");
this.categories.add(category);
return this;
}
+ public Builder save(@NotNull Runnable saveFunction) {
+ Validate.notNull(saveFunction, "`saveFunction` cannot be null");
+
+ this.saveFunction = saveFunction;
+ return this;
+ }
+
+ public Builder screenInit(@NotNull Consumer<YACLScreen> initConsumer) {
+ Validate.notNull(initConsumer, "`initConsumer` cannot be null");
+
+ this.initConsumer = initConsumer;
+ return this;
+ }
+
public YetAnotherConfigLib build() {
Validate.notNull(title, "`title must not be null to build `YetAnotherConfigLib`");
Validate.notEmpty(categories, "`categories` must not be empty to build `YetAnotherConfigLib`");
- return new YetAnotherConfigLibImpl(title, ImmutableList.copyOf(categories));
+ return new YetAnotherConfigLibImpl(title, ImmutableList.copyOf(categories), saveFunction, initConsumer);
}
}
}
diff --git a/src/main/java/dev/isxander/yacl/api/utils/Dimension.java b/src/main/java/dev/isxander/yacl/api/utils/Dimension.java
index cf7127a..69958b1 100644
--- a/src/main/java/dev/isxander/yacl/api/utils/Dimension.java
+++ b/src/main/java/dev/isxander/yacl/api/utils/Dimension.java
@@ -12,8 +12,29 @@ public interface Dimension<T extends Number> {
T xLimit();
T yLimit();
+ T centerX();
+ T centerY();
+
boolean isPointInside(T x, T y);
+ Dimension<T> clone();
+
+ Dimension<T> setX(T x);
+ Dimension<T> setY(T y);
+ Dimension<T> setWidth(T width);
+ Dimension<T> setHeight(T height);
+
+ Dimension<T> withX(T x);
+ Dimension<T> withY(T y);
+ Dimension<T> withWidth(T width);
+ Dimension<T> withHeight(T height);
+
+ Dimension<T> move(T x, T y);
+ Dimension<T> expand(T width, T height);
+
+ Dimension<T> moved(T x, T y);
+ Dimension<T> expanded(T width, T height);
+
static Dimension<Integer> ofInt(int x, int y, int width, int height) {
return new DimensionIntegerImpl(x, y, width, height);
}
diff --git a/src/main/java/dev/isxander/yacl/api/utils/OptionUtils.java b/src/main/java/dev/isxander/yacl/api/utils/OptionUtils.java
new file mode 100644
index 0000000..ed51683
--- /dev/null
+++ b/src/main/java/dev/isxander/yacl/api/utils/OptionUtils.java
@@ -0,0 +1,28 @@
+package dev.isxander.yacl.api.utils;
+
+import dev.isxander.yacl.api.ConfigCategory;
+import dev.isxander.yacl.api.Option;
+import dev.isxander.yacl.api.OptionGroup;
+import dev.isxander.yacl.api.YetAnotherConfigLib;
+
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+public class OptionUtils {
+ public static void consumeOptions(YetAnotherConfigLib yacl, Function<Option<?>, Boolean> consumer) {
+ for (ConfigCategory category : yacl.categories()) {
+ for (OptionGroup group : category.groups()) {
+ for (Option<?> option : group.options()) {
+ if (!consumer.apply(option)) return;
+ }
+ }
+ }
+ }
+
+ public static void forEachOptions(YetAnotherConfigLib yacl, Consumer<Option<?>> consumer) {
+ consumeOptions(yacl, (opt) -> {
+ consumer.accept(opt);
+ return true;
+ });
+ }
+}