diff --git a/src/main/java/eu/crushedpixel/replaymod/ReplayMod.java b/src/main/java/eu/crushedpixel/replaymod/ReplayMod.java index 41b0cb0e..0d6860d6 100755 --- a/src/main/java/eu/crushedpixel/replaymod/ReplayMod.java +++ b/src/main/java/eu/crushedpixel/replaymod/ReplayMod.java @@ -20,6 +20,7 @@ import eu.crushedpixel.replaymod.settings.RenderOptions; import eu.crushedpixel.replaymod.settings.ReplaySettings; import eu.crushedpixel.replaymod.utils.ReplayFile; import eu.crushedpixel.replaymod.utils.ReplayFileIO; +import eu.crushedpixel.replaymod.utils.TooltipRenderer; import eu.crushedpixel.replaymod.video.frame.*; import net.minecraft.client.Minecraft; import net.minecraft.client.settings.GameSettings; @@ -41,23 +42,6 @@ import java.util.Queue; @Mod(modid = ReplayMod.MODID, version = ReplayMod.VERSION) public class ReplayMod { - //TODO: Set ReplayHandler replaying to false when replay is exited - //TODO: Hide Titles upon hurrying - - //TODO: Show the player whether he has already uploaded a replay - - //TODO: help page - - //TODO: Add "Miscellaneous" Replay Category - - //XXX - //Known Bugs - // - //Keyframes have problems with Linear Paths - //Rain isn't working - //Incompatible with Shaders Mod - // - public static final String MODID = "replaymod"; public static final String VERSION = "0.0.1"; public static final ApiClient apiClient = new ApiClient(); @@ -78,6 +62,7 @@ public class ReplayMod { public static FavoritedFileHandler favoritedFileHandler; public static RatedFileHandler ratedFileHandler; public static SpectatorRenderer spectatorRenderer; + public static TooltipRenderer tooltipRenderer; // The instance of your mod that Forge uses. @Instance(value = "ReplayModID") @@ -137,6 +122,8 @@ public class ReplayMod { e.printStackTrace(); } + tooltipRenderer = new TooltipRenderer(); + mc.getRenderManager().skinMap.put("default", new InvisibilityRender(mc.getRenderManager())); mc.getRenderManager().skinMap.put("slim", new InvisibilityRender(mc.getRenderManager(), true)); diff --git a/src/main/java/eu/crushedpixel/replaymod/events/GuiEventHandler.java b/src/main/java/eu/crushedpixel/replaymod/events/GuiEventHandler.java index 339fab50..ccc1fd04 100755 --- a/src/main/java/eu/crushedpixel/replaymod/events/GuiEventHandler.java +++ b/src/main/java/eu/crushedpixel/replaymod/events/GuiEventHandler.java @@ -97,12 +97,12 @@ public class GuiEventHandler { if(replayCount == 0) { if(editorButton.isMouseOver()) { Point mouse = MouseUtils.getMousePos(); - e.gui.drawCenteredString(mc.fontRendererObj, I18n.format("replaymod.gui.morereplays"), (int) mouse.getX(), (int) mouse.getY() + 4, Color.RED.getRGB()); + ReplayMod.tooltipRenderer.drawTooltip(mouse.getX(), mouse.getY(), I18n.format("replaymod.gui.morereplays"), e.gui, Color.RED.getRGB()); } } else if(!VersionValidator.isValid) { if(editorButton.isMouseOver()) { Point mouse = MouseUtils.getMousePos(); - e.gui.drawCenteredString(mc.fontRendererObj, I18n.format("replaymod.gui.java"), (int) mouse.getX(), (int) mouse.getY() + 4, Color.RED.getRGB()); + ReplayMod.tooltipRenderer.drawTooltip(mouse.getX(), mouse.getY(), I18n.format("replaymod.gui.java"), e.gui, Color.RED.getRGB()); } } } diff --git a/src/main/java/eu/crushedpixel/replaymod/gui/GuiPlayerOverview.java b/src/main/java/eu/crushedpixel/replaymod/gui/GuiPlayerOverview.java index dbdbb5c6..88951334 100755 --- a/src/main/java/eu/crushedpixel/replaymod/gui/GuiPlayerOverview.java +++ b/src/main/java/eu/crushedpixel/replaymod/gui/GuiPlayerOverview.java @@ -278,15 +278,15 @@ public class GuiPlayerOverview extends GuiScreen implements GuiReplayOverlay.NoO rememberHidden.drawButton(mc, mouseX, mouseY); if(hideAllBox.isMouseOver()) { - drawCenteredString(fontRendererObj, I18n.format("replaymod.gui.playeroverview.hideall"), mouseX, mouseY+5, Color.WHITE.getRGB()); + ReplayMod.tooltipRenderer.drawTooltip(mouseX, mouseY, I18n.format("replaymod.gui.playeroverview.hideall"), this, Color.WHITE.getRGB()); } if(showAllBox.isMouseOver()) { - drawCenteredString(fontRendererObj, I18n.format("replaymod.gui.playeroverview.showall"), mouseX, mouseY+5, Color.WHITE.getRGB()); + ReplayMod.tooltipRenderer.drawTooltip(mouseX, mouseY, I18n.format("replaymod.gui.playeroverview.showall"), this, Color.WHITE.getRGB()); } if(rememberHidden.isMouseOver()) { - drawCenteredString(fontRendererObj, I18n.format("replaymod.gui.playeroverview.remembersettings.description"), mouseX, mouseY+5, Color.WHITE.getRGB()); + ReplayMod.tooltipRenderer.drawTooltip(mouseX, mouseY, I18n.format("replaymod.gui.playeroverview.remembersettings.description"), this, Color.WHITE.getRGB()); } //this is necessary to reset the GL parameters for further GUI rendering diff --git a/src/main/java/eu/crushedpixel/replaymod/gui/elements/GuiTimeline.java b/src/main/java/eu/crushedpixel/replaymod/gui/elements/GuiTimeline.java index ecab3eea..1b5482e5 100644 --- a/src/main/java/eu/crushedpixel/replaymod/gui/elements/GuiTimeline.java +++ b/src/main/java/eu/crushedpixel/replaymod/gui/elements/GuiTimeline.java @@ -1,8 +1,11 @@ package eu.crushedpixel.replaymod.gui.elements; +import eu.crushedpixel.replaymod.ReplayMod; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Gui; +import java.awt.*; + import static eu.crushedpixel.replaymod.gui.overlay.GuiReplayOverlay.TEXTURE_SIZE; import static eu.crushedpixel.replaymod.gui.overlay.GuiReplayOverlay.replay_gui; import static org.lwjgl.opengl.GL11.GL_BLEND; @@ -149,7 +152,7 @@ public class GuiTimeline extends Gui { if (mouseTime != -1) { long sec = mouseTime / 1000; String timestamp = String.format("%02d:%02ds", sec / 60, sec % 60); - drawCenteredString(mc.fontRendererObj, timestamp, mouseX, mouseY + 5, 0xffffffff); + ReplayMod.tooltipRenderer.drawTooltip(mouseX, mouseY, timestamp, null, Color.WHITE.getRGB()); } } diff --git a/src/main/java/eu/crushedpixel/replaymod/gui/online/GuiReplayCenter.java b/src/main/java/eu/crushedpixel/replaymod/gui/online/GuiReplayCenter.java index 458d5d0a..db38253d 100755 --- a/src/main/java/eu/crushedpixel/replaymod/gui/online/GuiReplayCenter.java +++ b/src/main/java/eu/crushedpixel/replaymod/gui/online/GuiReplayCenter.java @@ -317,7 +317,7 @@ public class GuiReplayCenter extends GuiScreen implements GuiYesNoCallback { if(((favButton.isMouseOver() && !favButton.enabled) || (likeButton.isMouseOver() && !likeButton.enabled) || (dislikeButton.isMouseOver() && !dislikeButton.enabled ))&& currentList.selected != -1) { - this.drawCenteredString(fontRendererObj, I18n.format("replaymod.gui.center.downloadrequired"), mouseX, mouseY + 4, Color.RED.getRGB()); + ReplayMod.tooltipRenderer.drawTooltip(mouseX, mouseY, I18n.format("replaymod.gui.center.downloadrequired"), this, Color.RED.getRGB()); } this.drawCenteredString(fontRendererObj, I18n.format("replaymod.gui.replaycenter"), this.width / 2, 5, Color.WHITE.getRGB()); diff --git a/src/main/java/eu/crushedpixel/replaymod/gui/replayeditor/GuiReplayEditor.java b/src/main/java/eu/crushedpixel/replaymod/gui/replayeditor/GuiReplayEditor.java index 07b4c885..fa6b55dc 100755 --- a/src/main/java/eu/crushedpixel/replaymod/gui/replayeditor/GuiReplayEditor.java +++ b/src/main/java/eu/crushedpixel/replaymod/gui/replayeditor/GuiReplayEditor.java @@ -4,6 +4,7 @@ import eu.crushedpixel.replaymod.ReplayMod; import eu.crushedpixel.replaymod.gui.GuiConstants; import eu.crushedpixel.replaymod.gui.elements.GuiDropdown; import eu.crushedpixel.replaymod.utils.ReplayFileIO; +import eu.crushedpixel.replaymod.utils.StringUtils; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiMainMenu; import net.minecraft.client.gui.GuiScreen; @@ -162,30 +163,11 @@ public class GuiReplayEditor extends GuiScreen { drawCenteredString(fontRendererObj, "§n" + currentTab.getStudioPart().getTitle(), width / 2, 92, Color.WHITE.getRGB()); - List rows = new ArrayList(); - String remaining = currentTab.getStudioPart().getDescription(); - while(remaining.length() > 0) { - String[] split = remaining.split(" "); - String b = ""; - for(String sp : split) { - b += sp + " "; - if(fontRendererObj.getStringWidth(b.trim()) > width - 30 - 70 - 20) { - b = b.substring(0, b.trim().length() - (sp.length())); - break; - } - } - String trimmed = b.trim(); - rows.add(trimmed); - try { - remaining = remaining.substring(trimmed.length() + 1); - } catch(Exception e) { - break; - } - } + String[] rows = StringUtils.splitStringInMultipleRows(currentTab.getStudioPart().getDescription(), width - 30 - 70 - 20); int i = 0; for(String row : rows) { - drawString(fontRendererObj, row, 30, height - (15 * (rows.size() - i)), Color.WHITE.getRGB()); + drawString(fontRendererObj, row, 30, height - (15 * (rows.length - i)), Color.WHITE.getRGB()); i++; } diff --git a/src/main/java/eu/crushedpixel/replaymod/gui/replayviewer/GuiReplayViewer.java b/src/main/java/eu/crushedpixel/replaymod/gui/replayviewer/GuiReplayViewer.java index 96254a4c..9f57fdfe 100755 --- a/src/main/java/eu/crushedpixel/replaymod/gui/replayviewer/GuiReplayViewer.java +++ b/src/main/java/eu/crushedpixel/replaymod/gui/replayviewer/GuiReplayViewer.java @@ -154,10 +154,10 @@ public class GuiReplayViewer extends GuiScreen implements GuiYesNoCallback { if(uploadButton.isMouseOver() && !uploadButton.enabled && loadButton.enabled) { if(!AuthenticationHandler.isAuthenticated()) { Point mouse = MouseUtils.getMousePos(); - drawCenteredString(mc.fontRendererObj, I18n.format("replaymod.gui.viewer.noauth"), (int) mouse.getX(), (int) mouse.getY() + 4, Color.RED.getRGB()); + ReplayMod.tooltipRenderer.drawTooltip(mouseX, mouseY, I18n.format("replaymod.gui.viewer.noauth"), this, Color.RED.getRGB()); } else if(currentFileUploaded) { Point mouse = MouseUtils.getMousePos(); - drawCenteredString(mc.fontRendererObj, I18n.format("replaymod.gui.viewer.alreadyuploaded"), (int) mouse.getX(), (int) mouse.getY() + 4, Color.RED.getRGB()); + ReplayMod.tooltipRenderer.drawTooltip(mouseX, mouseY, I18n.format("replaymod.gui.viewer.alreadyuploaded"), this, Color.RED.getRGB()); } } } diff --git a/src/main/java/eu/crushedpixel/replaymod/utils/StringUtils.java b/src/main/java/eu/crushedpixel/replaymod/utils/StringUtils.java new file mode 100644 index 00000000..73015df2 --- /dev/null +++ b/src/main/java/eu/crushedpixel/replaymod/utils/StringUtils.java @@ -0,0 +1,36 @@ +package eu.crushedpixel.replaymod.utils; + +import net.minecraft.client.Minecraft; + +import java.util.ArrayList; +import java.util.List; + +public class StringUtils { + + private static final Minecraft mc = Minecraft.getMinecraft(); + + public static String[] splitStringInMultipleRows(String string, int maxWidth) { + List rows = new ArrayList(); + String remaining = string; + while(remaining.length() > 0) { + String[] split = remaining.split(" "); + String b = ""; + for(String sp : split) { + b += sp + " "; + if(mc.fontRendererObj.getStringWidth(b.trim()) > maxWidth) { + b = b.substring(0, b.trim().length() - (sp.length())); + break; + } + } + String trimmed = b.trim(); + rows.add(trimmed); + try { + remaining = remaining.substring(trimmed.length() + 1); + } catch(Exception e) { + break; + } + } + + return rows.toArray(new String[rows.size()]); + } +} diff --git a/src/main/java/eu/crushedpixel/replaymod/utils/TooltipRenderer.java b/src/main/java/eu/crushedpixel/replaymod/utils/TooltipRenderer.java new file mode 100644 index 00000000..0926b544 --- /dev/null +++ b/src/main/java/eu/crushedpixel/replaymod/utils/TooltipRenderer.java @@ -0,0 +1,78 @@ +package eu.crushedpixel.replaymod.utils; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.GuiScreen; + +public class TooltipRenderer extends Gui { + + private final Minecraft mc = Minecraft.getMinecraft(); + + public void drawTooltip(int x, int y, String text, GuiScreen parent, int textColor) { + drawTooltip(x, y, StringUtils.splitStringInMultipleRows(text, 250), parent, textColor); + } + + public void drawTooltip(int x, int y, String[] textLines, GuiScreen parent, int textColor) { + int maxLineWidth = 0; + + int screenWidth, screenHeight; + if(parent == null) { + screenWidth = mc.displayWidth; + screenHeight = mc.displayHeight; + } else { + screenWidth = parent.width; + screenHeight = parent.height; + } + + for(String line : textLines) { + int stringWidth = mc.fontRendererObj.getStringWidth(line); + + if(stringWidth > maxLineWidth) { + maxLineWidth = stringWidth; + } + } + + int j2 = x + 12; + int k2 = y - 12; + int i1 = 8; + + if (textLines.length > 1) { + i1 += 2 + (textLines.length - 1) * 10; + } + + if (j2 + maxLineWidth > screenWidth) { + j2 -= 28 + maxLineWidth; + } + + if (k2 + i1 + 6 > screenHeight) { + k2 = screenHeight - i1 - 6; + } + + int j1 = -267386864; + + this.drawGradientRect(j2 - 3, k2 - 4, j2 + maxLineWidth + 3, k2 - 3, j1, j1); + this.drawGradientRect(j2 - 3, k2 + i1 + 3, j2 + maxLineWidth + 3, k2 + i1 + 4, j1, j1); + this.drawGradientRect(j2 - 3, k2 - 3, j2 + maxLineWidth + 3, k2 + i1 + 3, j1, j1); + this.drawGradientRect(j2 - 4, k2 - 3, j2 - 3, k2 + i1 + 3, j1, j1); + this.drawGradientRect(j2 + maxLineWidth + 3, k2 - 3, j2 + maxLineWidth + 4, k2 + i1 + 3, j1, j1); + + int k1 = 1347420415; + int l1 = (k1 & 16711422) >> 1 | k1 & -16777216; + + this.drawGradientRect(j2 - 3, k2 - 3 + 1, j2 - 3 + 1, k2 + i1 + 3 - 1, k1, l1); + this.drawGradientRect(j2 + maxLineWidth + 2, k2 - 3 + 1, j2 + maxLineWidth + 3, k2 + i1 + 3 - 1, k1, l1); + this.drawGradientRect(j2 - 3, k2 - 3, j2 + maxLineWidth + 3, k2 - 3 + 1, k1, k1); + this.drawGradientRect(j2 - 3, k2 + i1 + 2, j2 + maxLineWidth + 3, k2 + i1 + 3, l1, l1); + + int i = 0; + for(String line : textLines) { + mc.fontRendererObj.drawStringWithShadow(line, j2, k2, textColor); + + if(i == 0) { + k2 += 2; + } + + k2 += 12; + } + } +}