From 0cb62c8df974b408577ea99e37cea801ace72175 Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 30 Apr 2024 16:35:08 -0230 Subject: Improvement: Defer renderable tooltips to end of rendering (#1603) --- src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt | 2 + .../utils/renderables/RenderLineTooltips.kt | 148 ------------------ .../skyhanni/utils/renderables/Renderable.kt | 7 +- .../utils/renderables/RenderableTooltips.kt | 174 +++++++++++++++++++++ 4 files changed, 177 insertions(+), 154 deletions(-) delete mode 100644 src/main/java/at/hannibal2/skyhanni/utils/renderables/RenderLineTooltips.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/utils/renderables/RenderableTooltips.kt diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt index 5c96ecde0..9fe8af976 100644 --- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt +++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt @@ -442,6 +442,7 @@ import at.hannibal2.skyhanni.utils.NEUItems import at.hannibal2.skyhanni.utils.NEUVersionCheck.checkIfNeuIsLoaded import at.hannibal2.skyhanni.utils.TabListData import at.hannibal2.skyhanni.utils.UtilsPatterns +import at.hannibal2.skyhanni.utils.renderables.RenderableTooltips import at.hannibal2.skyhanni.utils.repopatterns.RepoPatternManager import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope @@ -572,6 +573,7 @@ class SkyHanniMod { loadModule(MiningAPI) loadModule(FossilExcavatorAPI) loadModule(ChocolateFactoryAPI) + loadModule(RenderableTooltips) // features loadModule(BazaarOrderHelper()) diff --git a/src/main/java/at/hannibal2/skyhanni/utils/renderables/RenderLineTooltips.kt b/src/main/java/at/hannibal2/skyhanni/utils/renderables/RenderLineTooltips.kt deleted file mode 100644 index 09ab434d0..000000000 --- a/src/main/java/at/hannibal2/skyhanni/utils/renderables/RenderLineTooltips.kt +++ /dev/null @@ -1,148 +0,0 @@ -package at.hannibal2.skyhanni.utils.renderables - -import at.hannibal2.skyhanni.utils.ItemUtils.getLore -import at.hannibal2.skyhanni.utils.LorenzColor -import at.hannibal2.skyhanni.utils.RenderUtils -import at.hannibal2.skyhanni.utils.renderables.RenderableUtils.renderXAligned -import io.github.moulberry.notenoughupdates.util.Utils -import java.awt.Color -import net.minecraft.client.Minecraft -import net.minecraft.client.gui.ScaledResolution -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.client.renderer.RenderHelper -import net.minecraft.item.ItemStack - -object RenderLineTooltips { - - fun drawHoveringText( - posX: Int, posY: Int, - tips: List, - stack: ItemStack? = null, - borderColor: LorenzColor? = null, - snapsToTopIfToLong: Boolean = true, - mouseX: Int = Utils.getMouseX(), - mouseY: Int = Utils.getMouseY(), - ) { - if (tips.isEmpty()) return - - val (xTranslate, yTranslate, _) = RenderUtils.absoluteTranslation - - val x = mouseX - posX + 12 - val y = mouseY - posY - if (tips.size > 1) 2 else -7 - val color: Char = borderColor?.chatColorCode ?: stack?.getLore()?.lastOrNull()?.take(4)?.get(1) - ?: 'f' - val colourInt = Minecraft.getMinecraft().fontRendererObj.getColorCode(color) - val borderColorStart = Color(colourInt).darker().rgb and 0x00FFFFFF or (200 shl 24) - val scaled = ScaledResolution(Minecraft.getMinecraft()) - - val tooltipTextWidth = tips.maxOf { it.width } - val tooltipHeight = tips.sumOf { it.height } - - val tooltipY = when { - y + yTranslate < 16 -> -yTranslate + 4 // Limit Top - y + yTranslate + tooltipHeight > scaled.scaledHeight -> { - if (snapsToTopIfToLong && tooltipHeight + 8 > scaled.scaledHeight) - -yTranslate + 4 // Snap to Top if to Long - else - scaled.scaledHeight - tooltipHeight - 4 - yTranslate // Limit Bottom - } - - else -> { - y - 12 // normal - } - } - val tooltipX = if (x + tooltipTextWidth + 4 + xTranslate > scaled.scaledWidth) { - scaled.scaledWidth - tooltipTextWidth - 4 - xTranslate // Limit Right - } else { - x // normal - } - - GlStateManager.disableRescaleNormal() - RenderHelper.disableStandardItemLighting() - GlStateManager.enableDepth() - - val zLevel = 300f - GlStateManager.translate(tooltipX.toFloat(), tooltipY.toFloat(), zLevel) - - RenderUtils.drawGradientRect( - left = -3, - top = -4, - right = tooltipTextWidth + 3, - bottom = -3, - ) - RenderUtils.drawGradientRect( - left = -3, - top = tooltipHeight + 3, - right = tooltipTextWidth + 3, - bottom = tooltipHeight + 4, - ) - RenderUtils.drawGradientRect( - left = -3, - top = -3, - right = tooltipTextWidth + 3, - bottom = tooltipHeight + 3, - ) - RenderUtils.drawGradientRect( - left = -4, - top = -3, - right = -3, - bottom = tooltipHeight + 3, - ) - RenderUtils.drawGradientRect( - left = tooltipTextWidth + 3, - top = -3, - right = tooltipTextWidth + 4, - bottom = tooltipHeight + 3, - ) - val borderColorEnd = borderColorStart and 0xFEFEFE shr 1 or (borderColorStart and -0x1000000) - RenderUtils.drawGradientRect( - left = -3, - top = -3 + 1, - right = -3 + 1, - bottom = tooltipHeight + 3 - 1, - startColor = borderColorStart, - endColor = borderColorEnd - ) - RenderUtils.drawGradientRect( - left = tooltipTextWidth + 2, - top = -3 + 1, - right = tooltipTextWidth + 3, - bottom = tooltipHeight + 3 - 1, - startColor = borderColorStart, - endColor = borderColorEnd - ) - RenderUtils.drawGradientRect( - left = -3, - top = -3, - right = tooltipTextWidth + 3, - bottom = -3 + 1, - startColor = borderColorStart, - endColor = borderColorStart - ) - RenderUtils.drawGradientRect( - left = -3, - top = tooltipHeight + 2, - right = tooltipTextWidth + 3, - bottom = tooltipHeight + 3, - startColor = borderColorEnd, - endColor = borderColorEnd - ) - GlStateManager.disableDepth() - GlStateManager.translate(0f, 0f, -zLevel) - - var yTranslateSum = 0 - for (line in tips) { - line.renderXAligned(tooltipX, tooltipY, tooltipTextWidth) - val yShift = line.height - GlStateManager.translate(0f, yShift.toFloat(), 0f) - yTranslateSum += yShift - } - - GlStateManager.translate(-tooltipX.toFloat(), -tooltipY.toFloat() + yTranslateSum.toFloat(), 0f) - GlStateManager.enableLighting() - GlStateManager.enableDepth() - RenderHelper.enableStandardItemLighting() - GlStateManager.enableRescaleNormal() - GlStateManager.disableLighting() - } -} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt b/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt index 304e31141..fc1b0f45f 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt @@ -22,7 +22,6 @@ import at.hannibal2.skyhanni.utils.renderables.RenderableUtils.calculateTableYOf import at.hannibal2.skyhanni.utils.renderables.RenderableUtils.renderXAligned import at.hannibal2.skyhanni.utils.renderables.RenderableUtils.renderXYAligned import at.hannibal2.skyhanni.utils.renderables.RenderableUtils.renderYAligned -import io.github.moulberry.notenoughupdates.util.Utils import io.github.notenoughupdates.moulconfig.gui.GuiScreenElementWrapper import net.minecraft.client.Minecraft import net.minecraft.client.gui.Gui @@ -210,15 +209,11 @@ interface Renderable { GlStateManager.pushMatrix() GlStateManager.translate(0F, 0F, 400F) - RenderLineTooltips.drawHoveringText( - posX = posX, - posY = posY, + RenderableTooltips.setTooltipForRender( tips = tipsRender, stack = stack, borderColor = color, snapsToTopIfToLong = snapsToTopIfToLong, - mouseX = currentRenderPassMousePosition?.first ?: Utils.getMouseX(), - mouseY = currentRenderPassMousePosition?.second ?: Utils.getMouseY(), ) GlStateManager.popMatrix() } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/renderables/RenderableTooltips.kt b/src/main/java/at/hannibal2/skyhanni/utils/renderables/RenderableTooltips.kt new file mode 100644 index 000000000..14e4fde13 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/utils/renderables/RenderableTooltips.kt @@ -0,0 +1,174 @@ +package at.hannibal2.skyhanni.utils.renderables + +import at.hannibal2.skyhanni.utils.ItemUtils.getLore +import at.hannibal2.skyhanni.utils.LorenzColor +import at.hannibal2.skyhanni.utils.RenderUtils +import at.hannibal2.skyhanni.utils.renderables.RenderableUtils.renderXAligned +import io.github.moulberry.notenoughupdates.util.Utils +import net.minecraft.client.Minecraft +import net.minecraft.client.gui.ScaledResolution +import net.minecraft.client.renderer.GlStateManager +import net.minecraft.client.renderer.RenderHelper +import net.minecraft.item.ItemStack +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.fml.common.gameevent.TickEvent +import net.minecraftforge.fml.common.gameevent.TickEvent.RenderTickEvent +import java.awt.Color + +object RenderableTooltips { + + private var tooltip: DeferredTooltip? = null + + @SubscribeEvent + fun onPostRenderTick(event: RenderTickEvent) { + if (event.phase == TickEvent.Phase.START) { + tooltip = null + } else if (event.phase == TickEvent.Phase.END) { + drawHoveringText() + } + } + + fun setTooltipForRender( + tips: List, + stack: ItemStack? = null, + borderColor: LorenzColor? = null, + snapsToTopIfToLong: Boolean = true, + ) { + tooltip = DeferredTooltip(tips, stack, borderColor, snapsToTopIfToLong) + } + + private fun drawHoveringText() { + val tooltip = tooltip ?: return + val tips = tooltip.tips + if (tips.isEmpty()) return + + val x = Utils.getMouseX() + 12 + val y = Utils.getMouseY() - if (tips.size > 1) 2 else -7 + val borderColorStart = Color(tooltip.getBorderColor()).darker().rgb and 0x00FFFFFF or (200 shl 24) + val scaled = ScaledResolution(Minecraft.getMinecraft()) + + val tooltipTextWidth = tips.maxOf { it.width } + val tooltipHeight = tips.sumOf { it.height } + + val tooltipY = when { + y < 16 -> 4 // Limit Top + y + tooltipHeight > scaled.scaledHeight -> { + if (tooltip.snapsToTopIfToLong && tooltipHeight + 8 > scaled.scaledHeight) + 4 // Snap to Top if to Long + else + scaled.scaledHeight - tooltipHeight - 4 // Limit Bottom + } + + else -> { + y - 12 // normal + } + } + val tooltipX = if (x + tooltipTextWidth + 4 > scaled.scaledWidth) { + scaled.scaledWidth - tooltipTextWidth - 4 // Limit Right + } else { + x // normal + } + + GlStateManager.disableRescaleNormal() + RenderHelper.disableStandardItemLighting() + GlStateManager.enableDepth() + + val zLevel = 300f + GlStateManager.translate(tooltipX.toFloat(), tooltipY.toFloat(), zLevel) + + RenderUtils.drawGradientRect( + left = -3, + top = -4, + right = tooltipTextWidth + 3, + bottom = -3, + ) + RenderUtils.drawGradientRect( + left = -3, + top = tooltipHeight + 3, + right = tooltipTextWidth + 3, + bottom = tooltipHeight + 4, + ) + RenderUtils.drawGradientRect( + left = -3, + top = -3, + right = tooltipTextWidth + 3, + bottom = tooltipHeight + 3, + ) + RenderUtils.drawGradientRect( + left = -4, + top = -3, + right = -3, + bottom = tooltipHeight + 3, + ) + RenderUtils.drawGradientRect( + left = tooltipTextWidth + 3, + top = -3, + right = tooltipTextWidth + 4, + bottom = tooltipHeight + 3, + ) + val borderColorEnd = borderColorStart and 0xFEFEFE shr 1 or (borderColorStart and -0x1000000) + RenderUtils.drawGradientRect( + left = -3, + top = -3 + 1, + right = -3 + 1, + bottom = tooltipHeight + 3 - 1, + startColor = borderColorStart, + endColor = borderColorEnd + ) + RenderUtils.drawGradientRect( + left = tooltipTextWidth + 2, + top = -3 + 1, + right = tooltipTextWidth + 3, + bottom = tooltipHeight + 3 - 1, + startColor = borderColorStart, + endColor = borderColorEnd + ) + RenderUtils.drawGradientRect( + left = -3, + top = -3, + right = tooltipTextWidth + 3, + bottom = -3 + 1, + startColor = borderColorStart, + endColor = borderColorStart + ) + RenderUtils.drawGradientRect( + left = -3, + top = tooltipHeight + 2, + right = tooltipTextWidth + 3, + bottom = tooltipHeight + 3, + startColor = borderColorEnd, + endColor = borderColorEnd + ) + GlStateManager.disableDepth() + GlStateManager.translate(0f, 0f, -zLevel) + + var yTranslateSum = 0 + for (line in tips) { + line.renderXAligned(tooltipX, tooltipY, tooltipTextWidth) + val yShift = line.height + GlStateManager.translate(0f, yShift.toFloat(), 0f) + yTranslateSum += yShift + } + + GlStateManager.translate(-tooltipX.toFloat(), -tooltipY.toFloat() + yTranslateSum.toFloat(), 0f) + GlStateManager.enableLighting() + GlStateManager.enableDepth() + RenderHelper.enableStandardItemLighting() + GlStateManager.enableRescaleNormal() + GlStateManager.disableLighting() + } +} + +private data class DeferredTooltip( + val tips: List, + val stack: ItemStack? = null, + val borderColor: LorenzColor? = null, + val snapsToTopIfToLong: Boolean = true, +) { + + fun getBorderColor(): Int { + return Minecraft.getMinecraft().fontRendererObj.getColorCode( + borderColor?.chatColorCode ?: stack?.getLore()?.lastOrNull()?.take(4)?.get(1) ?: 'f' + ) + } +} -- cgit