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/DescriptionWithName.java11
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/ImageRenderer.java70
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/OptionDescriptionWidget.java22
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/OptionListWidget.java12
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()));
}
}