aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/com/anthonyhilyard/iceberg/util/ItemColor.java33
-rw-r--r--src/main/java/com/anthonyhilyard/iceberg/util/Tooltips.java80
2 files changed, 108 insertions, 5 deletions
diff --git a/src/main/java/com/anthonyhilyard/iceberg/util/ItemColor.java b/src/main/java/com/anthonyhilyard/iceberg/util/ItemColor.java
index 6f8de4e..3714681 100644
--- a/src/main/java/com/anthonyhilyard/iceberg/util/ItemColor.java
+++ b/src/main/java/com/anthonyhilyard/iceberg/util/ItemColor.java
@@ -1,12 +1,32 @@
package com.anthonyhilyard.iceberg.util;
import net.minecraft.world.item.ItemStack;
+import net.minecraft.util.FormattedCharSink;
import net.minecraft.network.chat.TextColor;
import net.minecraft.network.chat.Component;
+import net.minecraft.network.chat.Style;
import net.minecraft.ChatFormatting;
public class ItemColor
{
+ private static class ColorCollector implements FormattedCharSink
+ {
+ private TextColor color = null;
+
+ @Override
+ public boolean accept(int index, Style style, int codePoint)
+ {
+ if (style.getColor() != null)
+ {
+ color = style.getColor();
+ return false;
+ }
+ return true;
+ }
+
+ public TextColor getColor() { return color; }
+ }
+
public static TextColor findFirstColorCode(Component textComponent)
{
// This function finds the first specified color code in the given text component.
@@ -36,6 +56,7 @@ public class ItemColor
return null;
}
}
+
return null;
}
@@ -61,13 +82,21 @@ public class ItemColor
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 there is a color code specified for the item name, use that.
+ TextColor formattingColor = findFirstColorCode(item.getHoverName());
if (formattingColor != null)
{
result = formattingColor;
}
+ // Finally, if there is a color style stored per-character, use the first one found.
+ ColorCollector colorCollector = new ColorCollector();
+ item.getHoverName().getVisualOrderText().accept(colorCollector);
+ if (colorCollector.getColor() != null)
+ {
+ result = colorCollector.getColor();
+ }
+
// 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 b3ab741..1673815 100644
--- a/src/main/java/com/anthonyhilyard/iceberg/util/Tooltips.java
+++ b/src/main/java/com/anthonyhilyard/iceberg/util/Tooltips.java
@@ -2,8 +2,13 @@ package com.anthonyhilyard.iceberg.util;
import java.util.ArrayList;
import java.util.List;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import com.anthonyhilyard.iceberg.events.RenderTooltipExtEvent;
import com.mojang.blaze3d.vertex.PoseStack;
@@ -15,10 +20,18 @@ 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 net.minecraft.locale.Language;
+import net.minecraft.network.chat.Component;
+import net.minecraft.network.chat.FormattedText;
import com.mojang.blaze3d.vertex.Tesselator;
+import com.mojang.datafixers.util.Either;
+
+import net.minecraft.world.inventory.tooltip.TooltipComponent;
import net.minecraft.world.item.ItemStack;
import com.mojang.math.Matrix4f;
+
+import net.minecraftforge.client.ForgeHooksClient;
import net.minecraftforge.client.event.RenderTooltipEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.client.gui.GuiUtils;
@@ -98,8 +111,8 @@ public class Tooltips
itemRenderer = Minecraft.getInstance().getItemRenderer();
}
- int rectX = rect.getX() - 8;
- int rectY = rect.getY() + 18;
+ int rectX = rect.getX() + 4;
+ int rectY = rect.getY() + 4;
RenderTooltipExtEvent.Pre preEvent = new RenderTooltipExtEvent.Pre(stack, poseStack, rectX, rectY, screenWidth, screenHeight, info.getFont(), info.getComponents(), comparison);
if (MinecraftForge.EVENT_BUS.post(preEvent))
@@ -167,6 +180,67 @@ public class Tooltips
MinecraftForge.EVENT_BUS.post(postEvent);
}
+ public static List<ClientTooltipComponent> gatherTooltipComponents(ItemStack stack, List<? extends FormattedText> textElements, Optional<TooltipComponent> itemComponent,
+ int mouseX, int screenWidth, int screenHeight, @Nullable Font forcedFont, Font fallbackFont, int maxWidth)
+ {
+ Font font = ForgeHooksClient.getTooltipFont(forcedFont, stack, fallbackFont);
+ List<Either<FormattedText, TooltipComponent>> elements = textElements.stream()
+ .map((Function<FormattedText, Either<FormattedText, TooltipComponent>>) Either::left)
+ .collect(Collectors.toCollection(ArrayList::new));
+
+ itemComponent.ifPresent(c -> elements.add(1, Either.right(c)));
+
+ var event = new RenderTooltipEvent.GatherComponents(stack, screenWidth, screenHeight, elements, maxWidth);
+ if (MinecraftForge.EVENT_BUS.post(event))
+ {
+ return List.of();
+ }
+
+ int tooltipTextWidth = event.getTooltipElements().stream()
+ .mapToInt(either -> either.map(font::width, component -> 0))
+ .max()
+ .orElse(0);
+
+ boolean needsWrap = false;
+
+ int tooltipX = mouseX + 12;
+ 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 - 12 - 8;
+ else
+ tooltipTextWidth = screenWidth - 16 - mouseX;
+ needsWrap = true;
+ }
+ }
+
+ if (event.getMaxWidth() > 0 && tooltipTextWidth > event.getMaxWidth())
+ {
+ tooltipTextWidth = event.getMaxWidth();
+ needsWrap = true;
+ }
+
+ final int tooltipTextWidthFinal = tooltipTextWidth;
+ if (needsWrap)
+ {
+ return event.getTooltipElements().stream()
+ .flatMap(either -> either.map(
+ text -> font.split(text, tooltipTextWidthFinal).stream().map(ClientTooltipComponent::create),
+ component -> Stream.of(ClientTooltipComponent.create(component))
+ ))
+ .toList();
+ }
+ return event.getTooltipElements().stream()
+ .map(either -> either.map(
+ text -> ClientTooltipComponent.create(text instanceof Component ? ((Component) text).getVisualOrderText() : Language.getInstance().getVisualOrder(text)),
+ ClientTooltipComponent::create
+ ))
+ .toList();
+ }
+
public static Rect2i calculateRect(final ItemStack stack, PoseStack poseStack, List<ClientTooltipComponent> components,
int mouseX, int mouseY,int screenWidth, int screenHeight, int maxTextWidth, Font font)
{
@@ -215,7 +289,7 @@ public class Tooltips
tooltipY = screenHeight - tooltipHeight - 6;
}
- rect = new Rect2i(tooltipX - 4, tooltipY - 4, tooltipTextWidth + 8, tooltipHeight + 8);
+ rect = new Rect2i(tooltipX - 2, tooltipY - 4, tooltipTextWidth, tooltipHeight);
return rect;
}
}