package gminers.glasspane.component.text; import gminers.glasspane.HorzAlignment; import gminers.glasspane.VertAlignment; import gminers.glasspane.component.ColorablePaneComponent; import gminers.kitchensink.Rendering; import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; import lombok.ToString; import lombok.experimental.FieldDefaults; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import org.lwjgl.opengl.GL11; /** * Implements a simple component that displays some text. * * @author Aesen Vismea * */ @FieldDefaults(level = AccessLevel.PROTECTED) @ToString @Getter @Setter public class PaneLabel extends ColorablePaneComponent { /** * The text to render for this label. Allows newlines. */ @Setter(AccessLevel.NONE) String text = ""; /** * The font renderer to use for the text of this label. * * @see Minecraft#fontRenderer * @see Minecraft#standardGalacticFontRenderer */ FontRenderer renderer = Minecraft.getMinecraft().fontRendererObj; /** * Whether or not to render a shadow for this text. */ boolean shadow = true; /** * Whether or not to outline this text. */ boolean outlined = false; /** * Whether or not to put a more vibrant color for the outline, instead of the default of a darker color. */ boolean invertedOutline = false; /** * The X alignment of this label. */ HorzAlignment alignmentX = HorzAlignment.LEFT; /** * The Y alignment of this label. */ VertAlignment alignmentY = VertAlignment.TOP; /** * Whether or not to render this label at 50% size. */ boolean small = false; /** * The amount of pixels between lines of text. */ int lineSpacing = 4; public PaneLabel() { recalculateSize(); } public PaneLabel(final String text) { this.text = text; recalculateSize(); } public PaneLabel(final String text, final int color) { this.text = text; recalculateSize(); this.color = color; } public PaneLabel(final String text, final int color, final FontRenderer renderer) { this.text = text; recalculateSize(); this.color = color; this.renderer = renderer; } public int getLineCount() { if (text.trim().isEmpty()) return 0; if (text.contains("\n")) return text.split("\n").length; else return 1; } public int getLongestLineWidth() { if (text.contains("\n")) { int work = 0; for (final String s : text.split("\n")) { work = Math.max(renderer.getStringWidth(s), work); } return work; } else return renderer.getStringWidth(text); } /** * The text to render for this label. Allows newlines. */ public void setText(final String text) { this.text = text; recalculateSize(); } protected void recalculateSize() { int addX = 0; int addY = 0; final boolean addToX = alignmentX == HorzAlignment.LEFT || alignmentX == HorzAlignment.MIDDLE; final boolean addToY = alignmentY == VertAlignment.TOP || alignmentY == VertAlignment.MIDDLE; if (outlined) { addX += 2; addY += 2; } if (shadow) { addX += 1; addY += 1; } if (alignmentY == VertAlignment.TOP) { height = ((getLineCount() * (renderer.FONT_HEIGHT + lineSpacing)) - lineSpacing) + (addToX ? addX : 0); } if (alignmentX == HorzAlignment.LEFT) { width = getLongestLineWidth() + (addToY ? addY : 0); } } @Override protected void doRender(final int mouseX, final int mouseY, final float partialTicks) { if (small) { GL11.glScalef(0.5f, 0.5f, 1.0f); } if (text.contains("\n")) { int offset = 0; for (final String s : text.split("\n")) { draw(s, offset); offset += renderer.FONT_HEIGHT + lineSpacing; } } else { draw(text, 0); } } private void draw(final String s, final int offset) { int adjX = 0; int adjY = 0; if (alignmentX == HorzAlignment.MIDDLE) { adjX = width / 2 - renderer.getStringWidth(s) / (small ? 4 : 2); if (outlined) { adjX++; } } else if (alignmentX == HorzAlignment.RIGHT) { adjX = width - renderer.getStringWidth(s) / (small ? 2 : 1); if (outlined) { adjX--; } } else { if (outlined) { adjX++; } } if (alignmentY == VertAlignment.MIDDLE) { adjY = height / 2 - renderer.FONT_HEIGHT / 2; if (outlined) { adjY--; } } else if (alignmentY == VertAlignment.BOTTOM) { adjY = height - ((getLineCount() * (renderer.FONT_HEIGHT + lineSpacing)) - lineSpacing); if (outlined) { adjY--; } } else { if (outlined) { adjY++; } } if (small) { adjX *= 2; adjY *= 2; } adjY += offset; if (outlined) { if (shadow) { final int shadowColor = (color & 16579836) >> 2 | color & -16777216; Rendering.drawOutlinedString(renderer, s, adjX + 1, adjY + 1, shadowColor, invertedOutline); } Rendering.drawOutlinedString(renderer, s, adjX, adjY, color, invertedOutline); } else { renderer.drawString(s, adjX, adjY, color, shadow); } } /** * Creates and returns a 'title label' - a label that has width set to 100% and Y set to 3, and a MIDDLE X alignment. * * @param text * The text the label should have * @return A newly created 'title label' */ public static PaneLabel createTitleLabel(final String text) { final PaneLabel label = new PaneLabel(text); label.setAutoResizeWidth(true); label.setY(3); label.setAlignmentX(HorzAlignment.MIDDLE); return label; } /** * Creates and returns a 'center label' - a label that has width and height set to 100% and MIDDLE X and Y alignments. * * @param text * The text the label should have * @return A newly created 'center label' */ public static PaneLabel createCenterLabel(final String text) { final PaneLabel label = new PaneLabel(text); label.setAutoResize(true); label.setAlignmentY(VertAlignment.MIDDLE); label.setAlignmentX(HorzAlignment.MIDDLE); return label; } }