From 4c45f38d129568292bd6fe34475aeebfb5ef548c Mon Sep 17 00:00:00 2001 From: Discreater Date: Wed, 28 Apr 2021 23:02:57 +0800 Subject: [PATCH] feat: Tweak in GUI --- .../jecalculation/client/gui/JecGui.java | 47 +++++++++------ .../jecalculation/client/gui/Resource.java | 6 +- .../client/gui/drawables/DButton.java | 41 +++---------- .../client/gui/drawables/DButtonIcon.java | 34 +++++++++++ .../client/gui/drawables/DButtonText.java | 32 +++++++++++ .../client/gui/drawables/DContainer.java | 4 ++ .../client/gui/drawables/DIcon.java | 23 ++++---- .../client/gui/drawables/DPage.java | 54 ++++++++++++++++++ .../client/gui/drawables/DPager.java | 45 --------------- .../client/gui/drawables/DScroll.java | 4 +- .../client/gui/drawables/DTooltip.java | 38 ++++++++++++ .../client/gui/guis/GuiCalculator.java | 15 +++-- .../client/gui/guis/GuiLabel.java | 53 +++++++++++++++++ .../client/gui/guis/GuiLabelPicker.java | 16 ------ .../guis/{GuiEditor.java => GuiRecipe.java} | 24 ++++---- .../jecalculation/core/labels/ILabel.java | 15 +++-- .../core/labels/labels/LabelOreDict.java | 19 ++++-- .../jecalculation/nei/JecaOverlayHandler.java | 5 +- .../utils/helpers/LocalizationHelper.java | 28 --------- .../assets/jecalculation/lang/en_US.lang | 2 +- .../jecalculation/textures/gui/resources.png | Bin 9932 -> 10659 bytes 21 files changed, 316 insertions(+), 189 deletions(-) create mode 100644 src/main/java/me/towdium/jecalculation/client/gui/drawables/DButtonIcon.java create mode 100644 src/main/java/me/towdium/jecalculation/client/gui/drawables/DButtonText.java create mode 100644 src/main/java/me/towdium/jecalculation/client/gui/drawables/DPage.java delete 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/DTooltip.java create mode 100644 src/main/java/me/towdium/jecalculation/client/gui/guis/GuiLabel.java delete mode 100644 src/main/java/me/towdium/jecalculation/client/gui/guis/GuiLabelPicker.java rename src/main/java/me/towdium/jecalculation/client/gui/guis/{GuiEditor.java => GuiRecipe.java} (58%) 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 2e13d4f..74bae97 100644 --- a/src/main/java/me/towdium/jecalculation/client/gui/JecGui.java +++ b/src/main/java/me/towdium/jecalculation/client/gui/JecGui.java @@ -39,45 +39,58 @@ import java.util.function.Function; @ParametersAreNonnullByDefault public class JecGui extends GuiContainer { public static final int COLOR_GREY = 0xFFA1A1A1; - protected static JecGui last; + public static final boolean ALWAYS_TOOLTIP = false; + protected JecGui parent; public ILabel hand = ILabel.EMPTY; - public DContainer container = new DContainer(); + public IDrawable root; protected List>> tooltipBuffer = new ArrayList<>(); - public JecGui(@Nullable JecGui parent, IDrawable... drawables) { - this(parent, false, drawables); + public JecGui(@Nullable JecGui parent, IDrawable root) { + this(parent, false, root); } - public JecGui(@Nullable JecGui parent, boolean acceptsTransfer, IDrawable... drawables) { + public JecGui(@Nullable JecGui parent, boolean acceptsTransfer, IDrawable root) { super(acceptsTransfer ? new ContainerTransfer() : new ContainerNonTransfer()); this.parent = parent; - container.addAll(drawables); + this.root = root; } 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; } - public static void displayGui(IDrawable... components) { - displayGui(true, false, components); + public static void displayGui(IDrawable root) { + displayGui(true, false, root); } - public static void displayGui(boolean updateParent, boolean acceptsTransfer, IDrawable... components) { + public static void displayGui(boolean updateParent, boolean acceptsTransfer, IDrawable root) { // isCallingFromMinecraftThread if (Minecraft.getMinecraft().func_152345_ab()) - displayGuiUnsafe(updateParent, acceptsTransfer, components); + displayGuiUnsafe(updateParent, acceptsTransfer, root); } - public static void displayGuiUnsafe(boolean updateParent, boolean acceptsTransfer, IDrawable... components) { + public static JecGui getCurrent() { + return last; + } + + private static void displayGuiUnsafe(boolean updateParent, boolean acceptsTransfer, IDrawable root) { 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)); + JecGui toShow = new JecGui(parent, acceptsTransfer, root); + mc.displayGuiScreen(toShow); + last = toShow; + } + + @Override + public void onGuiClosed() { + super.onGuiClosed(); + last = null; } @Override @@ -97,7 +110,7 @@ public class JecGui extends GuiContainer { GlStateManager.translate(guiLeft, guiTop, 0); GlStateManager.disableLighting(); GlStateManager.disableDepth(); - container.onDraw(this, mouseX - guiLeft, mouseY - guiTop); + root.onDraw(this, mouseX - guiLeft, mouseY - guiTop); GlStateManager.popMatrix(); GlStateManager.pushMatrix(); GlStateManager.translate(mouseX - 8, mouseY - 8, 0); @@ -318,10 +331,6 @@ public class JecGui extends GuiContainer { RenderHelper.disableStandardItemLighting(); } - public String localize(String key, Object... os) { - return LocalizationHelper.format(this.getClass(), "gui", key, os); - } - 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); @@ -358,7 +367,7 @@ public class JecGui extends GuiContainer { @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); + boolean inGui = root.onClicked(this, mouseX - guiLeft, mouseY - guiTop, mouseButton); if(!inGui) { this.handleMouseEvent(); } @@ -366,7 +375,7 @@ public class JecGui extends GuiContainer { @Override protected void keyTyped(char typedChar, int keyCode) { - if (!container.onKey(this, typedChar, keyCode)) { + if (!root.onKey(this, typedChar, keyCode)) { if (keyCode == Keyboard.KEY_ESCAPE) { if (hand != ILabel.EMPTY) hand = ILabel.EMPTY; diff --git a/src/main/java/me/towdium/jecalculation/client/gui/Resource.java b/src/main/java/me/towdium/jecalculation/client/gui/Resource.java index 4493a29..7406d9d 100644 --- a/src/main/java/me/towdium/jecalculation/client/gui/Resource.java +++ b/src/main/java/me/towdium/jecalculation/client/gui/Resource.java @@ -36,8 +36,9 @@ 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 WGT_PAGER_FN = new Resource(120, 232, 20, 20); + public static final Resource WGT_PAGER_F0 = new Resource(140, 232, 20, 20); + public static final Resource WGT_PAGER_N = new Resource(160, 232, 20, 20); 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); @@ -46,6 +47,7 @@ public class Resource { public static final Resource ICN_OUTPUT_F = new Resource(28, 28, 14, 14); public static final Resource ICN_CATALYST_N = new Resource(42, 42, 14, 14); public static final Resource ICN_CATALYST_F = new Resource(42, 28, 14, 14); + public static final Resource LBL_ORE_DICT = new Resource(0, 56, 16, 16); protected int xPos, yPos, xSize, ySize; protected ResourceLocation rl; 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 index 8ee901e..81f23fb 100644 --- a/src/main/java/me/towdium/jecalculation/client/gui/drawables/DButton.java +++ b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DButton.java @@ -14,31 +14,17 @@ import javax.annotation.ParametersAreNonnullByDefault; * Date: 17-8-17. */ @ParametersAreNonnullByDefault -public class DButton implements IDrawable { +public abstract class DButton extends DTooltip { 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) { + public DButton(int xPos, int yPos, int xSize, int ySize, @Nullable String name) { + super(name); 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) { @@ -56,22 +42,6 @@ public class DButton implements IDrawable { 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 @@ -89,4 +59,9 @@ public class DButton implements IDrawable { } return false; } + + @Override + boolean mouseIn(int xMouse, int yMouse) { + return JecGui.mouseIn(xPos + 1, yPos + 1, xSize - 2, ySize - 2, xMouse, yMouse); + } } diff --git a/src/main/java/me/towdium/jecalculation/client/gui/drawables/DButtonIcon.java b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DButtonIcon.java new file mode 100644 index 0000000..c5fbcd8 --- /dev/null +++ b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DButtonIcon.java @@ -0,0 +1,34 @@ +package me.towdium.jecalculation.client.gui.drawables; + +import me.towdium.jecalculation.client.gui.JecGui; +import me.towdium.jecalculation.client.gui.Resource; + +import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; + +/** + * Author: towdium + * Date: 17-9-16. + */ +@ParametersAreNonnullByDefault +public class DButtonIcon extends DButton { + protected Resource normal, focused; + + public DButtonIcon(int xPos, int yPos, int xSize, int ySize, Resource normal, Resource focused) { + this(xPos, yPos, xSize, ySize, normal, focused, null); + } + + public DButtonIcon(int xPos, int yPos, int xSize, int ySize, Resource normal, Resource focused, @Nullable String name) { + super(xPos, yPos, xSize, ySize, name); + this.normal = normal; + this.focused = focused; + } + + @Override + public void onDraw(JecGui gui, int xMouse, int yMouse) { + super.onDraw(gui, xMouse, yMouse); + Resource r = mouseIn(xMouse, yMouse) ? focused : normal; + if (r != null) + gui.drawResource(r, xPos + (xSize - r.getXSize()) / 2, yPos + (ySize - r.getYSize()) / 2); + } +} diff --git a/src/main/java/me/towdium/jecalculation/client/gui/drawables/DButtonText.java b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DButtonText.java new file mode 100644 index 0000000..c7b6e7e --- /dev/null +++ b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DButtonText.java @@ -0,0 +1,32 @@ +package me.towdium.jecalculation.client.gui.drawables; + +import me.towdium.jecalculation.client.gui.JecGui; +import me.towdium.jecalculation.utils.helpers.LocalizationHelper; + +import javax.annotation.ParametersAreNonnullByDefault; + +/** + * Author: towdium + * Date: 17-9-16. + */ +@ParametersAreNonnullByDefault +public class DButtonText extends DButton { + public DButtonText(int xPos, int yPos, int xSize, int ySize, String name) { + super(xPos, yPos, xSize, ySize, name); + } + + @Override + public void onDraw(JecGui gui, int xMouse, int yMouse) { + super.onDraw(gui, xMouse, yMouse); + int textColor = mouseIn(xMouse, yMouse) ? 16777120 : 0; + String text = LocalizationHelper.format(String.join(".", "gui", name, "text")); + 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); + } +} 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 index b0cef0d..0ead4e1 100644 --- a/src/main/java/me/towdium/jecalculation/client/gui/drawables/DContainer.java +++ b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DContainer.java @@ -34,6 +34,10 @@ public class DContainer implements IDrawable { remove(aw); } + public void clear() { + widgets.clear(); + } + public void onDraw(JecGui gui, int mouseX, int mouseY) { widgets.forEach(widget -> widget.onDraw(gui, mouseX, mouseY)); } diff --git a/src/main/java/me/towdium/jecalculation/client/gui/drawables/DIcon.java b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DIcon.java index 2ccee70..113c436 100644 --- a/src/main/java/me/towdium/jecalculation/client/gui/drawables/DIcon.java +++ b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DIcon.java @@ -14,37 +14,36 @@ import javax.annotation.ParametersAreNonnullByDefault; * Date: 17-8-18. */ @ParametersAreNonnullByDefault -public class DIcon implements IDrawable { +public class DIcon extends DTooltip { public int xPos, yPos, xSize, ySize; public Resource normal, focused; - Timer timer = new Timer(); - public String tooltip; public DIcon(int xPos, int yPos, int xSize, int ySize, Resource normal, Resource focused) { this(xPos, yPos, xSize, ySize, normal, focused, null); } public DIcon(int xPos, int yPos, int xSize, int ySize, - Resource normal, Resource focused, @Nullable String tooltip) { + Resource normal, Resource focused, @Nullable String name) { + super(name); this.xPos = xPos; this.yPos = yPos; this.xSize = xSize; this.ySize = ySize; this.normal = normal; this.focused = focused; - this.tooltip = tooltip; } @Override public void onDraw(JecGui gui, int xMouse, int yMouse) { - boolean hovered = JecGui.mouseIn(xPos + (xSize - normal.getXSize()) / 2, - yPos + (ySize - normal.getYSize()) / 2, normal.getXSize(), normal.getYSize(), xMouse, yMouse); + super.onDraw(gui, xMouse, yMouse); gui.drawRectangle(xPos, yPos, xSize, ySize, JecGui.COLOR_GREY); - Resource r = hovered ? focused : normal; + Resource r = mouseIn(xMouse, yMouse) ? focused : normal; 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)); - } + } + + @Override + boolean mouseIn(int xMouse, int yMouse) { + return JecGui.mouseIn(xPos + (xSize - normal.getXSize()) / 2, + yPos + (ySize - normal.getYSize()) / 2, normal.getXSize(), normal.getYSize(), xMouse, yMouse); } } diff --git a/src/main/java/me/towdium/jecalculation/client/gui/drawables/DPage.java b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DPage.java new file mode 100644 index 0000000..3556468 --- /dev/null +++ b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DPage.java @@ -0,0 +1,54 @@ +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.Utilities; +import me.towdium.jecalculation.utils.helpers.LocalizationHelper; + +import javax.annotation.ParametersAreNonnullByDefault; + +/** + * Author: towdium + * Date: 17-9-16. + */ +@ParametersAreNonnullByDefault +public class DPage implements IDrawable { + + + protected int index; + protected ILabel.RegistryEditor.Record record; + protected Utilities.Timer timer = new Utilities.Timer(); + protected boolean focused; + protected Runnable listener; + + public DPage(int index, ILabel.RegistryEditor.Record record, boolean focused) { + this.index = index; + this.record = record; + this.focused = focused; + } + + @Override + public void onDraw(JecGui gui, int xMouse, int yMouse) { + Resource resource = focused ? (index == 0 ? Resource.WGT_PAGER_F0 : Resource.WGT_PAGER_FN) + : Resource.WGT_PAGER_N; + gui.drawResourceContinuous(resource, index * 24, -21, 24, 25, 4, 4, 4, 4); + record.representation.drawEntry(gui, index * 24 + 4, -17, false); + timer.setState(JecGui.mouseIn(index * 24, -21, 24, 21, xMouse, yMouse)); + if (timer.getTime() > 1000) + gui.drawTooltip(xMouse, yMouse, LocalizationHelper.format("gui." + record.localizeKey)); + } + + @Override + public boolean onClicked(JecGui gui, int xMouse, int yMouse, int button) { + boolean ret = JecGui.mouseIn(index * 24, -21, 24, 21, xMouse, yMouse) && listener != null && !focused; + if (ret) listener.run(); + return ret; + } + + public DPage setListener(Runnable r) { + listener = r; + return this; + } +} 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 deleted file mode 100644 index 92e2a0d..0000000 --- a/src/main/java/me/towdium/jecalculation/client/gui/drawables/DPager.java +++ /dev/null @@ -1,45 +0,0 @@ -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/DScroll.java b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DScroll.java index 5ce6e90..1083b74 100644 --- a/src/main/java/me/towdium/jecalculation/client/gui/drawables/DScroll.java +++ b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DScroll.java @@ -36,9 +36,9 @@ public class DScroll implements IDrawable { 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) + left = new DButtonIcon(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, + right = new DButtonIcon(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); diff --git a/src/main/java/me/towdium/jecalculation/client/gui/drawables/DTooltip.java b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DTooltip.java new file mode 100644 index 0000000..6ffda5f --- /dev/null +++ b/src/main/java/me/towdium/jecalculation/client/gui/drawables/DTooltip.java @@ -0,0 +1,38 @@ +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.utils.Utilities; +import me.towdium.jecalculation.utils.helpers.LocalizationHelper; +import me.towdium.jecalculation.utils.wrappers.Pair; + +import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; + +/** + * Author: towdium + * Date: 17-9-16. + */ +@ParametersAreNonnullByDefault +public abstract class DTooltip implements IDrawable { + @Nullable + public String name; + Utilities.Timer timer = new Utilities.Timer(); + + public DTooltip(@Nullable String name) { + this.name = name; + } + + @Override + public void onDraw(JecGui gui, int xMouse, int yMouse) { + if (name != null) { + timer.setState(mouseIn(xMouse, yMouse)); + if (timer.getTime() > 500) { + Pair str = LocalizationHelper.search(String.join(".", "gui", name, "tooltip")); + if (str.two || JecGui.ALWAYS_TOOLTIP) gui.drawTooltip(xMouse, yMouse, str.one); + } + } + } + + abstract boolean mouseIn(int xMouse, int yMouse); +} 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 264ff3a..d90ec7a 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 @@ -17,16 +17,19 @@ 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 DButtonIcon(7, 7, 20, 20, Resource.BTN_LABEL_N, Resource.BTN_LABEL_F, "calculator.label") + .setListenerLeft(() -> JecGui.displayGui(new GuiLabel(l -> { + JecGui.displayGui(this); + JecGui.getCurrent().hand = l; + })))); + add(new DButtonIcon(130, 7, 20, 20, Resource.BTN_NEW_N, Resource.BTN_NEW_F, "calculator.recipe") + .setListenerLeft(() -> JecGui.displayGui(new GuiRecipe()))); + add(new DButtonIcon(149, 7, 20, 20, Resource.BTN_SEARCH_N, Resource.BTN_SEARCH_F, "calculator.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 DIcon(151, 31, 18, 18, Resource.ICN_RECENT_N, Resource.ICN_RECENT_F, "calculator.history")); add(new DScroll(7, 56, 162, 5)); } } diff --git a/src/main/java/me/towdium/jecalculation/client/gui/guis/GuiLabel.java b/src/main/java/me/towdium/jecalculation/client/gui/guis/GuiLabel.java new file mode 100644 index 0000000..695bfdc --- /dev/null +++ b/src/main/java/me/towdium/jecalculation/client/gui/guis/GuiLabel.java @@ -0,0 +1,53 @@ +package me.towdium.jecalculation.client.gui.guis; + +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import com.google.common.cache.Weigher; +import me.towdium.jecalculation.client.gui.IDrawable; +import me.towdium.jecalculation.client.gui.drawables.DContainer; +import me.towdium.jecalculation.client.gui.drawables.DPage; +import me.towdium.jecalculation.client.gui.drawables.DPanel; +import me.towdium.jecalculation.core.labels.ILabel; +import me.towdium.jecalculation.utils.wrappers.Single; + +import javax.annotation.ParametersAreNonnullByDefault; +import java.util.function.Consumer; + +/** + * Author: towdium + * Date: 17-9-14. + */ +@ParametersAreNonnullByDefault +public class GuiLabel extends DContainer { + DContainer container = new DContainer(); + Consumer callback; + LoadingCache cache = CacheBuilder.newBuilder().concurrencyLevel(1) + .maximumWeight(16).weigher((Weigher) (key, value) -> 1) + .build(new CacheLoader() { + @Override + public IDrawable load(Integer i) { + ILabel.RegistryEditor.Record record = ILabel.EDITOR.getRecords().get(i); + return record.editor.setCallback(callback); + } + }); + + public GuiLabel(Consumer callback) { + this.callback = callback; + Single index = new Single<>(0); + ILabel.EDITOR.getRecords().forEach(r -> { + int i = index.value; + add(new DPage(0, r, false).setListener(() -> refresh(i))); + index.value += 1; + }); + add(new DPanel()); + add(container); + refresh(0); + } + + protected void refresh(int index) { + container.clear(); + container.add(cache.getUnchecked(index)); + container.add(new DPage(index, ILabel.EDITOR.getRecords().get(index), true)); + } +} 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 deleted file mode 100644 index 8909cbc..0000000 --- a/src/main/java/me/towdium/jecalculation/client/gui/guis/GuiLabelPicker.java +++ /dev/null @@ -1,16 +0,0 @@ -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/guis/GuiEditor.java b/src/main/java/me/towdium/jecalculation/client/gui/guis/GuiRecipe.java similarity index 58% rename from src/main/java/me/towdium/jecalculation/client/gui/guis/GuiEditor.java rename to src/main/java/me/towdium/jecalculation/client/gui/guis/GuiRecipe.java index f4215ff..0c1c8d1 100644 --- a/src/main/java/me/towdium/jecalculation/client/gui/guis/GuiEditor.java +++ b/src/main/java/me/towdium/jecalculation/client/gui/guis/GuiRecipe.java @@ -9,26 +9,26 @@ import static me.towdium.jecalculation.client.gui.drawables.DLabel.enumMode.EDIT * Author: towdium * Date: 17-9-8. */ -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"); +public class GuiRecipe extends DContainer { + DButton buttonSave = new DButtonIcon(26, 33, 20, 20, Resource.BTN_SAVE_N, Resource.BTN_SAVE_F, "recipe.save"); + DButton buttonCopy = new DButtonIcon(83, 33, 20, 20, Resource.BTN_COPY_N, Resource.BTN_COPY_F, "recipe.copy"); + DButton buttonDel = new DButtonIcon(64, 33, 20, 20, Resource.BTN_DEL_N, Resource.BTN_DEL_F, "recipe.clear"); + DButton buttonLabel = new DButtonIcon(45, 33, 20, 20, Resource.BTN_LABEL_N, Resource.BTN_LABEL_F, "recipe.label"); + DButton buttonYes = new DButtonIcon(7, 33, 20, 20, Resource.BTN_YES_N, Resource.BTN_YES_F, "recipe.confirm"); + DButton buttonNo = new DButtonIcon(26, 33, 20, 20, Resource.BTN_NO_N, Resource.BTN_NO_F, "recipe.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") + DButton buttonNew = new DButtonIcon(7, 33, 20, 20, Resource.BTN_NEW_N, Resource.BTN_NEW_F, "recipe.new") .setListenerLeft(() -> setModeNewGroup(true)); - public GuiEditor() { + public GuiRecipe() { 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 DIcon(7, 63, 21, 20, Resource.ICN_OUTPUT_N, Resource.ICN_OUTPUT_F, "recipe.output")); + add(new DIcon(7, 87, 21, 20, Resource.ICN_CATALYST_N, Resource.ICN_CATALYST_F, "recipe.catalyst")); + add(new DIcon(7, 111, 21, 40, Resource.ICN_INPUT_N, Resource.ICN_INPUT_F, "recipe.input")); add(new DLine(57)); addAll(groupInput, groupCatalyst, groupOutput); setModeNewGroup(false); diff --git a/src/main/java/me/towdium/jecalculation/core/labels/ILabel.java b/src/main/java/me/towdium/jecalculation/core/labels/ILabel.java index 3d31f57..8c1678e 100644 --- a/src/main/java/me/towdium/jecalculation/core/labels/ILabel.java +++ b/src/main/java/me/towdium/jecalculation/core/labels/ILabel.java @@ -28,7 +28,10 @@ public interface ILabel { RegistryDeserializer DESERIALIZER = RegistryDeserializer.INSTANCE; RegistryConverterItem CONVERTER_ITEM = RegistryConverterItem.INSTANCE; RegistryConverterFluid CONVERTER_FLUID = RegistryConverterFluid.INSTANCE; + RegistryEditor EDITOR = RegistryEditor.INSTANCE; ILabel EMPTY = new LabelItemStack(ItemStackHelper.EMPTY_ITEM_STACK, 0); + String LOCALIZE_PREFIX = "label"; + String LOCALIZE_SUFFIX = "name"; ILabel increaseAmount(); @@ -215,7 +218,7 @@ public interface ILabel { static { INSTANCE = new RegistryEditor(); - INSTANCE.register(LabelOreDict.getEditor(), "ore_dict", new LabelOreDict("ingotIron")); + INSTANCE.register(LabelOreDict.getEditor(), "common.label.ore_dict", new LabelOreDict("ingotIron")); } private ArrayList records = new ArrayList<>(); @@ -227,22 +230,22 @@ public interface ILabel { records.add(new Record(editor, unlocalizedName, representation)); } - public Collection getRecords() { + public List getRecords() { return records; } public interface IEditor extends IDrawable { - void setCallback(Consumer callback); + IEditor setCallback(Consumer callback); } public static class Record { public IEditor editor; - public String unlocalizedName; + public String localizeKey; public ILabel representation; - public Record(IEditor editor, String unlocalizedName, ILabel representation) { + public Record(IEditor editor, String localizeKey, ILabel representation) { this.editor = editor; - this.unlocalizedName = unlocalizedName; + this.localizeKey = localizeKey; this.representation = representation; } } 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 index 4c12012..ac3210f 100644 --- a/src/main/java/me/towdium/jecalculation/core/labels/labels/LabelOreDict.java +++ b/src/main/java/me/towdium/jecalculation/core/labels/labels/LabelOreDict.java @@ -1,6 +1,7 @@ package me.towdium.jecalculation.core.labels.labels; import me.towdium.jecalculation.client.gui.JecGui; +import me.towdium.jecalculation.client.gui.Resource; import me.towdium.jecalculation.client.gui.drawables.DContainer; import me.towdium.jecalculation.client.gui.drawables.DText; import me.towdium.jecalculation.core.labels.ILabel; @@ -11,12 +12,14 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraftforge.oredict.OreDictionary; +import javax.annotation.ParametersAreNonnullByDefault; import java.util.function.Consumer; /** * Author: towdium * Date: 17-9-10. */ +@ParametersAreNonnullByDefault public class LabelOreDict extends LabelSimpleAmount { public static final String IDENTIFIER = "oreDict"; public static final String KEY_NAME = "name"; @@ -65,8 +68,9 @@ public class LabelOreDict extends LabelSimpleAmount { is.getItem().getSubItems(is.getItem(), CreativeTabs.tabAllSearch, list); } else list.add(is); }); + if(list.isEmpty()) return; long index = System.currentTimeMillis() / 1500; - + gui.drawResource(Resource.LBL_ORE_DICT, 0, 0); GlStateManager.pushMatrix(); GlStateManager.translate(1, 1, 0); GlStateManager.scale(14f / 16, 14f / 16, 1); @@ -83,15 +87,22 @@ public class LabelOreDict extends LabelSimpleAmount { } public static class Editor extends DContainer implements RegistryEditor.IEditor { - Consumer label; + Consumer callback; public Editor() { add(new DText(5, 5, JecGui.Font.DEFAULT_NO_SHADOW, "hello")); } @Override - public void setCallback(Consumer callback) { - label = callback; + public RegistryEditor.IEditor setCallback(Consumer callback) { + this.callback = callback; + return this; + } + + @Override + public boolean onClicked(JecGui gui, int xMouse, int yMouse, int button) { + callback.accept(new LabelOreDict("plankWood")); + return super.onClicked(gui, xMouse, yMouse, button); } } } diff --git a/src/main/java/me/towdium/jecalculation/nei/JecaOverlayHandler.java b/src/main/java/me/towdium/jecalculation/nei/JecaOverlayHandler.java index 439078b..0d0f1d0 100644 --- a/src/main/java/me/towdium/jecalculation/nei/JecaOverlayHandler.java +++ b/src/main/java/me/towdium/jecalculation/nei/JecaOverlayHandler.java @@ -4,8 +4,7 @@ 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.client.gui.guis.GuiRecipe; import me.towdium.jecalculation.utils.ItemStackHelper; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.inventory.GuiContainer; @@ -33,7 +32,7 @@ public class JecaOverlayHandler implements IOverlayHandler { ItemStack outputStack = recipe.getResultStack(recipeIndex).items[0]; Minecraft mc = Minecraft.getMinecraft(); - JecGui.displayGui(new GuiEditor()); + JecGui.displayGui(new GuiRecipe()); GuiContainer myGuiContainer = (GuiContainer) mc.currentScreen; if (myGuiContainer != null) { myGuiContainer.inventorySlots.getSlot(0).putStack(outputStack); diff --git a/src/main/java/me/towdium/jecalculation/utils/helpers/LocalizationHelper.java b/src/main/java/me/towdium/jecalculation/utils/helpers/LocalizationHelper.java index c557fb0..d8b37b0 100644 --- a/src/main/java/me/towdium/jecalculation/utils/helpers/LocalizationHelper.java +++ b/src/main/java/me/towdium/jecalculation/utils/helpers/LocalizationHelper.java @@ -23,35 +23,7 @@ public class LocalizationHelper { return ret; } - /** - * @param c the (super) class name will be used after prefix translation key - * @param prefix the prefix of translation key - * @param translateKey the body of translation key - * @param parameters format parameters - * @return the localized value - * The localized key is "prefix.className(superClassName).translateKey". - * It will search all the super classes. - */ - public static Pair search(Class c, String prefix, String translateKey, Object... parameters) { - String clazz = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, c.getSimpleName()); - String key = String.join(".", prefix, clazz, translateKey); - Pair ret = LocalizationHelper.search(key, parameters); - if (ret.two || c.equals(Object.class)) - return ret; - else { - ret = search(c.getSuperclass(), prefix, translateKey, parameters); - if (ret.two) - return ret; - else - return ret.setOne(key); - } - } - public static String format(String translateKey, Object... parameters) { return search(translateKey, parameters).one; } - - public static String format(Class c, String prefix, String translateKey, Object... parameters) { - return search(c, prefix, translateKey, parameters).one; - } } diff --git a/src/main/resources/assets/jecalculation/lang/en_US.lang b/src/main/resources/assets/jecalculation/lang/en_US.lang index 47990dd..a3da9ad 100644 --- a/src/main/resources/assets/jecalculation/lang/en_US.lang +++ b/src/main/resources/assets/jecalculation/lang/en_US.lang @@ -10,6 +10,6 @@ command.state.s_client=client only command.state.s_both=client with server command.state.s_undefined=error state -gui.gui_calculator.tooltip.new_recipe=New recipe +gui.gui_calculator.name.new_recipe=New recipe config.force_client=Force Client diff --git a/src/main/resources/assets/jecalculation/textures/gui/resources.png b/src/main/resources/assets/jecalculation/textures/gui/resources.png index 626accea1aed012c3de4a661b3fab163eb61558f..86315cb2ede35a88ac860a47b819660514866e61 100644 GIT binary patch literal 10659 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

DwH`b2ZZGOUuw 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