package com.minestellar.core.gui.widget; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.Gui; import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.renderer.RenderHelper; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.util.EnumChatFormatting; import org.lwjgl.input.Mouse; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL12; import com.minestellar.utils.MathHelper; import java.awt.*; import java.awt.geom.Point2D; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class GuiDraw{ public static class GuiHook extends Gui{ public void setZLevel(float f) { zLevel = f; } public float getZLevel() { return zLevel; } public void incZLevel(float f) { zLevel += f; } @Override public void drawGradientRect(int par1, int par2, int par3, int par4, int par5, int par6) { super.drawGradientRect(par1, par2, par3, par4, par5, par6); } } public static final GuiHook gui = new GuiHook(); public static FontRenderer fontRenderer = Minecraft.getMinecraft().fontRenderer; public static TextureManager renderEngine = Minecraft.getMinecraft().renderEngine; public static void drawRect(int x, int y, int w, int h, int colour) { drawGradientRect(x, y, w, h, colour, colour); } public static void drawGradientRect(int x, int y, int w, int h, int colour1, int colour2) { gui.drawGradientRect(x, y, x + w, y + h, colour1, colour2); } public static void drawTexturedModalRect(int x, int y, int tx, int ty, int w, int h) { gui.drawTexturedModalRect(x, y, tx, ty, w, h); } public static void drawString(String text, int x, int y, int colour, boolean shadow) { if (shadow) fontRenderer.drawStringWithShadow(text, x, y, colour); else fontRenderer.drawString(text, x, y, colour); } public static void drawString(String text, int x, int y, int colour) { drawString(text, x, y, colour, true); } public interface ITooltipLineHandler { Dimension getSize(); void draw(int x, int y); } public static int getTipLineId(ITooltipLineHandler handler) { tipLineHandlers.add(handler); return tipLineHandlers.size()-1; } public static ITooltipLineHandler getTipLine(String line) { if(!line.startsWith(TOOLTIP_HANDLER)) return null; return tipLineHandlers.get(Integer.parseInt(line.substring(2))); } public static void drawMultilineTip(int x, int y, List<String> list) { if (list.isEmpty()) return; GL11.glDisable(GL12.GL_RESCALE_NORMAL); GL11.glDisable(GL11.GL_DEPTH_TEST); RenderHelper.disableStandardItemLighting(); int w = 0; int h = -2; for (int i = 0; i < list.size(); i++) { String s = list.get(i); ITooltipLineHandler line = getTipLine(s); Dimension d = line != null ? line.getSize() : new Dimension(getStringWidth(s), list.get(i).endsWith(TOOLTIP_LINESPACE) && i + 1 < list.size() ? 12 : 10); w = Math.max(w, d.width); h += d.height; } if (x < 8) x = 8; else if (x > displaySize().width - w - 8) { x -= 24 + w;//flip side of cursor if(x < 8) x = 8; } y = (int) MathHelper.clip(y, 8, displaySize().height - 8 - h); gui.incZLevel(300); drawTooltipBox(x - 4, y - 4, w + 7, h + 7); for (String s : list) { ITooltipLineHandler line = getTipLine(s); if(line != null) { line.draw(x, y); y += line.getSize().height; } else { fontRenderer.drawStringWithShadow(s, x, y, -1); y += s.endsWith(TOOLTIP_LINESPACE) ? 12 : 10; } } tipLineHandlers.clear(); gui.incZLevel(- 300); GL11.glEnable(GL11.GL_DEPTH_TEST); GL11.glEnable(GL12.GL_RESCALE_NORMAL); RenderHelper.enableGUIStandardItemLighting(); } public static void drawLine(int x1, int y1, int x2, int y2, float thickness, float red, float green, float blue, float alpha){ GL11.glColor4f(red, green, blue, alpha); GL11.glDisable(GL11.GL_LIGHTING); GL11.glDisable(GL11.GL_DEPTH_TEST); GL11.glDepthMask(false); GL11.glEnable(GL11.GL_BLEND); GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); GL11.glLineWidth(thickness); GL11.glDisable(GL11.GL_TEXTURE_2D); GL11.glEnable(GL11.GL_LINE_SMOOTH); GL11.glBegin(GL11.GL_LINES); GL11.glVertex2i(x1, x1); GL11.glVertex2i(x2, y2); GL11.glEnd(); GL11.glEnable(GL11.GL_LIGHTING); GL11.glEnable(GL11.GL_DEPTH_TEST); GL11.glDepthMask(true); GL11.glDisable(GL11.GL_BLEND); GL11.glEnable(GL11.GL_TEXTURE_2D); GL11.glDisable(GL11.GL_LINE_SMOOTH); } public static void drawStringC(String text, int x, int y, int colour, boolean shadow) { drawString(text, x - getStringWidth(text) / 2, y, colour, shadow); } public static void drawStringC(String text, int x, int y, int colour) { drawStringC(text, x, y, colour, true); } public static void drawStringR(String text, int x, int y, int colour, boolean shadow) { drawString(text, x - getStringWidth(text), y, colour, shadow); } public static void drawStringR(String text, int x, int y, int colour) { drawStringR(text, x, y, colour, true); } public static int getStringWidth(String s) { if (s == null || s.equals("")) return 0; return fontRenderer.getStringWidth(EnumChatFormatting.getTextWithoutFormattingCodes(s)); } public static void drawCentered(String s, int x, int y, int colour) { fontRenderer.drawString(s, x - getStringWidth(s) / 2, y, colour); } public static Dimension displaySize() { Minecraft mc = Minecraft.getMinecraft(); ScaledResolution res = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight); return new Dimension(res.getScaledWidth(), res.getScaledHeight()); } public static Dimension displayRes() { Minecraft mc = Minecraft.getMinecraft(); return new Dimension(mc.displayWidth, mc.displayHeight); } public static Point getMousePosition(int eventX, int eventY) { Dimension size = displaySize(); Dimension res = displayRes(); return new Point(eventX * size.width / res.width, size.height - eventY * size.height / res.height - 1); } public static Point getMousePosition() { return getMousePosition(Mouse.getX(), Mouse.getY()); } public static void drawTip(int x, int y, String text) { drawMultilineTip(x, y, Collections.singletonList(text)); } /** * Append a string in the tooltip list with TOOLTIP_LINESPACE to have a small gap between it and the next line */ public static final String TOOLTIP_LINESPACE = "\u00A7h"; /** * Have a string in the tooltip list with TOOLTIP_HANDLER + getTipLineId(handler) for a custom handler */ public static final String TOOLTIP_HANDLER = "\u00A7x"; private static List<ITooltipLineHandler> tipLineHandlers = new ArrayList<ITooltipLineHandler>(); public static void drawTooltipBox(int x, int y, int w, int h) { int bg = 0xf0100010; drawGradientRect(x + 1, y, w - 1, 1, bg, bg); drawGradientRect(x + 1, y + h, w - 1, 1, bg, bg); drawGradientRect(x + 1, y + 1, w - 1, h - 1, bg, bg);// center drawGradientRect(x, y + 1, 1, h - 1, bg, bg); drawGradientRect(x + w, y + 1, 1, h - 1, bg, bg); int grad1 = 0x505000ff; int grad2 = 0x5028007F; drawGradientRect(x + 1, y + 2, 1, h - 3, grad1, grad2); drawGradientRect(x + w - 1, y + 2, 1, h - 3, grad1, grad2); drawGradientRect(x + 1, y + 1, w - 1, 1, grad1, grad1); drawGradientRect(x + 1, y + h - 1, w - 1, 1, grad2, grad2); } /** * Draws a texture of size bigger than 256x256 */ public static void drawNonStandartTexturedRect(int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight) { float f = 1F / (float) textureWidth; float f1 = 1F / (float) textureHeight; Tessellator tessellator = Tessellator.instance; tessellator.startDrawingQuads(); tessellator.addVertexWithUV((double) (x), (double) (y + height), 0, (double) ((float) (u) * f), (double) ((float) (v + height) * f1)); tessellator.addVertexWithUV((double) (x + width), (double) (y + height), 0, (double) ((float) (u + width) * f), (double) ((float) (v + height) * f1)); tessellator.addVertexWithUV((double) (x + width), (double) (y), 0, (double) ((float) (u + width) * f), (double) ((float) (v) * f1)); tessellator.addVertexWithUV((double) (x), (double) (y), 0, (double) ((float) (u) * f), (double) ((float) (v) * f1)); tessellator.draw(); } /** * Draws a texture for the whole screen, even <b>bigger than 256x256</b> */ public static void drawFullscreenImage(int width, int height) { Tessellator tessellator = Tessellator.instance; tessellator.startDrawingQuads(); tessellator.addVertexWithUV(0.0D, (double) height, -90.0D, 0.0D, 1.0D); tessellator.addVertexWithUV((double) width, (double) height, -90.0D, 1.0D, 1.0D); tessellator.addVertexWithUV((double) width, 0.0D, -90.0D, 1.0D, 0.0D); tessellator.addVertexWithUV(0.0D, 0.0D, -90.0D, 0.0D, 0.0D); tessellator.draw(); } public static void drawLine(int x1, int y1, int x2, int y2, float thickness, int red, int green, int blue, int alpha) { GL11.glColor4f(red, green, blue, alpha); GL11.glDisable(GL11.GL_LIGHTING); GL11.glDisable(GL11.GL_DEPTH_TEST); GL11.glDepthMask(false); GL11.glEnable(GL11.GL_BLEND); GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); GL11.glLineWidth(thickness); GL11.glDisable(GL11.GL_TEXTURE_2D); GL11.glEnable(GL11.GL_LINE_SMOOTH); GL11.glBegin(GL11.GL_LINES); GL11.glVertex2i(x1, x1); GL11.glVertex2i(x2, y2); GL11.glEnd(); GL11.glEnable(GL11.GL_LIGHTING); GL11.glEnable(GL11.GL_DEPTH_TEST); GL11.glDepthMask(true); GL11.glDisable(GL11.GL_BLEND); GL11.glEnable(GL11.GL_TEXTURE_2D); GL11.glDisable(GL11.GL_LINE_SMOOTH); } public static void drawLine(int x1, int y1, int x2, int y2, float thickness, int colour) { float f3 = (float) (colour >> 24 & 255) / 255.0F; float f = (float) (colour >> 16 & 255) / 255.0F; float f1 = (float) (colour >> 8 & 255) / 255.0F; float f2 = (float) (colour & 255) / 255.0F; GL11.glColor4f(f, f1, f2, f3); GL11.glDisable(GL11.GL_LIGHTING); GL11.glDisable(GL11.GL_DEPTH_TEST); GL11.glDepthMask(false); GL11.glEnable(GL11.GL_BLEND); GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); GL11.glLineWidth(thickness); GL11.glDisable(GL11.GL_TEXTURE_2D); GL11.glEnable(GL11.GL_LINE_SMOOTH); GL11.glBegin(GL11.GL_LINES); GL11.glVertex2i(x1, x1); GL11.glVertex2i(x2, y2); GL11.glEnd(); GL11.glEnable(GL11.GL_LIGHTING); GL11.glEnable(GL11.GL_DEPTH_TEST); GL11.glDepthMask(true); GL11.glDisable(GL11.GL_BLEND); GL11.glEnable(GL11.GL_TEXTURE_2D); GL11.glDisable(GL11.GL_LINE_SMOOTH); } /** * Draws a circle with the center in P(x,y) * * @param x * The x coordinate of the center * @param y * The y coordinate of the center * @param radius * The radius of the circle * @param colour * The color of the circle * @param definition * How often it draws a line. The higher it is the more smooth it looks. You'll see definition/2 lines * @param isFilled * Whether or not this circle is filled */ public static void drawCircle(int x, int y, int radius, int definition, int colour, boolean isFilled) { float f3 = (float) (colour >> 24 & 255) / 255.0F; float f = (float) (colour >> 16 & 255) / 255.0F; float f1 = (float) (colour >> 8 & 255) / 255.0F; float f2 = (float) (colour & 255) / 255.0F; GL11.glColor4f(f, f1, f2, f3); GL11.glDisable(GL11.GL_LIGHTING); GL11.glDisable(GL11.GL_DEPTH_TEST); GL11.glDepthMask(false); GL11.glEnable(GL11.GL_BLEND); GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); GL11.glDisable(GL11.GL_TEXTURE_2D); Tessellator tes = Tessellator.instance; if (isFilled) tes.startDrawing(GL11.GL_TRIANGLE_FAN); else tes.startDrawing(GL11.GL_LINES); double end = Math.PI * 2.0; double incr = end / definition; for (double theta = -incr; theta < end; theta += incr) { tes.addVertex(x + (radius * Math.cos(-theta)), y + (radius * Math.sin(-theta)), 0.0); } tes.draw(); GL11.glEnable(GL11.GL_LIGHTING); GL11.glEnable(GL11.GL_DEPTH_TEST); GL11.glDepthMask(true); GL11.glDisable(GL11.GL_BLEND); GL11.glEnable(GL11.GL_TEXTURE_2D); GL11.glDisable(GL11.GL_LINE_SMOOTH); } /** * Draws a ellipse with the center in P(x,y) * * @param x * The x coordinate of the center * @param y * The y coordinate of the center * @param radiusX * The radius on the "x" axis of the circle * @param radiusY * The radius on the "y" axis of the circle * @param colour * The color of the ellipse * @param definition * How often it draws a line. The higher it is the more smooth it looks. You'll see definition/2 lines * @param isFilled * Whether or not this ellipse is filled */ public static void drawEllipse(int x, int y, int radiusX, int radiusY, int definition, int colour, boolean isFilled) { float f3 = (float) (colour >> 24 & 255) / 255.0F; float f = (float) (colour >> 16 & 255) / 255.0F; float f1 = (float) (colour >> 8 & 255) / 255.0F; float f2 = (float) (colour & 255) / 255.0F; GL11.glColor4f(f, f1, f2, f3); GL11.glDisable(GL11.GL_LIGHTING); GL11.glDisable(GL11.GL_DEPTH_TEST); GL11.glDepthMask(false); GL11.glEnable(GL11.GL_BLEND); GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); GL11.glDisable(GL11.GL_TEXTURE_2D); Tessellator tes = Tessellator.instance; if (isFilled) tes.startDrawing(GL11.GL_TRIANGLE_FAN); else tes.startDrawing(GL11.GL_LINES); double end = Math.PI * 2.0; double incr = end / definition; for (double theta = -incr; theta < end; theta += incr) { tes.addVertex(x + (radiusX * Math.cos(-theta)), y + (radiusY * Math.sin(-theta)), 0.0); } tes.draw(); GL11.glEnable(GL11.GL_LIGHTING); GL11.glEnable(GL11.GL_DEPTH_TEST); GL11.glDepthMask(true); GL11.glDisable(GL11.GL_BLEND); GL11.glEnable(GL11.GL_TEXTURE_2D); GL11.glDisable(GL11.GL_LINE_SMOOTH); } /** * Fills the array used to describe an ellipse * * @param a * The a coefficient of the ellipse * @param b * The b coefficient of the ellipse * @param array * The array to be filled */ public static void fillEllipseCoordsArray(double a, double b, ArrayList<Point2D.Double> array) { double y = 0.0D; for (double x = a; x >= -a; x -= 0.05) { if (x == 0.0D) { continue; } y = -Math.sqrt((b * b) * (-((x * x) / (a * a)) + 1)); array.add(new Point2D.Double(x, y)); } for (double x = -a; x <= a; x += 0.05) { if (x == 0.0D) { continue; } y = Math.sqrt((b * b) * (-((x * x) / (a * a)) + 1)); array.add(new Point2D.Double(x, y)); } } }