aboutsummaryrefslogtreecommitdiff
path: root/common/src/main/java/dev/isxander/yacl/gui
diff options
context:
space:
mode:
Diffstat (limited to 'common/src/main/java/dev/isxander/yacl/gui')
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/AbstractWidget.java94
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/DescriptionWithName.java11
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/ElementListWidgetExt.java222
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/ImageRenderer.java386
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/LowProfileButtonWidget.java29
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/OptionDescriptionWidget.java215
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/OptionListWidget.java572
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/RequireRestartScreen.java21
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/SearchFieldWidget.java62
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/TextScaledButtonWidget.java34
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/TooltipButtonWidget.java25
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/YACLScreen.java358
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/YACLTooltipPositioner.java48
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/controllers/ActionController.java120
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/controllers/BooleanController.java157
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/controllers/ColorController.java220
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/controllers/ControllerWidget.java157
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/controllers/LabelController.java194
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/controllers/ListEntryWidget.java129
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/controllers/TickBoxController.java120
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/controllers/cycling/CyclingControllerElement.java60
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/controllers/cycling/CyclingListController.java79
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/controllers/cycling/EnumController.java43
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/controllers/cycling/ICyclingController.java38
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/controllers/package-info.java12
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/controllers/slider/DoubleSliderController.java114
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/controllers/slider/FloatSliderController.java114
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/controllers/slider/ISliderController.java54
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/controllers/slider/IntegerSliderController.java111
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/controllers/slider/LongSliderController.java111
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/controllers/slider/SliderControllerElement.java158
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/controllers/slider/package-info.java10
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/controllers/string/IStringController.java44
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/controllers/string/StringController.java37
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/controllers/string/StringControllerElement.java404
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/controllers/string/number/DoubleFieldController.java104
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/controllers/string/number/FloatFieldController.java104
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/controllers/string/number/IntegerFieldController.java109
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/controllers/string/number/LongFieldController.java109
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/controllers/string/number/NumberFieldController.java69
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/controllers/string/number/package-info.java10
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/tab/ListHolderWidget.java116
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/tab/ScrollableNavigationBar.java110
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/tab/TabExt.java9
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/utils/GuiUtils.java32
45 files changed, 0 insertions, 5335 deletions
diff --git a/common/src/main/java/dev/isxander/yacl/gui/AbstractWidget.java b/common/src/main/java/dev/isxander/yacl/gui/AbstractWidget.java
deleted file mode 100644
index 06a6e23..0000000
--- a/common/src/main/java/dev/isxander/yacl/gui/AbstractWidget.java
+++ /dev/null
@@ -1,94 +0,0 @@
-package dev.isxander.yacl.gui;
-
-import dev.isxander.yacl.api.utils.Dimension;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.Font;
-import net.minecraft.client.gui.GuiGraphics;
-import net.minecraft.client.gui.components.Renderable;
-import net.minecraft.client.gui.components.events.GuiEventListener;
-import net.minecraft.client.gui.narration.NarratableEntry;
-import net.minecraft.client.gui.narration.NarrationElementOutput;
-import net.minecraft.client.resources.sounds.SimpleSoundInstance;
-import net.minecraft.sounds.SoundEvents;
-
-import java.awt.*;
-
-public abstract class AbstractWidget implements GuiEventListener, Renderable, NarratableEntry {
- protected final Minecraft client = Minecraft.getInstance();
- protected final Font textRenderer = client.font;
- protected final int inactiveColor = 0xFFA0A0A0;
-
- private Dimension<Integer> dim;
-
- public AbstractWidget(Dimension<Integer> dim) {
- this.dim = dim;
- }
-
- public boolean canReset() {
- return false;
- }
-
- @Override
- public boolean isMouseOver(double mouseX, double mouseY) {
- if (dim == null) return false;
- return this.dim.isPointInside((int) mouseX, (int) mouseY);
- }
-
- public void setDimension(Dimension<Integer> dim) {
- this.dim = dim;
- }
-
- public Dimension<Integer> getDimension() {
- return dim;
- }
-
- @Override
- public NarrationPriority narrationPriority() {
- return NarrationPriority.NONE;
- }
-
- public void unfocus() {
-
- }
-
- public boolean matchesSearch(String query) {
- return true;
- }
-
- @Override
- public void updateNarration(NarrationElementOutput builder) {
-
- }
-
- protected void drawButtonRect(GuiGraphics graphics, int x1, int y1, int x2, int y2, boolean hovered, boolean enabled) {
- if (x1 > x2) {
- int xx1 = x1;
- x1 = x2;
- x2 = xx1;
- }
- if (y1 > y2) {
- int yy1 = y1;
- y1 = y2;
- y2 = yy1;
- }
- int width = x2 - x1;
- int height = y2 - y1;
-
- int i = !enabled ? 0 : hovered ? 2 : 1;
- graphics.blit(net.minecraft.client.gui.components.AbstractWidget.WIDGETS_LOCATION, x1, y1, 0, 0, 46 + i * 20, width / 2, height, 256, 256);
- graphics.blit(net.minecraft.client.gui.components.AbstractWidget.WIDGETS_LOCATION, x1 + width / 2, y1, 0, 200 - width / 2f, 46 + i * 20, width / 2, height, 256, 256);
- }
-
- protected int multiplyColor(int hex, float amount) {
- Color color = new Color(hex, true);
-
- return new Color(Math.max((int)(color.getRed() * amount), 0),
- Math.max((int)(color.getGreen() * amount), 0),
- Math.max((int)(color.getBlue() * amount), 0),
- color.getAlpha()).getRGB();
- }
-
- public void playDownSound() {
- Minecraft.getInstance().getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F));
- }
-}
diff --git a/common/src/main/java/dev/isxander/yacl/gui/DescriptionWithName.java b/common/src/main/java/dev/isxander/yacl/gui/DescriptionWithName.java
deleted file mode 100644
index c29e0ca..0000000
--- a/common/src/main/java/dev/isxander/yacl/gui/DescriptionWithName.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package dev.isxander.yacl.gui;
-
-import dev.isxander.yacl.api.OptionDescription;
-import net.minecraft.ChatFormatting;
-import net.minecraft.network.chat.Component;
-
-public record DescriptionWithName(Component name, OptionDescription description) {
- public static DescriptionWithName of(Component name, OptionDescription description) {
- return new DescriptionWithName(name.copy().withStyle(ChatFormatting.BOLD), description);
- }
-}
diff --git a/common/src/main/java/dev/isxander/yacl/gui/ElementListWidgetExt.java b/common/src/main/java/dev/isxander/yacl/gui/ElementListWidgetExt.java
deleted file mode 100644
index 6b3ab1c..0000000
--- a/common/src/main/java/dev/isxander/yacl/gui/ElementListWidgetExt.java
+++ /dev/null
@@ -1,222 +0,0 @@
-package dev.isxander.yacl.gui;
-
-import com.mojang.blaze3d.platform.InputConstants;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.GuiGraphics;
-import net.minecraft.client.gui.components.AbstractWidget;
-import net.minecraft.client.gui.components.ContainerObjectSelectionList;
-import net.minecraft.client.gui.components.events.GuiEventListener;
-import net.minecraft.client.gui.layouts.LayoutElement;
-import net.minecraft.client.gui.navigation.ScreenRectangle;
-import net.minecraft.util.Mth;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.function.Consumer;
-
-public class ElementListWidgetExt<E extends ElementListWidgetExt.Entry<E>> extends ContainerObjectSelectionList<E> implements LayoutElement {
- protected int x, y;
-
- private double smoothScrollAmount = getScrollAmount();
- private boolean returnSmoothAmount = false;
- private final boolean doSmoothScrolling;
-
- public ElementListWidgetExt(Minecraft client, int x, int y, int width, int height, boolean smoothScrolling) {
- super(client, width, height, y, y + height, 22);
- this.x = this.x0 = x;
- this.y = y;
- this.x1 = this.x0 + width;
- this.doSmoothScrolling = smoothScrolling;
- }
-
- @Override
- public boolean mouseScrolled(double mouseX, double mouseY, double amount) {
- // default implementation bases scroll step from total height of entries, this is constant
- this.setScrollAmount(this.getScrollAmount() - amount * 20);
- return true;
- }
-
- @Override
- protected void renderBackground(GuiGraphics graphics) {
- // render transparent background if in-game.
- setRenderBackground(true);
- setRenderTopAndBottom(false);
- }
-
- @Override
- protected int getScrollbarPosition() {
- // default implementation does not respect left/right
- return this.x1 - 2;
- }
-
- @Override
- public void render(GuiGraphics graphics, int mouseX, int mouseY, float delta) {
- smoothScrollAmount = Mth.lerp(Minecraft.getInstance().getDeltaFrameTime() * 0.5, smoothScrollAmount, getScrollAmount());
- returnSmoothAmount = true;
-
- graphics.enableScissor(x0, y0, x1, y1);
-
- super.render(graphics, mouseX, mouseY, delta);
-
- graphics.disableScissor();
-
- returnSmoothAmount = false;
- }
-
- public void updateDimensions(ScreenRectangle rectangle) {
- this.x0 = rectangle.left();
- this.y0 = rectangle.top();
- this.x1 = rectangle.right();
- this.y1 = rectangle.bottom();
- this.width = rectangle.width();
- this.height = rectangle.height();
- }
-
- /**
- * awful code to only use smooth scroll state when rendering,
- * not other code that needs target scroll amount
- */
- @Override
- public double getScrollAmount() {
- if (returnSmoothAmount && doSmoothScrolling)
- return smoothScrollAmount;
-
- return super.getScrollAmount();
- }
-
- protected void resetSmoothScrolling() {
- this.smoothScrollAmount = getScrollAmount();
- }
-
- @Nullable
- @Override
- protected E getEntryAtPosition(double x, double y) {
- y += getScrollAmount();
-
- if (x < this.x0 || x > this.x1)
- return null;
-
- int currentY = this.y0 - headerHeight + 4;
- for (E entry : children()) {
- if (y >= currentY && y <= currentY + entry.getItemHeight()) {
- return entry;
- }
-
- currentY += entry.getItemHeight();
- }
-
- return null;
- }
-
- /*
- below code is licensed from cloth-config under LGPL3
- modified to inherit vanilla's EntryListWidget and use yarn mappings
-
- code is responsible for having dynamic item heights
- */
-
- @Override
- protected int getMaxPosition() {
- return children().stream().map(E::getItemHeight).reduce(0, Integer::sum) + headerHeight;
- }
-
- @Override
- protected void centerScrollOn(E entry) {
- double d = (this.height) / -2d;
- for (int i = 0; i < this.children().indexOf(entry) && i < this.getItemCount(); i++)
- d += children().get(i).getItemHeight();
- this.setScrollAmount(d);
- }
-
- @Override
- protected int getRowTop(int index) {
- int integer = y0 + 4 - (int) this.getScrollAmount() + headerHeight;
- for (int i = 0; i < children().size() && i < index; i++)
- integer += children().get(i).getItemHeight();
- return integer;
- }
-
- @Override
- protected void renderList(GuiGraphics graphics, int mouseX, int mouseY, float delta) {
- int left = this.getRowLeft();
- int right = this.getRowWidth();
- int count = this.getItemCount();
-
- for(int i = 0; i < count; ++i) {
- E entry = children().get(i);
- int top = this.getRowTop(i);
- int bottom = top + entry.getItemHeight();
- int entryHeight = entry.getItemHeight() - 4;
- if (bottom >= this.y0 && top <= this.y1) {
- this.renderItem(graphics, mouseX, mouseY, delta, i, left, top, right, entryHeight);
- }
- }
- }
-
- /* END cloth config code */
-
- @Override
- public void setX(int i) {
- this.x = x0 = i;
- this.x1 = x0 + width;
- }
-
- @Override
- public void setY(int i) {
- this.y = y0 = i;
- this.y1 = y0 + height;
- }
-
- @Override
- public int getX() {
- return x;
- }
-
- @Override
- public int getY() {
- return y;
- }
-
- @Override
- public int getWidth() {
- return width;
- }
-
- @Override
- public int getHeight() {
- return height;
- }
-
- @Override
- public void visitWidgets(Consumer<AbstractWidget> consumer) {
- }
-
- public abstract static class Entry<E extends Entry<E>> extends ContainerObjectSelectionList.Entry<E> {
- @Override
- public boolean mouseClicked(double mouseX, double mouseY, int button) {
- for (GuiEventListener child : this.children()) {
- if (child.mouseClicked(mouseX, mouseY, button)) {
- if (button == InputConstants.MOUSE_BUTTON_LEFT)
- this.setDragging(true);
- return true;
- }
- }
-
- return false;
- }
-
- @Override
- public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) {
- if (isDragging() && button == InputConstants.MOUSE_BUTTON_LEFT) {
- for (GuiEventListener child : this.children()) {
- if (child.mouseDragged(mouseX, mouseY, button, deltaX, deltaY))
- return true;
- }
- }
- return false;
- }
-
- public int getItemHeight() {
- return 22;
- }
- }
-}
diff --git a/common/src/main/java/dev/isxander/yacl/gui/ImageRenderer.java b/common/src/main/java/dev/isxander/yacl/gui/ImageRenderer.java
deleted file mode 100644
index 7389232..0000000
--- a/common/src/main/java/dev/isxander/yacl/gui/ImageRenderer.java
+++ /dev/null
@@ -1,386 +0,0 @@
-package dev.isxander.yacl.gui;
-
-import com.mojang.blaze3d.Blaze3D;
-import com.mojang.blaze3d.platform.NativeImage;
-import com.twelvemonkeys.imageio.plugins.webp.WebPImageReaderSpi;
-import dev.isxander.yacl.impl.utils.YACLConstants;
-import net.minecraft.CrashReport;
-import net.minecraft.CrashReportCategory;
-import net.minecraft.ReportedException;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.GuiGraphics;
-import net.minecraft.client.renderer.texture.DynamicTexture;
-import net.minecraft.client.renderer.texture.TextureManager;
-import net.minecraft.resources.ResourceLocation;
-import net.minecraft.server.packs.resources.Resource;
-import net.minecraft.server.packs.resources.ResourceManager;
-import net.minecraft.util.FastColor;
-
-import javax.imageio.ImageIO;
-import javax.imageio.ImageReader;
-import javax.imageio.metadata.IIOMetadata;
-import javax.imageio.metadata.IIOMetadataNode;
-import java.awt.*;
-import java.awt.image.BufferedImage;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.Field;
-import java.nio.file.Path;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.Supplier;
-import java.util.stream.IntStream;
-
-public interface ImageRenderer {
- int render(GuiGraphics graphics, int x, int y, int renderWidth);
-
- void close();
-
- Map<ResourceLocation, CompletableFuture<Optional<ImageRenderer>>> CACHE = new ConcurrentHashMap<>();
-
- static CompletableFuture<Optional<ImageRenderer>> getOrMakeAsync(ResourceLocation id, Supplier<Optional<ImageRenderer>> factory) {
- return CACHE.computeIfAbsent(id, key -> CompletableFuture.supplyAsync(factory, YACLConstants.SINGLE_THREAD_EXECUTOR));
- }
-
- static CompletableFuture<Optional<ImageRenderer>> getOrMakeSync(ResourceLocation id, Supplier<Optional<ImageRenderer>> factory) {
- return CACHE.computeIfAbsent(id, key -> CompletableFuture.completedFuture(factory.get()));
- }
-
- static void closeAll() {
- CACHE.values().forEach(future -> future.thenAccept(opt -> opt.ifPresent(ImageRenderer::close)));
- CACHE.clear();
- }
-
- class TextureBacked implements ImageRenderer {
- private final ResourceLocation location;
- private final int width, height;
- private final int textureWidth, textureHeight;
- private final float u, v;
-
- public TextureBacked(ResourceLocation location, float u, float v, int width, int height, int textureWidth, int textureHeight) {
- this.location = location;
- this.width = width;
- this.height = height;
- this.textureWidth = textureWidth;
- this.textureHeight = textureHeight;
- this.u = u;
- this.v = v;
- }
-
- @Override
- public int render(GuiGraphics graphics, int x, int y, int renderWidth) {
- float ratio = renderWidth / (float)this.width;
- int targetHeight = (int) (this.height * ratio);
-
- graphics.pose().pushPose();
- graphics.pose().translate(x, y, 0);
- graphics.pose().scale(ratio, ratio, 1);
- graphics.blit(location, 0, 0, this.u, this.v, this.width, this.height, this.textureWidth, this.textureHeight);
- graphics.pose().popPose();
-
- return targetHeight;
- }
-
- @Override
- public void close() {
-
- }
- }
-
- class NativeImageBacked implements ImageRenderer {
- protected static final TextureManager textureManager = Minecraft.getInstance().getTextureManager();
-
- protected NativeImage image;
- protected DynamicTexture texture;
- protected final ResourceLocation uniqueLocation;
- protected final int width, height;
-
- public NativeImageBacked(NativeImage image, ResourceLocation uniqueLocation) {
- this.image = image;
- this.texture = new DynamicTexture(image);
- this.uniqueLocation = uniqueLocation;
- textureManager.register(this.uniqueLocation, this.texture);
- this.width = image.getWidth();
- this.height = image.getHeight();
- }
-
- private NativeImageBacked(Path imagePath, ResourceLocation uniqueLocation) throws IOException {
- this.uniqueLocation = uniqueLocation;
- this.image = NativeImage.read(new FileInputStream(imagePath.toFile()));
- this.width = image.getWidth();
- this.height = image.getHeight();
- this.texture = new DynamicTexture(image);
- textureManager.register(this.uniqueLocation, this.texture);
- }
-
- public static Optional<ImageRenderer> createFromPath(Path path, ResourceLocation uniqueLocation) {
- try {
- return Optional.of(new NativeImageBacked(path, uniqueLocation));
- } catch (IOException e) {
- e.printStackTrace();
- return Optional.empty();
- }
- }
-
- @Override
- public int render(GuiGraphics graphics, int x, int y, int renderWidth) {
- if (image == null) return 0;
-
- float ratio = renderWidth / (float)this.width;
- int targetHeight = (int) (this.height * ratio);
-
- graphics.pose().pushPose();
- graphics.pose().translate(x, y, 0);
- graphics.pose().scale(ratio, ratio, 1);
- graphics.blit(uniqueLocation, 0, 0, 0, 0, this.width, this.height, this.width, this.height);
- graphics.pose().popPose();
-
- return targetHeight;
- }
-
- @Override
- public void close() {
- image.close();
- image = null;
- texture = null;
- textureManager.release(uniqueLocation);
- }
- }
-
- class AnimatedNativeImageBacked extends NativeImageBacked {
- private int currentFrame;
- private double lastFrameTime;
-
- private final double[] frameDelays;
- private final int frameCount;
-
- private final int packCols, packRows;
- private final int frameWidth, frameHeight;
-
- public AnimatedNativeImageBacked(NativeImage image, int frameWidth, int frameHeight, int frameCount, double[] frameDelayMS, int packCols, int packRows, ResourceLocation uniqueLocation) {
- super(image, uniqueLocation);
- this.frameWidth = frameWidth;
- this.frameHeight = frameHeight;
- this.frameCount = frameCount;
- this.frameDelays = frameDelayMS;
- this.packCols = packCols;
- this.packRows = packRows;
- }
-
- public static AnimatedNativeImageBacked createGIFFromTexture(ResourceLocation textureLocation) throws IOException {
- ResourceManager resourceManager = Minecraft.getInstance().getResourceManager();
- Resource resource = resourceManager.getResource(textureLocation).orElseThrow();
-
- return createGIF(resource.open(), textureLocation);
- }
-
- public static AnimatedNativeImageBacked createWEBPFromTexture(ResourceLocation textureLocation) throws IOException {
- ResourceManager resourceManager = Minecraft.getInstance().getResourceManager();
- Resource resource = resourceManager.getResource(textureLocation).orElseThrow();
-
- return createWEBP(resource.open(), textureLocation);
- }
-
- public static AnimatedNativeImageBacked createGIF(InputStream is, ResourceLocation uniqueLocation) {
- try (is) {
- ImageReader reader = ImageIO.getImageReadersBySuffix("gif").next();
- reader.setInput(ImageIO.createImageInputStream(is));
-
-
-
- AnimFrameProvider animFrameFunction = i -> {
- IIOMetadata metadata = reader.getImageMetadata(i);
- String metaFormatName = metadata.getNativeMetadataFormatName();
- IIOMetadataNode root = (IIOMetadataNode) metadata.getAsTree(metaFormatName);
- IIOMetadataNode graphicsControlExtensionNode = (IIOMetadataNode) root.getElementsByTagName("GraphicControlExtension").item(0);
- int delay = Integer.parseInt(graphicsControlExtensionNode.getAttribute("delayTime")) * 10;
-
- return new AnimFrame(delay, 0, 0);
- };
-
- return createFromImageReader(reader, animFrameFunction, uniqueLocation);
- } catch (Exception e) {
- CrashReport crashReport = CrashReport.forThrowable(e, "Failed to load GIF image");
- CrashReportCategory category = crashReport.addCategory("YACL Gui");
- category.setDetail("Image identifier", uniqueLocation.toString());
- throw new ReportedException(crashReport);
- }
- }
-
- public static AnimatedNativeImageBacked createWEBP(InputStream is, ResourceLocation uniqueLocation) {
- try (is) {
- ImageReader reader = new WebPImageReaderSpi().createReaderInstance();
- reader.setInput(ImageIO.createImageInputStream(is));
-
- int numImages = reader.getNumImages(true); // Force reading of all frames
- AnimFrameProvider animFrameFunction = i -> null;
- if (numImages > 1) {
- // WebP reader does not expose frame delay, prepare for reflection hell
- Class<?> webpReaderClass = Class.forName("com.twelvemonkeys.imageio.plugins.webp.WebPImageReader");
- Field framesField = webpReaderClass.getDeclaredField("frames");
- framesField.setAccessible(true);
- List<?> frames = (List<?>) framesField.get(reader);
-
- Class<?> animationFrameClass = Class.forName("com.twelvemonkeys.imageio.plugins.webp.AnimationFrame");
- Field durationField = animationFrameClass.getDeclaredField("duration");
- durationField.setAccessible(true);
- Field boundsField = a