package codechicken.nei; import codechicken.lib.gui.GuiDraw; import codechicken.nei.KeyManager.IKeyStateTracker; import codechicken.nei.api.*; import codechicken.nei.guihook.*; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.gui.inventory.GuiContainerCreative; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.InventoryEffectRenderer; import net.minecraft.inventory.Slot; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import org.lwjgl.opengl.GL11; import java.util.HashMap; import java.util.List; import java.util.TreeSet; import static codechicken.lib.gui.GuiDraw.*; import static codechicken.nei.NEIClientConfig.*; import static codechicken.nei.NEIClientUtils.*; public class LayoutManager implements IContainerInputHandler, IContainerTooltipHandler, IContainerDrawHandler, IContainerObjectHandler, IKeyStateTracker { private static LayoutManager instance; private static Widget inputFocused; /** * Sorted bottom first */ private static TreeSet<Widget> drawWidgets; /** * Sorted top first */ private static TreeSet<Widget> controlWidgets; public static ItemPanel itemPanel; public static SubsetWidget dropDown; public static TextField searchField; public static Button options; public static Button prev; public static Button next; public static Label pageLabel; public static Button more; public static Button less; public static ItemQuantityField quantity; public static SaveLoadButton[] stateButtons; public static Button[] deleteButtons; public static Button delete; public static ButtonCycled gamemode; public static Button rain; public static Button magnet; public static Button[] timeButtons = new Button[4]; public static Button heal; public static IRecipeOverlayRenderer overlayRenderer; public static HashMap<Integer, LayoutStyle> layoutStyles = new HashMap<Integer, LayoutStyle>(); public static void load() { API.addLayoutStyle(0, new LayoutStyleMinecraft()); API.addLayoutStyle(1, new LayoutStyleTMIOld()); instance = new LayoutManager(); KeyManager.trackers.add(instance); GuiContainerManager.addInputHandler(instance); GuiContainerManager.addTooltipHandler(instance); GuiContainerManager.addDrawHandler(instance); GuiContainerManager.addObjectHandler(instance); init(); } @Override public void onPreDraw(GuiContainer gui) { if (!isHidden() && isEnabled() && gui instanceof InventoryEffectRenderer)//Reset the gui to the center of the screen, for potion effect offsets etc { gui.guiLeft = (gui.width - gui.xSize) / 2; gui.guiTop = (gui.height - gui.ySize) / 2; if (gui instanceof GuiContainerCreative && gui.buttonList.size() >= 2) { GuiButton button1 = (GuiButton) gui.buttonList.get(0); GuiButton button2 = (GuiButton) gui.buttonList.get(1); button1.xPosition = gui.guiLeft; button2.xPosition = gui.guiLeft + gui.xSize - 20; } } } @Override public void onMouseClicked(GuiContainer gui, int mousex, int mousey, int button) { if (isHidden()) { return; } for (Widget widget : controlWidgets) { widget.onGuiClick(mousex, mousey); } } @Override public boolean mouseClicked(GuiContainer gui, int mousex, int mousey, int button) { if (isHidden()) { return false; } if (!isEnabled()) { return options.contains(mousex, mousey) && options.handleClick(mousex, mousey, button); } for (Widget widget : controlWidgets) { widget.onGuiClick(mousex, mousey); if (widget.contains(mousex, mousey) ? widget.handleClick(mousex, mousey, button) : widget.handleClickExt(mousex, mousey, button)) { return true; } } return false; } @Override public boolean objectUnderMouse(GuiContainer gui, int mousex, int mousey) { if (!isHidden() && isEnabled()) { for (Widget widget : controlWidgets) { if (widget.contains(mousex, mousey)) { return true; } } } return false; } public boolean keyTyped(GuiContainer gui, char keyChar, int keyID) { if (isEnabled() && !isHidden()) { if (inputFocused != null) { return inputFocused.handleKeyPress(keyID, keyChar); } for (Widget widget : controlWidgets) { if (widget.handleKeyPress(keyID, keyChar)) { return true; } } } return false; } @Override public void onKeyTyped(GuiContainer gui, char keyChar, int keyID) { } @Override public boolean lastKeyTyped(GuiContainer gui, char keyChar, int keyID) { if (keyID == getKeyBinding("gui.hide")) { toggleBooleanSetting("inventory.hidden"); return true; } if (isEnabled() && !isHidden()) { for (Widget widget : controlWidgets) { if (inputFocused == null) { widget.lastKeyTyped(keyID, keyChar); } } } return false; } public void onMouseUp(GuiContainer gui, int mx, int my, int button) { if (!isHidden() && isEnabled()) { for (Widget widget : controlWidgets) { widget.mouseUp(mx, my, button); } } } @Override public void onMouseDragged(GuiContainer gui, int mx, int my, int button, long heldTime) { if (!isHidden() && isEnabled()) { for (Widget widget : controlWidgets) { widget.mouseDragged(mx, my, button, heldTime); } } } @Override public ItemStack getStackUnderMouse(GuiContainer gui, int mousex, int mousey) { if (!isHidden() && isEnabled()) { for (Widget widget : controlWidgets) { ItemStack stack = widget.getStackMouseOver(mousex, mousey); if (stack != null) { return stack; } } } return null; } public void renderObjects(GuiContainer gui, int mousex, int mousey) { if (!isHidden()) { layout(gui); if (isEnabled()) { getLayoutStyle().drawBackground(GuiContainerManager.getManager(gui)); for (Widget widget : drawWidgets) { widget.draw(mousex, mousey); } } else { options.draw(mousex, mousey); } GlStateManager.enableLighting(); GlStateManager.disableDepth(); } } @Override public void postRenderObjects(GuiContainer gui, int mousex, int mousey) { if (!isHidden() && isEnabled()) { for (Widget widget : drawWidgets) { widget.postDraw(mousex, mousey); } } } @Override public List<String> handleTooltip(GuiContainer gui, int mousex, int mousey, List<String> currenttip) { if (!isHidden() && isEnabled() && GuiContainerManager.shouldShowTooltip(gui)) { for (Widget widget : controlWidgets) { currenttip = widget.handleTooltip(mousex, mousey, currenttip); } } return currenttip; } @Override public List<String> handleItemDisplayName(GuiContainer gui, ItemStack stack, List<String> currenttip) { String overridename = ItemInfo.getNameOverride(stack); if (overridename != null) { currenttip.set(0, overridename); } String mainname = currenttip.get(0); if (showIDs()) { mainname += " " + Item.getIdFromItem(stack.getItem()); if (stack.getItemDamage() != 0) { mainname += ":" + stack.getItemDamage(); } currenttip.set(0, mainname); } return currenttip; } @Override public List<String> handleItemTooltip(GuiContainer gui, ItemStack itemstack, int mousex, int mousey, List<String> currenttip) { return currenttip; } public static void layout(GuiContainer gui) { VisiblityData visiblity = new VisiblityData(); if (isHidden()) { visiblity.showNEI = false; } if (gui.height - gui.ySize <= 40) { visiblity.showSearchSection = false; } if (gui.guiLeft - 4 < 76) { visiblity.showWidgets = false; } for (INEIGuiHandler handler : GuiInfo.guiHandlers) { handler.modifyVisiblity(gui, visiblity); } visiblity.translateDependancies(); getLayoutStyle().layout(gui, visiblity); updateWidgetVisiblities(gui, visiblity); } private static void init() { itemPanel = new ItemPanel(); dropDown = new SubsetWidget(); searchField = new SearchField("search"); options = new Button("Options") { @Override public boolean onButtonPress(boolean rightclick) { if (!rightclick) { getOptionList().openGui(getGuiContainer(), false); return true; } return false; } @Override public String getRenderLabel() { return translate("inventory.options"); } }; prev = new Button("Prev") { public boolean onButtonPress(boolean rightclick) { if (!rightclick) { LayoutManager.itemPanel.scroll(-1); return true; } return false; } @Override public String getRenderLabel() { return translate("inventory.prev"); } }; next = new Button("Next") { public boolean onButtonPress(boolean rightclick) { if (!rightclick) { LayoutManager.itemPanel.scroll(1); return true; } return false; } @Override public String getRenderLabel() { return translate("inventory.next"); } }; pageLabel = new Label("(0/0)", true); more = new Button("+") { @Override public boolean onButtonPress(boolean rightclick) { if (rightclick) { return false; } int modifier = controlKey() ? 64 : shiftKey() ? 10 : 1; int quantity = getItemQuantity() + modifier; if (quantity < 0) { quantity = 0; } setItemQuantity(quantity); return true; } }; less = new Button("-") { @Override public boolean onButtonPress(boolean rightclick) { if (rightclick) { return false; } int modifier = controlKey() ? -64 : shiftKey() ? -10 : -1; int quantity = getItemQuantity() + modifier; if (quantity < 0) { quantity = 0; } setItemQuantity(quantity); return true; } }; quantity = new ItemQuantityField("quantity"); stateButtons = new SaveLoadButton[7]; deleteButtons = new Button[7]; for (int i = 0; i < 7; i++) { final int savestate = i; stateButtons[i] = new SaveLoadButton("") { @Override public boolean onButtonPress(boolean rightclick) { if (isStateSaved(savestate)) { loadState(savestate); } else { saveState(savestate); } return true; } @Override public void onTextChange() { NBTTagCompound statelist = global.nbt.getCompoundTag("statename"); global.nbt.setTag("statename", statelist); statelist.setString("" + savestate, label); global.saveNBT(); } }; deleteButtons[i] = new Button("x") { @Override public boolean onButtonPress(boolean rightclick) { if (!rightclick) { clearState(savestate); return true; } return false; } }; } delete = new Button() { @Override public boolean onButtonPress(boolean rightclick) { if ((state & 0x3) == 2) { return false; } ItemStack held = getHeldItem(); if (held != null) { if (shiftKey()) { deleteHeldItem(); deleteItemsOfType(held); } else if (rightclick) { decreaseSlotStack(-999); } else { deleteHeldItem(); } } else if (shiftKey()) { deleteEverything(); } else { NEIController.toggleDeleteMode(); } return true; } public String getButtonTip() { if ((state & 0x3) != 2) { if (shiftKey()) { return translate("inventory.delete.inv"); } if (NEIController.canUseDeleteMode()) { return getStateTip("delete", state); } } return null; } @Override public void postDraw(int mousex, int mousey) { if (contains(mousex, mousey) && getHeldItem() != null && (state & 0x3) != 2) { GuiDraw.drawTip(mousex + 9, mousey, translate("inventory.delete." + (shiftKey() ? "all" : "one"), GuiContainerManager.itemDisplayNameShort(getHeldItem()))); } } }; gamemode = new ButtonCycled() { @Override public boolean onButtonPress(boolean rightclick) { if (!rightclick) { cycleGamemode(); return true; } return false; } public String getButtonTip() { return translate("inventory.gamemode." + getNextGamemode()); } }; gamemode.icons = new Image[3]; rain = new Button() { @Override public boolean onButtonPress(boolean rightclick) { if (handleDisabledButtonPress("rain", rightclick)) { return true; } if (!rightclick) { toggleRaining(); return true; } return false; } public String getButtonTip() { return getStateTip("rain", state); } }; magnet = new Button() { @Override public boolean onButtonPress(boolean rightclick) { if (!rightclick) { toggleMagnetMode(); return true; } return false; } public String getButtonTip() { return getStateTip("magnet", state); } }; for (int i = 0; i < 4; i++) { final int zone = i; timeButtons[i] = new Button() { @Override public boolean onButtonPress(boolean rightclick) { if (handleDisabledButtonPress(NEIActions.timeZones[zone], rightclick)) { return true; } if (!rightclick) { setHourForward(zone * 6); return true; } return false; } @Override public String getButtonTip() { return getTimeTip(NEIActions.timeZones[zone], state); } }; } heal = new Button() { @Override public boolean onButtonPress(boolean rightclick) { if (!rightclick) { healPlayer(); return true; } return false; } @Override public String getButtonTip() { return translate("inventory.heal"); } }; delete.state |= 0x4; gamemode.state |= 0x4; rain.state |= 0x4; magnet.state |= 0x4; } private static String getStateTip(String name, int state) { String sfx = (state & 0x3) == 2 ? "enable" : (state & 0x3) == 1 ? "0" : "1"; return translate("inventory." + name + "." + sfx); } private static String getTimeTip(String name, int state) { String sfx = (state & 0x3) == 2 ? "enable" : "set"; return translate("inventory." + name + "." + sfx); } private static boolean handleDisabledButtonPress(String ident, boolean rightclick) { if (!NEIActions.canDisable.contains(ident)) { return false; } if (rightclick != disabledActions.contains(ident)) { return setPropertyDisabled(ident, rightclick); } return false; } private static boolean setPropertyDisabled(String ident, boolean disable) { if (disable && NEIActions.base(ident).equals("time")) { int count = 0; for (int i = 0; i < 4; i++) { if (disabledActions.contains(NEIActions.timeZones[i])) { count++; } } if (count == 3) { return false; } } if (hasSMPCounterPart()) { NEICPH.sendSetPropertyDisabled(ident, disable); } return true; } @Override public void load(GuiContainer gui) { if (isEnabled()) { setInputFocused(null); ItemList.loadItems.restart(); overlayRenderer = null; getLayoutStyle().init(); layout(gui); } NEIController.load(gui); if (checkCreativeInv(gui) && gui.mc.currentScreen instanceof GuiContainerCreative)//override creative with creative+ { gui.mc.displayGuiScreen(null);//close the screen and wait for the server to open it for us } } @Override public void refresh(GuiContainer gui) { } public boolean checkCreativeInv(GuiContainer gui) { if (gui instanceof GuiContainerCreative && invCreativeMode()) { NEICPH.sendCreativeInv(true); return true; } else if (gui instanceof GuiExtendedCreativeInv && !invCreativeMode()) { NEICPH.sendCreativeInv(false); return true; } return false; } public static void updateWidgetVisiblities(GuiContainer gui, VisiblityData visiblity) { drawWidgets = new TreeSet<Widget>(new WidgetZOrder(false)); controlWidgets = new TreeSet<Widget>(new WidgetZOrder(true)); if (!visiblity.showNEI) { return; } addWidget(options); if (visiblity.showItemPanel) { addWidget(itemPanel); addWidget(prev); addWidget(next); addWidget(pageLabel); if (canPerformAction("item")) { addWidget(more); addWidget(less); addWidget(quantity); } } if (visiblity.showSearchSection) { addWidget(dropDown); addWidget(searchField); } if (canPerformAction("item") && hasSMPCounterPart() && visiblity.showStateButtons) { for (int i = 0; i < 7; i++) { addWidget(stateButtons[i]); if (isStateSaved(i)) { addWidget(deleteButtons[i]); } } } if (visiblity.showUtilityButtons) { if (canPerformAction("time")) { for (int i = 0; i < 4; i++) { addWidget(timeButtons[i]); } } if (canPerformAction("rain")) { addWidget(rain); } if (canPerformAction("heal")) { addWidget(heal); } if (canPerformAction("magnet")) { addWidget(magnet); } if (isValidGamemode("creative") || isValidGamemode("creative+") || isValidGamemode("adventure")) { addWidget(gamemode); } if (canPerformAction("delete")) { addWidget(delete); } } } public static LayoutStyle getLayoutStyle(int id) { LayoutStyle style = layoutStyles.get(id); if (style == null) { style = layoutStyles.get(0); } return style; } public static LayoutStyle getLayoutStyle() { return getLayoutStyle(NEIClientConfig.getLayoutStyle()); } private static void addWidget(Widget widget) { drawWidgets.add(widget); controlWidgets.add(widget); } @Override public void guiTick(GuiContainer gui) { if (checkCreativeInv(gui)) { return; } if (!isEnabled()) { return; } for (Widget widget : controlWidgets) { widget.update(); } } @Override public boolean mouseScrolled(GuiContainer gui, int mousex, int mousey, int scrolled) { if (isHidden() || !isEnabled()) { return false; } for (Widget widget : controlWidgets) { if (widget.onMouseWheel(scrolled, mousex, mousey)) { return true; } } return false; } @Override public void onMouseScrolled(GuiContainer gui, int mousex, int mousey, int scrolled) { } @Override public boolean shouldShowTooltip(GuiContainer gui) { return itemPanel.draggedStack == null; } public static Widget getInputFocused() { return inputFocused; } public static void setInputFocused(Widget widget) { if (inputFocused != null) { inputFocused.loseFocus(); } inputFocused = widget; if (inputFocused != null) { inputFocused.gainFocus(); } } @Override public void renderSlotUnderlay(GuiContainer gui, Slot slot) { if (overlayRenderer != null) { overlayRenderer.renderOverlay(GuiContainerManager.getManager(gui), slot); } } @Override public void renderSlotOverlay(GuiContainer window, Slot slot) { ItemStack item = slot.getStack(); if (world.nbt.getBoolean("searchinventories") && (item == null ? !getSearchExpression().equals("") : !ItemList.itemMatches(item))) { GlStateManager.disableLighting(); GlStateManager.translate(0, 0, 150); drawRect(slot.xDisplayPosition, slot.yDisplayPosition, 16, 16, 0x80000000); GlStateManager.translate(0, 0, -150); GlStateManager.enableLighting(); } } public static void drawIcon(int x, int y, Image image) { changeTexture("nei:textures/nei_sprites.png"); GlStateManager.color(1, 1, 1, 1); GlStateManager.enableBlend(); GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); drawTexturedModalRect(x, y, image.x, image.y, image.width, image.height); GlStateManager.disableBlend(); } public static void drawButtonBackground(int x, int y, int w, int h, boolean edges, int type) { int wtiles = 0; int ew = w;//end width if (w / 2 > 100) { wtiles = (w - 200) / 50 + 1; ew = 200; } int w1 = ew / 2; int h1 = h / 2; int w2 = (ew + 1) / 2; int h2 = (h + 1) / 2; int x2 = x + w - w2; int y2 = y + h - h2; int ty = 46 + type * 20; int te = (edges ? 0 : 1);//tex edges int ty1 = ty + te; int tx1 = te; int tx3 = 75; //halfway the 1 is for odd number adjustment int ty2 = ty + 20 - h2 - te; int tx2 = 200 - w2 - te; changeTexture("textures/gui/widgets.png"); drawTexturedModalRect(x, y, tx1, ty1, w1, h1);//top left drawTexturedModalRect(x, y2, tx1, ty2, w1, h2);//bottom left for (int tile = 0; tile < wtiles; tile++) { int tilex = x + w1 + 50 * tile; drawTexturedModalRect(tilex, y, tx3, ty1, 50, h1);//top drawTexturedModalRect(tilex, y2, tx3, ty2, 50, h2);//bottom } drawTexturedModalRect(x2, y, tx2, ty1, w2, h1);//top right drawTexturedModalRect(x2, y2, tx2, ty2, w2, h2);//bottom right } public static LayoutManager instance() { return instance; } @Override public void tickKeyStates() { if (Minecraft.getMinecraft().currentScreen != null) { return; } if (KeyManager.keyStates.get("world.dawn").down) { timeButtons[0].onButtonPress(false); } if (KeyManager.keyStates.get("world.noon").down) { timeButtons[1].onButtonPress(false); } if (KeyManager.keyStates.get("world.dusk").down) { timeButtons[2].onButtonPress(false); } if (KeyManager.keyStates.get("world.midnight").down) { timeButtons[3].onButtonPress(false); } if (KeyManager.keyStates.get("world.rain").down) { rain.onButtonPress(false); } if (KeyManager.keyStates.get("world.heal").down) { heal.onButtonPress(false); } if (KeyManager.keyStates.get("world.creative").down) { gamemode.onButtonPress(false); } } }