package anticope.rejects.settings; import meteordevelopment.meteorclient.gui.GuiTheme; import meteordevelopment.meteorclient.gui.renderer.GuiRenderer; import meteordevelopment.meteorclient.gui.widgets.containers.WTable; import meteordevelopment.meteorclient.gui.widgets.input.WTextBox; import meteordevelopment.meteorclient.gui.widgets.pressable.WButton; import meteordevelopment.meteorclient.gui.widgets.pressable.WMinus; import meteordevelopment.meteorclient.gui.widgets.pressable.WPlus; import meteordevelopment.meteorclient.settings.IVisible; import meteordevelopment.meteorclient.settings.Setting; import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtString; import java.util.LinkedHashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; public class StringMapSetting extends Setting> { public final Class renderer; public StringMapSetting(String name, String description, Map defaultValue, Consumer> onChanged, Consumer>> onModuleActivated, IVisible visible, Class renderer) { super(name, description, defaultValue, onChanged, onModuleActivated, visible); this.renderer = renderer; } @Override protected Map parseImpl(String str) { String[] values = str.split(","); Map map = new LinkedHashMap<>(values.length / 2); try { String left = null; for (int i = 0; i < values.length; i++) { if (i % 2 == 0) { left = values[i]; } else { map.put(left, values[i]); } } } catch (Exception ignored) { } return map; } @Override protected boolean isValueValid(Map value) { return true; } @Override protected void resetImpl() { value = new LinkedHashMap<>(defaultValue); } @Override protected NbtCompound save(NbtCompound tag) { NbtCompound valueTag = new NbtCompound(); for (String key : get().keySet()) { valueTag.put(key, NbtString.of(get().get(key))); } tag.put("map", valueTag); return tag; } @Override protected Map load(NbtCompound tag) { get().clear(); NbtCompound valueTag = tag.getCompound("map").orElse(new NbtCompound()); for (String key : valueTag.getKeys()) { get().put(key, valueTag.getString(key).orElse("")); } return get(); } public static void fillTable(GuiTheme theme, WTable table, StringMapSetting setting) { table.clear(); Map map = setting.get(); for (String key : map.keySet()) { AtomicReference key2 = new AtomicReference<>(key); WTextBox textBoxK = table.add(theme.textBox(key2.get())).minWidth(150).expandX().widget(); textBoxK.actionOnUnfocused = () -> { String text = textBoxK.get(); if (map.containsKey(text)) { textBoxK.set(key2.get()); return; } String value = map.remove(key2.get()); key2.set(text); map.put(text, value); }; WTextBox textBoxV = table.add(theme.textBox(map.get(key2.get()), (text1, c) -> true, setting.renderer)).minWidth(150).expandX().widget(); textBoxV.actionOnUnfocused = () -> map.replace(key2.get(), textBoxV.get()); WMinus delete = table.add(theme.minus()).widget(); delete.action = () -> { map.remove(key2.get()); fillTable(theme, table, setting); }; table.row(); } if (!map.isEmpty()) { table.add(theme.horizontalSeparator()).expandX(); table.row(); } WButton reset = table.add(theme.button(GuiRenderer.RESET)).widget(); reset.action = () -> { setting.reset(); fillTable(theme, table, setting); }; WPlus add = table.add(theme.plus()).widget(); add.action = () -> { map.put("", ""); fillTable(theme, table, setting); }; table.row(); } public static class Builder extends SettingBuilder, StringMapSetting> { private Class renderer; public Builder() { super(new LinkedHashMap<>(0)); } public Builder defaultValue(Map map) { this.defaultValue = map; return this; } public Builder renderer(Class renderer) { this.renderer = renderer; return this; } @Override public StringMapSetting build() { return new StringMapSetting(name, description, defaultValue, onChanged, onModuleActivated, visible, renderer); } } }