Commit 08af396fe6f0bacc4f07b7030dc5bda61ed752b4

Authored by Mumfrey
1 parent 0decdf16

Add an abstract config panel base class as a convenience for small mods

src/client/java/com/mumfrey/liteloader/client/mixin/IGuiButton.java 0 → 100644
  1 +/*
  2 + * This file is part of LiteLoader.
  3 + * Copyright (C) 2012-16 Adam Mummery-Smith
  4 + * All Rights Reserved.
  5 + */
  6 +package com.mumfrey.liteloader.client.mixin;
  7 +
  8 +import org.spongepowered.asm.mixin.Mixin;
  9 +import org.spongepowered.asm.mixin.gen.Accessor;
  10 +
  11 +import net.minecraft.client.gui.GuiButton;
  12 +
  13 +@Mixin(GuiButton.class)
  14 +public interface IGuiButton
  15 +{
  16 + @Accessor("width")
  17 + public abstract int getButtonWidth();
  18 +
  19 + @Accessor("height")
  20 + public abstract int getButtonHeight();
  21 +}
src/client/java/com/mumfrey/liteloader/modconfig/AbstractConfigPanel.java 0 → 100644
  1 +/*
  2 + * This file is part of LiteLoader.
  3 + * Copyright (C) 2012-16 Adam Mummery-Smith
  4 + * All Rights Reserved.
  5 + */
  6 +package com.mumfrey.liteloader.modconfig;
  7 +
  8 +import java.util.ArrayList;
  9 +import java.util.List;
  10 +
  11 +import org.lwjgl.input.Keyboard;
  12 +
  13 +import com.mumfrey.liteloader.client.mixin.IGuiButton;
  14 +
  15 +import net.minecraft.client.Minecraft;
  16 +import net.minecraft.client.gui.GuiButton;
  17 +import net.minecraft.client.gui.GuiLabel;
  18 +import net.minecraft.client.gui.GuiScreen;
  19 +
  20 +/**
  21 + * A general-purpose base class for mod config panels which implements a lot of
  22 + * the boilerplate needed to create a simple config panel. This should make it
  23 + * easier for mods which only need to provide a couple of options to do so
  24 + * without having to write a mountain of code.
  25 + */
  26 +public abstract class AbstractConfigPanel implements ConfigPanel
  27 +{
  28 + /**
  29 + * A callback for a control click event. Used so that consumers can pass in
  30 + * a lamba in Java 8 or consolidate listeners by control type.
  31 + *
  32 + * @param <T> type of control
  33 + */
  34 + public interface ConfigOptionListener<T extends GuiButton>
  35 + {
  36 + /**
  37 + * Called when a control is clicked
  38 + *
  39 + * @param control control being clicked
  40 + */
  41 + public abstract void actionPerformed(T control);
  42 + }
  43 +
  44 + /**
  45 + * Struct which keeps a control together with its callback object
  46 + *
  47 + * @param <T> control type
  48 + */
  49 + class ConfigOption<T extends GuiButton>
  50 + {
  51 + final GuiLabel label;
  52 + final T control;
  53 + final ConfigOptionListener<T> listener;
  54 +
  55 + ConfigOption(GuiLabel label)
  56 + {
  57 + this.label = label;
  58 + this.control = null;
  59 + this.listener = null;
  60 + }
  61 +
  62 + ConfigOption(T control, ConfigOptionListener<T> listener)
  63 + {
  64 + this.label = null;
  65 + this.control = control;
  66 + this.listener = listener;
  67 + }
  68 +
  69 + void draw(Minecraft minecraft, int mouseX, int mouseY, float partialTicks)
  70 + {
  71 + if (this.label != null)
  72 + {
  73 + this.label.drawLabel(minecraft, mouseX, mouseY);
  74 + }
  75 +
  76 + if (this.control != null)
  77 + {
  78 + this.control.drawButton(minecraft, mouseX, mouseY);
  79 + }
  80 + }
  81 +
  82 + boolean mousePressed(Minecraft minecraft, int mouseX, int mouseY)
  83 + {
  84 + if (this.control != null && this.control.mousePressed(minecraft, mouseX, mouseY))
  85 + {
  86 + this.control.playPressSound(minecraft.getSoundHandler());
  87 + if (this.listener != null)
  88 + {
  89 + this.listener.actionPerformed(this.control);
  90 + }
  91 + return true;
  92 + }
  93 +
  94 + return false;
  95 + }
  96 +
  97 + void mouseReleased(Minecraft mc, int mouseX, int mouseY)
  98 + {
  99 + if (this.control != null)
  100 + {
  101 + this.control.mouseReleased(mouseX, mouseY);
  102 + }
  103 + }
  104 + }
  105 +
  106 + protected final Minecraft mc;
  107 +
  108 + private final List<ConfigOption<?>> options = new ArrayList<ConfigOption<?>>();
  109 +
  110 + private int contentHeight = 0;
  111 +
  112 + private ConfigOption<?> selected;
  113 +
  114 + public AbstractConfigPanel()
  115 + {
  116 + this.mc = Minecraft.getMinecraft();
  117 + }
  118 +
  119 + @Override
  120 + public int getContentHeight()
  121 + {
  122 + return this.contentHeight;
  123 + }
  124 +
  125 + @Override
  126 + public final void onPanelShown(ConfigPanelHost host)
  127 + {
  128 + this.clearOptions();
  129 + this.addOptions(host);
  130 + }
  131 +
  132 + /**
  133 + * Stub for implementors, this is similar to {@link GuiScreen#initGui} and
  134 + * consumers should add all of their controls here
  135 + *
  136 + * @param host
  137 + */
  138 + protected abstract void addOptions(ConfigPanelHost host);
  139 +
  140 + /**
  141 + * Clear the options, called immediately before {@link #addOptions}
  142 + */
  143 + protected void clearOptions()
  144 + {
  145 + this.options.clear();
  146 + this.contentHeight = 0;
  147 + }
  148 +
  149 + /**
  150 + * Add a label to the panel
  151 + *
  152 + * @param id label id
  153 + * @param x label x position
  154 + * @param y label y position
  155 + * @param width width for the label, currently unused
  156 + * @param height height for the label, used to calculate display height
  157 + * @param colour label colour
  158 + * @param lines text for the label
  159 + */
  160 + protected void addLabel(int id, int x, int y, int width, int height, int colour, String... lines)
  161 + {
  162 + if (lines == null || lines.length < 1)
  163 + {
  164 + return;
  165 + }
  166 +
  167 + GuiLabel label = new GuiLabel(this.mc.fontRendererObj, id, x, y, width, height, colour);
  168 + for (String line : lines)
  169 + {
  170 + label.addLine(line);
  171 + }
  172 + this.contentHeight = Math.max(y + height, this.contentHeight);
  173 + this.options.add(new ConfigOption<GuiButton>(label));
  174 + }
  175 +
  176 + /**
  177 + * Add a control to the panel
  178 + *
  179 + * @param control control to add
  180 + * @param listener callback for when the control is clicked, can be null
  181 + * @return the control
  182 + */
  183 + protected <T extends GuiButton> T addControl(T control, ConfigOptionListener<T> listener)
  184 + {
  185 + if (control != null)
  186 + {
  187 + this.contentHeight = Math.max(control.yPosition + ((IGuiButton)control).getButtonHeight(), this.contentHeight);
  188 + this.options.add(new ConfigOption<T>(control, listener));
  189 + }
  190 +
  191 + return control;
  192 + }
  193 +
  194 + @Override
  195 + public void onPanelResize(ConfigPanelHost host)
  196 + {
  197 + }
  198 +
  199 + @Override
  200 + public void onTick(ConfigPanelHost host)
  201 + {
  202 + }
  203 +
  204 + @Override
  205 + public void drawPanel(ConfigPanelHost host, int mouseX, int mouseY, float partialTicks)
  206 + {
  207 + for (ConfigOption<?> configOption : this.options)
  208 + {
  209 + configOption.draw(this.mc, mouseX, mouseY, partialTicks);
  210 + }
  211 + }
  212 +
  213 + @Override
  214 + public void mousePressed(ConfigPanelHost host, int mouseX, int mouseY, int mouseButton)
  215 + {
  216 + this.selected = null;
  217 + if (mouseButton != 0)
  218 + {
  219 + return;
  220 + }
  221 +
  222 + for (ConfigOption<?> configOption : this.options)
  223 + {
  224 + if (configOption.mousePressed(this.mc, mouseX, mouseY))
  225 + {
  226 + this.selected = configOption;
  227 + }
  228 + }
  229 + }
  230 +
  231 + @Override
  232 + public void mouseReleased(ConfigPanelHost host, int mouseX, int mouseY, int mouseButton)
  233 + {
  234 + if (this.selected != null && mouseButton == 0)
  235 + {
  236 + this.selected.mouseReleased(this.mc, mouseX, mouseY);
  237 + }
  238 + this.selected = null;
  239 + }
  240 +
  241 + @Override
  242 + public void mouseMoved(ConfigPanelHost host, int mouseX, int mouseY)
  243 + {
  244 + }
  245 +
  246 + @Override
  247 + public void keyPressed(ConfigPanelHost host, char keyChar, int keyCode)
  248 + {
  249 + if (keyCode == Keyboard.KEY_ESCAPE)
  250 + {
  251 + host.close();
  252 + return;
  253 + }
  254 + }
  255 +}
src/client/resources/mixins.liteloader.client.json
1 { 1 {
2 "required": true, 2 "required": true,
3 - "minVersion": "0.5.10", 3 + "minVersion": "0.6",
4 "target": "@env(DEFAULT)", 4 "target": "@env(DEFAULT)",
5 "package": "com.mumfrey.liteloader.client.mixin", 5 "package": "com.mumfrey.liteloader.client.mixin",
6 "refmap": "mixins.liteloader.client.refmap.json", 6 "refmap": "mixins.liteloader.client.refmap.json",
@@ -22,7 +22,8 @@ @@ -22,7 +22,8 @@
22 "MixinSoundHandler", 22 "MixinSoundHandler",
23 "MixinGuiTextField", 23 "MixinGuiTextField",
24 "MixinIntIdentityHashBiMap", 24 "MixinIntIdentityHashBiMap",
25 - "MixinGuiOverlayDebug" 25 + "MixinGuiOverlayDebug",
  26 + "IGuiButton"
26 ], 27 ],
27 "injectors": { 28 "injectors": {
28 "defaultRequire": 1 29 "defaultRequire": 1