diff options
Diffstat (limited to 'common/src/main/java/dev/isxander/yacl/gui')
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 |
