diff options
Diffstat (limited to 'common/src/main/java/dev/isxander/yacl/gui')
4 files changed, 68 insertions, 47 deletions
diff --git a/common/src/main/java/dev/isxander/yacl/gui/DescriptionWithName.java b/common/src/main/java/dev/isxander/yacl/gui/DescriptionWithName.java new file mode 100644 index 0000000..c29e0ca --- /dev/null +++ b/common/src/main/java/dev/isxander/yacl/gui/DescriptionWithName.java @@ -0,0 +1,11 @@ +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/ImageRenderer.java b/common/src/main/java/dev/isxander/yacl/gui/ImageRenderer.java index 1c9ac2e..26aacb7 100644 --- a/common/src/main/java/dev/isxander/yacl/gui/ImageRenderer.java +++ b/common/src/main/java/dev/isxander/yacl/gui/ImageRenderer.java @@ -53,11 +53,17 @@ public interface ImageRenderer { 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, int width, int height) { + 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 @@ -68,7 +74,7 @@ public interface ImageRenderer { graphics.pose().pushPose(); graphics.pose().translate(x, y, 0); graphics.pose().scale(ratio, ratio, 1); - graphics.blit(location, 0, 0, 0, 0, this.width, this.height, this.width, this.height); + graphics.blit(location, 0, 0, this.u, this.v, this.width, this.height, this.textureWidth, this.textureHeight); graphics.pose().popPose(); return targetHeight; @@ -86,7 +92,7 @@ public interface ImageRenderer { protected NativeImage image; protected DynamicTexture texture; protected final ResourceLocation uniqueLocation; - protected int width, height; + protected final int width, height; public NativeImageBacked(NativeImage image, ResourceLocation uniqueLocation) { this.image = image; @@ -144,11 +150,11 @@ public interface ImageRenderer { private int currentFrame; private double lastFrameTime; - private double frameDelay; - private int frameCount; + private final double frameDelay; + private final int frameCount; - private int packCols, packRows; - private int frameWidth, frameHeight; + 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); @@ -196,24 +202,26 @@ public interface ImageRenderer { ImageReader reader = new WebPImageReaderSpi().createReaderInstance(); reader.setInput(ImageIO.createImageInputStream(is)); - // WebP reader does not expose frame delay, prepare for reflection hell - int frameDelayMS; - reader.getNumImages(true); // Force reading of all frames - try { - Class<?> webpReaderClass = Class.forName("com.twelvemonkeys.imageio.plugins.webp.WebPImageReader"); - Field framesField = webpReaderClass.getDeclaredField("frames"); - framesField.setAccessible(true); - List<?> frames = (List<?>) framesField.get(reader); - Object firstFrame = frames.get(0); - - Class<?> animationFrameClass = Class.forName("com.twelvemonkeys.imageio.plugins.webp.AnimationFrame"); - Field durationField = animationFrameClass.getDeclaredField("duration"); - durationField.setAccessible(true); - frameDelayMS = (int) durationField.get(firstFrame); - } catch (ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) { - throw new RuntimeException(e); + int frameDelayMS = 0; + int numImages = reader.getNumImages(true); // Force reading of all frames + if (numImages > 1) { + // WebP reader does not expose frame delay, prepare for reflection hell + try { + Class<?> webpReaderClass = Class.forName("com.twelvemonkeys.imageio.plugins.webp.WebPImageReader"); + Field framesField = webpReaderClass.getDeclaredField("frames"); + framesField.setAccessible(true); + List<?> frames = (List<?>) framesField.get(reader); + Object firstFrame = frames.get(0); + + Class<?> animationFrameClass = Class.forName("com.twelvemonkeys.imageio.plugins.webp.AnimationFrame"); + Field durationField = animationFrameClass.getDeclaredField("duration"); + durationField.setAccessible(true); + frameDelayMS = (int) durationField.get(firstFrame); + } catch (ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) { + throw new RuntimeException(e); + } + // that was fun } - // that was fun return createFromImageReader(reader, frameDelayMS, uniqueLocation); } catch (IOException e) { @@ -301,13 +309,15 @@ public interface ImageRenderer { ); graphics.pose().popPose(); - double timeMS = Blaze3D.getTime() * 1000; - if (lastFrameTime == 0) lastFrameTime = timeMS; - if (timeMS - lastFrameTime >= frameDelay) { - currentFrame++; - lastFrameTime = timeMS; + if (frameCount > 1) { + double timeMS = Blaze3D.getTime() * 1000; + if (lastFrameTime == 0) lastFrameTime = timeMS; + if (timeMS - lastFrameTime >= frameDelay) { + currentFrame++; + lastFrameTime = timeMS; + } + if (currentFrame >= frameCount - 1) currentFrame = 0; } - if (currentFrame >= frameCount - 1) currentFrame = 0; return targetHeight; } diff --git a/common/src/main/java/dev/isxander/yacl/gui/OptionDescriptionWidget.java b/common/src/main/java/dev/isxander/yacl/gui/OptionDescriptionWidget.java index 5c346d0..4d86048 100644 --- a/common/src/main/java/dev/isxander/yacl/gui/OptionDescriptionWidget.java +++ b/common/src/main/java/dev/isxander/yacl/gui/OptionDescriptionWidget.java @@ -22,7 +22,7 @@ public class OptionDescriptionWidget extends AbstractWidget { private static final int AUTO_SCROLL_TIMER = 3000; private static final float AUTO_SCROLL_SPEED = 1; - private @Nullable OptionDescription description; + private @Nullable DescriptionWithName description; private List<FormattedCharSequence> wrappedText; private static final Minecraft minecraft = Minecraft.getInstance(); @@ -37,8 +37,8 @@ public class OptionDescriptionWidget extends AbstractWidget { private int lastInteractionTime; private boolean scrollingBackward; - public OptionDescriptionWidget(Supplier<ScreenRectangle> dimensions, @Nullable OptionDescription description) { - super(0, 0, 0, 0, description == null ? Component.empty() : description.descriptiveName()); + public OptionDescriptionWidget(Supplier<ScreenRectangle> dimensions, @Nullable DescriptionWithName description) { + super(0, 0, 0, 0, description == null ? Component.empty() : description.name()); this.dimensions = dimensions; this.setOptionDescription(description); } @@ -57,11 +57,11 @@ public class OptionDescriptionWidget extends AbstractWidget { int y = getY(); - int nameWidth = font.width(description.descriptiveName()); + int nameWidth = font.width(description.name()); if (nameWidth > getWidth()) { - renderScrollingString(graphics, font, description.descriptiveName(), getX(), y, getX() + getWidth(), y + font.lineHeight, -1); + renderScrollingString(graphics, font, description.name(), getX(), y, getX() + getWidth(), y + font.lineHeight, -1); } else { - graphics.drawString(font, description.descriptiveName(), getX(), y, 0xFFFFFF); + graphics.drawString(font, description.name(), getX(), y, 0xFFFFFF); } y += 5 + font.lineHeight; @@ -70,16 +70,16 @@ public class OptionDescriptionWidget extends AbstractWidget { y -= (int)currentScrollAmount; - if (description.image().isDone()) { - var image = description.image().join(); + if (description.description().image().isDone()) { + var image = description.description().image().join(); if (image.isPresent()) { image.get().render(graphics, getX(), y, getWidth()); y += image.get().render(graphics, getX(), y, getWidth()) + 5; } } - if (wrappedText == null && description.description() != null) - wrappedText = font.split(description.description(), getWidth()); + if (wrappedText == null) + wrappedText = font.split(description.description().description(), getWidth()); descriptionY = y; for (var line : wrappedText) { @@ -187,7 +187,7 @@ public class OptionDescriptionWidget extends AbstractWidget { } - public void setOptionDescription(OptionDescription description) { + public void setOptionDescription(DescriptionWithName description) { this.description = description; this.wrappedText = null; this.targetScrollAmount = 0; diff --git a/common/src/main/java/dev/isxander/yacl/gui/OptionListWidget.java b/common/src/main/java/dev/isxander/yacl/gui/OptionListWidget.java index 98272d1..fb49578 100644 --- a/common/src/main/java/dev/isxander/yacl/gui/OptionListWidget.java +++ b/common/src/main/java/dev/isxander/yacl/gui/OptionListWidget.java @@ -27,10 +27,10 @@ public class OptionListWidget extends ElementListWidgetExt<OptionListWidget.Entr private final ConfigCategory category; private ImmutableList<Entry> viewableChildren; private String searchQuery = ""; - private final Consumer<OptionDescription> hoverEvent; - private OptionDescription lastHoveredOption; + private final Consumer<DescriptionWithName> hoverEvent; + private DescriptionWithName lastHoveredOption; - public OptionListWidget(YACLScreen screen, ConfigCategory category, Minecraft client, int x, int y, int width, int height, Consumer<OptionDescription> hoverEvent) { + public OptionListWidget(YACLScreen screen, ConfigCategory category, Minecraft client, int x, int y, int width, int height, Consumer<DescriptionWithName> hoverEvent) { super(client, x, y, width, height, true); this.yaclScreen = screen; this.category = category; @@ -237,7 +237,7 @@ public class OptionListWidget extends ElementListWidgetExt<OptionListWidget.Entr return ret; } - private void setHoverDescription(OptionDescription description) { + private void setHoverDescription(DescriptionWithName description) { if (description != lastHoveredOption) { lastHoveredOption = description; hoverEvent.accept(description); @@ -300,7 +300,7 @@ public class OptionListWidget extends ElementListWidgetExt<OptionListWidget.Entr } if (isHovered() || isFocused()) { - setHoverDescription(option.description()); + setHoverDescription(DescriptionWithName.of(option.name(), option.description())); } } @@ -398,7 +398,7 @@ public class OptionListWidget extends ElementListWidgetExt<OptionListWidget.Entr wrappedName.renderCentered(graphics, x + entryWidth / 2, y + getYPadding()); if (isHovered() || isFocused()) { - setHoverDescription(group.description()); + setHoverDescription(DescriptionWithName.of(group.name(), group.description())); } } |