diff --git a/src/main/java/me/towdium/jecalculation/data/capability/JecaCapabilityProvider.java b/src/main/java/me/towdium/jecalculation/data/capability/JecaCapabilityProvider.java deleted file mode 100644 index 2db66a8..0000000 --- a/src/main/java/me/towdium/jecalculation/data/capability/JecaCapabilityProvider.java +++ /dev/null @@ -1,37 +0,0 @@ -package me.towdium.jecalculation.data.capability; - -import me.towdium.jecalculation.JustEnoughCalculation; -import me.towdium.jecalculation.data.structure.Recipes; -import net.minecraft.entity.Entity; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.world.World; -import net.minecraftforge.common.IExtendedEntityProperties; - -@Deprecated -public class JecaCapabilityProvider implements IExtendedEntityProperties { - public final static String PROPERTIES_NAME = JustEnoughCalculation.Reference.MODID + ".record"; - public Recipes record; - protected Entity theEntity; - protected World theWorld; - - public JecaCapabilityProvider(Recipes record) { - this.record = record; - } - - @Override - public void saveNBTData(NBTTagCompound compound) { - JustEnoughCalculation.logger.info("ExtendedProperties save NBTData()"); - } - - @Override - public void loadNBTData(NBTTagCompound compound) { - JustEnoughCalculation.logger.info("ExtendedProperties load NBTData()"); - } - - @Override - public void init(Entity entity, World world) { - JustEnoughCalculation.logger.info("ExtendedProperties init()"); - this.theEntity = entity; - this.theWorld = world; - } -} \ No newline at end of file diff --git a/src/main/java/me/towdium/jecalculation/data/label/ILabel.java b/src/main/java/me/towdium/jecalculation/data/label/ILabel.java index 18e6f0f..6d8d644 100644 --- a/src/main/java/me/towdium/jecalculation/data/label/ILabel.java +++ b/src/main/java/me/towdium/jecalculation/data/label/ILabel.java @@ -411,9 +411,6 @@ public interface ILabel { return IDENTIFIER; } -// @Override -// public void drawLabel(JecaGui gui, int xPos, int yPos, boolean center) { -// } } abstract class Impl implements ILabel { diff --git a/src/main/java/me/towdium/jecalculation/data/label/labels/LOreDict.java b/src/main/java/me/towdium/jecalculation/data/label/labels/LOreDict.java index 23465e7..e0ce426 100644 --- a/src/main/java/me/towdium/jecalculation/data/label/labels/LOreDict.java +++ b/src/main/java/me/towdium/jecalculation/data/label/labels/LOreDict.java @@ -69,6 +69,7 @@ public class LOreDict extends ILabel.Impl { if (a instanceof LOreDict && b instanceof LItemStack) { LOreDict lod = (LOreDict) a; LItemStack lis = (LItemStack) b; + // TODO check performance if (lod.getAmount() * lis.getAmount() < 0) { for (ItemStack ore : OreDictionary.getOres(lod.name)) { if (LItemStack.merge(Converter.from(ore), lis)) { diff --git a/src/main/java/me/towdium/jecalculation/data/structure/Recipe.java b/src/main/java/me/towdium/jecalculation/data/structure/Recipe.java index b2a4b05..e34f7e4 100644 --- a/src/main/java/me/towdium/jecalculation/data/structure/Recipe.java +++ b/src/main/java/me/towdium/jecalculation/data/structure/Recipe.java @@ -16,6 +16,7 @@ import java.util.function.BiPredicate; import java.util.function.Consumer; import java.util.function.Function; import java.util.stream.Collectors; +import java.util.stream.Stream; import java.util.stream.StreamSupport; /** @@ -38,19 +39,11 @@ public class Recipe { } public Recipe(List input, List catalyst, List output) { - Consumer> check = ls -> { - boolean ret = false; - for (ILabel i : ls) { - Objects.requireNonNull(i); - if (i != ILabel.EMPTY) - ret = true; - } - if (!ret || ls.get(ls.size() - 1) == ILabel.EMPTY) - throw new IllegalArgumentException("Invalid recipe"); - }; - check.accept(input); - check.accept(catalyst); - check.accept(output); + boolean a = Stream.of(input, output, catalyst).anyMatch(i -> + !i.isEmpty() && i.get(i.size() - 1) == ILabel.EMPTY); + boolean b = Stream.of(input, output).anyMatch(i -> + i.stream().allMatch(j -> j == ILabel.EMPTY)); + if (a || b) throw new IllegalArgumentException("Invalid recipe"); this.input = input; this.catalyst = catalyst; this.output = output; @@ -155,10 +148,6 @@ public class Recipe { } public enum IO { - INPUT, OUTPUT, CATALYST; - - public int getSize() { - return this == INPUT ? 16 : 8; - } + INPUT, OUTPUT, CATALYST } } diff --git a/src/main/java/me/towdium/jecalculation/data/structure/RecordCraft.java b/src/main/java/me/towdium/jecalculation/data/structure/RecordCraft.java index 25f4cc5..b0ddc8b 100644 --- a/src/main/java/me/towdium/jecalculation/data/structure/RecordCraft.java +++ b/src/main/java/me/towdium/jecalculation/data/structure/RecordCraft.java @@ -19,10 +19,12 @@ public class RecordCraft implements IRecord { public static final String KEY_RECENTS = "recents"; public static final String KEY_AMOUNT = "amount"; public static final String KEY_INVENTORY = "inventory"; + public static final String KEY_MODE = "mode"; Utilities.Recent record = new Utilities.Recent<>((a, b) -> a == ILabel.EMPTY || a.equals(b), 9); public String amount; public boolean inventory; + public Mode mode; public RecordCraft(NBTTagCompound nbt) { List ls = StreamSupport.stream(NBTHelper.spliterator(nbt.getTagList(KEY_RECENTS, 10)), false) @@ -32,8 +34,14 @@ public class RecordCraft implements IRecord { new Utilities.ReversedIterator<>(ls).forEachRemaining(l -> record.push(l, false)); amount = nbt.getString(KEY_AMOUNT); inventory = nbt.getBoolean(KEY_INVENTORY); + String s = nbt.getString(KEY_MODE); + mode = Mode.INPUT; + for (Mode m : Mode.values()) { + if (s.equals(m.toString().toLowerCase())) mode = m; + } } + // return true if any existing matches public boolean push(ILabel label, boolean replace) { return record.push(label, replace); } @@ -54,6 +62,11 @@ public class RecordCraft implements IRecord { NBTTagList recent = new NBTTagList(); record.toList().forEach(l -> recent.appendTag(ILabel.SERIALIZER.serialize(l))); ret.setTag(KEY_RECENTS, recent); + ret.setString(KEY_MODE, mode.toString().toLowerCase()); return ret; } + + public enum Mode { + INPUT, OUTPUT, CATALYST, STEPS + } } diff --git a/src/main/java/me/towdium/jecalculation/gui/JecaGui.java b/src/main/java/me/towdium/jecalculation/gui/JecaGui.java index eac084e..4b9769d 100644 --- a/src/main/java/me/towdium/jecalculation/gui/JecaGui.java +++ b/src/main/java/me/towdium/jecalculation/gui/JecaGui.java @@ -57,6 +57,8 @@ public class JecaGui extends GuiContainer { public static final int COLOR_TEXT_GREY = 0x404040; public static final int COLOR_TEXT_WHITE = 0xFFFFFF; public static final boolean ALWAYS_TOOLTIP = false; + @SuppressWarnings("StringOperationCanBeSimplified") + public static final String SEPARATOR = new String(); public ILabel hand = ILabel.EMPTY; protected static JecaGui last; protected static Runnable scheduled; @@ -69,7 +71,7 @@ public class JecaGui extends GuiContainer { } public JecaGui(@Nullable JecaGui parent, boolean acceptsTransfer, IGui root) { - super(acceptsTransfer ? new ContainerTransfer() : new ContainerNonTransfer()); + super(acceptsTransfer ? new JecaGui.ContainerTransfer() : new JecaGui.ContainerNonTransfer()); this.parent = parent; this.root = root; if (inventorySlots instanceof JecaContainer) @@ -293,14 +295,19 @@ public class JecaGui extends GuiContainer { GlStateManager.disableLighting(); GlStateManager.disableDepth(); int i = 0; + int separators = 0; for (String s : textLines) { int j = this.fontRendererObj.getStringWidth(s); if (j > i) i = j; + //noinspection StringEquality + if (s == JecaGui.SEPARATOR) separators++; } + //noinspection StringEquality + if (textLines.get(textLines.size() - 1) == SEPARATOR) separators--; int l1 = x + 12; int i2 = y - 12; - int k = 8 + (textLines.size() - 1) * 10; + int k = 8 + (textLines.size() - separators - 1) * 10 + 2 * separators; if (l1 + i > this.width) l1 -= 28 + i; if (i2 + k + 6 > this.height) @@ -317,8 +324,12 @@ public class JecaGui extends GuiContainer { drawGradientRect(l1 - 3, i2 - 3, l1 + i + 3, i2 - 3 + 1, 1347420415, 1347420415); drawGradientRect(l1 - 3, i2 + k + 2, l1 + i + 3, i2 + k + 3, 1344798847, 1344798847); for (String s1 : textLines) { - fontRendererObj.drawStringWithShadow(s1, l1, i2, -1); - i2 += 10; + //noinspection StringEquality + if (s1 == SEPARATOR) i2 += 2; + else { + font.drawStringWithShadow(s1, l1, i2, -1); + i2 += 10; + } } zLevel = 0.0F; itemRender.zLevel = 0.0F; diff --git a/src/main/java/me/towdium/jecalculation/gui/Resource.java b/src/main/java/me/towdium/jecalculation/gui/Resource.java index 8edf798..91637d4 100644 --- a/src/main/java/me/towdium/jecalculation/gui/Resource.java +++ b/src/main/java/me/towdium/jecalculation/gui/Resource.java @@ -18,6 +18,7 @@ public class Resource { JustEnoughCalculation.Reference.MODID, "textures/gui/resources.png"); // letters abbr for button & icon: N - normal, F - focused, D - disabled // letters abbr for fuzzy related: N - normal, F - fuzzy + // letters abbr for state related: N - normal, A - active public static final Resource BTN_LABEL_N = getIcon(0, 1); public static final Resource BTN_LABEL_F = getIcon(0, 0); public static final Resource BTN_NEW_N = getIcon(1, 1); @@ -92,6 +93,12 @@ public class Resource { public static final Resource BTN_DELETE_1_N = getIcon(9, 4); public static final Resource BTN_DELETE_1_F = getIcon(9, 3); public static final Resource BTN_DELETE_1_D = getIcon(9, 5); + public static final Resource BTN_DOWN_N_N = getIcon(10, 4); + public static final Resource BTN_DOWN_N_F = getIcon(10, 3); + public static final Resource BTN_DOWN_A_N = getIcon(11, 4); + public static final Resource BTN_DOWN_A_F = getIcon(11, 3); + public static final Resource BTN_UP_N_N = getIcon(12, 4); + public static final Resource BTN_UP_N_F = getIcon(12, 3); public static final Resource WGT_BUTTON_N = getWidget(0); public static final Resource WGT_BUTTON_F = getWidget(1); @@ -112,7 +119,8 @@ public class Resource { public static final Resource WGT_ARR_R_F = new Resource(112, 142, 7, 10); public static final Resource WGT_ARR_R_N = new Resource(119, 142, 7, 10); public static final Resource WGT_ARR_R_D = new Resource(126, 142, 7, 10); - public static final Resource WGT_SCROLL = new Resource(133, 132, 14, 17); + public static final Resource WGT_SCROLL_N = new Resource(133, 132, 14, 10); + public static final Resource WGT_SCROLL_F = new Resource(133, 142, 14, 10); public static final Resource WGT_HELP_F = new Resource(147, 132, 20, 20); public static final Resource WGT_HELP_N = new Resource(167, 132, 20, 20); public static final Resource WGT_LCD_UL_F = new Resource(187, 132, 4, 16); @@ -192,6 +200,9 @@ public class Resource { public static final ResourceGroup BTN_PICK = new ResourceGroup(BTN_PICK_N, BTN_PICK_F); public static final ResourceGroup BTN_DELETE_N = new ResourceGroup(BTN_DELETE_N_N, BTN_DELETE_N_F, BTN_DELETE_N_D); public static final ResourceGroup BTN_DELETE_1 = new ResourceGroup(BTN_DELETE_1_N, BTN_DELETE_1_F, BTN_DELETE_1_D); + public static final ResourceGroup BTN_DOWN_N = new ResourceGroup(BTN_DOWN_N_N, BTN_DOWN_N_F); + public static final ResourceGroup BTN_DOWN_A = new ResourceGroup(BTN_DOWN_A_N, BTN_DOWN_A_F); + public static final ResourceGroup BTN_UP_N = new ResourceGroup(BTN_UP_N_N, BTN_UP_N_F); public static final ResourceGroup WGT_ARR_L = new ResourceGroup(WGT_ARR_L_N, WGT_ARR_L_F, WGT_ARR_L_D); public static final ResourceGroup WGT_ARR_R = new ResourceGroup(WGT_ARR_R_N, WGT_ARR_R_F, WGT_ARR_R_D); diff --git a/src/main/java/me/towdium/jecalculation/gui/guis/GuiCraft.java b/src/main/java/me/towdium/jecalculation/gui/guis/GuiCraft.java index 198def6..07d2136 100644 --- a/src/main/java/me/towdium/jecalculation/gui/guis/GuiCraft.java +++ b/src/main/java/me/towdium/jecalculation/gui/guis/GuiCraft.java @@ -25,6 +25,8 @@ import java.util.function.Consumer; import java.util.stream.Collectors; import java.util.stream.Stream; +import static me.towdium.jecalculation.data.structure.RecordCraft.Mode.*; + /** * Author: towdium * Date: 8/14/17. @@ -33,28 +35,25 @@ import java.util.stream.Stream; @MethodsReturnNonnullByDefault @SideOnly(Side.CLIENT) public class GuiCraft extends WContainer implements IGui { - Mode mode = Mode.INPUT; ItemStack itemStack; Calculator calculator = null; RecordCraft record; - WLabelGroup recent = new WLabelGroup(7, 31, 8, 1, false, false).setLsnrClick( - (i, v) -> JecaGui.getCurrent().hand = i.get(v).getLabel()); - WLabelScroll result = new WLabelScroll(7, 87, 8, 4, true, false, false, true).setListener((i, v) -> { + WLabel label = new WLabel(31, 7, 20, 20, true).setLsnrUpdate((i, v) -> refreshLabel(v, false, true)); + WLabelGroup recent = new WLabelGroup(7, 31, 8, 1, false).setLsnrClick( + (i, v) -> label.setLabel(i.get(v).getLabel().copy(), true)); + WLabelScroll result = new WLabelScroll(7, 87, 8, 4, false).setLsnrClick((i, v) -> { Object rep = i.get(v).getLabel().getRepresentation(); NEIPlugin.openRecipeGui(rep, Mouse.getEventButton()); - }).setFormatter(i -> i.getAmountString(true)); - WButton steps = new WButtonIcon(64, 62, 20, 20, Resource.BTN_LIST, "craft.step").setListener( - i -> setMode(Mode.STEPS)); + }).setFmtAmount(i -> i.getAmountString(true)).setFmtTooltip((i, j) -> i.getToolTip(j, true)); + WButton steps = new WButtonIcon(64, 62, 20, 20, Resource.BTN_LIST, "craft.step").setListener(i -> setMode(STEPS)); WButton catalyst = new WButtonIcon(45, 62, 20, 20, Resource.BTN_CAT, "common.catalyst").setListener( - i -> setMode(Mode.CATALYST)); + i -> setMode(CATALYST)); WButton output = new WButtonIcon(26, 62, 20, 20, Resource.BTN_OUT, "craft.output").setListener( - i -> setMode(Mode.OUTPUT)); - WButton input = new WButtonIcon(7, 62, 20, 20, Resource.BTN_IN, "common.input").setListener( - i -> setMode(Mode.INPUT)); - WLabel label = new WLabel(31, 7, 20, 20, false, true).setLsnrUpdate((i, v) -> refreshLabel(v, false, true)); + i -> setMode(OUTPUT)); + WButton input = new WButtonIcon(7, 62, 20, 20, Resource.BTN_IN, "common.input").setListener(i -> setMode(INPUT)); WButton invE = new WButtonIcon(149, 62, 20, 20, Resource.BTN_INV_E, "craft.inventory_enabled"); WButton invD = new WButtonIcon(149, 62, 20, 20, Resource.BTN_INV_D, "craft.inventory_disabled"); - WTextField amount = new WTextField(60, 7, 65).setText(record.amount).setListener(i -> { + WTextField amount = new WTextField(60, 7, 65).setListener(i -> { record.amount = i.getText(); Controller.setRCraft(record); refreshCalculator(); @@ -62,6 +61,8 @@ public class GuiCraft extends WContainer implements IGui { public GuiCraft() { + record = Controller.getRCraft(); + amount.setText(record.amount); add(new WHelp("craft")); add(new WPanel()); add(new WButtonIcon(7, 7, 20, 20, Resource.BTN_LABEL, "craft.label").setListener( @@ -92,7 +93,7 @@ public class GuiCraft extends WContainer implements IGui { refreshCalculator(); }); refreshRecent(); - setMode(Mode.INPUT); + setMode(record.mode); } @Override @@ -100,12 +101,13 @@ public class GuiCraft extends WContainer implements IGui { refreshCalculator(); } - void setMode(Mode mode) { - this.mode = mode; - input.setDisabled(mode == Mode.INPUT); - output.setDisabled(mode == Mode.OUTPUT); - catalyst.setDisabled(mode == Mode.CATALYST); - steps.setDisabled(mode == Mode.STEPS); + void setMode(RecordCraft.Mode mode) { + record.mode = mode; + Controller.setRCraft(record); + input.setDisabled(mode == INPUT); + output.setDisabled(mode == OUTPUT); + catalyst.setDisabled(mode == CATALYST); + steps.setDisabled(mode == STEPS); refreshResult(); } @@ -145,7 +147,7 @@ public class GuiCraft extends WContainer implements IGui { if (calculator == null) { result.setLabels(new ArrayList<>()); } else { - switch (mode) { + switch (record.mode) { case INPUT: result.setLabels(calculator.getInputs()); break; @@ -193,10 +195,6 @@ public class GuiCraft extends WContainer implements IGui { .collect(Collectors.toList()); } - enum Mode { - INPUT, OUTPUT, CATALYST, STEPS - } - class Suggest extends WOverlay { boolean replace; @@ -204,12 +202,12 @@ public class GuiCraft extends WContainer implements IGui { this.replace = replace; int width = labels.size() * 20; add(new WPanel(-width, 2, 56 + width, 30)); - add(new WLabel(31, 7, 20, 20, false, false).setLabel(label.getLabel()).setLsnrUpdate((i, v) -> refresh(v))); + add(new WLabel(31, 7, 20, 20, false).setLabel(label.getLabel()).setLsnrUpdate((i, v) -> refresh(v))); add(new WIcon(5 - width, 7, 18, 20, Resource.ICN_HELP, "craft.suggest")); add(new WLine(26, 7, 20, false)); for (int i = 0; i < labels.size(); i++) { - add(new WLabel(3 - i * 20, 7, 20, 20, false, false).setLabel(labels.get(i)) - .setLsnrUpdate((j, v) -> refresh(v))); + add(new WLabel(3 - i * 20, 7, 20, 20, false).setLabel(labels.get(i)) + .setLsnrUpdate((j, v) -> refresh(v))); } } diff --git a/src/main/java/me/towdium/jecalculation/gui/guis/GuiRecipe.java b/src/main/java/me/towdium/jecalculation/gui/guis/GuiRecipe.java index 62d0f32..27889ba 100644 --- a/src/main/java/me/towdium/jecalculation/gui/guis/GuiRecipe.java +++ b/src/main/java/me/towdium/jecalculation/gui/guis/GuiRecipe.java @@ -1,6 +1,8 @@ package me.towdium.jecalculation.gui.guis; import codechicken.nei.recipe.IRecipeHandler; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; import me.towdium.jecalculation.data.Controller; import me.towdium.jecalculation.data.label.ILabel; import me.towdium.jecalculation.data.structure.CostList; @@ -10,16 +12,15 @@ import me.towdium.jecalculation.gui.JecaGui; import me.towdium.jecalculation.gui.widgets.*; import me.towdium.jecalculation.nei.Adapter; import me.towdium.jecalculation.nei.NEIPlugin; +import me.towdium.jecalculation.polyfill.MethodsReturnNonnullByDefault; import me.towdium.jecalculation.utils.Utilities; import me.towdium.jecalculation.utils.wrappers.Pair; import me.towdium.jecalculation.utils.wrappers.Trio; +import net.minecraft.item.ItemStack; import org.lwjgl.input.Keyboard; import javax.annotation.ParametersAreNonnullByDefault; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; +import java.util.*; import java.util.stream.Collectors; import static me.towdium.jecalculation.gui.JecaGui.COLOR_TEXT_RED; @@ -31,49 +32,28 @@ import static me.towdium.jecalculation.gui.Resource.*; * Author: towdium * Date: 17-9-8. */ +@MethodsReturnNonnullByDefault @ParametersAreNonnullByDefault +@SideOnly(Side.CLIENT) public class GuiRecipe extends WContainer implements IGui { Pair dest; - // HashMap> disambCache = new HashMap<>(); WSwitcher group = new WSwitcher(7, 7, 162, Controller.getGroups()).setListener(i -> refresh()); WTextField text = new WTextField(49, 32, 119); - List input = new ArrayList<>(); - List output = new ArrayList<>(); - List catalyst = new ArrayList<>(); - WLabelGroup mid = new WLabelGroup(29, 87, 7, 1, 20, 20, true, true); - WLabelGroup down = new WLabelGroup(29, 111, 7, 2, 20, 20, true, true); - WLabelGroup up = new WLabelGroup(29, 63, 7, 1, 20, 20, true, true); - // WLabelGroup catalyst = new WLabelGroup(29, 87, 7, 1, 20, 20, WLabel.Mode.EDITOR).setListener((i, v) -> { - // disambCache.remove(v + 14); - // refresh(); - // }); - // WLabelGroup input = new WLabelGroup(29, 111, 7, 2, 20, 20, WLabel.Mode.EDITOR).setListener((i, v) -> { - // disambCache.remove(v); - // refresh(); - // }); - // WLabelGroup output = new WLabelGroup(29, 63, 7, 1, 20, 20, WLabel.Mode.EDITOR).setListener((i, v) -> { - // disambCache.remove(v + 21); - // refresh(); - // }); - // WButton disamb = new WButtonIcon(102, 32, 20, 20, BTN_DISAMB, "recipe.disamb").setListener(i -> { - // if (disambCache != null) - // JecaGui.displayGui(new GuiDisamb(new ArrayList<>(disambCache.values())).setCallback(l -> { - // JecaGui.displayParent(); - // JecaGui.getCurrent().hand = l; - // })); - // }); - WButton clear = new WButtonIcon(64, 32, 20, 20, BTN_DEL, "recipe.clear").setListener(i -> reset()); + WLabelScroll catalyst = new WLabelScroll(25, 101, 7, 1, true); + WLabelScroll input = new WLabelScroll(25, 123, 7, 2, true); + WLabelScroll output = new WLabelScroll(25, 61, 7, 2, true); + WButton clear = new WButtonIcon(64, 25, 20, 20, BTN_DEL, "recipe.clear").setListener(i -> reset()); // check duplicate and valid - WButton copy = new WButtonIcon(83, 32, 20, 20, BTN_COPY, "recipe.copy").setListener(i -> { + WButton copy = new WButtonIcon(83, 25, 20, 20, BTN_COPY, "recipe.copy").setListener(i -> { Controller.addRecipe(group.getText(), toRecipe()); JecaGui.displayParent(); }); - WButton label = new WButtonIcon(45, 32, 20, 20, BTN_LABEL, "recipe.label").setListener( + WButton label = new WButtonIcon(45, 25, 20, 20, BTN_LABEL, "recipe.label").setListener( i -> JecaGui.displayGui(new GuiLabel((l) -> { JecaGui.displayParent(); JecaGui.getCurrent().hand = l; }))); - WButton save = new WButtonIcon(26, 32, 20, 20, BTN_SAVE, "recipe.save").setDisabled(true).setListener(i -> { + WButton save = new WButtonIcon(26, 25, 20, 20, BTN_SAVE, "recipe.save").setDisabled(true).setListener(i -> { if (dest == null) Controller.addRecipe(group.getText(), toRecipe()); else { @@ -85,36 +65,47 @@ public class GuiRecipe extends WContainer implements IGui { } JecaGui.displayParent(); }); - WButton yes = new WButtonIcon(7, 32, 20, 20, BTN_YES, "recipe.confirm").setDisabled(true).setListener(i -> { + WButton yes = new WButtonIcon(7, 25, 20, 20, BTN_YES, "recipe.confirm").setDisabled(true).setListener(i -> { group.setText(text.getText()); text.setText(""); setNewGroup(false); refresh(); }); - WButton no = new WButtonIcon(26, 32, 20, 20, BTN_NO, "common.cancel").setListener(i -> setNewGroup(false)); - WButton neu = new WButtonIcon(7, 32, 20, 20, BTN_NEW, "recipe.new").setListener(i -> setNewGroup(true)); + WButton no = new WButtonIcon(26, 25, 20, 20, BTN_NO, "common.cancel").setListener(i -> setNewGroup(false)); + WButton neu = new WButtonIcon(7, 25, 20, 20, BTN_NEW, "recipe.new").setListener(i -> setNewGroup(true)); + EnumMap>> disamb = new EnumMap<>(IO.class); public GuiRecipe(String group, int index) { this(); dest = new Pair<>(group, index); Recipe r = Controller.getRecipe(group, index); - // fromRecipe(r); - input = r.getLabel(IO.INPUT).stream().map(ILabel::copy).collect(Collectors.toList()); - catalyst = r.getLabel(IO.CATALYST).stream().map(ILabel::copy).collect(Collectors.toList()); - output = r.getLabel(IO.OUTPUT).stream().map(ILabel::copy).collect(Collectors.toList()); + for (IO i : IO.values()) { + getWidget(i).setLabels(r.getLabel(i).stream().map(ILabel::copy).collect(Collectors.toList())); + } this.group.setIndex(Controller.getGroups().indexOf(group)); refresh(); } public GuiRecipe() { - for (IO i : IO.values()) - setup(getWidget(i), i); + for (IO j : IO.values()) { + getWidget(j).setFmtAmount(i -> i.getAmountString(false)) + .setFmtTooltip((i, k) -> i.getToolTip(k, true)) + .setLsnrClick((i, v) -> { + ILabel l = i.get(v).getLabel(); + if (l != ILabel.EMPTY) + add(new WAmount(j, v)); + }) + .setLsnrUpdate((i, v) -> { + refresh(); + removeDisamb(j, v); + }); + } add(new WHelp("recipe"), new WPanel()); - add(new WIcon(7, 63, 22, 20, ICN_OUTPUT, "common.output")); - add(new WIcon(7, 87, 22, 20, ICN_CATALYST, "common.catalyst")); - add(new WIcon(7, 111, 22, 40, ICN_INPUT, "common.input")); - add(new WLine(57)); - add(up, down, mid, group); + add(new WIcon(7, 61, 18, 36, ICN_OUTPUT, "common.output")); + add(new WIcon(7, 101, 18, 18, ICN_CATALYST, "common.catalyst")); + add(new WIcon(7, 123, 18, 36, ICN_INPUT, "common.input")); + add(new WLine(52)); + add(catalyst, input, output, group); if (group.getTexts().isEmpty()) group.setText(Utilities.I18n.get("gui.common.default")); String last = Controller.getLast(); @@ -125,33 +116,13 @@ public class GuiRecipe extends WContainer implements IGui { group.setIndex(index); setNewGroup(false); copy.setDisabled(true); - // disamb.setDisabled(true); text.setListener(i -> yes.setDisabled(i.getText().isEmpty())); } - public List getLabel(IO type) { + public WLabelScroll getWidget(IO type) { return Recipe.get(type, input, output, catalyst); } - public WLabelGroup getWidget(IO type) { - return Recipe.get(type, down, up, mid); - } - - private void setup(WLabelGroup w, IO type) { - w.setLsnrUpdate((i, v) -> { - List ls = getLabel(type); - while (ls.size() <= v) - ls.add(ILabel.EMPTY); - ls.set(v, i.get(v).getLabel()); - trim(ls); - refresh(); - }).setLsnrClick((i, v) -> { - ILabel l = i.get(v).getLabel(); - if (l != ILabel.EMPTY) - add(new WAmount(i.get(v))); - }); - } - @Override public boolean onKeyPressed(JecaGui gui, char ch, int code) { if (code == Keyboard.KEY_ESCAPE && contains(text)) { @@ -186,98 +157,101 @@ public class GuiRecipe extends WContainer implements IGui { } public void reset() { - input = new ArrayList<>(); - catalyst = new ArrayList<>(); - output = new ArrayList<>(); - // disambCache.clear(); + for (IO i : IO.values()) + getWidget(i).setLabels(new ArrayList<>()); + disamb.clear(); refresh(); } public void transfer(IRecipeHandler recipe, int recipeIndex) { // item disamb raw - ArrayList> input = new ArrayList<>(); - ArrayList> output = new ArrayList<>(); - // disambCache = new HashMap<>(); - + EnumMap>> merged = new EnumMap<>(IO.class); + disamb.clear(); + // merge recipe input, output and catalysts List recipeInputs = new ArrayList<>(); List recipeOutputs = new ArrayList<>(); Adapter.handleRecipe(recipe, recipeIndex, recipeInputs, recipeOutputs); // input - recipeInputs.forEach(i -> merge(input, Arrays.asList(i), recipe, true)); + recipeInputs.forEach(i -> merge(merged, Arrays.asList(i), recipe, IO.INPUT)); // output - recipeOutputs.forEach(o -> merge(output, Arrays.asList(o), recipe, false)); + recipeOutputs.forEach(o -> merge(merged, Arrays.asList(o), recipe, IO.OUTPUT)); // catalyst. Ignore multiple catalyst - this.catalyst = new ArrayList<>(); - NEIPlugin.getCatalyst(recipe) - .map(ILabel.Converter::from) - .ifPresent(catalyst -> this.catalyst.add(ILabel.CONVERTER.first(Collections.singletonList(catalyst), recipe))); + NEIPlugin.getCatalyst(recipe).ifPresent(catalyst -> { + List catalysts = Collections.singletonList(catalyst); + merge(merged, catalysts, recipe, IO.CATALYST); + }); // other. Unused. For example fuel in furnaces. // recipe.getOtherStacks(recipeIndex).stream(); - this.input = extract(input); - this.output = extract(output); + // generate disamb and fill slots + for (IO i : IO.values()) + getWidget(i).setLabels(extract(merged, i, recipe)); refresh(); } - private void merge(ArrayList> dst, - List gi, + private void merge(EnumMap>> dst, + List objs, IRecipeHandler context, - boolean input) { - List list = gi.stream() - .map(ILabel.Converter::from) - .filter(i -> i != ILabel.EMPTY) - .collect(Collectors.toList()); + IO type) { + List list = objs.stream().map(ILabel.Converter::from).collect(Collectors.toList()); if (list.isEmpty()) return; - dst.stream().filter(p -> { + ILabel rep = list.get(0).copy(); + if (type == IO.INPUT && list.size() != 1) + rep = ILabel.CONVERTER.first(list, context); + ILabel fin = rep; + + dst.computeIfAbsent(type, i -> new ArrayList<>()).stream().filter(p -> { CostList cl = new CostList(list); if (p.three.equals(cl)) { - ILabel.MERGER.merge(p.one, ILabel.CONVERTER.first(list, context)).ifPresent(i -> p.one = i); + ILabel.MERGER.merge(p.one, fin).ifPresent(i -> p.one = i); p.two = p.two.merge(cl, true, false); return true; } else return false; }).findAny().orElseGet(() -> { - ILabel rep = ILabel.CONVERTER.first(list, context); - if (!input && list.size() == 1) - rep = list.get(0).copy(); - Trio ret = new Trio<>(rep, new CostList(list), new CostList(list)); - dst.add(ret); + Trio ret = new Trio<>(fin, new CostList(list), new CostList(list)); + dst.get(type).add(ret); return ret; }); } - private ArrayList extract(ArrayList> src) { + private ArrayList extract(EnumMap>> src, + IO type, + IRecipeHandler context) { + List> l = src.get(type); ArrayList ret = new ArrayList<>(); - for (int i = 0; i < src.size(); i++) { - Trio p = src.get(i); + for (int i = 0; i < l.size(); i++) { + Trio p = l.get(i); ret.add(p.one); - // TODO disamb - // if (p.two.getLabels().size() > 1) disambCache.put(i + offset, p.two.getLabels()); + if (p.two.getLabels().size() > 1) { + List raw = p.two.getLabels(); + List suggest = new ArrayList<>(); + suggest.addAll(ILabel.CONVERTER.guess(raw, context).one); + suggest.addAll(raw); + disamb.computeIfAbsent(type, j -> new HashMap<>()).put(i, suggest); + } } return ret; } - private void trim(List ls) { + private List trim(List ls) { for (int i = ls.size() - 1; i >= 0; i--) { if (ls.get(i) == ILabel.EMPTY) ls.remove(i); } + return ls; } - private Recipe toRecipe() { // TODO - return new Recipe(input, catalyst, output); + private Recipe toRecipe() { + return new Recipe(trim(input.getLabels()), trim(catalyst.getLabels()), trim(output.getLabels())); } void refresh() { - up.setLabel(output, 0); - mid.setLabel(catalyst, 0); - down.setLabel(input, 0); - try { Recipe r = toRecipe(); boolean d = dest == null ? Controller.hasDuplicate(r) : Controller.hasDuplicate(r, dest.one, dest.two); @@ -290,7 +264,13 @@ public class GuiRecipe extends WContainer implements IGui { } } - static class WAmount extends WOverlay { + private void removeDisamb(IO type, int index) { + Map> entry = disamb.get(type); + if (entry != null) + entry.remove(index); + } + + class WAmount extends WOverlay { WLabel temp; WButton number; WTextField text; @@ -298,35 +278,44 @@ public class GuiRecipe extends WContainer implements IGui { WButton pick; WButton yes; WButton no; + WButton disamb; WLabel ref; - public WAmount(WLabel w) { - ref = w; - number = new WButtonText(ref.xPos + ref.xSize + 60, ref.yPos, 20, 20, "#", - "general.to_percent").setListener(i -> { + public WAmount(IO type, int idx) { + ref = getWidget(type).get(idx); + int x = ref.xPos; + int y = ref.yPos; + number = new WButtonText(x + 78, y - 1, 20, 20, "#", "recipe.to_percent").setListener(i -> { temp.getLabel().setPercent(true); update(); }); - percent = new WButtonText(ref.xPos + ref.xSize + 60, ref.yPos, 20, 20, "%", - "general.to_percent").setListener(i -> { + percent = new WButtonText(x + 78, y - 1, 20, 20, "%", "recipe.to_amount").setListener(i -> { temp.getLabel().setPercent(false); update(); }); - temp = new WLabel(ref.xPos, ref.yPos, ref.xSize, ref.ySize, false, true).setLsnrUpdate((i, v) -> update()); + temp = new WLabel(x - 1, y - 1, 20, 20, true).setLsnrUpdate((i, v) -> update()); temp.setLabel(ref.getLabel().copy()); - add(new WPanel(ref.xPos - 5, ref.yPos - 5, ref.xSize + 152, ref.ySize + 10)); - add(new WText(ref.xPos + ref.xSize + 3, ref.yPos + 5, PLAIN, "x")); - text = new WTextField(ref.xPos + ref.xSize + 10, ref.yPos + ref.ySize / 2 - WTextField.HEIGHT / 2, 50); - pick = new WButtonIcon(ref.xPos + ref.xSize + 83, ref.yPos, 20, 20, BTN_PICK, "label.pick").setListener( - i -> { - JecaGui.getCurrent().hand = temp.getLabel(); - set(ILabel.EMPTY); - }); - yes = new WButtonIcon(ref.xPos + ref.xSize + 102, ref.yPos, 20, 20, BTN_YES, "label.confirm").setListener( - i -> set(temp.getLabel())); - no = new WButtonIcon(ref.xPos + ref.xSize + 121, ref.yPos, 20, 20, BTN_NO, "label.delete").setListener( - i -> set(ILabel.EMPTY)); - add(temp, text, pick, yes, no); + add(new WPanel(x - 7, y - 30, 111, 55)); + add(new WText(x + 21, y + 5, PLAIN, "x")); + text = new WTextField(x + 28, y + 9 - WTextField.HEIGHT / 2, 50); + pick = new WButtonIcon(x + 21, y - 24, 20, 20, BTN_PICK, "recipe.pick").setListener(i -> { + JecaGui.getCurrent().hand = temp.getLabel(); + set(ILabel.EMPTY, type, idx); + }); + yes = new WButtonIcon(x + 59, y - 24, 20, 20, BTN_YES, "recipe.confirm").setListener( + i -> set(temp.getLabel(), type, idx)); + no = new WButtonIcon(x + 78, y - 24, 20, 20, BTN_NO, "recipe.delete").setListener( + i -> set(ILabel.EMPTY, type, idx)); + disamb = new WButtonIcon(x + 40, y - 24, 20, 20, BTN_DISAMB, "recipe.disamb"); + Map> entry = GuiRecipe.this.disamb.get(type); + if (entry != null && entry.containsKey(idx)) { + disamb.setListener(i -> { + GuiRecipe.this.remove(this); + GuiRecipe.this.add(new WDisamb(type, idx)); + }); + } else + disamb.setDisabled(true); + add(temp, text, pick, yes, no, disamb); text.setListener(i -> { boolean acceptable; long amount; @@ -347,11 +336,10 @@ public class GuiRecipe extends WContainer implements IGui { } - private void set(ILabel l) { + private void set(ILabel l, IO type, int idx) { ref.setLabel(l, true); - //refresh(); - //disambCache.remove(idx); - JecaGui.getCurrent().root.remove(this); + removeDisamb(type, idx); + GuiRecipe.this.remove(this); } private void update() { @@ -366,4 +354,31 @@ public class GuiRecipe extends WContainer implements IGui { text.setText(Long.toString(temp.getLabel().getAmount())); } } + + class WDisamb extends WOverlay { + WLabel temp; + WLabel ref; + WLabelScroll content; + WTextField search; + + public WDisamb(IO type, int idx) { + ref = getWidget(type).get(idx); + int x = ref.xPos; + int y = ref.yPos; + add(new WPanel(x - 7, y - 46, 111, 71)); + temp = new WLabel(x - 1, y - 1, 20, 20, false); + temp.setLabel(ref.getLabel().copy()); + content = new WLabelScroll(x + 8, y - 40, 4, 2, false).setLabels(disamb.get(type).get(idx)) + .setLsnrClick((i, v) -> { + ref.setLabel( + i.get(v).getLabel().copy().multiply(-1), + false); + GuiRecipe.this.remove(this); + refresh(); + }); + add(new WIcon(x + 22, y - 1, 20, 20, ICN_TEXT, "common.search")); + search = new WSearch(x + 42, y - 1, 56, content); + add(temp, content, search); + } + } } diff --git a/src/main/java/me/towdium/jecalculation/gui/guis/GuiSearch.java b/src/main/java/me/towdium/jecalculation/gui/guis/GuiSearch.java index 2ae8e9b..0ee7189 100644 --- a/src/main/java/me/towdium/jecalculation/gui/guis/GuiSearch.java +++ b/src/main/java/me/towdium/jecalculation/gui/guis/GuiSearch.java @@ -6,6 +6,7 @@ import me.towdium.jecalculation.data.structure.Recipe; import me.towdium.jecalculation.data.structure.Recipes; import me.towdium.jecalculation.gui.JecaGui; import me.towdium.jecalculation.gui.widgets.*; +import me.towdium.jecalculation.polyfill.MethodsReturnNonnullByDefault; import me.towdium.jecalculation.utils.Utilities; import me.towdium.jecalculation.utils.wrappers.Trio; import org.lwjgl.input.Keyboard; @@ -19,10 +20,11 @@ import java.util.function.Consumer; import static me.towdium.jecalculation.gui.Resource.*; @ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault public class GuiSearch extends WContainer implements IGui { IdentityHashMap> recipes; - WLabelScroll labels = new WLabelScroll(7, 51, 8, 6, false, true, false, true) - .setListener((i, v) -> { + WLabelScroll labels = new WLabelScroll(7, 51, 8, 6, false) + .setLsnrClick((i, v) -> { ILabel l = i.get(v).getLabel(); if (l != ILabel.EMPTY) add(new Overlay(i.get(v))); }); @@ -143,7 +145,7 @@ public class GuiSearch extends WContainer implements IGui { int x = l.xPos - 1; int y = l.yPos - 1; add(new WPanel(x - 5, y - 5, 72, 30)); - add(new WLabel(x, y, 20, 20, false, false).setLabel(l.getLabel())); + add(new WLabel(x, y, 20, 20, false).setLabel(l.getLabel())); add(new WButtonIcon(x + 23, y, 20, 20, BTN_EDIT, "search.edit").setListener(i -> { JecaGui.displayGui(true, true, new GuiRecipe(recipe.two, recipe.three)); GuiSearch.this.remove(this); diff --git a/src/main/java/me/towdium/jecalculation/gui/guis/pickers/PickerItemStack.java b/src/main/java/me/towdium/jecalculation/gui/guis/pickers/PickerItemStack.java index f29379a..a428e3b 100644 --- a/src/main/java/me/towdium/jecalculation/gui/guis/pickers/PickerItemStack.java +++ b/src/main/java/me/towdium/jecalculation/gui/guis/pickers/PickerItemStack.java @@ -20,7 +20,7 @@ import static me.towdium.jecalculation.gui.Resource.*; @ParametersAreNonnullByDefault @SideOnly(Side.CLIENT) public class PickerItemStack extends IPicker.Impl implements IGui { - WLabel label = new WLabel(7, 7, 20, 20, false, true).setLsnrUpdate((i, v) -> update(v)); + WLabel label = new WLabel(7, 7, 20, 20, true).setLsnrUpdate((i, v) -> update(v)); WButton bConfirm = new WButtonIcon(149, 7, 20, 20, BTN_YES, "item_stack.confirm").setListener( i -> callback.accept(label.getLabel())); WButton bNbtN = new WButtonIcon(49, 7, 20, 20, BTN_NBT_N, "item_stack.nbt_normal").setListener(i -> setFNbt(true)); diff --git a/src/main/java/me/towdium/jecalculation/gui/guis/pickers/PickerPlaceholder.java b/src/main/java/me/towdium/jecalculation/gui/guis/pickers/PickerPlaceholder.java index 8416df6..09298ef 100644 --- a/src/main/java/me/towdium/jecalculation/gui/guis/pickers/PickerPlaceholder.java +++ b/src/main/java/me/towdium/jecalculation/gui/guis/pickers/PickerPlaceholder.java @@ -23,8 +23,8 @@ import static me.towdium.jecalculation.gui.Resource.ICN_TEXT; @SideOnly(Side.CLIENT) public class PickerPlaceholder extends IPicker.Impl implements IGui { public PickerPlaceholder() { - WLabelScroll scroll = new WLabelScroll(7, 69, 8, 5, false, true, false, true).setLabels( - LPlaceholder.getRecent()).setListener((i, v) -> notifyLsnr(i.get(v).getLabel())); + WLabelScroll scroll = new WLabelScroll(7, 69, 8, 5, false) + .setLabels(LPlaceholder.getRecent()).setLsnrClick((i, v) -> notifyLsnr(i.get(v).getLabel())); WTextField create = new WTextField(26, 7, 69).setListener( i -> i.setColor(i.getText().equals("") ? COLOR_TEXT_RED : COLOR_TEXT_WHITE)); add(new WSearch(26, 45, 90, scroll)); diff --git a/src/main/java/me/towdium/jecalculation/gui/guis/pickers/PickerSimple.java b/src/main/java/me/towdium/jecalculation/gui/guis/pickers/PickerSimple.java index 24d9f74..905eaae 100644 --- a/src/main/java/me/towdium/jecalculation/gui/guis/pickers/PickerSimple.java +++ b/src/main/java/me/towdium/jecalculation/gui/guis/pickers/PickerSimple.java @@ -33,8 +33,8 @@ public class PickerSimple extends IPicker.Impl implements IGui { * @param labels label to be displayed for selection */ public PickerSimple(List labels) { - WLabelScroll ls = new WLabelScroll(7, 33, 8, 7, false, true, false, true).setLabels(labels) - .setListener((i, v) -> notifyLsnr(i.get(v).getLabel())); + WLabelScroll ls = new WLabelScroll(7, 33, 8, 7, false).setLabels(labels) + .setLsnrClick((i, v) -> notifyLsnr(i.get(v).getLabel())); add(new WSearch(26, 7, 90, ls)); add(new WIcon(7, 7, 20, 20, ICN_TEXT, "common.search")); add(ls); diff --git a/src/main/java/me/towdium/jecalculation/gui/widgets/WLabel.java b/src/main/java/me/towdium/jecalculation/gui/widgets/WLabel.java index 05fb4f7..5f05bf3 100644 --- a/src/main/java/me/towdium/jecalculation/gui/widgets/WLabel.java +++ b/src/main/java/me/towdium/jecalculation/gui/widgets/WLabel.java @@ -11,6 +11,7 @@ import me.towdium.jecalculation.utils.Utilities.Timer; import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; import java.util.List; +import java.util.function.BiConsumer; import java.util.function.Function; import static me.towdium.jecalculation.gui.JecaGui.Font.HALF; @@ -26,18 +27,18 @@ import static me.towdium.jecalculation.gui.Resource.WGT_SLOT; public class WLabel implements IWidget { public int xPos, yPos, xSize, ySize; ILabel label = ILabel.EMPTY; - public boolean multiple, accept; + public boolean accept; public ListenerValue update; public ListenerAction click; - Function formatter = i -> i.getAmountString(false); + Function fmtAmount = i -> ""; + BiConsumer> fmtTooltip = (i, j) -> i.getToolTip(j, false); protected Timer timer = new Timer(); - public WLabel(int xPos, int yPos, int xSize, int ySize, boolean multiple, boolean accept) { + public WLabel(int xPos, int yPos, int xSize, int ySize, boolean accept) { this.xPos = xPos; this.yPos = yPos; this.xSize = xSize; this.ySize = ySize; - this.multiple = multiple; this.accept = accept; } @@ -60,11 +61,9 @@ public class WLabel implements IWidget { public void onDraw(JecaGui gui, int xMouse, int yMouse) { gui.drawResourceContinuous(WGT_SLOT, xPos, yPos, xSize, ySize, 3, 3, 3, 3); label.drawLabel(gui, xPos + xSize / 2, yPos + ySize / 2, true); - if (multiple) { - String s = formatter.apply(label); - gui.drawText(xPos + xSize / 2.0f + 8 - HALF.getTextWidth(s), - yPos + ySize / 2.0f + 8.5f - HALF.getTextHeight(), HALF, s); - } + String s = fmtAmount.apply(label); + gui.drawText(xPos + xSize / 2.0f + 8 - HALF.getTextWidth(s), yPos + ySize / 2.0f + 8.5f - HALF.getTextHeight(), + HALF, s); if (accept) { timer.setState(gui.hand != ILabel.EMPTY); int color = 0xFFFFFF + (int) ((-Math.cos(timer.getTime() * Math.PI / 1500) + 1) * 0x40) * 0x1000000; @@ -80,7 +79,8 @@ public class WLabel implements IWidget { return false; if (label != ILabel.EMPTY) { tooltip.add(label.getDisplayName()); - label.getToolTip(tooltip, multiple); + tooltip.add(JecaGui.SEPARATOR); + fmtTooltip.accept(label, tooltip); } return false; } @@ -177,8 +177,13 @@ public class WLabel implements IWidget { return this; } - public WLabel setFormatter(Function f) { - formatter = f; + public WLabel setFmtAmount(Function f) { + fmtAmount = f; + return this; + } + + public WLabel setFmtTooltip(BiConsumer> f) { + fmtTooltip = f; return this; } diff --git a/src/main/java/me/towdium/jecalculation/gui/widgets/WLabelGroup.java b/src/main/java/me/towdium/jecalculation/gui/widgets/WLabelGroup.java index ba9425c..236161b 100644 --- a/src/main/java/me/towdium/jecalculation/gui/widgets/WLabelGroup.java +++ b/src/main/java/me/towdium/jecalculation/gui/widgets/WLabelGroup.java @@ -8,6 +8,7 @@ import me.towdium.jecalculation.polyfill.MethodsReturnNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault; import java.util.ArrayList; import java.util.List; +import java.util.function.BiConsumer; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.IntStream; @@ -24,22 +25,15 @@ public class WLabelGroup extends WContainer { ListenerValue lsnrUpdate; ListenerValue lsnrClick; - public WLabelGroup(int xPos, int yPos, int column, int row, boolean multiple, boolean accept) { - this(xPos, yPos, column, row, 18, 18, multiple, accept); + public WLabelGroup(int xPos, int yPos, int column, int row, boolean accept) { + this(xPos, yPos, column, row, 18, 18, accept); } - public WLabelGroup(int xPos, - int yPos, - int column, - int row, - int xSize, - int ySize, - boolean multiple, - boolean accept) { + public WLabelGroup(int xPos, int yPos, int column, int row, int xSize, int ySize, boolean accept) { for (int j = 0; j < row; j++) { int r = j; IntStream.range(0, column).forEach(c -> { - WLabel l = new WLabel(xPos + c * xSize, yPos + r * ySize, xSize, ySize, multiple, accept).setLsnrUpdate( + WLabel l = new WLabel(xPos + c * xSize, yPos + r * ySize, xSize, ySize, accept).setLsnrUpdate( (i, v) -> { if (lsnrUpdate != null) lsnrUpdate.invoke(this, r * column + c); @@ -80,8 +74,13 @@ public class WLabelGroup extends WContainer { return this; } - public WLabelGroup setFormatter(Function f) { - labels.forEach(i -> i.setFormatter(f)); + public WLabelGroup setFmtAmount(Function f) { + labels.forEach(i -> i.setFmtAmount(f)); + return this; + } + + public WLabelGroup setFmtTooltip(BiConsumer> f) { + labels.forEach(i -> i.setFmtTooltip(f)); return this; } } \ No newline at end of file diff --git a/src/main/java/me/towdium/jecalculation/gui/widgets/WLabelScroll.java b/src/main/java/me/towdium/jecalculation/gui/widgets/WLabelScroll.java index 5ef89f6..c534384 100644 --- a/src/main/java/me/towdium/jecalculation/gui/widgets/WLabelScroll.java +++ b/src/main/java/me/towdium/jecalculation/gui/widgets/WLabelScroll.java @@ -2,15 +2,15 @@ package me.towdium.jecalculation.gui.widgets; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; -import me.towdium.jecalculation.gui.JecaGui; import me.towdium.jecalculation.data.label.ILabel; +import me.towdium.jecalculation.gui.JecaGui; import me.towdium.jecalculation.polyfill.MethodsReturnNonnullByDefault; import me.towdium.jecalculation.utils.Utilities.I18n; import javax.annotation.ParametersAreNonnullByDefault; import java.util.ArrayList; import java.util.List; -import java.util.function.Consumer; +import java.util.function.BiConsumer; import java.util.function.Function; import java.util.stream.Collectors; @@ -23,86 +23,132 @@ import java.util.stream.Collectors; @SideOnly(Side.CLIENT) public class WLabelScroll extends WContainer implements ISearchable { protected List labels = new ArrayList<>(); - protected List filtered = new ArrayList<>(); + protected List filtered = null; protected WLabelGroup labelGroup; protected WScroll scroll; - protected int xPos, yPos, column, row, current; protected String filter = ""; - protected ListenerValue lsnrUpdate; - protected ListenerValue listener; + protected int xPos, yPos, column, row, current; + private ListenerValue lsnrUpdate; + private ListenerValue lsnrClick; + protected final boolean accept; - public WLabelScroll(int xPos, int yPos, int column, int row, boolean multiple, boolean accurate, boolean accept, boolean drawConnection) { + public WLabelScroll(int xPos, int yPos, int column, int row, boolean accept) { + this.accept = accept; this.xPos = xPos; this.yPos = yPos; this.column = column; this.row = row; - labelGroup = new WLabelGroup(xPos, yPos, column, row, multiple, accept) - .setLsnrUpdate((i, v) -> { - if (lsnrUpdate != null) lsnrUpdate.invoke(this, column * current + v); - }).setLsnrClick((i, v) -> { - if (listener != null) listener.invoke(this, column * current + v); - }); - scroll = new WScroll(xPos + column * 18 + 4, yPos, row * 18).setListener(i -> update(i.getCurrent())); + labelGroup = new WLabelGroup(xPos, yPos, column, row, accept).setLsnrUpdate(this::onUpdate) + .setLsnrClick(this::onClick); + scroll = new WScroll(xPos + column * 18 + 4, yPos, row * 18).setListener(i -> update(i.getCurrent())) + .setStep(Float.POSITIVE_INFINITY) + .setRatio(1); add(labelGroup); add(scroll); - if (drawConnection) add(new WRectangle(xPos + column * 18, yPos, 4, row * 18, JecaGui.COLOR_GUI_GREY)); + add(new WRectangle(xPos + column * 18, yPos, 4, row * 18, JecaGui.COLOR_GUI_GREY)); } public void update(float f) { - if (f < 0) f = 0; - if (f > 1) f = 1; - int step = getStepAmount(); - current = (int) (step * f); - if (current == step) current--; - labelGroup.setLabel(filtered, current * column); + if (f < 0) + f = 0; + if (f > 1) + f = 1; + int amount = getAmountSteps(); + current = (int) (amount * f); + if (current == amount) + current--; + List ls = accept ? labels : filtered; + labelGroup.setLabel(ls, current * column); + float step = 1f / (amount - 1); + scroll.setRatio(Math.min(row / (float) getAmountRows(), 1f)).setCurrent(f).setStep(step); } - @Override - public boolean onMouseScroll(JecaGui gui, int xMouse, int yMouse, int diff) { - boolean in = JecaGui.mouseIn(xPos, yPos, column * 18, row * 18, xMouse, yMouse); - if (in) { - float pos = getPos(current - diff); - scroll.setCurrent(pos); - update(pos); - } - return in; - } + // @Override + // public boolean onMouseScroll(JecaGui gui, int xMouse, int yMouse, int diff) { + // boolean in = JecaGui.mouseIn(xPos, yPos, column * 18, row * 18, xMouse, yMouse); + // if (in) { + // float pos = getPos(current - diff); + // scroll.setCurrent(pos); + // update(pos); + // } + // return in; + // } public WLabel get(int index) { return labelGroup.get(index - column * current); } - private float getPos(int step) { - return 1f / (getStepAmount() - 1) * step; - } - public WLabelScroll setLabels(List labels) { this.labels = labels; - setFilter(filter); + if (accept) + update(0); + else + setFilter(filter); return this; } public boolean setFilter(String str) { - filter = str; - filtered = labels.stream().filter(l -> I18n.contains(l.getDisplayName().toLowerCase(), str.toLowerCase())) + if (accept) + throw new RuntimeException("Filtering not allowed when editing"); + filtered = labels.stream() + .filter(l -> I18n.contains(l.getDisplayName().toLowerCase(), str.toLowerCase())) .collect(Collectors.toList()); - scroll.setCurrent(0); update(0); return filtered.size() != 0; } - public WLabelScroll setListener(ListenerValue listener) { - this.listener = listener; + public WLabelScroll setLsnrUpdate(ListenerValue lsnrUpdate) { + this.lsnrUpdate = lsnrUpdate; return this; } - public WLabelScroll setFormatter(Function f) { - labelGroup.setFormatter(f); + public WLabelScroll setLsnrClick(ListenerValue lsnrClick) { + this.lsnrClick = lsnrClick; return this; } - private int getStepAmount() { - int line = (labels.size() + column - 1) / column; - return Math.max(line - row + 1, 1); + public List getLabels() { + return new ArrayList<>(labels); + } + + protected void onUpdate(WLabelGroup w, int index) { + ILabel l = w.get(index).getLabel(); + int i = column * current + index; + while (labels.size() <= i) + labels.add(ILabel.EMPTY); + labels.set(i, l); + if (lsnrUpdate != null) + lsnrUpdate.invoke(this, i); + + if (index + 1 == row * column && l != ILabel.EMPTY && (row + current) * column == labels.size()) { + labels.add(ILabel.EMPTY); + int amount = getAmountSteps(); + float step = 1f / (amount - 1); + update(step * current); + } + } + + protected void onClick(WLabelGroup w, int index) { + if (lsnrClick != null) + lsnrClick.invoke(this, column * current + index); + } + + public WLabelScroll setFmtAmount(Function f) { + labelGroup.setFmtAmount(f); + return this; + } + + public WLabelScroll setFmtTooltip(BiConsumer> f) { + labelGroup.setFmtTooltip(f); + return this; + } + + protected int getAmountSteps() { + return Math.max(getAmountRows() - row + 1, 1); + } + + protected int getAmountRows() { + List ls = accept ? labels : filtered; + return (ls.size() + column - 1) / column; } } diff --git a/src/main/java/me/towdium/jecalculation/gui/widgets/WOverlay.java b/src/main/java/me/towdium/jecalculation/gui/widgets/WOverlay.java index 6bc1abf..128f4ce 100644 --- a/src/main/java/me/towdium/jecalculation/gui/widgets/WOverlay.java +++ b/src/main/java/me/towdium/jecalculation/gui/widgets/WOverlay.java @@ -2,6 +2,7 @@ package me.towdium.jecalculation.gui.widgets; import me.towdium.jecalculation.gui.JecaGui; import me.towdium.jecalculation.polyfill.MethodsReturnNonnullByDefault; +import me.towdium.jecalculation.polyfill.mc.client.renderer.GlStateManager; import org.lwjgl.input.Keyboard; import javax.annotation.ParametersAreNonnullByDefault; @@ -33,4 +34,12 @@ public class WOverlay extends WContainer { if (!super.onMouseScroll(gui, xMouse, yMouse, diff)) gui.root.remove(this); return true; } + + @Override + public void onDraw(JecaGui gui, int mouseX, int mouseY) { + GlStateManager.pushMatrix(); + GlStateManager.translate(0, 0, 40); + super.onDraw(gui, mouseX, mouseY); + GlStateManager.popMatrix(); + } } diff --git a/src/main/java/me/towdium/jecalculation/gui/widgets/WScroll.java b/src/main/java/me/towdium/jecalculation/gui/widgets/WScroll.java index 06197f5..3de43c8 100644 --- a/src/main/java/me/towdium/jecalculation/gui/widgets/WScroll.java +++ b/src/main/java/me/towdium/jecalculation/gui/widgets/WScroll.java @@ -10,6 +10,8 @@ import org.lwjgl.input.Mouse; import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; +import static me.towdium.jecalculation.gui.Resource.*; + /** * Author: towdium * Date: 17-8-19. @@ -19,11 +21,15 @@ import javax.annotation.ParametersAreNonnullByDefault; @MethodsReturnNonnullByDefault @SideOnly(Side.CLIENT) public class WScroll implements IWidget { - public int xPos, yPos, ySize, current; + public int xPos, yPos, ySize; + public float current; + boolean active = false; + float step = 0f; public ListenerAction listener; - protected boolean drag; + int height; public WScroll(int xPos, int yPos, int ySize) { + height = 17; this.xPos = xPos; this.yPos = yPos; this.ySize = ySize; @@ -31,39 +37,70 @@ public class WScroll implements IWidget { @Override public void onDraw(JecaGui gui, int xMouse, int yMouse) { - if (Mouse.isButtonDown(0) && drag) - setCurrent(yMouse - yPos - 9, true); + if (Mouse.isButtonDown(0) && active) + setCurrent(yMouse - yPos - height / 2, true); else - drag = false; + active = false; - gui.drawResourceContinuous(Resource.WGT_SLOT, xPos, yPos, 14, ySize, 3, 3, 3, 3); - gui.drawResource(Resource.WGT_SCROLL, xPos, yPos + current); + int offset = (int) (current * (ySize - height)); + boolean in = mouseIn(xMouse, yMouse); + Resource r = in ? WGT_SCROLL_F : WGT_SCROLL_N; + + gui.drawResourceContinuous(WGT_SLOT, xPos, yPos, 14, ySize, 3, 3, 3, 3); + gui.drawResourceContinuous(r, xPos, yPos + offset, 14, height, 3); } @Override public boolean onMouseClicked(JecaGui gui, int xMouse, int yMouse, int button) { - drag = mouseIn(xMouse, yMouse); - if (drag) - setCurrent(yMouse - yPos - 9, true); - return drag; + active = mouseIn(xMouse, yMouse); + if (active) + setCurrent(yMouse - yPos - height / 2, true); + return active; + } + + @Override + public boolean onMouseReleased(JecaGui gui, int xMouse, int yMouse, int button) { + active = false; + return false; + } + + @Override + public boolean onMouseScroll(JecaGui gui, int xMouse, int yMouse, int diff) { + boolean in = mouseIn(xMouse, yMouse); + if (in) setCurrent(getCurrent() - diff * step, true); + return in; + } + + public WScroll setStep(float step) { + this.step = step; + return this; + } + + public WScroll setRatio(float ratio) { + height = Math.max((int) ((ySize - 6) * ratio), 2) + 6; + return this; } private void setCurrent(int pos, boolean notify) { - current = pos; - if (current < 0) - current = 0; - if (current > ySize - 17) - current = ySize - 17; - if (notify && listener != null) - listener.invoke(this); + setCurrent(pos / (float) (ySize - height), notify); } public float getCurrent() { - return current / (ySize - 17f); + return current; } - public void setCurrent(float ratio) { - setCurrent((int) ((ySize - 17) * ratio), false); + public WScroll setCurrent(float ratio, boolean notify) { + //setCurrent((int) ((ySize - height) * ratio), false); + current = ratio; + if (current < 0) current = 0; + if (current > 1) current = 1; + if (notify && listener != null) listener.invoke(this); + return this; + } + + public WScroll setCurrent(float ratio) { + setCurrent(ratio, false); + return this; } public boolean mouseIn(int xMouse, int yMouse) { diff --git a/src/main/resources/assets/jecalculation/lang/en_US.lang b/src/main/resources/assets/jecalculation/lang/en_US.lang index 0edb4e0..93854f1 100644 --- a/src/main/resources/assets/jecalculation/lang/en_US.lang +++ b/src/main/resources/assets/jecalculation/lang/en_US.lang @@ -37,13 +37,18 @@ jecalculation.gui.recipe.confirm.disabled=Cannot use empty string as group name jecalculation.gui.recipe.disamb.enabled=Open disambiguate settings jecalculation.gui.recipe.disamb.disabled=Disambiguation settings are only\navailable when transferring recipes\nwith multiple options from JEI jecalculation.gui.recipe.new=New group + +jecalculation.gui.recipe.pick=Pick label +jecalculation.gui.recipe.confirm=Apply changes +jecalculation.gui.recipe.delete=Delete label +jecalculation.gui.recipe.to_percent=Change to percentage +jecalculation.gui.recipe.to_amount=Change to amount + jecalculation.gui.recipe.title=Recipe Editing jecalculation.gui.recipe.help=This interface allows you to create or edit recipes. To create one recipe, you can pick items from the JEI item list, then put it into the slots. When finished, simply click the save button. You can also fast transer recipes from JEI by clicking "+" when openning recipe view.\fTo edit one label, you can simply click it, then a toolbar will pop up to help you, where you can switch between amount and percentage mode, type the amount, or remove the label. In addition, you can use mouse scroll to quickly change the amount. Clicking the "Clear" button will remove all of the labels.\fUsing recipe fast transfer, some labels will automatically setup for you, like oreDict labels. If you do not want this behavoir, simply use "Disambiguous" button to select manually. You can also add labels by ckicking the "Add label" button. By the way, normally you shouldn't put fuzzy labels as output.\fYou can easily manage recipes using groups. Click the "New group" button, type the group name and hit the tick, you are done. The new group name will show in the top bar. If you already have groups set up and you want to use an existing one, you can use the arrows to select between them.\fWhen you are editing an existing recipe, you will have two extra buttons, "Save as" and "Delete". "Save as" allows you to save the current recipe as a new recipe, without changing the existing one. "Delete" simply allows you to delete the recipe. jecalculation.gui.label.title=Label Editing jecalculation.gui.label.help=This interface allows you to create labels. This mod provides 4 types of labels: fluid, oreDict, placeholder and item. To create fluid and oreDict label, you can just search and pick. Item labels represent an item stack, but with fuzzy options for meta, nbt and capalibity.\fAs is indicated by the name, Placeholder labels do not hold any content. It is just a string to connect recipes. You can use it for anything, like structure or event energy. To create one, simply type in the name, then hit the tick. You can also search and pick from existing ones. -jecalculation.gui.label.pick=Pick label -jecalculation.gui.label.confirm=Apply changes -jecalculation.gui.label.delete=Delete label + jecalculation.gui.search.all=All jecalculation.gui.search.import=Import recipes jecalculation.gui.search.export_group=Export recipes in current group diff --git a/src/main/resources/assets/jecalculation/lang/ru_RU.lang b/src/main/resources/assets/jecalculation/lang/ru_RU.lang index 97327b4..dbfb9d4 100644 --- a/src/main/resources/assets/jecalculation/lang/ru_RU.lang +++ b/src/main/resources/assets/jecalculation/lang/ru_RU.lang @@ -10,7 +10,7 @@ jecalculation.command.state.inactive=Сервер неактивен. jecalculation.chat.max_loop=Извините, похоже, расчет не сходится за 1000 итераций. Пожалуйста, свяжитесь с разработчиком, если вы думаете, что этот процесс должен иметь результат. jecalculation.chat.server_mode=Мод не работает в клиентском режиме, поэтому вы не сможете открыть интерфейс без калькулятора jecalculation.chat.export=Выбранные рецепты были экспортированы в "%s". -jecalculation.chat.help=/jeca craft - open crafting calculator\n/jeca math - open math calculator +#jecalculation.chat.help=/jeca craft - open crafting calculator\n/jeca math - open math calculator jecalculation.gui.craft.inventory_enabled=Обнаружение инвентаря включено jecalculation.gui.craft.inventory_disabled=Обнаружение инвентаря выключено jecalculation.gui.craft.recipe=Новый рецепт @@ -19,7 +19,7 @@ jecalculation.gui.craft.help=Добро пожаловать в основной jecalculation.gui.craft.title=Калькулятор создания jecalculation.gui.craft.label=Добавить метку jecalculation.gui.craft.step=Этапы -jecalculation.gui.craft.output=Extra outputs +#jecalculation.gui.craft.output=Extra outputs jecalculation.gui.craft.search=Поиск рецепта jecalculation.gui.craft.suggest=Предложения jecalculation.gui.math.title=Математический калькулятор @@ -29,7 +29,7 @@ jecalculation.gui.disamb.label=Выводимые типы jecalculation.gui.recipe.save.enabled=Сохранить jecalculation.gui.recipe.save.disabled=Не удается сохранить рецепт, потому что\nрецепт недействителен или у вас\nуже есть тот же рецепт jecalculation.gui.recipe.copy.enabled=Сохранить как новый рецепт -jecalculation.gui.recipe.copy.disabled=Не удается сохранить как новый рецепт,\nпотому что вы не редактируете\nрецепт +#jecalculation.gui.recipe.copy.disabled=Не удается сохранить как новый рецепт,\nпотому что вы не редактируете\nрецепт jecalculation.gui.recipe.clear=Очистить сетку jecalculation.gui.recipe.label=Добавить метку jecalculation.gui.recipe.confirm.enabled=Подтвердить @@ -37,13 +37,18 @@ jecalculation.gui.recipe.confirm.disabled=Нельзя использовать jecalculation.gui.recipe.disamb.enabled=Открыть настройки устранения неоднозначности jecalculation.gui.recipe.disamb.disabled=Настройки неоднозначности доступны только\nпри переносе рецептов\nс несколькими вариантами из JEI jecalculation.gui.recipe.new=Новая группа + +#jecalculation.gui.recipe.pick=Pick label +#jecalculation.gui.recipe.confirm=Apply changes +#jecalculation.gui.recipe.delete=Delete label +#jecalculation.gui.recipe.to_percent=Change to percentage +#jecalculation.gui.recipe.to_amount=Change to amount + jecalculation.gui.recipe.title=Редактирование рецепта jecalculation.gui.recipe.help=Этот интерфейс позволяет создавать или редактировать рецепты. Чтобы создать один рецепт, вы можете выбрать предметы из списка предметов JEI, а затем поместить их в слоты. Когда закончите, просто нажмите кнопку Сохранить. Вы также можете быстро пересылать рецепты из JEI, нажимая "+" при открытии представления рецептов.\fДля редактирования одной метки вы можете просто щелкнуть его, после чего появится всплывающая панель инструментов, где вы можете переключаться между режимом количества и процента, введите сумму или удалите метку. Кроме того, вы можете использовать прокрутку мыши, чтобы быстро изменить сумму. Нажатие кнопки "Очистить" удалит все метки.\fПри использовании быстрого переноса рецепта некоторые метки будут автоматически настроены для вас, например, метки словаря руды. Если вы не хотите этого поведения, просто используйте кнопку "Однозначный", чтобы выбрать вручную. Вы также можете добавить метки, нажав кнопку "Добавить метку". Кстати, обычно вы не должны помещать нечеткие метки в качестве вывода.\fВы можете легко управлять рецептами, используя группы. Нажмите кнопку "Новая группа", введите имя группы и нажмите галочку, все готово. Имя новой группы будет отображаться в верхней панели. Если у вас уже настроены группы и вы хотите использовать существующую, вы можете использовать стрелки для выбора между ними.\fПри редактировании существующего рецепта у вас будут две дополнительные кнопки: "Сохранить как" и "Удалить". "Сохранить как" позволяет сохранить текущий рецепт как новый рецепт, не меняя существующий. "Удалить" просто позволяет удалить рецепт. jecalculation.gui.label.title=Редактирование метки jecalculation.gui.label.help=Этот интерфейс позволяет создавать метки. Этот мод предоставляет 4 типа меток: жидкость, словарь руды, заполнитель и предмет. Чтобы создать жидкостную и словарь руды метки, вы можете просто искать и выбирать. Метки предметво представляют стак предметов, но с нечеткими опциями для мета, nbt и возможность.\fКак указано именем, метки заполнитель не содержат никакого содержимого. Это просто строка для подключения рецептов. Вы можете использовать его для чего угодно, например, для структуры или энергии события. Чтобы создать его, просто введите имя, а затем нажмите галочку. Вы также можете искать и выбирать из существующих. -#jecalculation.gui.label.pick=Pick label -#jecalculation.gui.label.confirm=Apply changes -#jecalculation.gui.label.delete=Delete label + jecalculation.gui.search.all=Все jecalculation.gui.search.import=Импорт рецептов jecalculation.gui.search.export_group=Экспорт рецептов в текущую группу @@ -98,4 +103,19 @@ jecalculation.label.item_stack.fuzzy_meta=Нечеткие метаданные jecalculation.label.item_stack.fuzzy_nbt=Нечеткие NBT jecalculation.label.item_stack.fuzzy_cap=Нечеткие возможности jecalculation.label.common.amount=Количество: %s - +jecalculation.chat.help=/jeca craft - open crafting calculator\n/jeca math - open math calculator +jecalculation.gui.craft.output=Extra outputs +jecalculation.gui.recipe.copy.disabled=Cannot save as new recipe\nbecause you are not editing\na recipe or already have\nsame recipe +jecalculation.gui.recipe.pick=Pick label +jecalculation.gui.recipe.confirm=Apply changes +jecalculation.gui.recipe.delete=Delete label +jecalculation.gui.recipe.to_percent=Change to percentage +jecalculation.gui.recipe.to_amount=Change to amount +jecalculation.gui.search.rename.enabled=Rename group +jecalculation.gui.search.rename.disabled=Rename options only available\nwhen one group selected +jecalculation.gui.search.confirm.enabled=Confirm +jecalculation.gui.search.confirm.disabled=New name cannot be empty\nor the same as existing ones +jecalculation.gui.search.edit=Edit recipe +jecalculation.gui.search.delete_group=\u00A7cDelete\u00A7r all recipes in group +jecalculation.gui.search.delete_all.enabled=\u00A7cDelete all\u00A7r recipes +jecalculation.gui.search.delete_all.disabled=No record to delete diff --git a/src/main/resources/assets/jecalculation/lang/zh_CN.lang b/src/main/resources/assets/jecalculation/lang/zh_CN.lang index 2b162e5..c5ca8b2 100644 --- a/src/main/resources/assets/jecalculation/lang/zh_CN.lang +++ b/src/main/resources/assets/jecalculation/lang/zh_CN.lang @@ -37,13 +37,18 @@ jecalculation.gui.recipe.confirm.disabled=组名不能为空 jecalculation.gui.recipe.disamb.enabled=打开消歧义设定 jecalculation.gui.recipe.disamb.disabled=消歧义设定只在从JEI转移配方\n并且含有歧义项时生效 jecalculation.gui.recipe.new=新建编组 + +jecalculation.gui.recipe.pick=抓取算子 +jecalculation.gui.recipe.confirm=应用修改 +jecalculation.gui.recipe.delete=删除算子 +jecalculation.gui.recipe.to_percent=切换至百分比 +jecalculation.gui.recipe.to_amount=切换至数量 + jecalculation.gui.recipe.title=编辑配方 jecalculation.gui.recipe.help=你可以使用本界面编辑或者创建配方。你可以手动从JEI物品列表抓取物品,然后放入槽位中。除此之外,你也可以使用JEI查询,然后点击“+”来快速转移配方。完成编辑后,点击“保存配方”就可以将该配方添加至你个人的配方库中。\n当你点击一个算子,一个工具栏会弹出来帮助你编辑。你可以使用这个工具栏来输入数量,切换百分比设定,或是删除算子。除此之外,你也可以直接使用鼠标滚轮来编辑算子的数量。\f在你从JEI快速转移配方的时候,系统会帮你自动配置好一些算子,诸如矿辞或是流体之类。如果你不想系统自动匹配,你可以使用消歧义选项来手动选取你需要的算子类型。与此同时,你也可以通过“添加算子”按钮手动选取并添加算子。值得一提的是,虽然本模组不会阻止你在输出列表中使用模糊算子,但是这通常是不必要的。\f你可以使用编组来轻松地管理你的配方。要添加一个新组,你只需要点击“新建编组”,键入名称,再点击确认即可。如果你想要使用已有的编组,可以使用两侧的箭头按钮进行切换。\n在你编辑已有的合成表时,会有两个额外的按钮。使用“另存为”,你可以将当前的合成表保存为新的合成表,而不改动原有合成表。使用“删除”将从合成表库中删除当前合成表。 jecalculation.gui.label.title=编辑算子 jecalculation.gui.label.help=你可以使用该界面创建算子。本模组目前有四类算子:流体栈,矿物词典,占位符和物品栈。要创建流体或矿辞算子,你只需要搜索并抓取即可。物品栈算子可以表示游戏中的物品栈,但是可以对Metadata,NBT和Capability使用额外的模糊选项。\n占位符并不表示任何实际内容,但可以用来链接配方,代表多方块结构,能量,或者任何你能想到的东西。只需要键入名字,就可以创建占位符算子。另外地,你也可以在已有的占位符中直接搜索并抓取。 -jecalculation.gui.label.pick=抓取算子 -jecalculation.gui.label.confirm=应用修改 -jecalculation.gui.label.delete=删除算子 + jecalculation.gui.search.all=全部组 jecalculation.gui.search.import=导入配方 jecalculation.gui.search.export_group=导出当前组内的配方 diff --git a/src/main/resources/assets/jecalculation/textures/gui/resources.png b/src/main/resources/assets/jecalculation/textures/gui/resources.png index 4ee24ca..7921f9a 100644 Binary files a/src/main/resources/assets/jecalculation/textures/gui/resources.png and b/src/main/resources/assets/jecalculation/textures/gui/resources.png differ