From d7753d2e78c2fd2c4cc005dfeed80ebd3d5e3af6 Mon Sep 17 00:00:00 2001 From: Chicken-Bomes Date: Fri, 25 Jul 2014 14:45:45 +1000 Subject: [PATCH] Abstracted gui option list and added patreon button --- build/build.properties | 4 +- resources/assets/nei/textures/patreonNeon.png | Bin 0 -> 25190 bytes resources/neimod.info | 12 +- src/codechicken/nei/ClientHandler.java | 2 + src/codechicken/nei/ItemList.java | 10 +- src/codechicken/nei/ItemPanel.java | 3 + src/codechicken/nei/LayoutManager.java | 2 +- src/codechicken/nei/NEIClientConfig.java | 17 +- src/codechicken/nei/NEIModContainer.java | 23 ++- src/codechicken/nei/NEIServerConfig.java | 4 +- src/codechicken/nei/api/NEIInfo.java | 2 +- src/codechicken/nei/config/DataDumper.java | 4 +- .../nei/config/GuiNEIOptionList.java | 54 +++++ src/codechicken/nei/config/GuiOptionList.java | 34 ++-- .../nei/config/IConfigSetHolder.java | 7 - src/codechicken/nei/config/Option.java | 11 +- src/codechicken/nei/config/OptionList.java | 190 +++++++++--------- src/codechicken/nei/config/PatreonButton.java | 23 +++ 18 files changed, 253 insertions(+), 149 deletions(-) create mode 100644 resources/assets/nei/textures/patreonNeon.png create mode 100644 src/codechicken/nei/config/GuiNEIOptionList.java delete mode 100644 src/codechicken/nei/config/IConfigSetHolder.java create mode 100644 src/codechicken/nei/config/PatreonButton.java diff --git a/build/build.properties b/build/build.properties index 87de3555..3755adf8 100644 --- a/build/build.properties +++ b/build/build.properties @@ -1,5 +1,5 @@ mc_version=1.7.10 forge_version=10.13.0.1151 ccl_version=1.1.1.96 -ccc_version=1.0.2.+ -mod_version=1.0.2 +ccc_version=1.0.3.+ +mod_version=1.0.3 diff --git a/resources/assets/nei/textures/patreonNeon.png b/resources/assets/nei/textures/patreonNeon.png new file mode 100644 index 0000000000000000000000000000000000000000..c069e36fdea140d851e9fefdd913241a9610245a GIT binary patch literal 25190 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

