From 523700d2877ef8166eca0a04fdaf3f897807dee2 Mon Sep 17 00:00:00 2001 From: Raoul Van den Berge Date: Wed, 7 Dec 2016 21:45:06 +0100 Subject: [PATCH] Grid tabs. Doesn't save current tab to server yet, and doesn't handle container resize correctly all the times. --- .../container/ContainerGrid.java | 23 ++-- .../refinedstorage/gui/GuiBase.java | 5 +- .../refinedstorage/gui/grid/GridTab.java | 29 +++++ .../refinedstorage/gui/grid/GuiGrid.java | 110 +++++++++++++++--- .../gui/grid/filtering/GridFilterParser.java | 7 +- .../ItemHandlerGridFilterInGrid.java | 19 ++- .../refinedstorage/tile/grid/IGrid.java | 3 + .../refinedstorage/tile/grid/TileGrid.java | 9 +- .../tile/grid/WirelessGrid.java | 9 +- .../assets/refinedstorage/textures/icons.png | Bin 20037 -> 8532 bytes 10 files changed, 180 insertions(+), 34 deletions(-) create mode 100755 src/main/java/com/raoulvdberge/refinedstorage/gui/grid/GridTab.java diff --git a/src/main/java/com/raoulvdberge/refinedstorage/container/ContainerGrid.java b/src/main/java/com/raoulvdberge/refinedstorage/container/ContainerGrid.java index dd741bd60..d660413bb 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/container/ContainerGrid.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/container/ContainerGrid.java @@ -15,6 +15,9 @@ import net.minecraft.item.ItemStack; import net.minecraftforge.items.SlotItemHandler; public class ContainerGrid extends ContainerBase { + public static final int TAB_WIDTH = 28; + public static final int TAB_HEIGHT = 31; + private IGrid grid; private SlotGridCraftingResult craftingResultSlot; @@ -25,11 +28,11 @@ public class ContainerGrid extends ContainerBase { this.grid = grid; - addPlayerInventory(8, (grid.getType() == EnumGridType.CRAFTING || grid.getType() == EnumGridType.PATTERN) ? 165 : 126); + addPlayerInventory(8, ((grid.getType() == EnumGridType.CRAFTING || grid.getType() == EnumGridType.PATTERN) ? 165 : 126) + getTabDelta()); if (grid.getType() == EnumGridType.CRAFTING) { int x = 26; - int y = 96; + int y = 96 + getTabDelta(); for (int i = 0; i < 9; ++i) { addSlotToContainer(new SlotGridCrafting(((TileGrid) grid).getMatrix(), i, x, y)); @@ -42,10 +45,10 @@ public class ContainerGrid extends ContainerBase { } } - addSlotToContainer(craftingResultSlot = new SlotGridCraftingResult(this, player, (TileGrid) grid, 0, 130 + 4, 110 + 4)); + addSlotToContainer(craftingResultSlot = new SlotGridCraftingResult(this, player, (TileGrid) grid, 0, 130 + 4, 110 + 4 + getTabDelta())); } else if (grid.getType() == EnumGridType.PATTERN) { int x = 8; - int y = 96; + int y = 96 + getTabDelta(); for (int i = 0; i < 9; ++i) { addSlotToContainer(new SlotFilterLegacy(((TileGrid) grid).getMatrix(), i, x, y)); @@ -58,19 +61,23 @@ public class ContainerGrid extends ContainerBase { } } - addSlotToContainer(patternResultSlot = new SlotDisabled(((TileGrid) grid).getResult(), 0, 112 + 4, 110 + 4)); + addSlotToContainer(patternResultSlot = new SlotDisabled(((TileGrid) grid).getResult(), 0, 112 + 4, 110 + 4 + getTabDelta())); - addSlotToContainer(new SlotItemHandler(((TileGrid) grid).getPatterns(), 0, 152, 96)); - addSlotToContainer(new SlotOutput(((TileGrid) grid).getPatterns(), 1, 152, 132)); + addSlotToContainer(new SlotItemHandler(((TileGrid) grid).getPatterns(), 0, 152, 96 + getTabDelta())); + addSlotToContainer(new SlotOutput(((TileGrid) grid).getPatterns(), 1, 152, 132 + getTabDelta())); } if (grid.getType() != EnumGridType.FLUID) { for (int i = 0; i < 4; ++i) { - addSlotToContainer(new SlotItemHandler(grid.getFilter(), i, 204, 6 + (18 * i))); + addSlotToContainer(new SlotItemHandler(grid.getFilter(), i, 204, 6 + (18 * i) + getTabDelta())); } } } + private int getTabDelta() { + return !grid.getTabs().isEmpty() ? TAB_HEIGHT - 4 : 0; + } + public IGrid getGrid() { return grid; } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/gui/GuiBase.java b/src/main/java/com/raoulvdberge/refinedstorage/gui/GuiBase.java index 2b31c71d9..cf2f1310c 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/gui/GuiBase.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/gui/GuiBase.java @@ -49,8 +49,9 @@ public abstract class GuiBase extends GuiContainer { } } + protected int sideButtonYStart = 6; private int lastButtonId; - private int lastSideButtonY = 6; + private int lastSideButtonY = sideButtonYStart; protected int width; protected int height; @@ -75,7 +76,7 @@ public abstract class GuiBase extends GuiContainer { super.initGui(); lastButtonId = 0; - lastSideButtonY = 6; + lastSideButtonY = sideButtonYStart; init(guiLeft, guiTop); } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/GridTab.java b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/GridTab.java new file mode 100755 index 000000000..bbb89eab5 --- /dev/null +++ b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/GridTab.java @@ -0,0 +1,29 @@ +package com.raoulvdberge.refinedstorage.gui.grid; + +import net.minecraft.item.ItemStack; + +import java.util.List; + +public class GridTab { + private List filters; + private String name; + private ItemStack icon; + + public GridTab(List filters, String name, ItemStack icon) { + this.filters = filters; + this.name = name; + this.icon = icon; + } + + public List getFilters() { + return filters; + } + + public String getName() { + return name; + } + + public ItemStack getIcon() { + return icon; + } +} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/GuiGrid.java b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/GuiGrid.java index 29e249daa..57bfdffcf 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/GuiGrid.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/GuiGrid.java @@ -61,6 +61,9 @@ public class GuiGrid extends GuiBase { private ContainerGrid container; private IGrid grid; + private int tabSelected = -1; + private int tabHovering = -1; + private int slotNumber; private Deque konami = new ArrayDeque<>(Arrays.asList( @@ -84,13 +87,17 @@ public class GuiGrid extends GuiBase { } public GuiGrid(ContainerGrid container, IGrid grid) { - super(container, grid.getType() == EnumGridType.FLUID ? 193 : 227, (grid.getType() == EnumGridType.CRAFTING || grid.getType() == EnumGridType.PATTERN) ? 247 : 208); + super(container, grid.getType() == EnumGridType.FLUID ? 193 : 227, ((grid.getType() == EnumGridType.CRAFTING || grid.getType() == EnumGridType.PATTERN) ? 247 : 208) + (!grid.getTabs().isEmpty() ? ContainerGrid.TAB_HEIGHT : 0)); this.container = container; this.grid = grid; this.wasConnected = this.grid.isActive(); - this.scrollbar = new Scrollbar(174, 20, 12, (grid.getType() == EnumGridType.CRAFTING || grid.getType() == EnumGridType.PATTERN || grid.getType() == EnumGridType.FLUID) ? 70 : 88); + this.scrollbar = new Scrollbar(174, 20 + getTabDelta(), 12, (grid.getType() == EnumGridType.CRAFTING || grid.getType() == EnumGridType.PATTERN || grid.getType() == EnumGridType.FLUID) ? 70 : 88); + + if (!grid.getTabs().isEmpty()) { + sideButtonYStart += ContainerGrid.TAB_HEIGHT - 3; + } this.konamiOffsetsX = new int[9 * getVisibleRows()]; this.konamiOffsetsY = new int[9 * getVisibleRows()]; @@ -103,7 +110,7 @@ public class GuiGrid extends GuiBase { } int sx = x + 80 + 1; - int sy = y + 6 + 1; + int sy = y + 6 + 1 + getTabDelta(); if (searchField == null) { searchField = new GuiTextField(0, fontRendererObj, sx, sy, 88 - 6, fontRendererObj.FONT_HEIGHT); @@ -118,7 +125,7 @@ public class GuiGrid extends GuiBase { } if (grid.getType() == EnumGridType.PATTERN) { - oredictPattern = addCheckBox(x + 64, y + 138, t("misc.refinedstorage:oredict"), TileGrid.OREDICT_PATTERN.getValue()); + oredictPattern = addCheckBox(x + 64, y + 138 + getTabDelta(), t("misc.refinedstorage:oredict"), TileGrid.OREDICT_PATTERN.getValue()); } if (grid.getType() != EnumGridType.FLUID) { @@ -142,7 +149,7 @@ public class GuiGrid extends GuiBase { if (grid.isActive()) { stacks.addAll(grid.getType() == EnumGridType.FLUID ? FLUIDS.values() : ITEMS.values()); - List filters = GridFilterParser.getFilters(grid, searchField.getText()); + List filters = GridFilterParser.getFilters(grid, searchField.getText(), (tabSelected >= 0 && tabSelected < grid.getTabs().size()) ? grid.getTabs().get(tabSelected).getFilters() : grid.getFilteredItems()); Iterator t = stacks.iterator(); @@ -209,7 +216,7 @@ public class GuiGrid extends GuiBase { } public boolean isOverSlotArea(int mouseX, int mouseY) { - return inBounds(7, 19, 162, 18 * getVisibleRows(), mouseX, mouseY); + return inBounds(7, 19 + getTabDelta(), 162, 18 * getVisibleRows(), mouseX, mouseY); } private int getVisibleRows() { @@ -219,20 +226,75 @@ public class GuiGrid extends GuiBase { private boolean isOverClear(int mouseX, int mouseY) { switch (grid.getType()) { case CRAFTING: - return inBounds(82, 95, 7, 7, mouseX, mouseY); + return inBounds(82, 95 + getTabDelta(), 7, 7, mouseX, mouseY); case PATTERN: - return inBounds(64, 95, 7, 7, mouseX, mouseY); + return inBounds(64, 95 + getTabDelta(), 7, 7, mouseX, mouseY); default: return false; } } private boolean isOverCreatePattern(int mouseX, int mouseY) { - return grid.getType() == EnumGridType.PATTERN && inBounds(152, 114, 16, 16, mouseX, mouseY) && ((TileGrid) grid).canCreatePattern(); + return grid.getType() == EnumGridType.PATTERN && inBounds(152, 114 + getTabDelta(), 16, 16, mouseX, mouseY) && ((TileGrid) grid).canCreatePattern(); + } + + private int getTabDelta() { + return !grid.getTabs().isEmpty() ? ContainerGrid.TAB_HEIGHT - 4 : 0; + } + + private void renderTab(GridTab tab, boolean foregroundLayer, int x, int y, int mouseX, int mouseY) { + int i = grid.getTabs().indexOf(tab); + boolean selected = i == tabSelected; + + if ((foregroundLayer && !selected) || (!foregroundLayer && selected)) { + return; + } + + int tx = x + ((ContainerGrid.TAB_WIDTH + 2) * i); + int ty = y; + + bindTexture("icons.png"); + + if (!selected) { + ty += 3; + } + + int uvx = 0, uvy = 225; + int tbw = ContainerGrid.TAB_WIDTH; + int otx = tx; + + if (selected) { + uvx = 227; + + if (i > 0) { + uvx = 226; + uvy = 194; + tbw++; + tx--; + } + } else { + uvx = 199; + } + + drawTexture(tx, ty, uvx, uvy, tbw, ContainerGrid.TAB_HEIGHT); + + RenderHelper.enableGUIStandardItemLighting(); + + drawItem(otx + 6, ty + 8 - (!selected ? 3 : 0), tab.getIcon()); + + if (inBounds(tx, ty, ContainerGrid.TAB_WIDTH, ContainerGrid.TAB_HEIGHT, mouseX, mouseY)) { + tabHovering = i; + } } @Override public void drawBackground(int x, int y, int mouseX, int mouseY) { + tabHovering = -1; + + for (GridTab tab : grid.getTabs()) { + renderTab(tab, false, x, y, mouseX, mouseY); + } + if (grid.getType() == EnumGridType.CRAFTING) { bindTexture("gui/crafting_grid.png"); } else if (grid.getType() == EnumGridType.PATTERN) { @@ -241,7 +303,11 @@ public class GuiGrid extends GuiBase { bindTexture("gui/grid.png"); } - drawTexture(x, y, 0, 0, width, height); + drawTexture(x, y + getTabDelta(), 0, 0, width, height - (!grid.getTabs().isEmpty() ? ContainerGrid.TAB_HEIGHT : 0)); + + for (GridTab tab : grid.getTabs()) { + renderTab(tab, true, x, y, mouseX, mouseY); + } if (grid.getType() == EnumGridType.PATTERN) { int ty = 0; @@ -254,7 +320,7 @@ public class GuiGrid extends GuiBase { ty = 2; } - drawTexture(x + 152, y + 114, 240, ty * 16, 16, 16); + drawTexture(x + 152, y + 114 + getTabDelta(), 240, ty * 16, 16, 16); } searchField.drawTextBox(); @@ -262,11 +328,11 @@ public class GuiGrid extends GuiBase { @Override public void drawForeground(int mouseX, int mouseY) { - drawString(7, 7, t(grid.getGuiTitle())); - drawString(7, (grid.getType() == EnumGridType.CRAFTING || grid.getType() == EnumGridType.PATTERN) ? 153 : 114, t("container.inventory")); + drawString(7, 7 + getTabDelta(), t(grid.getGuiTitle())); + drawString(7, ((grid.getType() == EnumGridType.CRAFTING || grid.getType() == EnumGridType.PATTERN) ? 153 : 114) + getTabDelta(), t("container.inventory")); int x = 8; - int y = 20; + int y = 20 + getTabDelta(); this.slotNumber = -1; @@ -321,6 +387,10 @@ public class GuiGrid extends GuiBase { if (isOverCreatePattern(mouseX, mouseY)) { drawTooltip(mouseX, mouseY, t("gui.refinedstorage:grid.pattern_create")); } + + if (tabHovering >= 0 && tabHovering < grid.getTabs().size()) { + drawTooltip(mouseX, mouseY, grid.getTabs().get(tabHovering).getName()); + } } @Override @@ -338,7 +408,13 @@ public class GuiGrid extends GuiBase { searchField.mouseClicked(mouseX, mouseY, clickedButton); - if (clickedButton == 1 && inBounds(79, 5, 90, 12, mouseX - guiLeft, mouseY - guiTop)) { + if (tabHovering != -1) { + tabSelected = tabSelected == tabHovering ? -1 : tabHovering; + + sortItems(); + } + + if (clickedButton == 1 && inBounds(79, 5 + getTabDelta(), 90, 12, mouseX - guiLeft, mouseY - guiTop)) { searchField.setText(""); searchField.setFocused(true); @@ -347,8 +423,8 @@ public class GuiGrid extends GuiBase { updateJEI(); } - boolean clickedClear = clickedButton == 0 && isOverClear(mouseX - guiLeft, mouseY - guiTop); - boolean clickedCreatePattern = clickedButton == 0 && isOverCreatePattern(mouseX - guiLeft, mouseY - guiTop); + boolean clickedClear = clickedButton == 0 && isOverClear(mouseX - guiLeft, mouseY - guiTop + getTabDelta()); + boolean clickedCreatePattern = clickedButton == 0 && isOverCreatePattern(mouseX - guiLeft, mouseY - guiTop + getTabDelta()); if (clickedCreatePattern) { BlockPos gridPos = ((TileGrid) grid).getPos(); diff --git a/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/filtering/GridFilterParser.java b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/filtering/GridFilterParser.java index 0e251326d..3c101376a 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/filtering/GridFilterParser.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/filtering/GridFilterParser.java @@ -1,5 +1,6 @@ package com.raoulvdberge.refinedstorage.gui.grid.filtering; +import com.raoulvdberge.refinedstorage.gui.grid.GridFilteredItem; import com.raoulvdberge.refinedstorage.tile.grid.IGrid; import com.raoulvdberge.refinedstorage.tile.grid.TileGrid; @@ -7,7 +8,7 @@ import java.util.LinkedList; import java.util.List; public class GridFilterParser { - public static List getFilters(IGrid grid, String query) { + public static List getFilters(IGrid grid, String query, List itemFilters) { List filters = new LinkedList<>(); for (String part : query.toLowerCase().trim().split(" ")) { @@ -26,8 +27,8 @@ public class GridFilterParser { filters.add(new GridFilterCraftable(true)); } - if (!grid.getFilteredItems().isEmpty()) { - filters.add(new GridFilterFilteredItems(grid.getFilteredItems())); + if (!itemFilters.isEmpty()) { + filters.add(new GridFilterFilteredItems(itemFilters)); } return filters; diff --git a/src/main/java/com/raoulvdberge/refinedstorage/inventory/ItemHandlerGridFilterInGrid.java b/src/main/java/com/raoulvdberge/refinedstorage/inventory/ItemHandlerGridFilterInGrid.java index a4039afda..772205b4a 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/inventory/ItemHandlerGridFilterInGrid.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/inventory/ItemHandlerGridFilterInGrid.java @@ -2,21 +2,25 @@ package com.raoulvdberge.refinedstorage.inventory; import com.raoulvdberge.refinedstorage.RSItems; import com.raoulvdberge.refinedstorage.gui.grid.GridFilteredItem; +import com.raoulvdberge.refinedstorage.gui.grid.GridTab; import com.raoulvdberge.refinedstorage.gui.grid.GuiGrid; import com.raoulvdberge.refinedstorage.item.ItemGridFilter; import net.minecraft.item.ItemStack; import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.relauncher.Side; +import java.util.ArrayList; import java.util.List; public class ItemHandlerGridFilterInGrid extends ItemHandlerBasic { private List filteredItems; + private List tabs; - public ItemHandlerGridFilterInGrid(List filteredItems) { + public ItemHandlerGridFilterInGrid(List filteredItems, List tabs) { super(4, new ItemValidatorBasic(RSItems.GRID_FILTER)); this.filteredItems = filteredItems; + this.tabs = tabs; } @Override @@ -24,6 +28,7 @@ public class ItemHandlerGridFilterInGrid extends ItemHandlerBasic { super.onContentsChanged(slot); filteredItems.clear(); + tabs.clear(); for (int i = 0; i < getSlots(); ++i) { ItemStack filter = getStackInSlot(i); @@ -35,11 +40,21 @@ public class ItemHandlerGridFilterInGrid extends ItemHandlerBasic { ItemHandlerGridFilter items = new ItemHandlerGridFilter(filter); + List filters = new ArrayList<>(); + for (ItemStack item : items.getFilteredItems()) { if (!item.isEmpty()) { - filteredItems.add(new GridFilteredItem(item, compare, mode, modFilter)); + filters.add(new GridFilteredItem(item, compare, mode, modFilter)); } } + + ItemStack icon = ItemGridFilter.getIcon(filter); + + if (icon.isEmpty()) { + filteredItems.addAll(filters); + } else { + tabs.add(new GridTab(filters, ItemGridFilter.getName(filter), icon)); + } } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/IGrid.java b/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/IGrid.java index 3d7dfa981..319afdf68 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/IGrid.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/IGrid.java @@ -4,6 +4,7 @@ import com.raoulvdberge.refinedstorage.api.network.grid.IFluidGridHandler; import com.raoulvdberge.refinedstorage.api.network.grid.IItemGridHandler; import com.raoulvdberge.refinedstorage.block.EnumGridType; import com.raoulvdberge.refinedstorage.gui.grid.GridFilteredItem; +import com.raoulvdberge.refinedstorage.gui.grid.GridTab; import com.raoulvdberge.refinedstorage.inventory.ItemHandlerBasic; import com.raoulvdberge.refinedstorage.tile.data.TileDataParameter; import net.minecraft.util.math.BlockPos; @@ -41,6 +42,8 @@ public interface IGrid { List getFilteredItems(); + List getTabs(); + ItemHandlerBasic getFilter(); TileDataParameter getRedstoneModeConfig(); diff --git a/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/TileGrid.java b/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/TileGrid.java index 8be95c337..d503c800f 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/TileGrid.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/TileGrid.java @@ -11,6 +11,7 @@ import com.raoulvdberge.refinedstorage.block.BlockGrid; import com.raoulvdberge.refinedstorage.block.EnumGridType; import com.raoulvdberge.refinedstorage.container.ContainerGrid; import com.raoulvdberge.refinedstorage.gui.grid.GridFilteredItem; +import com.raoulvdberge.refinedstorage.gui.grid.GridTab; import com.raoulvdberge.refinedstorage.gui.grid.GuiGrid; import com.raoulvdberge.refinedstorage.inventory.ItemHandlerBasic; import com.raoulvdberge.refinedstorage.inventory.ItemHandlerGridFilterInGrid; @@ -164,7 +165,8 @@ public class TileGrid extends TileNode implements IGrid { private ItemHandlerBasic patterns = new ItemHandlerBasic(2, this, new ItemValidatorBasic(RSItems.PATTERN)); private List filteredItems = new ArrayList<>(); - private ItemHandlerGridFilterInGrid filter = new ItemHandlerGridFilterInGrid(filteredItems); + private List tabs = new ArrayList<>(); + private ItemHandlerGridFilterInGrid filter = new ItemHandlerGridFilterInGrid(filteredItems, tabs); private EnumGridType type; @@ -264,6 +266,11 @@ public class TileGrid extends TileNode implements IGrid { return filteredItems; } + @Override + public List getTabs() { + return tabs; + } + public void onCraftingMatrixChanged() { markDirty(); diff --git a/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/WirelessGrid.java b/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/WirelessGrid.java index ac48fd690..1bedbb62c 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/WirelessGrid.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/WirelessGrid.java @@ -6,6 +6,7 @@ import com.raoulvdberge.refinedstorage.api.network.grid.IFluidGridHandler; import com.raoulvdberge.refinedstorage.api.network.grid.IItemGridHandler; import com.raoulvdberge.refinedstorage.block.EnumGridType; import com.raoulvdberge.refinedstorage.gui.grid.GridFilteredItem; +import com.raoulvdberge.refinedstorage.gui.grid.GridTab; import com.raoulvdberge.refinedstorage.gui.grid.GuiGrid; import com.raoulvdberge.refinedstorage.inventory.ItemHandlerBasic; import com.raoulvdberge.refinedstorage.inventory.ItemHandlerGridFilterInGrid; @@ -38,7 +39,8 @@ public class WirelessGrid implements IGrid { private int searchBoxMode; private List filteredItems = new ArrayList<>(); - private ItemHandlerGridFilterInGrid filter = new ItemHandlerGridFilterInGrid(filteredItems) { + private List tabs = new ArrayList<>(); + private ItemHandlerGridFilterInGrid filter = new ItemHandlerGridFilterInGrid(filteredItems, tabs) { @Override protected void onContentsChanged(int slot) { super.onContentsChanged(slot); @@ -161,6 +163,11 @@ public class WirelessGrid implements IGrid { return filteredItems; } + @Override + public List getTabs() { + return tabs; + } + @Override public ItemHandlerBasic getFilter() { return filter; diff --git a/src/main/resources/assets/refinedstorage/textures/icons.png b/src/main/resources/assets/refinedstorage/textures/icons.png index f7bfb95c85207fdf004a4db5f01e145d48e26018..0bdd15588428336ea590cb74e97f2c8bac6cff85 100755 GIT binary patch literal 8532 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 literal 20037 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