package pneumaticCraft.client.gui.widget; import java.awt.Rectangle; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.Gui; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.renderer.RenderHelper; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.entity.RenderItem; import net.minecraft.client.resources.I18n; import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.MathHelper; import org.lwjgl.input.Mouse; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL12; import pneumaticCraft.api.client.IGuiAnimatedStat; import pneumaticCraft.client.gui.GuiPneumaticContainerBase; import pneumaticCraft.common.util.PneumaticCraftUtils; import pneumaticCraft.lib.GuiConstants; import pneumaticCraft.lib.Textures; import cpw.mods.fml.client.FMLClientHandler; /** * IMPORTANT: WHEN CHANGING THE PACKAGE OF THIS CLASS, ALSO EDIT GUIANIMATEDSTATSUPPLIER.JAVA!! */ public class GuiAnimatedStat implements IGuiAnimatedStat, IGuiWidget, IWidgetListener{ public static final int ANIMATED_STAT_SPEED = 10; private IGuiAnimatedStat affectingStat; private ItemStack iStack; private String texture = ""; private final GuiScreen gui; private final List<String> textList = new ArrayList<String>(); private final List<IGuiWidget> widgets = new ArrayList<IGuiWidget>(); private int baseX; private int baseY; private int affectedY; private int width; private int height; private int oldBaseX; private int oldAffectedY; private int oldWidth; private int oldHeight; private boolean isClicked = false; private int minWidth = 17; private int minHeight = 17; private final int backGroundColor; private String title; private boolean leftSided; // this boolean determines if the stat is going // to expand to the left or right. private boolean doneExpanding; private RenderItem itemRenderer; private float textSize; private float textScale = 1F; private IWidgetListener listener; private int curScroll; private static final int MAX_LINES = 12; private int lastMouseX, lastMouseY; public GuiAnimatedStat(GuiScreen gui, String title, int xPos, int yPos, int backGroundColor, IGuiAnimatedStat affectingStat, boolean leftSided){ this.gui = gui; baseX = xPos; baseY = yPos; this.affectingStat = affectingStat; width = minWidth; height = minHeight; this.backGroundColor = backGroundColor; setTitle(title); texture = ""; this.leftSided = leftSided; if(gui != null) { ScaledResolution sr = new ScaledResolution(Minecraft.getMinecraft(), Minecraft.getMinecraft().displayWidth, Minecraft.getMinecraft().displayHeight); if(sr.getScaledWidth() < 520) { textSize = (sr.getScaledWidth() - 220) * 0.0033F; } else { textSize = 1F; } } else { textSize = 1; } affectedY = baseY; if(affectingStat != null) { affectedY += affectingStat.getAffectedY() + affectingStat.getHeight(); } } public GuiAnimatedStat(GuiScreen gui, int backgroundColor){ this(gui, "", 0, 0, backgroundColor, null, false); } public GuiAnimatedStat(GuiScreen gui, int backgroundColor, ItemStack icon){ this(gui, backgroundColor); iStack = icon; } public GuiAnimatedStat(GuiScreen gui, int backgroundColor, String texture){ this(gui, backgroundColor); this.texture = texture; } public GuiAnimatedStat(GuiScreen gui, String title, ItemStack icon, int xPos, int yPos, int backGroundColor, IGuiAnimatedStat affectingStat, boolean leftSided){ this(gui, title, xPos, yPos, backGroundColor, affectingStat, leftSided); iStack = icon; } public GuiAnimatedStat(GuiScreen gui, String title, String texture, int xPos, int yPos, int backGroundColor, IGuiAnimatedStat affectingStat, boolean leftSided){ this(gui, title, xPos, yPos, backGroundColor, affectingStat, leftSided); this.texture = texture; } @Override public void setParentStat(IGuiAnimatedStat stat){ affectingStat = stat; } public void addWidget(IGuiWidget widget){ widgets.add(widget); widget.setListener(this); } public void removeWidget(IGuiWidget widget){ widgets.remove(widget); } @Override public Rectangle getButtonScaledRectangle(int origX, int origY, int width, int height){ int scaledX = (int)(origX * textSize); int scaledY = (int)(origY * textSize); //scaledX = (int)(origX * textSize); //scaledY = (int)(origY * textSize); return new Rectangle(scaledX, scaledY, (int)(width * textSize), (int)(height * textSize)); } @Override public void scaleTextSize(float scale){ textSize *= scale; textScale = scale; for(IGuiWidget widget : widgets) { if(widget.getID() == -1000) { widgets.remove(widget); break; } } onTextChange(); } @Override public boolean isLeftSided(){ return leftSided; } @Override public void setLeftSided(boolean leftSided){ this.leftSided = leftSided; } @Override public IGuiAnimatedStat setText(List<String> text){ textList.clear(); for(String line : text) { textList.addAll(PneumaticCraftUtils.convertStringIntoList(I18n.format(line), (int)(GuiConstants.maxCharPerLineLeft / textScale))); } onTextChange(); return this; } @Override public IGuiAnimatedStat setText(String text){ textList.clear(); textList.addAll(PneumaticCraftUtils.convertStringIntoList(I18n.format(text), (int)(GuiConstants.maxCharPerLineLeft / textScale))); onTextChange(); return this; } @Override public void setTextWithoutCuttingString(List<String> text){ textList.clear(); textList.addAll(text); onTextChange(); } public void onTextChange(){ if(textList.size() > MAX_LINES) { for(IGuiWidget widget : widgets) { if(widget.getID() == -1000) return; } curScroll = 0; /*Rectangle upRect = getButtonScaledRectangle(2, 24, 20, 20); addWidget(new GuiButtonSpecial(-1000, upRect.x, upRect.y, upRect.width, upRect.height, "^")); Rectangle downRect = getButtonScaledRectangle(2, 44, 20, 20); addWidget(new GuiButtonSpecial(-1001, downRect.x, downRect.y, downRect.width, downRect.height, "V")); */ addWidget(new WidgetVerticalScrollbar(-1000, leftSided ? -16 : 2, 20, (int)((MAX_LINES * 10 - 20) * textSize)).setStates(textList.size() - MAX_LINES)); } else { Iterator<IGuiWidget> iterator = widgets.iterator(); while(iterator.hasNext()) { IGuiWidget widget = iterator.next(); if(widget.getID() == -1000) { iterator.remove(); curScroll = 0; } } } } @Override public void setMinDimensionsAndReset(int minWidth, int minHeight){ this.minWidth = minWidth; this.minHeight = minHeight; width = minWidth; height = minHeight; } @Override public void update(){ oldBaseX = baseX; oldAffectedY = affectedY; oldWidth = width; oldHeight = height; FontRenderer fontRenderer = FMLClientHandler.instance().getClient().fontRenderer; doneExpanding = true; if(isClicked) { // calculate the width and height needed for the box to fit the // strings. int maxWidth = fontRenderer.getStringWidth(title); int maxHeight = 12; if(textList.size() > 0) { maxHeight += 4 + Math.min(MAX_LINES, textList.size()) * 10; } maxHeight = (int)(maxHeight * textSize); for(String line : textList) { if(fontRenderer.getStringWidth(line) > maxWidth) maxWidth = fontRenderer.getStringWidth(line); } maxWidth = (int)(maxWidth * textSize); maxWidth += 20; // expand the box for(int i = 0; i < ANIMATED_STAT_SPEED; i++) { if(width < maxWidth) { width++; doneExpanding = false; } if(height < maxHeight) { height++; doneExpanding = false; } if(width > maxWidth) width--; if(height > maxHeight) height--; } if(doneExpanding) { for(IGuiWidget widget : widgets) { if(widget.getID() == -1000) { curScroll = ((WidgetVerticalScrollbar)widget).getState(); } } } } else { for(int i = 0; i < ANIMATED_STAT_SPEED; i++) { if(width > minWidth) width--; if(height > minHeight) height--; } doneExpanding = false; } affectedY = baseY; if(affectingStat != null) { affectedY += affectingStat.getAffectedY() + affectingStat.getHeight(); } } @Override public void render(int mouseX, int mouseY, float partialTicks){ lastMouseX = mouseX; lastMouseY = mouseY; float zLevel = 0; FontRenderer fontRenderer = Minecraft.getMinecraft().fontRenderer; int renderBaseX = (int)(oldBaseX + (baseX - oldBaseX) * partialTicks); int renderAffectedY = (int)(oldAffectedY + (affectedY - oldAffectedY) * partialTicks); int renderWidth = (int)(oldWidth + (width - oldWidth) * partialTicks); int renderHeight = (int)(oldHeight + (height - oldHeight) * partialTicks); if(leftSided) renderWidth *= -1; Gui.drawRect(renderBaseX, renderAffectedY /* + 1 */, renderBaseX + renderWidth /*- 1*/, renderAffectedY + renderHeight, backGroundColor); GL11.glDisable(GL11.GL_TEXTURE_2D); GL11.glLineWidth(3.0F); GL11.glColor4d(0, 0, 0, 1); Tessellator tess = Tessellator.instance; tess.startDrawing(GL11.GL_LINE_LOOP); tess.addVertex(renderBaseX, renderAffectedY, zLevel); tess.addVertex(renderBaseX + renderWidth, renderAffectedY, zLevel); tess.addVertex(renderBaseX + renderWidth, renderAffectedY + renderHeight, zLevel); tess.addVertex(renderBaseX, renderAffectedY + renderHeight, zLevel); tess.draw(); GL11.glEnable(GL11.GL_TEXTURE_2D); if(leftSided) renderWidth *= -1; // if done expanding, draw the information if(doneExpanding) { GL11.glPushMatrix(); GL11.glTranslated(renderBaseX + (leftSided ? -renderWidth : 16), renderAffectedY, 0); GL11.glScaled(textSize, textSize, textSize); GL11.glTranslated(-renderBaseX - (leftSided ? -renderWidth : 16), -renderAffectedY, 0); fontRenderer.drawStringWithShadow(title, renderBaseX + (leftSided ? -renderWidth + 2 : 18), renderAffectedY + 2, 0xFFFF00); for(int i = curScroll; i < textList.size() && i < curScroll + MAX_LINES; i++) { if(textList.get(i).contains("\u00a70") || textList.get(i).contains(EnumChatFormatting.DARK_RED.toString())) { fontRenderer.drawString(textList.get(i), renderBaseX + (leftSided ? -renderWidth + 2 : 18), renderAffectedY + (i - curScroll) * 10 + 12, 0xFFFFFF); } else { fontRenderer.drawStringWithShadow(textList.get(i), renderBaseX + (leftSided ? -renderWidth + 2 : 18), renderAffectedY + (i - curScroll) * 10 + 12, 0xFFFFFF); } } GL11.glPopMatrix(); GL11.glPushMatrix(); GL11.glTranslated(renderBaseX, renderAffectedY, 0); GL11.glEnable(GL11.GL_TEXTURE_2D); for(IGuiWidget widget : widgets) widget.render(mouseX - renderBaseX, mouseY - renderAffectedY, partialTicks); GL11.glPopMatrix(); } if(renderHeight > 16 && renderWidth > 16) { GL11.glColor4d(1, 1, 1, 1); GL11.glEnable(GL11.GL_BLEND); GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); if(iStack == null) { if(texture.contains(Textures.GUI_LOCATION)) { GuiPneumaticContainerBase.drawTexture(texture, renderBaseX - (leftSided ? 16 : 0), renderAffectedY); } else { fontRenderer.drawString(texture, renderBaseX - (leftSided ? 16 : 0), renderAffectedY, 0xFFFFFFFF); } } else if(gui != null || !(iStack.getItem() instanceof ItemBlock)) { if(itemRenderer == null) itemRenderer = new RenderItem(); itemRenderer.zLevel = 1; GL11.glPushMatrix(); GL11.glTranslated(0, 0, -50); GL11.glEnable(GL12.GL_RESCALE_NORMAL); RenderHelper.enableGUIStandardItemLighting(); itemRenderer.renderItemAndEffectIntoGUI(fontRenderer, FMLClientHandler.instance().getClient().renderEngine, iStack, renderBaseX - (leftSided ? 16 : 0), renderAffectedY); GL11.glEnable(GL11.GL_ALPHA_TEST); RenderHelper.disableStandardItemLighting(); GL11.glDisable(GL12.GL_RESCALE_NORMAL); GL11.glPopMatrix(); } } } /* * button: 0 = left 1 = right 2 = middle */ @Override public void onMouseClicked(int mouseX, int mouseY, int button){ if(button == 0) { isClicked = !isClicked; listener.actionPerformed(this); } mouseX -= baseX; mouseY -= affectedY; for(IGuiWidget widget : widgets) { if(widget.getBounds().contains(mouseX, mouseY)) { widget.onMouseClicked(mouseX, mouseY, button); isClicked = true; } } } @Override public void onMouseClickedOutsideBounds(int mouseX, int mouseY, int button){ } @Override public void closeWindow(){ isClicked = false; } @Override public void openWindow(){ isClicked = true; } @Override public boolean isClicked(){ return isClicked; } @Override public int getAffectedY(){ return affectedY; } @Override public int getBaseX(){ return baseX; } @Override public int getBaseY(){ return baseY; } @Override public int getHeight(){ return height; } @Override public int getWidth(){ return width; } @Override public void setBaseY(int y){ baseY = y; } @Override public void setTitle(String title){ this.title = I18n.format(title); } @Override public boolean isDoneExpanding(){ return doneExpanding; } @Override public void setBaseX(int x){ baseX = x; } @Override public String getTitle(){ return title; } @Override public Rectangle getBounds(){ return new Rectangle(baseX - (leftSided ? width : 0), affectedY, width, height); } @Override public void setListener(IWidgetListener gui){ listener = gui; } @Override public int getID(){ return -1; } @Override public void actionPerformed(IGuiWidget widget){ isClicked = !isClicked; listener.actionPerformed(widget); } @Override public void onKeyTyped(IGuiWidget widget){ listener.onKeyTyped(widget); } @Override public void addTooltip(int mouseX, int mouseY, List<String> curTooltip, boolean shiftPressed){ if(mouseIsHoveringOverIcon(mouseX, mouseY)) { curTooltip.add(title); } for(IGuiWidget widget : widgets) if(isMouseOverWidget(widget, mouseX, mouseY)) widget.addTooltip(mouseX, mouseY, curTooltip, shiftPressed); } private boolean mouseIsHoveringOverIcon(int x, int y){ if(leftSided) { return x <= baseX && x >= baseX - 16 && y >= affectedY && y <= affectedY + 16; } else { return x >= baseX && x <= baseX + 16 && y >= affectedY && y <= affectedY + 16; } } @Override public boolean onKey(char key, int keyCode){ for(IGuiWidget widget : widgets) if(widget.onKey(key, keyCode)) return true; return false; } private boolean isMouseOverWidget(IGuiWidget widget, int mouseX, int mouseY){ Rectangle rect = getBounds(); mouseX -= rect.x; mouseY -= rect.y; return widget.getBounds().contains(mouseX, mouseY); } @Override public void handleMouseInput(){ if(getBounds().contains(lastMouseX, lastMouseY)) { handleMouseWheel(Mouse.getDWheel()); } } public boolean handleMouseWheel(int mouseWheel){ for(IGuiWidget widget : widgets) { widget.handleMouseInput(); if(widget.getID() == -1000) { int wheel = -mouseWheel; wheel = MathHelper.clamp_int(wheel, -1, 1); ((WidgetVerticalScrollbar)widget).currentScroll += (float)wheel / (textList.size() - MAX_LINES); return true; } } return false; } @Override public void postRender(int mouseX, int mouseY, float partialTick){ } }