diff --git a/src/main/java/codechicken/nei/ItemHistoryPanel.java b/src/main/java/codechicken/nei/ItemHistoryPanel.java new file mode 100644 index 000000000..969e05176 --- /dev/null +++ b/src/main/java/codechicken/nei/ItemHistoryPanel.java @@ -0,0 +1,206 @@ +package codechicken.nei; + +import static codechicken.lib.gui.GuiDraw.drawRect; + +import net.minecraft.client.gui.inventory.GuiContainer; +import net.minecraft.item.ItemStack; + +import org.lwjgl.opengl.GL11; + +import codechicken.nei.ItemPanel.ItemPanelSlot; +import codechicken.nei.recipe.GuiCraftingRecipe; +import codechicken.nei.recipe.GuiRecipe; +import codechicken.nei.recipe.GuiUsageRecipe; +import codechicken.nei.recipe.StackInfo; + +public class ItemHistoryPanel extends Widget { + + protected int mouseDownSlot = -1; + protected ItemsGrid grid; + + public ItemHistoryPanel() { + grid = new ItemsGrid(); + } + + public void draw(int mousex, int mousey) { + + if (NEIClientConfig.getIntSetting("inventory.history.splittingMode") == 0) { + drawRect(x, y, w, h, NEIClientConfig.getSetting("inventory.history.historyColor").getHexValue()); + } else { + drawSplittingArea(x, y, w, h, NEIClientConfig.getSetting("inventory.history.historyColor").getHexValue()); + } + + grid.draw(mousex, mousey); + } + + public void update() { + grid.update(); + } + + public void addItem(ItemStack stack) { + if (stack != null) { + ItemStack is = stack.copy(); + is.stackSize = 1; + + grid.realItems.removeIf(historyStack -> StackInfo.equalItemAndNBT(historyStack, stack, true)); + grid.realItems.add(0, is); + + if (grid.realItems.size() > (grid.rows * grid.columns)) { + grid.realItems.remove(grid.rows * grid.columns); + } + + grid.onItemsChanged(); + } + } + + public void resize(GuiContainer gui) { + grid.setGridSize(x, y, w, h); + grid.refresh(gui); + } + + @Override + public ItemStack getStackMouseOver(int mousex, int mousey) { + ItemPanelSlot slot = getSlotMouseOver(mousex, mousey); + return slot == null ? null : slot.item; + } + + public ItemPanelSlot getSlotMouseOver(int mousex, int mousey) { + return grid.getSlotMouseOver(mousex, mousey); + } + + private void drawSplittingArea(int x, int y, int width, int height, int color) { + + float alpha = (float) (color >> 24 & 255) / 255.0F; + float red = (float) (color >> 16 & 255) / 255.0F; + float green = (float) (color >> 8 & 255) / 255.0F; + float blue = (float) (color & 255) / 255.0F; + + GL11.glPushMatrix(); + + GL11.glDisable(GL11.GL_TEXTURE_2D); + GL11.glEnable(GL11.GL_LINE_STIPPLE); + GL11.glColor4f(red, green, blue, alpha); + GL11.glLineWidth(2F); + GL11.glLineStipple(2, (short) 0x00FF); + + GL11.glBegin(GL11.GL_LINE_LOOP); + + GL11.glVertex2i(x, y); + GL11.glVertex2i(x + width, y); + GL11.glVertex2i(x + width, y + height); + GL11.glVertex2i(x, y + height); + + GL11.glEnd(); + + GL11.glLineStipple(1, (short) 0xFFFF); + GL11.glLineWidth(1F); + GL11.glDisable(GL11.GL_LINE_STIPPLE); + GL11.glEnable(GL11.GL_TEXTURE_2D); + GL11.glColor4f(1F, 1F, 1F, 1F); + + GL11.glPopMatrix(); + + } + + @Override + public void mouseDragged(int mousex, int mousey, int button, long heldTime) { + + if (mouseDownSlot >= 0 && ItemPanels.itemPanel.draggedStack == null + && NEIClientUtils.getHeldItem() == null + && NEIClientConfig.hasSMPCounterPart()) { + + ItemPanelSlot mouseOverSlot = getSlotMouseOver(mousex, mousey); + + if (mouseOverSlot == null || mouseOverSlot.slotIndex != mouseDownSlot || heldTime > 500) { + ItemPanels.itemPanel.draggedStack = getDraggedStackWithQuantity(mouseDownSlot); + mouseDownSlot = -1; + } + } + + } + + @Override + public boolean handleClick(int mousex, int mousey, int button) { + + if (handleClickExt(mousex, mousey, button)) return true; + + if (NEIClientUtils.getHeldItem() != null) { + + if (!grid.contains(mousex, mousey)) { + return false; + } + + if (NEIClientConfig.canPerformAction("delete") && NEIClientConfig.canPerformAction("item")) { + if (button == 1) { + NEIClientUtils.decreaseSlotStack(-999); + } else { + NEIClientUtils.deleteHeldItem(); + } + } else { + NEIClientUtils.dropHeldItem(); + } + + return true; + } + + ItemPanelSlot hoverSlot = getSlotMouseOver(mousex, mousey); + if (hoverSlot != null) { + + if (button == 2) { + + if (hoverSlot.item != null) { + ItemPanels.itemPanel.draggedStack = getDraggedStackWithQuantity(hoverSlot.slotIndex); + } + + } else { + mouseDownSlot = hoverSlot.slotIndex; + } + + return true; + } + + return false; + } + + @Override + public void mouseUp(int mousex, int mousey, int button) { + ItemPanelSlot hoverSlot = getSlotMouseOver(mousex, mousey); + + if (hoverSlot != null && hoverSlot.slotIndex == mouseDownSlot && ItemPanels.itemPanel.draggedStack == null) { + ItemStack item = hoverSlot.item.copy(); + + if (NEIController.manager.window instanceof GuiRecipe || !NEIClientConfig.canCheatItem(item)) { + + if (button == 0) { + GuiCraftingRecipe.openRecipeGui("item", item); + } else if (button == 1) { + GuiUsageRecipe.openRecipeGui("item", item); + } + + mouseDownSlot = -1; + return; + } + + NEIClientUtils.cheatItem(getDraggedStackWithQuantity(hoverSlot.slotIndex), button, -1); + } + + mouseDownSlot = -1; + } + + protected ItemStack getDraggedStackWithQuantity(int mouseDownSlot) { + ItemStack stack = grid.getItem(mouseDownSlot); + + if (stack != null) { + int amount = NEIClientConfig.showItemQuantityWidget() ? NEIClientConfig.getItemQuantity() : 0; + + if (amount == 0) { + amount = stack.getMaxStackSize(); + } + + return NEIServerUtils.copyStack(stack, amount); + } + + return null; + } + +} diff --git a/src/main/java/codechicken/nei/ItemPanel.java b/src/main/java/codechicken/nei/ItemPanel.java index c66296586..5e5f9354d 100644 --- a/src/main/java/codechicken/nei/ItemPanel.java +++ b/src/main/java/codechicken/nei/ItemPanel.java @@ -34,6 +34,7 @@ public ItemStack getStackMouseOver(int mousex, int mousey) { public Button more; public Button less; public ItemQuantityField quantity; + public ItemHistoryPanel historyPanel; public static class ItemPanelSlot { @@ -134,6 +135,7 @@ public boolean onButtonPress(boolean rightclick) { }; quantity = new ItemQuantityField("quantity"); + historyPanel = new ItemHistoryPanel(); } @Deprecated @@ -191,20 +193,40 @@ protected int resizeFooter(GuiContainer gui) { less.y = more.y + more.h; } - return BUTTON_SIZE + 2; + if (NEIClientConfig.showHistoryPanelWidget()) { + historyPanel.x = x; + historyPanel.w = w; + historyPanel.h = ItemsGrid.SLOT_SIZE * NEIClientConfig.getIntSetting("inventory.history.useRows"); + historyPanel.y = quantity.y - PanelWidget.PADDING - historyPanel.h; + return quantity.h + historyPanel.h + PanelWidget.PADDING * 2; + } + + return quantity.h + PanelWidget.PADDING; } @Override public void setVisible() { super.setVisible(); - if (grid.getPerPage() > 0 && NEIClientConfig.showItemQuantityWidget()) { - LayoutManager.addWidget(more); - LayoutManager.addWidget(less); - LayoutManager.addWidget(quantity); + if (grid.getPerPage() > 0) { + if (NEIClientConfig.showItemQuantityWidget()) { + LayoutManager.addWidget(more); + LayoutManager.addWidget(less); + LayoutManager.addWidget(quantity); + } + + if (NEIClientConfig.showHistoryPanelWidget()) { + LayoutManager.addWidget(historyPanel); + } } } + @Override + public void resize(GuiContainer gui) { + super.resize(gui); + historyPanel.resize(gui); + } + protected ItemStack getDraggedStackWithQuantity(int mouseDownSlot) { ItemStack stack = grid.getItem(mouseDownSlot); diff --git a/src/main/java/codechicken/nei/NEIClientConfig.java b/src/main/java/codechicken/nei/NEIClientConfig.java index 3a9281b54..61c157deb 100644 --- a/src/main/java/codechicken/nei/NEIClientConfig.java +++ b/src/main/java/codechicken/nei/NEIClientConfig.java @@ -43,6 +43,7 @@ import codechicken.nei.config.GuiPanelSettings; import codechicken.nei.config.OptionCycled; import codechicken.nei.config.OptionGamemodes; +import codechicken.nei.config.OptionIntegerField; import codechicken.nei.config.OptionList; import codechicken.nei.config.OptionOpenGui; import codechicken.nei.config.OptionTextField; @@ -162,6 +163,19 @@ public boolean optionValid(int index) { ItemSorter.initConfig(tag); + tag.getTag("inventory.history.enabled").setComment("Enable/disable History Panel").getBooleanValue(true); + API.addOption(new OptionToggleButton("inventory.history.enabled", true)); + + tag.getTag("inventory.history.historyColor").setComment("Color of the history area display") + .getHexValue(0xee555555); + API.addOption(new OptionIntegerField("inventory.history.historyColor")); + + tag.getTag("inventory.history.useRows").setComment("Rows used in historical areas").getIntValue(2); + API.addOption(new OptionIntegerField("inventory.history.useRows", 1, 5)); + + tag.getTag("inventory.history.splittingMode").getIntValue(1); + API.addOption(new OptionCycled("inventory.history.splittingMode", 2, true)); + tag.getTag("inventory.itemIDs").getIntValue(1); API.addOption(new OptionCycled("inventory.itemIDs", 3, true)); @@ -386,6 +400,8 @@ private static void setDefaultKeyBindings() { API.addKeyBind("world.rain", 0); API.addKeyBind("world.heal", 0); API.addKeyBind("world.creative", 0); + API.addHashBind("gui.copy_name", Keyboard.KEY_C + NEIClientUtils.CTRL_HASH); + API.addHashBind("gui.copy_oredict", Keyboard.KEY_D + NEIClientUtils.CTRL_HASH); } public static OptionList getOptionList() { @@ -725,6 +741,10 @@ public static boolean shouldInvertMouseScrollTransfer() { return !getBooleanSetting("inventory.invertMouseScrollTransfer"); } + public static boolean showHistoryPanelWidget() { + return getBooleanSetting("inventory.history.enabled"); + } + public static boolean shouldCacheItemRendering() { return getBooleanSetting("inventory.cacheItemRendering") && OpenGlHelper.framebufferSupported; } diff --git a/src/main/java/codechicken/nei/api/ShortcutInputHandler.java b/src/main/java/codechicken/nei/api/ShortcutInputHandler.java index 7eefce1a2..59aaee36a 100644 --- a/src/main/java/codechicken/nei/api/ShortcutInputHandler.java +++ b/src/main/java/codechicken/nei/api/ShortcutInputHandler.java @@ -3,10 +3,13 @@ import static codechicken.lib.gui.GuiDraw.getMousePosition; import java.awt.Point; +import java.awt.Toolkit; +import java.awt.datatransfer.StringSelection; import java.util.List; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.item.ItemStack; +import net.minecraftforge.oredict.OreDictionary; import org.lwjgl.input.Mouse; @@ -60,6 +63,14 @@ public static boolean handleKeyEvent(ItemStack stackover) { return openOverlayRecipe(stackover, false); } + if (NEIClientConfig.isKeyHashDown("gui.copy_name")) { + return copyItemStackName(stackover); + } + + if (NEIClientConfig.isKeyHashDown("gui.copy_oredict")) { + return copyItemStackOreDictionary(stackover); + } + if (NEIClientConfig.isKeyHashDown("gui.overlay_use")) { return openOverlayRecipe(stackover, true); } @@ -120,6 +131,30 @@ private static boolean hideOverlayRecipe() { return false; } + private static boolean copyItemStackName(ItemStack stackover) { + Toolkit.getDefaultToolkit().getSystemClipboard() + .setContents(new StringSelection(stackover.getDisplayName()), null); + return true; + } + + private static boolean copyItemStackOreDictionary(ItemStack stackover) { + StringBuilder builder = new StringBuilder(); + + for (int id : OreDictionary.getOreIDs(stackover)) { + String oreDictionaryName = OreDictionary.getOreName(id); + if (!"Unknown".equals(oreDictionaryName)) { + builder.append(oreDictionaryName).append(","); + } + } + + if (builder.length() > 0) { + builder.deleteCharAt(builder.length() - 1); + } + + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(builder.toString()), null); + return true; + } + private static boolean openOverlayRecipe(ItemStack stackover, boolean shift) { final GuiContainer gui = NEIClientUtils.getGuiContainer(); diff --git a/src/main/java/codechicken/nei/config/OptionIntegerField.java b/src/main/java/codechicken/nei/config/OptionIntegerField.java index 09efc1773..7504864ac 100644 --- a/src/main/java/codechicken/nei/config/OptionIntegerField.java +++ b/src/main/java/codechicken/nei/config/OptionIntegerField.java @@ -20,7 +20,11 @@ public boolean isValidInput(String s) { if (s.length() == 0) return true; try { - Integer.parseInt(s); + if (s.startsWith("0x")) { + Long.parseLong(s.substring(2), 16); + } else { + Integer.parseInt(s); + } return true; } catch (NumberFormatException nfe) { return false; @@ -30,8 +34,14 @@ public boolean isValidInput(String s) { @Override public boolean isValidValue(String s) { if (s.length() == 0 || !isValidInput(s)) return false; + int i = 0; + + if (s.startsWith("0x")) { + i = (int) Long.parseLong(s.substring(2), 16); + } else { + i = Integer.parseInt(s); + } - int i = Integer.parseInt(s); return i >= min && i <= max; } } diff --git a/src/main/java/codechicken/nei/config/OptionTextField.java b/src/main/java/codechicken/nei/config/OptionTextField.java index 981a85b77..a0afc814a 100644 --- a/src/main/java/codechicken/nei/config/OptionTextField.java +++ b/src/main/java/codechicken/nei/config/OptionTextField.java @@ -11,7 +11,6 @@ public class OptionTextField extends Option { - private boolean focused = false; private TextField textField = new TextField("test") { @Override @@ -25,16 +24,11 @@ public void onTextChange(String oldText) { getTag().setValue(text()); } - @Override - public boolean focused() { - return focused; - } - @Override public void setFocus(boolean focus) { if (!focus && !isValidValue(text())) setText(renderTag().getValue()); - focused = focus; + super.setFocus(focus); } }; diff --git a/src/main/java/codechicken/nei/recipe/ItemsHistoryHandler.java b/src/main/java/codechicken/nei/recipe/ItemsHistoryHandler.java new file mode 100644 index 000000000..02ad0ac7c --- /dev/null +++ b/src/main/java/codechicken/nei/recipe/ItemsHistoryHandler.java @@ -0,0 +1,117 @@ +package codechicken.nei.recipe; + +import java.util.List; + +import net.minecraft.client.gui.inventory.GuiContainer; +import net.minecraft.inventory.Container; +import net.minecraft.item.ItemStack; + +import codechicken.nei.ItemPanels; +import codechicken.nei.NEIClientConfig; +import codechicken.nei.PositionedStack; +import codechicken.nei.api.IOverlayHandler; +import codechicken.nei.api.IRecipeOverlayRenderer; + +class ItemsHistoryHandler implements ICraftingHandler, IUsageHandler { + + @Override + public ICraftingHandler getRecipeHandler(String outputId, Object... results) { + + if (NEIClientConfig.showHistoryPanelWidget() && "item".equals(outputId) && results[0] instanceof ItemStack) { + ItemPanels.itemPanel.historyPanel.addItem((ItemStack) results[0]); + } + + return null; + } + + @Override + public IUsageHandler getUsageHandler(String inputId, Object... ingredients) { + + if (NEIClientConfig.showHistoryPanelWidget() && "item".equals(inputId) && ingredients[0] instanceof ItemStack) { + ItemPanels.itemPanel.historyPanel.addItem((ItemStack) ingredients[0]); + } + + return null; + } + + @Override + public void onUpdate() { + + } + + @Override + public boolean hasOverlay(GuiContainer gui, Container container, int recipe) { + return false; + } + + @Override + public IRecipeOverlayRenderer getOverlayRenderer(GuiContainer gui, int recipe) { + return null; + } + + @Override + public IOverlayHandler getOverlayHandler(GuiContainer gui, int recipe) { + return null; + } + + @Override + public int recipiesPerPage() { + return 0; + } + + @Override + public List handleTooltip(GuiRecipe gui, List currenttip, int recipe) { + return null; + } + + @Override + public List handleItemTooltip(GuiRecipe gui, ItemStack stack, List currenttip, int recipe) { + return null; + } + + @Override + public boolean keyTyped(GuiRecipe gui, char keyChar, int keyCode, int recipe) { + return false; + } + + @Override + public boolean mouseClicked(GuiRecipe gui, int button, int recipe) { + return true; + } + + @Override + public String getRecipeName() { + return null; + } + + @Override + public int numRecipes() { + return 0; + } + + @Override + public void drawBackground(int recipe) { + + } + + @Override + public void drawForeground(int recipe) { + + } + + @Override + public List getIngredientStacks(int recipe) { + return null; + } + + @Override + public List getOtherStacks(int recipeType) { + return null; + } + + @Override + public PositionedStack getResultStack(int recipe) { + return null; + } + +} diff --git a/src/main/java/codechicken/nei/recipe/RecipeInfo.java b/src/main/java/codechicken/nei/recipe/RecipeInfo.java index 75ad591f0..9ab78fabb 100644 --- a/src/main/java/codechicken/nei/recipe/RecipeInfo.java +++ b/src/main/java/codechicken/nei/recipe/RecipeInfo.java @@ -113,5 +113,7 @@ public static void load() { API.registerRecipeHandler(new ProfilerRecipeHandler(true)); API.registerUsageHandler(new ProfilerRecipeHandler(false)); + API.registerRecipeHandler(new ItemsHistoryHandler()); + API.registerUsageHandler(new ItemsHistoryHandler()); } } diff --git a/src/main/resources/assets/nei/lang/en_US.lang b/src/main/resources/assets/nei/lang/en_US.lang index dac2ca5e8..bdc78684b 100644 --- a/src/main/resources/assets/nei/lang/en_US.lang +++ b/src/main/resources/assets/nei/lang/en_US.lang @@ -121,6 +121,8 @@ nei.options.keys.gui.overlay_use=Use Overlay Recipe nei.options.keys.gui.getprevioussearch=Previous Search nei.options.keys.gui.getnextsearch=Next Search nei.options.keys.gui.next_tooltip=Next Tooltip +nei.options.keys.gui.copy_name=Copy Item Name +nei.options.keys.gui.copy_oredict=Copy Item OreDictionary nei.options.keys.world=World nei.options.keys.world.chunkoverlay=Chunk Boundary Overlay nei.options.keys.world.moboverlay=Mob Spawn Overlay @@ -233,6 +235,15 @@ nei.options.inventory.invertMouseScrollTransfer.false=False nei.options.inventory.cacheItemRendering=Cache Item Rendering nei.options.inventory.cacheItemRendering.true=True nei.options.inventory.cacheItemRendering.false=False +nei.options.inventory.history=History Panel +nei.options.inventory.history.enabled=History Panel Visibility +nei.options.inventory.history.enabled.true=Enabled +nei.options.inventory.history.enabled.false=Disabled +nei.options.inventory.history.historyColor=Color +nei.options.inventory.history.useRows=Rows +nei.options.inventory.history.splittingMode=Splitting Mode +nei.options.inventory.history.splittingMode.0=Background +nei.options.inventory.history.splittingMode.1=Dotted Line nei.options.command=Commands nei.options.command.creative=Gamemode diff --git a/src/main/resources/assets/nei/lang/zh_CN.lang b/src/main/resources/assets/nei/lang/zh_CN.lang index e43edea70..ede630335 100644 --- a/src/main/resources/assets/nei/lang/zh_CN.lang +++ b/src/main/resources/assets/nei/lang/zh_CN.lang @@ -112,6 +112,8 @@ nei.options.keys.gui.overlay_hide=隐藏覆盖合成表 nei.options.keys.gui.overlay_use=使用覆盖合成表 nei.options.keys.gui.getprevioussearch=上一个搜索 nei.options.keys.gui.getnextsearch=下一个搜索 +nei.options.keys.gui.copy_name=复制物品名称 +nei.options.keys.gui.copy_oredict=复制物品矿词词典 nei.options.keys.world=世界 nei.options.keys.world.chunkoverlay=区块(chunks)边界显示 nei.options.keys.world.moboverlay=刷怪区域显示