From 595c0cdcb107d23138d603104115feed042d62f0 Mon Sep 17 00:00:00 2001 From: Discreater Date: Wed, 28 Apr 2021 22:38:45 +0800 Subject: [PATCH] feat: decoupling label --- .../jecalculation/client/gui/IDrawable.java | 23 ++ .../jecalculation/client/gui/JecGui.java | 230 ++++++---------- .../client/gui/{resource => }/Resource.java | 4 +- .../client/gui/drawables/DButton.java | 92 +++++++ .../client/gui/drawables/DContainer.java | 63 +++++ .../WIcon.java => drawables/DIcon.java} | 20 +- .../client/gui/drawables/DLabel.java | 125 +++++++++ .../DLabelGroup.java} | 26 +- .../client/gui/drawables/DLine.java | 25 ++ .../client/gui/drawables/DPager.java | 45 ++++ .../client/gui/drawables/DPanel.java | 19 ++ .../DRectangle.java} | 10 +- .../client/gui/drawables/DScroll.java | 64 +++++ .../WText.java => drawables/DText.java} | 26 +- .../DTextField.java} | 17 +- .../client/gui/guis/GuiCalculator.java | 38 ++- .../client/gui/guis/GuiEditor.java | 58 ++-- .../client/gui/guis/GuiLabelPicker.java | 16 ++ .../client/gui/widget/IDrawable.java | 19 -- .../client/gui/widget/Widget.java | 26 -- .../client/gui/widget/widgets/WButton.java | 104 -------- .../gui/widget/widgets/WButtonIcon.java | 80 ------ .../client/gui/widget/widgets/WEntry.java | 124 --------- .../client/gui/widget/widgets/WLine.java | 25 -- .../client/gui/widget/widgets/WPager.java | 73 ----- .../jecalculation/core/entry/Entry.java | 198 -------------- .../core/entry/entries/EntryItemStack.java | 40 --- .../core/entry/entries/EntryOreDict.java | 58 ---- .../jecalculation/core/labels/ILabel.java | 250 ++++++++++++++++++ .../core/labels/labels/LabelItemStack.java | 62 +++++ .../core/labels/labels/LabelOreDict.java | 97 +++++++ .../labels/LabelSimpleAmount.java} | 18 +- .../event/handlers/InputEventHandler.java | 2 +- .../towdium/jecalculation/item/JecaItem.java | 17 -- .../item/items/ItemCalculator.java | 12 + .../jecalculation/nei/JecaOverlayHandler.java | 4 +- .../towdium/jecalculation/nei/NEIPlugin.java | 19 +- .../jecalculation/network/ProxyCommon.java | 5 +- .../jecalculation/polyfill/Polyfill.java | 3 + .../jecalculation/utils/ItemStackHelper.java | 3 + .../jecalculation/utils/wrappers/Pair.java | 9 - .../jecalculation/textures/gui/resources.png | Bin 9880 -> 9932 bytes 42 files changed, 1095 insertions(+), 1054 deletions(-) create mode 100644 src/main/java/me/towdium/jecalculation/client/gui/IDrawable.java rename src/main/java/me/towdium/jecalculation/client/gui/{resource => }/Resource.java (94%) create mode 100644 src/main/java/me/towdium/jecalculation/client/gui/drawables/DButton.java create mode 100644 src/main/java/me/towdium/jecalculation/client/gui/drawables/DContainer.java rename src/main/java/me/towdium/jecalculation/client/gui/{widget/widgets/WIcon.java => drawables/DIcon.java} (58%) create mode 100644 src/main/java/me/towdium/jecalculation/client/gui/drawables/DLabel.java rename src/main/java/me/towdium/jecalculation/client/gui/{widget/widgets/WEntryGroup.java => drawables/DLabelGroup.java} (54%) create mode 100644 src/main/java/me/towdium/jecalculation/client/gui/drawables/DLine.java create mode 100644 src/main/java/me/towdium/jecalculation/client/gui/drawables/DPager.java create mode 100644 src/main/java/me/towdium/jecalculation/client/gui/drawables/DPanel.java rename src/main/java/me/towdium/jecalculation/client/gui/{widget/widgets/WRectangle.java => drawables/DRectangle.java} (61%) create mode 100644 src/main/java/me/towdium/jecalculation/client/gui/drawables/DScroll.java rename src/main/java/me/towdium/jecalculation/client/gui/{widget/widgets/WText.java => drawables/DText.java} (57%) rename src/main/java/me/towdium/jecalculation/client/gui/{widget/widgets/WTextField.java => drawables/DTextField.java} (70%) create mode 100644 src/main/java/me/towdium/jecalculation/client/gui/guis/GuiLabelPicker.java delete mode 100644 src/main/java/me/towdium/jecalculation/client/gui/widget/IDrawable.java delete mode 100644 src/main/java/me/towdium/jecalculation/client/gui/widget/Widget.java delete mode 100644 src/main/java/me/towdium/jecalculation/client/gui/widget/widgets/WButton.java delete mode 100644 src/main/java/me/towdium/jecalculation/client/gui/widget/widgets/WButtonIcon.java delete mode 100644 src/main/java/me/towdium/jecalculation/client/gui/widget/widgets/WEntry.java delete mode 100644 src/main/java/me/towdium/jecalculation/client/gui/widget/widgets/WLine.java delete mode 100644 src/main/java/me/towdium/jecalculation/client/gui/widget/widgets/WPager.java delete mode 100644 src/main/java/me/towdium/jecalculation/core/entry/Entry.java delete mode 100644 src/main/java/me/towdium/jecalculation/core/entry/entries/EntryItemStack.java delete mode 100644 src/main/java/me/towdium/jecalculation/core/entry/entries/EntryOreDict.java create mode 100644 src/main/java/me/towdium/jecalculation/core/labels/ILabel.java create mode 100644 src/main/java/me/towdium/jecalculation/core/labels/labels/LabelItemStack.java create mode 100644 src/main/java/me/towdium/jecalculation/core/labels/labels/LabelOreDict.java rename src/main/java/me/towdium/jecalculation/core/{entry/entries/EntrySimpleAmount.java => labels/labels/LabelSimpleAmount.java} (57%) diff --git a/src/main/java/me/towdium/jecalculation/client/gui/IDrawable.java b/src/main/java/me/towdium/jecalculation/client/gui/IDrawable.java new file mode 100644 index 0000000..f7e51f4 --- /dev/null +++ b/src/main/java/me/towdium/jecalculation/client/gui/IDrawable.java @@ -0,0 +1,23 @@ +package me.towdium.jecalculation.client.gui; + +import me.towdium.jecalculation.client.gui.JecGui; + +public interface IDrawable { + static int gl(JecGui gui) { + return gui.getGuiLeft(); + } + + static int gt(JecGui gui) { + return gui.getGuiTop(); + } + + void onDraw(JecGui gui, int xMouse, int yMouse); + + default boolean onClicked(JecGui gui, int xMouse, int yMouse, int button) { + return false; + } + + default boolean onKey(JecGui gui, char ch, int code) { + return false; + } +} diff --git a/src/main/java/me/towdium/jecalculation/client/gui/JecGui.java b/src/main/java/me/towdium/jecalculation/client/gui/JecGui.java index 03b598d..2e13d4f 100644 --- a/src/main/java/me/towdium/jecalculation/client/gui/JecGui.java +++ b/src/main/java/me/towdium/jecalculation/client/gui/JecGui.java @@ -2,12 +2,8 @@ package me.towdium.jecalculation.client.gui; import cpw.mods.fml.client.config.GuiUtils; import me.towdium.jecalculation.JustEnoughCalculation; -import me.towdium.jecalculation.client.gui.resource.Resource; -import me.towdium.jecalculation.client.gui.widget.IDrawable; -import me.towdium.jecalculation.client.gui.widget.Widget; -import me.towdium.jecalculation.client.gui.widget.widgets.WEntry; -import me.towdium.jecalculation.client.gui.widget.widgets.WEntryGroup; -import me.towdium.jecalculation.core.entry.Entry; +import me.towdium.jecalculation.client.gui.drawables.DContainer; +import me.towdium.jecalculation.core.labels.ILabel; import me.towdium.jecalculation.nei.NEIPlugin; import me.towdium.jecalculation.polyfill.mc.client.renderer.GlStateManager; import me.towdium.jecalculation.utils.IllegalPositionException; @@ -16,8 +12,6 @@ import me.towdium.jecalculation.utils.wrappers.Single; import me.towdium.jecalculation.utils.wrappers.Triple; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; -import net.minecraft.client.gui.GuiButton; -import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.renderer.RenderHelper; import net.minecraft.client.renderer.Tessellator; @@ -36,7 +30,6 @@ import javax.annotation.ParametersAreNonnullByDefault; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.Optional; import java.util.function.Function; /** @@ -46,48 +39,45 @@ import java.util.function.Function; @ParametersAreNonnullByDefault public class JecGui extends GuiContainer { public static final int COLOR_GREY = 0xFFA1A1A1; - public static final int COLOR_BLUE = 0xFFb0b9e6; - public List buttonList = super.buttonList; - public WidgetManager wgtMgr = new WidgetManager(); - public Entry hand = Entry.EMPTY; - protected GuiScreen parent; + protected static JecGui last; + protected JecGui parent; + public ILabel hand = ILabel.EMPTY; + public DContainer container = new DContainer(); protected List>> tooltipBuffer = new ArrayList<>(); - public JecGui(@Nullable GuiScreen parent) { - this(parent, false); + public JecGui(@Nullable JecGui parent, IDrawable... drawables) { + this(parent, false, drawables); } - public JecGui(@Nullable GuiScreen parent, boolean acceptsTransfer) { + public JecGui(@Nullable JecGui parent, boolean acceptsTransfer, IDrawable... drawables) { super(acceptsTransfer ? new ContainerTransfer() : new ContainerNonTransfer()); this.parent = parent; - } - - @Override - public void initGui() { - super.initGui(); - wgtMgr.onInit(); + container.addAll(drawables); } public static boolean mouseIn(int xPos, int yPos, int xSize, int ySize, int xMouse, int yMouse) { return xMouse > xPos && yMouse > yPos && xMouse <= xPos + xSize && yMouse <= yPos + ySize; } - @Override - public void drawScreen(int mouseX, int mouseY, float partialTicks) { - drawDefaultBackground(); - super.drawScreen(mouseX, mouseY, partialTicks); - GlStateManager.disableLighting(); - GlStateManager.disableDepth(); - wgtMgr.onDraw(mouseX, mouseY); - drawExtra(); - GlStateManager.pushMatrix(); - GlStateManager.translate(mouseX - 8, mouseY - 8, 0); - hand.drawEntry(this); - GlStateManager.popMatrix(); - drawBufferedTooltip(); - GlStateManager.enableLighting(); - GlStateManager.enableDepth(); + public static void displayGui(IDrawable... components) { + displayGui(true, false, components); + } + + public static void displayGui(boolean updateParent, boolean acceptsTransfer, IDrawable... components) { + // isCallingFromMinecraftThread + if (Minecraft.getMinecraft().func_152345_ab()) + displayGuiUnsafe(updateParent, acceptsTransfer, components); + } + + public static void displayGuiUnsafe(boolean updateParent, boolean acceptsTransfer, IDrawable... components) { + Minecraft mc = Minecraft.getMinecraft(); + JecGui parent; + if (mc.currentScreen == null) parent = null; + else if (!(mc.currentScreen instanceof JecGui)) parent = last; + else if (updateParent) parent = (JecGui) mc.currentScreen; + else parent = ((JecGui) mc.currentScreen).parent; + mc.displayGuiScreen(new JecGui(parent, acceptsTransfer, components)); } @Override @@ -97,35 +87,25 @@ public class JecGui extends GuiContainer { @Override protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) { - drawResourceContinuous(Resource.WGT_PANEL, guiLeft, guiTop, xSize, ySize, 5, 5, 5, 5); } @Override - protected void mouseClicked(int mouseX, int mouseY, int mouseButton) { - super.mouseClicked(mouseX, mouseY, mouseButton); - boolean InGui = wgtMgr.onClick(mouseX, mouseY, mouseButton); - if(!InGui) { - this.handleMouseEvent(); - } - } - - @Override - public void handleMouseInput() { - super.handleMouseInput(); - } - - @Override - protected void keyTyped(char typedChar, int keyCode) { - if (!wgtMgr.onKey(typedChar, keyCode)) { - if (keyCode == Keyboard.KEY_ESCAPE) { - if (hand != Entry.EMPTY) - hand = Entry.EMPTY; - else if (parent != null) - Minecraft.getMinecraft().displayGuiScreen(parent); - else - super.keyTyped(typedChar, keyCode); - } - } + public void drawScreen(int mouseX, int mouseY, float partialTicks) { + drawDefaultBackground(); + super.drawScreen(mouseX, mouseY, partialTicks); + GlStateManager.pushMatrix(); + GlStateManager.translate(guiLeft, guiTop, 0); + GlStateManager.disableLighting(); + GlStateManager.disableDepth(); + container.onDraw(this, mouseX - guiLeft, mouseY - guiTop); + GlStateManager.popMatrix(); + GlStateManager.pushMatrix(); + GlStateManager.translate(mouseX - 8, mouseY - 8, 0); + hand.drawEntry(this); + GlStateManager.popMatrix(); + drawBufferedTooltip(); + GlStateManager.enableLighting(); + GlStateManager.enableDepth(); } /** @@ -140,22 +120,21 @@ public class JecGui extends GuiContainer { int yMouse = this.height - Mouse.getEventY() * this.height / this.mc.displayHeight - 1; if (Mouse.getEventButtonState()) { if (Mouse.getEventButton() == 0) { - if (hand == Entry.EMPTY) { - // TODO - Entry e = NEIPlugin.getEntryUnderMouse(); - if (e != Entry.EMPTY) { + if (hand == ILabel.EMPTY) { + ILabel e = NEIPlugin.getEntryUnderMouse(); + if (e != ILabel.EMPTY) { hand = e; return true; } } else { if (!mouseIn(guiLeft, guiTop, width, height, xMouse, yMouse)) { - hand = Entry.EMPTY; + hand = ILabel.EMPTY; return true; } } } else if (Mouse.getEventButton() == 1) { - if (hand != Entry.EMPTY) { - hand = Entry.EMPTY; + if (hand != ILabel.EMPTY) { + hand = ILabel.EMPTY; return true; } } @@ -199,7 +178,8 @@ public class JecGui extends GuiContainer { public void drawFluid(Fluid f, int xPos, int yPos, int xSize, int ySize) { IIcon fluidStillIcon = f.getStillIcon(); mc.renderEngine.bindTexture(TextureMap.locationBlocksTexture); - if (fluidStillIcon != null) drawTexturedModelRectFromIcon(xPos, yPos, fluidStillIcon, xSize, ySize); + if (fluidStillIcon != null) + drawTexturedModelRectFromIcon(xPos, yPos, fluidStillIcon, xSize, ySize); } public void drawTextureContinuous(ResourceLocation l, @@ -221,7 +201,6 @@ public class JecGui extends GuiContainer { } public void drawRectangle(int xPos, int yPos, int xSize, int ySize, int color) { - drawRect(xPos, yPos, xPos + xSize, yPos + ySize, color); float f3 = (float) (color >> 24 & 255) / 255.0F; float f = (float) (color >> 16 & 255) / 255.0F; float f1 = (float) (color >> 8 & 255) / 255.0F; @@ -281,9 +260,12 @@ public class JecGui extends GuiContainer { int l = fontRendererObj.getStringWidth("..."); String[] ss = !f.cut ? text : Arrays.stream(text).map(s -> { int w = fontRendererObj.getStringWidth(s); - if (w <= sizeScaled) return s; - else if (l >= w) return "..."; - else return fontRendererObj.trimStringToWidth(s, (int) (sizeScaled - l)) + "..."; + if (w <= sizeScaled) + return s; + else if (l >= w) + return "..."; + else + return fontRendererObj.trimStringToWidth(s, (int) (sizeScaled - l)) + "..."; }).toArray(String[]::new); switch (f.align) { case LEFT: @@ -307,7 +289,7 @@ public class JecGui extends GuiContainer { } public void drawTooltip(int xPos, int yPos, String... text) { - drawTooltip(xPos, yPos, Arrays.asList(text)); + drawTooltip(xPos + guiLeft, yPos + guiTop, Arrays.asList(text)); } public void drawTooltip(int xPos, int yPos, List text) { @@ -340,11 +322,6 @@ public class JecGui extends GuiContainer { return LocalizationHelper.format(this.getClass(), "gui", key, os); } - // function to override - - protected void drawExtra() { - } - public static class Font { public static final Font DEFAULT_SHADOW = new Font(0xFFFFFF, true, true, false, 1, enumAlign.AUTO); public static final Font DEFAULT_NO_SHADOW = new Font(0x404040, false, true, false, 1, enumAlign.AUTO); @@ -378,6 +355,29 @@ public class JecGui extends GuiContainer { public enum enumAlign {LEFT, CENTRE, RIGHT, AUTO} } + @Override + protected void mouseClicked(int mouseX, int mouseY, int mouseButton) { + super.mouseClicked(mouseX, mouseY, mouseButton); + boolean inGui = container.onClicked(this, mouseX - guiLeft, mouseY - guiTop, mouseButton); + if(!inGui) { + this.handleMouseEvent(); + } + } + + @Override + protected void keyTyped(char typedChar, int keyCode) { + if (!container.onKey(this, typedChar, keyCode)) { + if (keyCode == Keyboard.KEY_ESCAPE) { + if (hand != ILabel.EMPTY) + hand = ILabel.EMPTY; + else if (parent != null) + Minecraft.getMinecraft().displayGuiScreen(parent); + else + super.keyTyped(typedChar, keyCode); + } + } + } + public static boolean isShiftDown() { return Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT); } @@ -396,69 +396,6 @@ public class JecGui extends GuiContainer { } } - - public class WidgetManager { - protected List widgets = new ArrayList<>(); - protected boolean initialized = false; - - public void add(Widget w) { - widgets.add(w); - if (initialized && w instanceof IDrawable) - ((IDrawable) w).onGuiInit(JecGui.this); - } - - public void addAll(Widget... w) { - for (Widget aw : w) - add(aw); - } - - public void remove(Widget w) { - if (widgets.remove(w) && w instanceof IDrawable) ((IDrawable) w).onRemoved(JecGui.this); - } - - public void removeAll(Widget... w) { - for (Widget aw : w) - remove(aw); - } - - public void onInit() { - widgets.stream().filter(w -> w instanceof IDrawable) - .forEach(w -> ((IDrawable) w).onGuiInit(JecGui.this)); - initialized = true; - } - - public void onDraw(int mouseX, int mouseY) { - widgets.forEach(widget -> widget.onDraw(JecGui.this, mouseX, mouseY)); - } - - @SuppressWarnings("UnusedReturnValue") - public boolean onClick(int xMouse, int yMouse, int button) { - for (Widget w : widgets) { - if (w instanceof IDrawable && - ((IDrawable) w).onClicked(JecGui.this, xMouse, yMouse, button)) - return true; - } - return false; - } - - @SuppressWarnings("UnusedReturnValue") - public boolean onKey(char ch, int code) { - return widgets.stream().filter(w -> w instanceof IDrawable) - .anyMatch(w -> ((IDrawable) w).onKey(JecGui.this, ch, code)); - } - - public Optional getEntryAt(int xMouse, int yMouse) { - return widgets.stream().map(w -> { - if (w instanceof WEntryGroup) - return ((WEntryGroup) w).getEntryAt(JecGui.this, xMouse, yMouse); - else if (w instanceof WEntry) - return Optional.ofNullable(((WEntry) w).mouseIn(JecGui.this, xMouse, yMouse) ? ((WEntry) w) : null); - else - return Optional.empty(); - }).filter(Optional::isPresent).findFirst().orElse(Optional.empty()); - } - } - public int getGuiLeft() { return guiLeft; } @@ -474,4 +411,7 @@ public class JecGui extends GuiContainer { public void drawHoveringText(List textLines, int x, int y) { super.drawHoveringText(textLines, x, y, fontRendererObj); } + + public int getXSize() { return xSize; } + public int getYSize() { return ySize; } } diff --git a/src/main/java/me/towdium/jecalculation/client/gui/resource/Resource.java b/src/main/java/me/towdium/jecalculation/client/gui/Resource.java similarity index 94% rename from src/main/java/me/towdium/jecalculation/client/gui/resource/Resource.java rename to src/main/java/me/towdium/jecalculation/client/gui/Resource.java index f8cb71f..4493a29 100644 --- a/src/main/java/me/towdium/jecalculation/client/gui/resource/Resource.java +++ b/src/main/java/me/towdium/jecalculation/client/gui/Resource.java @@ -1,4 +1,4 @@ -package me.towdium.jecalculation.client.gui.resource; +package me.towdium.jecalculation.client.gui; import me.towdium.jecalculation.JustEnoughCalculation; import net.minecraft.util.ResourceLocation; @@ -36,6 +36,8 @@ public class Resource { public static final Resource WGT_ARR_L_N = new Resource(0, 242, 9, 9); public static final Resource WGT_ARR_R_F = new Resource(10, 232, 9, 9); public static final Resource WGT_ARR_R_N = new Resource(10, 242, 9, 9); + public static final Resource WGT_PAGER_F = new Resource(120, 232, 20, 20); + public static final Resource WGT_PAGER_B = new Resource(120, 232, 20, 16); public static final Resource ICN_RECENT_N = new Resource(0, 42, 14, 14); public static final Resource ICN_RECENT_F = new Resource(0, 28, 14, 14); public static final Resource ICN_INPUT_N = new Resource(14, 42, 14, 14); diff --git a/src/main/java/me/towdium/jecalculation/client/gui/drawables/DButton.java b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DButton.java new file mode 100644 index 0000000..8ee901e --- /dev/null +++ b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DButton.java @@ -0,0 +1,92 @@ +package me.towdium.jecalculation.client.gui.drawables; + +import me.towdium.jecalculation.client.gui.JecGui; +import me.towdium.jecalculation.client.gui.Resource; +import me.towdium.jecalculation.client.gui.IDrawable; +import me.towdium.jecalculation.utils.ClientUtils; +import me.towdium.jecalculation.utils.Utilities; + +import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; + +/** + * Author: towdium + * Date: 17-8-17. + */ +@ParametersAreNonnullByDefault +public class DButton implements IDrawable { + protected int xPos, yPos, xSize, ySize; + protected Resource normal, focused; + protected String tooltip, text; + protected Runnable lsnrLeft, lsnrRight; + protected Utilities.Timer timer = new Utilities.Timer(); + + public DButton(int xPos, int yPos, int xSize, int ySize, Resource normal, Resource focused) { + this(xPos, yPos, xSize, ySize, "", normal, focused, null); + } + + public DButton(int xPos, int yPos, int xSize, int ySize, Resource normal, Resource focused, String tooltip) { + this(xPos, yPos, xSize, ySize, "", normal, focused, tooltip); + } + + public DButton(int xPos, int yPos, int xSize, int ySize, String text, + @Nullable Resource normal, @Nullable Resource focused, @Nullable String tooltip) { + this.xPos = xPos; + this.yPos = yPos; + this.xSize = xSize; + this.ySize = ySize; + this.normal = normal; + this.focused = focused; + this.tooltip = tooltip; + this.text = text; + } + + public DButton setListenerLeft(Runnable r) { + lsnrLeft = r; + return this; + } + + public DButton setListenerRight(Runnable r) { + lsnrRight = r; + return this; + } + + @Override + public void onDraw(JecGui gui, int xMouse, int yMouse) { + boolean hovered = JecGui.mouseIn(xPos + 1, yPos + 1, xSize - 2, ySize - 2, xMouse, yMouse); + gui.drawResourceContinuous(hovered ? Resource.WGT_BUTTON_F : Resource.WGT_BUTTON_N, xPos, yPos, + xSize, ySize, 3, 3, 3, 3); + Resource r = hovered ? focused : normal; + if (r != null) + gui.drawResource(r, xPos + (xSize - r.getXSize()) / 2, yPos + (ySize - r.getYSize()) / 2); + if (tooltip != null) { + timer.setState(hovered); + if (timer.getTime() > 500) gui.drawTooltip(xMouse, yMouse, gui.localize("tooltip." + tooltip)); + } + int textColor = hovered ? 16777120 : 0; + int strWidth = gui.getFontRenderer().getStringWidth(text); + int ellipsisWidth = gui.getFontRenderer().getStringWidth("..."); + String str = text; + if (strWidth > xSize - 6 && strWidth > ellipsisWidth) + str = gui.getFontRenderer().trimStringToWidth(text, xSize - 6 - ellipsisWidth).trim() + "..."; + JecGui.Font f = JecGui.Font.DEFAULT_SHADOW.copy(); + f.color = textColor; + gui.drawText(xPos, yPos, xSize, ySize, f, str); + } + + @Override + public boolean onClicked(JecGui gui, int xMouse, int yMouse, int button) { + if (JecGui.mouseIn(xPos + 1, yPos + 1, xSize - 2, ySize - 2, xMouse, yMouse)) { + if (button == 0 && lsnrLeft != null) { + lsnrLeft.run(); + ClientUtils.playClickSound(1.0F); + return true; + } else if (button == 1 && lsnrRight != null) { + lsnrLeft.run(); + ClientUtils.playClickSound(0.8F); + return true; + } + } + return false; + } +} diff --git a/src/main/java/me/towdium/jecalculation/client/gui/drawables/DContainer.java b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DContainer.java new file mode 100644 index 0000000..b0cef0d --- /dev/null +++ b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DContainer.java @@ -0,0 +1,63 @@ +package me.towdium.jecalculation.client.gui.drawables; + +import me.towdium.jecalculation.client.gui.JecGui; +import me.towdium.jecalculation.client.gui.IDrawable; + +import javax.annotation.ParametersAreNonnullByDefault; +import java.util.ArrayList; +import java.util.List; + +/** + * Author: towdium + * Date: 17-9-14. + */ +@ParametersAreNonnullByDefault +public class DContainer implements IDrawable { + protected List widgets = new ArrayList<>(); + protected JecGui gui; + + public void add(IDrawable w) { + widgets.add(w); + } + + public void addAll(IDrawable... w) { + for (IDrawable aw : w) + add(aw); + } + + public void remove(IDrawable w) { + widgets.remove(w); + } + + public void removeAll(IDrawable... w) { + for (IDrawable aw : w) + remove(aw); + } + + public void onDraw(JecGui gui, int mouseX, int mouseY) { + widgets.forEach(widget -> widget.onDraw(gui, mouseX, mouseY)); + } + + public boolean onClicked(JecGui gui, int xMouse, int yMouse, int button) { + for (IDrawable w : widgets) { + if (w.onClicked(gui, xMouse, yMouse, button)) return true; + } + return false; + } + + public boolean onKey(JecGui gui, char ch, int code) { + for (IDrawable w : widgets) { + if (w.onKey(gui, ch, code)) return true; + } + return false; + } + + /*public Optional getEntryAt(int xMouse, int yMouse) { + return drawables.stream().map(w -> { + if (w instanceof DLabelGroup) return ((DLabelGroup) w).getEntryAt(xMouse, yMouse); + else if (w instanceof DLabel) return Optional.ofNullable( + ((DLabel) w).mouseIn(xMouse, yMouse) ? ((DLabel) w) : null); + else return Optional.empty(); + }).filter(Optional::isPresent).findFirst().orElse(Optional.empty()); + }*/ +} diff --git a/src/main/java/me/towdium/jecalculation/client/gui/widget/widgets/WIcon.java b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DIcon.java similarity index 58% rename from src/main/java/me/towdium/jecalculation/client/gui/widget/widgets/WIcon.java rename to src/main/java/me/towdium/jecalculation/client/gui/drawables/DIcon.java index f36aaa6..2ccee70 100644 --- a/src/main/java/me/towdium/jecalculation/client/gui/widget/widgets/WIcon.java +++ b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DIcon.java @@ -1,8 +1,8 @@ -package me.towdium.jecalculation.client.gui.widget.widgets; +package me.towdium.jecalculation.client.gui.drawables; +import me.towdium.jecalculation.client.gui.IDrawable; import me.towdium.jecalculation.client.gui.JecGui; -import me.towdium.jecalculation.client.gui.resource.Resource; -import me.towdium.jecalculation.client.gui.widget.Widget; +import me.towdium.jecalculation.client.gui.Resource; import me.towdium.jecalculation.utils.Utilities.Timer; import javax.annotation.Nullable; @@ -14,17 +14,17 @@ import javax.annotation.ParametersAreNonnullByDefault; * Date: 17-8-18. */ @ParametersAreNonnullByDefault -public class WIcon extends Widget { +public class DIcon implements IDrawable { public int xPos, yPos, xSize, ySize; public Resource normal, focused; Timer timer = new Timer(); public String tooltip; - public WIcon(int xPos, int yPos, int xSize, int ySize, Resource normal, Resource focused) { + public DIcon(int xPos, int yPos, int xSize, int ySize, Resource normal, Resource focused) { this(xPos, yPos, xSize, ySize, normal, focused, null); } - public WIcon(int xPos, int yPos, int xSize, int ySize, + public DIcon(int xPos, int yPos, int xSize, int ySize, Resource normal, Resource focused, @Nullable String tooltip) { this.xPos = xPos; this.yPos = yPos; @@ -37,11 +37,11 @@ public class WIcon extends Widget { @Override public void onDraw(JecGui gui, int xMouse, int yMouse) { - boolean hovered = JecGui.mouseIn(xPos + gl(gui) + (xSize - normal.getXSize()) / 2, - yPos + gt(gui) + (ySize - normal.getYSize()) / 2, normal.getXSize(), normal.getYSize(), xMouse, yMouse); - gui.drawRectangle(xPos + gl(gui), yPos + gt(gui), xSize, ySize, JecGui.COLOR_GREY); + boolean hovered = JecGui.mouseIn(xPos + (xSize - normal.getXSize()) / 2, + yPos + (ySize - normal.getYSize()) / 2, normal.getXSize(), normal.getYSize(), xMouse, yMouse); + gui.drawRectangle(xPos, yPos, xSize, ySize, JecGui.COLOR_GREY); Resource r = hovered ? focused : normal; - gui.drawResource(r, (xSize - r.getXSize()) / 2 + xPos + gl(gui), (ySize - r.getYSize()) / 2 + yPos + gt(gui)); + gui.drawResource(r, (xSize - r.getXSize()) / 2 + xPos, (ySize - r.getYSize()) / 2 + yPos); if (tooltip != null) { timer.setState(hovered); if (timer.getTime() > 500) gui.drawTooltip(xMouse, yMouse, gui.localize("tooltip." + tooltip)); diff --git a/src/main/java/me/towdium/jecalculation/client/gui/drawables/DLabel.java b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DLabel.java new file mode 100644 index 0000000..d9e2c16 --- /dev/null +++ b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DLabel.java @@ -0,0 +1,125 @@ +package me.towdium.jecalculation.client.gui.drawables; + +import me.towdium.jecalculation.client.gui.IDrawable; +import me.towdium.jecalculation.client.gui.JecGui; +import me.towdium.jecalculation.client.gui.Resource; +import me.towdium.jecalculation.core.labels.ILabel; +import me.towdium.jecalculation.utils.IllegalPositionException; + +import javax.annotation.ParametersAreNonnullByDefault; + +/** + * Author: towdium + * Date: 17-8-17. + */ +@ParametersAreNonnullByDefault +public class DLabel implements IDrawable { + static JecGui.Font font; + + static { + font = JecGui.Font.DEFAULT_HALF.copy(); + font.align = JecGui.Font.enumAlign.RIGHT; + } + + public int xPos, yPos, xSize, ySize; + public ILabel ILabel; + public enumMode mode; + + public DLabel(int xPos, int yPos, int xSize, int ySize, enumMode mode) { + this.xPos = xPos; + this.yPos = yPos; + this.xSize = xSize; + this.ySize = ySize; + this.ILabel = ILabel.EMPTY; + this.mode = mode; + } + + public ILabel getILabel() { + return ILabel; + } + + public void setILabel(ILabel ILabel) { + this.ILabel = ILabel; + } + + @Override + public void onDraw(JecGui gui, int xMouse, int yMouse) { + gui.drawResourceContinuous(Resource.WGT_SLOT, xPos, yPos, xSize, ySize, 3, 3, 3, 3); + ILabel.drawEntry(gui, xPos + xSize / 2, yPos + ySize / 2, true); + if (mode == enumMode.RESULT || mode == enumMode.EDITOR) + gui.drawText(xPos + xSize / 2 + 7.5f, + yPos + ySize / 2 + 7 - (int) (font.size * gui.getFontRenderer().FONT_HEIGHT), font, + ILabel.getAmountString()); + if (mouseIn(gui, xMouse, yMouse)) + gui.drawRectangle(xPos + 1, yPos + 1, xSize - 2, ySize - 2, 0x80FFFFFF); + } + + @Override + public boolean onClicked(JecGui gui, int xMouse, int yMouse, int button) { + if (mouseIn(gui, xMouse, yMouse)) { + switch (mode) { + case EDITOR: + if (gui.hand != ILabel.EMPTY) { + ILabel = gui.hand; + gui.hand = ILabel.EMPTY; + return true; + } else if (ILabel != ILabel.EMPTY) { + if (button == 0) { + if (JecGui.isShiftDown()) + ILabel = ILabel.increaseAmountLarge(); + else + ILabel = ILabel.increaseAmount(); + return true; + } else if (button == 1) { + if (JecGui.isShiftDown()) + ILabel = ILabel.decreaseAmountLarge(); + else + ILabel = ILabel.decreaseAmount(); + return true; + } + } else + return false; + case RESULT: + return false; + case PICKER: + if (ILabel != ILabel.EMPTY) { + gui.hand = ILabel.copy(); + return true; + } else + return false; + case SELECTOR: + ILabel = gui.hand; + gui.hand = ILabel.EMPTY; + return true; + default: + throw new IllegalPositionException(); + } + } else + return false; + } + + public boolean mouseIn(JecGui gui, int x, int y) { + int xx = x - xPos; + int yy = y - yPos; + return xx >= 0 && xx < xSize && yy >= 0 && yy < ySize; + } + + public enum enumMode { + /** + * Slots in editor gui. Can use to edit amount. Exact amount displayed. + */ + EDITOR, + /** + * Slots to display calculate/search result. Rounded amount displayed. + */ + RESULT, + /** + * Slots that can pick items from. No amount displayed. + */ + PICKER, + /** + * Slots to select items, eg. in calculate and search gui. No amount displayed. + */ + SELECTOR + } +} diff --git a/src/main/java/me/towdium/jecalculation/client/gui/widget/widgets/WEntryGroup.java b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DLabelGroup.java similarity index 54% rename from src/main/java/me/towdium/jecalculation/client/gui/widget/widgets/WEntryGroup.java rename to src/main/java/me/towdium/jecalculation/client/gui/drawables/DLabelGroup.java index cd02d11..78202ba 100644 --- a/src/main/java/me/towdium/jecalculation/client/gui/widget/widgets/WEntryGroup.java +++ b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DLabelGroup.java @@ -1,7 +1,7 @@ -package me.towdium.jecalculation.client.gui.widget.widgets; +package me.towdium.jecalculation.client.gui.drawables; import me.towdium.jecalculation.client.gui.JecGui; -import me.towdium.jecalculation.client.gui.widget.IDrawable; +import me.towdium.jecalculation.client.gui.IDrawable; import javax.annotation.ParametersAreNonnullByDefault; import java.util.ArrayList; @@ -13,21 +13,16 @@ import java.util.stream.IntStream; * Date: 17-8-17. */ @ParametersAreNonnullByDefault -public class WEntryGroup extends IDrawable { - ArrayList widgets = new ArrayList<>(); +public class DLabelGroup implements IDrawable { + ArrayList widgets = new ArrayList<>(); - public WEntryGroup(int xPos, int yPos, int column, int row, WEntry.enumMode mode) { + public DLabelGroup(int xPos, int yPos, int column, int row, DLabel.enumMode mode) { this(xPos, yPos, column, row, 18, 18, mode); } - public WEntryGroup(int xPos, int yPos, int column, int row, int xSize, int ySize, WEntry.enumMode mode) { + public DLabelGroup(int xPos, int yPos, int column, int row, int xSize, int ySize, DLabel.enumMode mode) { IntStream.range(0, column).forEach(c -> IntStream.range(0, row).forEach(r -> - widgets.add(new WEntry(xPos + c * xSize, yPos + r * ySize, xSize, ySize, mode)))); - } - - @Override - public void onGuiInit(JecGui gui) { - widgets.forEach(w -> w.onGuiInit(gui)); + widgets.add(new DLabel(xPos + c * xSize, yPos + r * ySize, xSize, ySize, mode)))); } @Override @@ -35,17 +30,12 @@ public class WEntryGroup extends IDrawable { widgets.forEach(w -> w.onDraw(gui, xMouse, yMouse)); } - @Override - public void onRemoved(JecGui gui) { - widgets.forEach(w -> w.onRemoved(gui)); - } - @Override public boolean onClicked(JecGui gui, int xMouse, int yMouse, int button) { return widgets.stream().anyMatch(w -> w.onClicked(gui, xMouse, yMouse, button)); } - public Optional getEntryAt(JecGui gui, int xMouse, int yMouse) { + public Optional getEntryAt(JecGui gui, int xMouse, int yMouse) { return widgets.stream().filter(w -> w.mouseIn(gui, xMouse, yMouse)).findFirst(); } } diff --git a/src/main/java/me/towdium/jecalculation/client/gui/drawables/DLine.java b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DLine.java new file mode 100644 index 0000000..6537783 --- /dev/null +++ b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DLine.java @@ -0,0 +1,25 @@ +package me.towdium.jecalculation.client.gui.drawables; + +import me.towdium.jecalculation.client.gui.IDrawable; +import me.towdium.jecalculation.client.gui.JecGui; +import me.towdium.jecalculation.client.gui.Resource; + +import javax.annotation.ParametersAreNonnullByDefault; + +/** + * Author: towdium + * Date: 17-8-18. + */ +@ParametersAreNonnullByDefault +public class DLine implements IDrawable { + public int y; + + public DLine(int y) { + this.y = y; + } + + @Override + public void onDraw(JecGui gui, int xMouse, int yMouse) { + gui.drawResource(Resource.WGT_LINE, 6, y - 1); + } +} diff --git a/src/main/java/me/towdium/jecalculation/client/gui/drawables/DPager.java b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DPager.java new file mode 100644 index 0000000..92e2a0d --- /dev/null +++ b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DPager.java @@ -0,0 +1,45 @@ +package me.towdium.jecalculation.client.gui.drawables; + +import me.towdium.jecalculation.client.gui.JecGui; +import me.towdium.jecalculation.client.gui.Resource; +import me.towdium.jecalculation.client.gui.IDrawable; +import me.towdium.jecalculation.core.labels.ILabel; +import me.towdium.jecalculation.utils.Utilities; + +import javax.annotation.ParametersAreNonnullByDefault; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +/** + * Author: towdium + * Date: 17-8-19. + */ +@ParametersAreNonnullByDefault +public class DPager extends DContainer { + public DPager() { + // TODO + //add(new DPage(0, ILabel.DESERIALIZER.getRecords().stream().filter(r -> r.representation != null).findFirst().get())); + } + + public class DPage implements IDrawable { + protected int index; + protected ILabel.RegistryEditor.Record record; + + public DPage(int index, ILabel.RegistryEditor.Record record) { + this.index = index; + this.record = record; + } + + @Override + public void onDraw(JecGui gui, int xMouse, int yMouse) { + gui.drawResourceContinuous(Resource.WGT_PAGER_B, index * 24, -21, 24, 24, 4, 4, 4, 4); + } + + @Override + public boolean onClicked(JecGui gui, int xMouse, int yMouse, int button) { + return false; + } + } +} diff --git a/src/main/java/me/towdium/jecalculation/client/gui/drawables/DPanel.java b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DPanel.java new file mode 100644 index 0000000..7a1546a --- /dev/null +++ b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DPanel.java @@ -0,0 +1,19 @@ +package me.towdium.jecalculation.client.gui.drawables; + +import me.towdium.jecalculation.client.gui.IDrawable; +import me.towdium.jecalculation.client.gui.JecGui; +import me.towdium.jecalculation.client.gui.Resource; + +import javax.annotation.ParametersAreNonnullByDefault; + +/** + * Author: towdium + * Date: 17-9-15. + */ +@ParametersAreNonnullByDefault +public class DPanel implements IDrawable { + @Override + public void onDraw(JecGui gui, int xMouse, int yMouse) { + gui.drawResourceContinuous(Resource.WGT_PANEL, 0, 0, gui.getXSize(), gui.getYSize(), 5, 5, 5, 5); + } +} diff --git a/src/main/java/me/towdium/jecalculation/client/gui/widget/widgets/WRectangle.java b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DRectangle.java similarity index 61% rename from src/main/java/me/towdium/jecalculation/client/gui/widget/widgets/WRectangle.java rename to src/main/java/me/towdium/jecalculation/client/gui/drawables/DRectangle.java index fbe7046..0715df7 100644 --- a/src/main/java/me/towdium/jecalculation/client/gui/widget/widgets/WRectangle.java +++ b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DRectangle.java @@ -1,7 +1,7 @@ -package me.towdium.jecalculation.client.gui.widget.widgets; +package me.towdium.jecalculation.client.gui.drawables; +import me.towdium.jecalculation.client.gui.IDrawable; import me.towdium.jecalculation.client.gui.JecGui; -import me.towdium.jecalculation.client.gui.widget.Widget; import javax.annotation.ParametersAreNonnullByDefault; @@ -10,10 +10,10 @@ import javax.annotation.ParametersAreNonnullByDefault; * Date: 17-8-22. */ @ParametersAreNonnullByDefault -public class WRectangle extends Widget { +public class DRectangle implements IDrawable { public int xPos, yPos, xSize, ySize, color; - public WRectangle(int xPos, int yPos, int xSize, int ySize, int color) { + public DRectangle(int xPos, int yPos, int xSize, int ySize, int color) { this.xPos = xPos; this.yPos = yPos; this.xSize = xSize; @@ -23,6 +23,6 @@ public class WRectangle extends Widget { @Override public void onDraw(JecGui gui, int xMouse, int yMouse) { - gui.drawRectangle(xPos + gl(gui), yPos + gt(gui), xSize, ySize, color); + gui.drawRectangle(xPos, yPos, xSize, ySize, color); } } diff --git a/src/main/java/me/towdium/jecalculation/client/gui/drawables/DScroll.java b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DScroll.java new file mode 100644 index 0000000..5ce6e90 --- /dev/null +++ b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DScroll.java @@ -0,0 +1,64 @@ +package me.towdium.jecalculation.client.gui.drawables; + +import me.towdium.jecalculation.client.gui.IDrawable; +import me.towdium.jecalculation.client.gui.JecGui; +import me.towdium.jecalculation.client.gui.Resource; +import me.towdium.jecalculation.utils.Utilities.Circulator; + +import javax.annotation.ParametersAreNonnullByDefault; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +/** + * Author: towdium + * Date: 17-8-19. + */ +@ParametersAreNonnullByDefault +public class DScroll implements IDrawable { + public static final int SIZE = 13; + + protected int xPos, xSize, yPos; + protected DButton left, right; + protected DRectangle wRect; + protected DText dText; + protected List keys; + protected Circulator index; + + public DScroll(int xPos, int yPos, int xSize, int total) { + this(xPos, yPos, xSize, IntStream.rangeClosed(1, total) + .mapToObj(i -> i + "/" + total).collect(Collectors.toList())); + } + + public DScroll(int xPos, int yPos, int xSize, List keys) { + this.xPos = xPos; + this.xSize = xSize; + this.yPos = yPos; + this.keys = keys; + left = new DButton(xPos, yPos, SIZE, SIZE, Resource.WGT_ARR_L_N, Resource.WGT_ARR_L_F) + .setListenerLeft(() -> index.prev()); + right = new DButton(xPos + xSize - SIZE, yPos, SIZE, SIZE, + Resource.WGT_ARR_R_N, Resource.WGT_ARR_R_F) + .setListenerLeft(() -> index.next()); + wRect = new DRectangle(xPos + SIZE, yPos, xSize - 2 * SIZE, SIZE, JecGui.COLOR_GREY); + dText = new DText(xPos + SIZE, yPos, xSize - 2 * SIZE, SIZE, JecGui.Font.DEFAULT_SHADOW, + () -> keys.get(index.index())); + index = new Circulator(keys.size()); + } + + @Override + public void onDraw(JecGui gui, int xMouse, int yMouse) { + Stream.of(left, right, wRect, dText).forEach(w -> w.onDraw(gui, xMouse, yMouse)); + } + + @Override + public boolean onClicked(JecGui gui, int xMouse, int yMouse, int button) { + return Stream.of(left, right).anyMatch(w -> w.onClicked(gui, xMouse, yMouse, button)); + } + + @Override + public boolean onKey(JecGui gui, char ch, int code) { + return Stream.of(left, right).anyMatch(w -> w.onKey(gui, ch, code)); + } +} diff --git a/src/main/java/me/towdium/jecalculation/client/gui/widget/widgets/WText.java b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DText.java similarity index 57% rename from src/main/java/me/towdium/jecalculation/client/gui/widget/widgets/WText.java rename to src/main/java/me/towdium/jecalculation/client/gui/drawables/DText.java index 1d3a98f..7fa09f9 100644 --- a/src/main/java/me/towdium/jecalculation/client/gui/widget/widgets/WText.java +++ b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DText.java @@ -1,7 +1,7 @@ -package me.towdium.jecalculation.client.gui.widget.widgets; +package me.towdium.jecalculation.client.gui.drawables; +import me.towdium.jecalculation.client.gui.IDrawable; import me.towdium.jecalculation.client.gui.JecGui; -import me.towdium.jecalculation.client.gui.widget.Widget; import javax.annotation.ParametersAreNonnullByDefault; import java.util.function.Supplier; @@ -11,35 +11,35 @@ import java.util.function.Supplier; * Date: 17-8-21. */ @ParametersAreNonnullByDefault -public class WText extends Widget { +public class DText implements IDrawable { public static final int UNDEFINED = Integer.MAX_VALUE; public int xPos, yPos, xSize, ySize; public JecGui.Font font; public Supplier key; - public WText(int xPos, int yPos, JecGui.Font font, String key) { + public DText(int xPos, int yPos, JecGui.Font font, String key) { this(xPos, yPos, UNDEFINED, UNDEFINED, font, key); } - public WText(int xPos, int yPos, JecGui.Font font, Supplier key) { + public DText(int xPos, int yPos, JecGui.Font font, Supplier key) { this(xPos, yPos, UNDEFINED, UNDEFINED, font, key); } - public WText(int xPos, int yPos, int xSize, JecGui.Font font, String key) { + public DText(int xPos, int yPos, int xSize, JecGui.Font font, String key) { this(xPos, yPos, xSize, UNDEFINED, font, key); } - public WText(int xPos, int yPos, int xSize, JecGui.Font font, Supplier key) { + public DText(int xPos, int yPos, int xSize, JecGui.Font font, Supplier key) { this(xPos, yPos, xSize, UNDEFINED, font, key); } - public WText(int xPos, int yPos, int xSize, int ySize, JecGui.Font font, String key) { + public DText(int xPos, int yPos, int xSize, int ySize, JecGui.Font font, String key) { this(xPos, yPos, xSize, UNDEFINED, font, () -> key); } - public WText(int xPos, int yPos, int xSize, int ySize, JecGui.Font font, Supplier key) { + public DText(int xPos, int yPos, int xSize, int ySize, JecGui.Font font, Supplier key) { this.xPos = xPos; this.yPos = yPos; this.xSize = xSize; @@ -50,11 +50,9 @@ public class WText extends Widget { @Override public void onDraw(JecGui gui, int xMouse, int yMouse) { - int gl = gl(gui); - int gt = gt(gui); String[] text = key.get().split("\n"); - if (xSize == UNDEFINED) gui.drawText(xPos + gl, yPos + gt, font, text); - else if (ySize == UNDEFINED) gui.drawText(xPos + gl, yPos + gt, xSize, font, text); - else gui.drawText(xPos + gl, yPos + gt, xSize, ySize, font, text); + if (xSize == UNDEFINED) gui.drawText(xPos, yPos, font, text); + else if (ySize == UNDEFINED) gui.drawText(xPos, yPos, xSize, font, text); + else gui.drawText(xPos, yPos, xSize, ySize, font, text); } } diff --git a/src/main/java/me/towdium/jecalculation/client/gui/widget/widgets/WTextField.java b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DTextField.java similarity index 70% rename from src/main/java/me/towdium/jecalculation/client/gui/widget/widgets/WTextField.java rename to src/main/java/me/towdium/jecalculation/client/gui/drawables/DTextField.java index 2e94929..7bfca28 100644 --- a/src/main/java/me/towdium/jecalculation/client/gui/widget/widgets/WTextField.java +++ b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DTextField.java @@ -1,7 +1,8 @@ -package me.towdium.jecalculation.client.gui.widget.widgets; +package me.towdium.jecalculation.client.gui.drawables; import me.towdium.jecalculation.client.gui.JecGui; -import me.towdium.jecalculation.client.gui.widget.IDrawable; +import me.towdium.jecalculation.client.gui.IDrawable; +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiTextField; import javax.annotation.ParametersAreNonnullByDefault; @@ -11,20 +12,14 @@ import javax.annotation.ParametersAreNonnullByDefault; * Date: 17-8-18. */ @ParametersAreNonnullByDefault -public class WTextField extends IDrawable { +public class DTextField implements IDrawable { protected int xPos, yPos, xSize; GuiTextField textField; - - public WTextField(int xPos, int yPos, int xSize) { + public DTextField(int xPos, int yPos, int xSize) { this.xPos = xPos; this.yPos = yPos; this.xSize = xSize; - } - - @Override - public void onGuiInit(JecGui gui) { - textField = new GuiTextField(gui.getFontRenderer(), xPos + gui.getGuiLeft() + 1, yPos + gui.getGuiTop() + 1, - xSize - 2, 18); + textField = new GuiTextField(Minecraft.getMinecraft().fontRenderer, xPos + 1, yPos + 1, xSize - 2, 18); } @Override diff --git a/src/main/java/me/towdium/jecalculation/client/gui/guis/GuiCalculator.java b/src/main/java/me/towdium/jecalculation/client/gui/guis/GuiCalculator.java index 79d4ab5..264ff3a 100644 --- a/src/main/java/me/towdium/jecalculation/client/gui/guis/GuiCalculator.java +++ b/src/main/java/me/towdium/jecalculation/client/gui/guis/GuiCalculator.java @@ -1,34 +1,32 @@ package me.towdium.jecalculation.client.gui.guis; import me.towdium.jecalculation.client.gui.JecGui; -import me.towdium.jecalculation.client.gui.resource.Resource; -import me.towdium.jecalculation.client.gui.widget.widgets.*; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiScreen; +import me.towdium.jecalculation.client.gui.Resource; +import me.towdium.jecalculation.client.gui.drawables.*; -import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; -import static me.towdium.jecalculation.client.gui.widget.widgets.WEntry.enumMode.*; +import static me.towdium.jecalculation.client.gui.drawables.DLabel.enumMode.*; /** * Author: towdium * Date: 8/14/17. */ @ParametersAreNonnullByDefault -public class GuiCalculator extends JecGui { - public GuiCalculator(@Nullable GuiScreen parent) { - super(parent, true); - wgtMgr.add(new WButtonIcon(7, 7, 20, 20, Resource.BTN_LABEL_N, Resource.BTN_LABEL_F, "label")); - wgtMgr.add(new WButtonIcon(130, 7, 20, 20, Resource.BTN_NEW_N, Resource.BTN_NEW_F, "recipe") - .setListenerLeft(() -> Minecraft.getMinecraft().displayGuiScreen(new GuiEditor(this)))); - wgtMgr.add(new WButtonIcon(149, 7, 20, 20, Resource.BTN_SEARCH_N, Resource.BTN_SEARCH_F, "search")); - wgtMgr.add(new WEntryGroup(7, 87, 9, 4, RESULT)); - wgtMgr.add(new WEntryGroup(7, 31, 8, 1, PICKER)); - wgtMgr.add(new WEntry(31, 7, 20, 20, SELECTOR)); - wgtMgr.add(new WLine(52)); - wgtMgr.add(new WTextField(61, 7, 64)); - wgtMgr.add(new WIcon(151, 31, 18, 18, Resource.ICN_RECENT_N, Resource.ICN_RECENT_F, "history")); - wgtMgr.add(new WPager(7, 56, 162, 5)); +public class GuiCalculator extends DContainer { + public GuiCalculator() { + add(new DPanel()); + add(new DTextField(61, 7, 64)); + add(new DButton(7, 7, 20, 20, Resource.BTN_LABEL_N, Resource.BTN_LABEL_F, "label") + .setListenerLeft(() -> JecGui.displayGui(new GuiLabelPicker()))); + add(new DButton(130, 7, 20, 20, Resource.BTN_NEW_N, Resource.BTN_NEW_F, "recipe") + .setListenerLeft(() -> JecGui.displayGui(new GuiEditor()))); + add(new DButton(149, 7, 20, 20, Resource.BTN_SEARCH_N, Resource.BTN_SEARCH_F, "search")); + add(new DLabelGroup(7, 87, 9, 4, RESULT)); + add(new DLabelGroup(7, 31, 8, 1, PICKER)); + add(new DLabel(31, 7, 20, 20, SELECTOR)); + add(new DLine(52)); + add(new DIcon(151, 31, 18, 18, Resource.ICN_RECENT_N, Resource.ICN_RECENT_F, "history")); + add(new DScroll(7, 56, 162, 5)); } } diff --git a/src/main/java/me/towdium/jecalculation/client/gui/guis/GuiEditor.java b/src/main/java/me/towdium/jecalculation/client/gui/guis/GuiEditor.java index 972c6e7..f4215ff 100644 --- a/src/main/java/me/towdium/jecalculation/client/gui/guis/GuiEditor.java +++ b/src/main/java/me/towdium/jecalculation/client/gui/guis/GuiEditor.java @@ -1,50 +1,46 @@ package me.towdium.jecalculation.client.gui.guis; -import me.towdium.jecalculation.client.gui.JecGui; -import me.towdium.jecalculation.client.gui.resource.Resource; -import me.towdium.jecalculation.client.gui.widget.widgets.*; -import net.minecraft.client.gui.GuiScreen; +import me.towdium.jecalculation.client.gui.Resource; +import me.towdium.jecalculation.client.gui.drawables.*; -import javax.annotation.Nullable; - -import static me.towdium.jecalculation.client.gui.widget.widgets.WEntry.enumMode.EDITOR; +import static me.towdium.jecalculation.client.gui.drawables.DLabel.enumMode.EDITOR; /** * Author: towdium * Date: 17-9-8. */ -public class GuiEditor extends JecGui { - WButtonIcon buttonSave = new WButtonIcon(26, 33, 20, 20, Resource.BTN_SAVE_N, Resource.BTN_SAVE_F, "save"); - WButtonIcon buttonCopy = new WButtonIcon(83, 33, 20, 20, Resource.BTN_COPY_N, Resource.BTN_COPY_F, "copy"); - WButtonIcon buttonDel = new WButtonIcon(64, 33, 20, 20, Resource.BTN_DEL_N, Resource.BTN_DEL_F, "clear"); - WButtonIcon buttonLabel = new WButtonIcon(45, 33, 20, 20, Resource.BTN_LABEL_N, Resource.BTN_LABEL_F, "label"); - WButtonIcon buttonYes = new WButtonIcon(7, 33, 20, 20, Resource.BTN_YES_N, Resource.BTN_YES_F, "confirm"); - WButtonIcon buttonNo = new WButtonIcon(26, 33, 20, 20, Resource.BTN_NO_N, Resource.BTN_NO_F, "abort"); - WEntryGroup groupInput = new WEntryGroup(28, 111, 7, 2, 20, 20, EDITOR); - WEntryGroup groupCatalyst = new WEntryGroup(28, 87, 7, 1, 20, 20, EDITOR); - WEntryGroup groupOutput = new WEntryGroup(28, 63, 7, 1, 20, 20, EDITOR); - WTextField textField = new WTextField(49, 33, 119); - WButtonIcon buttonNew = new WButtonIcon(7, 33, 20, 20, Resource.BTN_NEW_N, Resource.BTN_NEW_F, "new") +public class GuiEditor extends DContainer { + DButton buttonSave = new DButton(26, 33, 20, 20, Resource.BTN_SAVE_N, Resource.BTN_SAVE_F, "save"); + DButton buttonCopy = new DButton(83, 33, 20, 20, Resource.BTN_COPY_N, Resource.BTN_COPY_F, "copy"); + DButton buttonDel = new DButton(64, 33, 20, 20, Resource.BTN_DEL_N, Resource.BTN_DEL_F, "clear"); + DButton buttonLabel = new DButton(45, 33, 20, 20, Resource.BTN_LABEL_N, Resource.BTN_LABEL_F, "label"); + DButton buttonYes = new DButton(7, 33, 20, 20, Resource.BTN_YES_N, Resource.BTN_YES_F, "confirm"); + DButton buttonNo = new DButton(26, 33, 20, 20, Resource.BTN_NO_N, Resource.BTN_NO_F, "abort"); + DLabelGroup groupInput = new DLabelGroup(28, 111, 7, 2, 20, 20, EDITOR); + DLabelGroup groupCatalyst = new DLabelGroup(28, 87, 7, 1, 20, 20, EDITOR); + DLabelGroup groupOutput = new DLabelGroup(28, 63, 7, 1, 20, 20, EDITOR); + DTextField textField = new DTextField(49, 33, 119); + DButton buttonNew = new DButton(7, 33, 20, 20, Resource.BTN_NEW_N, Resource.BTN_NEW_F, "new") .setListenerLeft(() -> setModeNewGroup(true)); - public GuiEditor(@Nullable GuiScreen parent) { - super(parent); - wgtMgr.add(new WPager(7, 7, 162, 2)); - wgtMgr.add(new WIcon(7, 63, 21, 20, Resource.ICN_OUTPUT_N, Resource.ICN_OUTPUT_F, "output")); - wgtMgr.add(new WIcon(7, 87, 21, 20, Resource.ICN_CATALYST_N, Resource.ICN_CATALYST_F, "catalyst")); - wgtMgr.add(new WIcon(7, 111, 21, 40, Resource.ICN_INPUT_N, Resource.ICN_INPUT_F, "input")); - wgtMgr.add(new WLine(57)); - wgtMgr.addAll(groupInput, groupCatalyst, groupOutput); + public GuiEditor() { + add(new DPanel()); + add(new DScroll(7, 7, 162, 2)); + add(new DIcon(7, 63, 21, 20, Resource.ICN_OUTPUT_N, Resource.ICN_OUTPUT_F, "output")); + add(new DIcon(7, 87, 21, 20, Resource.ICN_CATALYST_N, Resource.ICN_CATALYST_F, "catalyst")); + add(new DIcon(7, 111, 21, 40, Resource.ICN_INPUT_N, Resource.ICN_INPUT_F, "input")); + add(new DLine(57)); + addAll(groupInput, groupCatalyst, groupOutput); setModeNewGroup(false); } public void setModeNewGroup(boolean b) { if (b) { - wgtMgr.removeAll(buttonNew, buttonLabel, buttonDel, buttonCopy, buttonSave); - wgtMgr.addAll(buttonYes, buttonNo, textField); + removeAll(buttonNew, buttonLabel, buttonDel, buttonCopy, buttonSave); + addAll(buttonYes, buttonNo, textField); } else { - wgtMgr.addAll(buttonNew, buttonLabel, buttonDel, buttonSave); // TODO buttonCopy - wgtMgr.removeAll(buttonYes, buttonNo, textField); + addAll(buttonNew, buttonLabel, buttonDel, buttonSave); // TODO buttonCopy + removeAll(buttonYes, buttonNo, textField); } } } diff --git a/src/main/java/me/towdium/jecalculation/client/gui/guis/GuiLabelPicker.java b/src/main/java/me/towdium/jecalculation/client/gui/guis/GuiLabelPicker.java new file mode 100644 index 0000000..8909cbc --- /dev/null +++ b/src/main/java/me/towdium/jecalculation/client/gui/guis/GuiLabelPicker.java @@ -0,0 +1,16 @@ +package me.towdium.jecalculation.client.gui.guis; + +import me.towdium.jecalculation.client.gui.drawables.DContainer; +import me.towdium.jecalculation.client.gui.drawables.DPager; +import me.towdium.jecalculation.client.gui.drawables.DPanel; + +/** + * Author: towdium + * Date: 17-9-14. + */ +public class GuiLabelPicker extends DContainer { + public GuiLabelPicker() { + add(new DPager()); + add(new DPanel()); + } +} diff --git a/src/main/java/me/towdium/jecalculation/client/gui/widget/IDrawable.java b/src/main/java/me/towdium/jecalculation/client/gui/widget/IDrawable.java deleted file mode 100644 index 43c04f4..0000000 --- a/src/main/java/me/towdium/jecalculation/client/gui/widget/IDrawable.java +++ /dev/null @@ -1,19 +0,0 @@ -package me.towdium.jecalculation.client.gui.widget; - -import me.towdium.jecalculation.client.gui.JecGui; - -public class IDrawable extends Widget { - public void onRemoved(JecGui gui) { - } - - public boolean onClicked(JecGui gui, int xMouse, int yMouse, int button) { - return false; - } - - public boolean onKey(JecGui gui, char ch, int code) { - return false; - } - - public void onGuiInit(JecGui gui) { - } -} diff --git a/src/main/java/me/towdium/jecalculation/client/gui/widget/Widget.java b/src/main/java/me/towdium/jecalculation/client/gui/widget/Widget.java deleted file mode 100644 index 728dd2d..0000000 --- a/src/main/java/me/towdium/jecalculation/client/gui/widget/Widget.java +++ /dev/null @@ -1,26 +0,0 @@ -package me.towdium.jecalculation.client.gui.widget; - -import me.towdium.jecalculation.client.gui.JecGui; -import net.minecraft.client.gui.Gui; - -import javax.annotation.ParametersAreNonnullByDefault; - -/** - * Author: towdium - * Date: 8/14/17. - */ -@ParametersAreNonnullByDefault -public class Widget extends Gui { - protected static int gl(JecGui gui) { - return gui.getGuiLeft(); - } - - protected static int gt(JecGui gui) { - return gui.getGuiTop(); - } - - public void onDraw(JecGui gui, int xMouse, int yMouse) { - } - - -} diff --git a/src/main/java/me/towdium/jecalculation/client/gui/widget/widgets/WButton.java b/src/main/java/me/towdium/jecalculation/client/gui/widget/widgets/WButton.java deleted file mode 100644 index 6538532..0000000 --- a/src/main/java/me/towdium/jecalculation/client/gui/widget/widgets/WButton.java +++ /dev/null @@ -1,104 +0,0 @@ -package me.towdium.jecalculation.client.gui.widget.widgets; - -import cpw.mods.fml.client.config.GuiButtonExt; -import me.towdium.jecalculation.client.gui.JecGui; -import me.towdium.jecalculation.client.gui.widget.IDrawable; -import me.towdium.jecalculation.utils.ClientUtils; -import me.towdium.jecalculation.utils.Utilities; -import net.minecraft.client.Minecraft; - -import javax.annotation.Nullable; -import javax.annotation.ParametersAreNonnullByDefault; - -/** - * Author: towdium - * Date: 8/14/17. - */ -@ParametersAreNonnullByDefault -public class WButton extends IDrawable { - protected int xPos, yPos, xSize, ySize; - public Runnable lsnrLeft, lsnrRight; - public String text, tooltip; - protected GuiButtonExt button; - protected Utilities.Timer timer = new Utilities.Timer(); - - public WButton(int xPos, int yPos, int xSize, int ySize, String text) { - this(xPos, yPos, xSize, ySize, text, null); - } - - public WButton(int xPos, int yPos, int xSize, int ySize, String text, @Nullable String tooltip) { - this.xPos = xPos; - this.yPos = yPos; - this.xSize = xSize; - this.ySize = ySize; - this.text = text; - this.tooltip = tooltip; - } - - public WButton setListenerLeft(Runnable r) { - lsnrLeft = r; - return this; - } - - public WButton setListenerRight(Runnable r) { - lsnrRight = r; - return this; - } - - public boolean isEnabled() { - return button.enabled; - } - - public WButton setEnabled(boolean e) { - button.enabled = e; - return this; - } - - protected static boolean mouseIn(GuiButtonExt button, int x, int y) { - return button.enabled && button.visible && - JecGui.mouseIn(button.xPosition, button.yPosition, button.width, button.height, x, y); - } - - - @Override - public void onGuiInit(JecGui gui) { - super.onGuiInit(gui); - button = new GuiButtonExt(0, xPos + gui.getGuiLeft(), yPos + gui.getGuiTop(), xSize, ySize, text) { - @Override - public boolean mousePressed(Minecraft mc, int mouseX, int mouseY) { - return false; - } - }; - gui.buttonList.add(button); - } - - @Override - public boolean onClicked(JecGui gui, int xMouse, int yMouse, int button) { - if (mouseIn(this.button, xMouse, yMouse) && isEnabled()) { - if (button == 0 && lsnrLeft != null) { - lsnrLeft.run(); - ClientUtils.playClickSound(1.0F); - return true; - } else if (button == 1 && lsnrRight != null) { - lsnrLeft.run(); - ClientUtils.playClickSound(0.8F); - return true; - } - } - return false; - } - - @Override - public void onRemoved(JecGui gui) { - gui.buttonList.remove(button); - } - - @Override - public void onDraw(JecGui gui, int xMouse, int yMouse) { - if (tooltip != null) { - boolean hovered = JecGui.mouseIn(xPos + gl(gui), yPos + gt(gui), xSize, ySize, xMouse, yMouse); - timer.setState(hovered); - if (timer.getTime() > 500) gui.drawTooltip(xMouse, yMouse, gui.localize("tooltip." + tooltip)); - } - } -} diff --git a/src/main/java/me/towdium/jecalculation/client/gui/widget/widgets/WButtonIcon.java b/src/main/java/me/towdium/jecalculation/client/gui/widget/widgets/WButtonIcon.java deleted file mode 100644 index e469540..0000000 --- a/src/main/java/me/towdium/jecalculation/client/gui/widget/widgets/WButtonIcon.java +++ /dev/null @@ -1,80 +0,0 @@ -package me.towdium.jecalculation.client.gui.widget.widgets; - -import cpw.mods.fml.client.config.GuiButtonExt; -import me.towdium.jecalculation.client.gui.JecGui; -import me.towdium.jecalculation.client.gui.resource.Resource; -import net.minecraft.client.Minecraft; - -import javax.annotation.Nullable; -import javax.annotation.ParametersAreNonnullByDefault; - -/** - * Author: towdium - * Date: 17-8-17. - */ -@ParametersAreNonnullByDefault -public class WButtonIcon extends WButton { - protected int xPos, yPos, xSize, ySize; - protected Resource normal, focused; - - public WButtonIcon(int xPos, int yPos, int xSize, int ySize, Resource normal, Resource focused) { - this(xPos, yPos, xSize, ySize, normal, focused, null); - } - - public WButtonIcon(int xPos, - int yPos, - int xSize, - int ySize, - Resource normal, - Resource focused, - @Nullable String tooltip) { - super(xPos, yPos, xSize, ySize, "", tooltip); - this.xPos = xPos; - this.yPos = yPos; - this.xSize = xSize; - this.ySize = ySize; - this.normal = normal; - this.focused = focused; - } - - @Override - public void onGuiInit(JecGui gui) { - button = new GuiButtonExt(0, xPos + gui.getGuiLeft(), yPos + gui.getGuiTop(), xSize, ySize, "") { - @Override - public void drawButton(Minecraft mc, int mouseX, int mouseY) { - final int x = this.xPosition; - final int y = this.yPosition; - boolean hovered = mouseX > x + 1 && mouseY > y + 1 && mouseX <= x + width - 1 && mouseY <= y + height - 1; - this.field_146123_n = hovered; - gui.drawResourceContinuous(hovered ? Resource.WGT_BUTTON_F : Resource.WGT_BUTTON_N, x, y, width, height, - 3, 3, 3, 3); - Resource r = hovered ? focused : normal; - gui.drawResource(r, x + (width - r.getXSize()) / 2, y + (height - r.getYSize()) / 2); - } - - @Override - public boolean mousePressed(Minecraft mc, int mouseX, int mouseY) { - return false; - } - }; - gui.buttonList.add(button); - } - - public WButtonIcon setListenerLeft(Runnable r) { - return ((WButtonIcon) super.setListenerLeft(r)); - } - - public WButtonIcon setListenerRight(Runnable r) { - return ((WButtonIcon) super.setListenerRight(r)); - } - - @Override - public boolean isEnabled() { - return true; - } - - public WButtonIcon setEnabled(boolean e) { - if (!e) throw new RuntimeException("Unsupported"); - else return this; - } -} diff --git a/src/main/java/me/towdium/jecalculation/client/gui/widget/widgets/WEntry.java b/src/main/java/me/towdium/jecalculation/client/gui/widget/widgets/WEntry.java deleted file mode 100644 index 7eb0119..0000000 --- a/src/main/java/me/towdium/jecalculation/client/gui/widget/widgets/WEntry.java +++ /dev/null @@ -1,124 +0,0 @@ -package me.towdium.jecalculation.client.gui.widget.widgets; - -import me.towdium.jecalculation.client.gui.JecGui; -import me.towdium.jecalculation.client.gui.resource.Resource; -import me.towdium.jecalculation.client.gui.widget.IDrawable; -import me.towdium.jecalculation.core.entry.Entry; -import me.towdium.jecalculation.polyfill.mc.client.renderer.GlStateManager; -import me.towdium.jecalculation.utils.IllegalPositionException; - -import javax.annotation.ParametersAreNonnullByDefault; - -/** - * Author: towdium - * Date: 17-8-17. - */ -@ParametersAreNonnullByDefault -public class WEntry extends IDrawable { - static JecGui.Font font; - - static { - font = JecGui.Font.DEFAULT_HALF.copy(); - font.align = JecGui.Font.enumAlign.RIGHT; - } - - - public int xPos, yPos, xSize, ySize; - public Entry entry; - public enumMode mode; - - public WEntry(int xPos, int yPos, int xSize, int ySize, enumMode mode) { - this.xPos = xPos; - this.yPos = yPos; - this.xSize = xSize; - this.ySize = ySize; - this.entry = Entry.EMPTY; - this.mode = mode; - } - - public Entry getEntry() { - return entry; - } - - public void setEntry(Entry entry) { - this.entry = entry; - } - - @Override - public void onDraw(JecGui gui, int xMouse, int yMouse) { - gui.drawResourceContinuous(Resource.WGT_SLOT, xPos + gui.getGuiLeft(), yPos + gui.getGuiTop(), xSize, ySize, - 3, 3, 3, 3); - GlStateManager.pushMatrix(); - GlStateManager.translate(xPos + gl(gui) + xSize / 2 - 8, yPos + gt(gui) + ySize / 2 - 8, 0); - entry.drawEntry(gui); - GlStateManager.popMatrix(); - if (mode == enumMode.RESULT || mode == enumMode.EDITOR) - gui.drawText(gl(gui) + xPos + xSize / 2 + 7.5f, gt(gui) + yPos + ySize / 2 + 7 - - (int) (font.size * gui.getFontRenderer().FONT_HEIGHT), font, entry.getAmountString()); - if (mouseIn(gui, xMouse, yMouse)) - gui.drawRectangle(gui.getGuiLeft() + xPos + 1, gui.getGuiTop() + yPos + 1, xSize - 2, ySize - 2, - 0x80FFFFFF); - } - - @Override - public boolean onClicked(JecGui gui, int xMouse, int yMouse, int button) { - if (mouseIn(gui, xMouse, yMouse)) { - switch (mode) { - case EDITOR: - if (gui.hand != Entry.EMPTY) { - entry = gui.hand; - gui.hand = Entry.EMPTY; - return true; - } else if (entry != Entry.EMPTY) { - if (button == 0) { - if (JecGui.isShiftDown()) entry = entry.increaseAmountLarge(); - else entry = entry.increaseAmount(); - return true; - } else if (button == 1) { - if (JecGui.isShiftDown()) entry = entry.decreaseAmountLarge(); - else entry = entry.decreaseAmount(); - return true; - } - } else return false; - case RESULT: - return false; - case PICKER: - if (entry != Entry.EMPTY) { - gui.hand = entry.copy(); - return true; - } else return false; - case SELECTOR: - entry = gui.hand; - gui.hand = Entry.EMPTY; - return true; - default: - throw new IllegalPositionException(); - } - } else return false; - } - - public boolean mouseIn(JecGui gui, int x, int y) { - int xx = x - gui.getGuiLeft() - xPos; - int yy = y - gui.getGuiTop() - yPos; - return xx >= 0 && xx < xSize && yy >= 0 && yy < ySize; - } - - public enum enumMode { - /** - * Slots in editor gui. Can use to edit amount. Exact amount displayed. - */ - EDITOR, - /** - * Slots to display calculate/search result. Rounded amount displayed. - */ - RESULT, - /** - * Slots that can pick items from. No amount displayed. - */ - PICKER, - /** - * Slots to select items, eg. in calculate and search gui. No amount displayed. - */ - SELECTOR - } -} diff --git a/src/main/java/me/towdium/jecalculation/client/gui/widget/widgets/WLine.java b/src/main/java/me/towdium/jecalculation/client/gui/widget/widgets/WLine.java deleted file mode 100644 index 8fc437b..0000000 --- a/src/main/java/me/towdium/jecalculation/client/gui/widget/widgets/WLine.java +++ /dev/null @@ -1,25 +0,0 @@ -package me.towdium.jecalculation.client.gui.widget.widgets; - -import me.towdium.jecalculation.client.gui.JecGui; -import me.towdium.jecalculation.client.gui.resource.Resource; -import me.towdium.jecalculation.client.gui.widget.Widget; - -import javax.annotation.ParametersAreNonnullByDefault; - -/** - * Author: towdium - * Date: 17-8-18. - */ -@ParametersAreNonnullByDefault -public class WLine extends Widget { - public int y; - - public WLine(int y) { - this.y = y; - } - - @Override - public void onDraw(JecGui gui, int xMouse, int yMouse) { - gui.drawResource(Resource.WGT_LINE, 6 + gui.getGuiLeft(), y + gui.getGuiTop() - 1); - } -} diff --git a/src/main/java/me/towdium/jecalculation/client/gui/widget/widgets/WPager.java b/src/main/java/me/towdium/jecalculation/client/gui/widget/widgets/WPager.java deleted file mode 100644 index 2d38c75..0000000 --- a/src/main/java/me/towdium/jecalculation/client/gui/widget/widgets/WPager.java +++ /dev/null @@ -1,73 +0,0 @@ -package me.towdium.jecalculation.client.gui.widget.widgets; - -import me.towdium.jecalculation.client.gui.JecGui; -import me.towdium.jecalculation.client.gui.resource.Resource; -import me.towdium.jecalculation.client.gui.widget.IDrawable; -import me.towdium.jecalculation.utils.Utilities; - -import javax.annotation.ParametersAreNonnullByDefault; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.IntStream; -import java.util.stream.Stream; - -/** - * Author: towdium - * Date: 17-8-19. - */ -@ParametersAreNonnullByDefault -public class WPager extends IDrawable { - public static final int SIZE = 13; - - protected int xPos, xSize, yPos; - protected WButtonIcon left, right; - protected WRectangle wRect; - protected WText wText; - protected List keys; - protected Utilities.Circulator index; - - public WPager(int xPos, int yPos, int xSize, int total) { - this(xPos, yPos, xSize, - IntStream.rangeClosed(1, total).mapToObj(i -> i + "/" + total).collect(Collectors.toList())); - } - - public WPager(int xPos, int yPos, int xSize, List keys) { - this.xPos = xPos; - this.xSize = xSize; - this.yPos = yPos; - this.keys = keys; - left = new WButtonIcon(xPos, yPos, SIZE, SIZE, Resource.WGT_ARR_L_N, Resource.WGT_ARR_L_F) - .setListenerLeft(() -> index.prev()); - right = new WButtonIcon(xPos + xSize - SIZE, yPos, SIZE, SIZE, Resource.WGT_ARR_R_N, Resource.WGT_ARR_R_F) - .setListenerLeft(() -> index.next()); - wRect = new WRectangle(xPos + SIZE, yPos, xSize - 2 * SIZE, SIZE, JecGui.COLOR_GREY); - wText = new WText(xPos + SIZE, yPos, xSize - 2 * SIZE, SIZE, JecGui.Font.DEFAULT_SHADOW, - () -> keys.get(index.index())); - index = new Utilities.Circulator(keys.size()); - } - - @Override - public void onGuiInit(JecGui gui) { - Stream.of(left, right).forEach(w -> w.onGuiInit(gui)); - } - - @Override - public void onDraw(JecGui gui, int xMouse, int yMouse) { - Stream.of(left, right, wRect, wText).forEach(w -> w.onDraw(gui, xMouse, yMouse)); - } - - @Override - public void onRemoved(JecGui gui) { - Stream.of(left, right).forEach(w -> w.onRemoved(gui)); - } - - @Override - public boolean onClicked(JecGui gui, int xMouse, int yMouse, int button) { - return Stream.of(left, right).anyMatch(w -> w.onClicked(gui, xMouse, yMouse, button)); - } - - @Override - public boolean onKey(JecGui gui, char ch, int code) { - return Stream.of(left, right).anyMatch(w -> w.onKey(gui, ch, code)); - } -} diff --git a/src/main/java/me/towdium/jecalculation/core/entry/Entry.java b/src/main/java/me/towdium/jecalculation/core/entry/Entry.java deleted file mode 100644 index 90723d1..0000000 --- a/src/main/java/me/towdium/jecalculation/core/entry/Entry.java +++ /dev/null @@ -1,198 +0,0 @@ -package me.towdium.jecalculation.core.entry; - -import me.towdium.jecalculation.client.gui.JecGui; -import me.towdium.jecalculation.core.entry.entries.EntryItemStack; -import me.towdium.jecalculation.utils.Utilities.Relation; -import me.towdium.jecalculation.utils.Utilities.ReversedIterator; -import me.towdium.jecalculation.utils.wrappers.Pair; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraftforge.fluids.FluidStack; - -import java.util.*; -import java.util.function.Function; -import java.util.stream.Collectors; - -/** - * Author: towdium - * Date: 8/11/17. - */ -public interface Entry { - ItemStack EMPTY_ITEM_STACK = new ItemStack((Item)null); - - EntryMergerRegistry MERGER = EntryMergerRegistry.INSTANCE; - Registry REGISTRY = Registry.INSTANCE; - Entry EMPTY = new EntryItemStack(Entry.EMPTY_ITEM_STACK, 0); - - Entry increaseAmount(); - - Entry increaseAmountLarge(); - - Entry decreaseAmount(); - - Entry decreaseAmountLarge(); - - String getAmountString(); - - Entry copy(); - - void drawEntry(JecGui gui); - - - /** - * Since {@link Entry} merging is bidirectional, it is redundant to - * implement on both side. So this class is created for merging - * {@link Entry Entry(s)}. - * It uses singleton mode. First register merge functions, then use - * {@link #test(Entry, Entry)} and {@link #merge(Entry, Entry, boolean)} - * to operate the {@link Entry}. - * For registering, see {@link Registry}. - */ - class EntryMergerRegistry { - public static final EntryMergerRegistry INSTANCE; - - static { - INSTANCE = new EntryMergerRegistry(); - // register functions here - } - - private Relation functions = new Relation<>(); - - private EntryMergerRegistry() { - } - - public void register(String a, String b, MergerFunction func) { - functions.add(a, b, func); - } - - public Pair merge(Entry a, Entry b, boolean add) { - return functions.get(REGISTRY.getIdentifier(a), REGISTRY.getIdentifier(b)) - .orElse((x, y, f) -> new Pair<>(x, y)).merge(a, b, add); - } - - public boolean test(Entry a, Entry b) { - Optional f = functions.get(REGISTRY.getIdentifier(a), REGISTRY.getIdentifier(b)); - if (!f.isPresent()) return false; - else { - Pair p = f.get().merge(a, b, true); - return (!(p.one == a && p.two == b) && !(p.two == a && p.one == a)); - } - } - - @FunctionalInterface - public interface MergerFunction { - /** - * @param a an {@link Entry} to merge - * @param b another {@link Entry} to merge - * @param add add together or cancel each other - * @return merged {@link Entry Entry(s)} if not changed (no matter order), they cannot merge. - */ - Pair merge(Entry a, Entry b, boolean add); - } - } - - /** - * This class is used to register an {@link Entry} type. - * Here you can find the identifier and deserializer of one type. - * For {@link Entry} operations, see {@link EntryMergerRegistry} - */ - class Registry { - public static final String KEY_IDENTIFIER = "identifier"; - public static final String KEY_CONTENT = "content"; - public static final Registry INSTANCE; - - static { - INSTANCE = new Registry(); - } - - private HashMap, Pair>>> clazzToData = new HashMap<>(); - private HashMap, - Function>>> idToData = new HashMap<>(); - - private Registry() { - } - - public void register( - Class clazz, String identifier, Function> deserializer) { - clazzToData.put(clazz, new Pair<>(identifier, deserializer)); - idToData.put(identifier, new Pair<>(clazz, deserializer)); - } - - /** - * @param nbt NBT to deserialize - * @return the recovered entry - * A typical NBT structure of an {@link Entry} is as follows: - *
{@code
-         * {
-         *     KEY_IDENTIFIER: entry_id
-         *     KEY_CONTENT: {
-         *         entry_content
-         *     }
-         * }
-         * }
- */ - public Entry deserialization(NBTTagCompound nbt) { - String s = nbt.getString(KEY_IDENTIFIER); - Optional e = idToData.get(s).two.apply(nbt.getCompoundTag(KEY_CONTENT)); - if (e.isPresent()) return e.get(); - else throw new RuntimeException("Fail to deserialize entry type: " + s); - } - - public String getIdentifier(Entry e) { - Pair>> p = clazzToData.get(e.getClass()); - if (p == null) throw new RuntimeException("Unregistered entry type: " + e.getClass()); - else return p.one; - } - } - - class ConverterRegistry { - List, List>> handlers = new ArrayList<>(); - - private ConverterRegistry() { - } - - public Entry toEntry(T ingredient) { - return handlers.stream().map(h -> h.apply(Collections.singletonList(ingredient))) - .filter(l -> !l.isEmpty()).findFirst().orElse(Collections.singletonList(Entry.EMPTY)).get(0); - } - - public List toEntry(List ingredients) { - return new ReversedIterator<>(handlers).stream().flatMap(h -> h.apply(ingredients).stream()) - .collect(Collectors.toList()); - } - - void register(Function, List> handler) { - handlers.add(handler); - } - } - - class ConverterRegistryItem extends ConverterRegistry { - public static final ConverterRegistryItem INSTANCE; - - static { - INSTANCE = new ConverterRegistryItem(); - - INSTANCE.register(ConverterRegistryItem::convertRawItemStack); - } - - private ConverterRegistryItem() { - } - - public static List convertRawItemStack(List iss) { - return iss.stream().map(EntryItemStack::new).collect(Collectors.toList()); - } - } - - class ConverterRegistryFluid extends ConverterRegistry { - public static final ConverterRegistryFluid INSTANCE; - - static { - INSTANCE = new ConverterRegistryFluid(); - } - - private ConverterRegistryFluid() { - } - } -} diff --git a/src/main/java/me/towdium/jecalculation/core/entry/entries/EntryItemStack.java b/src/main/java/me/towdium/jecalculation/core/entry/entries/EntryItemStack.java deleted file mode 100644 index 34b5103..0000000 --- a/src/main/java/me/towdium/jecalculation/core/entry/entries/EntryItemStack.java +++ /dev/null @@ -1,40 +0,0 @@ -package me.towdium.jecalculation.core.entry.entries; - -import me.towdium.jecalculation.client.gui.JecGui; -import me.towdium.jecalculation.core.entry.Entry; -import net.minecraft.item.ItemStack; - -/** - * Author: towdium - * Date: 8/11/17. - */ -public class EntryItemStack extends EntrySimpleAmount { - int amount; - ItemStack itemStack; - - public EntryItemStack(ItemStack is) { - this(is, is.stackSize); // todo check - } - - - // I will copy it! - public EntryItemStack(ItemStack is, int amount) { - itemStack = is.copy(); - this.amount = amount; - } - - private EntryItemStack(EntryItemStack eis) { - amount = eis.amount; - itemStack = eis.itemStack; - } - - @Override - public Entry copy() { - return new EntryItemStack(this); - } - - @Override - public void drawEntry(JecGui gui) { - gui.drawItemStack(0, 0, itemStack, false); - } -} diff --git a/src/main/java/me/towdium/jecalculation/core/entry/entries/EntryOreDict.java b/src/main/java/me/towdium/jecalculation/core/entry/entries/EntryOreDict.java deleted file mode 100644 index ce8fb0c..0000000 --- a/src/main/java/me/towdium/jecalculation/core/entry/entries/EntryOreDict.java +++ /dev/null @@ -1,58 +0,0 @@ -package me.towdium.jecalculation.core.entry.entries; - -import me.towdium.jecalculation.client.gui.JecGui; -import me.towdium.jecalculation.polyfill.mc.client.renderer.GlStateManager; -import me.towdium.jecalculation.polyfill.mc.util.NonNullList; -import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.item.ItemStack; -import net.minecraftforge.oredict.OreDictionary; - -/** - * Author: towdium - * Date: 17-9-10. - */ -public class EntryOreDict extends EntrySimpleAmount { - public static final String IDENTIFIER = "ore"; - - protected String name; - - public EntryOreDict(String name) { - this(name, 1); - } - - public EntryOreDict(String name, int amount) { - this.name = name; - this.amount = amount; - } - - public EntryOreDict(EntryOreDict eod) { - this.name = eod.name; - this.amount = eod.amount; - } - - @Override - public EntryOreDict copy() { - return new EntryOreDict(this); - } - - public String getName() { - return name; - } - - @Override - public void drawEntry(JecGui gui) { - NonNullList list = NonNullList.create(); - OreDictionary.getOres(name).forEach(is -> { - if (is.getItemDamage() == OreDictionary.WILDCARD_VALUE) { - is.getItem().getSubItems(is.getItem(), CreativeTabs.tabAllSearch, list); - } else list.add(is); - }); - long index = System.currentTimeMillis() / 1500; - - GlStateManager.pushMatrix(); - GlStateManager.translate(1, 1, 0); - GlStateManager.scale(14f / 16, 14f / 16, 1); - gui.drawItemStack(0, 0, list.get((int) (index % list.size())), false); - GlStateManager.popMatrix(); - } -} diff --git a/src/main/java/me/towdium/jecalculation/core/labels/ILabel.java b/src/main/java/me/towdium/jecalculation/core/labels/ILabel.java new file mode 100644 index 0000000..3d31f57 --- /dev/null +++ b/src/main/java/me/towdium/jecalculation/core/labels/ILabel.java @@ -0,0 +1,250 @@ +package me.towdium.jecalculation.core.labels; + +import com.google.common.base.CaseFormat; +import me.towdium.jecalculation.client.gui.IDrawable; +import me.towdium.jecalculation.client.gui.JecGui; +import me.towdium.jecalculation.core.labels.labels.LabelItemStack; +import me.towdium.jecalculation.core.labels.labels.LabelOreDict; +import me.towdium.jecalculation.polyfill.mc.client.renderer.GlStateManager; +import me.towdium.jecalculation.utils.ItemStackHelper; +import me.towdium.jecalculation.utils.Utilities.Relation; +import me.towdium.jecalculation.utils.Utilities.ReversedIterator; +import me.towdium.jecalculation.utils.wrappers.Pair; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.fluids.FluidStack; + +import java.util.*; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * Author: towdium + * Date: 8/11/17. + */ +public interface ILabel { + RegistryEntryMerger MERGER = RegistryEntryMerger.INSTANCE; + RegistryDeserializer DESERIALIZER = RegistryDeserializer.INSTANCE; + RegistryConverterItem CONVERTER_ITEM = RegistryConverterItem.INSTANCE; + RegistryConverterFluid CONVERTER_FLUID = RegistryConverterFluid.INSTANCE; + ILabel EMPTY = new LabelItemStack(ItemStackHelper.EMPTY_ITEM_STACK, 0); + + ILabel increaseAmount(); + + ILabel increaseAmountLarge(); + + ILabel decreaseAmount(); + + ILabel decreaseAmountLarge(); + + String getAmountString(); + + String getDisplayName(); + + default String getIdentifier() { + String s = this.getClass().getSimpleName(); + if (s.startsWith("Label")) s = s.substring(5); + return CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, s); + } + + ILabel copy(); + + NBTTagCompound toNBTTagCompound(); + + default void drawEntry(JecGui gui, int xPos, int yPos, boolean center) { + GlStateManager.pushMatrix(); + GlStateManager.translate(center ? xPos - 8 : xPos, center ? yPos - 8 : yPos, 0); + drawEntry(gui); + GlStateManager.popMatrix(); + } + + void drawEntry(JecGui gui); + + /** + * Since {@link ILabel} merging is bidirectional, it is redundant to + * implement on both side. So this class is created for merging + * {@link ILabel ILabel(s)}. + * It uses singleton mode. First register merge functions, then use + * {@link #test(ILabel, ILabel)} and {@link #merge(ILabel, ILabel, boolean)} + * to operate the {@link ILabel}. + * For registering, see {@link RegistryDeserializer}. + */ + class RegistryEntryMerger { + public static final RegistryEntryMerger INSTANCE; + + static { + INSTANCE = new RegistryEntryMerger(); + // register functions here + } + + private Relation functions = new Relation<>(); + + + private RegistryEntryMerger() { + } + + public void register(String a, String b, MergerFunction func) { + functions.add(a, b, func); + } + + public Pair merge(ILabel a, ILabel b, boolean add) { + return functions.get(a.getIdentifier(), b.getIdentifier()) + .orElse((x, y, f) -> new Pair<>(x, y)).merge(a, b, add); + } + + public boolean test(ILabel a, ILabel b) { + Optional f = functions.get(a.getIdentifier(), b.getIdentifier()); + if (!f.isPresent()) return false; + else { + Pair p = f.get().merge(a, b, true); + return (!(p.one == a && p.two == b) && !(p.two == a && p.one == a)); + } + } + + @FunctionalInterface + public interface MergerFunction { + /** + * @param a an {@link ILabel} to merge + * @param b another {@link ILabel} to merge + * @param add add together or cancel each other + * @return merged {@link ILabel ILabel(s)} if not changed (no matter order), they cannot merge. + */ + Pair merge(ILabel a, ILabel b, boolean add); + } + } + + /** + * This class is used to register an {@link ILabel} type. + * Here you can find the identifier and deserializer of one type. + * For {@link ILabel} operations, see {@link RegistryEntryMerger} + */ + class RegistryDeserializer { + public static final String KEY_IDENTIFIER = "identifier"; + public static final String KEY_CONTENT = "content"; + public static final RegistryDeserializer INSTANCE; + + static { + INSTANCE = new RegistryDeserializer(); + + INSTANCE.register("itemStack", LabelOreDict::new); + } + + private HashMap> idToData = new HashMap<>(); + + private RegistryDeserializer() { + } + + public void register(String identifier, Function deserializer) { + idToData.put(identifier, deserializer); + } + + /** + * @param nbt NBT to deserialize + * @return the recovered ILabel + * A typical NBT structure of an {@link ILabel} is as follows: + *
{@code
+         * {
+         *     KEY_IDENTIFIER: entry_id
+         *     KEY_CONTENT: {
+         *         entry_content
+         *     }
+         * }
+         * }
+ */ + public ILabel deserialization(NBTTagCompound nbt) { + String s = nbt.getString(KEY_IDENTIFIER); + ILabel e = idToData.get(s).apply(nbt.getCompoundTag(KEY_CONTENT)); + if (e != ILabel.EMPTY) return e; + else throw new RuntimeException("Fail to deserialize ILabel type: " + s); + } + } + + class RegistryConverter { + List, List>> handlers = new ArrayList<>(); + + private RegistryConverter() { + } + + public ILabel toEntry(T ingredient) { + return handlers.stream().map(h -> h.apply(Collections.singletonList(ingredient))) + .filter(l -> !l.isEmpty()).findFirst().orElse(Collections.singletonList(ILabel.EMPTY)).get(0); + } + + public List toEntry(List ingredients) { + return new ReversedIterator<>(handlers).stream().flatMap(h -> h.apply(ingredients).stream()) + .collect(Collectors.toList()); + } + + void register(Function, List> handler) { + handlers.add(handler); + } + } + + class RegistryConverterItem extends RegistryConverter { + public static final RegistryConverterItem INSTANCE; + + static { + INSTANCE = new RegistryConverterItem(); + + INSTANCE.register(RegistryConverterItem::convertRawItemStack); + } + + private RegistryConverterItem() { + } + + public static List convertRawItemStack(List iss) { + return iss.stream().map(LabelItemStack::new).collect(Collectors.toList()); + } + } + + class RegistryConverterFluid extends RegistryConverter { + public static final RegistryConverterFluid INSTANCE; + + static { + INSTANCE = new RegistryConverterFluid(); + } + + private RegistryConverterFluid() { + } + } + + class RegistryEditor { + public static final RegistryEditor INSTANCE; + + static { + INSTANCE = new RegistryEditor(); + + INSTANCE.register(LabelOreDict.getEditor(), "ore_dict", new LabelOreDict("ingotIron")); + } + + private ArrayList records = new ArrayList<>(); + + private RegistryEditor() { + } + + public void register(IEditor editor, String unlocalizedName, ILabel representation) { + records.add(new Record(editor, unlocalizedName, representation)); + } + + public Collection getRecords() { + return records; + } + + public interface IEditor extends IDrawable { + void setCallback(Consumer callback); + } + + public static class Record { + public IEditor editor; + public String unlocalizedName; + public ILabel representation; + + public Record(IEditor editor, String unlocalizedName, ILabel representation) { + this.editor = editor; + this.unlocalizedName = unlocalizedName; + this.representation = representation; + } + } + } +} diff --git a/src/main/java/me/towdium/jecalculation/core/labels/labels/LabelItemStack.java b/src/main/java/me/towdium/jecalculation/core/labels/labels/LabelItemStack.java new file mode 100644 index 0000000..b135180 --- /dev/null +++ b/src/main/java/me/towdium/jecalculation/core/labels/labels/LabelItemStack.java @@ -0,0 +1,62 @@ +package me.towdium.jecalculation.core.labels.labels; + +import me.towdium.jecalculation.client.gui.JecGui; +import me.towdium.jecalculation.core.labels.ILabel; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +/** + * Author: towdium + * Date: 8/11/17. + */ +public class LabelItemStack extends LabelSimpleAmount { + public static final String IDENTIFIER = "oreDict"; + public static final String KEY_STACK = "stack"; + public static final String KEY_AMOUNT = "amount"; + + ItemStack itemStack; + + public LabelItemStack(ItemStack is) { + this(is, is.stackSize); + } + + // I will copy it! + public LabelItemStack(ItemStack is, int amount) { + itemStack = is.copy(); + this.amount = amount; + } + + public LabelItemStack(NBTTagCompound nbt) { + itemStack = ItemStack.loadItemStackFromNBT(nbt.getCompoundTag(KEY_STACK)); + amount = nbt.getInteger(KEY_AMOUNT); + } + + private LabelItemStack(LabelItemStack eis) { + amount = eis.amount; + itemStack = eis.itemStack; + } + + @Override + public String getDisplayName() { + return itemStack.getDisplayName(); + } + + @Override + public ILabel copy() { + return new LabelItemStack(this); + } + + @Override + public NBTTagCompound toNBTTagCompound() { + NBTTagCompound ret = new NBTTagCompound(); + ret.setTag(KEY_STACK, itemStack.writeToNBT(new NBTTagCompound())); + ret.setInteger(KEY_AMOUNT, amount); + return ret; + } + + @Override + public void drawEntry(JecGui gui) { + gui.drawItemStack(0, 0, itemStack, false); + } +} diff --git a/src/main/java/me/towdium/jecalculation/core/labels/labels/LabelOreDict.java b/src/main/java/me/towdium/jecalculation/core/labels/labels/LabelOreDict.java new file mode 100644 index 0000000..4c12012 --- /dev/null +++ b/src/main/java/me/towdium/jecalculation/core/labels/labels/LabelOreDict.java @@ -0,0 +1,97 @@ +package me.towdium.jecalculation.core.labels.labels; + +import me.towdium.jecalculation.client.gui.JecGui; +import me.towdium.jecalculation.client.gui.drawables.DContainer; +import me.towdium.jecalculation.client.gui.drawables.DText; +import me.towdium.jecalculation.core.labels.ILabel; +import me.towdium.jecalculation.polyfill.mc.client.renderer.GlStateManager; +import me.towdium.jecalculation.polyfill.mc.util.NonNullList; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.oredict.OreDictionary; + +import java.util.function.Consumer; + +/** + * Author: towdium + * Date: 17-9-10. + */ +public class LabelOreDict extends LabelSimpleAmount { + public static final String IDENTIFIER = "oreDict"; + public static final String KEY_NAME = "name"; + public static final String KEY_AMOUNT = "amount"; + + protected String name; + + public LabelOreDict(String name) { + this(name, 1); + } + + public LabelOreDict(String name, int amount) { + this.name = name; + this.amount = amount; + } + + public LabelOreDict(LabelOreDict eod) { + this.name = eod.name; + this.amount = eod.amount; + } + + public LabelOreDict(NBTTagCompound nbt) { + name = nbt.getString(KEY_NAME); + amount = nbt.getInteger(KEY_AMOUNT); + } + + @Override + public String getDisplayName() { + return "Ore: " + name; // localization + } + + public static RegistryEditor.IEditor getEditor() { + return new Editor(); + } + + @Override + public LabelOreDict copy() { + return new LabelOreDict(this); + } + + @Override + public void drawEntry(JecGui gui) { + NonNullList list = NonNullList.create(); + OreDictionary.getOres(name).forEach(is -> { + if (is.getItemDamage() == OreDictionary.WILDCARD_VALUE) { + is.getItem().getSubItems(is.getItem(), CreativeTabs.tabAllSearch, list); + } else list.add(is); + }); + long index = System.currentTimeMillis() / 1500; + + GlStateManager.pushMatrix(); + GlStateManager.translate(1, 1, 0); + GlStateManager.scale(14f / 16, 14f / 16, 1); + gui.drawItemStack(0, 0, list.get((int) (index % list.size())), false); + GlStateManager.popMatrix(); + } + + @Override + public NBTTagCompound toNBTTagCompound() { + NBTTagCompound ret = new NBTTagCompound(); + ret.setString(KEY_NAME, name); + ret.setInteger(KEY_AMOUNT, amount); + return ret; + } + + public static class Editor extends DContainer implements RegistryEditor.IEditor { + Consumer label; + + public Editor() { + add(new DText(5, 5, JecGui.Font.DEFAULT_NO_SHADOW, "hello")); + } + + @Override + public void setCallback(Consumer callback) { + label = callback; + } + } +} diff --git a/src/main/java/me/towdium/jecalculation/core/entry/entries/EntrySimpleAmount.java b/src/main/java/me/towdium/jecalculation/core/labels/labels/LabelSimpleAmount.java similarity index 57% rename from src/main/java/me/towdium/jecalculation/core/entry/entries/EntrySimpleAmount.java rename to src/main/java/me/towdium/jecalculation/core/labels/labels/LabelSimpleAmount.java index a5bf299..4cafc5c 100644 --- a/src/main/java/me/towdium/jecalculation/core/entry/entries/EntrySimpleAmount.java +++ b/src/main/java/me/towdium/jecalculation/core/labels/labels/LabelSimpleAmount.java @@ -1,30 +1,30 @@ -package me.towdium.jecalculation.core.entry.entries; +package me.towdium.jecalculation.core.labels.labels; -import me.towdium.jecalculation.core.entry.Entry; +import me.towdium.jecalculation.core.labels.ILabel; import me.towdium.jecalculation.utils.Utilities; /** * Author: towdium * Date: 17-9-11. */ -public abstract class EntrySimpleAmount implements Entry { +public abstract class LabelSimpleAmount implements ILabel { protected int amount; @Override - public Entry increaseAmount() { + public ILabel increaseAmount() { amount++; return this; } @Override - public Entry increaseAmountLarge() { + public ILabel increaseAmountLarge() { amount += 10; return this; } @Override - public Entry decreaseAmount() { - if (amount <= 1) return Entry.EMPTY; + public ILabel decreaseAmount() { + if (amount <= 1) return ILabel.EMPTY; else { amount--; return this; @@ -32,8 +32,8 @@ public abstract class EntrySimpleAmount implements Entry { } @Override - public Entry decreaseAmountLarge() { - if (amount <= 10) return Entry.EMPTY; + public ILabel decreaseAmountLarge() { + if (amount <= 10) return ILabel.EMPTY; else { amount -= 10; return this; diff --git a/src/main/java/me/towdium/jecalculation/event/handlers/InputEventHandler.java b/src/main/java/me/towdium/jecalculation/event/handlers/InputEventHandler.java index 8b6fd7b..a47139e 100644 --- a/src/main/java/me/towdium/jecalculation/event/handlers/InputEventHandler.java +++ b/src/main/java/me/towdium/jecalculation/event/handlers/InputEventHandler.java @@ -22,7 +22,7 @@ public class InputEventHandler { @SubscribeEvent public void onKey(InputEvent.KeyInputEvent event) { if (ProxyClient.keyOpenGui.isPressed() && JustEnoughCalculation.side != JustEnoughCalculation.enumSide.SERVER) { - Minecraft.getMinecraft().displayGuiScreen(new GuiCalculator(null)); + JecGui.displayGui(new GuiCalculator()); } } diff --git a/src/main/java/me/towdium/jecalculation/item/JecaItem.java b/src/main/java/me/towdium/jecalculation/item/JecaItem.java index 62c6a35..3ca6bfe 100644 --- a/src/main/java/me/towdium/jecalculation/item/JecaItem.java +++ b/src/main/java/me/towdium/jecalculation/item/JecaItem.java @@ -10,26 +10,9 @@ import net.minecraft.item.ItemStack; * @author Towdium */ public class JecaItem extends Item { - public static JecaItem INSTANCE = new JecaItem(); - public static final String CRAFTING_NAME = "item_calculator_crafting"; public static final String MATH_NAME = "item_calculator_math"; - - public JecaItem() { - setHasSubtypes(true); - setMaxStackSize(1); - setUnlocalizedName(CRAFTING_NAME); - setTextureName(JustEnoughCalculation.Reference.MODID + ":" + CRAFTING_NAME); - setCreativeTab(CreativeTabs.tabTools); - } - -// @Override -// public ItemStack onItemRightClick(ItemStack itemStackIn, World worldIn, EntityPlayer playerIn) { -// playerIn.openGui(JustEnoughCalculation.INSTANCE, GuiHandler.GuiId.EDITOR, worldIn, 0, 0, 0); -// return itemStackIn; -// } - public String getUnlocalizedName(int meta) { return getUnlocalizedName(); } diff --git a/src/main/java/me/towdium/jecalculation/item/items/ItemCalculator.java b/src/main/java/me/towdium/jecalculation/item/items/ItemCalculator.java index 4e0f6ba..c876aa7 100644 --- a/src/main/java/me/towdium/jecalculation/item/items/ItemCalculator.java +++ b/src/main/java/me/towdium/jecalculation/item/items/ItemCalculator.java @@ -1,11 +1,15 @@ package me.towdium.jecalculation.item.items; import me.towdium.jecalculation.JustEnoughCalculation; +import me.towdium.jecalculation.client.gui.JecGui; +import me.towdium.jecalculation.client.gui.guis.GuiCalculator; import me.towdium.jecalculation.item.JecaItem; import me.towdium.jecalculation.utils.IllegalPositionException; import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.world.World; import java.util.List; @@ -37,4 +41,12 @@ public class ItemCalculator extends JecaItem { items.add(new ItemStack(this, 1, 1)); } } + + @Override + public ItemStack onItemRightClick(ItemStack p_77659_1_, World p_77659_2_, EntityPlayer p_77659_3_) { + if (JustEnoughCalculation.side != JustEnoughCalculation.enumSide.SERVER) { + JecGui.displayGui(new GuiCalculator()); + } + return super.onItemRightClick(p_77659_1_, p_77659_2_, p_77659_3_); + } } diff --git a/src/main/java/me/towdium/jecalculation/nei/JecaOverlayHandler.java b/src/main/java/me/towdium/jecalculation/nei/JecaOverlayHandler.java index e48dd71..439078b 100644 --- a/src/main/java/me/towdium/jecalculation/nei/JecaOverlayHandler.java +++ b/src/main/java/me/towdium/jecalculation/nei/JecaOverlayHandler.java @@ -4,6 +4,8 @@ import codechicken.nei.PositionedStack; import codechicken.nei.api.IOverlayHandler; import codechicken.nei.recipe.IRecipeHandler; import me.towdium.jecalculation.client.gui.JecGui; +import me.towdium.jecalculation.client.gui.guis.GuiCalculator; +import me.towdium.jecalculation.client.gui.guis.GuiEditor; import me.towdium.jecalculation.utils.ItemStackHelper; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.inventory.GuiContainer; @@ -31,7 +33,7 @@ public class JecaOverlayHandler implements IOverlayHandler { ItemStack outputStack = recipe.getResultStack(recipeIndex).items[0]; Minecraft mc = Minecraft.getMinecraft(); - mc.displayGuiScreen(new JecGui(firstGui)); + JecGui.displayGui(new GuiEditor()); GuiContainer myGuiContainer = (GuiContainer) mc.currentScreen; if (myGuiContainer != null) { myGuiContainer.inventorySlots.getSlot(0).putStack(outputStack); diff --git a/src/main/java/me/towdium/jecalculation/nei/NEIPlugin.java b/src/main/java/me/towdium/jecalculation/nei/NEIPlugin.java index 1a40005..6de4be8 100644 --- a/src/main/java/me/towdium/jecalculation/nei/NEIPlugin.java +++ b/src/main/java/me/towdium/jecalculation/nei/NEIPlugin.java @@ -1,21 +1,12 @@ package me.towdium.jecalculation.nei; -import codechicken.nei.api.API; import codechicken.nei.guihook.GuiContainerManager; -import me.towdium.jecalculation.core.entry.Entry; -import me.towdium.jecalculation.core.entry.entries.EntryItemStack; -import me.towdium.jecalculation.utils.Utilities; +import me.towdium.jecalculation.core.labels.ILabel; import net.minecraft.item.ItemStack; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.function.Function; -import java.util.stream.Collectors; - public class NEIPlugin { - public static final Entry.ConverterRegistryItem registryItem = Entry.ConverterRegistryItem.INSTANCE; - public static final Entry.ConverterRegistryFluid registryFluid = Entry.ConverterRegistryFluid.INSTANCE; + public static final ILabel.RegistryConverterItem registryItem = ILabel.RegistryConverterItem.INSTANCE; + public static final ILabel.RegistryConverterFluid registryFluid = ILabel.RegistryConverterFluid.INSTANCE; public static void init() { GuiContainerManager.addTooltipHandler(new JecaTooltipHandler()); @@ -23,8 +14,8 @@ public class NEIPlugin { private static ItemStack currentItemStack; - public static Entry getEntryUnderMouse() { - if (NEIPlugin.currentItemStack == null) return Entry.EMPTY; + public static ILabel getEntryUnderMouse() { + if (NEIPlugin.currentItemStack == null) return ILabel.EMPTY; else return registryItem.toEntry(NEIPlugin.currentItemStack); } diff --git a/src/main/java/me/towdium/jecalculation/network/ProxyCommon.java b/src/main/java/me/towdium/jecalculation/network/ProxyCommon.java index a57933e..ba04df7 100644 --- a/src/main/java/me/towdium/jecalculation/network/ProxyCommon.java +++ b/src/main/java/me/towdium/jecalculation/network/ProxyCommon.java @@ -4,13 +4,16 @@ import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.registry.GameRegistry; import me.towdium.jecalculation.JustEnoughCalculation; import me.towdium.jecalculation.event.Handlers; +import me.towdium.jecalculation.item.Items; import me.towdium.jecalculation.item.JecaItem; import net.minecraftforge.common.MinecraftForge; public class ProxyCommon { public void initPre() { JustEnoughCalculation.logger.info("common proxy init pre"); - GameRegistry.registerItem(JecaItem.INSTANCE, JecaItem.CRAFTING_NAME); + for (JecaItem item : Items.items) { + GameRegistry.registerItem(item, item.getUnlocalizedName()); + } Handlers.handlers.forEach(FMLCommonHandler.instance().bus()::register); } diff --git a/src/main/java/me/towdium/jecalculation/polyfill/Polyfill.java b/src/main/java/me/towdium/jecalculation/polyfill/Polyfill.java index 5e120f2..a4c2cf7 100644 --- a/src/main/java/me/towdium/jecalculation/polyfill/Polyfill.java +++ b/src/main/java/me/towdium/jecalculation/polyfill/Polyfill.java @@ -1,5 +1,7 @@ package me.towdium.jecalculation.polyfill; +import me.towdium.jecalculation.utils.ItemStackHelper; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; @@ -23,4 +25,5 @@ public class Polyfill { return null; } } + } diff --git a/src/main/java/me/towdium/jecalculation/utils/ItemStackHelper.java b/src/main/java/me/towdium/jecalculation/utils/ItemStackHelper.java index 53cfcda..c0ff3ba 100644 --- a/src/main/java/me/towdium/jecalculation/utils/ItemStackHelper.java +++ b/src/main/java/me/towdium/jecalculation/utils/ItemStackHelper.java @@ -2,6 +2,7 @@ package me.towdium.jecalculation.utils; import me.towdium.jecalculation.JustEnoughCalculation; import me.towdium.jecalculation.polyfill.Polyfill; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; @@ -13,6 +14,8 @@ import java.util.function.Function; public class ItemStackHelper { public static final String keyAmount = "amount"; public static final String keyType = "type"; + public static final Item EMPTY_ITEM = null; + public static final ItemStack EMPTY_ITEM_STACK = new ItemStack((Item)null); public enum EnumStackAmountType { INVALID, NUMBER, PERCENTAGE, FLUID; diff --git a/src/main/java/me/towdium/jecalculation/utils/wrappers/Pair.java b/src/main/java/me/towdium/jecalculation/utils/wrappers/Pair.java index ab5626d..b3fe9f7 100644 --- a/src/main/java/me/towdium/jecalculation/utils/wrappers/Pair.java +++ b/src/main/java/me/towdium/jecalculation/utils/wrappers/Pair.java @@ -18,15 +18,6 @@ public class Pair { return one.hashCode() ^ two.hashCode(); } - @Override - public boolean equals(Object obj) { - if (obj instanceof Pair) { - Pair p = (Pair) obj; - return one.equals(p.one) && two.equals(p.two); - } - return false; - } - public boolean swap(Class ke, Class ve) { if (ke.isInstance(one) && ve.isInstance(two)) return true; else if (!(ke.isInstance(two) && ve.isInstance(one))) return false; diff --git a/src/main/resources/assets/jecalculation/textures/gui/resources.png b/src/main/resources/assets/jecalculation/textures/gui/resources.png index 2791f9535b491e7e6e8881ace821ca8728506140..626accea1aed012c3de4a661b3fab163eb61558f 100644 GIT binary patch delta 9437 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 CpA)$N delta 9360 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 Br0)O#