backport: 1.14

This commit is contained in:
Discreater committed 2021-05-07 03:00:16 +08:00
1 parent de1c2abe7b
commit ea0253a359
22 files changed
+466 -340

No files matched your search

@@ -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;
}
}
@@ -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 {
@@ -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)) {
@@ -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<ILabel> input, List<ILabel> catalyst, List<ILabel> output) {
Consumer<List<ILabel>> 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
}
}
@@ -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<ILabel> 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<ILabel> 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
}
}
@@ -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;
@@ -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);
@@ -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)));
}
}
@@ -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<String, Integer> dest;
// HashMap<Integer, List<ILabel>> disambCache = new HashMap<>();
WSwitcher group = new WSwitcher(7, 7, 162, Controller.getGroups()).setListener(i -> refresh());
WTextField text = new WTextField(49, 32, 119);
List<ILabel> input = new ArrayList<>();
List<ILabel> output = new ArrayList<>();
List<ILabel> 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<IO, Map<Integer, List<ILabel>>> 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<ILabel> 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<ILabel> 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<Trio<ILabel, CostList, CostList>> input = new ArrayList<>();
ArrayList<Trio<ILabel, CostList, CostList>> output = new ArrayList<>();
// disambCache = new HashMap<>();
EnumMap<IO, List<Trio<ILabel, CostList, CostList>>> merged = new EnumMap<>(IO.class);
disamb.clear();
// merge recipe input, output and catalysts
List<Object[]> recipeInputs = new ArrayList<>();
List<Object[]> 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<ItemStack> 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<Trio<ILabel, CostList, CostList>> dst,
List<Object> gi,
private void merge(EnumMap<IO, List<Trio<ILabel, CostList, CostList>>> dst,
List<?> objs,
IRecipeHandler context,
boolean input) {
List<ILabel> list = gi.stream()
.map(ILabel.Converter::from)
.filter(i -> i != ILabel.EMPTY)
.collect(Collectors.toList());
IO type) {
List<ILabel> 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<ILabel, CostList, CostList> ret = new Trio<>(rep, new CostList(list), new CostList(list));
dst.add(ret);
Trio<ILabel, CostList, CostList> ret = new Trio<>(fin, new CostList(list), new CostList(list));
dst.get(type).add(ret);
return ret;
});
}
private ArrayList<ILabel> extract(ArrayList<Trio<ILabel, CostList, CostList>> src) {
private ArrayList<ILabel> extract(EnumMap<IO, List<Trio<ILabel, CostList, CostList>>> src,
IO type,
IRecipeHandler context) {
List<Trio<ILabel, CostList, CostList>> l = src.get(type);
ArrayList<ILabel> ret = new ArrayList<>();
for (int i = 0; i < src.size(); i++) {
Trio<ILabel, CostList, CostList> p = src.get(i);
for (int i = 0; i < l.size(); i++) {
Trio<ILabel, CostList, CostList> 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<ILabel> raw = p.two.getLabels();
List<ILabel> 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<ILabel> ls) {
private List<ILabel> trim(List<ILabel> 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<Integer, List<ILabel>> 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<Integer, List<ILabel>> 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);
}
}
}
@@ -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<ILabel, Trio<Recipe, String, Integer>> 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);
@@ -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));
@@ -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));
@@ -33,8 +33,8 @@ public class PickerSimple extends IPicker.Impl implements IGui {
* @param labels label to be displayed for selection
*/
public PickerSimple(List<ILabel> 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);
@@ -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<? super WLabel, ILabel> update;
public ListenerAction<? super WLabel> click;
Function<ILabel, String> formatter = i -> i.getAmountString(false);
Function<ILabel, String> fmtAmount = i -> "";
BiConsumer<ILabel, List<String>> 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<ILabel, String> f) {
formatter = f;
public WLabel setFmtAmount(Function<ILabel, String> f) {
fmtAmount = f;
return this;
}
public WLabel setFmtTooltip(BiConsumer<ILabel, List<String>> f) {
fmtTooltip = f;
return this;
}
@@ -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<? super WLabelGroup, Integer> lsnrUpdate;
ListenerValue<? super WLabelGroup, Integer> 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<ILabel, String> f) {
labels.forEach(i -> i.setFormatter(f));
public WLabelGroup setFmtAmount(Function<ILabel, String> f) {
labels.forEach(i -> i.setFmtAmount(f));
return this;
}
public WLabelGroup setFmtTooltip(BiConsumer<ILabel, List<String>> f) {
labels.forEach(i -> i.setFmtTooltip(f));
return this;
}
}
@@ -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<ILabel> labels = new ArrayList<>();
protected List<ILabel> filtered = new ArrayList<>();
protected List<ILabel> filtered = null;
protected WLabelGroup labelGroup;
protected WScroll scroll;
protected int xPos, yPos, column, row, current;
protected String filter = "";
protected ListenerValue<? super WLabelScroll, Integer> lsnrUpdate;
protected ListenerValue<? super WLabelScroll, Integer> listener;
protected int xPos, yPos, column, row, current;
private ListenerValue<? super WLabelScroll, Integer> lsnrUpdate;
private ListenerValue<? super WLabelScroll, Integer> 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<ILabel> 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<ILabel> 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<? super WLabelScroll, Integer> listener) {
this.listener = listener;
public WLabelScroll setLsnrUpdate(ListenerValue<? super WLabelScroll, Integer> lsnrUpdate) {
this.lsnrUpdate = lsnrUpdate;
return this;
}
public WLabelScroll setFormatter(Function<ILabel, String> f) {
labelGroup.setFormatter(f);
public WLabelScroll setLsnrClick(ListenerValue<? super WLabelScroll, Integer> 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<ILabel> 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<ILabel, String> f) {
labelGroup.setFmtAmount(f);
return this;
}
public WLabelScroll setFmtTooltip(BiConsumer<ILabel, List<String>> f) {
labelGroup.setFmtTooltip(f);
return this;
}
protected int getAmountSteps() {
return Math.max(getAmountRows() - row + 1, 1);
}
protected int getAmountRows() {
List<ILabel> ls = accept ? labels : filtered;
return (ls.size() + column - 1) / column;
}
}
@@ -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();
}
}
@@ -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<? super WScroll> 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) {