Compare commits

...
14 Commits
56 changed files with 4155 additions and 2101 deletions

No files matched your search

+1 -1
View File
@@ -2,7 +2,7 @@
dependencies {
api('com.github.GTNewHorizons:CodeChickenCore:1.4.7:dev')
implementation('com.github.GTNewHorizons:GTNHLib:0.6.40:dev')
implementation('com.github.GTNewHorizons:GTNHLib:0.7.0:dev')
shadowImplementation('org.apache.commons:commons-csv:1.10.0')
@@ -6,12 +6,11 @@ import net.minecraft.item.ItemStack;
import org.lwjgl.opengl.GL11;
import codechicken.nei.ItemsGrid.ItemsGridSlot;
import codechicken.nei.api.ShortcutInputHandler;
import codechicken.nei.drawable.DrawableBuilder;
import codechicken.nei.drawable.DrawableResource;
import codechicken.nei.guihook.IContainerTooltipHandler;
import codechicken.nei.recipe.GuiCraftingRecipe;
import codechicken.nei.recipe.GuiRecipe;
import codechicken.nei.recipe.GuiUsageRecipe;
public abstract class AbstractSubpanel<T extends ItemsGrid<? extends ItemsGridSlot, ? extends ItemsGrid.MouseContext>>
extends Widget implements IContainerTooltipHandler {
@@ -122,13 +121,7 @@ public abstract class AbstractSubpanel<T extends ItemsGrid<? extends ItemsGridSl
if (NEIController.manager.window instanceof GuiRecipe || NEIClientUtils.shiftKey()
|| !NEIClientConfig.canCheatItem(hoverSlot.getItemStack())) {
if (button == 0) {
GuiCraftingRecipe.openRecipeGui("item", hoverSlot.getItemStack().copy());
} else if (button == 1) {
GuiUsageRecipe.openRecipeGui("item", hoverSlot.getItemStack().copy());
}
ShortcutInputHandler.handleMouseClick(hoverSlot.getItemStack().copy());
} else {
NEIClientUtils.cheatItem(getDraggedStackWithQuantity(hoverSlot.getItemStack()), button, -1);
}
@@ -695,7 +695,7 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
}
@Override
public List<String> handleTooltip(GuiContainer gui, int mousex, int mousey, List<String> currenttip) {
public List<String> handleTooltip(int mousex, int mousey, List<String> currenttip) {
if (this.grid.getPerPage() == 0 || this.grid.isEmpty()) {
return new ArrayList<>();
@@ -722,7 +722,7 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
this.recipeChainTooltipLineHandler = null;
}
return super.handleTooltip(gui, mousex, mousey, currenttip);
return super.handleTooltip(mousex, mousey, currenttip);
}
@Override
@@ -748,7 +748,7 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
}
@Override
public Map<String, String> handleHotkeys(GuiContainer gui, int mousex, int mousey, Map<String, String> hotkeys) {
public Map<String, String> handleHotkeys(int mousex, int mousey, Map<String, String> hotkeys) {
final int overRowIndex = this.grid.getHoveredRowIndex(true);
final BookmarksGridSlot slot = getSlotMouseOver(mousex, mousey);
@@ -781,7 +781,7 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
NEIClientConfig.getKeyName("gui.remove_recipe"),
NEIClientUtils.translate("bookmark.group.remove_recipe"));
if (BookmarkContainerInfo.getBookmarkContainerHandler(gui) != null) {
if (BookmarkContainerInfo.getBookmarkContainerHandler(NEIClientUtils.getGuiContainer()) != null) {
hotkeys.put(
NEIClientConfig.getKeyName("gui.bookmark_pull_items"),
NEIClientUtils.translate("bookmark.group.pull_items"));
@@ -878,7 +878,7 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
}
}
return hotkeys;
return super.handleHotkeys(mousex, mousey, hotkeys);
}
private List<String> recipeChainTooltip(int groupId, List<String> currenttip) {
@@ -915,8 +915,7 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
}
@Override
public List<String> handleItemTooltip(GuiContainer gui, ItemStack itemstack, int mousex, int mousey,
List<String> currenttip) {
public List<String> handleItemTooltip(ItemStack itemstack, int mousex, int mousey, List<String> currenttip) {
final BookmarksGridSlot slot = this.grid.getSlotMouseOver(mousex, mousey);
if (slot != null) {
@@ -27,8 +27,8 @@ public class HeldItemHandler implements IContainerInputHandler, IContainerToolti
protected boolean contains(int mousex, int mousey) {
return NEIClientUtils.getHeldItem() != null && !ItemPanels.bookmarkPanel.inEditingState()
&& !AutoCraftingManager.processing()
&& (ItemPanels.bookmarkPanel.contains(mousex, mousey) || ItemPanels.itemPanel.contains(mousex, mousey)
|| ItemPanels.itemPanel.historyPanel.contains(mousex, mousey));
&& (ItemPanels.bookmarkPanel.contains(mousex, mousey)
|| ItemPanels.itemPanel.containsWithSubpanels(mousex, mousey));
}
@Override
+9 -5
View File
@@ -222,8 +222,7 @@ public class ItemPanel extends PanelWidget<ItemsPanelGrid> {
}
@Override
public List<String> handleItemTooltip(GuiContainer gui, ItemStack itemstack, int mousex, int mousey,
List<String> currenttip) {
public List<String> handleItemTooltip(ItemStack itemstack, int mousex, int mousey, List<String> currenttip) {
if (!this.grid.forceExpand && !currenttip.isEmpty()) {
final ItemsPanelGridSlot hoverSlot = this.grid.getSlotMouseOver(mousex, mousey);
@@ -237,7 +236,7 @@ public class ItemPanel extends PanelWidget<ItemsPanelGrid> {
}
}
return super.handleItemTooltip(gui, itemstack, mousex, mousey, currenttip);
return super.handleItemTooltip(itemstack, mousex, mousey, currenttip);
}
@Override
@@ -258,7 +257,7 @@ public class ItemPanel extends PanelWidget<ItemsPanelGrid> {
}
@Override
public Map<String, String> handleHotkeys(GuiContainer gui, int mousex, int mousey, Map<String, String> hotkeys) {
public Map<String, String> handleHotkeys(int mousex, int mousey, Map<String, String> hotkeys) {
final ItemsPanelGridSlot hoverSlot = this.grid.getSlotMouseOver(mousex, mousey);
if (!this.grid.forceExpand && hoverSlot != null && hoverSlot.groupIndex >= 0 && hoverSlot.groupSize > 1) {
@@ -269,7 +268,12 @@ public class ItemPanel extends PanelWidget<ItemsPanelGrid> {
NEIClientUtils.translate(message, hoverSlot.groupSize));
}
return hotkeys;
return super.handleHotkeys(mousex, mousey, hotkeys);
}
public boolean containsWithSubpanels(int px, int py) {
return contains(px, py) || NEIClientConfig.showHistoryPanelWidget() && this.historyPanel.contains(px, py)
|| NEIClientConfig.showCraftablesPanelWidget() && this.craftablesPanel.contains(px, py);
}
}
+1 -1
View File
@@ -58,7 +58,7 @@ public class ItemZoom extends Widget implements IContainerInputHandler {
GL11.glPopMatrix();
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
GL11.glPushAttrib(GL11.GL_ENABLE_BIT | GL11.GL_COLOR_BUFFER_BIT);
GuiContainerManager.enable2DRender();
if (NEIClientConfig.getBooleanSetting("inventory.itemzoom.showName")) {
+1 -1
View File
@@ -52,7 +52,7 @@ public abstract class ItemsGrid<T extends ItemsGrid.ItemsGridSlot, M extends Ite
}
public void captureScreen(Runnable callback, int mode) {
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
GL11.glPushAttrib(GL11.GL_ENABLE_BIT | GL11.GL_COLOR_BUFFER_BIT);
resetFramebuffer();
this.framebuffer.bindFramebuffer(false);
@@ -100,7 +100,7 @@ public class ItemsTooltipLineHandler implements ITooltipLineHandler {
fontRenderer.drawStringWithShadow(this.labelColor + this.label + ":", x, y, 0);
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
GL11.glPushAttrib(GL11.GL_ENABLE_BIT | GL11.GL_COLOR_BUFFER_BIT);
GL11.glPushMatrix();
RenderHelper.enableGUIStandardItemLighting();
@@ -66,6 +66,7 @@ import codechicken.nei.guihook.IContainerInputHandler;
import codechicken.nei.guihook.IContainerObjectHandler;
import codechicken.nei.guihook.IContainerTooltipHandler;
import codechicken.nei.recipe.AutoCraftingManager;
import codechicken.nei.recipe.DebugHandlerWidget;
import codechicken.nei.recipe.GuiRecipeTab;
import codechicken.nei.recipe.RecipeCatalysts;
@@ -91,6 +92,7 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
public static SubsetWidget dropDown;
public static SearchField searchField;
public static ItemZoom itemZoom;
public static DebugHandlerWidget recipeHandlerWidget;
public static ButtonCycled options;
public static ButtonCycled bookmarksButton;
@@ -291,19 +293,6 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
}
}
@Override
public void postRenderTooltips(GuiContainer gui, int mousex, int mousey, List<String> tooltip) {
if (!isHidden() && isEnabled() && GuiContainerManager.shouldShowTooltip(gui)) {
final Widget focused = getWidgetUnderMouse(mousex, mousey);
if (focused != null) {
focused.postDrawTooltips(mousex, mousey, tooltip);
}
}
}
@Override
public List<String> handleTooltip(GuiContainer gui, int mousex, int mousey, List<String> currenttip) {
@@ -354,6 +343,10 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
if (!isHidden() && isEnabled() && GuiContainerManager.shouldShowTooltip(gui)) {
final Widget focused = getWidgetUnderMouse(mousex, mousey);
if (focused != null) {
currenttip = focused.handleItemTooltip(itemstack, mousex, mousey, currenttip);
}
if (focused instanceof IContainerTooltipHandler tip) {
currenttip = tip.handleItemTooltip(gui, itemstack, mousex, mousey, currenttip);
}
@@ -368,9 +361,14 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
if (!isHidden() && isEnabled() && GuiContainerManager.shouldShowTooltip(gui)) {
final Widget focused = getWidgetUnderMouse(mousex, mousey);
if (focused instanceof IContainerTooltipHandler tip) {
hotkeys = tip.handleHotkeys(gui, mousex, mousey, hotkeys);
if (focused != null) {
hotkeys = focused.handleHotkeys(mousex, mousey, hotkeys);
if (focused instanceof IContainerTooltipHandler tip) {
hotkeys = tip.handleHotkeys(gui, mousex, mousey, hotkeys);
}
}
}
return hotkeys;
@@ -408,6 +406,8 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
itemZoom = new ItemZoom();
recipeHandlerWidget = new DebugHandlerWidget();
dropDown = new SubsetWidget();
searchField = new SearchField("search");
API.addItemFilter(searchField);
@@ -783,9 +783,11 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
addWidget(itemZoom);
if (visiblity.showSubsetDropdown) {
// Bookmarks or Subset/dropdown
addWidget(dropDown);
}
addWidget(recipeHandlerWidget);
recipeHandlerWidget.setVisible();
}
public static LayoutStyle getLayoutStyle(int id) {
@@ -56,6 +56,7 @@ import codechicken.nei.config.OptionToggleButtonBoubs;
import codechicken.nei.config.OptionUtilities;
import codechicken.nei.config.preset.GuiPresetList;
import codechicken.nei.event.NEIConfigsLoadedEvent;
import codechicken.nei.recipe.DebugHandlerWidget;
import codechicken.nei.recipe.GuiRecipeTab;
import codechicken.nei.recipe.IRecipeHandler;
import codechicken.nei.recipe.InformationHandler;
@@ -248,6 +249,13 @@ public class NEIClientConfig {
.getBooleanValue(true);
API.addOption(new OptionToggleButton("inventory.guirecipe.slotHighlightPresent", true));
tag.getTag("inventory.guirecipe.infiniteScroll").setComment("Use Infinite Scroll for Handlers")
.getBooleanValue(false);
API.addOption(new OptionToggleButton("inventory.guirecipe.infiniteScroll", true));
tag.getTag("inventory.guirecipe.maxHeight").setComment("Recipe GUI Max Height").getIntValue(370);
API.addOption(new OptionIntegerField("inventory.guirecipe.maxHeight", 166, 4000));
tag.getTag("inventory.guirecipe.shiftOverlayRecipe")
.setComment("Require holding shift to move items when overlaying recipe").getBooleanValue(true);
API.addOption(new OptionToggleButton("inventory.guirecipe.shiftOverlayRecipe", true));
@@ -255,6 +263,10 @@ public class NEIClientConfig {
tag.getTag("inventory.guirecipe.profile").getBooleanValue(false);
API.addOption(new OptionToggleButton("inventory.guirecipe.profile", true));
tag.getTag("inventory.guirecipe.handlerInfo").setComment("ADVANCED: Handler Info Widget")
.getBooleanValue(false);
API.addOption(new OptionToggleButton("inventory.guirecipe.handlerInfo", true));
tag.getTag("inventory.subsets.enabled").setComment("Enable/disable Subsets Dropdown").getBooleanValue(true);
API.addOption(new OptionToggleButton("inventory.subsets.enabled", true));
@@ -989,6 +1001,7 @@ public class NEIClientConfig {
pluginNEIConfigLoaded = true;
MinecraftForge.EVENT_BUS.post(new NEIConfigsLoadedEvent());
DebugHandlerWidget.loadHandlerInfoPatch();
ItemList.loadItems.restart();
}
}.start();
@@ -528,7 +528,9 @@ public class NEIClientUtils extends NEIServerUtils {
}
public static void drawRect(double left, double top, double width, double height, Color color) {
Tessellator tessellator = Tessellator.instance;
final boolean is2DTexture = GL11.glGetBoolean(GL11.GL_TEXTURE_2D);
final boolean isBlend = GL11.glGetBoolean(GL11.GL_BLEND);
final Tessellator tessellator = Tessellator.instance;
GL11.glEnable(GL11.GL_BLEND);
GL11.glDisable(GL11.GL_TEXTURE_2D);
@@ -540,8 +542,9 @@ public class NEIClientUtils extends NEIServerUtils {
tessellator.addVertex(left + width, top, 0.0D);
tessellator.addVertex(left, top, 0.0D);
tessellator.draw();
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glDisable(GL11.GL_BLEND);
GL11.glColor4f(1, 1, 1, 1);
if (is2DTexture) GL11.glEnable(GL11.GL_TEXTURE_2D);
if (!isBlend) GL11.glDisable(GL11.GL_BLEND);
}
public static void drawNEIOverlayText(String text, Rectangle4i rect, float scale, int color, boolean shadow,
+3 -11
View File
@@ -11,14 +11,12 @@ import codechicken.lib.vec.Rectangle4i;
import codechicken.nei.ItemsGrid.ItemsGridSlot;
import codechicken.nei.api.GuiInfo;
import codechicken.nei.api.INEIGuiHandler;
import codechicken.nei.api.ShortcutInputHandler;
import codechicken.nei.guihook.GuiContainerManager;
import codechicken.nei.guihook.IContainerTooltipHandler;
import codechicken.nei.recipe.GuiCraftingRecipe;
import codechicken.nei.recipe.GuiRecipe;
import codechicken.nei.recipe.GuiUsageRecipe;
public abstract class PanelWidget<T extends ItemsGrid<? extends ItemsGridSlot, ? extends ItemsGrid.MouseContext>>
extends Widget implements IContainerTooltipHandler {
extends Widget {
protected static final int PADDING = 2;
@@ -285,13 +283,7 @@ public abstract class PanelWidget<T extends ItemsGrid<? extends ItemsGridSlot, ?
if (NEIController.manager.window instanceof GuiRecipe || NEIClientUtils.shiftKey()
|| !NEIClientConfig.canCheatItem(hoverSlot.getItemStack())) {
if (button == 0) {
GuiCraftingRecipe.openRecipeGui("item", hoverSlot.getItemStack().copy());
} else if (button == 1) {
GuiUsageRecipe.openRecipeGui("item", hoverSlot.getItemStack().copy());
}
ShortcutInputHandler.handleMouseClick(hoverSlot.getItemStack());
} else {
NEIClientUtils.cheatItem(getDraggedStackWithQuantity(hoverSlot.getItemStack()), button, -1);
}
@@ -114,16 +114,25 @@ public class PositionedStack {
return filteredItems.isEmpty() ? items : filteredItems;
}
public boolean setPermutationToRender(ItemStack ingredient) {
public int getPermutationIndex(ItemStack stack) {
for (int index = 0; index < this.items.length; index++) {
if (NEIServerUtils.areStacksSameTypeCraftingWithNBT(this.items[index], ingredient)) {
setPermutationToRender(index);
return true;
if (NEIServerUtils.areStacksSameTypeCraftingWithNBT(items[index], stack)) {
return index;
}
}
return false;
return -1;
}
public boolean setPermutationToRender(ItemStack ingredient) {
final int stackIndex = getPermutationIndex(ingredient);
if (stackIndex >= 0) {
setPermutationToRender(stackIndex);
}
return stackIndex >= 0;
}
public void setPermutationToRender(int index) {
@@ -136,6 +145,10 @@ public class PositionedStack {
}
}
public boolean contains(int mx, int my) {
return this.relx <= mx && this.rely <= my && this.relx + 16 >= mx && this.rely + 16 >= my;
}
public boolean contains(ItemStack ingredient) {
for (ItemStack item : items) if (NEIServerUtils.areStacksSameTypeCrafting(item, ingredient)) return true;
@@ -18,7 +18,6 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
@@ -40,7 +39,6 @@ import codechicken.nei.api.API;
import codechicken.nei.api.ItemFilter;
import codechicken.nei.api.ItemFilter.ItemFilterProvider;
import codechicken.nei.guihook.GuiContainerManager;
import codechicken.nei.guihook.IContainerTooltipHandler;
import codechicken.nei.recipe.GuiCraftingRecipe;
import codechicken.nei.recipe.GuiRecipeTab;
import codechicken.nei.recipe.ICraftingHandler;
@@ -49,7 +47,7 @@ import codechicken.nei.recipe.StackInfo;
import codechicken.nei.util.NBTJson;
import codechicken.nei.util.NEIMouseUtils;
public class SubsetWidget extends Button implements ItemFilterProvider, IContainerTooltipHandler {
public class SubsetWidget extends Button implements ItemFilterProvider {
protected static final int SLOT_HEIGHT = 18;
protected static final int MARGIN = 2;
@@ -788,7 +786,7 @@ public class SubsetWidget extends Button implements ItemFilterProvider, IContain
root.resize(screen, parent, dropRight);
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
GL11.glPushAttrib(GL11.GL_ENABLE_BIT | GL11.GL_COLOR_BUFFER_BIT);
GuiContainerManager.enable2DRender();
GuiContainerManager.drawItems.zLevel += 100;
@@ -939,7 +937,7 @@ public class SubsetWidget extends Button implements ItemFilterProvider, IContain
}
@Override
public Map<String, String> handleHotkeys(GuiContainer gui, int mousex, int mousey, Map<String, String> hotkeys) {
public Map<String, String> handleHotkeys(int mousex, int mousey, Map<String, String> hotkeys) {
if (SubsetWidget.hoverStack != null) {
+14 -2
View File
@@ -1,6 +1,7 @@
package codechicken.nei;
import java.util.List;
import java.util.Map;
import net.minecraft.item.ItemStack;
@@ -14,8 +15,6 @@ public abstract class Widget {
public void postDraw(int mx, int my) {}
public void postDrawTooltips(int mx, int my, List<String> tooltip) {}
public boolean handleClick(int mx, int my, int button) {
return true;
}
@@ -38,6 +37,10 @@ public abstract class Widget {
return false;
}
public Map<String, String> handleHotkeys(int mousex, int mousey, Map<String, String> hotkeys) {
return hotkeys;
}
public void update() {}
public Rectangle4i bounds() {
@@ -58,6 +61,14 @@ public abstract class Widget {
return tooltip;
}
public List<String> handleItemTooltip(ItemStack itemstack, int mousex, int mousey, List<String> tooltip) {
return tooltip;
}
public boolean isFocused() {
return false;
}
public void loseFocus() {}
public void gainFocus() {}
@@ -67,4 +78,5 @@ public abstract class Widget {
public int z;
public int w;
public int h;
}
@@ -0,0 +1,254 @@
package codechicken.nei;
import java.awt.Point;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
import net.minecraft.item.ItemStack;
import codechicken.lib.gui.GuiDraw;
import codechicken.lib.vec.Rectangle4i;
public class WidgetContainer extends Widget {
protected final List<Widget> widgets = new ArrayList<>();
protected boolean isFocused = false;
public void addWidget(Widget widget) {
this.widgets.add(widget);
}
public void setWidgets(List<Widget> widgets) {
final boolean isFocused = this.isFocused;
clear();
loseFocus();
for (Widget widget : widgets) {
addWidget(widget);
}
this.isFocused = isFocused;
}
public void clear() {
this.widgets.clear();
this.isFocused = false;
}
public List<Widget> getWidgets() {
return Collections.unmodifiableList(this.widgets);
}
public boolean removeIf(Predicate<Widget> filter) {
return this.widgets.removeIf(filter);
}
@Override
public void draw(int mousex, int mousey) {
drawWidgets(mousex, mousey);
}
protected void drawWidgets(int mousex, int mousey) {
final Rectangle4i bounds = bounds();
for (Widget widget : this.widgets) {
if (widget.bounds().intersects(bounds)) {
widget.draw(mousex, mousey);
}
}
}
@Override
public void update() {
for (Widget widget : this.widgets) {
widget.update();
}
Collections.sort(this.widgets, Comparator.comparingInt((Widget widget) -> widget.z));
}
public Widget getWidgetUnderMouse(int mousex, int mousey) {
if (!bounds().contains(mousex, mousey)) {
return null;
}
for (int index = this.widgets.size() - 1; index >= 0; index--) {
final Widget widget = this.widgets.get(index);
if (widget.contains(mousex, mousey)) {
return widget;
}
}
return null;
}
@Override
public boolean onMouseWheel(int scroll, int mousex, int mousey) {
final Widget widget = getWidgetUnderMouse(mousex, mousey);
return widget != null && widget.onMouseWheel(scroll, mousex, mousey);
}
@Override
public boolean handleClick(int mousex, int mousey, int button) {
if (contains(mousex, mousey)) {
gainFocus();
}
final Widget widget = getWidgetUnderMouse(mousex, mousey);
return widget != null && widget.handleClick(mousex, mousey, button);
}
@Override
public boolean handleClickExt(int mousex, int mousey, int button) {
loseFocus();
for (int index = this.widgets.size() - 1; index >= 0; index--) {
final Widget widget = this.widgets.get(index);
if (!widget.contains(mousex, mousey) && widget.handleClickExt(mousex, mousey, button)) {
return true;
}
}
return false;
}
@Override
public void mouseDragged(int mousex, int mousey, int button, long heldTime) {
for (int index = this.widgets.size() - 1; index >= 0; index--) {
final Widget widget = this.widgets.get(index);
widget.mouseDragged(mousex, mousey, button, heldTime);
}
}
@Override
public void mouseUp(int mousex, int mousey, int button) {
for (int index = this.widgets.size() - 1; index >= 0; index--) {
final Widget widget = this.widgets.get(index);
widget.mouseUp(mousex, mousey, button);
}
}
@Override
public boolean handleKeyPress(int keyCode, char keyChar) {
for (int index = this.widgets.size() - 1; index >= 0; index--) {
final Widget widget = this.widgets.get(index);
if (widget.handleKeyPress(keyCode, keyChar)) {
return true;
}
}
return false;
}
@Override
public void lastKeyTyped(int keyID, char keyChar) {
for (int index = this.widgets.size() - 1; index >= 0; index--) {
final Widget widget = this.widgets.get(index);
widget.lastKeyTyped(keyID, keyChar);
}
}
@Override
public boolean isFocused() {
return this.isFocused;
}
@Override
public void loseFocus() {
for (int index = this.widgets.size() - 1; index >= 0; index--) {
final Widget widget = this.widgets.get(index);
if (widget.isFocused()) {
widget.loseFocus();
}
}
this.isFocused = false;
}
@Override
public void gainFocus() {
final Point mouse = GuiDraw.getMousePosition();
final Widget widget = getWidgetUnderMouse(mouse.x, mouse.y);
if (widget != null) {
if (!widget.isFocused()) {
loseFocus();
widget.gainFocus();
}
} else {
loseFocus();
}
this.isFocused = true;
}
@Override
public ItemStack getStackMouseOver(int mousex, int mousey) {
final Widget widget = getWidgetUnderMouse(mousex, mousey);
if (widget != null) {
return widget.getStackMouseOver(mousex, mousey);
}
return null;
}
@Override
public void postDraw(int mousex, int mousey) {
for (Widget widget : this.widgets) {
widget.postDraw(mousex, mousey);
}
}
@Override
public void onGuiClick(int mousex, int mousey) {
for (int index = this.widgets.size() - 1; index >= 0; index--) {
final Widget widget = this.widgets.get(index);
widget.onGuiClick(mousex, mousey);
}
}
@Override
public List<String> handleTooltip(int mousex, int mousey, List<String> tooltip) {
final Widget widget = getWidgetUnderMouse(mousex, mousey);
if (widget != null) {
return widget.handleTooltip(mousex, mousey, tooltip);
}
return tooltip;
}
@Override
public Map<String, String> handleHotkeys(int mousex, int mousey, Map<String, String> hotkeys) {
final Widget widget = getWidgetUnderMouse(mousex, mousey);
if (widget != null) {
return widget.handleHotkeys(mousex, mousey, hotkeys);
}
return hotkeys;
}
}
@@ -24,7 +24,7 @@ public class DefaultOverlayRenderer implements IRecipeOverlayRenderer {
@Override
public void renderOverlay(GuiContainerManager gui, Slot slot) {
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
GL11.glPushAttrib(GL11.GL_ENABLE_BIT | GL11.GL_COLOR_BUFFER_BIT);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(770, 1);
@@ -16,7 +16,6 @@ import codechicken.nei.NEIDummySlotHandler;
import codechicken.nei.NEIPotionGuiHandler;
import codechicken.nei.recipe.CheatItemHandler;
import codechicken.nei.recipe.FillFluidContainerHandler;
import codechicken.nei.recipe.GuiRecipeCatalyst;
import codechicken.nei.recipe.SearchInputDropHandler;
public class GuiInfo {
@@ -31,7 +30,6 @@ public class GuiInfo {
API.registerNEIGuiHandler(new NEICreativeGuiHandler());
API.registerNEIGuiHandler(new NEIChestGuiHandler());
API.registerNEIGuiHandler(new NEIDummySlotHandler());
API.registerNEIGuiHandler(new GuiRecipeCatalyst(null));
API.registerNEIGuiHandler(new SearchInputDropHandler());
API.registerNEIGuiHandler(new FillFluidContainerHandler());
API.registerNEIGuiHandler(new CheatItemHandler());
@@ -145,9 +145,9 @@ public abstract class ShortcutInputHandler {
final int button = Mouse.getEventButton();
if (button == 0) {
return GuiCraftingRecipe.openRecipeGui("item", stackover);
return GuiCraftingRecipe.openRecipeGui("item", stackover.copy());
} else if (button == 1) {
return GuiUsageRecipe.openRecipeGui("item", stackover);
return GuiUsageRecipe.openRecipeGui("item", stackover.copy());
}
}
@@ -305,10 +305,9 @@ public abstract class ShortcutInputHandler {
if (!saveStackSize) {
stackover = StackInfo.withAmount(stackover, 0);
} else if (ItemPanels.itemPanel.contains(mousePos.x, mousePos.y)
|| ItemPanels.itemPanel.historyPanel.contains(mousePos.x, mousePos.y)) {
stackover = ItemQuantityField.prepareStackWithQuantity(stackover, 0);
}
} else if (ItemPanels.itemPanel.containsWithSubpanels(mousePos.x, mousePos.y)) {
stackover = ItemQuantityField.prepareStackWithQuantity(stackover, 0);
}
ItemPanels.bookmarkPanel
.addItem(stackover, existsRecipe ? recipeId : null, BookmarkGrid.DEFAULT_GROUP_ID);
@@ -380,7 +379,8 @@ public abstract class ShortcutInputHandler {
return ItemPanels.bookmarkPanel.pullBookmarkItems(math, shift);
}
public static Map<String, String> handleHotkeys(GuiContainer gui, int mousex, int mousey, ItemStack stack) {
public static Map<String, String> handleHotkeys(int mousex, int mousey, ItemStack stack) {
final GuiContainer gui = NEIClientUtils.getGuiContainer();
final int groupId = ItemPanels.bookmarkPanel.getHoveredGroupId(true);
final Map<String, String> hotkeys = new HashMap<>();
@@ -98,6 +98,7 @@ public class IMCHandler {
}
// true if not set to false
info.setUseCustomScroll(tag.hasKey("useCustomScroll") && tag.getBoolean("useCustomScroll"));
info.setShowFavoritesButton(!tag.hasKey("showFavoritesButton") || tag.getBoolean("showFavoritesButton"));
info.setShowOverlayButton(!tag.hasKey("showOverlayButton") || tag.getBoolean("showOverlayButton"));
@@ -47,7 +47,7 @@ public class OptionUtilities extends OptionStringSet {
LayoutManager.drawIcon(x + 4, 4, new Image(132, 12, 12, 12));
x += 24;
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
GL11.glPushAttrib(GL11.GL_ENABLE_BIT | GL11.GL_COLOR_BUFFER_BIT);
RenderHelper.enableGUIStandardItemLighting();
GL11.glEnable(GL12.GL_RESCALE_NORMAL);
ItemStack sword = new ItemStack(Items.diamond_sword);
@@ -4,6 +4,8 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL11;
import codechicken.nei.Image;
public class DrawableResource extends Image {
@@ -43,15 +45,160 @@ public class DrawableResource extends Image {
}
public void draw(int xOffset, int yOffset, int maskTop, int maskBottom, int maskLeft, int maskRight) {
Minecraft.getMinecraft().getTextureManager().bindTexture(this.resourceLocation);
final int x = xOffset + this.paddingLeft + maskLeft;
final int y = yOffset + this.paddingTop + maskTop;
final int textureX = this.x + maskLeft;
final int textureY = this.y + maskTop;
final boolean is2DTexture = GL11.glGetBoolean(GL11.GL_TEXTURE_2D);
final int width = this.width - maskRight - maskLeft;
final int height = this.height - maskBottom - maskTop;
// drawModalRectWithCustomSizedTexture
Gui.func_146110_a(x, y, textureX, textureY, width, height, textureWidth, textureHeight);
GL11.glEnable(GL11.GL_TEXTURE_2D);
Minecraft.getMinecraft().getTextureManager().bindTexture(this.resourceLocation);
drawModalRectWithCustomSizedTexture(xOffset + maskLeft, yOffset + maskTop, maskLeft, maskTop, width, height);
if (!is2DTexture) GL11.glDisable(GL11.GL_TEXTURE_2D);
}
public void draw(int xOffset, int yOffset, int width, int height, int sliceLeft, int sliceRight, int sliceTop,
int sliceBottom) {
final int textureWidth = getWidth();
final int textureHeight = getHeight();
final int middleWidth = textureWidth - sliceLeft - sliceRight;
final int middleHeight = textureHeight - sliceTop - sliceBottom;
final int tileWidth = width - sliceLeft - sliceRight;
final int tileHeight = height - sliceTop - sliceBottom;
if (middleWidth > 0 && middleHeight > 0 && tileWidth > 0 && tileHeight > 0) {
final boolean is2DTexture = GL11.glGetBoolean(GL11.GL_TEXTURE_2D);
final int tileWidthCount = tileWidth / middleWidth;
final int remainderWidth = tileWidth - (tileWidthCount * middleWidth);
final int tileHeightCount = tileHeight / middleHeight;
final int remainderHeight = tileHeight - (tileHeightCount * middleHeight);
GL11.glEnable(GL11.GL_TEXTURE_2D);
Minecraft.getMinecraft().getTextureManager().bindTexture(this.resourceLocation);
// middle parts
for (int tileW = 0; tileW <= tileWidthCount; tileW++) {
final int tileWidthSize = (tileW == tileWidthCount) ? remainderWidth : middleWidth;
final int x = xOffset + sliceLeft + tileW * middleWidth;
for (int tileH = 0; tileH <= tileHeightCount; tileH++) {
final int tileHeightSize = (tileH == tileHeightCount) ? remainderHeight : middleHeight;
drawModalRectWithCustomSizedTexture(
x,
yOffset + sliceTop + tileH * middleHeight,
sliceLeft,
sliceTop,
tileWidthSize,
tileHeightSize);
}
}
// border top
if (sliceTop > 0) {
for (int tileW = 0; tileW <= tileWidthCount; tileW++) {
final int tileWidthSize = (tileW == tileWidthCount) ? remainderWidth : middleWidth;
drawModalRectWithCustomSizedTexture(
xOffset + sliceLeft + tileW * middleWidth,
yOffset,
sliceLeft,
0,
tileWidthSize,
sliceTop);
}
}
// border bottom
if (sliceBottom > 0) {
for (int tileW = 0; tileW <= tileWidthCount; tileW++) {
final int tileWidthSize = (tileW == tileWidthCount) ? remainderWidth : middleWidth;
drawModalRectWithCustomSizedTexture(
xOffset + sliceLeft + tileW * middleWidth,
yOffset + sliceTop + tileHeight,
sliceLeft,
sliceTop + middleHeight,
tileWidthSize,
sliceBottom);
}
}
// border left
if (sliceLeft > 0) {
for (int tileH = 0; tileH <= tileHeightCount; tileH++) {
final int tileHeightSize = (tileH == tileHeightCount) ? remainderHeight : middleHeight;
drawModalRectWithCustomSizedTexture(
xOffset,
yOffset + sliceTop + tileH * middleHeight,
0,
sliceTop,
sliceLeft,
tileHeightSize);
}
}
// border right
if (sliceRight > 0) {
for (int tileH = 0; tileH <= tileHeightCount; tileH++) {
final int tileHeightSize = (tileH == tileHeightCount) ? remainderHeight : middleHeight;
drawModalRectWithCustomSizedTexture(
xOffset + sliceLeft + tileWidth,
yOffset + sliceTop + tileH * middleHeight,
sliceLeft + middleWidth,
sliceTop,
sliceRight,
tileHeightSize);
}
}
// angle left-top
if (sliceLeft > 0 && sliceTop > 0) {
drawModalRectWithCustomSizedTexture(xOffset, yOffset, 0, 0, sliceLeft, sliceTop);
}
// angle right-top
if (sliceRight > 0 && sliceTop > 0) {
drawModalRectWithCustomSizedTexture(
xOffset + sliceLeft + tileWidth,
yOffset,
sliceLeft + middleWidth,
0,
sliceRight,
sliceTop);
}
// angle left-bottom
if (sliceLeft > 0 && sliceBottom > 0) {
drawModalRectWithCustomSizedTexture(
xOffset,
yOffset + sliceTop + tileHeight,
0,
sliceTop + middleHeight,
sliceLeft,
sliceBottom);
}
// angle right-bottom
if (sliceRight > 0 && sliceBottom > 0) {
drawModalRectWithCustomSizedTexture(
xOffset + sliceLeft + tileWidth,
yOffset + sliceTop + tileHeight,
sliceLeft + middleWidth,
sliceTop + middleHeight,
sliceRight,
sliceBottom);
}
if (!is2DTexture) GL11.glDisable(GL11.GL_TEXTURE_2D);
}
}
private void drawModalRectWithCustomSizedTexture(int xOffset, int yOffset, int u, int v, int width, int height) {
Gui.func_146110_a(
xOffset + this.paddingLeft,
yOffset + this.paddingTop,
this.x + u,
this.y + v,
width,
height,
this.textureWidth,
this.textureHeight);
}
}
@@ -1,93 +0,0 @@
package codechicken.nei.drawable;
import net.minecraft.client.gui.GuiScreen;
import org.lwjgl.opengl.GL11;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
/*
* Taken from Mantle 1.12-1.3.3.49 under the MIT License The MIT License (MIT) Copyright (c) 2013-2014 Slime Knights
* (mDiyo, fuj1n, Sunstrike, progwml6, pillbox, alexbegt) Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
@SideOnly(Side.CLIENT)
public class GuiElementDuex {
// this is totally completely ugly but it's a simple solution that doesn't clutter everything too much >_>
public static int defaultTexW = 256;
public static int defaultTexH = 256;
public final int x;
public final int y;
public final int w;
public final int h;
public int texW;
public int texH;
public GuiElementDuex(int x, int y, int w, int h, int texW, int texH) {
this(x, y, w, h);
setTextureSize(texW, texH);
defaultTexW = texW;
defaultTexH = texH;
}
public GuiElementDuex(int x, int y, int w, int h) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
setTextureSize(defaultTexW, defaultTexH);
}
public GuiElementDuex setTextureSize(int w, int h) {
texW = w;
texH = h;
return this;
}
public GuiElementDuex shift(int xd, int yd) {
return new GuiElementDuex(this.x + xd, this.y + yd, this.w, this.h, this.texW, this.texH);
}
/**
* Draws the element at the given x/y coordinates
*
* @param xPos X-Coordinate on the screen
* @param yPos Y-Coordinate on the screen
*/
public int draw(int xPos, int yPos) {
// drawModalRectWithCustomSizedTexture
GL11.glColor4f(1, 1, 1, 1);
GuiScreen.func_146110_a(xPos, yPos, x, y, w, h, texW, texH);
return w;
}
public static class Builder {
public int w;
public int h;
public Builder(int w, int h) {
this.w = w;
this.h = h;
}
public GuiElementDuex get(int x, int y, int w, int h) {
return new GuiElementDuex(x, y, w, h, this.w, this.h);
}
}
}
@@ -1,91 +0,0 @@
package codechicken.nei.drawable;
import net.minecraft.client.gui.GuiScreen;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
/*
* Taken from Mantle 1.12-1.3.3.49 under the MIT License The MIT License (MIT) Copyright (c) 2013-2014 Slime Knights
* (mDiyo, fuj1n, Sunstrike, progwml6, pillbox, alexbegt) Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions: The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
@SideOnly(Side.CLIENT)
public class GuiElementScalable extends GuiElementDuex {
public GuiElementScalable(int x, int y, int w, int h, int texW, int texH) {
super(x, y, w, h, texW, texH);
}
public GuiElementScalable(int x, int y, int w, int h) {
super(x, y, w, h);
}
public int drawScaledX(int xPos, int yPos, int width) {
for (int i = 0; i < width / w; i++) {
draw(xPos + i * w, yPos);
}
// remainder that doesn't fit total width
int remainder = width % w;
if (remainder > 0) {
GuiScreen.func_146110_a(xPos + width - remainder, yPos, x, y, remainder, h, texW, texH);
}
return width;
}
public int drawScaledY(int xPos, int yPos, int height) {
for (int i = 0; i < height / h; i++) {
draw(xPos, yPos + i * h);
}
// remainder that doesn't fit total width
int remainder = height % h;
if (remainder > 0) {
// drawModalRectWithCustomSizedTexture
GuiScreen.func_146110_a(xPos, yPos + height - remainder, x, y, w, remainder, texW, texH);
}
return w;
}
public int drawScaled(int xPos, int yPos, int width, int height) {
// we draw full height row-wise
int full = height / this.h;
for (int i = 0; i < full; i++) {
drawScaledX(xPos, yPos + i * this.h, width);
}
yPos += full * this.h;
// and the remainder is drawn manually
int yRest = height % this.h;
// the same as drawScaledX but with the remaining height
for (int i = 0; i < width / w; i++) {
drawScaledY(xPos + i * w, yPos, yRest);
}
// remainder that doesn't fit total width
int remainder = width % w;
if (remainder > 0) {
// drawModalRectWithCustomSizedTexture
GuiScreen.func_146110_a(xPos + width - remainder, yPos, x, y, remainder, yRest, texW, texH);
}
return width;
}
@Override
public GuiElementScalable shift(int xd, int yd) {
GuiElementScalable element = new GuiElementScalable(this.x + xd, this.y + yd, this.w, this.h);
element.setTextureSize(texW, texH);
return element;
}
}
@@ -404,7 +404,7 @@ public class GuiContainerManager {
public static void enableMatrixStackLogging() {
if (!contextEnabled) {
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
GL11.glPushAttrib(GL11.GL_ENABLE_BIT | GL11.GL_COLOR_BUFFER_BIT);
modelviewDepth = GL11.glGetInteger(GL11.GL_MODELVIEW_STACK_DEPTH);
contextEnabled = true;
}
@@ -648,9 +648,6 @@ public class GuiContainerManager {
drawPagedTooltip(font, mousex + 12, mousey - 12, tooltip);
}
for (IContainerDrawHandler drawHandler : drawHandlers) {
drawHandler.postRenderTooltips(window, mousex, mousey, tooltip);
}
}
private List<String> collectHotkeyTips(int mousex, int mousey) {
@@ -1,7 +1,5 @@
package codechicken.nei.guihook;
import java.util.List;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.inventory.Slot;
@@ -9,14 +7,14 @@ public interface IContainerDrawHandler {
/**
* Initialize your objects and the gui for drawing.
*
*
* @param gui An instance of the currentscreen
*/
public void onPreDraw(GuiContainer gui);
/**
* Draw your objects. Called after all normal gui rendering has been performed.
*
*
* @param gui An instance of the currentscreen
* @param mousex The x position of the mouse in pixels from left
* @param mousey The y position of the mouse in pixels from top
@@ -25,27 +23,16 @@ public interface IContainerDrawHandler {
/**
* Use this to draw things that should always be on top, for example objects being held by the mouse.
*
*
* @param gui An instance of the currentscreen
* @param mousex The x position of the mouse in pixels from left
* @param mousey The y position of the mouse in pixels from top
*/
public void postRenderObjects(GuiContainer gui, int mousex, int mousey);
/**
* Use this to draw things that should be drawn just after vanilla slot tooltips, on top of buttons and other
* usually always-on-top widgets.
*
* @param gui An instance of the currentscreen
* @param mousex The x position of the mouse in pixels from left
* @param mousey The y position of the mouse in pixels from top
* @param tooltip The contents of the tooltip that has previously been drawn
*/
default void postRenderTooltips(GuiContainer gui, int mousex, int mousey, List<String> tooltip) {}
/**
* Render something over a slot before the item in the slot.
*
*
* @param gui An instance of the currentscreen
* @param slot The slot being rendered.
*/
@@ -53,7 +40,7 @@ public interface IContainerDrawHandler {
/**
* Render something over a slot after the item in the slot.
*
*
* @param gui An instance of the currentscreen
* @param slot The slot being rendered.
*/
@@ -2,122 +2,29 @@ package codechicken.nei.recipe;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import codechicken.nei.PositionedStack;
import codechicken.nei.api.ShortcutInputHandler;
public class ContainerRecipe extends Container {
private class RecipeInventory implements IInventory {
private ItemStack activeStack = null;
@Override
public boolean isUseableByPlayer(EntityPlayer entityplayer) {
return true;
}
@Override
public int getSizeInventory() {
return inventorySlots.size();
}
@Override
public ItemStack getStackInSlot(int i) {
if (i < 0 || i > inventoryItemStacks.size()) return null;
return (ItemStack) inventoryItemStacks.get(i);
}
@Override
public ItemStack decrStackSize(int i, int j) {
return null;
}
@Override
public void setInventorySlotContents(int slot, ItemStack itemstack) {
if (slot < 0 || slot >= inventoryItemStacks.size()) return;
inventoryItemStacks.set(slot, itemstack);
}
@Override
public String getInventoryName() {
return null;
}
@Override
public int getInventoryStackLimit() {
return 1;
}
@Override
public void markDirty() {}
@Override
public void openInventory() {}
@Override
public void closeInventory() {}
@Override
public ItemStack getStackInSlotOnClosing(int var1) {
return null;
}
@Override
public boolean isItemValidForSlot(int i, ItemStack itemstack) {
return false;
}
@Override
public boolean hasCustomInventoryName() {
return false;
}
}
private final RecipeInventory recipeInventory = new RecipeInventory();
public void clearInventory() {
inventoryItemStacks.clear();
inventorySlots.clear();
}
public ItemStack slotClick(int slot, int button, boolean flag, EntityPlayer entityplayer) {
if (slot < 0) return null;
ItemStack stack = recipeInventory.getStackInSlot(slot);
if (stack != null) {
if (button == 0) {
GuiCraftingRecipe.openRecipeGui("item", stack);
} else if (button == 1) {
GuiUsageRecipe.openRecipeGui("item", stack);
}
}
@Override
public ItemStack slotClick(int slotId, int clickedButton, int mode, EntityPlayer player) {
ShortcutInputHandler.handleMouseClick(this.activeStack);
return null;
}
public void addSlot(PositionedStack stack, int recipex, int recipey) {
int slot = inventorySlots.size();
addSlotToContainer(new Slot(recipeInventory, slot, recipex + stack.relx, recipey + stack.rely) {
@Override
public boolean isItemValid(ItemStack par1ItemStack) {
return false;
}
});
recipeInventory.setInventorySlotContents(slot, stack.item);
}
public Slot getSlotWithStack(PositionedStack stack, int recipex, int recipey) {
for (Object inventorySlot : inventorySlots) {
Slot slot = (Slot) inventorySlot;
if (slot.xDisplayPosition == (stack.relx + recipex) && slot.yDisplayPosition == (stack.rely + recipey))
return slot;
}
return null;
public void setActiveStack(ItemStack activeStack) {
this.inventorySlots.clear();
this.inventoryItemStacks.clear();
this.activeStack = activeStack;
}
@Override
public boolean canInteractWith(EntityPlayer entityplayer) {
return true;
}
@@ -131,4 +38,9 @@ public class ContainerRecipe extends Container {
public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2) {
return null; // no shift clicking (scrolling...)
}
@Deprecated
public Slot getSlotWithStack(PositionedStack stack, int recipex, int recipey) {
return null;
}
}
@@ -0,0 +1,640 @@
package codechicken.nei.recipe;
import java.awt.Point;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.stream.Collectors;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.inventory.GuiContainer;
import org.apache.commons.io.IOUtils;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.GL11;
import codechicken.lib.gui.GuiDraw;
import codechicken.lib.vec.Rectangle4i;
import codechicken.nei.Button;
import codechicken.nei.ClientHandler;
import codechicken.nei.FormattedTextField;
import codechicken.nei.LayoutManager;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.NEIClientUtils;
import codechicken.nei.TextField;
import codechicken.nei.Widget;
import codechicken.nei.drawable.DrawableBuilder;
import codechicken.nei.drawable.DrawableResource;
import codechicken.nei.guihook.GuiContainerManager;
import codechicken.nei.guihook.IContainerInputHandler;
import codechicken.nei.recipe.TemplateRecipeHandler.RecipeTransferRect;
public class DebugHandlerWidget extends Widget implements IContainerInputHandler {
private static abstract class IntegerField extends TextField {
protected int defaultValue = 0;
public IntegerField(String ident, int defaultValue) {
super(ident);
this.defaultValue = defaultValue;
this.h = LINE_HEIGHT;
this.z = 2;
((FormattedTextField) field).setPlaceholder(Integer.toString(this.defaultValue));
}
@Override
protected void initInternalTextField() {
field = new FormattedTextField(Minecraft.getMinecraft().fontRenderer, 0, 0, 0, 0) {
@Override
public String getText() {
String text = super.getText();
return !isFocused() && this.placeholder.equals(text) ? "" : text;
}
@Override
protected boolean beforeWrite(String text) {
if (text == null || text.isEmpty()) return true;
try {
return Integer.parseInt(text) >= 0;
} catch (NumberFormatException e) {
return false;
}
}
@Override
public boolean textboxKeyTyped(char keyChar, int keyID) {
if (!isFocused()) return false;
if (super.textboxKeyTyped(keyChar, keyID)) {
return true;
} else if (keyID == Keyboard.KEY_DOWN) {
setText(Integer.toString(getInteger() - 1));
return true;
} else if (keyID == Keyboard.KEY_UP) {
setText(Integer.toString(getInteger() + 1));
return true;
}
return false;
}
};
field.setMaxStringLength(maxSearchLength);
field.setCursorPositionZero();
}
protected int getInteger() {
try {
return Integer.parseInt(text());
} catch (NumberFormatException nfe) {
return this.defaultValue;
}
}
@Override
public boolean onMouseWheel(int i, int mx, int my) {
if (!contains(mx, my)) return false;
setText(Integer.toString(getInteger() + i));
return true;
}
}
private final int[] COLORS = new int[] { 0x2200FF00, 0x22FF0000, 0x220000FF, 0x2200FFFF, 0x22FF00FF, 0x22FFFF00 };
private IRecipeHandler handler;
private HandlerInfo handlerInfo;
private static final int WINDOW_WIDTH = 176;
private static final int LINE_HEIGHT = 16;
private static final int INLINE_PADDING = 6;
private static final int LABEL_WIDTH = 50;
private IntegerField order;
private IntegerField yShift;
private IntegerField handlerHeight;
private IntegerField handlerWidth;
private IntegerField maxRecipesPerPage;
private Button useCustomScroll;
private Point dragPoint = null;
public boolean showWidget = false;
private static final int BORDER_PADDING = 6;
private final DrawableResource BG_TEXTURE = new DrawableBuilder("nei:textures/gui/recipebg.png", 0, 0, 176, 166)
.build();
public DebugHandlerWidget() {
GuiContainerManager.addInputHandler(this);
this.order = new IntegerField("order", 0) {
@Override
public void onTextChange(String oldText) {
if (NEIClientConfig.handlerOrdering.get(handler.getOverlayIdentifier()) != null) {
if (getInteger() != NEIClientConfig.handlerOrdering.get(handler.getOverlayIdentifier())) {
updatePatch(5, getInteger(), this.defaultValue);
}
} else if (NEIClientConfig.handlerOrdering.get(handler.getHandlerId()) != null) {
if (getInteger() != NEIClientConfig.handlerOrdering.get(handler.getHandlerId())) {
updatePatch(5, getInteger(), this.defaultValue);
}
}
}
};
this.yShift = new IntegerField("yShift", 0) {
@Override
public void onTextChange(String oldText) {
if (getInteger() != handlerInfo.getYShift()) {
handlerInfo.setYShift(getInteger());
updatePatch(1, getInteger(), this.defaultValue);
}
}
};
this.maxRecipesPerPage = new IntegerField("maxRecipesPerPage", HandlerInfo.DEFAULT_MAX_PER_PAGE) {
@Override
public void onTextChange(String oldText) {
if (getInteger() != handlerInfo.getMaxRecipesPerPage()) {
handlerInfo.setHandlerDimensions(handlerInfo.getHeight(), handlerInfo.getWidth(), getInteger());
updatePatch(4, getInteger(), this.defaultValue);
}
}
};
this.handlerHeight = new IntegerField("handlerHeight", HandlerInfo.DEFAULT_HEIGHT) {
@Override
public void onTextChange(String oldText) {
if (getInteger() != handlerInfo.getHeight()) {
handlerInfo.setHandlerDimensions(
getInteger(),
handlerInfo.getWidth(),
handlerInfo.getMaxRecipesPerPage());
updatePatch(2, getInteger(), this.defaultValue);
}
}
};
this.handlerWidth = new IntegerField("handlerWidth", HandlerInfo.DEFAULT_WIDTH) {
@Override
public void onTextChange(String oldText) {
if (getInteger() != handlerInfo.getWidth()) {
handlerInfo.setHandlerDimensions(
handlerInfo.getHeight(),
getInteger(),
handlerInfo.getMaxRecipesPerPage());
updatePatch(3, getInteger(), this.defaultValue);
}
}
};
this.useCustomScroll = new Button() {
{
this.h = LINE_HEIGHT;
this.z = 2;
}
public String getRenderLabel() {
return handlerInfo.getUseCustomScroll() ? "On" : "Off";
}
@Override
public boolean onButtonPress(boolean rightclick) {
handlerInfo.setUseCustomScroll(!handlerInfo.getUseCustomScroll());
updatePatch(6, handlerInfo.getUseCustomScroll() ? 1 : 0, 0);
return true;
}
};
this.w = WINDOW_WIDTH;
this.h = 10 + 13 * LINE_HEIGHT;
this.x = 10;
this.y = 50;
this.z = 1;
}
private void updatePatch(int key, int value, int defaultValue) {
final String handlerKey = getHandlerID(handler);
if (!patches.containsKey(handlerKey)) {
patches.put(handlerKey, new String[] { handlerKey, null, null, null, null, null, null });
}
if (value == defaultValue) {
patches.get(handlerKey)[key] = null;
} else {
patches.get(handlerKey)[key] = String.valueOf(value);
}
saveHandlerInfoPatch();
if (NEIClientUtils.getGuiContainer() instanceof GuiRecipe<?>recipe) {
recipe.forceRefreshPage();
}
}
private void drawKeyLabel(String keyLabel, int topShift) {
GuiDraw.drawString(
NEIClientUtils.cropText(GuiDraw.fontRenderer, keyLabel, LABEL_WIDTH),
this.x + INLINE_PADDING,
topShift,
0x66555555,
false);
GuiDraw.drawString(":", this.x + INLINE_PADDING + LABEL_WIDTH, topShift, 0x66555555, false);
}
private void drawDetail(String keyLabel, String valueLabel, int topShift, int spaceWidth) {
drawKeyLabel(keyLabel, topShift);
GuiDraw.drawString(
NEIClientUtils.cropText(
GuiDraw.fontRenderer,
valueLabel,
this.w - INLINE_PADDING * 2 - LABEL_WIDTH - spaceWidth),
this.x + INLINE_PADDING + LABEL_WIDTH + spaceWidth,
topShift,
0xffffff);
}
private void drawControl(String keyLabel, Widget field, int topShift, int spaceWidth) {
drawKeyLabel(keyLabel, topShift);
field.x = this.x + INLINE_PADDING + LABEL_WIDTH + spaceWidth;
field.y = topShift - 4;
field.w = this.w - INLINE_PADDING * 2 - LABEL_WIDTH - spaceWidth;
}
@Override
public void draw(int mx, int my) {
if (this.handler != null) {
final int spaceWidth = GuiDraw.fontRenderer.getStringWidth(": ");
int topShift = this.y + BORDER_PADDING + 12 + 6;
GL11.glColor4f(1F, 1F, 1F, 1F);
GL11.glScaled(1, 1, 2f);
GL11.glDisable(GL11.GL_DEPTH_TEST);
BG_TEXTURE.draw(
this.x,
this.y,
this.w,
this.h,
BORDER_PADDING,
BORDER_PADDING,
BORDER_PADDING,
BORDER_PADDING);
GuiDraw.drawRect(
this.x + INLINE_PADDING,
this.y + BORDER_PADDING,
this.w - INLINE_PADDING * 2,
12,
0x30000000);
GuiDraw.drawStringC("Debug Recipe Handler", this.x + this.w / 2, this.y + BORDER_PADDING + 2, 0xffffff);
for (Map.Entry<String, String> entry : getDetailsInfo().entrySet()) {
drawDetail(entry.getKey(), entry.getValue(), topShift, spaceWidth);
topShift += LINE_HEIGHT;
}
drawControl("Order", this.order, topShift, spaceWidth);
topShift += LINE_HEIGHT;
drawControl("yShift", this.yShift, topShift, spaceWidth);
topShift += LINE_HEIGHT;
drawControl("Per Page", this.maxRecipesPerPage, topShift, spaceWidth);
topShift += LINE_HEIGHT;
drawControl("Height", this.handlerHeight, topShift, spaceWidth);
topShift += LINE_HEIGHT;
drawControl("Width", this.handlerWidth, topShift, spaceWidth);
topShift += LINE_HEIGHT;
drawControl("Use Custom Scroll", this.useCustomScroll, topShift, spaceWidth);
topShift += LINE_HEIGHT;
GL11.glScaled(1, 1, 1 / 2f);
}
}
private Map<String, String> getDetailsInfo() {
final Map<String, String> lines = new LinkedHashMap<>();
final boolean isHeightHackApplied = NEIClientConfig.heightHackHandlerRegex.stream()
.map(pattern -> pattern.matcher(this.handler.getHandlerId())).anyMatch(Matcher::matches);
lines.put("Name", this.handler.getRecipeName());
lines.put("ID", this.handler.getOverlayIdentifier());
lines.put("Key", this.handler.getHandlerId());
lines.put("H.Hack", String.valueOf(isHeightHackApplied));
lines.put("Mod Name", this.handlerInfo.getModName());
lines.put("Mod ID", this.handlerInfo.getModId());
return lines;
}
public void setVisible() {
if (showWidget && this.handler != null) {
LayoutManager.addWidget(this.order);
LayoutManager.addWidget(this.yShift);
LayoutManager.addWidget(this.handlerHeight);
LayoutManager.addWidget(this.handlerWidth);
LayoutManager.addWidget(this.maxRecipesPerPage);
LayoutManager.addWidget(this.useCustomScroll);
}
}
@Override
public void update() {
final GuiContainer gui = NEIClientUtils.getGuiContainer();
if (showWidget && gui instanceof GuiRecipe recipe) {
if (this.handler != recipe.getHandler()) {
this.handler = recipe.getHandler();
this.handlerInfo = GuiRecipeTab.getHandlerInfo(handler);
this.order.setText(String.valueOf(NEIClientConfig.getHandlerOrder(this.handler)));
this.yShift.setText(String.valueOf(this.handlerInfo.getYShift()));
this.handlerHeight.setText(String.valueOf(this.handlerInfo.getHeight()));
this.handlerWidth.setText(String.valueOf(this.handlerInfo.getWidth()));
this.maxRecipesPerPage.setText(String.valueOf(this.handlerInfo.getMaxRecipesPerPage()));
}
} else {
this.handler = null;
this.handlerInfo = null;
showWidget = false;
}
}
@Override
public List<String> handleTooltip(int mx, int my, List<String> tooltip) {
if (this.handler != null) {
final int spaceWidth = GuiDraw.fontRenderer.getStringWidth(": ");
final int leftShift = this.x + INLINE_PADDING;
if (mx >= leftShift && mx < this.x + WINDOW_WIDTH - INLINE_PADDING) {
int topShift = this.y + BORDER_PADDING + 12 + 6;
for (Map.Entry<String, String> entry : getDetailsInfo().entrySet()) {
if (my >= topShift && my < topShift + LINE_HEIGHT) {
if (mx < leftShift + LABEL_WIDTH + spaceWidth) {
tooltip.add(String.valueOf(entry.getKey()));
} else {
tooltip.add(String.valueOf(entry.getValue()));
}
break;
}
topShift += LINE_HEIGHT;
}
}
}
return tooltip;
}
@Override
public boolean keyTyped(GuiContainer gui, char keyChar, int keyCode) {
if (NEIClientConfig.getBooleanSetting("inventory.guirecipe.handlerInfo") && showWidget
&& keyCode == Keyboard.KEY_C
&& NEIClientUtils.controlKey()) {
final int spaceWidth = GuiDraw.fontRenderer.getStringWidth(": ");
final Point mouse = GuiDraw.getMousePosition();
if (mouse.x >= this.x + INLINE_PADDING + LABEL_WIDTH + spaceWidth
&& mouse.x < this.x + WINDOW_WIDTH - INLINE_PADDING) {
int topShift = this.y + BORDER_PADDING + 12 + 6;
for (Map.Entry<String, String> entry : getDetailsInfo().entrySet()) {
if (mouse.y >= topShift && mouse.y < topShift + LINE_HEIGHT) {
GuiScreen.setClipboardString(entry.getValue());
return true;
}
topShift += LINE_HEIGHT;
}
}
}
return false;
}
@Override
public boolean mouseClicked(GuiContainer gui, int mousex, int mousey, int button) {
return false;
}
@Override
public void onKeyTyped(GuiContainer gui, char keyChar, int keyID) {}
@Override
public boolean lastKeyTyped(GuiContainer gui, char keyChar, int keyID) {
if (NEIClientConfig.getBooleanSetting("inventory.guirecipe.handlerInfo") && keyID == Keyboard.KEY_D
&& NEIClientUtils.shiftKey()) {
showWidget = !showWidget;
return true;
} else if (this.handler != null) {
return this.order.focused() || this.yShift.focused()
|| this.handlerHeight.focused()
|| this.handlerWidth.focused()
|| this.maxRecipesPerPage.focused();
}
return false;
}
@Override
public void onMouseClicked(GuiContainer gui, int mousex, int mousey, int button) {
if (this.handler != null
&& new Rectangle4i(this.x + INLINE_PADDING, this.y + BORDER_PADDING, this.w - INLINE_PADDING * 2, 12)
.contains(mousex, mousey)) {
this.dragPoint = new Point(mousex, mousey);
}
}
@Override
public boolean contains(int px, int py) {
return this.handler != null && super.contains(px, py);
}
@Override
public void onMouseUp(GuiContainer gui, int mousex, int mousey, int button) {
this.dragPoint = null;
}
@Override
public boolean mouseScrolled(GuiContainer gui, int mousex, int mousey, int scrolled) {
return false;
}
@Override
public void onMouseScrolled(GuiContainer gui, int mousex, int mousey, int scrolled) {}
@Override
public boolean handleClickExt(int mx, int my, int button) {
return false;
}
@Override
public void onMouseDragged(GuiContainer gui, int mousex, int mousey, int button, long heldTime) {
if (this.dragPoint != null) {
this.x -= this.dragPoint.x - mousex;
this.y -= this.dragPoint.y - mousey;
this.dragPoint.move(mousex, mousey);
}
}
public void drawGuiPlaceholder(NEIRecipeWidget widget) {
if (!showWidget) return;
NEIClientUtils.gl2DRenderContext(() -> {
// background
GuiDraw.drawRect(
widget.x,
widget.y,
widget.w,
widget.h,
COLORS[widget.handlerRef.recipeIndex % COLORS.length]);
// blue-line-top (grid-top)
GuiDraw.drawRect(widget.x + 14, widget.y + 5, widget.w - 38, 1, 0xff0000aa);
// blue-line-bottom {grid-bottom}
GuiDraw.drawRect(widget.x + 14, widget.y + widget.h - 7, widget.w - 38, 1, 0xff0000aa);
// blue-left (grid start)
GuiDraw.drawRect(widget.x + 24, widget.y + (widget.h - 16) / 2, 1, 16, 0xffaa00aa);
// purple (before favorite)
GuiDraw.drawRect(
widget.x + Math.min(168, widget.w) - 27,
widget.y + widget.h - 6 - GuiRecipeButton.BUTTON_HEIGHT * 2 - 4,
GuiRecipeButton.BUTTON_WIDTH,
1,
0xffaa00aa);
// green ()
GuiDraw.drawRect(
widget.x + Math.min(168, widget.w) - 35,
widget.y + widget.h - 6 - GuiRecipeButton.BUTTON_HEIGHT - 3,
20,
1,
0xff00aa00);
// purple space before bottom grid
GuiDraw.drawRect(
widget.x + 14,
widget.y + widget.h - 7 - GuiRecipeButton.BUTTON_WIDTH / 2,
38,
1,
0xffaa00aa);
if (widget.handlerRef.handler instanceof TemplateRecipeHandler handler) {
int yShift = widget.getHandlerInfo().getYShift();
for (RecipeTransferRect rect : handler.transferRects) {
GuiDraw.drawRect(
widget.x + rect.rect.x,
widget.y + yShift + rect.rect.y,
rect.rect.width,
rect.rect.height,
0x40ff0000);
}
}
});
}
private static Map<String, String[]> patches = new HashMap<>();
public static void loadHandlerInfoPatch() {
ClientHandler.loadSettingsFile("handlers.patch", lines -> {
for (String line : lines.collect(Collectors.toCollection(HashSet::new))) {
final String[] parts = line.split(",");
final String handler = parts[0];
if (GuiRecipeTab.handlerMap.containsKey(handler)) {
final HandlerInfo info = GuiRecipeTab.handlerMap.get(handler);
final int yShift = intOrDefault(parts[1], info.getYShift());
final int height = intOrDefault(parts[2], info.getHeight());
final int width = intOrDefault(parts[3], info.getWidth());
final int maxRecipesPerPage = intOrDefault(parts[4], info.getMaxRecipesPerPage());
final int order = intOrDefault(parts[5], NEIClientConfig.handlerOrdering.getOrDefault(handler, 0));
final boolean useCustomScroll = intOrDefault(parts[6], info.getUseCustomScroll() ? 1 : 0) == 1;
info.setYShift(yShift);
info.setHandlerDimensions(height, width, maxRecipesPerPage);
info.setUseCustomScroll(useCustomScroll);
NEIClientConfig.handlerOrdering.put(handler, order);
}
patches.put(handler, parts);
}
});
}
private static void saveHandlerInfoPatch() {
final List<String> lines = new ArrayList<>();
for (String[] line : patches.values()) {
lines.add(String.join(",", line));
}
final File path = new File(NEIClientConfig.configDir, "handlers.patch");
try (FileOutputStream output = new FileOutputStream(path)) {
IOUtils.writeLines(lines, "\n", output, StandardCharsets.UTF_8);
} catch (IOException e) {}
}
private static int intOrDefault(String str, int defaultValue) {
if (str == null || str.equals("")) return defaultValue;
try {
return Integer.parseInt(str);
} catch (NumberFormatException e) {
return defaultValue;
}
}
private static String getHandlerID(IRecipeHandler handler) {
if (GuiRecipeTab.handlerMap.containsKey(handler.getHandlerId())) {
return handler.getHandlerId();
} else if (handler instanceof TemplateRecipeHandler) {
return handler.getOverlayIdentifier();
}
return null;
}
}
@@ -50,7 +50,7 @@ public class GuiCraftingRecipe extends GuiRecipe<ICraftingHandler> {
final ArrayList<ICraftingHandler> handlers = getCraftingHandlers(outputId, results);
if (!handlers.isEmpty()) {
final GuiCraftingRecipe gui = new GuiCraftingRecipe(handlers, "recipeId".equals(outputId));
final GuiCraftingRecipe gui = new GuiCraftingRecipe(handlers);
if (open) {
@@ -147,9 +147,8 @@ public class GuiCraftingRecipe extends GuiRecipe<ICraftingHandler> {
return null;
}
private GuiCraftingRecipe(ArrayList<ICraftingHandler> handlers, boolean limitToOneRecipe) {
private GuiCraftingRecipe(ArrayList<ICraftingHandler> handlers) {
super(NEIClientUtils.mc().currentScreen);
this.limitToOneRecipe = limitToOneRecipe;
this.currenthandlers = handlers;
}
@@ -9,7 +9,6 @@ import java.util.Map;
import java.util.Set;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.item.ItemStack;
import org.lwjgl.opengl.GL11;
@@ -116,7 +115,7 @@ public class GuiFavoriteButton extends GuiRecipeButton {
return Recipe.of(this.handlerRef);
}
public void lastKeyTyped(GuiRecipe<?> gui, char keyChar, int keyID) {
public void lastKeyTyped(char keyChar, int keyID) {
if (NEIClientConfig.isKeyHashDown("gui.bookmark") && NEIClientUtils.shiftKey()) {
saveRecipeInBookmark();
@@ -125,7 +124,7 @@ public class GuiFavoriteButton extends GuiRecipeButton {
}
@Override
public Map<String, String> handleHotkeys(GuiContainer gui, int mousex, int mousey, Map<String, String> hotkeys) {
public Map<String, String> handleHotkeys(int mousex, int mousey, Map<String, String> hotkeys) {
hotkeys.put(
NEIClientConfig.getKeyName("gui.bookmark", NEIClientUtils.SHIFT_HASH),
translate("recipe.favorite.bookmark_recipe"));
@@ -140,7 +139,7 @@ public class GuiFavoriteButton extends GuiRecipeButton {
}
@Override
public List<String> handleTooltip(GuiRecipe<?> gui, List<String> currenttip) {
public List<String> handleTooltip(List<String> currenttip) {
currenttip.add(translate("recipe.favorite"));
return currenttip;
@@ -161,7 +160,7 @@ public class GuiFavoriteButton extends GuiRecipeButton {
}
@Override
public boolean mouseScrolled(GuiRecipe<?> gui, int scroll) {
public boolean mouseScrolled(int scroll) {
if (this.selectedResult == null) return true;
final List<RecipeIngredient> results = new ArrayList<>(this.recipe.getResults());
@@ -106,17 +106,17 @@ public class GuiOverlayButton extends GuiRecipeButton {
}
@Override
public List<String> handleTooltip(GuiRecipe<?> gui, List<String> currenttip) {
public List<String> handleTooltip(List<String> currenttip) {
currenttip.add(NEIClientUtils.translate("recipe.overlay"));
if (!this.enabled && this.requireShiftForOverlayRecipe && this.canFillCraftingGrid) {
if (!this.enabled && requireShiftForOverlayRecipe() && canFillCraftingGrid()) {
currenttip.set(currenttip.size() - 1, currenttip.get(currenttip.size() - 1) + GuiDraw.TOOLTIP_LINESPACE);
currenttip.add(
EnumChatFormatting.RED + NEIClientUtils.translate("recipe.overlay.mismatch")
+ EnumChatFormatting.RESET);
} else if (this.missedMaterialsTooltipLineHandler != null) {
if ((!this.requireShiftForOverlayRecipe || NEIClientUtils.shiftKey()) && this.canFillCraftingGrid) {
if ((!requireShiftForOverlayRecipe() || NEIClientUtils.shiftKey()) && canFillCraftingGrid()) {
this.missedMaterialsTooltipLineHandler.setLabelColor(EnumChatFormatting.RED);
} else {
this.missedMaterialsTooltipLineHandler.setLabelColor(EnumChatFormatting.GRAY);
@@ -129,7 +129,7 @@ public class GuiOverlayButton extends GuiRecipeButton {
}
@Override
public Map<String, String> handleHotkeys(GuiContainer gui, int mousex, int mousey, Map<String, String> hotkeys) {
public Map<String, String> handleHotkeys(int mousex, int mousey, Map<String, String> hotkeys) {
if (requireShiftForOverlayRecipe()) {
@@ -174,7 +174,7 @@ public class GuiOverlayButton extends GuiRecipeButton {
protected void drawContent(Minecraft minecraft, int y, int x, boolean mouseOver) {
DrawableResource icon = ICON_OVERLAY;
if (this.hasOverlay && (!this.requireShiftForOverlayRecipe || NEIClientUtils.shiftKey())) {
if (hasOverlay() && (!requireShiftForOverlayRecipe() || NEIClientUtils.shiftKey())) {
icon = this.missedMaterialsTooltipLineHandler == null ? ICON_FILL : ICON_FILL_ERROR;
}
@@ -206,18 +206,19 @@ public class GuiOverlayButton extends GuiRecipeButton {
}
protected List<ItemOverlayState> ingredientsOverlay() {
List<PositionedStack> ingredients = this.handlerRef.handler.getIngredientStacks(this.handlerRef.recipeIndex);
final List<PositionedStack> ingredients = this.handlerRef.handler
.getIngredientStacks(this.handlerRef.recipeIndex);
if (this.itemPresenceCache.size() != ingredients.size()) {
this.itemPresenceCache.clear();
if (this.canFillCraftingGrid) {
if (canFillCraftingGrid()) {
this.itemPresenceCache.addAll(this.handlerRef.getPresenceOverlay(this.firstGui));
} else if (this.firstGui != null) {
this.itemPresenceCache.addAll(presenceOverlay(ingredients));
}
List<ItemStack> items = this.itemPresenceCache.stream().filter(state -> !state.isPresent())
final List<ItemStack> items = this.itemPresenceCache.stream().filter(state -> !state.isPresent())
.map(state -> state.getSlot().item).collect(Collectors.toList());
if (!items.isEmpty()) {
@@ -236,7 +237,7 @@ public class GuiOverlayButton extends GuiRecipeButton {
public void setRequireShiftForOverlayRecipe(boolean require) {
this.requireShiftForOverlayRecipe = require;
this.enabled = this.hasOverlay && (this.requireShiftForOverlayRecipe || this.canFillCraftingGrid);
this.enabled = hasOverlay() && (this.requireShiftForOverlayRecipe || canFillCraftingGrid());
}
public void setCanUseOverlayRenderer(boolean use) {
@@ -263,7 +264,7 @@ public class GuiOverlayButton extends GuiRecipeButton {
return Recipe.of(this.handlerRef);
}
private List<ItemOverlayState> presenceOverlay(List<PositionedStack> ingredients) {
protected List<ItemOverlayState> presenceOverlay(List<PositionedStack> ingredients) {
final List<ItemOverlayState> itemPresenceSlots = new ArrayList<>();
final List<ItemStack> invStacks = this.firstGui.inventorySlots.inventorySlots.stream()
.filter(
@@ -289,9 +290,9 @@ public class GuiOverlayButton extends GuiRecipeButton {
}
public void overlayRecipe(boolean shift) {
if (!this.hasOverlay) return;
if (!hasOverlay()) return;
if (!this.requireShiftForOverlayRecipe || shift) {
if (!requireShiftForOverlayRecipe() || shift) {
if (canFillCraftingGrid()) {
this.handlerRef.fillCraftingGrid(this.firstGui, 0);
}
@@ -302,8 +303,7 @@ public class GuiOverlayButton extends GuiRecipeButton {
}
@Override
public void lastKeyTyped(GuiRecipe<?> gui, char keyChar, int keyID) {
public void lastKeyTyped(char keyChar, int keyID) {
if (NEIClientConfig.isKeyHashDown("gui.bookmark") && NEIClientUtils.shiftKey()) {
saveRecipeInBookmark();
}
File diff suppressed because it is too large. Load diff
@@ -4,7 +4,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraftforge.client.event.GuiScreenEvent;
import codechicken.lib.vec.Rectangle4i;
@@ -16,33 +15,30 @@ public abstract class GuiRecipeButton extends GuiNEIButton {
public static class UpdateRecipeButtonsEvent extends GuiScreenEvent {
public List<GuiRecipeButton> buttonList;
public NEIRecipeWidget recipeWidget;
public UpdateRecipeButtonsEvent(GuiRecipe<?> gui, List<GuiRecipeButton> buttonList) {
public UpdateRecipeButtonsEvent(GuiRecipe<?> gui, NEIRecipeWidget recipeWidget,
List<GuiRecipeButton> buttonList) {
super(gui);
this.recipeWidget = recipeWidget;
this.buttonList = new ArrayList<>(buttonList);
}
@Cancelable
public static class Pre extends UpdateRecipeButtonsEvent {
public int xOffset;
public int yOffset;
public int height;
public HandlerInfo handlerInfo;
public Pre(GuiRecipe<?> gui, int xOffset, int yOffset, int height, HandlerInfo handlerInfo) {
super(gui, new ArrayList<>());
this.xOffset = xOffset;
this.yOffset = yOffset;
this.height = height;
public Pre(GuiRecipe<?> gui, NEIRecipeWidget recipeWidget, HandlerInfo handlerInfo) {
super(gui, recipeWidget, new ArrayList<>());
this.handlerInfo = handlerInfo;
}
}
public static class Post extends UpdateRecipeButtonsEvent {
public Post(GuiRecipe<?> gui, List<GuiRecipeButton> buttonList) {
super(gui, buttonList);
public Post(GuiRecipe<?> gui, NEIRecipeWidget recipeWidget, List<GuiRecipeButton> buttonList) {
super(gui, recipeWidget, buttonList);
}
}
}
@@ -57,15 +53,15 @@ public abstract class GuiRecipeButton extends GuiNEIButton {
this.handlerRef = point;
}
abstract List<String> handleTooltip(GuiRecipe<?> gui, List<String> currenttip);
public abstract List<String> handleTooltip(List<String> currenttip);
abstract Map<String, String> handleHotkeys(GuiContainer gui, int mousex, int mousey, Map<String, String> hotkeys);
public abstract Map<String, String> handleHotkeys(int mousex, int mousey, Map<String, String> hotkeys);
abstract void lastKeyTyped(GuiRecipe<?> gui, char keyChar, int keyID);
public abstract void lastKeyTyped(char keyChar, int keyID);
abstract void drawItemOverlay();
public abstract void drawItemOverlay();
public boolean mouseScrolled(GuiRecipe<?> gui, int scroll) {
public boolean mouseScrolled(int scroll) {
return false;
}
@@ -1,159 +1,167 @@
package codechicken.nei.recipe;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.util.ResourceLocation;
import java.util.ArrayList;
import java.util.List;
import org.lwjgl.util.Rectangle;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.item.ItemStack;
import codechicken.nei.api.INEIGuiAdapter;
import codechicken.nei.drawable.GuiElementDuex;
import codechicken.nei.drawable.GuiElementScalable;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
public class GuiRecipeCatalyst extends INEIGuiAdapter {
import codechicken.lib.gui.GuiDraw;
import codechicken.nei.NEIClientUtils;
import codechicken.nei.NEIServerUtils;
import codechicken.nei.PositionedStack;
import codechicken.nei.Widget;
import codechicken.nei.api.ShortcutInputHandler;
import codechicken.nei.drawable.DrawableBuilder;
import codechicken.nei.drawable.DrawableResource;
import codechicken.nei.guihook.GuiContainerManager;
private GuiRecipe<?> guiRecipe;
public static final int ingredientSize = 16;
public static final int ingredientBorder = 1;
public static final int tabBorder = 5;
public static final int fullBorder = ingredientBorder + tabBorder;
public class GuiRecipeCatalyst extends Widget {
private static final Rectangle catalystRect = new Rectangle();
private static final Rectangle targetRect = new Rectangle();
private static final int SLOT_SIZE = 16;
private static final int BORDER_PADDING = 6;
private static final DrawableResource BG_TEXTURE = new DrawableBuilder(
"nei:textures/catalyst_tab.png",
0,
0,
28,
28).setTextureSize(28, 28).build();
public GuiRecipeCatalyst(GuiRecipe<?> guiRecipe) {
this.guiRecipe = guiRecipe;
private static final DrawableResource FG_TEXTURE = new DrawableBuilder("nei:textures/slot.png", 0, 0, 18, 18)
.setTextureSize(18, 18).build();
private final List<PositionedStack> items = new ArrayList<>();
private int availableHeight = 0;
private boolean showWidget = false;
public void setCatalysts(List<PositionedStack> items) {
this.items.clear();
this.items.addAll(items);
}
public void draw() {
if (guiRecipe == null) return;
int catalystsSize = RecipeCatalysts.getRecipeCatalysts(guiRecipe.getHandler()).size();
if (catalystsSize == 0) return;
public void setAvailableHeight(int height) {
this.availableHeight = height;
}
int availableHeight = RecipeCatalysts.getHeight();
int columnCount = RecipeCatalysts.getColumnCount(availableHeight, catalystsSize);
int rowCount = RecipeCatalysts.getRowCount(availableHeight, catalystsSize);
int width, height, xPos, yPos;
public int getAvailableHeight() {
return this.availableHeight;
}
width = (ingredientBorder * 2) + (tabBorder * 2) + (columnCount * ingredientSize);
height = (ingredientBorder * 2) + (tabBorder * 2) + (rowCount * ingredientSize);
xPos = guiRecipe.guiLeft - width + tabBorder + 1;
yPos = guiRecipe.guiTop;
drawBordered("nei:textures/catalyst_tab.png", xPos, yPos, width, height, 28, 28, 6, 6, 6, 6);
public boolean isShowWidget() {
return this.showWidget;
}
width = (ingredientBorder * 2) + (columnCount * ingredientSize);
height = (ingredientBorder * 2) + (rowCount * ingredientSize);
xPos = guiRecipe.guiLeft - width + ingredientBorder + 1;
yPos = guiRecipe.guiTop + fullBorder - ingredientBorder;
drawBordered("nei:textures/slot.png", xPos, yPos, width, height, 18, 18, 1, 1, 1, 1);
public int getColumnCount() {
final int maxItemsPerColumn = Math.max(0, this.availableHeight - 2 - BORDER_PADDING * 2) / SLOT_SIZE;
return maxItemsPerColumn > 0 ? NEIServerUtils.divideCeil(this.items.size(), maxItemsPerColumn) : 0;
}
public int getRowCount() {
final int columnCount = getColumnCount();
return columnCount > 0 ? NEIServerUtils.divideCeil(this.items.size(), columnCount) : 0;
}
@Override
public boolean hideItemPanelSlot(GuiContainer gui, int x, int y, int w, int h) {
if (!(gui instanceof GuiRecipe)) return false;
guiRecipe = (GuiRecipe<?>) gui;
int catalystsSize = RecipeCatalysts.getRecipeCatalysts(guiRecipe.getHandler()).size();
if (catalystsSize == 0) return false;
public void update() {
final int columns = getColumnCount();
final int rows = getRowCount();
int availableHeight = RecipeCatalysts.getHeight();
int columnCount = RecipeCatalysts.getColumnCount(availableHeight, catalystsSize);
int rowCount = RecipeCatalysts.getRowCount(availableHeight, catalystsSize);
int margin = 4;
this.showWidget = rows * columns > 0;
this.w = columns * SLOT_SIZE + 2 + BORDER_PADDING * 2;
this.h = rows * SLOT_SIZE + 2 + BORDER_PADDING * 2;
if (rows == 0 || columns == 0) {
return;
}
int index = 0;
for (PositionedStack pStack : this.items) {
if (pStack.items.length > 1) {
final int stackIndex = (pStack.items.length + pStack.getPermutationIndex(pStack.item) + 1)
% pStack.items.length;
pStack.setPermutationToRender(stackIndex);
}
pStack.relx = this.w - BORDER_PADDING - 1 - SLOT_SIZE - (index / rows) * SLOT_SIZE;
pStack.rely = BORDER_PADDING + 1 + (index % rows) * SLOT_SIZE;
index++;
}
int width = (ingredientBorder * 2) + (tabBorder * 2) + (columnCount * ingredientSize) + margin;
int height = (ingredientBorder * 2) + (tabBorder * 2) + (rowCount * ingredientSize) + margin;
int xOffset = guiRecipe.guiLeft - width + tabBorder;
int yOffset = guiRecipe.guiTop;
catalystRect.setBounds(xOffset, yOffset, width, height);
targetRect.setBounds(x, y, w, h);
return targetRect.intersects(catalystRect);
}
private void drawBordered(String location, int xPos, int yPos, int width, int height, int texWidth, int texHeight,
int sliceLeft, int sliceRight, int sliceTop, int sliceBottom) {
Minecraft.getMinecraft().renderEngine.bindTexture(new ResourceLocation(location));
@Override
public void draw(int mx, int my) {
if (!this.showWidget) return;
GuiElementDuex cornerTopLeft = new GuiElementDuex(0, 0, sliceLeft, sliceTop, texWidth, texHeight);
GuiElementDuex cornerTopRight = new GuiElementDuex(
texWidth - sliceRight,
0,
sliceRight,
sliceTop,
texWidth,
texHeight);
GuiElementDuex cornerBottomLeft = new GuiElementDuex(
0,
texHeight - sliceBottom,
sliceLeft,
sliceBottom,
texWidth,
texHeight);
GuiElementDuex cornerBottomRight = new GuiElementDuex(
texWidth - sliceRight,
texHeight - sliceBottom,
sliceRight,
sliceBottom,
texWidth,
texHeight);
GL11.glTranslatef(this.x, this.y, 0);
GL11.glColor4f(1, 1, 1, 1);
GuiElementScalable borderTop = new GuiElementScalable(
sliceLeft,
0,
texWidth - sliceLeft - sliceRight,
sliceTop,
texWidth,
texHeight);
GuiElementScalable borderBottom = new GuiElementScalable(
sliceLeft,
texHeight - sliceBottom,
texWidth - sliceLeft - sliceRight,
sliceBottom,
texWidth,
texHeight);
GuiElementScalable borderLeft = new GuiElementScalable(
0,
sliceTop,
sliceLeft,
texHeight - sliceTop - sliceBottom,
texWidth,
texHeight);
GuiElementScalable borderRight = new GuiElementScalable(
texWidth - sliceRight,
sliceTop,
sliceRight,
texHeight - sliceTop - sliceBottom,
texWidth,
texHeight);
GuiElementScalable center = new GuiElementScalable(
sliceLeft,
sliceTop,
texWidth - sliceLeft - sliceRight,
texHeight - sliceTop - sliceBottom,
texWidth,
texHeight);
BG_TEXTURE.draw(0, 0, this.w, this.h, BORDER_PADDING, BORDER_PADDING, BORDER_PADDING, BORDER_PADDING);
FG_TEXTURE.draw(
BORDER_PADDING,
BORDER_PADDING,
this.w - BORDER_PADDING * 2,
this.h - BORDER_PADDING * 2,
1,
1,
1,
1);
int midW = width - borderLeft.w - borderRight.w;
int midH = height - borderTop.h - borderBottom.h;
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
RenderHelper.enableGUIStandardItemLighting();
GL11.glEnable(GL12.GL_RESCALE_NORMAL);
// top row
int x = xPos;
int y = yPos;
x += cornerTopLeft.draw(x, y);
x += borderTop.drawScaledX(x, y, midW);
cornerTopRight.draw(x, y);
for (PositionedStack pStack : this.items) {
GuiContainerManager.drawItem(pStack.relx, pStack.rely, pStack.item);
// center row
x = xPos;
y += borderTop.h;
x += borderLeft.drawScaledY(x, y, midH);
x += center.drawScaled(x, y, midW, midH);
borderRight.drawScaledY(x, y, midH);
if (pStack.contains(mx - this.x, my - this.y)) {
NEIClientUtils.gl2DRenderContext(
() -> GuiDraw.drawRect(pStack.relx, pStack.rely, SLOT_SIZE, SLOT_SIZE, -2130706433));
}
}
// bottom row
x = xPos;
y += midH;
x += cornerBottomLeft.draw(x, y);
x += borderBottom.drawScaledX(x, y, midW);
cornerBottomRight.draw(x, y);
GL11.glPopAttrib();
GL11.glTranslatef(-this.x, -this.y, 0);
}
public PositionedStack getPositionedStackMouseOver(int mx, int my) {
for (PositionedStack pStack : this.items) {
if (pStack.contains(mx - this.x, my - this.y)) {
return pStack;
}
}
return null;
}
@Override
public ItemStack getStackMouseOver(int mx, int my) {
final PositionedStack pStack = getPositionedStackMouseOver(mx, my);
if (pStack != null) {
return pStack.item;
}
return null;
}
@Override
public boolean handleClick(int mx, int my, int button) {
return ShortcutInputHandler.handleMouseClick(getStackMouseOver(mx, my));
}
@Deprecated
public static final int ingredientSize = 16;
@Deprecated
public static final int ingredientBorder = 1;
@Deprecated
public static final int tabBorder = 5;
@Deprecated
public static final int fullBorder = ingredientBorder + tabBorder;
}
@@ -42,10 +42,9 @@ public abstract class GuiRecipeTab extends Widget {
public static HashMap<String, HandlerInfo> handlerAdderFromIMC = new HashMap<>();
public static Set<String> handlerRemoverFromIMC = new HashSet<>();
private final GuiRecipe<?> guiRecipe;
private final IRecipeHandler handler;
private final String handlerName;
private final String handlerID;
protected final IRecipeHandler handler;
protected final String handlerName;
protected final String handlerID;
private boolean selected;
@@ -61,7 +60,7 @@ public abstract class GuiRecipeTab extends Widget {
protected abstract int getForegroundIconY();
public GuiRecipeTab(GuiRecipe<?> guiRecipe, IRecipeHandler handler, int x, int y) {
public GuiRecipeTab(IRecipeHandler handler, int x, int y) {
super();
this.x = x;
this.y = y;
@@ -69,7 +68,6 @@ public abstract class GuiRecipeTab extends Widget {
this.h = getHeight();
this.handler = handler;
this.handlerName = handler.getHandlerId();
this.guiRecipe = guiRecipe;
this.selected = false;
if (handler instanceof TemplateRecipeHandler) {
@@ -154,16 +152,10 @@ public abstract class GuiRecipeTab extends Widget {
}
}
public boolean onButtonPress(boolean rightclick) {
int newIdx = guiRecipe.currenthandlers.indexOf(handler);
if (newIdx == -1) return false;
public abstract boolean onButtonPress(boolean rightclick);
guiRecipe.setRecipePage(newIdx);
return true;
}
public void setSelected(IRecipeHandler current) {
selected = handler == current;
public void setSelected(boolean selected) {
this.selected = selected;
}
public static HandlerInfo getHandlerInfo(IRecipeHandler handler) {
@@ -273,6 +265,8 @@ public abstract class GuiRecipeTab extends Widget {
NEIClientConfig.logger.info("Error setting handler dimensions for " + handler);
}
info.setUseCustomScroll(
record.isSet("useCustomScroll") ? Boolean.parseBoolean(record.get("useCustomScroll")) : false);
handlerMap.put(handler, info);
NEIClientConfig.logger.info("Loaded " + handler);
}
@@ -3,7 +3,7 @@ package codechicken.nei.recipe;
import codechicken.nei.drawable.DrawableBuilder;
import codechicken.nei.drawable.DrawableResource;
public class GuiRecipeTabCreative extends GuiRecipeTab {
public abstract class GuiRecipeTabCreative extends GuiRecipeTab {
public static final int TAB_WIDTH = 28;
public static final int TAB_HEIGHT = 31;
@@ -20,8 +20,8 @@ public class GuiRecipeTabCreative extends GuiRecipeTab {
28,
30).build();
public GuiRecipeTabCreative(GuiRecipe<?> guiRecipe, IRecipeHandler handler, int x, int y) {
super(guiRecipe, handler, x, y);
public GuiRecipeTabCreative(IRecipeHandler handler, int x, int y) {
super(handler, x, y);
}
@Override
@@ -3,7 +3,7 @@ package codechicken.nei.recipe;
import codechicken.nei.drawable.DrawableBuilder;
import codechicken.nei.drawable.DrawableResource;
public class GuiRecipeTabJEI extends GuiRecipeTab {
public abstract class GuiRecipeTabJEI extends GuiRecipeTab {
public static final int TAB_WIDTH = 24;
public static final int TAB_HEIGHT = 24;
@@ -20,8 +20,8 @@ public class GuiRecipeTabJEI extends GuiRecipeTab {
24,
24).build();
public GuiRecipeTabJEI(GuiRecipe<?> guiRecipe, IRecipeHandler handler, int x, int y) {
super(guiRecipe, handler, x, y);
public GuiRecipeTabJEI(IRecipeHandler handler, int x, int y) {
super(handler, x, y);
}
@Override
@@ -1,168 +1,154 @@
package codechicken.nei.recipe;
import static codechicken.lib.gui.GuiDraw.getMousePosition;
import java.awt.Point;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;
import codechicken.lib.gui.GuiDraw;
import codechicken.nei.Button;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.NEIClientUtils;
public class GuiRecipeTabs {
private final GuiRecipe<?> guiRecipe;
private final List<GuiRecipeTab> tabs = new ArrayList<>();
private final List<Button> buttons = new ArrayList<>();
private final Rectangle area = new Rectangle();
private List<? extends IRecipeHandler> currenthandlers;
private int pageCount = 1;
private int pageNumber = 0;
private int categoriesPerPage = 1;
private int numHandlers = 1;
private int tabWidth;
private int tabHeight;
private int recipetype;
public GuiRecipeTabs(GuiRecipe<?> guiRecipe) {
this.guiRecipe = guiRecipe;
}
private final Button prevTab = new Button("<") {
public void initLayout() {
if (NEIClientConfig.useCreativeTabStyle()) {
tabWidth = GuiRecipeTabCreative.TAB_WIDTH;
tabHeight = GuiRecipeTabCreative.TAB_HEIGHT;
} else {
tabWidth = GuiRecipeTabJEI.TAB_WIDTH;
tabHeight = GuiRecipeTabJEI.TAB_HEIGHT;
@Override
public boolean onButtonPress(boolean rightClick) {
if (!rightClick) {
NEIClientUtils.playClickSound();
return previousPage();
} else return false;
}
int totalWidth = 0;
categoriesPerPage = 0;
numHandlers = guiRecipe.currenthandlers.size();
};
for (int i = 0; i < numHandlers; i++) {
if (totalWidth + tabWidth < (guiRecipe.xSize - 4)) {
totalWidth += tabWidth;
categoriesPerPage++;
} else {
break;
}
private final Button nextTab = new Button(">") {
@Override
public boolean onButtonPress(boolean rightclick) {
if (!rightclick) {
NEIClientUtils.playClickSound();
return nextPage();
} else return false;
}
area.width = totalWidth;
area.height = tabHeight;
area.x = guiRecipe.guiLeft + 4;
area.y = guiRecipe.guiTop - tabHeight + 3;
};
pageCount = (int) Math.ceil((float) numHandlers / categoriesPerPage);
calcPageNumber();
Rectangle navigationArea = new Rectangle(area);
navigationArea.height = 20;
navigationArea.translate(0, -(2 + navigationArea.height));
public static int getTabWidth() {
return NEIClientConfig.useCreativeTabStyle() ? GuiRecipeTabCreative.TAB_WIDTH : GuiRecipeTabJEI.TAB_WIDTH;
}
public void calcPageNumber() {
pageNumber = guiRecipe.recipetype / Math.max(categoriesPerPage, 1);
public static int getTabHeight() {
return NEIClientConfig.useCreativeTabStyle() ? GuiRecipeTabCreative.TAB_HEIGHT : GuiRecipeTabJEI.TAB_HEIGHT;
}
public void update(GuiRecipe<?> guiRecipe) {
final int tabWidth = getTabWidth();
final int tabHeight = getTabHeight();
this.recipetype = guiRecipe.recipetype;
this.currenthandlers = guiRecipe.currenthandlers;
this.numHandlers = this.currenthandlers.size();
this.categoriesPerPage = (guiRecipe.xSize - 4) / tabWidth;
this.pageNumber = this.recipetype / Math.max(this.categoriesPerPage, 1);
this.pageCount = (int) Math.ceil((float) this.numHandlers / this.categoriesPerPage);
this.area.width = this.categoriesPerPage * tabWidth;
this.area.height = tabHeight;
this.area.x = guiRecipe.guiLeft + 4;
this.area.y = guiRecipe.guiTop - tabHeight + 3;
refreshPage();
updateArrows(tabHeight);
}
public void refreshPage() {
tabs.clear();
buttons.clear();
final int startIndex = this.pageNumber * this.categoriesPerPage;
final int tabWidth = getTabWidth();
final int startIndex = pageNumber * categoriesPerPage;
for (int i = 0; i < categoriesPerPage; i++) {
this.tabs.clear();
for (int i = 0; i < this.categoriesPerPage && i + startIndex < numHandlers; i++) {
final int index = i + startIndex;
if (index >= numHandlers) break;
IRecipeHandler handler = guiRecipe.currenthandlers.get(index);
int tabX = area.x + (i * tabWidth);
final IRecipeHandler handler = this.currenthandlers.get(index);
final int tabX = this.area.x + (i * tabWidth);
if (NEIClientConfig.useCreativeTabStyle()) {
tabs.add(new GuiRecipeTabCreative(guiRecipe, handler, tabX, area.y));
tabs.add(new GuiRecipeTabCreative(handler, tabX, this.area.y) {
@Override
public boolean onButtonPress(boolean rightclick) {
setRecipePage(index);
return true;
}
});
} else {
tabs.add(new GuiRecipeTabJEI(guiRecipe, handler, tabX, area.y));
tabs.add(new GuiRecipeTabJEI(handler, tabX, this.area.y) {
@Override
public boolean onButtonPress(boolean rightclick) {
setRecipePage(index);
return true;
}
});
}
}
}
// Maybe add buttons
if (numHandlers > categoriesPerPage) {
Button prevTab = new Button("prevTab") {
private void updateArrows(int tabHeight) {
this.buttons.clear();
@Override
public boolean onButtonPress(boolean rightClick) {
if (!rightClick) {
NEIClientUtils.playClickSound();
return previousPage();
} else return false;
}
if (this.numHandlers > this.categoriesPerPage) {
this.prevTab.w = this.nextTab.w = 8;
this.prevTab.h = this.nextTab.h = tabHeight - 4;
this.prevTab.y = this.nextTab.y = this.area.y + 2;
@Override
public String getRenderLabel() {
return "<";
}
};
prevTab.w = 8;
prevTab.h = tabHeight - 4;
prevTab.x = area.x - prevTab.w + 1;
prevTab.y = area.y + 2;
buttons.add(prevTab);
this.prevTab.x = this.area.x - this.prevTab.w + 1;
this.nextTab.x = this.area.x + this.area.width - 1;
Button nextTab = new Button("nextTab") {
@Override
public boolean onButtonPress(boolean rightclick) {
if (!rightclick) {
NEIClientUtils.playClickSound();
return nextPage();
} else return false;
}
@Override
public String getRenderLabel() {
return ">";
}
};
nextTab.w = prevTab.w;
nextTab.h = prevTab.h;
nextTab.x = area.x + area.width - 1;
nextTab.y = prevTab.y;
buttons.add(nextTab);
this.buttons.add(this.prevTab);
this.buttons.add(this.nextTab);
}
}
public boolean nextPage() {
if (hasNext()) pageNumber++;
else pageNumber = 0;
protected void setRecipePage(int recipetype) {}
public boolean nextPage() {
this.pageNumber = (this.pageNumber + 1) % this.pageCount;
refreshPage();
return true;
}
public boolean hasNext() {
return pageNumber + 1 < pageCount;
}
public boolean previousPage() {
if (hasPrevious()) pageNumber--;
else pageNumber = pageCount - 1;
this.pageNumber = (this.pageCount + this.pageNumber - 1) % this.pageCount;
refreshPage();
return true;
}
public boolean hasPrevious() {
return pageNumber > 0;
}
public void draw(int mouseX, int mouseY) {
IRecipeHandler current = guiRecipe.currenthandlers.get(guiRecipe.recipetype);
for (GuiRecipeTab tab : tabs) {
tab.setSelected(current);
final int indexShift = this.pageNumber * this.categoriesPerPage;
for (int index = 0; index < this.tabs.size(); index++) {
final GuiRecipeTab tab = this.tabs.get(index);
tab.setSelected(indexShift + index == this.recipetype);
tab.draw(mouseX, mouseY);
}
for (Button button : buttons) {
for (Button button : this.buttons) {
button.draw(mouseX, mouseY);
}
}
@@ -170,12 +156,12 @@ public class GuiRecipeTabs {
public void handleTooltip(int mousex, int mousey, List<String> tooltips) {
if (!NEIClientConfig.areJEIStyleTabsVisible()) return;
for (GuiRecipeTab tab : tabs) {
for (GuiRecipeTab tab : this.tabs) {
if (tab.contains(mousex, mousey)) {
tab.addTooltips(tooltips);
}
}
for (Button button : buttons) {
for (Button button : this.buttons) {
if (button.contains(mousex, mousey)) {
button.addTooltips(tooltips);
}
@@ -185,27 +171,26 @@ public class GuiRecipeTabs {
protected boolean mouseClicked(int x, int y, int mouseButton) {
if (!NEIClientConfig.areJEIStyleTabsVisible()) return false;
for (Button button : buttons) {
for (Button button : this.buttons) {
if (button.contains(x, y)) {
return button.onButtonPress(mouseButton == 1);
}
}
for (GuiRecipeTab tab : tabs) {
for (GuiRecipeTab tab : this.tabs) {
if (tab.contains(x, y)) {
return tab.onButtonPress(mouseButton == 1);
}
}
return false;
}
protected boolean mouseScrolled(int i) {
Point mousePosition = getMousePosition();
protected boolean mouseScrolled(int scroll) {
// Switch between recipe handlers if the cursor is over the tabbar.
if (NEIClientConfig.areJEIStyleTabsVisible() && area.contains(mousePosition)) {
if (i < 0) guiRecipe.nextType();
else guiRecipe.prevType();
if (NEIClientConfig.areJEIStyleTabsVisible() && this.area.contains(GuiDraw.getMousePosition())) {
setRecipePage(this.recipetype - scroll);
return true;
}
@@ -21,15 +21,13 @@ public class HandlerInfo {
private boolean requiresMod;
private String excludedModId;
private String itemId;
private String nbtString;
private int yShift = 0;
private int height = DEFAULT_HEIGHT;
private int width = DEFAULT_WIDTH;
private int maxRecipesPerPage = DEFAULT_MAX_PER_PAGE;
private boolean showFavoritesButton = true;
private boolean showOverlayButton = true;
private boolean useCustomScroll = false;
private ItemStack itemStack = null;
private DrawableResource image = null;
@@ -51,13 +49,13 @@ public class HandlerInfo {
public boolean setItem(String itemId, String nbtString) {
if (hasImageOrItem()) return false;
itemStack = NEIServerUtils.getModdedItem(itemId, nbtString);
if (itemStack == null) NEIClientConfig.logger.info("Couldn't find " + modName + " - " + itemId);
else {
this.itemId = itemId;
this.nbtString = nbtString;
this.itemStack = NEIServerUtils.getModdedItem(itemId, nbtString);
if (this.itemStack == null) {
NEIClientConfig.logger.info("Couldn't find " + this.modName + " - " + itemId);
}
return (itemStack != null);
return this.itemStack != null;
}
public boolean setImage(String resourceLocation, int imageX, int imageY, int imageWidth, int imageHeight) {
@@ -68,46 +66,43 @@ public class HandlerInfo {
}
public DrawableResource getImage() {
return image;
return this.image;
}
public ItemStack getItemStack() {
return itemStack;
return this.itemStack;
}
public String getModName() {
return modName;
return this.modName;
}
public String getModId() {
return modId;
return this.modId;
}
public int getHeight() {
return height;
return this.height;
}
public int getWidth() {
return width;
return this.width;
}
public int getMaxRecipesPerPage() {
return Math.max(maxRecipesPerPage, 1);
return Math.max(this.maxRecipesPerPage, 1);
}
public int getYShift() {
return yShift;
return this.yShift;
}
public String getHandlerName() {
return handlerName;
return this.handlerName;
}
public boolean hasImageOrItem() {
if (image != null) return true;
if (itemStack != null) return true;
return false;
return this.image != null || this.itemStack != null;
}
public void setYShift(int yShift) {
@@ -130,6 +125,14 @@ public class HandlerInfo {
this.showOverlayButton = showOverlayButton;
}
public boolean getUseCustomScroll() {
return this.useCustomScroll;
}
public void setUseCustomScroll(boolean useCustomScroll) {
this.useCustomScroll = useCustomScroll;
}
public static class Builder {
private final HandlerInfo info;
@@ -162,6 +165,11 @@ public class HandlerInfo {
return this;
}
public Builder setUseCustomScroll(boolean useCustomScroll) {
info.setUseCustomScroll(useCustomScroll);
return this;
}
public Builder setShiftY(int shiftY) {
info.setYShift(shiftY);
return this;
@@ -126,12 +126,6 @@ public interface IRecipeHandler {
return null;
}
/**
*
* @return The number of recipes that can fit on a page in the viewer (1 or 2)
*/
int recipiesPerPage();
/**
*
* @param gui An instance of the currentscreen
@@ -178,4 +172,12 @@ public interface IRecipeHandler {
default boolean mouseScrolled(GuiRecipe<?> gui, int scroll, int recipe) {
return false;
}
/**
* @deprecated
* @return The number of recipes that can fit on a page in the viewer (1 or 2)
*/
default int recipiesPerPage() {
return 2;
}
}
@@ -0,0 +1,399 @@
package codechicken.nei.recipe;
import java.awt.Point;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.MinecraftForge;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import codechicken.lib.gui.GuiDraw;
import codechicken.nei.LayoutManager;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.NEIClientUtils;
import codechicken.nei.PositionedStack;
import codechicken.nei.Widget;
import codechicken.nei.api.IGuiContainerOverlay;
import codechicken.nei.api.ShortcutInputHandler;
import codechicken.nei.guihook.GuiContainerManager;
import codechicken.nei.recipe.GuiRecipeButton.UpdateRecipeButtonsEvent;
public class NEIRecipeWidget extends Widget {
protected final RecipeHandlerRef handlerRef;
protected final HandlerInfo handlerInfo;
protected boolean showAsWidget = false;
protected List<GuiRecipeButton> recipeButtons = null;
protected boolean firstDraw = true;
protected boolean needUpdate = true;
public NEIRecipeWidget(RecipeHandlerRef handlerRef) {
this.handlerRef = handlerRef;
this.handlerInfo = GuiRecipeTab.getHandlerInfo(this.handlerRef.handler);
update();
}
public void setLocation(int x, int y) {
this.x = x;
this.y = y;
}
public void update() {
this.w = this.handlerInfo.getWidth();
if (this.showAsWidget || !this.handlerInfo.getUseCustomScroll()
|| this.handlerInfo.getMaxRecipesPerPage() > 1) {
this.h = this.handlerInfo.getHeight() + this.handlerInfo.getYShift();
}
this.needUpdate = true;
}
public List<GuiRecipeButton> getRecipeButtons() {
if (this.recipeButtons == null) {
if (this.handlerRef.handler.getResultStack(this.handlerRef.recipeIndex) != null
|| !this.handlerRef.handler.getOtherStacks(this.handlerRef.recipeIndex).isEmpty()) {
this.recipeButtons = initButtons();
} else {
this.recipeButtons = Collections.emptyList();
}
}
return Collections.unmodifiableList(this.recipeButtons);
}
protected List<GuiRecipeButton> getRecipeButtonsIfInit() {
if (this.recipeButtons == null) {
return Collections.emptyList();
}
return Collections.unmodifiableList(this.recipeButtons);
}
public RecipeHandlerRef getRecipeHandlerRef() {
return this.handlerRef;
}
public Recipe getRecipe() {
return Recipe.of(this.handlerRef);
}
public HandlerInfo getHandlerInfo() {
return this.handlerInfo;
}
public void showAsWidget(boolean show) {
this.showAsWidget = show;
}
protected List<GuiRecipeButton> initButtons() {
final GuiRecipe<?> guiRecipe = getGuiRecipe();
if (guiRecipe != null) {
final UpdateRecipeButtonsEvent.Pre preEvent = new UpdateRecipeButtonsEvent.Pre(
guiRecipe,
this,
this.handlerInfo);
if (MinecraftForge.EVENT_BUS.post(preEvent)) {
return preEvent.buttonList;
} else {
final UpdateRecipeButtonsEvent.Post postEvent = new UpdateRecipeButtonsEvent.Post(
guiRecipe,
this,
getDefatulButtons());
MinecraftForge.EVENT_BUS.post(postEvent);
return postEvent.buttonList;
}
} else {
return getDefatulButtons();
}
}
protected List<GuiRecipeButton> getDefatulButtons() {
GuiContainer guiContainer = NEIClientUtils.getGuiContainer();
final List<GuiRecipeButton> buttons = new ArrayList<>();
final boolean showFavorites = NEIClientConfig.favoritesEnabled() && handlerInfo.getShowFavoritesButton();
final boolean showOverlay = handlerInfo.getShowOverlayButton();
final int x = Math.min(168, this.w) - GuiRecipeButton.BUTTON_WIDTH;
int y = this.h - GuiRecipeButton.BUTTON_HEIGHT - 6;
if (guiContainer instanceof IGuiContainerOverlay overlay) {
guiContainer = overlay.getFirstScreen();
}
if (showOverlay) {
buttons.add(new GuiOverlayButton(guiContainer, this.handlerRef, x, y));
y -= GuiRecipeButton.BUTTON_HEIGHT + 1;
}
if (showFavorites) {
buttons.add(new GuiFavoriteButton(handlerRef, x, y));
}
return buttons;
}
@Override
public void draw(int mouseX, int mouseY) {
final int yShift = this.handlerInfo.getYShift();
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
GL11.glTranslatef(this.x, this.y + yShift, 0);
this.handlerRef.handler.drawBackground(this.handlerRef.recipeIndex);
RenderHelper.enableGUIStandardItemLighting();
GL11.glEnable(GL12.GL_RESCALE_NORMAL);
GL11.glColor4f(1, 1, 1, 1);
if (this.firstDraw) {
this.firstDraw = false;
for (PositionedStack pStack : this.handlerRef.handler.getIngredientStacks(this.handlerRef.recipeIndex)) {
pStack.setPermutationToRender(pStack.getFilteredPermutations().get(0));
}
}
for (PositionedStack pStack : getItems(!this.needUpdate)) {
GuiContainerManager.drawItem(pStack.relx, pStack.rely, pStack.item);
if (pStack.contains(mouseX - this.x, mouseY - this.y - yShift)) {
NEIClientUtils.gl2DRenderContext(() -> GuiDraw.drawRect(pStack.relx, pStack.rely, 16, 16, -2130706433));
}
}
this.needUpdate = false;
this.handlerRef.handler.drawForeground(this.handlerRef.recipeIndex);
final GuiRecipeButton overlayButton = getRecipeButtons().stream()
.filter(
b -> this.showAsWidget ? b instanceof GuiOverlayButton
: b.contains(mouseX - this.x, mouseY - this.y - yShift))
.findAny().orElse(null);
if (overlayButton != null && overlayButton.enabled) {
NEIClientUtils.gl2DRenderContext(() -> overlayButton.drawItemOverlay());
}
GL11.glTranslatef(-this.x, -this.y - yShift, 0);
GL11.glPopAttrib();
if (!this.showAsWidget) {
final Minecraft mc = NEIClientUtils.mc();
for (GuiRecipeButton button : getRecipeButtons()) {
button.xPosition += this.x;
button.yPosition += this.y;
button.drawButton(mc, mouseX, mouseY);
button.xPosition -= this.x;
button.yPosition -= this.y;
}
}
LayoutManager.recipeHandlerWidget.drawGuiPlaceholder(this);
}
@Override
public boolean handleKeyPress(int keyID, char keyChar) {
return false;
}
@Override
public void lastKeyTyped(int keyID, char keyChar) {
final Point mouse = GuiDraw.getMousePosition();
forEachButtons(button -> {
if (button.contains(mouse.x, mouse.y)) {
button.lastKeyTyped(keyChar, keyID);
}
return null;
}, null);
}
@Override
public boolean handleClick(int mouseX, int mouseY, int button) {
if (ShortcutInputHandler.handleMouseClick(getStackMouseOver(mouseX, mouseY))) {
return true;
}
if (button == 0) {
final Minecraft mc = NEIClientUtils.mc();
if (forEachButtons(guibutton -> {
if (guibutton.mousePressed(mc, mouseX, mouseY)) {
NEIClientUtils.playClickSound();
guibutton.mouseReleased(mouseX, mouseY);
return true;
}
return null;
}, false)) {
return true;
}
}
final GuiRecipe<?> guiRecipe = getGuiRecipe();
if (guiRecipe == null) {
return false;
}
return this.handlerRef.handler.mouseClicked(guiRecipe, button, this.handlerRef.recipeIndex);
}
@Override
public List<String> handleTooltip(int mouseX, int mouseY, List<String> tooltip) {
final GuiRecipe<?> guiRecipe = getGuiRecipe();
if (guiRecipe == null) {
return tooltip;
}
final List<String> localTooltip = this.handlerRef.handler
.handleTooltip(guiRecipe, tooltip, this.handlerRef.recipeIndex);
return forEachButtons(
button -> button.contains(mouseX, mouseY) ? button.handleTooltip(localTooltip) : null,
localTooltip);
}
@Override
public List<String> handleItemTooltip(ItemStack itemstack, int mousex, int mousey, List<String> tooltip) {
final GuiRecipe<?> guiRecipe = getGuiRecipe();
if (guiRecipe == null) {
return tooltip;
}
return this.handlerRef.handler.handleItemTooltip(guiRecipe, itemstack, tooltip, this.handlerRef.recipeIndex);
}
@Override
public Map<String, String> handleHotkeys(int mouseX, int mouseY, Map<String, String> hotkeys) {
return forEachButtons(
button -> button.contains(mouseX, mouseY) ? button.handleHotkeys(mouseX, mouseY, hotkeys) : null,
hotkeys);
}
@Override
public boolean onMouseWheel(int scroll, int mx, int my) {
if (forEachButtons(button -> button.contains(mx, my) ? button.mouseScrolled(scroll) : null, false)) {
return true;
}
final GuiRecipe<?> guiRecipe = getGuiRecipe();
return guiRecipe != null
&& this.handlerRef.handler.mouseScrolled(guiRecipe, scroll, this.handlerRef.recipeIndex);
}
protected <R> R forEachButtons(Function<GuiRecipeButton, R> callback, R defaultValue) {
for (GuiRecipeButton button : getRecipeButtonsIfInit()) {
button.xPosition += this.x;
button.yPosition += this.y;
final R result = callback.apply(button);
button.xPosition -= this.x;
button.yPosition -= this.y;
if (result != null) {
return result;
}
}
return defaultValue;
}
public boolean isFocusedRecipe(int mx, int my) {
final int yShift = this.handlerInfo.getYShift();
final PositionedStack pStackResult = this.handlerRef.handler.getResultStack(this.handlerRef.recipeIndex);
if (pStackResult != null && pStackResult.contains(mx - this.x, my - this.y - yShift)) {
return true;
}
for (PositionedStack pStackOver : this.handlerRef.handler.getOtherStacks(this.handlerRef.recipeIndex)) {
if (pStackOver.contains(mx - this.x, my - this.y - yShift)) {
return true;
}
}
return false;
}
public PositionedStack getPositionedStackMouseOver(int mx, int my) {
final int yShift = this.handlerInfo.getYShift();
for (PositionedStack pStack : getItems(true)) {
if (pStack.contains(mx - this.x, my - this.y - yShift)) {
return pStack;
}
}
return null;
}
@Override
public ItemStack getStackMouseOver(int mx, int my) {
final PositionedStack pStack = getPositionedStackMouseOver(mx, my);
return pStack != null ? pStack.item : null;
}
protected GuiRecipe<?> getGuiRecipe() {
final GuiContainer guiContainer = NEIClientUtils.getGuiContainer();
if (guiContainer instanceof GuiRecipe<?>guiRecipe) {
return guiRecipe;
}
return null;
}
protected GuiContainer getFirstGui() {
final GuiContainer guiContainer = NEIClientUtils.getGuiContainer();
if (guiContainer instanceof GuiRecipe<?>guiRecipe) {
return guiRecipe.firstGui;
}
return guiContainer;
}
protected List<PositionedStack> getItems(boolean disableCycledIngredients) {
final PositionedStack pStackResult = this.handlerRef.handler.getResultStack(this.handlerRef.recipeIndex);
final List<PositionedStack> itemStacks = new ArrayList<>();
TemplateRecipeHandler.disableCycledIngredients = disableCycledIngredients;
itemStacks.addAll(this.handlerRef.handler.getIngredientStacks(this.handlerRef.recipeIndex));
itemStacks.addAll(this.handlerRef.handler.getOtherStacks(this.handlerRef.recipeIndex));
TemplateRecipeHandler.disableCycledIngredients = true;
if (pStackResult != null) {
itemStacks.add(pStackResult);
}
return itemStacks;
}
}
@@ -102,11 +102,6 @@ public class ProfilerRecipeHandler implements ICraftingHandler, IUsageHandler {
return null;
}
@Override
public int recipiesPerPage() {
return 1;
}
@Override
public List<String> handleTooltip(GuiRecipe<?> gui, List<String> currenttip, int recipe) {
return currenttip;
@@ -17,6 +17,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import net.minecraft.item.ItemStack;
@@ -37,10 +38,8 @@ public class RecipeCatalysts {
private static final Map<String, List<ItemStack>> catalystsRemoverFromAPI = new HashMap<>();
public static final Map<String, CatalystInfoList> catalystsAdderFromIMC = new HashMap<>();
public static final Map<String, List<ItemStack>> catalystsRemoverFromIMC = new HashMap<>();
private static final Map<String, CatalystInfoList> recipeCatalystMap = new HashMap<>();
private static Map<String, List<PositionedStack>> positionedRecipeCatalystMap = new HashMap<>();
private static final Map<String, List<PositionedStack>> recipeCatalystMap = new HashMap<>();
private static final List<String> forceClassNameList = new ArrayList<>();
private static int heightCache;
public static void addRecipeCatalyst(String handlerID, CatalystInfo catalystInfo) {
if (handlerID == null || handlerID.isEmpty() || catalystInfo.getStack() == null) return;
@@ -49,6 +48,7 @@ public class RecipeCatalysts {
public static void removeRecipeCatalyst(String handlerID, ItemStack stack) {
if (handlerID == null || handlerID.isEmpty() || stack == null) return;
if (catalystsRemoverFromAPI.containsKey(handlerID)) {
catalystsRemoverFromAPI.get(handlerID).add(stack);
} else {
@@ -56,8 +56,23 @@ public class RecipeCatalysts {
}
}
public static Map<String, List<PositionedStack>> getPositionedRecipeCatalystMap() {
return positionedRecipeCatalystMap;
public static void putRecipeCatalysts(String handlerID, List<ItemStack> items) {
if (handlerID == null || handlerID.isEmpty()) return;
final CatalystInfoList catalystInfoList = new CatalystInfoList(handlerID);
int stackIndex = 0;
for (ItemStack stack : items) {
catalystInfoList.add(new CatalystInfo(stack, stackIndex++));
}
putRecipeCatalysts(handlerID, catalystInfoList);
}
public static void putRecipeCatalysts(String handlerID, CatalystInfoList catalystInfoList) {
if (handlerID == null || handlerID.isEmpty()) return;
catalystsAdderFromAPI.put(handlerID, catalystInfoList);
recipeCatalystMap.put(handlerID, convertToPositionedStackList(catalystInfoList));
}
public static List<PositionedStack> getRecipeCatalysts(IRecipeHandler handler) {
@@ -65,10 +80,7 @@ public class RecipeCatalysts {
}
public static List<PositionedStack> getRecipeCatalysts(String handlerID) {
if (!NEIClientConfig.areJEIStyleTabsVisible() || !NEIClientConfig.areJEIStyleRecipeCatalystsVisible()) {
return Collections.emptyList();
}
return positionedRecipeCatalystMap.getOrDefault(handlerID, Collections.emptyList());
return recipeCatalystMap.getOrDefault(handlerID, Collections.emptyList());
}
public static boolean containsCatalyst(IRecipeHandler handler, ItemStack candidate) {
@@ -76,63 +88,21 @@ public class RecipeCatalysts {
}
public static boolean containsCatalyst(String handlerID, ItemStack candidate) {
if (recipeCatalystMap.containsKey(handlerID)) {
return recipeCatalystMap.get(handlerID).contains(candidate);
return recipeCatalystMap.get(handlerID).stream().anyMatch(pStack -> pStack.contains(candidate));
}
return false;
}
public static void updatePosition(int availableHeight, boolean force) {
if (availableHeight == heightCache && !force) return;
Map<String, List<PositionedStack>> newMap = new HashMap<>();
for (Map.Entry<String, CatalystInfoList> entry : recipeCatalystMap.entrySet()) {
CatalystInfoList catalysts = entry.getValue();
catalysts.sort();
List<PositionedStack> newStacks = new ArrayList<>();
int rowCount = getRowCount(availableHeight, catalysts.size());
for (int index = 0; index < catalysts.size(); index++) {
ItemStack catalyst = catalysts.get(index).getStack();
int column = index / rowCount;
int row = index % rowCount;
newStacks.add(
new PositionedStack(
catalyst,
-column * GuiRecipeCatalyst.ingredientSize,
row * GuiRecipeCatalyst.ingredientSize));
}
newMap.put(entry.getKey(), newStacks);
}
positionedRecipeCatalystMap = newMap;
heightCache = availableHeight;
}
public static void updatePosition(int availableHeight) {
updatePosition(availableHeight, false);
}
public static int getHeight() {
return heightCache;
}
public static int getColumnCount(int availableHeight, int catalystsSize) {
int maxItemsPerColumn = availableHeight / GuiRecipeCatalyst.ingredientSize;
return NEIServerUtils.divideCeil(catalystsSize, maxItemsPerColumn);
}
public static int getRowCount(int availableHeight, int catalystsSize) {
int columnCount = getColumnCount(availableHeight, catalystsSize);
return NEIServerUtils.divideCeil(catalystsSize, columnCount);
}
public static void loadCatalystInfo() {
final boolean fromJar = NEIClientConfig.loadCatalystsFromJar();
final URL handlerUrl = RecipeCatalysts.class.getResource("/assets/nei/csv/catalysts.csv");
final Map<String, CatalystInfoList> calculatedCatalysts = new HashMap<>();
NEIClientConfig.logger.info("Loading catalyst info from " + (fromJar ? "JAR" : "Config"));
recipeCatalystMap.clear();
URL handlerUrl = RecipeCatalysts.class.getResource("/assets/nei/csv/catalysts.csv");
resolveAdderQueue();
resolveAdderQueue(calculatedCatalysts);
URL url;
if (fromJar) {
@@ -211,7 +181,7 @@ public class RecipeCatalysts {
// Prefer info added by API if we're using default jar config.
// If not, user config overwrites it.
addOrPut(recipeCatalystMap, handlerID, catalystInfo, !fromJar);
addOrPut(calculatedCatalysts, handlerID, catalystInfo, !fromJar);
}
} catch (Exception e) {
NEIClientConfig.logger.warn("Error parsing CSV");
@@ -219,13 +189,17 @@ public class RecipeCatalysts {
}
if (fromJar) {
resolveRemoverQueue();
resolveRemoverQueue(calculatedCatalysts);
}
recipeCatalystMap.clear();
for (Map.Entry<String, CatalystInfoList> entry : calculatedCatalysts.entrySet()) {
recipeCatalystMap.put(entry.getKey(), convertToPositionedStackList(entry.getValue()));
}
updatePosition(getHeight(), true);
}
private static void resolveAdderQueue() {
private static void resolveAdderQueue(Map<String, CatalystInfoList> recipeCatalystMap) {
for (Map.Entry<String, CatalystInfoList> entry : catalystsAdderFromAPI.entrySet()) {
String handlerID = entry.getKey();
for (CatalystInfo catalyst : entry.getValue()) {
@@ -256,7 +230,7 @@ public class RecipeCatalysts {
}
}
private static void resolveRemoverQueue() {
private static void resolveRemoverQueue(Map<String, CatalystInfoList> recipeCatalystMap) {
for (Map.Entry<String, List<ItemStack>> entry : catalystsRemoverFromAPI.entrySet()) {
String handlerID = entry.getKey();
if (recipeCatalystMap.containsKey(handlerID)) {
@@ -308,16 +282,49 @@ public class RecipeCatalysts {
}
}
private static List<PositionedStack> convertToPositionedStackList(CatalystInfoList catalystInfoList) {
catalystInfoList.sort();
return catalystInfoList.stream().filter(catalyst -> catalyst.getStack() != null)
.map(catalyst -> new PositionedStack(catalyst.getStack(), 0, 0, false)).collect(Collectors.toList());
}
@Deprecated
public static void addRecipeCatalyst(List<ItemStack> stacks, Class<? extends IRecipeHandler> handler) {}
@Deprecated
public static List<PositionedStack> getRecipeCatalysts(Class<? extends IRecipeHandler> handler) {
return Collections.emptyList();
return new ArrayList<>();
}
@Deprecated
public static boolean containsCatalyst(Class<? extends IRecipeHandler> handler, ItemStack candidate) {
return false;
}
@Deprecated
public static Map<String, List<PositionedStack>> getPositionedRecipeCatalystMap() {
return new HashMap<>();
}
@Deprecated
public static void updatePosition(int availableHeight, boolean force) {}
@Deprecated
public static void updatePosition(int availableHeight) {}
@Deprecated
public static int getHeight() {
return 1;
}
@Deprecated
public static int getColumnCount(int availableHeight, int catalystsSize) {
return 1;
}
@Deprecated
public static int getRowCount(int availableHeight, int catalystsSize) {
return 1;
}
}
@@ -61,6 +61,10 @@ public class RecipeHandlerRef {
return firstGui != null && firstGui.inventorySlots != null ? firstGui : null;
}
public NEIRecipeWidget getRecipeWidget() {
return new NEIRecipeWidget(this);
}
public IOverlayHandler getOverlayHandler(GuiContainer gui) {
final GuiContainer firstGui = prepareGui(gui);
@@ -37,23 +37,16 @@ public class RecipeItemInputHandler implements IContainerInputHandler, IContaine
@Override
public boolean mouseClicked(GuiContainer gui, int mousex, int mousey, int button) {
if (!(gui instanceof GuiRecipe) || ItemPanels.itemPanel.contains(mousex, mousey)
|| ItemPanels.bookmarkPanel.contains(mousex, mousey)
|| ItemPanels.itemPanel.historyPanel.contains(mousex, mousey))
return false;
return ShortcutInputHandler.handleMouseClick(GuiContainerManager.getStackMouseOver(gui));
return false;
}
@Override
public Map<String, String> handleHotkeys(GuiContainer gui, int mousex, int mousey, Map<String, String> hotkeys) {
if ((gui instanceof GuiRecipe) || ItemPanels.itemPanel.contains(mousex, mousey)
|| ItemPanels.bookmarkPanel.contains(mousex, mousey)
|| ItemPanels.itemPanel.historyPanel.contains(mousex, mousey)) {
if (gui instanceof GuiRecipe || ItemPanels.itemPanel.containsWithSubpanels(mousex, mousey)
|| ItemPanels.bookmarkPanel.contains(mousex, mousey)) {
hotkeys.putAll(
ShortcutInputHandler
.handleHotkeys(gui, mousex, mousey, GuiContainerManager.getStackMouseOver(gui)));
ShortcutInputHandler.handleHotkeys(mousex, mousey, GuiContainerManager.getStackMouseOver(gui)));
}
return hotkeys;
@@ -10,14 +10,29 @@ import net.minecraft.item.ItemStack;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import codechicken.lib.gui.GuiDraw;
import codechicken.lib.gui.GuiDraw.ITooltipLineHandler;
import codechicken.nei.drawable.DrawableBuilder;
import codechicken.nei.drawable.DrawableResource;
import codechicken.nei.guihook.GuiContainerManager;
import codechicken.nei.recipe.Recipe.RecipeId;
import codechicken.nei.scroll.GuiHelper;
public class RecipeTooltipLineHandler implements ITooltipLineHandler {
private static final int BG_PADDING = 5;
private static final DrawableResource BG_TEXTURE = new DrawableBuilder(
"nei:textures/gui/recipebg.png",
0,
0,
176,
166).build();
protected long lastUpdate = System.currentTimeMillis();
protected String recipeName = "";
protected GuiRecipe<?> gui = null;
protected RecipeHandlerRef handlerRef = null;
protected NEIRecipeWidget widget = null;
protected RecipeId recipeId = null;
protected boolean createdGui = false;
@@ -36,19 +51,22 @@ public class RecipeTooltipLineHandler implements ITooltipLineHandler {
@Override
public Dimension getSize() {
if (this.gui == null && !this.createdGui) {
this.gui = GuiCraftingRecipe.createRecipeGui("recipeId", false, this.recipeId.getResult(), this.recipeId);
if (this.widget == null && !this.createdGui) {
this.handlerRef = RecipeHandlerRef.of(this.recipeId);
this.createdGui = true;
if (this.gui != null) {
this.gui.initGui();
this.gui.guiTop = 0;
this.gui.guiLeft = 0;
if (handlerRef != null) {
this.widget = new NEIRecipeWidget(this.handlerRef);
this.widget.showAsWidget(true);
this.widget.x = BG_PADDING;
this.widget.y = BG_PADDING + 12;
this.recipeName = this.widget.getRecipeHandlerRef().handler.getRecipeName().trim();
}
}
if (this.gui != null) {
return this.gui.getWidgetSize();
if (this.widget != null) {
return new Dimension(this.widget.w + BG_PADDING * 2, this.widget.h + BG_PADDING * 2 + 12);
}
return new Dimension(0, 0);
@@ -56,41 +74,47 @@ public class RecipeTooltipLineHandler implements ITooltipLineHandler {
@Override
public void draw(int x, int y) {
if (this.gui == null) return;
if (this.widget == null) return;
if ((System.currentTimeMillis() - lastUpdate) > 50) {
lastUpdate = System.currentTimeMillis();
this.gui.onUpdate();
this.handlerRef.handler.onUpdate();
this.widget.update();
}
GL11.glPushMatrix();
final Dimension size = getSize();
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
GL11.glTranslatef(x, y, 0);
GL11.glScaled(1, 1, 3);
GL11.glTranslatef(x, y, 0);
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
GL11.glPushAttrib(GL11.GL_ENABLE_BIT | GL11.GL_COLOR_BUFFER_BIT);
RenderHelper.disableStandardItemLighting();
this.gui.drawGuiContainerBackgroundLayer(0.0f, -100, -100);
GuiContainerManager.enable2DRender();
GL11.glColor4f(1, 1, 1, 1);
GL11.glPopAttrib();
BG_TEXTURE.draw(0, 0, size.width, size.height, BG_PADDING, BG_PADDING, BG_PADDING, BG_PADDING);
if (this.gui.slotcontainer != null) {
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
GL11.glPushAttrib(GL11.GL_ENABLE_BIT | GL11.GL_COLOR_BUFFER_BIT);
RenderHelper.enableGUIStandardItemLighting();
GL11.glEnable(GL12.GL_RESCALE_NORMAL);
GL11.glDisable(GL11.GL_DEPTH_TEST);
List<Slot> slots = this.gui.slotcontainer.inventorySlots;
for (Slot slot : slots) {
if (slot != null && slot.getStack() != null) {
GuiContainerManager.drawItem(slot.xDisplayPosition, slot.yDisplayPosition, slot.getStack());
}
}
GuiDraw.drawRect(BG_PADDING, BG_PADDING, size.width - BG_PADDING * 2, 12, 0x30000000);
GuiDraw.drawStringC(this.recipeName, this.widget.w / 2, BG_PADDING + 2, 0xffffff);
GuiHelper.useScissor(
this.widget.x,
this.widget.y,
this.widget.w,
this.widget.h,
() -> { this.widget.draw(0, 0); });
GL11.glPopAttrib();
}
this.gui.drawGuiContainerForegroundLayer(-100, -100);
GL11.glPopMatrix();
}
}
@@ -1,6 +1,7 @@
package codechicken.nei.recipe;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.function.IntPredicate;
@@ -23,16 +24,16 @@ class SearchRecipeHandler<H extends IRecipeHandler> {
this.original = handler;
if (this.original.numRecipes() == 0) {
this.filteredRecipes = new ArrayList<>();
this.filteredRecipes = Collections.emptyList();
} else {
final Stream<Integer> items = IntStream.range(0, this.original.numRecipes()).boxed();
final IRecipeFilter filter = this.searchingAvailable() ? GuiRecipe.getRecipeListFilter() : null;
if (filter == null) {
this.filteredRecipes = items.collect(Collectors.toCollection(ArrayList::new));
this.filteredRecipes = items.collect(Collectors.toList());
} else {
this.filteredRecipes = items.filter(recipe -> mathRecipe(this.original, recipe, filter))
.collect(Collectors.toCollection(ArrayList::new));
.collect(Collectors.toList());
}
}
}
@@ -660,11 +660,6 @@ public abstract class TemplateRecipeHandler implements ICraftingHandler, IUsageH
return RecipeInfo.getOverlayHandler(gui, getOverlayIdentifier());
}
@Override
public int recipiesPerPage() {
return 2;
}
@Override
public List<String> handleTooltip(GuiRecipe<?> gui, List<String> currenttip, int recipe) {
if (GuiContainerManager.shouldShowTooltip(gui) && currenttip.isEmpty()) {
@@ -170,13 +170,13 @@ public class RecipeChainTooltipLineHandler implements ITooltipLineHandler {
inputs.sort(
Comparator.comparing((ItemStack stack) -> StackInfo.getFluid(stack) != null)
.thenComparing(ItemSorter.instance));
.thenComparingInt(stack -> -1 * stack.stackSize).thenComparing(ItemSorter.instance));
outputs.sort(
Comparator.comparing((ItemStack stack) -> StackInfo.getFluid(stack) != null)
.thenComparing(ItemSorter.instance));
.thenComparingInt(stack -> -1 * stack.stackSize).thenComparing(ItemSorter.instance));
remainder.sort(
Comparator.comparing((ItemStack stack) -> StackInfo.getFluid(stack) != null)
.thenComparing(ItemSorter.instance));
.thenComparingInt(stack -> -1 * stack.stackSize).thenComparing(ItemSorter.instance));
this.inputs = new ItemsTooltipLineHandler(
this.lastShiftKey ? NEIClientUtils.translate("bookmark.crafting_chain.missing")
@@ -0,0 +1,131 @@
package codechicken.nei.scroll;
import java.nio.FloatBuffer;
import java.util.Stack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.ScaledResolution;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class GuiHelper {
private static final Stack<int[]> scissorFrameStack = new Stack<>();
public static void useScissor(int x, int y, int width, int height, Runnable codeBlock) {
pushScissorFrame(x, y, width, height);
try {
codeBlock.run();
} finally {
popScissorFrame();
}
}
private static int[] peekFirstScissorOrFullScreen() {
final int[] currentTopFrame = scissorFrameStack.isEmpty() ? null : scissorFrameStack.peek();
if (currentTopFrame == null) {
final Minecraft minecraft = Minecraft.getMinecraft();
return new int[] { 0, 0, minecraft.displayWidth, minecraft.displayHeight };
}
return currentTopFrame;
}
private static void pushScissorFrame(int x, int y, int width, int height) {
int[] matrix = prepareMatrix(x, y, width, height);
int[] parentScissor = peekFirstScissorOrFullScreen();
int parentX = parentScissor[0];
int parentY = parentScissor[1];
int parentWidth = parentScissor[2];
int parentHeight = parentScissor[3];
boolean pushedFrame = false;
x = matrix[0];
y = matrix[1];
width = matrix[2];
height = matrix[3];
if (x <= parentX + parentWidth && y <= parentY + parentHeight) {
int newX = Math.max(x, parentX);
int newY = Math.max(y, parentY);
int newWidth = width - (newX - x);
int newHeight = height - (newY - y);
if (newWidth > 0 && newHeight > 0) {
int maxWidth = parentWidth - (x - parentX);
int maxHeight = parentHeight - (y - parentY);
newWidth = Math.min(maxWidth, newWidth);
newHeight = Math.min(maxHeight, newHeight);
applyScissor(newX, newY, newWidth, newHeight);
// finally, push applied scissor on top of scissor stack
if (scissorFrameStack.isEmpty()) {
GL11.glEnable(GL11.GL_SCISSOR_TEST);
}
scissorFrameStack.push(new int[] { newX, newY, newWidth, newHeight });
pushedFrame = true;
}
}
if (!pushedFrame) {
if (scissorFrameStack.isEmpty()) {
GL11.glEnable(GL11.GL_SCISSOR_TEST);
}
scissorFrameStack.push(new int[] { parentX, parentY, parentWidth, parentHeight });
}
}
public static void popScissorFrame() {
scissorFrameStack.pop();
int[] parentScissor = peekFirstScissorOrFullScreen();
int parentX = parentScissor[0];
int parentY = parentScissor[1];
int parentWidth = parentScissor[2];
int parentHeight = parentScissor[3];
applyScissor(parentX, parentY, parentWidth, parentHeight);
if (scissorFrameStack.isEmpty()) {
GL11.glDisable(GL11.GL_SCISSOR_TEST);
}
}
// applies scissor with gui-space coordinates and sizes
private static void applyScissor(int x, int y, int w, int h) {
// translate upper-left to bottom-left
final Minecraft mc = Minecraft.getMinecraft();
final ScaledResolution res = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight);
final int scaleFactor = res.getScaleFactor();
final int translatedY = mc.displayHeight - (y + h) * scaleFactor;
GL11.glScissor(x * scaleFactor, translatedY, w * scaleFactor, h * scaleFactor);
}
private static int[] prepareMatrix(int x, int y, int w, int h) {
// Get the current translation component to support the Gui being drawn at any position on the screen
final FloatBuffer matBuf = BufferUtils.createFloatBuffer(16);
GL11.glGetFloat(GL11.GL_MODELVIEW_MATRIX, matBuf);
final float xScale = matBuf.get(0);
final float yScale = matBuf.get(5);
final int xTranslate = (int) (matBuf.get(12) / xScale);
final int yTranslate = (int) (matBuf.get(13) / yScale);
x += xTranslate;
y += yTranslate;
x *= xScale;
y *= yScale;
w *= xScale;
h *= yScale;
return new int[] { x, y, w, h };
}
}
@@ -0,0 +1,398 @@
package codechicken.nei.scroll;
import java.awt.Color;
import org.lwjgl.opengl.GL11;
import codechicken.lib.vec.Rectangle4i;
import codechicken.nei.NEIClientUtils;
import codechicken.nei.drawable.DrawableBuilder;
import codechicken.nei.drawable.DrawableResource;
public class ScrollBar {
/** The minimum length of the scrollbar cursor. */
private static final int MINIMUM_THUMB_SIZE = 6;
private static final Color BACKGROUND_COLOR = new Color(0x90B1D4E0);
private static final Color THUMB_COLOR = new Color(0xF0145DA0);
private static final Color THUMB_SELECTED_COLOR = new Color(0xF02E8BC0);
public enum ScrollType {
HORIZONTAL,
VERTICAL
}
public enum OverflowType {
NONE,
AUTO,
SCROLL,
OVERLAY
}
public enum ScrollPlace {
INSIDE,
OUTSIDE
}
private ScrollType scrollType = ScrollType.VERTICAL;
private OverflowType overflowType = OverflowType.SCROLL;
private ScrollPlace scrollPlace = ScrollPlace.INSIDE;
private float handleClickOffset = -1;
private int scrollbarSize = 6;
private int thumbPadding = 0;
private int margin = 0;
private DrawableResource thumbTexture;
private int thumbSliceStart;
private int thumbSliceEnd;
private DrawableResource trackTexture;
private int trackSliceStart;
private int trackSliceEnd;
public static ScrollBar defaultScrollBar() {
return new ScrollBar();
}
public static ScrollBar defaultVerticalBar() {
return new ScrollBar().setScrollbarSize(8)
.setTrackTexture(new DrawableBuilder("nei:textures/nei_sprites.png", 29, 95, 12, 11).build(), 3, 4)
.setThumbTexture(new DrawableBuilder("nei:textures/nei_sprites.png", 21, 96, 8, 9).build(), 3, 2)
.setThumbPadding(1);
}
public static ScrollBar defaultHorizontalBar() {
return new ScrollBar().setScrollbarSize(8).setOverflowType(OverflowType.SCROLL)
.setScrollPlace(ScrollPlace.INSIDE)
.setTrackTexture(new DrawableBuilder("nei:textures/nei_sprites.png", 0, 97, 11, 8).build(), 3, 4)
.setThumbTexture(new DrawableBuilder("nei:textures/nei_sprites.png", 12, 97, 9, 7).build(), 3, 2)
.setThumbPadding(1);
}
public ScrollBar setScrollbarSize(int scrollbarSize) {
this.scrollbarSize = scrollbarSize;
return this;
}
public ScrollBar setThumbPadding(int thumbPadding) {
this.thumbPadding = thumbPadding;
return this;
}
public ScrollBar setMargin(int margin) {
this.margin = margin;
return this;
}
public int getMargin() {
return this.margin;
}
public int getScrollbarSize() {
return this.scrollbarSize;
}
public ScrollBar setThumbTexture(DrawableResource texture, int sliceStart, int sliceEnd) {
this.thumbTexture = texture;
this.thumbSliceStart = sliceStart;
this.thumbSliceEnd = sliceEnd;
return this;
}
public ScrollBar setTrackTexture(DrawableResource texture, int sliceStart, int sliceEnd) {
this.trackTexture = texture;
this.trackSliceStart = sliceStart;
this.trackSliceEnd = sliceEnd;
return this;
}
public ScrollBar setOverflowType(OverflowType overflowType) {
this.overflowType = overflowType;
return this;
}
public OverflowType getOverflowType() {
return this.overflowType;
}
public ScrollBar setScrollPlace(ScrollPlace scrollPlace) {
this.scrollPlace = scrollPlace;
return this;
}
public ScrollPlace getScrollPlace() {
return this.scrollPlace;
}
public ScrollBar setScrollType(ScrollType scrollType) {
this.scrollType = scrollType;
return this;
}
private int getActualSize(ScrollContainer container) {
if (this.scrollType == ScrollType.HORIZONTAL) {
return container.getActualWidth();
} else {
return container.getActualHeight();
}
}
public int getVisibleSize(ScrollContainer container) {
if (this.scrollType == ScrollType.HORIZONTAL) {
return container.getVisibleWidth();
} else {
return container.getVisibleHeight();
}
}
private int getMaxThumbSize(ScrollContainer container) {
return getMaxTrackSize(container) - this.thumbPadding * 2;
}
private int getMaxTrackSize(ScrollContainer container) {
if (this.scrollType == ScrollType.HORIZONTAL) {
int visibleSize = container.w;
if (container.canScrollVertical() && container.getVerticalScroll().getScrollPlace() == ScrollPlace.INSIDE) {
visibleSize -= container.getVerticalScroll().getScrollbarSize();
}
return visibleSize;
} else {
int visibleSize = container.h;
if (container.canScrollHorizontal()
&& container.getHorizontalScroll().getScrollPlace() == ScrollPlace.INSIDE) {
visibleSize -= container.getHorizontalScroll().getScrollbarSize();
}
return visibleSize;
}
}
private int getMinThumbSize() {
if (this.thumbTexture != null) {
return this.scrollType == ScrollType.HORIZONTAL ? this.thumbTexture.getWidth()
: this.thumbTexture.getHeight();
}
return MINIMUM_THUMB_SIZE;
}
public float getScrollOffset(ScrollContainer container) {
final float thumbSize = getMaxThumbSize(container) - calculateMainAxisSize(container);
if (this.scrollType == ScrollType.HORIZONTAL) {
return container.getHorizontalScrollOffset()
/ (float) (container.getActualWidth() - container.getVisibleWidth())
* thumbSize;
} else {
return container.getVerticalScrollOffset()
/ (float) (container.getActualHeight() - container.getVisibleHeight())
* thumbSize;
}
}
public float calculateMainAxisSize(ScrollContainer container) {
final int visibleSize = getVisibleSize(container);
final int actualSize = getActualSize(container);
final int trackSize = getMaxThumbSize(container);
return Math.max(Math.min(trackSize, (trackSize / (float) actualSize) * visibleSize), getMinThumbSize());
}
public Rectangle4i trackBounds(ScrollContainer container) {
if (this.scrollType == ScrollType.HORIZONTAL) {
return new Rectangle4i(
container.x,
container.y + container.h
+ this.margin
- (this.scrollPlace == ScrollPlace.INSIDE ? scrollbarSize : 0),
getMaxTrackSize(container),
scrollbarSize);
} else {
return new Rectangle4i(
container.x + container.w
+ this.margin
- (this.scrollPlace == ScrollPlace.INSIDE ? scrollbarSize : 0),
container.y,
scrollbarSize,
getMaxTrackSize(container));
}
}
public Rectangle4i thumbBounds(ScrollContainer container) {
final int mainAxisSize = (int) calculateMainAxisSize(container);
final int offset = (int) Math.ceil(getScrollOffset(container));
final Rectangle4i bounds = trackBounds(container);
if (this.scrollType == ScrollType.HORIZONTAL) {
return new Rectangle4i(bounds.x + this.thumbPadding + offset, bounds.y, mainAxisSize, bounds.h);
} else {
return new Rectangle4i(bounds.x, bounds.y + this.thumbPadding + offset, bounds.w, mainAxisSize);
}
}
public boolean setScrollOffset(ScrollContainer container, int offset) {
if (this.scrollType == ScrollType.HORIZONTAL) {
return container.setHorizontalScrollOffset(offset);
} else {
return container.setVerticalScrollOffset(offset);
}
}
public boolean onClick(ScrollContainer container, int mx, int my, int button) {
final Rectangle4i bounds = trackBounds(container);
if (bounds.contains(mx, my)) {
final float mainAxisSize = calculateMainAxisSize(container);
final float thumbSize = getMaxThumbSize(container) - mainAxisSize;
final Rectangle4i thumbBounds = thumbBounds(container);
if (this.scrollType == ScrollType.HORIZONTAL) {
final int relativeX = mx - bounds.x - this.thumbPadding;
if (mx < thumbBounds.x || mx > thumbBounds.x + thumbBounds.w) {
this.handleClickOffset = mainAxisSize / 2;
} else {
this.handleClickOffset = mx - thumbBounds.x;
}
final float newOffset = ((relativeX - this.handleClickOffset)
* (container.getActualWidth() - container.getVisibleWidth())) / thumbSize;
container.setHorizontalScrollOffset((int) newOffset);
} else {
final int relativeY = my - bounds.y - this.thumbPadding;
if (my < thumbBounds.y || my > thumbBounds.y + thumbBounds.h) {
this.handleClickOffset = mainAxisSize / 2f;
} else {
this.handleClickOffset = my - thumbBounds.y;
}
final float newOffset = ((relativeY - this.handleClickOffset)
* (container.getActualHeight() - container.getVisibleHeight())) / thumbSize;
container.setVerticalScrollOffset((int) newOffset);
}
return true;
}
return false;
}
public boolean onMouseDragged(ScrollContainer container, int mx, int my, int buttonId, long heldTime) {
if (this.handleClickOffset >= 0) {
final Rectangle4i bounds = trackBounds(container);
final float mainAxisSize = calculateMainAxisSize(container);
final float thumbSize = getMaxThumbSize(container) - mainAxisSize;
if (this.scrollType == ScrollType.HORIZONTAL) {
final int relativeX = mx - bounds.x - this.thumbPadding;
final float newOffset = ((relativeX - this.handleClickOffset)
* (container.getActualWidth() - container.getVisibleWidth())) / thumbSize;
container.setHorizontalScrollOffset((int) newOffset);
} else {
int relativeY = my - bounds.y - this.thumbPadding;
final float newOffset = ((relativeY - this.handleClickOffset)
* (container.getActualHeight() - container.getVisibleHeight())) / thumbSize;
container.setVerticalScrollOffset((int) newOffset);
}
return true;
}
return false;
}
public boolean onClickReleased(ScrollContainer container, int mx, int my, int buttonId) {
if (this.handleClickOffset >= 0) {
this.handleClickOffset = -1;
return true;
}
return false;
}
public boolean isMouseDragged() {
return this.handleClickOffset >= 0;
}
public void draw(ScrollContainer container, int mx, int my, float opacity) {
if (opacity <= 0 && this.overflowType == OverflowType.OVERLAY) {
return;
}
if (this.overflowType != OverflowType.OVERLAY) {
opacity = 1;
}
final Rectangle4i trackBounds = trackBounds(container);
final Rectangle4i thumbBounds = thumbBounds(container);
final boolean selected = isMouseDragged() || thumbBounds.contains(mx, my);
final boolean disabled = getVisibleSize(container) >= getActualSize(container);
if (this.trackTexture != null) {
drawTexture(this.trackTexture, this.trackSliceStart, this.trackSliceEnd, trackBounds, false, opacity);
} else {
drawTrackRect(container, trackBounds, opacity);
}
if (this.thumbTexture != null) {
drawTexture(this.thumbTexture, this.thumbSliceStart, this.thumbSliceEnd, thumbBounds, disabled, opacity);
} else {
drawThumbRect(container, thumbBounds, selected, opacity);
}
}
private void drawTrackRect(ScrollContainer container, Rectangle4i bounds, float opacity) {
final float trackSize = scrollbarSize / 3f;
final Color trackColor = new Color(
BACKGROUND_COLOR.getRed(),
BACKGROUND_COLOR.getGreen(),
BACKGROUND_COLOR.getBlue(),
(int) (BACKGROUND_COLOR.getAlpha() * opacity));
if (this.scrollType == ScrollType.HORIZONTAL) {
NEIClientUtils.drawRect(bounds.x, bounds.y + trackSize, bounds.w, trackSize, trackColor);
} else {
NEIClientUtils.drawRect(bounds.x + trackSize, bounds.y, trackSize, bounds.h, trackColor);
}
}
private void drawThumbRect(ScrollContainer container, Rectangle4i bounds, boolean selected, float opacity) {
final Color color = selected ? THUMB_SELECTED_COLOR : THUMB_COLOR;
final Color thumbColor = new Color(
color.getRed(),
color.getGreen(),
color.getBlue(),
(int) (color.getAlpha() * opacity));
NEIClientUtils.drawRect(bounds.x, bounds.y, bounds.w, bounds.h, thumbColor);
}
private void drawTexture(DrawableResource texture, int sliceStart, int sliceEnd, Rectangle4i bounds,
boolean disabled, float opacity) {
final float c = disabled ? 0.65f : 1f;
GL11.glColor4f(c, c, c, opacity);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
if (this.scrollType == ScrollType.HORIZONTAL) {
texture.draw(bounds.x, bounds.y, bounds.w, texture.getHeight(), sliceStart, sliceEnd, 0, 0);
} else {
texture.draw(bounds.x, bounds.y, texture.getWidth(), bounds.h, 0, 0, sliceStart, sliceEnd);
}
}
}
@@ -0,0 +1,418 @@
package codechicken.nei.scroll;
import java.awt.Point;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Predicate;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.GL11;
import codechicken.lib.gui.GuiDraw;
import codechicken.lib.vec.Rectangle4i;
import codechicken.nei.NEIClientUtils;
import codechicken.nei.Widget;
import codechicken.nei.WidgetContainer;
import codechicken.nei.scroll.ScrollBar.OverflowType;
import codechicken.nei.scroll.ScrollBar.ScrollPlace;
import codechicken.nei.scroll.ScrollBar.ScrollType;
public class ScrollContainer extends WidgetContainer {
/** The mouse scroll wheel scroll speed */
protected static final int MOUSE_SCROLL_SPEED = 16;
/** The keyboard arrow keys scroll speed */
protected static final int KEYBOARD_SCROLL_SPEED = 36;
/** The scrollbar will fade away over this many ticks */
protected static final int FADE_TICKS = 24;
protected int xScroll = 0;
protected int yScroll = 0;
protected int actualWidth = 0;
protected int actualHeight = 0;
protected int marginInline = 0;
protected int marginBlock = 0;
protected final Map<Widget, Point> relativePostion = new HashMap<>();
protected ScrollBar horizontalScrollBar;
protected ScrollBar verticalScrollBar;
protected int fade = 0;
public Rectangle4i boundsOutside() {
int width = this.w;
int height = this.h;
if (canScrollVertical() && (this.verticalScrollBar.getOverflowType() == OverflowType.SCROLL
|| this.verticalScrollBar.getOverflowType() == OverflowType.AUTO)) {
width += this.verticalScrollBar.getMargin();
if (this.verticalScrollBar.getScrollPlace() == ScrollPlace.OUTSIDE) {
width += this.verticalScrollBar.getScrollbarSize();
}
}
if (canScrollHorizontal() && (this.horizontalScrollBar.getOverflowType() == OverflowType.SCROLL
|| this.horizontalScrollBar.getOverflowType() == OverflowType.AUTO)) {
height += this.horizontalScrollBar.getMargin();
if (this.horizontalScrollBar.getScrollPlace() == ScrollPlace.OUTSIDE) {
height += this.horizontalScrollBar.getScrollbarSize();
}
}
return new Rectangle4i(x, y, width, height);
}
public Rectangle4i boundsInside() {
return new Rectangle4i(x, y, getVisibleWidth(), getVisibleHeight());
}
@Override
public void clear() {
super.clear();
this.relativePostion.clear();
}
@Override
public boolean removeIf(Predicate<Widget> filter) {
this.relativePostion.keySet().removeIf(filter);
return super.removeIf(filter);
}
public void addWidget(Widget widget) {
super.addWidget(widget);
this.relativePostion.put(widget, new Point(widget.x, widget.y));
}
public Point getWidgetPosition(Widget widget) {
return this.relativePostion.get(widget);
}
public void setMarginInline(int marginInline) {
this.marginInline = marginInline;
}
public void setMarginBlock(int marginBlock) {
this.marginBlock = marginBlock;
}
public int getMarginInline() {
return this.marginInline;
}
public int getMarginBlock() {
return this.marginBlock;
}
public int getVisibleWidth() {
if (canScrollVertical() && this.verticalScrollBar.getScrollPlace() == ScrollPlace.INSIDE
&& (this.verticalScrollBar.getOverflowType() == OverflowType.SCROLL
|| this.verticalScrollBar.getOverflowType() == OverflowType.AUTO)) {
return this.w - this.verticalScrollBar.getScrollbarSize();
}
return this.w;
}
public int getActualWidth() {
return this.actualWidth;
}
public boolean setHorizontalScrollOffset(int offset) {
if (!canScrollHorizontal() && this.w < getActualWidth()) {
offset = 0;
}
final int scroll = this.xScroll;
this.xScroll = Math.max(0, Math.min(getActualWidth() - getVisibleWidth(), offset));
if (scroll != this.xScroll) {
for (Widget widget : this.widgets) {
widget.x += scroll - this.xScroll;
}
this.fade = FADE_TICKS;
return true;
}
return false;
}
public int getHorizontalScrollOffset() {
return this.xScroll;
}
public boolean canScrollHorizontal() {
return this.horizontalScrollBar != null
&& (this.horizontalScrollBar.getOverflowType() != OverflowType.NONE && this.w < getActualWidth()
|| this.horizontalScrollBar.getOverflowType() == OverflowType.SCROLL);
}
public ScrollBar getHorizontalScroll() {
return this.horizontalScrollBar;
}
public ScrollContainer setHorizontalScroll() {
return setHorizontalScroll(ScrollBar.defaultScrollBar());
}
public ScrollContainer setHorizontalScroll(ScrollBar scrollBar) {
this.horizontalScrollBar = scrollBar;
if (this.horizontalScrollBar != null) {
this.horizontalScrollBar.setScrollType(ScrollType.HORIZONTAL);
}
return this;
}
public int getVisibleHeight() {
if (canScrollHorizontal() && this.horizontalScrollBar.getScrollPlace() == ScrollPlace.INSIDE
&& (this.horizontalScrollBar.getOverflowType() == OverflowType.SCROLL
|| this.horizontalScrollBar.getOverflowType() == OverflowType.AUTO)) {
return this.h - this.horizontalScrollBar.getScrollbarSize();
}
return this.h;
}
public int getActualHeight() {
return this.actualHeight;
}
public boolean setVerticalScrollOffset(int offset) {
if (!canScrollVertical() && this.h < getActualHeight()) {
offset = 0;
}
final int scroll = this.yScroll;
this.yScroll = Math.max(0, Math.min(getActualHeight() - getVisibleHeight(), offset));
if (scroll != this.yScroll) {
for (Widget widget : this.widgets) {
widget.y += scroll - this.yScroll;
}
this.fade = FADE_TICKS;
return true;
}
return false;
}
public int getVerticalScrollOffset() {
return this.yScroll;
}
public boolean canScrollVertical() {
return this.verticalScrollBar != null
&& (this.verticalScrollBar.getOverflowType() != OverflowType.NONE && this.h < getActualHeight()
|| this.verticalScrollBar.getOverflowType() == OverflowType.SCROLL);
}
public ScrollBar getVerticalScroll() {
return this.verticalScrollBar;
}
public ScrollContainer setVerticalScroll() {
return setVerticalScroll(ScrollBar.defaultScrollBar());
}
public ScrollContainer setVerticalScroll(ScrollBar scrollBar) {
this.verticalScrollBar = scrollBar;
if (this.verticalScrollBar != null) {
this.verticalScrollBar.setScrollType(ScrollType.VERTICAL);
}
return this;
}
@Override
public void draw(int mousex, int mousey) {
final boolean canScrollVertical = canScrollVertical();
final boolean canScrollHorizontal = canScrollHorizontal();
if (canScrollVertical || canScrollHorizontal) {
GuiHelper.useScissor(
this.x,
this.y,
getVisibleWidth(),
getVisibleHeight(),
() -> drawContent(mousex, mousey));
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
if (canScrollVertical) {
this.verticalScrollBar.draw(this, mousex, mousey, getScrollBarOpacity());
}
if (canScrollHorizontal) {
this.horizontalScrollBar.draw(this, mousex, mousey, getScrollBarOpacity());
}
GL11.glPopAttrib();
} else {
drawContent(mousex, mousey);
}
}
protected void drawContent(int mousex, int mousey) {
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
GL11.glPushMatrix();
GL11.glColor4f(1, 1, 1, 1);
super.draw(mousex, mousey);
GL11.glPopMatrix();
GL11.glPopAttrib();
}
private float getScrollBarOpacity() {
return Math.min(2f * this.fade, FADE_TICKS) / FADE_TICKS;
}
@Override
public void update() {
this.actualHeight = 0;
this.actualWidth = 0;
for (Map.Entry<Widget, Point> entry : this.relativePostion.entrySet()) {
entry.getKey().x = entry.getValue().x;
entry.getKey().y = entry.getValue().y;
}
super.update();
for (Widget widget : this.widgets) {
this.actualWidth = Math.max(this.actualWidth, widget.x + widget.w + this.marginInline * 2);
this.actualHeight = Math.max(this.actualHeight, widget.y + widget.h + this.marginBlock * 2);
widget.x += this.marginInline + this.x - this.xScroll;
widget.y += this.marginBlock + this.y - this.yScroll;
}
if (this.fade > 0) {
final Point mouse = GuiDraw.getMousePosition();
if (canScrollVertical() && (this.verticalScrollBar.isMouseDragged()
|| this.verticalScrollBar.trackBounds(this).contains(mouse.x, mouse.y))) {
this.fade = FADE_TICKS;
} else if (canScrollHorizontal() && (this.horizontalScrollBar.isMouseDragged()
|| this.horizontalScrollBar.trackBounds(this).contains(mouse.x, mouse.y))) {
this.fade = FADE_TICKS;
} else {
this.fade--;
}
}
setHorizontalScrollOffset(this.xScroll);
setVerticalScrollOffset(this.yScroll);
}
@Override
public boolean onMouseWheel(int direction, int mousex, int mousey) {
if (super.onMouseWheel(direction, mousex, mousey)) {
return true;
}
if (boundsOutside().contains(mousex, mousey)) {
if (canScrollHorizontal() && (NEIClientUtils.shiftKey()
|| this.horizontalScrollBar.trackBounds(this).contains(mousex, mousey))) {
this.horizontalScrollBar.setScrollOffset(this, this.xScroll - direction * MOUSE_SCROLL_SPEED);
return true;
}
if (canScrollVertical()) {
this.verticalScrollBar.setScrollOffset(this, this.yScroll - direction * MOUSE_SCROLL_SPEED);
return true;
}
}
return false;
}
@Override
public boolean handleClick(int mousex, int mousey, int button) {
if (canScrollVertical() && this.verticalScrollBar.onClick(this, mousex, mousey, button)) {
return true;
}
if (canScrollHorizontal() && this.horizontalScrollBar.onClick(this, mousex, mousey, button)) {
return true;
}
if (super.handleClick(mousex, mousey, button)) {
return true;
}
return false;
}
@Override
public void mouseDragged(int mousex, int mousey, int button, long heldTime) {
if (canScrollVertical() && this.verticalScrollBar.onMouseDragged(this, mousex, mousey, button, heldTime)) {
return;
}
if (canScrollHorizontal() && this.horizontalScrollBar.onMouseDragged(this, mousex, mousey, button, heldTime)) {
return;
}
super.mouseDragged(mousex, mousey, button, heldTime);
}
@Override
public void mouseUp(int mousex, int mousey, int button) {
if (canScrollVertical()) {
this.verticalScrollBar.onClickReleased(this, mousex, mousey, button);
}
if (canScrollHorizontal()) {
this.horizontalScrollBar.onClickReleased(this, mousex, mousey, button);
}
super.mouseUp(mousex, mousey, button);
}
@Override
public boolean handleKeyPress(int keyCode, char keyChar) {
if (this.isFocused()) {
switch (keyCode) {
case Keyboard.KEY_UP:
return canScrollVertical()
&& this.verticalScrollBar.setScrollOffset(this, this.yScroll - KEYBOARD_SCROLL_SPEED);
case Keyboard.KEY_DOWN:
return canScrollVertical()
&& this.verticalScrollBar.setScrollOffset(this, this.yScroll + KEYBOARD_SCROLL_SPEED);
case Keyboard.KEY_LEFT:
return canScrollHorizontal()
&& this.horizontalScrollBar.setScrollOffset(this, this.xScroll - KEYBOARD_SCROLL_SPEED);
case Keyboard.KEY_RIGHT:
return canScrollHorizontal()
&& this.horizontalScrollBar.setScrollOffset(this, this.xScroll + KEYBOARD_SCROLL_SPEED);
}
}
return super.handleKeyPress(keyCode, keyChar);
}
}
@@ -0,0 +1,63 @@
package codechicken.nei.util;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
public class SlotInaccessible extends Slot {
private ItemStack itemStack = null;
public SlotInaccessible(ItemStack itemStack, int xDisplayPosition, int yDisplayPosition) {
super(null, 0, xDisplayPosition, yDisplayPosition);
this.itemStack = itemStack;
}
@Override
public void onSlotChange(final ItemStack par1ItemStack, final ItemStack par2ItemStack) {}
@Override
public void onPickupFromSlot(final EntityPlayer par1EntityPlayer, final ItemStack par2ItemStack) {}
@Override
public boolean isItemValid(final ItemStack par1ItemStack) {
return false;
}
@Override
public ItemStack getStack() {
return this.itemStack;
}
@Override
public void putStack(final ItemStack par1ItemStack) {}
@Override
public void onSlotChanged() {}
@Override
public int getSlotStackLimit() {
return 0;
}
@Override
public ItemStack decrStackSize(final int par1) {
return null;
}
@Override
public boolean isSlotInInventory(final IInventory par1IInventory, final int par2) {
return false;
}
@Override
public boolean canTakeStack(final EntityPlayer par1EntityPlayer) {
return false;
}
@Override
public int getSlotIndex() {
return 0;
}
}
File diff suppressed because it is too large. Load diff
@@ -272,12 +272,19 @@ nei.options.inventory.guirecipe.itemPresenceOverlay.2=Background
nei.options.inventory.guirecipe.slotHighlightPresent=Highlight Present Item
nei.options.inventory.guirecipe.slotHighlightPresent.true=Yes
nei.options.inventory.guirecipe.slotHighlightPresent.false=No
nei.options.inventory.guirecipe.infiniteScroll=Use Infinite Scroll
nei.options.inventory.guirecipe.infiniteScroll.true=Yes
nei.options.inventory.guirecipe.infiniteScroll.false=No
nei.options.inventory.guirecipe.jeiStyleRecipeCatalyst=JEI Style Recipe Catalysts
nei.options.inventory.guirecipe.jeiStyleRecipeCatalyst.true=Yes
nei.options.inventory.guirecipe.jeiStyleRecipeCatalyst.false=No
nei.options.inventory.guirecipe.cycledIngredientsTooltip=Cycled Ingredients Tooltip
nei.options.inventory.guirecipe.cycledIngredientsTooltip.true=Show
nei.options.inventory.guirecipe.cycledIngredientsTooltip.false=Hide
nei.options.inventory.guirecipe.handlerInfo=Handler Info Widget
nei.options.inventory.guirecipe.handlerInfo.true=Enabled
nei.options.inventory.guirecipe.handlerInfo.false=Disabled
nei.options.inventory.guirecipe.maxHeight=Max Height
nei.options.inventory.showItemQuantityWidget=Show Item Quantity Widget
nei.options.inventory.showItemQuantityWidget.true=Yes
nei.options.inventory.showItemQuantityWidget.false=No
@@ -471,9 +478,6 @@ nei.options.tools.handler_load_from_config.false=JAR
nei.options.tools.catalyst_load_from_config=Load catalysts from Config
nei.options.tools.catalyst_load_from_config.true=Config
nei.options.tools.catalyst_load_from_config.false=JAR
nei.options.tools.handler_info=Handler Info Widget
nei.options.tools.handler_info.true=Enabled
nei.options.tools.handler_info.false=Disabled
nei.options.tools.dump=Data Dumps
nei.options.tools.dump.dump=Dump
nei.options.tools.dump.dumped=%s IDs dumped to %s
Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 33 KiB