package slimeknights.tconstruct.tools.common.client.module; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.inventory.Container; import net.minecraft.inventory.Slot; import net.minecraft.util.ResourceLocation; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import slimeknights.mantle.client.gui.GuiElement; import slimeknights.mantle.client.gui.GuiElementScalable; import slimeknights.mantle.client.gui.GuiModule; import slimeknights.mantle.client.gui.GuiMultiModule; import slimeknights.mantle.client.gui.GuiWidgetSlider; import slimeknights.mantle.inventory.BaseContainer; import slimeknights.tconstruct.library.Util; // a side inventory to be displayed to the left or right of another GUI @SideOnly(Side.CLIENT) public class GuiSideInventory extends GuiModule { protected GuiElementScalable overlap = GuiGeneric.overlap; protected GuiElement overlapTopLeft = GuiGeneric.overlapTopLeft; protected GuiElement overlapTopRight = GuiGeneric.overlapTopRight; protected GuiElement overlapBottomLeft = GuiGeneric.overlapBottomLeft; protected GuiElement overlapBottomRight = GuiGeneric.overlapBottomRight; protected GuiElement overlapTop = new GuiElement(7, 0, 7, 7, 64, 64); // same as borderTop but only 7 wide protected GuiElementScalable textBackground = GuiGeneric.textBackground; protected GuiElementScalable slot = GuiGeneric.slot; protected GuiElementScalable slotEmpty = GuiGeneric.slotEmpty; protected GuiElement sliderNormal = GuiGeneric.sliderNormal; protected GuiElement sliderLow = GuiGeneric.sliderLow; protected GuiElement sliderHigh = GuiGeneric.sliderHigh; protected GuiElement sliderTop = GuiGeneric.sliderTop; protected GuiElement sliderBottom = GuiGeneric.sliderBottom; protected GuiElementScalable sliderBackground = GuiGeneric.sliderBackground; // we use the chest gui as a preset for our parts protected static final ResourceLocation GUI_INVENTORY = Util.getResource("textures/gui/generic.png"); protected GuiWidgetBorder border = new GuiWidgetBorder(); protected int columns; protected int slotCount; protected int firstSlotId; protected int lastSlotId; protected int yOffset = 5; protected int xOffset; protected boolean connected; protected GuiWidgetSlider slider = new GuiWidgetSlider(sliderNormal, sliderHigh, sliderLow, sliderTop, sliderBottom, sliderBackground); public GuiSideInventory(GuiMultiModule parent, Container container, int slotCount, int columns) { this(parent, container, slotCount, columns, false, false); } public GuiSideInventory(GuiMultiModule parent, Container container, int slotCount, int columns, boolean rightSide, boolean connected) { super(parent, container, rightSide, false); this.connected = connected; this.columns = columns; this.slotCount = slotCount; this.xSize = columns * slot.w + border.w * 2; this.ySize = calcCappedYSize(slot.h * 10); if(connected) { if(right) { border.cornerTopLeft = overlapTopLeft; border.borderLeft = overlap; border.cornerBottomLeft = overlapBottomLeft; } else { border.cornerTopRight = overlapTopRight; border.borderRight = overlap; border.cornerBottomRight = overlapBottomRight; } } yOffset = 0; updateSlots(); } protected boolean shouldDrawName() { if(this.inventorySlots instanceof BaseContainer) { return ((BaseContainer) this.inventorySlots).getInventoryDisplayName() != null; } return false; } @Override public boolean shouldDrawSlot(Slot slot) { if(slot.getSlotIndex() >= slotCount) { return false; } // all visible if(!slider.isEnabled()) { return true; } return firstSlotId <= slot.getSlotIndex() && lastSlotId > slot.getSlotIndex(); } @Override public boolean isMouseOverSlot(Slot slotIn, int mouseX, int mouseY) { return super.isMouseOverSlot(slotIn, mouseX, mouseY) && shouldDrawSlot(slotIn); } public void updateSlotCount(int newSlotCount) { // don't do extra stuff if it's not needed if(slotCount == newSlotCount) { return; } this.slotCount = newSlotCount; // called twice to get correct slider calculation updatePosition(parent.cornerX, parent.cornerY, parent.realWidth, parent.realHeight); updatePosition(parent.cornerX, parent.cornerY, parent.realWidth, parent.realHeight); } @Override public void updatePosition(int parentX, int parentY, int parentSizeX, int parentSizeY) { // at most as big as the parent this.ySize = calcCappedYSize(parentSizeY - 10); // slider needed? if(getDisplayedRows() < getTotalRows()) { slider.enable(); this.xSize = columns * slot.w + slider.width + 2 * border.w; } else { slider.disable(); this.xSize = columns * slot.w + border.w * 2; } // update position super.updatePosition(parentX, parentY, parentSizeX, parentSizeY); // connected needs to move to the side if(connected) { if(yOffset == 0) { if(right) { border.cornerTopLeft = overlapTop; } else { border.cornerTopRight = overlapTop; } } xOffset = (border.w - 1) * (right ? -1 : 1); guiLeft += xOffset; } else { xOffset = 0; } // move it a bit this.guiTop += yOffset; border.setPosition(guiLeft, guiTop); border.setSize(xSize, ySize); int y = guiTop + border.h; int h = ySize - border.h * 2; if(shouldDrawName()) { y += textBackground.h; h -= textBackground.h; } slider.setPosition(guiLeft + columns * slot.w + border.w, y); slider.setSize(h); slider.setSliderParameters(0, getTotalRows() - getDisplayedRows(), 1); updateSlots(); } private int getDisplayedRows() { return slider.height / slot.h; } private int getTotalRows() { int total = slotCount / columns; if(slotCount % columns != 0) { total++; } return total; } private int calcCappedYSize(int max) { int h = slot.h * getTotalRows(); h = border.getHeightWithBorder(h); if(shouldDrawName()) { h += textBackground.h; } // not higher than the max while(h > max) { h -= slot.h; } return h; } // updates slot visibility protected void updateSlots() { firstSlotId = slider.getValue() * columns; lastSlotId = Math.min(slotCount, firstSlotId + getDisplayedRows() * columns); int xd = border.w + xOffset; int yd = border.h + yOffset; if(shouldDrawName()) { yd += textBackground.h; } for(Object o : inventorySlots.inventorySlots) { Slot slot = (Slot) o; if(shouldDrawSlot(slot)) { // calc position of the slot int offset = slot.getSlotIndex() - firstSlotId; int x = (offset % columns) * this.slot.w; int y = (offset / columns) * this.slot.h; slot.xPos = xd + x + 1; slot.yPos = yd + y + 1; if(this.right) { slot.xPos += parent.realWidth; } else { slot.xPos -= this.xSize; } } else { slot.xPos = 0; slot.yPos = 0; } } } @Override public void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { if(shouldDrawName()) { String name = ((BaseContainer) inventorySlots).getInventoryDisplayName(); this.fontRendererObj.drawString(name, border.w, border.h - 1, 0x404040); } } @Override protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) { guiLeft += border.w; guiTop += border.h; GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); this.mc.getTextureManager().bindTexture(GUI_INVENTORY); int x = guiLeft;// + border.w; int y = guiTop;// + border.h; int midW = xSize - border.w * 2; int midH = ySize - border.h * 2; border.draw(); if(shouldDrawName()) { textBackground.drawScaledX(x, y, midW); y += textBackground.h; } this.mc.getTextureManager().bindTexture(GUI_INVENTORY); drawSlots(x, y); /* // draw the connection to the main thing if(right) { x = guiLeft; y = guiTop; if(guiTop == parent.cornerY) { borderTop.drawScaledX(x, y, overlapTopLeft.w); } else { overlapTopLeft.draw(x, y); } y += cornerTopLeft.h; overlap.drawScaledY(x, y, midH); y += midH; if(guiBottom() == parent.cornerX + parent.realHeight) { borderBottom.drawScaledX(x, y, overlapBottomLeft.w); } else { overlapBottomLeft.draw(x, y); } } else if(slider.isEnabled()) { y = guiTop; borderTop.drawScaledX(x, y, cornerTopRight.w); y += cornerTopRight.h; overlap.drawScaledY(x, y, midH); y += midH; borderBottom.drawScaledX(x, y, cornerBottomRight.w); x = guiRight() - 1; y = guiTop; if(guiTop == parent.cornerY) { borderTop.drawScaledX(x, y, overlapTopRight.w); } else { overlapTopRight.draw(x, y); } y += cornerTopRight.h; overlap.drawScaledY(x, y, midH); y += midH; if(guiBottom() == parent.cornerX + parent.realHeight) { borderBottom.drawScaledX(x, y, overlapBottomRight.w); } else { overlapBottomRight.draw(x, y); } } */ // slider if(slider.isEnabled()) { slider.update(mouseX, mouseY, !isMouseOverFullSlot(mouseX, mouseY) && isMouseInModule(mouseX, mouseY)); slider.draw(); updateSlots(); } guiLeft -= border.w; guiTop -= border.h; } protected int drawSlots(int xPos, int yPos) { int width = columns * slot.w; int height = ySize - border.h * 2; int fullRows = (lastSlotId - firstSlotId) / columns; int y; for(y = 0; y < fullRows * slot.h && y < height; y += slot.h) { slot.drawScaledX(xPos, yPos + y, width); } // draw partial row and unused slots int slotsLeft = (lastSlotId - firstSlotId) % columns; if(slotsLeft > 0) { slot.drawScaledX(xPos, yPos + y, slotsLeft * slot.w); // empty slots that don't exist slotEmpty.drawScaledX(xPos + slotsLeft * slot.w, yPos + y, width - slotsLeft * slot.w); } return width; } }