aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/dev/isxander/yacl/api
diff options
context:
space:
mode:
authorxander <xander@isxander.dev>2022-09-01 11:58:49 +0100
committerxander <xander@isxander.dev>2022-09-01 11:58:49 +0100
commit4d977cc9764ecf0073650f126700f6ff638fa06b (patch)
tree883e68bbd80874c048b3e34db59bf0aa926b489b /src/main/java/dev/isxander/yacl/api
parente63a3c989e3a899bdc81558dd2e4c5cc2c659bde (diff)
downloadYetAnotherConfigLib-4d977cc9764ecf0073650f126700f6ff638fa06b.tar.gz
YetAnotherConfigLib-4d977cc9764ecf0073650f126700f6ff638fa06b.tar.bz2
YetAnotherConfigLib-4d977cc9764ecf0073650f126700f6ff638fa06b.zip
javadoc!
added LongSliderController renamed Control -> Controller add minecraft simple option binding constructor
Diffstat (limited to 'src/main/java/dev/isxander/yacl/api')
-rw-r--r--src/main/java/dev/isxander/yacl/api/Binding.java31
-rw-r--r--src/main/java/dev/isxander/yacl/api/ButtonOption.java4
-rw-r--r--src/main/java/dev/isxander/yacl/api/ConfigCategory.java60
-rw-r--r--src/main/java/dev/isxander/yacl/api/Control.java14
-rw-r--r--src/main/java/dev/isxander/yacl/api/Controller.java30
-rw-r--r--src/main/java/dev/isxander/yacl/api/NameableEnum.java3
-rw-r--r--src/main/java/dev/isxander/yacl/api/Option.java93
-rw-r--r--src/main/java/dev/isxander/yacl/api/OptionGroup.java45
-rw-r--r--src/main/java/dev/isxander/yacl/api/YetAnotherConfigLib.java60
-rw-r--r--src/main/java/dev/isxander/yacl/api/utils/OptionUtils.java13
10 files changed, 324 insertions, 29 deletions
diff --git a/src/main/java/dev/isxander/yacl/api/Binding.java b/src/main/java/dev/isxander/yacl/api/Binding.java
index 74120a0..d870d8c 100644
--- a/src/main/java/dev/isxander/yacl/api/Binding.java
+++ b/src/main/java/dev/isxander/yacl/api/Binding.java
@@ -1,10 +1,17 @@
package dev.isxander.yacl.api;
import dev.isxander.yacl.impl.GenericBindingImpl;
+import dev.isxander.yacl.mixin.SimpleOptionAccessor;
+import net.minecraft.client.option.SimpleOption;
+import org.apache.commons.lang3.Validate;
import java.util.function.Consumer;
import java.util.function.Supplier;
+/**
+ * Controls modifying the bound option.
+ * Provides the default value, a setter and a getter.
+ */
public interface Binding<T> {
void setValue(T value);
@@ -12,7 +19,31 @@ public interface Binding<T> {
T defaultValue();
+ /**
+ * Creates a generic binding.
+ *
+ * @param def default value of the option, used to reset
+ * @param getter should return the current value of the option
+ * @param setter should set the option to the supplied value
+ */
static <T> Binding<T> of(T def, Supplier<T> getter, Consumer<T> setter) {
+ Validate.notNull(def, "`def` must not be null");
+ Validate.notNull(getter, "`getter` must not be null");
+ Validate.notNull(setter, "`setter` must not be null");
+
return new GenericBindingImpl<>(def, getter, setter);
}
+
+ /**
+ * Creates a {@link Binding} for Minecraft's {@link SimpleOption}
+ */
+ static <T> Binding<T> of(SimpleOption<T> minecraftOption) {
+ Validate.notNull(minecraftOption, "`minecraftOption` must not be null");
+
+ return new GenericBindingImpl<>(
+ ((SimpleOptionAccessor<T>) (Object) minecraftOption).getDefaultValue(),
+ minecraftOption::getValue,
+ minecraftOption::setValue
+ );
+ }
}
diff --git a/src/main/java/dev/isxander/yacl/api/ButtonOption.java b/src/main/java/dev/isxander/yacl/api/ButtonOption.java
index 08436b3..346bfa4 100644
--- a/src/main/java/dev/isxander/yacl/api/ButtonOption.java
+++ b/src/main/java/dev/isxander/yacl/api/ButtonOption.java
@@ -20,7 +20,7 @@ public interface ButtonOption extends Option<Runnable> {
class Builder {
private Text name;
private final List<Text> tooltipLines = new ArrayList<>();
- private Function<ButtonOption, Control<Runnable>> controlGetter;
+ private Function<ButtonOption, Controller<Runnable>> controlGetter;
private Runnable action;
private Builder() {
@@ -48,7 +48,7 @@ public interface ButtonOption extends Option<Runnable> {
return this;
}
- public Builder controller(@NotNull Function<ButtonOption, Control<Runnable>> control) {
+ public Builder controller(@NotNull Function<ButtonOption, Controller<Runnable>> control) {
Validate.notNull(control, "`control` cannot be null");
this.controlGetter = control;
diff --git a/src/main/java/dev/isxander/yacl/api/ConfigCategory.java b/src/main/java/dev/isxander/yacl/api/ConfigCategory.java
index 13552d6..b2bbf95 100644
--- a/src/main/java/dev/isxander/yacl/api/ConfigCategory.java
+++ b/src/main/java/dev/isxander/yacl/api/ConfigCategory.java
@@ -10,14 +10,29 @@ import org.apache.commons.lang3.Validate;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
import java.util.function.Function;
+/**
+ * Separates {@link Option}s or {@link OptionGroup}s into multiple distinct sections.
+ * Served to a user as a button in the left column,
+ * upon pressing, the options list is filled with options contained within this category.
+ */
public interface ConfigCategory {
+ /**
+ * Name of category, displayed as a button on the left column.
+ */
@NotNull Text name();
+ /**
+ * Gets every {@link OptionGroup} in this category.
+ */
@NotNull ImmutableList<OptionGroup> groups();
+ /**
+ * Creates a builder to construct a {@link ConfigCategory}
+ */
static Builder createBuilder() {
return new Builder();
}
@@ -32,6 +47,11 @@ public interface ConfigCategory {
}
+ /**
+ * Sets name of the category
+ *
+ * @see ConfigCategory#name()
+ */
public Builder name(@NotNull Text name) {
Validate.notNull(name, "`name` cannot be null");
@@ -39,6 +59,14 @@ public interface ConfigCategory {
return this;
}
+ /**
+ * Adds an option to the root group of the category.
+ * To add to another group, use {@link Builder#group(OptionGroup)}.
+ * To construct an option, use {@link Option#createBuilder(Class)}
+ *
+ * @see ConfigCategory#groups()
+ * @see OptionGroup#isRoot()
+ */
public Builder option(@NotNull Option<?> option) {
Validate.notNull(option, "`option` must not be null");
@@ -46,6 +74,26 @@ public interface ConfigCategory {
return this;
}
+ /**
+ * Adds multiple options to the root group of the category.
+ * To add to another group, use {@link Builder#groups(Collection)}.
+ * To construct an option, use {@link Option#createBuilder(Class)}
+ *
+ * @see ConfigCategory#groups()
+ * @see OptionGroup#isRoot()
+ */
+ public Builder options(@NotNull Collection<Option<?>> options) {
+ Validate.notEmpty(options, "`options` must not be empty");
+
+ this.rootOptions.addAll(options);
+ return this;
+ }
+
+ /**
+ * Adds an option group.
+ * To add an option to the root group, use {@link Builder#option(Option)}
+ * To construct a group, use {@link OptionGroup#createBuilder()}
+ */
public Builder group(@NotNull OptionGroup group) {
Validate.notNull(group, "`group` must not be null");
@@ -53,6 +101,18 @@ public interface ConfigCategory {
return this;
}
+ /**
+ * Adds multiple option groups.
+ * To add multiple options to the root group, use {@link Builder#options(Collection)}
+ * To construct a group, use {@link OptionGroup#createBuilder()}
+ */
+ public Builder groups(@NotNull Collection<OptionGroup> groups) {
+ Validate.notEmpty(groups, "`groups` must not be empty");
+
+ this.groups.addAll(groups);
+ return this;
+ }
+
public ConfigCategory build() {
Validate.notNull(name, "`name` must not be null to build `ConfigCategory`");
Validate.notEmpty(rootOptions, "`at least one option must be added to build `ConfigCategory`");
diff --git a/src/main/java/dev/isxander/yacl/api/Control.java b/src/main/java/dev/isxander/yacl/api/Control.java
deleted file mode 100644
index 242b2c8..0000000
--- a/src/main/java/dev/isxander/yacl/api/Control.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package dev.isxander.yacl.api;
-
-import dev.isxander.yacl.api.utils.Dimension;
-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();
-
- Text formatValue();
-
- ControlWidget<?> provideWidget(Screen screen, Dimension<Integer> widgetDimension);
-}
diff --git a/src/main/java/dev/isxander/yacl/api/Controller.java b/src/main/java/dev/isxander/yacl/api/Controller.java
new file mode 100644
index 0000000..2c0a5e1
--- /dev/null
+++ b/src/main/java/dev/isxander/yacl/api/Controller.java
@@ -0,0 +1,30 @@
+package dev.isxander.yacl.api;
+
+import dev.isxander.yacl.api.utils.Dimension;
+import dev.isxander.yacl.gui.controllers.ControllerWidget;
+import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.text.Text;
+import org.jetbrains.annotations.ApiStatus;
+
+/**
+ * Provides a widget to control the option.
+ */
+public interface Controller<T> {
+ /**
+ * Gets the dedicated {@link Option} for this controller
+ */
+ Option<T> option();
+
+ /**
+ * Gets the formatted value based on {@link Option#pendingValue()}
+ */
+ Text formatValue();
+
+ /**
+ * Provides a widget to display
+ *
+ * @param screen parent screen
+ */
+ @ApiStatus.Internal
+ ControllerWidget<?> 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
index 12a58c3..9744ce9 100644
--- a/src/main/java/dev/isxander/yacl/api/NameableEnum.java
+++ b/src/main/java/dev/isxander/yacl/api/NameableEnum.java
@@ -2,6 +2,9 @@ package dev.isxander.yacl.api;
import net.minecraft.text.Text;
+/**
+ * Used for the default value formatter of {@link dev.isxander.yacl.gui.controllers.EnumController}
+ */
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 5a98d50..6598b80 100644
--- a/src/main/java/dev/isxander/yacl/api/Option.java
+++ b/src/main/java/dev/isxander/yacl/api/Option.java
@@ -5,7 +5,6 @@ import net.minecraft.text.MutableText;
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;
@@ -14,27 +13,70 @@ import java.util.function.Function;
import java.util.function.Supplier;
public interface Option<T> {
+ /**
+ * Name of the option
+ */
@NotNull Text name();
- @Nullable Text tooltip();
-
- @NotNull Control<T> control();
-
+ /**
+ * Tooltip (or description) of the option.
+ * Rendered on hover.
+ */
+ @NotNull Text tooltip();
+
+ /**
+ * Widget provider for a type of option.
+ *
+ * @see dev.isxander.yacl.gui.controllers
+ */
+ @NotNull Controller<T> controller();
+
+ /**
+ * Binding for the option.
+ * Controls setting, getting and default value.
+ *
+ * @see Binding
+ */
@NotNull Binding<T> binding();
+ /**
+ * Checks if the pending value is not equal to the current set value
+ */
boolean changed();
- T pendingValue();
+ /**
+ * Value in the GUI, ready to set the actual bound value or be undone.
+ */
+ @NotNull T pendingValue();
+ /**
+ * Sets the pending value
+ */
void requestSet(T value);
+ /**
+ * Applies the pending value to the bound value.
+ * Cannot be undone.
+ */
void applyValue();
+ /**
+ * Sets the pending value to the bound value.
+ */
void forgetPendingValue();
+ /**
+ * Sets the pending value to the default bound value.
+ */
void requestSetDefault();
- static <T> Builder<T> createBuilder(Class<T> clazz) {
+ /**
+ * Creates a builder to construct an {@link Option}
+ *
+ * @param <T> type of the option's value
+ * @param typeClass used to capture the type
+ */
+ static <T> Builder<T> createBuilder(Class<T> typeClass) {
return new Builder<>();
}
@@ -43,7 +85,7 @@ public interface Option<T> {
private final List<Text> tooltipLines = new ArrayList<>();
- private Function<Option<T>, Control<T>> controlGetter;
+ private Function<Option<T>, Controller<T>> controlGetter;
private Binding<T> binding;
@@ -51,6 +93,11 @@ public interface Option<T> {
}
+ /**
+ * Sets the name to be used by the option.
+ *
+ * @see Option#name()
+ */
public Builder<T> name(@NotNull Text name) {
Validate.notNull(name, "`name` cannot be null");
@@ -58,6 +105,13 @@ public interface Option<T> {
return this;
}
+ /**
+ * Sets the tooltip to be used by the option.
+ * Can be invoked twice to append more lines.
+ * No need to wrap the text yourself, the gui does this itself.
+ *
+ * @param tooltips text lines - merged with a new-line on {@link Builder#build()}.
+ */
public Builder<T> tooltip(@NotNull Text... tooltips) {
Validate.notEmpty(tooltips, "`tooltips` cannot be empty");
@@ -65,13 +119,25 @@ public interface Option<T> {
return this;
}
- public Builder<T> controller(@NotNull Function<Option<T>, Control<T>> control) {
+ /**
+ * Sets the controller for the option.
+ * This is how you interact and change the options.
+ *
+ * @see dev.isxander.yacl.gui.controllers
+ */
+ public Builder<T> controller(@NotNull Function<Option<T>, Controller<T>> control) {
Validate.notNull(control, "`control` cannot be null");
this.controlGetter = control;
return this;
}
+ /**
+ * Sets the binding for the option.
+ * Used for default, getter and setter.
+ *
+ * @see Binding
+ */
public Builder<T> binding(@NotNull Binding<T> binding) {
Validate.notNull(binding, "`binding` cannot be null");
@@ -79,6 +145,15 @@ public interface Option<T> {
return this;
}
+ /**
+ * Sets the binding for the option.
+ * Shorthand of {@link Binding#of(Object, Supplier, Consumer)}
+ *
+ * @param def default value of the option, used to reset
+ * @param getter should return the current value of the option
+ * @param setter should set the option to the supplied value
+ * @see Binding
+ */
public Builder<T> binding(@NotNull T def, @NotNull Supplier<@NotNull T> getter, @NotNull Consumer<@NotNull T> setter) {
Validate.notNull(def, "`def` must not be null");
Validate.notNull(getter, "`getter` must not be null");
diff --git a/src/main/java/dev/isxander/yacl/api/OptionGroup.java b/src/main/java/dev/isxander/yacl/api/OptionGroup.java
index bedbc82..6a302c4 100644
--- a/src/main/java/dev/isxander/yacl/api/OptionGroup.java
+++ b/src/main/java/dev/isxander/yacl/api/OptionGroup.java
@@ -5,18 +5,37 @@ 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.Collection;
import java.util.List;
+/**
+ * Serves as a separator between multiple chunks of options
+ * that may be too similar or too few to be placed in a separate {@link ConfigCategory}.
+ * Or maybe you just want your config to feel less dense.
+ */
public interface OptionGroup {
+ /**
+ * Name of the option group, displayed as a separator in the option lists.
+ * Can be empty.
+ */
Text name();
+ /**
+ * List of all options in the group
+ */
@NotNull ImmutableList<Option<?>> options();
+ /**
+ * Always false when using the {@link Builder}
+ * used to not render the separator if true
+ */
boolean isRoot();
+ /**
+ * Creates a builder to construct a {@link OptionGroup}
+ */
static Builder createBuilder() {
return new Builder();
}
@@ -29,6 +48,11 @@ public interface OptionGroup {
}
+ /**
+ * Sets name of the group, can be {@link Text#empty()} to just separate options, like sodium.
+ *
+ * @see OptionGroup#name()
+ */
public Builder name(@NotNull Text name) {
Validate.notNull(name, "`name` must not be null");
@@ -36,6 +60,12 @@ public interface OptionGroup {
return this;
}
+ /**
+ * Adds an option to group.
+ * To construct an option, use {@link Option#createBuilder(Class)}
+ *
+ * @see OptionGroup#options()
+ */
public Builder option(@NotNull Option<?> option) {
Validate.notNull(option, "`option` must not be null");
@@ -43,6 +73,19 @@ public interface OptionGroup {
return this;
}
+ /**
+ * Adds multiple options to group.
+ * To construct an option, use {@link Option#createBuilder(Class)}
+ *
+ * @see OptionGroup#options()
+ */
+ public Builder options(@NotNull Collection<Option<?>> options) {
+ Validate.notEmpty(options, "`options` must not be empty");
+
+ this.options.addAll(options);
+ return this;
+ }
+
public OptionGroup build() {
Validate.notEmpty(options, "`options` must not be empty to build `OptionGroup`");
diff --git a/src/main/java/dev/isxander/yacl/api/YetAnotherConfigLib.java b/src/main/java/dev/isxander/yacl/api/YetAnotherConfigLib.java
index a31a4fb..34ccc6a 100644
--- a/src/main/java/dev/isxander/yacl/api/YetAnotherConfigLib.java
+++ b/src/main/java/dev/isxander/yacl/api/YetAnotherConfigLib.java
@@ -10,21 +10,45 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
import java.util.function.Consumer;
+/**
+ * Main class of the mod.
+ * Contains all data and used to provide a {@link Screen}
+ */
public interface YetAnotherConfigLib {
-
+ /**
+ * Title of the GUI. Only used for Minecraft narration.
+ */
Text title();
+ /**
+ * Gets all config categories.
+ */
ImmutableList<ConfigCategory> categories();
+ /**
+ * Ran when changes are saved. Can be used to save config to a file etc.
+ */
Runnable saveFunction();
+ /**
+ * Ran every time the YACL screen initialises. Can be paired with FAPI to add custom widgets.
+ */
Consumer<YACLScreen> initConsumer();
+ /**
+ * Generates a Screen to display based on this instance.
+ *
+ * @param parent parent screen to open once closed
+ */
Screen generateScreen(@Nullable Screen parent);
+ /**
+ * Creates a builder to construct YACL
+ */
static Builder createBuilder() {
return new Builder();
}
@@ -39,6 +63,11 @@ public interface YetAnotherConfigLib {
}
+ /**
+ * Sets title of GUI for Minecraft narration
+ *
+ * @see YetAnotherConfigLib#title()
+ */
public Builder title(@NotNull Text title) {
Validate.notNull(title, "`title` cannot be null");
@@ -46,6 +75,12 @@ public interface YetAnotherConfigLib {
return this;
}
+ /**
+ * Adds a new category.
+ * To create a category you need to use {@link ConfigCategory#createBuilder()}
+ *
+ * @see YetAnotherConfigLib#categories()
+ */
public Builder category(@NotNull ConfigCategory category) {
Validate.notNull(category, "`category` cannot be null");
@@ -53,6 +88,24 @@ public interface YetAnotherConfigLib {
return this;
}
+ /**
+ * Adds multiple categories at once.
+ * To create a category you need to use {@link ConfigCategory#createBuilder()}
+ *
+ * @see YetAnotherConfigLib#categories()
+ */
+ public Builder categories(@NotNull Collection<ConfigCategory> categories) {
+ Validate.notEmpty(categories, "`categories` cannot be empty");
+
+ this.categories.addAll(categories);
+ return this;
+ }
+
+ /**
+ * Used to define a save function for when user clicks the Save Changes button
+ *
+ * @see YetAnotherConfigLib#saveFunction()
+ */
public Builder save(@NotNull Runnable saveFunction) {
Validate.notNull(saveFunction, "`saveFunction` cannot be null");
@@ -60,6 +113,11 @@ public interface YetAnotherConfigLib {
return this;
}
+ /**
+ * Defines a consumer that is accepted every time the YACL screen initialises
+ *
+ * @see YetAnotherConfigLib#initConsumer()
+ */
public Builder screenInit(@NotNull Consumer<YACLScreen> initConsumer) {
Validate.notNull(initConsumer, "`initConsumer` cannot be null");
diff --git a/src/main/java/dev/isxander/yacl/api/utils/OptionUtils.java b/src/main/java/dev/isxander/yacl/api/utils/OptionUtils.java
index ed51683..ab46b5b 100644
--- a/src/main/java/dev/isxander/yacl/api/utils/OptionUtils.java
+++ b/src/main/java/dev/isxander/yacl/api/utils/OptionUtils.java
@@ -9,20 +9,29 @@ import java.util.function.Consumer;
import java.util.function.Function;
public class OptionUtils {
+ /**
+ * Consumes all options, ignoring groups and categories.
+ * When consumer returns true, this function stops iterating.
+ */
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;
+ if (consumer.apply(option)) return;
}
}
}
}
+ /**
+ * Consumes all options, ignoring groups and categories.
+ *
+ * @see OptionUtils#consumeOptions(YetAnotherConfigLib, Function)
+ */
public static void forEachOptions(YetAnotherConfigLib yacl, Consumer<Option<?>> consumer) {
consumeOptions(yacl, (opt) -> {
consumer.accept(opt);
- return true;
+ return false;
});
}
}