From 50db93d77aff4c678fffd8604375497ca27845eb Mon Sep 17 00:00:00 2001 From: YannickMG Date: Tue, 11 Jan 2022 01:38:28 -0500 Subject: The tooltips your mod wishes it had (#858) * Add network support for chanining GT Tile GUIs * Implemented Cover Tabs for IGregTechTileEntity See GTNewHorizons/GT-New-Horizons-Modpack#9367 for details * Added IGuiIcon For easier addon extensibility of GT_GuiIcon Also fixed Ghost Circuit tab tooltip overlapping right-side cover tabs * Typo fix * Fixed unintended scala import * Tabs -> Spaces on the files I've touched * Propagate needsSteamVenting to UIs * Note special slot usage Determine whether a machine's recipe list ever makes use of the special slot * Add 2 configurable tooltip verbosity levels * Readability pass * New tooltip cache for flexibility It loads a configurable amount of lines per key based on the user's chosen verbosity levels * Let GT_GuiTooltipJava to use verbosity and LSHIFT * "Smart" auto-hiding tooltips * GT_GUIContainerMetaTile_Machine tooltip support * Rework Basic Machine tooltips * Wordy tooltips -> extended tooltips (clearer) * Fixed off-by-one error on power slot tooltips * Cleanup --- .../api/gui/widgets/GT_GuiSlotTooltip.java | 22 +++++ .../api/gui/widgets/GT_GuiSmartTooltip.java | 25 ++++++ .../gregtech/api/gui/widgets/GT_GuiTooltip.java | 93 ++++++++++++++++++++-- .../api/gui/widgets/GT_GuiTooltipManager.java | 7 +- 4 files changed, 137 insertions(+), 10 deletions(-) create mode 100644 src/main/java/gregtech/api/gui/widgets/GT_GuiSlotTooltip.java create mode 100644 src/main/java/gregtech/api/gui/widgets/GT_GuiSmartTooltip.java (limited to 'src/main/java/gregtech/api/gui/widgets') diff --git a/src/main/java/gregtech/api/gui/widgets/GT_GuiSlotTooltip.java b/src/main/java/gregtech/api/gui/widgets/GT_GuiSlotTooltip.java new file mode 100644 index 0000000000..1fb25ecb1a --- /dev/null +++ b/src/main/java/gregtech/api/gui/widgets/GT_GuiSlotTooltip.java @@ -0,0 +1,22 @@ +package gregtech.api.gui.widgets; + +import java.awt.Rectangle; + +import gregtech.api.util.GT_TooltipDataCache.TooltipData; +import net.minecraft.inventory.Slot; + +public class GT_GuiSlotTooltip extends GT_GuiTooltip { + private final Slot slot; + + public GT_GuiSlotTooltip(Slot slot, TooltipData data) { + super(new Rectangle(slot.xDisplayPosition - 1, slot.yDisplayPosition - 1, 18, 18), data); + this.slot = slot; + } + + @Override + protected void onTick() { + super.onTick(); + // If disabled by super, stay disabled. + this.enabled = this.enabled && this.slot.getStack() == null; + } +} diff --git a/src/main/java/gregtech/api/gui/widgets/GT_GuiSmartTooltip.java b/src/main/java/gregtech/api/gui/widgets/GT_GuiSmartTooltip.java new file mode 100644 index 0000000000..d4f7df6d2c --- /dev/null +++ b/src/main/java/gregtech/api/gui/widgets/GT_GuiSmartTooltip.java @@ -0,0 +1,25 @@ +package gregtech.api.gui.widgets; + +import java.awt.Rectangle; + +import gregtech.api.util.GT_TooltipDataCache.TooltipData; + +public class GT_GuiSmartTooltip extends GT_GuiTooltip{ + public interface TooltipVisibilityProvider { + boolean shouldShowTooltip(); + } + private final TooltipVisibilityProvider visibilityProvider; + + public GT_GuiSmartTooltip(Rectangle bounds, TooltipVisibilityProvider visibilityProvider, TooltipData data) { + super(bounds, data); + this.visibilityProvider = visibilityProvider; + } + + @Override + protected void onTick() { + super.onTick(); + // If disabled by super, stay disabled. + this.enabled = this.enabled && this.visibilityProvider.shouldShowTooltip(); + } + +} diff --git a/src/main/java/gregtech/api/gui/widgets/GT_GuiTooltip.java b/src/main/java/gregtech/api/gui/widgets/GT_GuiTooltip.java index 6b9e70a71b..815970c754 100644 --- a/src/main/java/gregtech/api/gui/widgets/GT_GuiTooltip.java +++ b/src/main/java/gregtech/api/gui/widgets/GT_GuiTooltip.java @@ -1,38 +1,115 @@ package gregtech.api.gui.widgets; -import java.awt.*; +import java.awt.Rectangle; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import org.lwjgl.input.Keyboard; + +import gregtech.api.util.GT_TooltipDataCache.TooltipData; public class GT_GuiTooltip { protected Rectangle bounds; - private List text; + protected TooltipData data; + private List displayedText; public boolean enabled = true; + /** + * Used to create a tooltip that will appear over the specified bounds. + * This will initially be a "static" tooltip that doesn't respect verbosity levels or respond to the shift key. + * + * @param bounds + * @param text + */ public GT_GuiTooltip(Rectangle bounds, String... text) { this.bounds = bounds; setToolTipText(text); } + /** + * Used to create a tooltip that will appear over the specified bounds. + * This will initially be a "dynamic" tooltip that respects verbosity levels and responds to the shift key. + * + * @param bounds + * @param data + */ + public GT_GuiTooltip(Rectangle bounds, TooltipData data) { + this.bounds = bounds; + // Trust that the tooltips have already been formatted and colored, just make sure it has no nulls + this.data = sanitizeTooltipData(data); + } + + private TooltipData sanitizeTooltipData(TooltipData data) { + if (data.text == null){ + data.text = Arrays.asList(new String[0]); + } + if (data.shiftText == null){ + data.shiftText = Arrays.asList(new String[0]); + } + return data; + } + + /** + * Called before the tooltip manager checks whether this tooltip is enabled + */ + protected void onTick() { + // Switch which of our 2 stored texts we're displaying now. + this.displayedText = Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) ? this.data.shiftText : this.data.text; + // If this text is empty, let's not display a tooltip at all. + this.enabled = this.displayedText.size() != 0; + } + + /** + * Called once this tooltip has been determined to be enabled + */ protected void updateText() { } + /** + * Used to set a "static" tooltip that doesn't respect verbosity levels or respond to the shift key + * + * @param text + */ public void setToolTipText(String... text) { + this.data = formatTooltip(text); + } + + /** + * Used to set a "dynamic" tooltip that respects verbosity levels and responds to the shift key + * + * @param text + */ + public void setToolTipText(TooltipData data) { + // Trust that the tooltips have already been formatted and colored, just make sure it has no nulls + this.data = sanitizeTooltipData(data); + } + + /** + * Apply tooltip colors in case the text doesn't contain them and return as tooltip data + * + * @param text + * @return colored tooltip lines as list + */ + protected TooltipData formatTooltip(String[] text) { + List list; if (text != null) { - this.text = new ArrayList<>(text.length); + list = new ArrayList<>(text.length); for (int i = 0; i < text.length; i++) { if (i == 0) - this.text.add("\u00a7f" + text[i]); + list.add("\u00a7f" + text[i]); else - this.text.add("\u00a77" + text[i]); + list.add("\u00a77" + text[i]); } - } else - this.text = new ArrayList<>(); + } else { + list = Arrays.asList(new String[0]); + } + return new TooltipData(list, list) ; } + public List getToolTipText() { - return text; + return this.displayedText; } public Rectangle getBounds() { diff --git a/src/main/java/gregtech/api/gui/widgets/GT_GuiTooltipManager.java b/src/main/java/gregtech/api/gui/widgets/GT_GuiTooltipManager.java index c098e4e2a7..e2ea65c482 100644 --- a/src/main/java/gregtech/api/gui/widgets/GT_GuiTooltipManager.java +++ b/src/main/java/gregtech/api/gui/widgets/GT_GuiTooltipManager.java @@ -29,10 +29,11 @@ public class GT_GuiTooltipManager { } public final void onTick(GT_IToolTipRenderer render, int mouseX, int mouseY) { - if ((Math.abs(mouseX-lastMouseX) < 2 ) && (Math.abs(mouseY-lastMouseY) < 2 )) + if ((Math.abs(mouseX-lastMouseX) < 2 ) && (Math.abs(mouseY-lastMouseY) < 2 )) { mouseStopped = Math.min(mouseStopped+1, 50); - else + } else { mouseStopped = 0; + } lastMouseX = mouseX; lastMouseY = mouseY; @@ -40,6 +41,8 @@ public class GT_GuiTooltipManager { mouseX -= render.getGuiLeft(); mouseY -= render.getGuiTop(); for (GT_GuiTooltip tip : tips) { + // Give the tooltip the opportunity to decide whether they should be enabled + tip.onTick(); if (tip.enabled && (!tip.isDelayed() || mouseStopped > DELAY) && tip.getBounds().contains(mouseX, mouseY)) { tip.updateText(); drawTooltip(tip, mouseX, mouseY, render); -- cgit