aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorisXander <xander@isxander.dev>2023-08-16 13:26:25 +0100
committerisXander <xander@isxander.dev>2023-08-16 13:26:25 +0100
commit5676db9905c774c9b65fcd92fdad39049b9b3fcc (patch)
tree20dc03e7b4e2bd734cf7e95c067bbd078c1749f2
parent98f29ec5c30d23999fce37d7daf7aba8f10f25d3 (diff)
downloadYetAnotherConfigLib-5676db9905c774c9b65fcd92fdad39049b9b3fcc.tar.gz
YetAnotherConfigLib-5676db9905c774c9b65fcd92fdad39049b9b3fcc.tar.bz2
YetAnotherConfigLib-5676db9905c774c9b65fcd92fdad39049b9b3fcc.zip
Add @OverrideImage
-rw-r--r--common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/OverrideImage.java27
-rw-r--r--common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/SimpleOptionFactory.java45
-rw-r--r--common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/AutoGenUtils.java13
-rw-r--r--common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/EmptyCustomImageFactory.java17
4 files changed, 97 insertions, 5 deletions
diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/OverrideImage.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/OverrideImage.java
new file mode 100644
index 0000000..649121a
--- /dev/null
+++ b/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/OverrideImage.java
@@ -0,0 +1,27 @@
+package dev.isxander.yacl3.config.v2.api.autogen;
+
+import dev.isxander.yacl3.config.v2.api.ConfigField;
+import dev.isxander.yacl3.config.v2.impl.autogen.EmptyCustomImageFactory;
+import dev.isxander.yacl3.gui.ImageRenderer;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface OverrideImage {
+ String value() default "";
+
+ int width() default 0;
+ int height() default 0;
+
+ Class<? extends CustomImageFactory<?>> factory() default EmptyCustomImageFactory.class;
+
+ interface CustomImageFactory<T> {
+ CompletableFuture<Optional<ImageRenderer>> createImage(T value, ConfigField<T> field, OptionAccess access);
+ }
+}
diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/SimpleOptionFactory.java b/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/SimpleOptionFactory.java
index bf886ae..0ab6369 100644
--- a/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/SimpleOptionFactory.java
+++ b/common/src/main/java/dev/isxander/yacl3/config/v2/api/autogen/SimpleOptionFactory.java
@@ -7,6 +7,8 @@ import dev.isxander.yacl3.api.controller.ControllerBuilder;
import dev.isxander.yacl3.config.v2.api.ConfigField;
import dev.isxander.yacl3.config.v2.impl.FieldBackedBinding;
import dev.isxander.yacl3.config.v2.impl.autogen.AutoGenUtils;
+import dev.isxander.yacl3.config.v2.impl.autogen.EmptyCustomImageFactory;
+import dev.isxander.yacl3.config.v2.impl.autogen.YACLAutoGenException;
import net.minecraft.client.Minecraft;
import net.minecraft.locale.Language;
import net.minecraft.network.chat.Component;
@@ -63,11 +65,44 @@ public abstract class SimpleOptionFactory<A extends Annotation, T> implements Op
}
}
- String imagePath = "textures/yacl3/" + field.parent().id().getPath() + "/" + field.access().name() + ".webp";
- imagePath = imagePath.toLowerCase().replaceAll("[^a-z0-9/._:-]", "_");
- ResourceLocation imageLocation = new ResourceLocation(field.parent().id().getNamespace(), imagePath);
- if (Minecraft.getInstance().getResourceManager().getResource(imageLocation).isPresent()) {
- builder.webpImage(imageLocation);
+ Optional<OverrideImage> imageOverrideOpt = field.access().getAnnotation(OverrideImage.class);
+ if (imageOverrideOpt.isPresent()) {
+ OverrideImage imageOverride = imageOverrideOpt.get();
+
+ if (!imageOverride.factory().equals(EmptyCustomImageFactory.class)) {
+ OverrideImage.CustomImageFactory<T> imageFactory;
+ try {
+ imageFactory = (OverrideImage.CustomImageFactory<T>) AutoGenUtils.constructNoArgsClass(
+ imageOverride.factory(),
+ () -> "'%s': The factory class on @OverrideImage has no no-args constructor.".formatted(field.access().name()),
+ () -> "'%s': Failed to instantiate factory class %s.".formatted(field.access().name(), imageOverride.factory().getName())
+ );
+ } catch (ClassCastException e) {
+ throw new YACLAutoGenException("'%s': The factory class on @OverrideImage is of incorrect type. Expected %s, got %s.".formatted(field.access().name(), field.access().type().getTypeName(), imageOverride.factory().getTypeParameters()[0].getName()));
+ }
+
+ builder.customImage(imageFactory.createImage(value, field, storage));
+ } else if (!imageOverride.value().isEmpty()) {
+ String path = imageOverride.value();
+ ResourceLocation imageLocation = new ResourceLocation(field.parent().id().getNamespace(), path);
+ String extension = path.substring(path.lastIndexOf('.') + 1);
+
+ switch (extension) {
+ case "png", "jpg", "jpeg" -> builder.image(imageLocation, imageOverride.width(), imageOverride.height());
+ case "webp" -> builder.webpImage(imageLocation);
+ case "gif" -> builder.gifImage(imageLocation);
+ default -> throw new YACLAutoGenException("'%s': Invalid image extension '%s' on @OverrideImage. Expected: ('png','jpg','webp','gif')".formatted(field.access().name(), extension));
+ }
+ } else {
+ throw new YACLAutoGenException("'%s': @OverrideImage has no value or factory class.".formatted(field.access().name()));
+ }
+ } else {
+ String imagePath = "textures/yacl3/" + field.parent().id().getPath() + "/" + field.access().name() + ".webp";
+ imagePath = imagePath.toLowerCase().replaceAll("[^a-z0-9/._:-]", "_");
+ ResourceLocation imageLocation = new ResourceLocation(field.parent().id().getNamespace(), imagePath);
+ if (Minecraft.getInstance().getResourceManager().getResource(imageLocation).isPresent()) {
+ builder.webpImage(imageLocation);
+ }
}
return builder;
diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/AutoGenUtils.java b/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/AutoGenUtils.java
index ecd4157..6bde931 100644
--- a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/AutoGenUtils.java
+++ b/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/AutoGenUtils.java
@@ -8,6 +8,9 @@ import dev.isxander.yacl3.config.v2.api.autogen.OverrideFormatter;
import org.jetbrains.annotations.ApiStatus;
import java.util.Optional;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Supplier;
@ApiStatus.Internal
public final class AutoGenUtils {
@@ -31,4 +34,14 @@ public final class AutoGenUtils {
}
});
}
+
+ public static <T> T constructNoArgsClass(Class<T> clazz, Supplier<String> constructorNotFoundConsumer, Supplier<String> constructorFailedConsumer) {
+ try {
+ return clazz.getConstructor().newInstance();
+ } catch (NoSuchMethodException e) {
+ throw new YACLAutoGenException(constructorNotFoundConsumer.get(), e);
+ } catch (Exception e) {
+ throw new YACLAutoGenException(constructorFailedConsumer.get(), e);
+ }
+ }
}
diff --git a/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/EmptyCustomImageFactory.java b/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/EmptyCustomImageFactory.java
new file mode 100644
index 0000000..f6949e7
--- /dev/null
+++ b/common/src/main/java/dev/isxander/yacl3/config/v2/impl/autogen/EmptyCustomImageFactory.java
@@ -0,0 +1,17 @@
+package dev.isxander.yacl3.config.v2.impl.autogen;
+
+import dev.isxander.yacl3.config.v2.api.ConfigField;
+import dev.isxander.yacl3.config.v2.api.autogen.OptionAccess;
+import dev.isxander.yacl3.config.v2.api.autogen.OverrideImage;
+import dev.isxander.yacl3.gui.ImageRenderer;
+
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
+
+public class EmptyCustomImageFactory implements OverrideImage.CustomImageFactory<Object> {
+
+ @Override
+ public CompletableFuture<Optional<ImageRenderer>> createImage(Object value, ConfigField<Object> field, OptionAccess access) {
+ throw new IllegalStateException();
+ }
+}