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); } }