From dea49bb4d483d5ff7e9897df008d74455cd3d9f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Gris?= Date: Thu, 20 Feb 2020 16:09:17 +0100 Subject: [PATCH] feature(gui): improve mode selection button - Replace mode selection button's text, with layout pictures. - Refactor some GUI implementations. - Prepare GUI layout for a future TODO scrollbar. --- .../team/chisel/client/gui/GuiChisel.java | 93 ++++++++------- .../gui/widgets/GuiButtonChiselMode.java | 106 ++++++++++++++++++ .../chisel/textures/chisel2GuiScroll.png | Bin 4676 -> 4274 bytes 3 files changed, 151 insertions(+), 48 deletions(-) create mode 100644 src/main/java/team/chisel/client/gui/widgets/GuiButtonChiselMode.java diff --git a/src/main/java/team/chisel/client/gui/GuiChisel.java b/src/main/java/team/chisel/client/gui/GuiChisel.java index 1c3cff35..550ebe14 100644 --- a/src/main/java/team/chisel/client/gui/GuiChisel.java +++ b/src/main/java/team/chisel/client/gui/GuiChisel.java @@ -1,5 +1,10 @@ package team.chisel.client.gui; +import com.cricketcraft.chisel.api.IAdvancedChisel; +import com.cricketcraft.chisel.api.IChiselItem; +import com.cricketcraft.chisel.api.carving.IChiselMode; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.resources.I18n; @@ -7,13 +12,9 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; - +import net.minecraft.util.ResourceLocation; import org.lwjgl.opengl.GL11; - -import com.cricketcraft.chisel.api.IAdvancedChisel; -import com.cricketcraft.chisel.api.IChiselItem; -import com.cricketcraft.chisel.api.carving.IChiselMode; - +import team.chisel.client.gui.widgets.GuiButtonChiselMode; import team.chisel.inventory.ContainerChisel; import team.chisel.inventory.InventoryChiselSelection; import team.chisel.inventory.SlotChiselInput; @@ -21,19 +22,27 @@ import team.chisel.item.chisel.ChiselMode; import team.chisel.network.PacketHandler; import team.chisel.network.message.MessageChiselMode; import team.chisel.utils.General; -import team.chisel.utils.GeneralClient; +import static team.chisel.Chisel.MOD_ID; + +@SideOnly(Side.CLIENT) public class GuiChisel extends GuiContainer { - public EntityPlayer player; - public ContainerChisel container; + public static final ResourceLocation TEXTURE_RESOURCE_LOCATION = new ResourceLocation(MOD_ID, "textures/chisel2GuiScroll.png"); + public static final int TEXTURE_WIDTH = 266; + public static final int TEXTURE_HEIGHT = 250; + public static final int GUI_WIDTH = 266; + public static final int GUI_HEIGHT = 202; + public static final int CHISEL_INPUT_SIZE = 48; + private EntityPlayer player; + private ContainerChisel container; private IChiselMode currentMode; public GuiChisel(InventoryPlayer iinventory, InventoryChiselSelection menu) { super(new ContainerChisel(iinventory, menu)); player = iinventory.player; - xSize = 252; - ySize = 202; + xSize = GUI_WIDTH; + ySize = GUI_HEIGHT; container = (ContainerChisel) inventorySlots; } @@ -44,92 +53,76 @@ public class GuiChisel extends GuiContainer { inventorySlots.onContainerClosed(player); } - @SuppressWarnings("unchecked") @Override + @SuppressWarnings("unchecked") public void initGui() { super.initGui(); currentMode = General.getChiselMode(container.chisel); if (showMode()) { - int x = this.width / 2 - 120; - int y = this.height / 2 - 6; - buttonList.add(new GuiButton(0, x, y, 53, 20, "")); - setButtonText(); + buttonList.add(new GuiButtonChiselMode(0, guiLeft + 12, guiTop + 132, this)); } } @Override public void updateScreen() { super.updateScreen(); - ItemStack held = player.getCurrentEquippedItem(); + final ItemStack held = player.getCurrentEquippedItem(); if (held == null || !(held.getItem() instanceof IChiselItem)) { mc.displayGuiScreen(null); } } - private void setButtonText() { - ((GuiButton) buttonList.get(0)).displayString = I18n.format(container.inventory.getInventoryName() + ".mode." + currentMode.name().toLowerCase()); - } - private boolean showMode() { - if (container.chisel != null && container.chisel.getItem() instanceof IChiselItem) { - return ((IChiselItem) container.chisel.getItem()).hasModes(container.chisel); - } - return false; + return container.chisel != null + && container.chisel.getItem() instanceof IChiselItem + && ((IChiselItem) container.chisel.getItem()).hasModes(container.chisel); } @Override - protected void drawGuiContainerForegroundLayer(int j, int i) { + protected void drawGuiContainerForegroundLayer(final int mouseX, final int mouseY) { GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - String line = I18n.format(this.container.inventory.getInventoryName() + ".title"); - fontRendererObj.drawSplitString(line, 50 - fontRendererObj.getStringWidth(line) / 2, 60, 40, 0x404040); + final String titleText = I18n.format(container.inventory.getInventoryName() + ".title"); + fontRendererObj.drawSplitString(titleText, 50 - fontRendererObj.getStringWidth(titleText) / 2, 60, 40, 0x404040); if (showMode()) { - line = I18n.format(this.container.inventory.getInventoryName() + ".mode"); - fontRendererObj.drawString(line, fontRendererObj.getStringWidth(line) / 2 + 6, 85, 0x404040); + final String modeText = I18n.format(container.inventory.getInventoryName() + ".mode"); + fontRendererObj.drawString(modeText, 12 + (GuiButtonChiselMode.BUTTON_WIDTH - fontRendererObj.getStringWidth(modeText)) / 2, 122, 0x404040); } } @Override - protected void drawGuiContainerBackgroundLayer(float f, int mx, int my) { + protected void drawGuiContainerBackgroundLayer(final float partialTicks, final int mouseX, final int mouseY) { GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glDisable(GL11.GL_LIGHTING); - int i = width - xSize >> 1; - int j = height - ySize >> 1; - - String texture = "chisel:textures/chisel2Gui.png"; - - GeneralClient.bind(texture); - drawTexturedModalRect(i, j, 0, 0, xSize, ySize); - - int x = (width - xSize) / 2; - int y = (height - ySize) / 2; + mc.getTextureManager().bindTexture(TEXTURE_RESOURCE_LOCATION); + // drawModalRectWithCustomSizedTexture: x, y, u, v, width, height, textureWidth, textureHeight + func_146110_a(guiLeft, guiTop, 0, 0, xSize, ySize, TEXTURE_WIDTH, TEXTURE_HEIGHT); Slot main = (Slot) container.inventorySlots.get(InventoryChiselSelection.normalSlots); if (main.getStack() == null) { - GuiAutoChisel.drawSlotOverlay(this, x + 14, y + 14, main, 0, ySize, 60); + func_146110_a(guiLeft + 8, guiTop + 8, 0, GUI_HEIGHT, CHISEL_INPUT_SIZE, CHISEL_INPUT_SIZE, TEXTURE_WIDTH, TEXTURE_HEIGHT); } } @Override - protected void actionPerformed(GuiButton button) { + protected void actionPerformed(final GuiButton button) { if (button.id == 0) { if (container.chisel != null && container.chisel.getItem() instanceof IAdvancedChisel) { - IAdvancedChisel item = (IAdvancedChisel) container.chisel.getItem(); + final IAdvancedChisel item = (IAdvancedChisel) container.chisel.getItem(); currentMode = item.getNextMode(container.chisel, currentMode); - PacketHandler.INSTANCE.sendToServer(new MessageChiselMode(currentMode)); } else { currentMode = ChiselMode.next(currentMode); - PacketHandler.INSTANCE.sendToServer(new MessageChiselMode(currentMode)); - setButtonText(); } + PacketHandler.INSTANCE.sendToServer(new MessageChiselMode(currentMode)); } super.actionPerformed(button); } @Override - protected void func_146977_a(Slot slot) { + protected void func_146977_a(final Slot slot) { if (slot instanceof SlotChiselInput) { GL11.glPushMatrix(); GL11.glScalef(2, 2, 2); @@ -143,4 +136,8 @@ public class GuiChisel extends GuiContainer { super.func_146977_a(slot); } } + + public IChiselMode getCurrentMode() { + return currentMode; + } } diff --git a/src/main/java/team/chisel/client/gui/widgets/GuiButtonChiselMode.java b/src/main/java/team/chisel/client/gui/widgets/GuiButtonChiselMode.java new file mode 100644 index 00000000..e9291953 --- /dev/null +++ b/src/main/java/team/chisel/client/gui/widgets/GuiButtonChiselMode.java @@ -0,0 +1,106 @@ +package team.chisel.client.gui.widgets; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiButton; +import org.lwjgl.opengl.GL11; +import team.chisel.client.gui.GuiChisel; +import team.chisel.item.chisel.ChiselMode; + +import static team.chisel.client.gui.GuiChisel.*; + +@SideOnly(Side.CLIENT) +public class GuiButtonChiselMode extends GuiButton { + public static final int BUTTON_WIDTH = 48; + public static final int BUTTON_HEIGHT = 48; + private static final float BUTTON_BACKGROUND_U = 48; + private static final float BUTTON_BACKGROUND_V = 202; + private static final float MODE_VIGNETTE_U = BUTTON_BACKGROUND_U + 2 * BUTTON_WIDTH + 3; + private static final float MODE_VIGNETTE_V = BUTTON_BACKGROUND_V + 3; + private static final int MODE_VIGNETTE_WIDTH = 14; + private static final int MODE_VIGNETTE_ROW_WIDTH = 3 * MODE_VIGNETTE_WIDTH; + private static final int MODE_VIGNETTE_HEIGHT = 14; + private static final int MODE_VIGNETTE_COL_HEIGHT = 3 * MODE_VIGNETTE_HEIGHT; + private final GuiChisel guiChisel; + + public GuiButtonChiselMode(int id, int x, int y, GuiChisel guiChisel) { + super(id, x, y, BUTTON_WIDTH, BUTTON_HEIGHT, ""); + this.guiChisel = guiChisel; + } + + /** + * Draws this button to the screen. + * + * @param mc The Minecraft instance + * @param mouseX The horizontal location of the mouse within the GuiScreen + * @param mouseY The vertical location of the mouse relative to the GuiScreen + */ + @Override + public void drawButton(final Minecraft mc, final int mouseX, final int mouseY) { + if (this.visible) { + mc.getTextureManager().bindTexture(TEXTURE_RESOURCE_LOCATION); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + // Mouse Hover State + this.field_146123_n = mouseX >= this.xPosition && mouseY >= this.yPosition && mouseX < this.xPosition + this.width && mouseY < this.yPosition + this.height; + drawButtonBackgroundLayer(); + drawButtonForegroundLayer(); + } + } + + private void drawButtonBackgroundLayer() { + final float u = BUTTON_BACKGROUND_U + (this.field_146123_n ? BUTTON_WIDTH : 0); + // drawModalRectWithCustomSizedTexture: x, y, u, v, width, height, textureWidth, textureHeight + func_146110_a(this.xPosition, this.yPosition, u, BUTTON_BACKGROUND_V, this.width, this.height, TEXTURE_WIDTH, TEXTURE_HEIGHT); + } + + private void drawButtonForegroundLayer() { + final int xBase = this.xPosition + 3; + final int yBase = this.yPosition + 3; + final float uBase = MODE_VIGNETTE_U + (this.field_146123_n ? BUTTON_WIDTH : 0); + final float u; + final float v; + final int w; + final int h; + final int x; + final int y; + switch ((ChiselMode) guiChisel.getCurrentMode()) { + case SINGLE: + x = xBase + MODE_VIGNETTE_WIDTH; + y = yBase + MODE_VIGNETTE_HEIGHT; + u = uBase + MODE_VIGNETTE_WIDTH; + v = MODE_VIGNETTE_V + MODE_VIGNETTE_HEIGHT; + w = MODE_VIGNETTE_WIDTH; + h = MODE_VIGNETTE_HEIGHT; + break; + case ROW: + x = xBase; + y = yBase + MODE_VIGNETTE_HEIGHT; + u = uBase; + v = MODE_VIGNETTE_V + MODE_VIGNETTE_HEIGHT; + w = MODE_VIGNETTE_ROW_WIDTH; + h = MODE_VIGNETTE_HEIGHT; + break; + case COLUMN: + x = xBase + MODE_VIGNETTE_WIDTH; + y = yBase; + u = uBase + MODE_VIGNETTE_WIDTH; + v = MODE_VIGNETTE_V; + w = MODE_VIGNETTE_WIDTH; + h = MODE_VIGNETTE_COL_HEIGHT; + break; + case PANEL: + x = xBase; + y = yBase; + u = uBase; + v = MODE_VIGNETTE_V; + w = MODE_VIGNETTE_ROW_WIDTH; + h = MODE_VIGNETTE_COL_HEIGHT; + break; + default: + return; + } + // drawModalRectWithCustomSizedTexture: x, y, u, v, width, height, textureWidth, textureHeight + func_146110_a(x, y, u, v, w, h, TEXTURE_WIDTH, TEXTURE_HEIGHT); + } +} diff --git a/src/main/resources/assets/chisel/textures/chisel2GuiScroll.png b/src/main/resources/assets/chisel/textures/chisel2GuiScroll.png index 4e56a217ab19ddbacaa875e4a587b1d7894c592e..66f179fa5288afe0f5b0d9252b4a4c25f4da976e 100644 GIT binary patch literal 4274 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 literal 4676 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