aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/anthonyhilyard/iceberg/events/RenderTooltipEvents.java51
-rw-r--r--src/main/java/com/anthonyhilyard/iceberg/mixin/ScreenMixin.java45
-rw-r--r--src/main/java/com/anthonyhilyard/iceberg/network/IcebergNetworkProtocol.java50
-rw-r--r--src/main/java/com/anthonyhilyard/iceberg/util/ItemColor.java43
-rw-r--r--src/main/java/com/anthonyhilyard/iceberg/util/Tooltips.java340
-rw-r--r--src/main/resources/iceberg.mixins.json4
6 files changed, 215 insertions, 318 deletions
diff --git a/src/main/java/com/anthonyhilyard/iceberg/events/RenderTooltipEvents.java b/src/main/java/com/anthonyhilyard/iceberg/events/RenderTooltipEvents.java
index 7dd58b7..d0693e3 100644
--- a/src/main/java/com/anthonyhilyard/iceberg/events/RenderTooltipEvents.java
+++ b/src/main/java/com/anthonyhilyard/iceberg/events/RenderTooltipEvents.java
@@ -15,6 +15,22 @@ public final class RenderTooltipEvents
{
public RenderTooltipEvents() { }
+ public static final Event<RenderTooltipEvents.PreExt> PREEXT = EventFactory.createArrayBacked(RenderTooltipEvents.PreExt.class,
+ callbacks -> (stack, components, poseStack, x, y, screenWidth, screenHeight, font, comparison) -> {
+ PreExtResult result = new PreExtResult(InteractionResult.PASS, x, y, screenWidth, screenHeight, font);
+ for (RenderTooltipEvents.PreExt callback : callbacks)
+ {
+ result = callback.onPre(stack, components, poseStack, x, y, screenWidth, screenHeight, font, comparison);
+
+ if (result.result != InteractionResult.PASS)
+ {
+ return result;
+ }
+ }
+ return result;
+ });
+
+ @Deprecated
public static final Event<RenderTooltipEvents.Pre> PRE = EventFactory.createArrayBacked(RenderTooltipEvents.Pre.class,
callbacks -> (stack, components, poseStack, x, y, screenWidth, screenHeight, maxWidth, font, comparison) -> {
for (RenderTooltipEvents.Pre callback : callbacks)
@@ -29,6 +45,17 @@ public final class RenderTooltipEvents
return InteractionResult.PASS;
});
+ public static final Event<RenderTooltipEvents.ColorExt> COLOREXT = EventFactory.createArrayBacked(RenderTooltipEvents.ColorExt.class,
+ callbacks -> (stack, components, poseStack, x, y, font, backgroundStart, backgroundEnd, borderStart, borderEnd, comparison) -> {
+ ColorExtResult result = new ColorExtResult(backgroundStart, backgroundEnd, borderStart, borderEnd);
+ for (RenderTooltipEvents.ColorExt callback : callbacks)
+ {
+ result = callback.onColor(stack, components, poseStack, x, y, font, result.backgroundStart, result.backgroundEnd, result.borderStart, result.borderEnd, comparison);
+ }
+ return result;
+ });
+
+ @Deprecated
public static final Event<RenderTooltipEvents.Color> COLOR = EventFactory.createArrayBacked(RenderTooltipEvents.Color.class,
callbacks -> (stack, components, poseStack, x, y, font, background, borderStart, borderEnd, comparison) -> {
ColorResult result = new ColorResult(background, borderStart, borderEnd);
@@ -41,19 +68,33 @@ public final class RenderTooltipEvents
public static final Event<RenderTooltipEvents.Post> POST = EventFactory.createArrayBacked(RenderTooltipEvents.Post.class,
callbacks -> (stack, components, poseStack, x, y, font, width, height, comparison) -> {
- for (RenderTooltipEvents.Post callback : callbacks)
- {
- callback.onPost(stack, components, poseStack, x, y, font, width, height, comparison);
- }
+ for (RenderTooltipEvents.Post callback : callbacks)
+ {
+ callback.onPost(stack, components, poseStack, x, y, font, width, height, comparison);
+ }
});
@FunctionalInterface
+ public interface PreExt
+ {
+ PreExtResult onPre(ItemStack stack, List<ClientTooltipComponent> components, PoseStack poseStack, int x, int y, int screenWidth, int screenHeight, Font font, boolean comparison);
+ }
+
+ @Deprecated
+ @FunctionalInterface
public interface Pre
{
InteractionResult onPre(ItemStack stack, List<ClientTooltipComponent> components, PoseStack poseStack, int x, int y, int screenWidth, int screenHeight, int maxWidth, Font font, boolean comparison);
}
@FunctionalInterface
+ public interface ColorExt
+ {
+ ColorExtResult onColor(ItemStack stack, List<ClientTooltipComponent> components, PoseStack poseStack, int x, int y, Font font, int backgroundStart, int backgroundEnd, int borderStart, int borderEnd, boolean comparison);
+ }
+
+ @Deprecated
+ @FunctionalInterface
public interface Color
{
ColorResult onColor(ItemStack stack, List<ClientTooltipComponent> components, PoseStack poseStack, int x, int y, Font font, int background, int borderStart, int borderEnd, boolean comparison);
@@ -65,5 +106,7 @@ public final class RenderTooltipEvents
void onPost(ItemStack stack, List<ClientTooltipComponent> components, PoseStack poseStack, int x, int y, Font font, int width, int height, boolean comparison);
}
+ public record PreExtResult(InteractionResult result, int x, int y, int screenWidth, int screenHeight, Font font) {}
+ public record ColorExtResult(int backgroundStart, int backgroundEnd, int borderStart, int borderEnd) {}
public record ColorResult(int background, int borderStart, int borderEnd) {}
}
diff --git a/src/main/java/com/anthonyhilyard/iceberg/mixin/ScreenMixin.java b/src/main/java/com/anthonyhilyard/iceberg/mixin/ScreenMixin.java
index 06e0e90..55a97c3 100644
--- a/src/main/java/com/anthonyhilyard/iceberg/mixin/ScreenMixin.java
+++ b/src/main/java/com/anthonyhilyard/iceberg/mixin/ScreenMixin.java
@@ -3,6 +3,7 @@ package com.anthonyhilyard.iceberg.mixin;
import java.util.List;
import com.anthonyhilyard.iceberg.events.RenderTooltipEvents;
+import com.anthonyhilyard.iceberg.events.RenderTooltipEvents.ColorExtResult;
import com.anthonyhilyard.iceberg.events.RenderTooltipEvents.ColorResult;
import com.google.common.collect.Lists;
import com.mojang.blaze3d.vertex.BufferBuilder;
@@ -10,7 +11,6 @@ import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.Tesselator;
import com.mojang.math.Matrix4f;
-import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
@@ -37,11 +37,10 @@ public class ScreenMixin extends AbstractContainerEventHandler
@Shadow
protected Font font = null;
- @Final
@Shadow
- private final List<GuiEventListener> children = Lists.newArrayList();
+ private List<GuiEventListener> children = Lists.newArrayList();
- @SuppressWarnings("unchecked")
+ @SuppressWarnings({"unchecked", "deprecation"})
@Inject(method = "renderTooltipInternal", at = @At(value = "HEAD"), cancellable = true)
private void preRenderTooltipInternal(PoseStack poseStack, List<ClientTooltipComponent> components, int x, int y, CallbackInfo info)
{
@@ -54,7 +53,16 @@ public class ScreenMixin extends AbstractContainerEventHandler
if (hoveredSlot != null)
{
ItemStack tooltipStack = hoveredSlot.getItem();
- if (RenderTooltipEvents.PRE.invoker().onPre(tooltipStack, components, poseStack, x, y, self.width, self.height, -1, font, false) != InteractionResult.PASS)
+ InteractionResult result = RenderTooltipEvents.PREEXT.invoker().onPre(tooltipStack, components, poseStack, x, y, self.width, self.height, font, false).result();
+
+ if (result != InteractionResult.PASS)
+ {
+ info.cancel();
+ }
+
+ // Fire a pre event as well for compatibility.
+ result = RenderTooltipEvents.PRE.invoker().onPre(tooltipStack, components, poseStack, x, y, self.width, self.height, -1, font, false);
+ if (result != InteractionResult.PASS)
{
info.cancel();
}
@@ -90,7 +98,7 @@ public class ScreenMixin extends AbstractContainerEventHandler
}
}
- @SuppressWarnings("unchecked")
+ @SuppressWarnings({"unchecked", "deprecation"})
@Inject(method = "renderTooltipInternal", at = @At(value = "INVOKE",
target = "Lnet/minecraft/client/gui/screens/Screen;fillGradient(Lcom/mojang/math/Matrix4f;Lcom/mojang/blaze3d/vertex/BufferBuilder;IIIIIII)V", shift = Shift.BEFORE),
locals = LocalCapture.CAPTURE_FAILEXCEPTION)
@@ -112,20 +120,33 @@ public class ScreenMixin extends AbstractContainerEventHandler
if (tooltipStack != ItemStack.EMPTY)
{
+ int backgroundEnd = background;
+
// Do colors now, sure why not.
- ColorResult result = RenderTooltipEvents.COLOR.invoker().onColor(tooltipStack, components, poseStack, x, y, font, background, borderStart, borderEnd, false);
+ ColorExtResult result = RenderTooltipEvents.COLOREXT.invoker().onColor(tooltipStack, components, poseStack, x, y, font, background, background, borderStart, borderEnd, false);
if (result != null)
{
- background = result.background();
+ background = result.backgroundStart();
+ backgroundEnd = result.backgroundEnd();
borderStart = result.borderStart();
borderEnd = result.borderEnd();
}
+ // Fire a colors event as well for compatibility.
+ ColorResult colorResult = RenderTooltipEvents.COLOR.invoker().onColor(tooltipStack, components, poseStack, x, y, font, background, borderStart, borderEnd, false);
+ if (colorResult != null)
+ {
+ background = colorResult.background();
+ borderStart = colorResult.borderStart();
+ borderEnd = colorResult.borderEnd();
+ }
+
+
Screen.fillGradient(matrix4f, bufferBuilder, left - 3, top - 4, left + width + 3, top - 3, zIndex, background, background);
- Screen.fillGradient(matrix4f, bufferBuilder, left - 3, top + height + 3, left + width + 3, top + height + 4, zIndex, background, background);
- Screen.fillGradient(matrix4f, bufferBuilder, left - 3, top - 3, left + width + 3, top + height + 3, zIndex, background, background);
- Screen.fillGradient(matrix4f, bufferBuilder, left - 4, top - 3, left - 3, top + height + 3, zIndex, background, background);
- Screen.fillGradient(matrix4f, bufferBuilder, left + width + 3, top - 3, left + width + 4, top + height + 3, zIndex, background, background);
+ Screen.fillGradient(matrix4f, bufferBuilder, left - 3, top + height + 3, left + width + 3, top + height + 4, zIndex, backgroundEnd, backgroundEnd);
+ Screen.fillGradient(matrix4f, bufferBuilder, left - 3, top - 3, left + width + 3, top + height + 3, zIndex, background, backgroundEnd);
+ Screen.fillGradient(matrix4f, bufferBuilder, left - 4, top - 3, left - 3, top + height + 3, zIndex, background, backgroundEnd);
+ Screen.fillGradient(matrix4f, bufferBuilder, left + width + 3, top - 3, left + width + 4, top + height + 3, zIndex, background, backgroundEnd);
Screen.fillGradient(matrix4f, bufferBuilder, left - 3, top - 3 + 1, left - 3 + 1, top + height + 3 - 1, zIndex, borderStart, borderEnd);
Screen.fillGradient(matrix4f, bufferBuilder, left + width + 2, top - 3 + 1, left + width + 3, top + height + 3 - 1, zIndex, borderStart, borderEnd);
Screen.fillGradient(matrix4f, bufferBuilder, left - 3, top - 3, left + width + 3, top - 3 + 1, zIndex, borderStart, borderStart);
diff --git a/src/main/java/com/anthonyhilyard/iceberg/network/IcebergNetworkProtocol.java b/src/main/java/com/anthonyhilyard/iceberg/network/IcebergNetworkProtocol.java
deleted file mode 100644
index d82d0e5..0000000
--- a/src/main/java/com/anthonyhilyard/iceberg/network/IcebergNetworkProtocol.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package com.anthonyhilyard.iceberg.network;
-
-import com.anthonyhilyard.iceberg.Loader;
-import com.anthonyhilyard.iceberg.events.NewItemPickupCallback;
-
-import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
-import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
-import net.fabricmc.fabric.api.networking.v1.PacketSender;
-import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.multiplayer.ClientPacketListener;
-import net.minecraft.network.FriendlyByteBuf;
-import net.minecraft.resources.ResourceLocation;
-import net.minecraft.server.level.ServerPlayer;
-import net.minecraft.world.item.ItemStack;
-
-public final class IcebergNetworkProtocol
-{
- private static final String VERSION = "v1";
-
- private static final ResourceLocation SEND_ITEM_ID = new ResourceLocation(Loader.MODID, VERSION + '/' + String.valueOf(0));
-
- public static void sendItemPickupEvent(ServerPlayer player, ItemStack item)
- {
- Loader.LOGGER.info("Sending item pickup event message!");
- if (!player.level.isClientSide)
- {
- // Build buffer.
- FriendlyByteBuf buffer = PacketByteBufs.create();
- buffer.writeUUID(player.getUUID());
- buffer.writeItem(item);
-
- // Send packet.
- ServerPlayNetworking.send(player, SEND_ITEM_ID, buffer);
- }
- }
-
- public static void handleItemPickupEvent(Minecraft client, ClientPacketListener handler, FriendlyByteBuf buf, PacketSender responseSender)
- {
- Loader.LOGGER.info("receiving item pickup event message!");
- client.execute(() -> {
- NewItemPickupCallback.EVENT.invoker().onItemPickup(buf.readUUID(), buf.readItem());
- });
- }
-
- public static void registerHandlers()
- {
- ClientPlayNetworking.registerGlobalReceiver(SEND_ITEM_ID, IcebergNetworkProtocol::handleItemPickupEvent);
- }
-}
diff --git a/src/main/java/com/anthonyhilyard/iceberg/util/ItemColor.java b/src/main/java/com/anthonyhilyard/iceberg/util/ItemColor.java
index 26cdc14..6f8de4e 100644
--- a/src/main/java/com/anthonyhilyard/iceberg/util/ItemColor.java
+++ b/src/main/java/com/anthonyhilyard/iceberg/util/ItemColor.java
@@ -2,9 +2,43 @@ package com.anthonyhilyard.iceberg.util;
import net.minecraft.world.item.ItemStack;
import net.minecraft.network.chat.TextColor;
+import net.minecraft.network.chat.Component;
+import net.minecraft.ChatFormatting;
public class ItemColor
{
+ public static TextColor findFirstColorCode(Component textComponent)
+ {
+ // This function finds the first specified color code in the given text component.
+ // It is intended to skip non-color formatting codes.
+ String rawTitle = textComponent.getString();
+ for (int i = 0; i < rawTitle.length(); i += 2)
+ {
+ // If we encounter a formatting code, check to see if it's a color. If so, return it.
+ if (rawTitle.charAt(i) == '\u00a7')
+ {
+ try
+ {
+ ChatFormatting format = ChatFormatting.getByCode(rawTitle.charAt(i + 1));
+ if (format.isColor())
+ {
+ return TextColor.fromLegacyFormat(format);
+ }
+ }
+ catch (StringIndexOutOfBoundsException e)
+ {
+ return null;
+ }
+ }
+ // Otherwise, if we encounter a non-formatting character, bail.
+ else
+ {
+ return null;
+ }
+ }
+ return null;
+ }
+
public static TextColor getColorForItem(ItemStack item, TextColor defaultColor)
{
TextColor result = null;
@@ -21,12 +55,19 @@ public class ItemColor
result = item.getItem().getName(item).getStyle().getColor();
}
- // Finally, if the item has a special hover name TextColor (Stored in NBT), use that.
+ // If the item has a special hover name TextColor (Stored in NBT), use that.
if (!item.getHoverName().getStyle().isEmpty() && item.getHoverName().getStyle().getColor() != null)
{
result = item.getHoverName().getStyle().getColor();
}
+ // Finally if there is a color code specified for the item name, use that.
+ TextColor formattingColor = findFirstColorCode(item.getItem().getName(item));
+ if (formattingColor != null)
+ {
+ result = formattingColor;
+ }
+
// Fallback to the default TextColor if we somehow haven't found a single valid TextColor.
if (result == null)
{
diff --git a/src/main/java/com/anthonyhilyard/iceberg/util/Tooltips.java b/src/main/java/com/anthonyhilyard/iceberg/util/Tooltips.java
index ec1dfc4..6d48c1a 100644
--- a/src/main/java/com/anthonyhilyard/iceberg/util/Tooltips.java
+++ b/src/main/java/com/anthonyhilyard/iceberg/util/Tooltips.java
@@ -1,35 +1,26 @@
package com.anthonyhilyard.iceberg.util;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import com.anthonyhilyard.iceberg.events.RenderTooltipEvents;
-import com.anthonyhilyard.iceberg.events.RenderTooltipEvents.ColorResult;
-import com.mojang.blaze3d.vertex.BufferBuilder;
-import com.mojang.blaze3d.vertex.BufferUploader;
-import com.mojang.blaze3d.vertex.DefaultVertexFormat;
+import com.anthonyhilyard.iceberg.events.RenderTooltipEvents.ColorExtResult;
+import com.anthonyhilyard.iceberg.events.RenderTooltipEvents.PreExtResult;
import com.mojang.blaze3d.vertex.PoseStack;
-import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font;
-import net.minecraft.client.gui.screens.inventory.tooltip.ClientTextTooltip;
import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent;
-import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.Rect2i;
+import net.minecraft.client.renderer.MultiBufferSource.BufferSource;
import net.minecraft.client.renderer.entity.ItemRenderer;
import com.mojang.blaze3d.vertex.Tesselator;
-import com.mojang.blaze3d.vertex.VertexFormat;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.item.ItemStack;
import com.mojang.math.Matrix4f;
-import net.minecraft.network.chat.FormattedText;
-import net.minecraft.locale.Language;
-import net.minecraft.network.chat.Style;
public class Tooltips
{
@@ -41,82 +32,33 @@ public class Tooltips
private int tooltipWidth = 0;
private int titleLines = 1;
private Font font;
- private List<ClientTooltipComponent> lines = new ArrayList<>();
+ private List<ClientTooltipComponent> components = new ArrayList<>();
- public TooltipInfo(List<ClientTooltipComponent> lines, Font font)
+ public TooltipInfo(List<ClientTooltipComponent> components, Font font)
{
- this.lines = lines;
+ this.components = components;
this.font = font;
}
public int getTooltipWidth() { return tooltipWidth; }
public int getTitleLines() { return titleLines; }
public Font getFont() { return font; }
- public List<ClientTooltipComponent> getLines() { return lines; }
+ public List<ClientTooltipComponent> getComponents() { return components; }
public void setFont(Font font) { this.font = font; }
public int getMaxLineWidth()
{
- int textWidth = 0;
- for (ClientTooltipComponent component : lines)
+ int width = 0;
+ for (ClientTooltipComponent component : components)
{
int textLineWidth = component.getWidth(font);
- if (textLineWidth > textWidth)
+ if (textLineWidth > width)
{
- textWidth = textLineWidth;
+ width = textLineWidth;
}
}
- return textWidth;
- }
-
- private List<ClientTextTooltip> splitComponent(ClientTextTooltip component, int maxWidth, Font font)
- {
- FormattedText text = FormattedText.composite(StringRecomposer.recompose(Arrays.asList(component)));
- List<FormattedText> wrappedLines = font.getSplitter().splitLines(text, maxWidth, Style.EMPTY);
- List<ClientTextTooltip> result = new ArrayList<>();
-
- for (FormattedText wrappedLine : wrappedLines)
- {
- result.add(new ClientTextTooltip(Language.getInstance().getVisualOrder(wrappedLine)));
- }
-
- return result;
- }
-
- public void wrap(int maxWidth)
- {
- tooltipWidth = 0;
- List<ClientTooltipComponent> wrappedLines = new ArrayList<>();
- for (int i = 0; i < lines.size(); i++)
- {
- ClientTooltipComponent textLine = lines.get(i);
-
- // Only wrap text lines.
- // TODO: What to do with images that are too big?
- if (!(textLine instanceof ClientTextTooltip))
- {
- continue;
- }
-
- List<ClientTextTooltip> wrappedLine = splitComponent((ClientTextTooltip)textLine, maxWidth, font);
- if (i == 0)
- {
- titleLines = wrappedLine.size();
- }
-
- for (ClientTooltipComponent line : wrappedLine)
- {
- int lineWidth = line.getWidth(font);
- if (lineWidth > tooltipWidth)
- {
- tooltipWidth = lineWidth;
- }
- wrappedLines.add(line);
- }
- }
-
- lines = wrappedLines;
+ return width;
}
}
@@ -127,12 +69,11 @@ public class Tooltips
}
public static void renderItemTooltip(final ItemStack stack, PoseStack poseStack, TooltipInfo info,
- Rect2i rect, int screenWidth, int screenHeight,
- int backgroundColor, int borderColorStart, int borderColorEnd)
+ Rect2i rect, int screenWidth, int screenHeight,
+ int backgroundColor, int borderColorStart, int borderColorEnd)
{
renderItemTooltip(stack, poseStack, info, rect, screenWidth, screenHeight, backgroundColor, borderColorStart, borderColorEnd, false);
}
-
public static void renderItemTooltip(final ItemStack stack, PoseStack poseStack, TooltipInfo info,
Rect2i rect, int screenWidth, int screenHeight,
int backgroundColor, int borderColorStart, int borderColorEnd, boolean comparison)
@@ -144,237 +85,138 @@ public class Tooltips
Rect2i rect, int screenWidth, int screenHeight,
int backgroundColor, int borderColorStart, int borderColorEnd, boolean comparison, boolean constrain)
{
- // Initialize if needed.
- if (!initialized)
+ renderItemTooltip(stack, poseStack, info, rect, screenWidth, screenHeight, backgroundColor, backgroundColor, borderColorStart, borderColorEnd, comparison, constrain);
+ }
+
+ public static void renderItemTooltip(final ItemStack stack, PoseStack poseStack, TooltipInfo info,
+ Rect2i rect, int screenWidth, int screenHeight,
+ int backgroundColorStart, int backgroundColorEnd, int borderColorStart, int borderColorEnd, boolean comparison, boolean constrain)
+ {
+ if (info.components.isEmpty())
{
- init(Minecraft.getInstance());
+ return;
}
- if (info.lines.isEmpty())
+ // Initialize if needed.
+ if (!initialized)
{
- return;
+ init(Minecraft.getInstance());
}
int rectX = rect.getX() - 8;
int rectY = rect.getY() + 18;
- int maxTextWidth = rect.getWidth() - 8;
- InteractionResult result = RenderTooltipEvents.PRE.invoker().onPre(stack, info.getLines(), poseStack, rectX, rectY, screenWidth, screenHeight, maxTextWidth, info.getFont(), comparison);
- if (result != InteractionResult.PASS)
+ PreExtResult preResult = RenderTooltipEvents.PREEXT.invoker().onPre(stack, info.getComponents(), poseStack, rectX, rectY, screenWidth, screenHeight, info.getFont(), comparison);
+ if (preResult.result() != InteractionResult.PASS)
{
return;
}
- boolean needsWrap = false;
+ rectX = preResult.x();
+ rectY = preResult.y();
+ screenWidth = preResult.screenWidth();
+ screenHeight = preResult.screenHeight();
+ info.setFont(preResult.font());
- int tooltipX = rectX + 12;
- int tooltipTextWidth = info.getMaxLineWidth();
-
- // Constrain the minimum width to the rect.
- if (constrain)
- {
- tooltipTextWidth = Math.max(info.getMaxLineWidth(), rect.getWidth() - 8);
- }
-
- if (tooltipX + tooltipTextWidth + 4 > screenWidth)
- {
- tooltipX = rectX - 16 - tooltipTextWidth;
- if (tooltipX < 4)
- {
- if (rectX > screenWidth / 2)
- {
- tooltipTextWidth = rectX - 20;
- }
- else
- {
- tooltipTextWidth = screenWidth - 16 - rectX;
- }
- needsWrap = true;
- }
- }
+ poseStack.pushPose();
- if (maxTextWidth > 0 && tooltipTextWidth > maxTextWidth)
- {
- tooltipTextWidth = maxTextWidth;
- needsWrap = true;
- }
+ final int zLevel = 400;
- if (needsWrap)
- {
- info.wrap(tooltipTextWidth);
- tooltipTextWidth = info.getTooltipWidth();
- tooltipX = rectX + 12;
- }
+ float f = itemRenderer.blitOffset;
+ itemRenderer.blitOffset = zLevel;
+ Matrix4f mat = poseStack.last().pose();
- int tooltipY = rectY - 12;
- int tooltipHeight = 8;
+ ColorExtResult colors = RenderTooltipEvents.COLOREXT.invoker().onColor(stack, info.components, poseStack, rectX, rectY, info.getFont(), backgroundColorStart, backgroundColorEnd, borderColorStart, borderColorEnd, comparison);
- if (info.getLines().size() > 1)
- {
- tooltipHeight += (info.getLines().size() - 1) * 10;
- if (info.getLines().size() > info.getTitleLines())
- {
- tooltipHeight += 2; // gap between title lines and next lines
- }
- }
+ backgroundColorStart = colors.backgroundStart();
+ backgroundColorEnd = colors.backgroundEnd();
+ borderColorStart = colors.borderStart();
+ borderColorEnd = colors.borderEnd();
- if (tooltipY < 4)
- {
- tooltipY = 4;
- }
- else if (tooltipY + tooltipHeight + 4 > screenHeight)
- {
- tooltipY = screenHeight - tooltipHeight - 4;
- }
-
- poseStack.pushPose();
- int bgColor = 0xF0100010;
- int borderStart = 0x505000FF;
- int borderEnd = 0x5028007F;
+ GuiHelper.drawGradientRect(mat, zLevel, rectX - 3, rectY - 4, rectX + rect.getWidth() + 3, rectY - 3, backgroundColorStart, backgroundColorStart);
+ GuiHelper.drawGradientRect(mat, zLevel, rectX - 3, rectY + rect.getHeight() + 3, rectX + rect.getWidth() + 3, rectY + rect.getHeight() + 4, backgroundColorEnd, backgroundColorEnd);
+ GuiHelper.drawGradientRect(mat, zLevel, rectX - 3, rectY - 3, rectX + rect.getWidth() + 3, rectY + rect.getHeight() + 3, backgroundColorStart, backgroundColorEnd);
+ GuiHelper.drawGradientRect(mat, zLevel, rectX - 4, rectY - 3, rectX - 3, rectY + rect.getHeight() + 3, backgroundColorStart, backgroundColorEnd);
+ GuiHelper.drawGradientRect(mat, zLevel, rectX + rect.getWidth() + 3, rectY - 3, rectX + rect.getWidth() + 4, rectY + rect.getHeight() + 3, backgroundColorStart, backgroundColorEnd);
+ GuiHelper.drawGradientRect(mat, zLevel, rectX - 3, rectY - 3 + 1, rectX - 3 + 1, rectY + rect.getHeight() + 3 - 1, borderColorStart, borderColorEnd);
+ GuiHelper.drawGradientRect(mat, zLevel, rectX + rect.getWidth() + 2, rectY - 3 + 1, rectX + rect.getWidth() + 3, rectY + rect.getHeight() + 3 - 1, borderColorStart, borderColorEnd);
+ GuiHelper.drawGradientRect(mat, zLevel, rectX - 3, rectY - 3, rectX + rect.getWidth() + 3, rectY - 3 + 1, borderColorStart, borderColorStart);
+ GuiHelper.drawGradientRect(mat, zLevel, rectX - 3, rectY + rect.getHeight() + 2, rectX + rect.getWidth() + 3, rectY + rect.getHeight() + 3, borderColorEnd, borderColorEnd);
- ColorResult colors = RenderTooltipEvents.COLOR.invoker().onColor(stack, info.lines, poseStack, tooltipX, tooltipY, info.getFont(), bgColor, borderStart, borderEnd, comparison);
+ BufferSource renderType = MultiBufferSource.immediate(Tesselator.getInstance().getBuilder());
+ poseStack.translate(0.0D, 0.0D, zLevel);
- bgColor = colors.background();
- borderStart = colors.borderStart();
- borderEnd = colors.borderEnd();
+ int tooltipTop = rectY;
- float f = itemRenderer.blitOffset;
- itemRenderer.blitOffset = 400.0F;
- Tesselator tesselator = Tesselator.getInstance();
- BufferBuilder bufferBuilder = tesselator.getBuilder();
- RenderSystem.setShader(GameRenderer::getPositionColorShader);
- bufferBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR);
- Matrix4f mat = poseStack.last().pose();
- GuiHelper.drawGradientRect(mat, bufferBuilder, tooltipX - 3, tooltipY - 4, tooltipX + tooltipTextWidth + 3, tooltipY - 3, 400, bgColor, bgColor);
- GuiHelper.drawGradientRect(mat, bufferBuilder, tooltipX - 3, tooltipY + tooltipHeight + 3, tooltipX + tooltipTextWidth + 3, tooltipY + tooltipHeight + 4, 400, bgColor, bgColor);
- GuiHelper.drawGradientRect(mat, bufferBuilder, tooltipX - 3, tooltipY - 3, tooltipX + tooltipTextWidth + 3, tooltipY + tooltipHeight + 3, 400, bgColor, bgColor);
- GuiHelper.drawGradientRect(mat, bufferBuilder, tooltipX - 4, tooltipY - 3, tooltipX - 3, tooltipY + tooltipHeight + 3, 400, bgColor, bgColor);
- GuiHelper.drawGradientRect(mat, bufferBuilder, tooltipX + tooltipTextWidth + 3, tooltipY - 3, tooltipX + tooltipTextWidth + 4, tooltipY + tooltipHeight + 3, 400, bgColor, bgColor);
- GuiHelper.drawGradientRect(mat, bufferBuilder, tooltipX - 3, tooltipY - 3 + 1, tooltipX - 3 + 1, tooltipY + tooltipHeight + 3 - 1, 400, borderStart, borderEnd);
- GuiHelper.drawGradientRect(mat, bufferBuilder, tooltipX + tooltipTextWidth + 2, tooltipY - 3 + 1, tooltipX + tooltipTextWidth + 3, tooltipY + tooltipHeight + 3 - 1, 400, borderStart, borderEnd);
- GuiHelper.drawGradientRect(mat, bufferBuilder, tooltipX - 3, tooltipY - 3, tooltipX + tooltipTextWidth + 3, tooltipY - 3 + 1, 400, borderStart, borderStart);
- GuiHelper.drawGradientRect(mat, bufferBuilder, tooltipX - 3, tooltipY + tooltipHeight + 2, tooltipX + tooltipTextWidth + 3, tooltipY + tooltipHeight + 3, 400, borderEnd, borderEnd);
- RenderSystem.enableDepthTest();
- RenderSystem.disableTexture();
- RenderSystem.enableBlend();
- RenderSystem.defaultBlendFunc();
- bufferBuilder.end();
- BufferUploader.end(bufferBuilder);
- RenderSystem.disableBlend();
- RenderSystem.enableTexture();
-
- MultiBufferSource.BufferSource bufferSource = MultiBufferSource.immediate(Tesselator.getInstance().getBuilder());
- poseStack.translate(0.0D, 0.0D, 400.0D);
- int v = tooltipY;
-
- ClientTooltipComponent clientTooltipComponent3;
- for (int i = 0; i < info.getLines().size(); ++i)
+ for (int componentNumber = 0; componentNumber < info.getComponents().size(); ++componentNumber)
{
- clientTooltipComponent3 = (ClientTooltipComponent)info.getLines().get(i);
- clientTooltipComponent3.renderText(info.getFont(), tooltipX, v, mat, bufferSource);
- v += clientTooltipComponent3.getHeight() + (i == 0 ? 2 : 0);
+ ClientTooltipComponent textComponent = (ClientTooltipComponent)info.getComponents().get(componentNumber);
+ textComponent.renderText(info.getFont(), rectX, tooltipTop, mat, renderType);
+ tooltipTop += textComponent.getHeight() + (componentNumber == 0 ? 2 : 0);
}
- bufferSource.endBatch();
+ renderType.endBatch();
poseStack.popPose();
- v = tooltipY;
+ tooltipTop = rectY;
- for (int i = 0; i < info.getLines().size(); ++i)
+ for (int componentNumber = 0; componentNumber < info.getComponents().size(); ++componentNumber)
{
- clientTooltipComponent3 = (ClientTooltipComponent)info.getLines().get(i);
- clientTooltipComponent3.renderImage(info.getFont(), tooltipX, v, poseStack, itemRenderer, 400);
- v += clientTooltipComponent3.getHeight() + (i == 0 ? 2 : 0);
+ ClientTooltipComponent imageComponent = (ClientTooltipComponent)info.getComponents().get(componentNumber);
+ imageComponent.renderImage(info.getFont(), rectX, tooltipTop, poseStack, itemRenderer, 400);
+ tooltipTop += imageComponent.getHeight() + (componentNumber == 0 ? 2 : 0);
}
itemRenderer.blitOffset = f;
- RenderTooltipEvents.POST.invoker().onPost(stack, info.getLines(), poseStack, tooltipX, tooltipY, info.getFont(), tooltipTextWidth, tooltipHeight, comparison);
+ RenderTooltipEvents.POST.invoker().onPost(stack, info.getComponents(), poseStack, rectX, rectY, info.getFont(), rect.getWidth(), rect.getHeight(), comparison);
}
- public static Rect2i calculateRect(final ItemStack stack, PoseStack poseStack, List<ClientTooltipComponent> textLines, int mouseX, int mouseY,
+ public static Rect2i calculateRect(final ItemStack stack, PoseStack poseStack, List<ClientTooltipComponent> components, int mouseX, int mouseY,
int screenWidth, int screenHeight, int maxTextWidth, Font font)
{
Rect2i rect = new Rect2i(0, 0, 0, 0);
- if (textLines == null || textLines.isEmpty() || stack == null)
+ if (components == null || components.isEmpty() || stack == null)
{
return rect;
}
- int tooltipTextWidth = 0;
-
- for (ClientTooltipComponent textLine : textLines)
+ // Generate a tooltip event even though we aren't rendering anything in case event handlers are modifying the input values.
+ PreExtResult preResult = RenderTooltipEvents.PREEXT.invoker().onPre(stack, components, poseStack, mouseX, mouseY, screenWidth, screenHeight, font, false);
+ if (preResult.result() != InteractionResult.PASS)
{
- int textLineWidth = textLine.getWidth(font);
- if (textLineWidth > tooltipTextWidth)
- {
- tooltipTextWidth = textLineWidth;
- }
+ return rect;
}
- boolean needsWrap = false;
-
- int titleLinesCount = 1;
- int tooltipX = mouseX + 14;
- if (tooltipX + tooltipTextWidth + 4 > screenWidth)
- {
- tooltipX = mouseX - 16 - tooltipTextWidth;
- if (tooltipX < 4) // if the tooltip doesn't fit on the screen
- {
- if (mouseX > screenWidth / 2)
- {
- tooltipTextWidth = mouseX - 14 - 8;
- }
- else
- {
- tooltipTextWidth = screenWidth - 16 - mouseX;
- }
- needsWrap = true;
- }
- }
+ mouseX = preResult.x();
+ mouseY = preResult.y();
+ screenWidth = preResult.screenWidth();
+ screenHeight = preResult.screenHeight();
+ font = preResult.font();
- if (maxTextWidth > 0 && tooltipTextWidth > maxTextWidth)
- {
- tooltipTextWidth = maxTextWidth;
- needsWrap = true;
- }
+ int tooltipTextWidth = 0;
+ int tooltipHeight = components.size() == 1 ? -2 : 0;
- if (needsWrap)
+ for (ClientTooltipComponent component : components)
{
- TooltipInfo info = new TooltipInfo(textLines, font);
- info.wrap(tooltipTextWidth);
-
- tooltipTextWidth = info.tooltipWidth;
- textLines = info.lines;
-
- if (mouseX > screenWidth / 2)
+ int componentWidth = component.getWidth(font);
+ if (componentWidth > tooltipTextWidth)
{
- tooltipX = mouseX - 16 - tooltipTextWidth;
+ tooltipTextWidth = componentWidth;
}
- else
- {
- tooltipX = mouseX + 14;
- }
- }
- int tooltipY = mouseY - 14;
- int tooltipHeight = 8;
-
- if (textLines.size() > 1)
- {
- tooltipHeight += (textLines.size() - 1) * 10;
- if (textLines.size() > titleLinesCount)
- {
- tooltipHeight += 2; // gap between title lines and next lines
- }
+ tooltipHeight += component.getHeight();
}
- if (tooltipY < 4)
+ int tooltipX = mouseX + 12;
+ int tooltipY = mouseY - 12;
+ if (tooltipX + tooltipTextWidth > screenWidth)
{
- tooltipY = 4;
+ tooltipX -= 28 + tooltipTextWidth;
}
- else if (tooltipY + tooltipHeight + 4 > screenHeight)
+
+ if (tooltipY + tooltipHeight + 6 > screenHeight)
{
- tooltipY = screenHeight - tooltipHeight - 4;
+ tooltipY = screenHeight - tooltipHeight - 6;
}
rect = new Rect2i(tooltipX - 4, tooltipY - 4, tooltipTextWidth + 8, tooltipHeight + 8);
diff --git a/src/main/resources/iceberg.mixins.json b/src/main/resources/iceberg.mixins.json
index 758fce2..ed2f38f 100644
--- a/src/main/resources/iceberg.mixins.json
+++ b/src/main/resources/iceberg.mixins.json
@@ -1,7 +1,7 @@
{
"required": true,
"package": "com.anthonyhilyard.iceberg.mixin",
- "compatibilityLevel": "JAVA_16",
+ "compatibilityLevel": "JAVA_17",
"verbose": true,
"mixins": [
"EntityMixin",
@@ -16,6 +16,6 @@
"injectors": {
"defaultRequire": 1
},
- "minVersion": "0.8.2",
+ "minVersion": "0.8.4",
"target": "@env(DEFAULT)"
}