cc((WDMk9*M5mZ_sUAM65Aw*{k)n&1 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%0D&JQJygsWua`X>$s6KWmfM1&&fr-Izt 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 items = new ArrayList(); + public static volatile List items = new ArrayList(); /** * Fields are replaced atomically and contents never modified. */ - public static ListMultimap itemMap = ArrayListMultimap.create(); + public static volatile ListMultimap itemMap = ArrayListMultimap.create(); /** * Updates to this should be synchronised on this */ public static final List itemFilterers = new LinkedList(); public static final List loadCallbacks = new LinkedList(); - private static boolean loading = false; - private static boolean reload = false; - - private static boolean filtering = false; - private static boolean refilter = false; - private static HashSet erroredItems = new HashSet(); private static HashSet stackTraces = new HashSet(); diff --git a/src/codechicken/nei/ItemPanel.java b/src/codechicken/nei/ItemPanel.java index 7e50e163..e936d2c1 100644 --- a/src/codechicken/nei/ItemPanel.java +++ b/src/codechicken/nei/ItemPanel.java @@ -17,6 +17,9 @@ import static codechicken.lib.gui.GuiDraw.drawRect; public class ItemPanel extends Widget { + /** + * Should not be externally modified, use updateItemList + */ public static ArrayList items = new ArrayList(); /** * Swapped into visible items on update diff --git a/src/codechicken/nei/LayoutManager.java b/src/codechicken/nei/LayoutManager.java index 62c10b3c..61d4c886 100644 --- a/src/codechicken/nei/LayoutManager.java +++ b/src/codechicken/nei/LayoutManager.java @@ -272,7 +272,7 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH @Override public boolean onButtonPress(boolean rightclick) { if (!rightclick) { - getOptionList().showGui(getGuiContainer()); + getOptionList().openGui(getGuiContainer(), false); return true; } return false; diff --git a/src/codechicken/nei/NEIClientConfig.java b/src/codechicken/nei/NEIClientConfig.java index e927228f..049f75a3 100644 --- a/src/codechicken/nei/NEIClientConfig.java +++ b/src/codechicken/nei/NEIClientConfig.java @@ -9,6 +9,7 @@ import codechicken.nei.config.*; import codechicken.nei.recipe.RecipeInfo; import codechicken.obfuscator.ObfuscationRun; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; @@ -151,16 +152,26 @@ public class NEIClientConfig } private static void linkOptionList() { - getOptionList().bindConfig(new IConfigSetHolder() + OptionList.setOptionList(new OptionList("nei.options") { + @Override + public ConfigSet globalConfigSet() { + return global; + } + @Override public ConfigSet worldConfigSet() { return world; } @Override - public ConfigSet globalConfigSet() { - return global; + public OptionList configBase() { + return this; + } + + @Override + public GuiOptionList getGui(GuiScreen parent, OptionList list, boolean world) { + return new GuiNEIOptionList(parent, list, world); } }); } diff --git a/src/codechicken/nei/NEIModContainer.java b/src/codechicken/nei/NEIModContainer.java index f0ae99cc..e7acea8c 100644 --- a/src/codechicken/nei/NEIModContainer.java +++ b/src/codechicken/nei/NEIModContainer.java @@ -28,7 +28,7 @@ public class NEIModContainer extends DummyModContainer public NEIModContainer() { super(MetadataCollection.from(MetadataCollection.class.getResourceAsStream("/neimod.info"), "NotEnoughItems").getMetadataForId("NotEnoughItems", null)); - getMetadata(); + loadMetadata(); } @Override @@ -43,24 +43,29 @@ public class NEIModContainer extends DummyModContainer return new LinkedList(getRequirements()); } + private String description; + private void loadMetadata() { + description = super.getMetadata().description; + } + @Override public ModMetadata getMetadata() { - ModMetadata meta = super.getMetadata(); - meta.description = "Recipe Viewer, Inventory Manager, Item Spawner, Cheats and more.\n"+ EnumChatFormatting.WHITE+"\n"; - + String s_plugins = ""; if (plugins.size() == 0) { - meta.description += EnumChatFormatting.RED+"No installed plugins."; + s_plugins += EnumChatFormatting.RED+"No installed plugins."; } else { - meta.description += EnumChatFormatting.GREEN+"Installed plugins: "; + s_plugins += EnumChatFormatting.GREEN+"Installed plugins: "; for (int i = 0; i < plugins.size(); i++) { if (i > 0) - meta.description += ", "; + s_plugins += ", "; IConfigureNEI plugin = plugins.get(i); - meta.description += plugin.getName() + " " + plugin.getVersion(); + s_plugins += plugin.getName() + " " + plugin.getVersion(); } - meta.description += "."; + s_plugins += "."; } + ModMetadata meta = super.getMetadata(); + meta.description = description.replace("$plugins", s_plugins); return meta; } diff --git a/src/codechicken/nei/NEIServerConfig.java b/src/codechicken/nei/NEIServerConfig.java index 13395123..2409e85b 100644 --- a/src/codechicken/nei/NEIServerConfig.java +++ b/src/codechicken/nei/NEIServerConfig.java @@ -193,7 +193,7 @@ public class NEIServerConfig continue; int delim = s.lastIndexOf('='); if(delim < 0) { - System.err.println("line "+line+": Missing ="); + logger.error("line "+line+": Missing ="); continue; } try { @@ -203,7 +203,7 @@ public class NEIServerConfig values.add(s2.trim()); bannedItems.put(InventoryUtils.loadPersistant(key), values); } catch (Exception e) { - System.err.println("line "+line+": "+e.getMessage()); + logger.error("line "+line+": "+e.getMessage()); } } r.close(); diff --git a/src/codechicken/nei/api/NEIInfo.java b/src/codechicken/nei/api/NEIInfo.java index 561145eb..77898df7 100644 --- a/src/codechicken/nei/api/NEIInfo.java +++ b/src/codechicken/nei/api/NEIInfo.java @@ -12,7 +12,7 @@ public class NEIInfo public static void load(World world) { OptionCycled modeOption = (OptionCycled) NEIClientConfig.getOptionList().getOption("inventory.cheatmode"); - modeOption.parent.synthesizeEnvironment(); + modeOption.parent.synthesizeEnvironment(false); if(!modeOption.optionValid(modeOption.value())) { modeOption.copyGlobals(); modeOption.cycle(); diff --git a/src/codechicken/nei/config/DataDumper.java b/src/codechicken/nei/config/DataDumper.java index cb42651c..f97565d2 100644 --- a/src/codechicken/nei/config/DataDumper.java +++ b/src/codechicken/nei/config/DataDumper.java @@ -3,6 +3,7 @@ package codechicken.nei.config; import codechicken.core.CommonUtils; import codechicken.lib.vec.Rectangle4i; import codechicken.nei.LayoutManager; +import codechicken.nei.NEIClientConfig; import codechicken.nei.NEIClientUtils; import net.minecraft.util.ChatComponentTranslation; import net.minecraft.util.IChatComponent; @@ -41,8 +42,7 @@ public abstract class DataDumper extends Option NEIClientUtils.printChatMessage(dumpMessage(file)); } catch (Exception e) { - System.err.println("Error dumping " + renderName() + " mode: " + getMode()); - e.printStackTrace(); + NEIClientConfig.logger.error("Error dumping " + renderName() + " mode: " + getMode(), e); } } diff --git a/src/codechicken/nei/config/GuiNEIOptionList.java b/src/codechicken/nei/config/GuiNEIOptionList.java new file mode 100644 index 00000000..4bb6dcb0 --- /dev/null +++ b/src/codechicken/nei/config/GuiNEIOptionList.java @@ -0,0 +1,54 @@ +package codechicken.nei.config; + +import codechicken.core.gui.GuiCCButton; +import codechicken.nei.NEIClientConfig; +import net.minecraft.client.gui.GuiConfirmOpenLink; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.gui.GuiYesNoCallback; + +import java.awt.*; +import java.net.URI; + +public class GuiNEIOptionList extends GuiOptionList implements GuiYesNoCallback +{ + private GuiCCButton patreonButton; + + public GuiNEIOptionList(GuiScreen parent, OptionList optionList, boolean world) { + super(parent, optionList, world); + } + + @Override + public void resize() { + super.resize(); + patreonButton.x = width-73; + patreonButton.y = height-23; + } + + @Override + public void addWidgets() { + super.addWidgets(); + add(patreonButton = new PatreonButton(0, 0, 70, 20).setActionCommand("patreon")); + } + + @Override + public void actionPerformed(String ident, Object... params) { + if (ident.equals("patreon")) { + GuiConfirmOpenLink gui = new GuiConfirmOpenLink(this, "patreon.com/cb", 0, true); + gui.func_146358_g(); + mc.displayGuiScreen(gui); + } else + super.actionPerformed(ident, params); + } + + @Override + public void confirmClicked(boolean yes, int id) { + if(yes && id == 0) { + try { + Desktop.getDesktop().browse(new URI("http://patreon.com/cb")); + } catch (Exception e) { + NEIClientConfig.logger.error("Failed to open patreon page", e); + } + } + mc.displayGuiScreen(this); + } +} diff --git a/src/codechicken/nei/config/GuiOptionList.java b/src/codechicken/nei/config/GuiOptionList.java index 0e45bf37..0425bb9c 100644 --- a/src/codechicken/nei/config/GuiOptionList.java +++ b/src/codechicken/nei/config/GuiOptionList.java @@ -6,10 +6,13 @@ import codechicken.core.gui.GuiScrollSlot; import codechicken.lib.vec.Rectangle4i; import codechicken.nei.LayoutManager; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiConfirmOpenLink; import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.gui.GuiYesNoCallback; import org.lwjgl.opengl.GL11; import java.awt.*; +import java.net.URI; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; @@ -173,13 +176,13 @@ public class GuiOptionList extends GuiScreenWidget } } - private final GuiScreen parent; - private final OptionList optionList; - private boolean world; + protected final GuiScreen parent; + protected final OptionList optionList; + protected boolean world; - private OptionScrollSlot slot; - private GuiCCButton backButton; - private GuiCCButton worldButton; + protected OptionScrollSlot slot; + protected GuiCCButton backButton; + protected GuiCCButton worldButton; public GuiOptionList(GuiScreen parent, OptionList optionList, boolean world) { this.parent = parent; @@ -193,14 +196,16 @@ public class GuiOptionList extends GuiScreenWidget ySize = height; super.initGui(); - if (slot != null) { - slot.resize(); - backButton.width = Math.min(200, width - 40); - backButton.x = (width - backButton.width) / 2; - backButton.y = height - 25; - worldButton.width = 60; - worldButton.x = width - worldButton.width - 15; - } + } + + @Override + public void resize() { + slot.resize(); + backButton.width = Math.min(200, width - 40); + backButton.x = (width - backButton.width) / 2; + backButton.y = height - 25; + worldButton.width = 60; + worldButton.x = width - worldButton.width - 15; } @Override @@ -208,7 +213,6 @@ public class GuiOptionList extends GuiScreenWidget add(slot = new OptionScrollSlot()); add(backButton = new GuiCCButton(0, 0, 0, 20, translateToLocal("nei.options.back")).setActionCommand("back")); add(worldButton = new GuiCCButton(0, 2, 0, 16, worldButtonName()).setActionCommand("world")); - initGui(); } private String worldButtonName() { diff --git a/src/codechicken/nei/config/IConfigSetHolder.java b/src/codechicken/nei/config/IConfigSetHolder.java deleted file mode 100644 index 5aa146af..00000000 --- a/src/codechicken/nei/config/IConfigSetHolder.java +++ /dev/null @@ -1,7 +0,0 @@ -package codechicken.nei.config; - -public interface IConfigSetHolder -{ - public ConfigSet worldConfigSet(); - public ConfigSet globalConfigSet(); -} diff --git a/src/codechicken/nei/config/Option.java b/src/codechicken/nei/config/Option.java index d2852de1..f34d3ac2 100644 --- a/src/codechicken/nei/config/Option.java +++ b/src/codechicken/nei/config/Option.java @@ -45,16 +45,21 @@ public abstract class Option return 20; } + private T assertParentOverride(T elem) { + if(elem == null) throw new IllegalStateException("Option "+fullName()+" does not have a defined parent list. Use OptionList.setOptionList to insert a parent"); + return elem; + } + public ConfigSet globalConfigSet() { - return parent.globalConfigSet(); + return assertParentOverride(parent.globalConfigSet()); } public ConfigSet worldConfigSet() { - return parent.worldConfigSet(); + return assertParentOverride(parent.worldConfigSet()); } public OptionList configBase() { - return parent.configBase(); + return assertParentOverride(parent.configBase()); } /** diff --git a/src/codechicken/nei/config/OptionList.java b/src/codechicken/nei/config/OptionList.java index eeee0de6..d9ebb5e2 100644 --- a/src/codechicken/nei/config/OptionList.java +++ b/src/codechicken/nei/config/OptionList.java @@ -1,5 +1,6 @@ package codechicken.nei.config; +import codechicken.nei.NEIClientConfig; import codechicken.nei.config.GuiOptionList.OptionScrollSlot; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiScreen; @@ -9,147 +10,152 @@ import java.util.HashMap; public class OptionList extends OptionButton { - public static final OptionList top = new OptionList(null); - - public static OptionList getOptionList(String fullName) + public static final OptionList root = new RootOptionList(); + + private static class RootOptionList extends OptionList { - Option o = top.getOption(fullName); - if(o == null) - top.addOption(o = new OptionList(fullName)); + public RootOptionList() { + super(null); + } + + @Override + public ConfigSet globalConfigSet() { + return null; + } + + @Override + public ConfigSet worldConfigSet() { + return null; + } + + @Override + public OptionList configBase() { + return null; + } + + @Override + public GuiOptionList getGui(GuiScreen parent, OptionList list, boolean world) { + return new GuiOptionList(parent, list, world); + } + } + + public static OptionList getOptionList(String fullName) { + Option o = root.getOption(fullName); + if (o == null) + root.addOption(o = new OptionList(fullName)); return (OptionList) o; } - public static String parent(String fullName) - { + public static void setOptionList(OptionList list) { + OptionList prev = (OptionList) root.getOption(list.fullName()); + if (prev == null) + root.addOption(list); + else { + list.parent = prev.parent; + list.options = prev.options; + list.optionList = prev.optionList; + for (Option o : list.optionList) + o.parent = list; + list.parent.options.put(list.fullName(), list); + list.parent.optionList.remove(prev); + list.parent.addSorted(list); + } + } + + public static String parent(String fullName) { int i = fullName.indexOf('.'); - if(i < 0) + if (i < 0) return fullName; return fullName.substring(0, i); } - - public static String child(String fullName) - { + + public static String child(String fullName) { int i = fullName.indexOf('.'); - return fullName.substring(i+1); + return fullName.substring(i + 1); } - + public ArrayList