From 13c7ba45ff201423eb8dba8a40cfb66ebb531439 Mon Sep 17 00:00:00 2001 From: Xander Date: Tue, 25 Apr 2023 16:28:41 +0100 Subject: Architectury! (#61) --- .../main/java/dev/isxander/yacl/api/Option.java | 227 +++++++++++++++++++++ 1 file changed, 227 insertions(+) create mode 100644 common/src/main/java/dev/isxander/yacl/api/Option.java (limited to 'common/src/main/java/dev/isxander/yacl/api/Option.java') diff --git a/common/src/main/java/dev/isxander/yacl/api/Option.java b/common/src/main/java/dev/isxander/yacl/api/Option.java new file mode 100644 index 0000000..a6c0311 --- /dev/null +++ b/common/src/main/java/dev/isxander/yacl/api/Option.java @@ -0,0 +1,227 @@ +package dev.isxander.yacl.api; + +import com.google.common.collect.ImmutableSet; +import dev.isxander.yacl.impl.OptionImpl; +import net.minecraft.network.chat.Component; +import org.jetbrains.annotations.NotNull; + +import java.util.*; +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Supplier; + +public interface Option { + /** + * Name of the option + */ + @NotNull Component name(); + + /** + * Tooltip (or description) of the option. + * Rendered on hover. + */ + @NotNull Component tooltip(); + + /** + * Widget provider for a type of option. + * + * @see dev.isxander.yacl.gui.controllers + */ + @NotNull Controller controller(); + + /** + * Binding for the option. + * Controls setting, getting and default value. + * + * @see Binding + */ + @NotNull Binding binding(); + + /** + * If the option can be configured + */ + boolean available(); + + /** + * Sets if the option can be configured after being built + * + * @see Option#available() + */ + void setAvailable(boolean available); + + /** + * Class of the option type. + * Used by some controllers. + */ + @NotNull Class typeClass(); + + /** + * Tasks that needs to be executed upon applying changes. + */ + @NotNull ImmutableSet flags(); + + /** + * Checks if the pending value is not equal to the current set value + */ + boolean changed(); + + /** + * 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. + * + * @return if there were changes to apply {@link Option#changed()} + */ + boolean applyValue(); + + /** + * Sets the pending value to the bound value. + */ + void forgetPendingValue(); + + /** + * Sets the pending value to the default bound value. + */ + void requestSetDefault(); + + /** + * Checks if the current pending value is equal to its default value + */ + boolean isPendingValueDefault(); + + default boolean canResetToDefault() { + return true; + } + + /** + * Adds a listener for when the pending value changes + */ + void addListener(BiConsumer, T> changedListener); + + /** + * Creates a builder to construct an {@link Option} + * + * @param type of the option's value + * @param typeClass used to capture the type + */ + static Builder createBuilder(Class typeClass) { + return new OptionImpl.BuilderImpl<>(typeClass); + } + + interface Builder { + /** + * Sets the name to be used by the option. + * + * @see Option#name() + */ + Builder name(@NotNull Component name); + + /** + * Sets the tooltip to be used by the option. + * No need to wrap the text yourself, the gui does this itself. + * + * @param tooltipGetter function to get tooltip depending on value {@link Builder#build()}. + */ + Builder tooltip(@NotNull Function tooltipGetter); + + /** + * Sets the tooltip to be used by the option. + * No need to wrap the text yourself, the gui does this itself. + * + * @param tooltipGetter function to get tooltip depending on value {@link Builder#build()}. + */ + @Deprecated + Builder tooltip(@NotNull Function... tooltipGetter); + + /** + * 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()}. + */ + Builder tooltip(@NotNull Component... tooltips); + + /** + * Sets the controller for the option. + * This is how you interact and change the options. + * + * @see dev.isxander.yacl.gui.controllers + */ + Builder controller(@NotNull Function, Controller> control); + + /** + * Sets the binding for the option. + * Used for default, getter and setter. + * + * @see Binding + */ + Builder binding(@NotNull Binding binding); + + /** + * Sets the binding for the option. + * Shorthand of {@link Binding#generic(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 + */ + Builder binding(@NotNull T def, @NotNull Supplier<@NotNull T> getter, @NotNull Consumer<@NotNull T> setter); + + /** + * Sets if the option can be configured + * + * @see Option#available() + */ + Builder available(boolean available); + + /** + * Adds a flag to the option. + * Upon applying changes, all flags are executed. + * {@link Option#flags()} + */ + Builder flag(@NotNull OptionFlag... flag); + + /** + * Adds a flag to the option. + * Upon applying changes, all flags are executed. + * {@link Option#flags()} + */ + Builder flags(@NotNull Collection flags); + + /** + * Instantly invokes the binder's setter when modified in the GUI. + * Prevents the user from undoing the change + *

+ * Does not support {@link Option#flags()}! + */ + Builder instant(boolean instant); + + /** + * Adds a listener to the option. Invoked upon changing the pending value. + * + * @see Option#addListener(BiConsumer) + */ + Builder listener(@NotNull BiConsumer, T> listener); + + /** + * Adds multiple listeners to the option. Invoked upon changing the pending value. + * + * @see Option#addListener(BiConsumer) + */ + Builder listeners(@NotNull Collection, T>> listeners); + + Option build(); + } +} -- cgit