From 08de334d98992ec995a9e03d72c6a49498975e27 Mon Sep 17 00:00:00 2001 From: Discreater Date: Thu, 29 Apr 2021 03:17:42 +0800 Subject: [PATCH] feat: mergers --- .../jecalculation/client/gui/JecGui.java | 8 ++- .../jecalculation/client/gui/Resource.java | 4 ++ .../client/gui/drawables/WButton.java | 13 +++-- .../client/gui/drawables/WButtonIcon.java | 29 ++++++++--- .../client/gui/drawables/WIcon.java | 2 +- .../client/gui/drawables/WLabel.java | 20 ++++++++ .../client/gui/drawables/WLabelGroup.java | 27 +++++----- .../client/gui/drawables/WSwitcher.java | 18 ++++++- .../client/gui/drawables/WTooltip.java | 16 ++++-- .../client/gui/guis/GuiDisambiguation.java | 30 ++++++++---- .../client/gui/guis/GuiRecipe.java | 46 ++++++++++++++---- .../jecalculation/core/labels/ILabel.java | 46 ++++++++++++++---- .../core/labels/labels/LabelItemStack.java | 4 ++ .../core/labels/labels/LabelOreDict.java | 4 ++ .../core/labels/labels/LabelSimpleAmount.java | 4 ++ .../jecalculation/utils/Utilities.java | 1 + .../jecalculation/utils/wrappers/Pair.java | 10 +++- .../jecalculation/textures/gui/resources.png | Bin 11800 -> 12657 bytes 18 files changed, 218 insertions(+), 64 deletions(-) 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 08123f6..1c12d60 100644 --- a/src/main/java/me/towdium/jecalculation/client/gui/JecGui.java +++ b/src/main/java/me/towdium/jecalculation/client/gui/JecGui.java @@ -128,7 +128,7 @@ public class JecGui extends GuiContainer { root.onDraw(this, mouseX - guiLeft, mouseY - guiTop); GlStateManager.popMatrix(); GlStateManager.pushMatrix(); - GlStateManager.translate(mouseX - 8, mouseY - 8, 0); + GlStateManager.translate(mouseX - 8, mouseY - 8, 80); hand.drawLabel(this); GlStateManager.popMatrix(); drawBufferedTooltip(); @@ -153,7 +153,7 @@ public class JecGui extends GuiContainer { /** * @return if the event is canceled - * This function handles click outside the normal region, + * This function handles click outside the rNormal region, * especially the overlap with JEI overlay. It handles * mouse event before JEI. */ @@ -277,12 +277,14 @@ public class JecGui extends GuiContainer { Tessellator tessellator = Tessellator.instance; GlStateManager.disableTexture2D(); GlStateManager.color(f, f1, f2, f3); + GlStateManager.disableAlpha(); tessellator.startDrawingQuads(); tessellator.addVertex((double) xPos, (double) bottom, 0.0D); tessellator.addVertex((double) right, (double) bottom, 0.0D); tessellator.addVertex((double) right, (double) yPos, 0.0D); tessellator.addVertex((double) xPos, (double) yPos, 0.0D); tessellator.draw(); + GlStateManager.enableAlpha(); GlStateManager.enableTexture2D(); } @@ -380,9 +382,11 @@ public class JecGui extends GuiContainer { xPos -= 8; yPos -= 8; } + GlStateManager.enableDepth(); RenderHelper.enableGUIStandardItemLighting(); itemRender.renderItemIntoGUI(fontRendererObj, mc.getTextureManager(), is, xPos, yPos); RenderHelper.disableStandardItemLighting(); + GlStateManager.disableDepth(); } public static class Font { 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 6b73927..9da9a12 100644 --- a/src/main/java/me/towdium/jecalculation/client/gui/Resource.java +++ b/src/main/java/me/towdium/jecalculation/client/gui/Resource.java @@ -26,6 +26,10 @@ public class Resource { public static final Resource BTN_YES_F = new Resource(84, 0, 14, 14); public static final Resource BTN_NO_N = new Resource(98, 14, 14, 14); public static final Resource BTN_NO_F = new Resource(98, 0, 14, 14); + public static final Resource BTN_DISAMB_D = new Resource(242, 0, 14, 14); + public static final Resource BTN_COPY_D = new Resource(242, 14, 14, 14); + public static final Resource BTN_DISAMB_N = new Resource(112, 14, 14, 14); + public static final Resource BTN_DISAMB_F = new Resource(112, 0, 14, 14); public static final Resource WGT_BUTTON_N = new Resource(40, 232, 20, 20); public static final Resource WGT_BUTTON_F = new Resource(60, 232, 20, 20); public static final Resource WGT_BUTTON_D = new Resource(80, 232, 20, 20); diff --git a/src/main/java/me/towdium/jecalculation/client/gui/drawables/WButton.java b/src/main/java/me/towdium/jecalculation/client/gui/drawables/WButton.java index 944403e..a90f7c9 100644 --- a/src/main/java/me/towdium/jecalculation/client/gui/drawables/WButton.java +++ b/src/main/java/me/towdium/jecalculation/client/gui/drawables/WButton.java @@ -17,6 +17,7 @@ public abstract class WButton extends WTooltip { protected int xPos, yPos, xSize, ySize; protected Runnable lsnrLeft, lsnrRight; protected Utilities.Timer timer = new Utilities.Timer(); + protected boolean disabled; public WButton(int xPos, int yPos, int xSize, int ySize, @Nullable String name) { super(name); @@ -38,9 +39,10 @@ public abstract class WButton extends WTooltip { @Override public void onDraw(JecGui gui, int xMouse, int yMouse) { + super.onDraw(gui, xMouse, 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); + gui.drawResourceContinuous(disabled ? Resource.WGT_BUTTON_D : + (hovered ? Resource.WGT_BUTTON_F : Resource.WGT_BUTTON_N), xPos, yPos, xSize, ySize, 3, 3, 3, 3); } @Override @@ -60,7 +62,12 @@ public abstract class WButton extends WTooltip { } @Override - boolean mouseIn(int xMouse, int yMouse) { + public boolean mouseIn(int xMouse, int yMouse) { return JecGui.mouseIn(xPos + 1, yPos + 1, xSize - 2, ySize - 2, xMouse, yMouse); } + + public WButton setDisabled(boolean b) { + disabled = b; + return this; + } } diff --git a/src/main/java/me/towdium/jecalculation/client/gui/drawables/WButtonIcon.java b/src/main/java/me/towdium/jecalculation/client/gui/drawables/WButtonIcon.java index e8f2734..6cd72e1 100644 --- a/src/main/java/me/towdium/jecalculation/client/gui/drawables/WButtonIcon.java +++ b/src/main/java/me/towdium/jecalculation/client/gui/drawables/WButtonIcon.java @@ -5,6 +5,9 @@ import me.towdium.jecalculation.client.gui.Resource; import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; /** * Author: towdium @@ -12,23 +15,33 @@ import javax.annotation.ParametersAreNonnullByDefault; */ @ParametersAreNonnullByDefault public class WButtonIcon extends WButton { - protected Resource normal, focused; + protected Resource rNormal, rFocused, rDisabled; public WButtonIcon(int xPos, int yPos, int xSize, int ySize, Resource normal, Resource focused) { - this(xPos, yPos, xSize, ySize, normal, focused, null); + this(xPos, yPos, xSize, ySize, normal, focused, null, null); } - public WButtonIcon(int xPos, int yPos, int xSize, int ySize, Resource normal, Resource focused, @Nullable String name) { + public WButtonIcon(int xPos, int yPos, int xSize, int ySize, Resource normal, Resource focused, String name) { + this(xPos, yPos, xSize, ySize, normal, focused, null, name); + } + + public WButtonIcon(int xPos, int yPos, int xSize, int ySize, Resource normal, Resource focused, + @Nullable Resource disabled, @Nullable String name) { super(xPos, yPos, xSize, ySize, name); - this.normal = normal; - this.focused = focused; + this.rNormal = normal; + this.rFocused = focused; + this.rDisabled = disabled; } @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); + Resource r = disabled ? rDisabled : (mouseIn(xMouse, yMouse) ? rFocused : rNormal); + if (r != null) gui.drawResource(r, xPos + (xSize - r.getXSize()) / 2, yPos + (ySize - r.getYSize()) / 2); + } + + @Override + protected List getSuffix() { + return disabled ? Arrays.asList("disabled", "active") : Collections.singletonList("active"); } } diff --git a/src/main/java/me/towdium/jecalculation/client/gui/drawables/WIcon.java b/src/main/java/me/towdium/jecalculation/client/gui/drawables/WIcon.java index 1272254..6799642 100644 --- a/src/main/java/me/towdium/jecalculation/client/gui/drawables/WIcon.java +++ b/src/main/java/me/towdium/jecalculation/client/gui/drawables/WIcon.java @@ -40,7 +40,7 @@ public class WIcon extends WTooltip { } @Override - boolean mouseIn(int xMouse, int yMouse) { + public 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/WLabel.java b/src/main/java/me/towdium/jecalculation/client/gui/drawables/WLabel.java index c9d7c9b..54da7cf 100644 --- a/src/main/java/me/towdium/jecalculation/client/gui/drawables/WLabel.java +++ b/src/main/java/me/towdium/jecalculation/client/gui/drawables/WLabel.java @@ -5,9 +5,11 @@ 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 me.towdium.jecalculation.utils.Utilities; import javax.annotation.ParametersAreNonnullByDefault; import java.util.ArrayList; +import java.util.stream.IntStream; /** * Author: towdium @@ -25,6 +27,7 @@ public class WLabel implements IWidget { public int xPos, yPos, xSize, ySize; public ILabel label; public enumMode mode; + protected Utilities.Timer timer = new Utilities.Timer(); public WLabel(int xPos, int yPos, int xSize, int ySize, enumMode mode) { this.xPos = xPos; @@ -59,8 +62,25 @@ public class WLabel implements IWidget { label.getToolTip(buf, mode == enumMode.EDITOR || mode == enumMode.RESULT)); } } + if (mode == enumMode.EDITOR || mode == enumMode.SELECTOR) { + timer.setState(gui.hand != ILabel.EMPTY); + int color = 0xFFFFFF + (int) ((-Math.cos(timer.getTime() * Math.PI / 1500) + 1) * 0x40) * 0x1000000; + gui.drawRectangle(xPos + 1, yPos + 1, xSize - 2, ySize - 2, color); + } } + @Override + public boolean onScroll(JecGui gui, int xMouse, int yMouse, int diff) { + if (mouseIn(xMouse, yMouse) && mode == enumMode.EDITOR && label != ILabel.EMPTY) { + IntStream.range(0, Math.abs(diff)).forEach(i -> { + if (JecGui.isShiftDown()) label = diff > 0 ? label.increaseAmountLarge() : label.decreaseAmountLarge(); + else label = diff > 0 ? label.increaseAmount() : label.decreaseAmount(); + }); + return true; + } else return false; + } + + @Override public boolean onClicked(JecGui gui, int xMouse, int yMouse, int button) { if (mouseIn(xMouse, yMouse)) { diff --git a/src/main/java/me/towdium/jecalculation/client/gui/drawables/WLabelGroup.java b/src/main/java/me/towdium/jecalculation/client/gui/drawables/WLabelGroup.java index c855f2f..7a0d0d6 100644 --- a/src/main/java/me/towdium/jecalculation/client/gui/drawables/WLabelGroup.java +++ b/src/main/java/me/towdium/jecalculation/client/gui/drawables/WLabelGroup.java @@ -16,34 +16,33 @@ import java.util.stream.IntStream; * Date: 17-8-17. */ @ParametersAreNonnullByDefault -public class WLabelGroup implements IWidget { - ArrayList widgets = new ArrayList<>(); +public class WLabelGroup extends WContainer { + ArrayList labels = new ArrayList<>(); public WLabelGroup(int xPos, int yPos, int column, int row, WLabel.enumMode mode) { this(xPos, yPos, column, row, 18, 18, mode); } public WLabelGroup(int xPos, int yPos, int column, int row, int xSize, int ySize, WLabel.enumMode mode) { - IntStream.range(0, row).forEach(r -> IntStream.range(0, column).forEach( - c -> widgets.add(new WLabel(xPos + c * xSize, yPos + r * ySize, xSize, ySize, mode)))); + IntStream.range(0, row).forEach(r -> IntStream.range(0, column).forEach(c -> { + WLabel l = new WLabel(xPos + c * xSize, yPos + r * ySize, xSize, ySize, mode); + labels.add(l); + add(l); + })); } @Override - public void onDraw(JecGui gui, int xMouse, int yMouse) { - widgets.forEach(w -> w.onDraw(gui, xMouse, yMouse)); - } - - @Override - public boolean onClicked(JecGui gui, int xMouse, int yMouse, int button) { - return widgets.stream().anyMatch(w -> w.onClicked(gui, xMouse, yMouse, button)); + public void remove(IWidget w) { + super.remove(w); + if (w instanceof WLabel) labels.remove(w); } public Optional getLabelAt(int xMouse, int yMouse) { - return widgets.stream().filter(w -> w.mouseIn(xMouse, yMouse)).findFirst(); + return labels.stream().filter(w -> w.mouseIn(xMouse, yMouse)).findFirst(); } public void setLabel(List labels, int start) { Single i = new Single<>(start); - widgets.forEach(l -> l.setLabel(i.value < labels.size() ? labels.get(i.value++) : ILabel.EMPTY)); + this.labels.forEach(l -> l.setLabel(i.value < labels.size() ? labels.get(i.value++) : ILabel.EMPTY)); } -} +} \ No newline at end of file diff --git a/src/main/java/me/towdium/jecalculation/client/gui/drawables/WSwitcher.java b/src/main/java/me/towdium/jecalculation/client/gui/drawables/WSwitcher.java index a822e22..b705318 100644 --- a/src/main/java/me/towdium/jecalculation/client/gui/drawables/WSwitcher.java +++ b/src/main/java/me/towdium/jecalculation/client/gui/drawables/WSwitcher.java @@ -7,6 +7,7 @@ import me.towdium.jecalculation.utils.Utilities.Circulator; import javax.annotation.ParametersAreNonnullByDefault; import java.util.List; +import java.util.function.Consumer; import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; @@ -25,6 +26,7 @@ public class WSwitcher implements IWidget { protected WText wText; protected List keys; protected Circulator index; + public Consumer listener; public WSwitcher(int xPos, int yPos, int xSize, int total) { this(xPos, yPos, xSize, IntStream.rangeClosed(1, total) @@ -37,15 +39,22 @@ public class WSwitcher implements IWidget { 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()); + .setListenerLeft(() -> move(true)); right = new WButtonIcon(xPos + xSize - SIZE, yPos, SIZE, SIZE, Resource.WGT_ARR_R_N, Resource.WGT_ARR_R_F) - .setListenerLeft(() -> index.next()); + .setListenerLeft(() -> move(false)); wRect = new WRectangle(xPos + SIZE, yPos, xSize - 2 * SIZE, SIZE, JecGui.COLOR_GUI_GREY); wText = new WText(xPos + SIZE, yPos, xSize - 2 * SIZE, SIZE, JecGui.Font.DEFAULT_SHADOW, () -> keys.get(index.index())); index = new Circulator(keys.size()); } + protected void move(boolean forward) { + if (forward) index.next(); + else index.prev(); + + if (listener != null) listener.accept(index.index()); + } + @Override public void onDraw(JecGui gui, int xMouse, int yMouse) { Stream.of(left, right, wRect, wText).forEach(w -> w.onDraw(gui, xMouse, yMouse)); @@ -60,4 +69,9 @@ public class WSwitcher implements IWidget { public boolean onKey(JecGui gui, char ch, int code) { return Stream.of(left, right).anyMatch(w -> w.onKey(gui, ch, code)); } + + public WSwitcher setListener(Consumer listener) { + this.listener = listener; + return this; + } } diff --git a/src/main/java/me/towdium/jecalculation/client/gui/drawables/WTooltip.java b/src/main/java/me/towdium/jecalculation/client/gui/drawables/WTooltip.java index 473d31e..3546455 100644 --- a/src/main/java/me/towdium/jecalculation/client/gui/drawables/WTooltip.java +++ b/src/main/java/me/towdium/jecalculation/client/gui/drawables/WTooltip.java @@ -7,6 +7,8 @@ import me.towdium.jecalculation.utils.wrappers.Pair; import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; +import java.util.Collections; +import java.util.List; /** * Author: towdium @@ -16,7 +18,7 @@ import javax.annotation.ParametersAreNonnullByDefault; public abstract class WTooltip implements IWidget { @Nullable public String name; - Utilities.Timer timer = new Utilities.Timer(); + protected Utilities.Timer timer = new Utilities.Timer(); public WTooltip(@Nullable String name) { this.name = name; @@ -27,11 +29,17 @@ public abstract class WTooltip implements IWidget { if (name != null) { timer.setState(mouseIn(xMouse, yMouse)); if (timer.getTime() > 500) { - Pair str = Utilities.L18n.search(String.join(".", "gui", name, "tooltip")); - if (str.two || JecGui.ALWAYS_TOOLTIP) gui.drawTooltip(xMouse, yMouse, str.one); + String str = getSuffix().stream().map(s -> Utilities.L18n.search(String.join(".", "gui", name, s))) + .filter(p -> p.two).findFirst().map(p -> p.one) + .orElse(JecGui.ALWAYS_TOOLTIP ? String.join(".", "gui", name, getSuffix().get(0)) : null); + if (str != null) gui.drawTooltip(xMouse, yMouse, str); } } } - abstract boolean mouseIn(int xMouse, int yMouse); + protected List getSuffix() { + return Collections.singletonList("tooltip"); + } + + public abstract boolean mouseIn(int xMouse, int yMouse); } diff --git a/src/main/java/me/towdium/jecalculation/client/gui/guis/GuiDisambiguation.java b/src/main/java/me/towdium/jecalculation/client/gui/guis/GuiDisambiguation.java index 6580e21..a693c80 100644 --- a/src/main/java/me/towdium/jecalculation/client/gui/guis/GuiDisambiguation.java +++ b/src/main/java/me/towdium/jecalculation/client/gui/guis/GuiDisambiguation.java @@ -1,5 +1,6 @@ package me.towdium.jecalculation.client.gui.guis; +import me.towdium.jecalculation.client.gui.IWPicker; import me.towdium.jecalculation.client.gui.Resource; import me.towdium.jecalculation.client.gui.drawables.*; import me.towdium.jecalculation.core.labels.ILabel; @@ -8,26 +9,37 @@ import net.minecraft.item.ItemStack; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; import java.util.stream.IntStream; /** * Author: towdium * Date: 17-9-16. */ -public class GuiDisambiguation extends WContainer { - public GuiDisambiguation(List> iss) { - ArrayList labels = new ArrayList<>(); - IntStream.range(0, 50).forEach(i -> labels.add(new LabelOreDict(i % 2 == 0 ? "plankWood" : "ingotIron", i))); - WLabelScroll lsUp = new WLabelScroll(25, 48, 7, 3, WLabel.enumMode.RESULT, true).setLabels(labels); - WLabelScroll lsDown = new WLabelScroll(25, 105, 7, 3, WLabel.enumMode.RESULT, true).setLabels(labels); +public class GuiDisambiguation extends IWPicker.Simple { + protected WLabelScroll lsUp; + protected WLabelScroll lsDown; + protected List> record; + + public GuiDisambiguation(List> record) { + lsUp = new WLabelScroll(25, 48, 7, 3, WLabel.enumMode.PICKER, true); + lsDown = new WLabelScroll(25, 105, 7, 3, WLabel.enumMode.PICKER, true); + this.record = new ArrayList<>(record.stream().filter(iss -> !ILabel.CONVERTER_ITEM.toLabel(iss).isEmpty()) + .collect(Collectors.toSet())); WTextField tf = new WTextField(25, 24, 90); add(new WPanel()); - add(new WSwitcher(7, 7, 162, 5)); + add(new WSwitcher(7, 7, 162, this.record.size()).setListener(this::setPage)); add(new WIcon(149, 24, 20, 20, Resource.ICN_HELP_N, Resource.ICN_HELP_F, "disambiguation.help")); add(new WIcon(7, 48, 18, 54, Resource.ICN_LIST_N, Resource.ICN_LIST_F, "disambiguation.list")); add(new WIcon(7, 105, 18, 54, Resource.ICN_LABEL_N, Resource.ICN_LABEL_F, "disambiguation.label")); - add(new WSearch(i -> { - }, tf, lsUp, lsDown)); + add(new WSearch(i -> callback.ifPresent(c -> c.accept(i)), tf, lsUp, lsDown)); + + setPage(0); + } + + protected void setPage(int n) { + lsUp.setLabels(record.get(n).stream().map(ILabel.CONVERTER_ITEM::toLabel).collect(Collectors.toList())); + lsDown.setLabels(ILabel.CONVERTER_ITEM.toLabel(record.get(n))); } } diff --git a/src/main/java/me/towdium/jecalculation/client/gui/guis/GuiRecipe.java b/src/main/java/me/towdium/jecalculation/client/gui/guis/GuiRecipe.java index d2dd626..08b514a 100644 --- a/src/main/java/me/towdium/jecalculation/client/gui/guis/GuiRecipe.java +++ b/src/main/java/me/towdium/jecalculation/client/gui/guis/GuiRecipe.java @@ -1,14 +1,16 @@ package me.towdium.jecalculation.client.gui.guis; import codechicken.nei.recipe.IRecipeHandler; +import me.towdium.jecalculation.client.gui.JecGui; import me.towdium.jecalculation.client.gui.Resource; import me.towdium.jecalculation.client.gui.drawables.*; import me.towdium.jecalculation.core.labels.ILabel; import net.minecraft.item.ItemStack; -import java.util.ArrayList; -import java.util.List; +import java.util.*; +import java.util.function.BiConsumer; import java.util.stream.Collectors; +import java.util.stream.IntStream; import static me.towdium.jecalculation.client.gui.drawables.WLabel.enumMode.EDITOR; @@ -17,10 +19,19 @@ import static me.towdium.jecalculation.client.gui.drawables.WLabel.enumMode.EDIT * Date: 17-9-8. */ public class GuiRecipe extends WContainer { + List> disambiguation; WButton buttonSave = new WButtonIcon(26, 33, 20, 20, Resource.BTN_SAVE_N, Resource.BTN_SAVE_F, "recipe.save"); - WButton buttonCopy = new WButtonIcon(83, 33, 20, 20, Resource.BTN_COPY_N, Resource.BTN_COPY_F, "recipe.copy"); + WButton buttonCopy = new WButtonIcon(83, 33, 20, 20, Resource.BTN_COPY_N, Resource.BTN_COPY_F, Resource.BTN_COPY_D, + "recipe.copy").setDisabled(true); WButton buttonDel = new WButtonIcon(64, 33, 20, 20, Resource.BTN_DEL_N, Resource.BTN_DEL_F, "recipe.clear"); WButton buttonLabel = new WButtonIcon(45, 33, 20, 20, Resource.BTN_LABEL_N, Resource.BTN_LABEL_F, "recipe.label"); + WButton buttonDisamb = new WButtonIcon(102, 33, 20, 20, Resource.BTN_DISAMB_N, + Resource.BTN_DISAMB_F, Resource.BTN_DISAMB_D, "recipe.disamb").setDisabled(true).setListenerLeft(() -> { + if (disambiguation != null) JecGui.displayGui(new GuiDisambiguation(disambiguation).setCallback(l -> { + JecGui.displayParent(); + JecGui.getCurrent().hand = l; + })); + }); WButton buttonYes = new WButtonIcon(7, 33, 20, 20, Resource.BTN_YES_N, Resource.BTN_YES_F, "recipe.confirm"); WButton buttonNo = new WButtonIcon(26, 33, 20, 20, Resource.BTN_NO_N, Resource.BTN_NO_F, "recipe.abort"); WLabelGroup groupInput = new WLabelGroup(28, 111, 7, 2, 20, 20, EDITOR); @@ -43,18 +54,29 @@ public class GuiRecipe extends WContainer { public void setModeNewGroup(boolean b) { if (b) { - removeAll(buttonNew, buttonLabel, buttonDel, buttonCopy, buttonSave); + removeAll(buttonNew, buttonLabel, buttonDel, buttonCopy, buttonSave, buttonDisamb); addAll(buttonYes, buttonNo, textField); } else { - addAll(buttonNew, buttonLabel, buttonDel, buttonSave); // TODO buttonCopy + addAll(buttonNew, buttonLabel, buttonDel, buttonCopy, buttonSave, buttonDisamb); removeAll(buttonYes, buttonNo, textField); } } public void transfer(IRecipeHandler recipe, int recipeIndex) { - List> buf = new ArrayList<>(); - List input = new ArrayList<>(); - List output = new ArrayList<>(); + ArrayList> buf = new ArrayList<>(); + ArrayList input = new ArrayList<>(); + ArrayList output = new ArrayList<>(); + + BiConsumer, ILabel> merge = (list, label) -> IntStream.range(0, list.size()).filter(i -> { + Optional l = ILabel.MERGER.merge(list.get(i), label, true); + boolean ret = l.isPresent(); + if (ret) list.set(i, l.get()); + return ret; + }).findAny().orElseGet(() -> { + list.add(label); + return -1; + }); + List raw = new ArrayList<>(); List itemStacks = recipe.getIngredientStacks(recipeIndex).stream() @@ -64,13 +86,17 @@ public class GuiRecipe extends WContainer { raw.add(ILabel.CONVERTER_ITEM.toLabel(itemStack)); }); List guessed = ILabel.CONVERTER_ITEM.toLabel(itemStacks); - input.add(guessed.isEmpty() ? ILabel.CONVERTER_ITEM.toLabel(itemStacks.get(0)) : guessed.get(0)); - buf.add(raw); + merge.accept(input, guessed.isEmpty() ? ILabel.CONVERTER_ITEM.toLabel(itemStacks.get(0)) : guessed.get(0)); + + buf.add(itemStacks); ItemStack outputStack = recipe.getResultStack(recipeIndex).item; output.add(ILabel.CONVERTER_ITEM.toLabel(outputStack)); + buf.add(Collections.singletonList(outputStack)); groupInput.setLabel(input, 0); groupOutput.setLabel(output, 0); + disambiguation = buf; + buttonDisamb.setDisabled(buf.isEmpty()); } } 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 4c89d96..765f2e2 100644 --- a/src/main/java/me/towdium/jecalculation/core/labels/ILabel.java +++ b/src/main/java/me/towdium/jecalculation/core/labels/ILabel.java @@ -91,8 +91,11 @@ public interface ILabel { static { INSTANCE = new RegistryMerger(); // registerGuess functions here + INSTANCE.register("itemStack", "itemStack", RegistryMerger::mergeItemStackNItemStack); + INSTANCE.register("oreDict", "oreDict", RegistryMerger::mergeOreDictNOreDict); } + private Relation functions = new Relation<>(); @@ -103,20 +106,43 @@ public interface ILabel { functions.add(a, b, func); } - public Pair merge(ILabel a, ILabel b, boolean add) { - return functions.get(ILabel.getIdentifier(a), ILabel.getIdentifier(b)) - .orElse((x, y, f) -> new Pair<>(x, y)).merge(a, b, add); + static Optional mergeItemStackNItemStack(ILabel a, ILabel b, boolean add) { + if (a instanceof LabelItemStack && b instanceof LabelItemStack) { + LabelItemStack lisA = (LabelItemStack) a; + LabelItemStack lisB = (LabelItemStack) b; + ItemStack isA = lisA.getItemStack(); + ItemStack isB = lisB.getItemStack(); + if (isA.getItem() == isB.getItem() && isA.getItemDamage() == isB.getItemDamage() && + (isA.getTagCompound() == null ? !isB.hasTagCompound() : + isA.getTagCompound().equals(isB.getTagCompound()))) { + LabelItemStack ret = new LabelItemStack(lisA.getItemStack(), + add ? lisA.getAmount() + lisB.getAmount() : lisA.getAmount() - lisB.getAmount()); + return Optional.of(ret); + } + } + return Optional.empty(); } - public boolean test(ILabel a, ILabel b) { - Optional f = functions.get(ILabel.getIdentifier(a), ILabel.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)); + static Optional mergeOreDictNOreDict(ILabel a, ILabel b, boolean add) { + if (a instanceof LabelOreDict && b instanceof LabelOreDict) { + LabelOreDict lodA = (LabelOreDict) a; + LabelOreDict lodB = (LabelOreDict) b; + if (lodA.getName().equals(lodB.getName())) + return Optional.of(new LabelOreDict(lodA.getName(), + add ? lodA.getAmount() + lodB.getAmount() : lodA.getAmount() - lodB.getAmount())); } + return Optional.empty(); } + public Optional merge(ILabel a, ILabel b, boolean add) { + Optional ret = functions.get(ILabel.getIdentifier(a), ILabel.getIdentifier(b)) + .orElse((x, y, f) -> Optional.empty()).merge(a, b, add); + if (ret.isPresent() && (ret.get() == a || ret.get() == b)) + throw new RuntimeException("Merger should not modify the given labels."); + return ret; + } + + @FunctionalInterface public interface MergerFunction { /** @@ -125,7 +151,7 @@ public interface ILabel { * @param add add together or cancel each other * @return merged {@link ILabel label(s)} if not changed (no matter order), they cannot merge. */ - Pair merge(ILabel a, ILabel b, boolean add); + Optional merge(ILabel a, ILabel b, boolean add); } } 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 index 5fdf682..ad711e0 100644 --- a/src/main/java/me/towdium/jecalculation/core/labels/labels/LabelItemStack.java +++ b/src/main/java/me/towdium/jecalculation/core/labels/labels/LabelItemStack.java @@ -75,4 +75,8 @@ public class LabelItemStack extends LabelSimpleAmount { public boolean equals(Object obj) { return obj instanceof LabelItemStack && itemStack.equals(((LabelItemStack) obj).itemStack); } + + public ItemStack getItemStack() { + return itemStack; + } } 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 da1a3c3..8a355a4 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 @@ -101,4 +101,8 @@ public class LabelOreDict extends LabelSimpleAmount { existing.add(FORMAT_BLUE + FORMAT_ITALIC + JustEnoughCalculation.Reference.MODNAME); return existing; } + + public String getName() { + return name; + } } diff --git a/src/main/java/me/towdium/jecalculation/core/labels/labels/LabelSimpleAmount.java b/src/main/java/me/towdium/jecalculation/core/labels/labels/LabelSimpleAmount.java index 93a9202..2cdac9c 100644 --- a/src/main/java/me/towdium/jecalculation/core/labels/labels/LabelSimpleAmount.java +++ b/src/main/java/me/towdium/jecalculation/core/labels/labels/LabelSimpleAmount.java @@ -77,4 +77,8 @@ public abstract class LabelSimpleAmount implements ILabel { nbt.setInteger(KEY_AMOUNT, amount); return nbt; } + + public int getAmount() { + return amount; + } } diff --git a/src/main/java/me/towdium/jecalculation/utils/Utilities.java b/src/main/java/me/towdium/jecalculation/utils/Utilities.java index 8c61458..f126d2f 100644 --- a/src/main/java/me/towdium/jecalculation/utils/Utilities.java +++ b/src/main/java/me/towdium/jecalculation/utils/Utilities.java @@ -98,6 +98,7 @@ public class Utilities { } + @SuppressWarnings("UnusedReturnValue") public static class Circulator { int total, current; 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 b3fe9f7..10794ab 100644 --- a/src/main/java/me/towdium/jecalculation/utils/wrappers/Pair.java +++ b/src/main/java/me/towdium/jecalculation/utils/wrappers/Pair.java @@ -15,9 +15,17 @@ public class Pair { @Override public int hashCode() { - return one.hashCode() ^ two.hashCode(); + 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 6f55f2710561d407a16f7789a5181ccd6df6a8d6..7269ece62e10366adf061464ee6b4c386f53aee0 100644 GIT binary patch literal 12657 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 literal 11800 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