Commit 176016aebb5ad215f056093a9ef741034b409667

Authored by Mumfrey
1 parent ad12632b

LiteLoader 1.6.4_02 - experimental - "Configurable" interface for mods that want…

… to provide a config panel in the mod info GUI
java/com/mumfrey/liteloader/Configurable.java 0 → 100644
  1 +package com.mumfrey.liteloader;
  2 +
  3 +import com.mumfrey.liteloader.modconfig.ConfigPanel;
  4 +
  5 +/**
  6 + * Interface for mods which want to provide a configuration panel inside the "mod info" screen
  7 + *
  8 + * @author Adam Mummery-Smith
  9 + */
  10 +public interface Configurable
  11 +{
  12 + /**
  13 + * Get the class of the configuration panel to use, the returned class must have a
  14 + * default (no-arg) constructor
  15 + *
  16 + * @return configuration panel class
  17 + */
  18 + public abstract Class<? extends ConfigPanel> getConfigPanelClass();
  19 +}
... ...
java/com/mumfrey/liteloader/core/LiteLoader.java
... ... @@ -39,6 +39,7 @@ import com.mumfrey.liteloader.crashreport.CallableLiteLoaderBrand;
39 39 import com.mumfrey.liteloader.crashreport.CallableLiteLoaderMods;
40 40 import com.mumfrey.liteloader.gui.GuiControlsPaginated;
41 41 import com.mumfrey.liteloader.gui.GuiScreenModInfo;
  42 +import com.mumfrey.liteloader.modconfig.ConfigPanelManager;
42 43 import com.mumfrey.liteloader.permissions.PermissionsManagerClient;
43 44 import com.mumfrey.liteloader.util.PrivateFields;
44 45  
... ... @@ -163,6 +164,11 @@ public final class LiteLoader
163 164 private final PermissionsManagerClient permissionsManager = PermissionsManagerClient.getInstance();
164 165  
165 166 /**
  167 + * Configuration panel manager/registry
  168 + */
  169 + private final ConfigPanelManager configPanelManager;
  170 +
  171 + /**
166 172 * Flag which keeps track of whether late initialisation has been done
167 173 */
168 174 private boolean postInitStarted, startupComplete;
... ... @@ -266,6 +272,8 @@ public final class LiteLoader
266 272  
267 273 this.enabledModsList = EnabledModsList.createFrom(this.enabledModsFile);
268 274 this.enabledModsList.processModsList(bootstrap.getProfile(), modNameFilter);
  275 +
  276 + this.configPanelManager = new ConfigPanelManager();
269 277 }
270 278  
271 279 /**
... ... @@ -899,10 +907,11 @@ public final class LiteLoader
899 907 // add the mod to all relevant listener queues
900 908 this.events.addListener(mod);
901 909  
902   - if (mod instanceof Permissible)
903   - {
904   - this.permissionsManager.registerPermissible((Permissible)mod);
905   - }
  910 + // add mod to permissions manager if permissible
  911 + this.permissionsManager.registerMod(mod);
  912 +
  913 + // register mod config panel if configurable
  914 + this.configPanelManager.registerMod(mod);
906 915  
907 916 this.loadedMods.add(mod);
908 917 this.loadedModsList += String.format("\n - %s version %s", mod.getName(), mod.getVersion());
... ... @@ -1023,7 +1032,7 @@ public final class LiteLoader
1023 1032 // If we're at the main menu, prepare the overlay
1024 1033 if (this.modInfoScreen == null || this.modInfoScreen.getMenu() != this.minecraft.currentScreen)
1025 1034 {
1026   - this.modInfoScreen = new GuiScreenModInfo(this.minecraft, (GuiMainMenu)this.minecraft.currentScreen, this, this.enabledModsList);
  1035 + this.modInfoScreen = new GuiScreenModInfo(this.minecraft, (GuiMainMenu)this.minecraft.currentScreen, this, this.enabledModsList, this.configPanelManager);
1027 1036 }
1028 1037  
1029 1038 this.modInfoScreen.drawScreen(mouseX, mouseY, partialTicks);
... ... @@ -1036,7 +1045,7 @@ public final class LiteLoader
1036 1045 }
1037 1046 else if (this.minecraft.currentScreen instanceof GuiMainMenu && Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) && Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) && Keyboard.isKeyDown(Keyboard.KEY_TAB))
1038 1047 {
1039   - this.minecraft.displayGuiScreen(new GuiScreenModInfo(this.minecraft, (GuiMainMenu)this.minecraft.currentScreen, this, this.enabledModsList));
  1048 + this.minecraft.displayGuiScreen(new GuiScreenModInfo(this.minecraft, (GuiMainMenu)this.minecraft.currentScreen, this, this.enabledModsList, this.configPanelManager));
1040 1049 }
1041 1050 }
1042 1051  
... ...
java/com/mumfrey/liteloader/gui/GuiConfigPanelContainer.java 0 → 100644
  1 +package com.mumfrey.liteloader.gui;
  2 +
  3 +import static org.lwjgl.opengl.GL11.*;
  4 +import static com.mumfrey.liteloader.gui.GuiScreenModInfo.glEnableClipping;
  5 +import static com.mumfrey.liteloader.gui.GuiScreenModInfo.glDisableClipping;
  6 +
  7 +import java.util.LinkedList;
  8 +import java.util.List;
  9 +
  10 +import net.minecraft.src.Gui;
  11 +import net.minecraft.src.GuiButton;
  12 +import net.minecraft.src.Minecraft;
  13 +
  14 +import com.mumfrey.liteloader.LiteMod;
  15 +import com.mumfrey.liteloader.modconfig.ConfigPanel;
  16 +import com.mumfrey.liteloader.modconfig.ConfigPanelHost;
  17 +
  18 +/**
  19 + * Config panel container, this handles drawing the configuration panel chrome and also hosts the
  20 + * configuration panels themselves to support scrolling and stuff
  21 + *
  22 + * @author Adam Mummery-Smith
  23 + */
  24 +public class GuiConfigPanelContainer extends Gui implements ConfigPanelHost
  25 +{
  26 + private static final int TOP = 26;
  27 + private static final int BOTTOM = 40;
  28 + private static final int MARGIN = 12;
  29 +
  30 + /**
  31 + * Parent screen
  32 + */
  33 + private GuiScreenModInfo parent;
  34 +
  35 + /**
  36 + * Minecraft
  37 + */
  38 + private Minecraft mc;
  39 +
  40 + /**
  41 + * Panel we are hosting
  42 + */
  43 + private ConfigPanel panel;
  44 +
  45 + /**
  46 + * Mod being configured, the panel may want a reference to it
  47 + */
  48 + private LiteMod mod;
  49 +
  50 + /**
  51 + * Buttons
  52 + */
  53 + private List<GuiButton> controls = new LinkedList<GuiButton>();
  54 +
  55 + /**
  56 + * Scroll bar for the panel
  57 + */
  58 + private GuiSimpleScrollBar scrollBar = new GuiSimpleScrollBar();
  59 +
  60 + /**
  61 + * Current available width
  62 + */
  63 + private int width = 0;
  64 +
  65 + /**
  66 + * Current available height
  67 + */
  68 + private int height = 0;
  69 +
  70 + /**
  71 + * Current panel width (width - margins)
  72 + */
  73 + private int panelWidth = 0;
  74 +
  75 + /**
  76 + * Current panel visible height (height - chrome)
  77 + */
  78 + private int panelHeight = 0;
  79 +
  80 + /**
  81 + * Panel's internal height (for scrolling)
  82 + */
  83 + private int totalHeight = -1;
  84 +
  85 + /**
  86 + * Panel Y position (for scroll)
  87 + */
  88 + private int panelTop = TOP;
  89 +
  90 + /**
  91 + * @param parent
  92 + * @param minecraft
  93 + * @param panel
  94 + * @param mod
  95 + */
  96 + GuiConfigPanelContainer(GuiScreenModInfo parent, Minecraft minecraft, ConfigPanel panel, LiteMod mod)
  97 + {
  98 + this.parent = parent;
  99 + this.mc = minecraft;
  100 + this.panel = panel;
  101 + this.mod = mod;
  102 + }
  103 +
  104 + /* (non-Javadoc)
  105 + * @see com.mumfrey.liteloader.modconfig.ConfigPanelHost#getMod()
  106 + */
  107 + @SuppressWarnings("unchecked")
  108 + @Override
  109 + public <ModClass extends LiteMod> ModClass getMod()
  110 + {
  111 + return (ModClass)this.mod;
  112 + }
  113 +
  114 + /* (non-Javadoc)
  115 + * @see com.mumfrey.liteloader.modconfig.ConfigPanelHost#getWidth()
  116 + */
  117 + @Override
  118 + public int getWidth()
  119 + {
  120 + return this.panelWidth;
  121 + }
  122 +
  123 + /* (non-Javadoc)
  124 + * @see com.mumfrey.liteloader.modconfig.ConfigPanelHost#getHeight()
  125 + */
  126 + @Override
  127 + public int getHeight()
  128 + {
  129 + return this.panelHeight;
  130 + }
  131 +
  132 + /* (non-Javadoc)
  133 + * @see com.mumfrey.liteloader.modconfig.ConfigPanelHost#close()
  134 + */
  135 + @Override
  136 + public void close()
  137 + {
  138 + this.parent.closeConfigPanel(this);
  139 + }
  140 +
  141 + /**
  142 + * Callback from parent screen when window is resized
  143 + *
  144 + * @param width
  145 + * @param height
  146 + */
  147 + void setSize(int width, int height)
  148 + {
  149 + this.width = width;
  150 + this.height = height;
  151 +
  152 + this.panelHeight = this.height - TOP - BOTTOM;
  153 + this.panelWidth = this.width - (MARGIN * 2) - 6;
  154 +
  155 + this.panel.onPanelResize(this);
  156 +
  157 + this.controls.clear();
  158 + this.controls.add(new GuiButton(0, this.width - 99 - MARGIN, this.height - BOTTOM + 9, 100, 20, "Save & Close"));
  159 + }
  160 +
  161 + /**
  162 + * Callback from parent screen when panel is displayed
  163 + */
  164 + void onShown()
  165 + {
  166 + this.panel.onPanelShown(this);
  167 + }
  168 +
  169 + /**
  170 + * Callback from parent screen when panel is hidden
  171 + */
  172 + void onHidden()
  173 + {
  174 + this.panel.onPanelHidden();
  175 + }
  176 +
  177 + /**
  178 + * Callback from parent screen every tick
  179 + */
  180 + void onTick()
  181 + {
  182 + this.panel.onTick(this);
  183 + }
  184 +
  185 + /**
  186 + * Draw the panel and chrome
  187 + *
  188 + * @param mouseX
  189 + * @param mouseY
  190 + * @param partialTicks
  191 + */
  192 + void draw(int mouseX, int mouseY, float partialTicks)
  193 + {
  194 + // Scroll position
  195 + this.panelTop = TOP - this.scrollBar.getValue();
  196 +
  197 + // Draw panel title
  198 + String panelTitle = this.panel.getPanelTitle();
  199 + if (panelTitle != null)
  200 + {
  201 + this.mc.fontRenderer.drawString(panelTitle, MARGIN, TOP - 14, 0xFFFFFFFF);
  202 + }
  203 +
  204 + // Draw top and bottom horizontal bars
  205 + drawRect(MARGIN, TOP - 4, this.width - MARGIN, TOP - 3, 0xFF999999);
  206 + drawRect(MARGIN, this.height - BOTTOM + 2, this.width - MARGIN, this.height - BOTTOM + 3, 0xFF999999);
  207 +
  208 + // Clip rect
  209 + glEnableClipping(MARGIN, this.width - MARGIN - 6, TOP, this.height - BOTTOM);
  210 +
  211 + // Offset by scroll
  212 + glPushMatrix();
  213 + glTranslatef(MARGIN, this.panelTop, 0.0F);
  214 +
  215 + // Draw panel contents
  216 + this.panel.drawPanel(this, mouseX - MARGIN, mouseY - this.panelTop, partialTicks);
  217 + glClear(GL_DEPTH_BUFFER_BIT);
  218 +
  219 + // Disable clip rect
  220 + glDisableClipping();
  221 +
  222 + // Restore transform
  223 + glPopMatrix();
  224 +
  225 + // Get total scroll height from panel
  226 + this.totalHeight = Math.max(-1, this.panel.getContentHeight());
  227 +
  228 + // Update and draw scroll bar
  229 + this.scrollBar.setMaxValue(this.totalHeight - this.panelHeight);
  230 + this.scrollBar.drawScrollBar(mouseX, mouseY, partialTicks, this.width - MARGIN - 5, TOP, 5, this.panelHeight, Math.max(this.panelHeight, this.totalHeight));
  231 +
  232 + // Draw other buttons
  233 + for (GuiButton control : this.controls)
  234 + control.drawButton(this.mc, mouseX, mouseY);
  235 + }
  236 +
  237 + /**
  238 + * @param control
  239 + */
  240 + private void actionPerformed(GuiButton control)
  241 + {
  242 + if (control.id == 0) this.close();
  243 + }
  244 +
  245 + /**
  246 + * @param mouseWheelDelta
  247 + */
  248 + public void mouseWheelScrolled(int mouseWheelDelta)
  249 + {
  250 + this.scrollBar.offsetValue(-mouseWheelDelta / 8);
  251 + }
  252 +
  253 + /**
  254 + * @param mouseX
  255 + * @param mouseY
  256 + * @param mouseButton
  257 + */
  258 + void mousePressed(int mouseX, int mouseY, int mouseButton)
  259 + {
  260 + if (mouseButton == 0)
  261 + {
  262 + if (this.scrollBar.wasMouseOver())
  263 + this.scrollBar.setDragging(true);
  264 +
  265 + for (GuiButton control : this.controls)
  266 + {
  267 + if (control.mousePressed(this.mc, mouseX, mouseY))
  268 + {
  269 + this.mc.sndManager.playSoundFX("random.click", 1.0F, 1.0F);
  270 + this.actionPerformed(control);
  271 + }
  272 + }
  273 + }
  274 +
  275 + this.panel.mousePressed(this, mouseX - MARGIN, mouseY - this.panelTop, mouseButton);
  276 + }
  277 +
  278 + /**
  279 + * @param mouseX
  280 + * @param mouseY
  281 + * @param mouseButton
  282 + */
  283 + void mouseReleased(int mouseX, int mouseY, int mouseButton)
  284 + {
  285 + if (mouseButton == 0)
  286 + {
  287 + this.scrollBar.setDragging(false);
  288 + }
  289 +
  290 + this.panel.mouseReleased(this, mouseX - MARGIN, mouseY - this.panelTop, mouseButton);
  291 + }
  292 +
  293 + /**
  294 + * @param mouseX
  295 + * @param mouseY
  296 + */
  297 + void mouseMoved(int mouseX, int mouseY)
  298 + {
  299 + this.panel.mouseMoved(this, mouseX - MARGIN, mouseY - this.panelTop);
  300 + }
  301 +
  302 + /**
  303 + * @param keyChar
  304 + * @param keyCode
  305 + */
  306 + void keyPressed(char keyChar, int keyCode)
  307 + {
  308 + this.panel.keyPressed(this, keyChar, keyCode);
  309 + }
  310 +}
... ...
java/com/mumfrey/liteloader/gui/GuiModListEntry.java
... ... @@ -24,6 +24,10 @@ public class GuiModListEntry extends Gui
24 24 * For text display
25 25 */
26 26 private FontRenderer fontRenderer;
  27 +
  28 + private LiteMod modInstance;
  29 +
  30 + private Class<? extends LiteMod> modClass;
27 31  
28 32 /**
29 33 * The metadata name (id) of the mod, used as the enablement/disablement key
... ... @@ -82,17 +86,19 @@ public class GuiModListEntry extends Gui
82 86 * @param loader
83 87 * @param enabledMods
84 88 * @param fontRenderer
85   - * @param mod
  89 + * @param modInstance
86 90 */
87   - GuiModListEntry(LiteLoader loader, EnabledModsList enabledMods, FontRenderer fontRenderer, LiteMod mod)
  91 + GuiModListEntry(LiteLoader loader, EnabledModsList enabledMods, FontRenderer fontRenderer, LiteMod modInstance)
88 92 {
89 93 this.fontRenderer = fontRenderer;
90   - this.metaName = loader.getModMetaName(mod.getClass());
91   - this.name = mod.getName();
92   - this.version = mod.getVersion();
93   - this.author = loader.getModMetaData(mod.getClass(), "author", "Unknown");
94   - this.url = loader.getModMetaData(mod.getClass(), "url", null);
95   - this.description = loader.getModMetaData(mod.getClass(), "description", "");
  94 + this.modInstance = modInstance;
  95 + this.modClass = modInstance.getClass();
  96 + this.metaName = loader.getModMetaName(this.modClass);
  97 + this.name = modInstance.getName();
  98 + this.version = modInstance.getVersion();
  99 + this.author = loader.getModMetaData(this.modClass, "author", "Unknown");
  100 + this.url = loader.getModMetaData(this.modClass, "url", null);
  101 + this.description = loader.getModMetaData(this.modClass, "description", "");
96 102 this.enabled = true;
97 103 this.canBeToggled = this.metaName != null && enabledMods.saveAllowed();
98 104 this.willBeEnabled = true;
... ... @@ -204,6 +210,16 @@ public class GuiModListEntry extends Gui
204 210 return this.metaName + Integer.toHexString(this.hashCode());
205 211 }
206 212  
  213 + public LiteMod getModInstance()
  214 + {
  215 + return this.modInstance;
  216 + }
  217 +
  218 + public Class<? extends LiteMod> getModClass()
  219 + {
  220 + return this.modClass;
  221 + }
  222 +
207 223 public String getName()
208 224 {
209 225 return this.name;
... ...
java/com/mumfrey/liteloader/gui/GuiScreenModInfo.java
... ... @@ -19,6 +19,8 @@ import com.mumfrey.liteloader.LiteMod;
19 19 import com.mumfrey.liteloader.core.EnabledModsList;
20 20 import com.mumfrey.liteloader.core.LiteLoader;
21 21 import com.mumfrey.liteloader.core.ModFile;
  22 +import com.mumfrey.liteloader.modconfig.ConfigPanel;
  23 +import com.mumfrey.liteloader.modconfig.ConfigPanelManager;
22 24  
23 25 import net.minecraft.src.DynamicTexture;
24 26 import net.minecraft.src.GuiButton;
... ... @@ -39,12 +41,14 @@ import net.minecraft.src.Tessellator;
39 41 */
40 42 public class GuiScreenModInfo extends GuiScreen
41 43 {
42   - private static final int LEFT_EDGE = 80;
43   - private static final int TAB_WIDTH = 20;
44   - private static final int TAB_HEIGHT = 40;
45   - private static final int TAB_TOP = 20;
46   - private static final int PANEL_TOP = 83;
47   - private static final int PANEL_BOTTOM = 26;
  44 + private static final int LEFT_EDGE = 80;
  45 + private static final int MARGIN = 12;
  46 + private static final int TAB_WIDTH = 20;
  47 + private static final int TAB_HEIGHT = 40;
  48 + private static final int TAB_TOP = 20;
  49 + private static final int PANEL_TOP = 83;
  50 + private static final int PANEL_BOTTOM = 26;
  51 + private static final int SCROLLBAR_WIDTH = 5;
48 52  
49 53 private static final double TWEEN_RATE = 0.08;
50 54  
... ... @@ -83,6 +87,11 @@ public class GuiScreenModInfo extends GuiScreen
83 87 private boolean mouseDown, toggled;
84 88  
85 89 /**
  90 + * Timer used to handle double-clicking on a mod
  91 + */
  92 + private int doubleClickTime = 0;
  93 +
  94 + /**
86 95 * Hover opacity for the tab
87 96 */
88 97 private float tabOpacity = 0.0F;
... ... @@ -118,20 +127,33 @@ public class GuiScreenModInfo extends GuiScreen
118 127 private GuiButton btnToggle;
119 128  
120 129 /**
  130 + * Config button
  131 + */
  132 + private GuiButton btnConfig;
  133 +
  134 + /**
121 135 * Enable the mod info tab checkbox
122 136 */
123 137 private GuiCheckbox chkEnabled;
124 138  
  139 + private ConfigPanelManager configPanelManager;
  140 +
  141 + /**
  142 + * Configuration panel
  143 + */
  144 + private GuiConfigPanelContainer configPanel;
  145 +
125 146 /**
126 147 * @param minecraft
127 148 * @param mainMenu
128 149 * @param loader
129 150 * @param enabledModsList
130 151 */
131   - public GuiScreenModInfo(Minecraft minecraft, GuiMainMenu mainMenu, LiteLoader loader, EnabledModsList enabledModsList)
  152 + public GuiScreenModInfo(Minecraft minecraft, GuiMainMenu mainMenu, LiteLoader loader, EnabledModsList enabledModsList, ConfigPanelManager configPanelManager)
132 153 {
133 154 this.mc = minecraft;
134 155 this.mainMenu = mainMenu;
  156 + this.configPanelManager = configPanelManager;
135 157  
136 158 // Spawn the texture resource if we haven't already
137 159 if (aboutTexture == null)
... ... @@ -206,11 +228,17 @@ public class GuiScreenModInfo extends GuiScreen
206 228 @Override
207 229 public void initGui()
208 230 {
209   - int left = LEFT_EDGE + 16 + (this.width - LEFT_EDGE - 28) / 2;
  231 + if (this.configPanel != null)
  232 + {
  233 + this.configPanel.setSize(this.width - LEFT_EDGE, this.height);
  234 + }
  235 +
  236 + int left = LEFT_EDGE + MARGIN + 4 + (this.width - LEFT_EDGE - MARGIN - MARGIN - 4) / 2;
210 237  
211 238 this.buttonList.clear();
212   - this.buttonList.add(this.btnToggle = new GuiButton(0, left, this.height - PANEL_BOTTOM - 24, 100, 20, "Enable mod"));
213   - this.buttonList.add(this.chkEnabled = new GuiCheckbox(1, LEFT_EDGE + 12, this.height - PANEL_BOTTOM + 9, "Show LiteLoader tab on main menu"));
  239 + this.buttonList.add(this.btnToggle = new GuiButton(0, left, this.height - PANEL_BOTTOM - 24, 90, 20, "Enable mod"));
  240 + this.buttonList.add(this.btnConfig = new GuiButton(1, left + 92, this.height - PANEL_BOTTOM - 24, 60, 20, "Config"));
  241 + this.buttonList.add(this.chkEnabled = new GuiCheckbox(2, LEFT_EDGE + MARGIN, this.height - PANEL_BOTTOM + 9, "Show LiteLoader tab on main menu"));
214 242  
215 243 this.selectMod(this.selectedMod);
216 244 }
... ... @@ -236,6 +264,11 @@ public class GuiScreenModInfo extends GuiScreen
236 264 @Override
237 265 public void updateScreen()
238 266 {
  267 + if (this.configPanel != null)
  268 + {
  269 + this.configPanel.onTick();
  270 + }
  271 +
239 272 this.tickNumber++;
240 273  
241 274 if (this.mc.currentScreen == this)
... ... @@ -248,6 +281,9 @@ public class GuiScreenModInfo extends GuiScreen
248 281 {
249 282 this.onToggled();
250 283 }
  284 +
  285 + if (this.doubleClickTime > 0)
  286 + this.doubleClickTime--;
251 287 }
252 288  
253 289 /* (non-Javadoc)
... ... @@ -311,28 +347,55 @@ public class GuiScreenModInfo extends GuiScreen
311 347 // Only draw the panel contents if we are actually open
312 348 if (this.tweenAmount > 0.0)
313 349 {
314   - // Draw the header pieces
315   - glDrawTexturedRect(LEFT_EDGE + 12, 12, 128, 40, 0, 0, 256, 80, 1.0F); // liteloader logo
316   - glDrawTexturedRect(this.width - 32 - 12, 12, 32, 45, 0, 80, 64, 170, 1.0F); // chicken
317   -
318   - // Draw header text
319   - this.fontRenderer.drawString("Version " + LiteLoader.getVersion(), LEFT_EDGE + 12 + 38, 50, 0xFFFFFFFF);
320   - this.fontRenderer.drawString(this.activeModText, LEFT_EDGE + 12 + 38, 60, 0xFFAAAAAA);
321   -
322   - // Draw top and bottom horizontal rules
323   - drawRect(LEFT_EDGE + 12, 80, this.width - 12, 81, 0xFF999999);
324   - drawRect(LEFT_EDGE + 12, this.height - PANEL_BOTTOM + 2, this.width - 12, this.height - PANEL_BOTTOM + 3, 0xFF999999);
  350 + if (this.configPanel != null)
  351 + {
  352 + this.drawConfigPanel(mouseX, mouseY, partialTicks);
  353 + }
  354 + else
  355 + {
  356 + // Draw the header pieces
  357 + glDrawTexturedRect(LEFT_EDGE + MARGIN, 12, 128, 40, 0, 0, 256, 80, 1.0F); // liteloader logo
  358 + glDrawTexturedRect(this.width - 32 - MARGIN, 12, 32, 45, 0, 80, 64, 170, 1.0F); // chicken
  359 +
  360 + // Draw header text
  361 + this.fontRenderer.drawString("Version " + LiteLoader.getVersion(), LEFT_EDGE + MARGIN + 38, 50, 0xFFFFFFFF);
  362 + this.fontRenderer.drawString(this.activeModText, LEFT_EDGE + MARGIN + 38, 60, 0xFFAAAAAA);
  363 +
  364 + // Draw top and bottom horizontal rules
  365 + drawRect(LEFT_EDGE + MARGIN, 80, this.width - MARGIN, 81, 0xFF999999);
  366 + drawRect(LEFT_EDGE + MARGIN, this.height - PANEL_BOTTOM + 2, this.width - MARGIN, this.height - PANEL_BOTTOM + 3, 0xFF999999);
  367 +
  368 + int innerWidth = this.width - LEFT_EDGE - MARGIN - MARGIN - 4;
  369 + int panelWidth = innerWidth / 2;
  370 + int panelHeight = this.height - PANEL_BOTTOM - PANEL_TOP;
  371 +
  372 + this.drawModsList(mouseX, mouseY, partialTicks, panelWidth, panelHeight);
  373 + this.drawSelectedMod(mouseX, mouseY, partialTicks, panelWidth, panelHeight);
  374 +
  375 + // Draw other controls inside the transform so that they slide properly
  376 + super.drawScreen(mouseX, mouseY, partialTicks);
  377 + }
  378 + }
  379 + else if (this.configPanel != null)
  380 + {
  381 + this.closeConfigPanel(this.configPanel);
  382 + }
325 383  
326   - int innerWidth = this.width - LEFT_EDGE - 24 - 4;
327   - int panelWidth = innerWidth / 2;
328   - int panelHeight = this.height - PANEL_BOTTOM - PANEL_TOP;
329   -
330   - this.drawModsList(mouseX, mouseY, partialTicks, panelWidth, panelHeight);
331   - this.drawSelectedMod(mouseX, mouseY, partialTicks, panelWidth, panelHeight);
  384 +
  385 + glPopMatrix();
  386 + }
332 387  
333   - // Draw other controls inside the transform so that they slide properly
334   - super.drawScreen(mouseX, mouseY, partialTicks);
335   - }
  388 + /**
  389 + * @param mouseX
  390 + * @param mouseY
  391 + * @param partialTicks
  392 + */
  393 + public void drawConfigPanel(int mouseX, int mouseY, float partialTicks)
  394 + {
  395 + glPushMatrix();
  396 + glTranslatef(LEFT_EDGE, 0, 0);
  397 +
  398 + this.configPanel.draw(mouseX - LEFT_EDGE, mouseY, partialTicks);
336 399  
337 400 glPopMatrix();
338 401 }
... ... @@ -346,10 +409,10 @@ public class GuiScreenModInfo extends GuiScreen
346 409 */
347 410 public void drawModsList(int mouseX, int mouseY, float partialTicks, int width, int height)
348 411 {
349   - this.scrollBar.drawScrollBar(mouseX, mouseY, partialTicks, LEFT_EDGE + 12 + width - 5, PANEL_TOP, 5, height, this.listHeight);
  412 + this.scrollBar.drawScrollBar(mouseX, mouseY, partialTicks, LEFT_EDGE + MARGIN + width - SCROLLBAR_WIDTH, PANEL_TOP, SCROLLBAR_WIDTH, height, this.listHeight);
350 413  
351 414 // clip outside of scroll area
352   - glEnableClipping(LEFT_EDGE + 12, LEFT_EDGE + 12 + width - 6, PANEL_TOP, this.height - PANEL_BOTTOM);
  415 + glEnableClipping(LEFT_EDGE + MARGIN, LEFT_EDGE + MARGIN + width - SCROLLBAR_WIDTH - 1, PANEL_TOP, this.height - PANEL_BOTTOM);
353 416  
354 417 // handle scrolling
355 418 glPushMatrix();
... ... @@ -361,7 +424,7 @@ public class GuiScreenModInfo extends GuiScreen
361 424 for (GuiModListEntry mod : this.mods)
362 425 {
363 426 // drawListEntry returns a value indicating the height of the item drawn
364   - yPos += mod.drawListEntry(mouseX, mouseY, partialTicks, LEFT_EDGE + 12, yPos, width - 6, mod == this.selectedMod);
  427 + yPos += mod.drawListEntry(mouseX, mouseY, partialTicks, LEFT_EDGE + MARGIN, yPos, width - 6, mod == this.selectedMod);
365 428 }
366 429  
367 430 glPopMatrix();
... ... @@ -382,8 +445,8 @@ public class GuiScreenModInfo extends GuiScreen
382 445 {
383 446 if (this.selectedMod != null)
384 447 {
385   - int left = LEFT_EDGE + 12 + width;
386   - int right = this.width - 12;
  448 + int left = LEFT_EDGE + MARGIN + width;
  449 + int right = this.width - MARGIN;
387 450  
388 451 glEnableClipping(left, right, PANEL_TOP, this.height - PANEL_BOTTOM - 28);
389 452 this.selectedMod.drawInfo(mouseX, mouseY, partialTicks, left, PANEL_TOP, right - left);
... ... @@ -399,11 +462,14 @@ public class GuiScreenModInfo extends GuiScreen
399 462 {
400 463 this.selectedMod = mod;
401 464 this.btnToggle.drawButton = false;
  465 + this.btnConfig.drawButton = false;
402 466  
403 467 if (this.selectedMod != null && this.selectedMod.canBeToggled())
404 468 {
405 469 this.btnToggle.drawButton = true;
406 470 this.btnToggle.displayString = this.selectedMod.willBeEnabled() ? "Disable mod" : "Enable mod";
  471 +
  472 + this.btnConfig.drawButton = this.configPanelManager.hasPanel(this.selectedMod.getModClass());
407 473 }
408 474 }
409 475  
... ... @@ -421,6 +487,11 @@ public class GuiScreenModInfo extends GuiScreen
421 487  
422 488 if (button.id == 1)
423 489 {
  490 + this.openConfigPanel();
  491 + }
  492 +
  493 + if (button.id == 2)
  494 + {
424 495 this.chkEnabled.checked = !this.chkEnabled.checked;
425 496 LiteLoader.getInstance().setDisplayModInfoScreenTab(this.chkEnabled.checked);
426 497  
... ... @@ -437,6 +508,12 @@ public class GuiScreenModInfo extends GuiScreen
437 508 @Override
438 509 protected void keyTyped(char keyChar, int keyCode)
439 510 {
  511 + if (this.configPanel != null)
  512 + {
  513 + this.configPanel.keyPressed(keyChar, keyCode);
  514 + return;
  515 + }
  516 +
440 517 if (keyCode == Keyboard.KEY_ESCAPE)
441 518 {
442 519 this.onToggled();
... ... @@ -450,6 +527,12 @@ public class GuiScreenModInfo extends GuiScreen
450 527 @Override
451 528 protected void mouseClicked(int mouseX, int mouseY, int button)
452 529 {
  530 + if (this.configPanel != null)
  531 + {
  532 + this.configPanel.mousePressed(mouseX - LEFT_EDGE, mouseY, button);
  533 + return;
  534 + }
  535 +
453 536 if (button == 0)
454 537 {
455 538 if (this.scrollBar.wasMouseOver())
... ... @@ -459,9 +542,22 @@ public class GuiScreenModInfo extends GuiScreen
459 542  
460 543 if (mouseY > PANEL_TOP && mouseY < this.height - PANEL_BOTTOM)
461 544 {
  545 + GuiModListEntry lastSelectedMod = this.selectedMod;
  546 +
462 547 for (GuiModListEntry mod : this.mods)
463 548 {
464   - if (mod.mouseWasOver()) this.selectMod(mod);
  549 + if (mod.mouseWasOver())
  550 + {
  551 + this.selectMod(mod);
  552 +
  553 + // handle double-click
  554 + if (mod == lastSelectedMod && this.doubleClickTime > 0 && this.btnConfig.drawButton)
  555 + {
  556 + this.actionPerformed(this.btnConfig);
  557 + }
  558 +
  559 + this.doubleClickTime = 5;
  560 + }
465 561 }
466 562 }
467 563 }
... ... @@ -475,6 +571,16 @@ public class GuiScreenModInfo extends GuiScreen
475 571 @Override
476 572 protected void mouseMovedOrUp(int mouseX, int mouseY, int button)
477 573 {
  574 + if (this.configPanel != null)
  575 + {
  576 + if (button == -1)
  577 + this.configPanel.mouseMoved(mouseX - LEFT_EDGE, mouseY);
  578 + else
  579 + this.configPanel.mouseReleased(mouseX - LEFT_EDGE, mouseY, button);
  580 +
  581 + return;
  582 + }
  583 +
478 584 if (button == 0)
479 585 {
480 586 this.scrollBar.setDragging(false);
... ... @@ -490,10 +596,12 @@ public class GuiScreenModInfo extends GuiScreen
490 596 public void handleMouseInput()
491 597 {
492 598 int mouseWheelDelta = Mouse.getEventDWheel();
493   -
494 599 if (mouseWheelDelta != 0)
495 600 {
496   - this.scrollBar.offsetValue(-mouseWheelDelta / 8);
  601 + if (this.configPanel != null)
  602 + this.configPanel.mouseWheelScrolled(mouseWheelDelta);
  603 + else
  604 + this.scrollBar.offsetValue(-mouseWheelDelta / 8);
497 605 }
498 606  
499 607 super.handleMouseInput();
... ... @@ -550,6 +658,40 @@ public class GuiScreenModInfo extends GuiScreen
550 658 }
551 659  
552 660 /**
  661 + * Callback for the "config" button, display the config panel for the currently selected mod
  662 + */
  663 + private void openConfigPanel()
  664 + {
  665 + if (this.selectedMod != null && this.selectedMod.getModClass() != null)
  666 + {
  667 + ConfigPanel panel = this.configPanelManager.getPanel(this.selectedMod.getModClass());
  668 + if (panel != null)
  669 + {
  670 + if (this.configPanel != null)
  671 + {
  672 + this.configPanel.onHidden();
  673 + }
  674 +
  675 + this.configPanel = new GuiConfigPanelContainer(this, this.mc, panel, this.selectedMod.getModInstance());
  676 + this.configPanel.setSize(this.width - LEFT_EDGE, this.height);
  677 + this.configPanel.onShown();
  678 + }
  679 + }
  680 + }
  681 +
  682 + /* (non-Javadoc)
  683 + * @see com.mumfrey.liteloader.modconfig.ConfigPanelHost#close()
  684 + */
  685 + void closeConfigPanel(GuiConfigPanelContainer container)
  686 + {
  687 + if (this.configPanel != null && (container == null || this.configPanel == container))
  688 + {
  689 + this.configPanel.onHidden();
  690 + this.configPanel = null;
  691 + }
  692 + }
  693 +
  694 + /**
553 695 * @param x
554 696 * @param y
555 697 * @param width
... ... @@ -590,7 +732,7 @@ public class GuiScreenModInfo extends GuiScreen
590 732 * @param yTop Top edge clip or -1 to not use this plane
591 733 * @param yBottom Bottom edge clip or -1 to not use this plane
592 734 */
593   - private final static void glEnableClipping(int xLeft, int xRight, int yTop, int yBottom)
  735 + final static void glEnableClipping(int xLeft, int xRight, int yTop, int yBottom)
594 736 {
595 737 // Apply left edge clipping if specified
596 738 if (xLeft != -1)
... ... @@ -632,7 +774,7 @@ public class GuiScreenModInfo extends GuiScreen
632 774 /**
633 775 * Disable OpenGL clipping planes (uses planes 2, 3, 4 and 5)
634 776 */
635   - private final static void glDisableClipping()
  777 + final static void glDisableClipping()
636 778 {
637 779 glDisable(GL_CLIP_PLANE5);
638 780 glDisable(GL_CLIP_PLANE4);
... ...
java/com/mumfrey/liteloader/modconfig/ConfigPanel.java 0 → 100644
  1 +package com.mumfrey.liteloader.modconfig;
  2 +
  3 +/**
  4 + * Interface for mod config panels to implement
  5 + *
  6 + * @author Adam Mummery-Smith
  7 + */
  8 +public interface ConfigPanel
  9 +{
  10 + /**
  11 + * Panels should return the text to display at the top of the config panel window
  12 + */
  13 + public abstract String getPanelTitle();
  14 +
  15 + /**
  16 + * Get the height of the content area for scrolling purposes, return -1 to disable scrolling
  17 + */
  18 + public abstract int getContentHeight();
  19 +
  20 + /**
  21 + * Called when the panel is displayed, initialise the panel (read settings, etc)
  22 + *
  23 + * @param host panel host
  24 + */
  25 + public abstract void onPanelShown(ConfigPanelHost host);
  26 +
  27 + /**
  28 + * Called when the window is resized whilst the panel is active
  29 + *
  30 + * @param host panel host
  31 + */
  32 + public abstract void onPanelResize(ConfigPanelHost host);
  33 +
  34 + /**
  35 + * Called when the panel is closed, panel should save settings
  36 + */
  37 + public abstract void onPanelHidden();
  38 +
  39 + /**
  40 + * Called every tick
  41 + */
  42 + public abstract void onTick(ConfigPanelHost host);
  43 +
  44 + /**
  45 + * Draw the configuration panel
  46 + *
  47 + * @param host
  48 + * @param mouseX
  49 + * @param mouseY
  50 + * @param partialTicks
  51 + */
  52 + public abstract void drawPanel(ConfigPanelHost host, int mouseX, int mouseY, float partialTicks);
  53 +
  54 + /**
  55 + * Called when a mouse button is pressed
  56 + *
  57 + * @param host
  58 + * @param mouseX
  59 + * @param mouseY
  60 + * @param mouseButton
  61 + */
  62 + public abstract void mousePressed(ConfigPanelHost host, int mouseX, int mouseY, int mouseButton);
  63 +
  64 + /**
  65 + * Called when a mouse button is released
  66 + *
  67 + * @param host
  68 + * @param mouseX
  69 + * @param mouseY
  70 + * @param mouseButton
  71 + */
  72 + public abstract void mouseReleased(ConfigPanelHost host, int mouseX, int mouseY, int mouseButton);
  73 +
  74 + /**
  75 + * Called when the mouse is moved
  76 + *
  77 + * @param host
  78 + * @param mouseX
  79 + * @param mouseY
  80 + */
  81 + public abstract void mouseMoved(ConfigPanelHost host, int mouseX, int mouseY);
  82 +
  83 + /**
  84 + * Called when a key is pressed
  85 + *
  86 + * @param host
  87 + * @param keyChar
  88 + * @param keyCode
  89 + */
  90 + public abstract void keyPressed(ConfigPanelHost host, char keyChar, int keyCode);
  91 +}
... ...
java/com/mumfrey/liteloader/modconfig/ConfigPanelHost.java 0 → 100644
  1 +package com.mumfrey.liteloader.modconfig;
  2 +
  3 +import com.mumfrey.liteloader.LiteMod;
  4 +
  5 +/**
  6 + * Interface for object which can host configuration panels
  7 + *
  8 + * @author Adam Mummery-Smith
  9 + */
  10 +public interface ConfigPanelHost
  11 +{
  12 + /**
  13 + * Get the mod instance which owns the panel
  14 + */
  15 + public abstract <ModClass extends LiteMod> ModClass getMod();
  16 +
  17 + /**
  18 + * Get the width of the configuration panel area
  19 + */
  20 + public abstract int getWidth();
  21 +
  22 + /**
  23 + * Get the height of the configuration panel area
  24 + */
  25 + public abstract int getHeight();
  26 +
  27 + /**
  28 + * Notify the panel host that the panel wishes to close
  29 + */
  30 + public abstract void close();
  31 +
  32 + /**
  33 + * Notify the panel host that the panel wishes to advance to the next panel
  34 + */
  35 +// public abstract void next();
  36 +
  37 + /**
  38 + * Notify the panel host that the panel wishes to go back to the previous panel
  39 + */
  40 +// public abstract void previous();
  41 +}
... ...
java/com/mumfrey/liteloader/modconfig/ConfigPanelManager.java 0 → 100644
  1 +package com.mumfrey.liteloader.modconfig;
  2 +
  3 +import java.util.HashMap;
  4 +import java.util.Map;
  5 +
  6 +import com.mumfrey.liteloader.Configurable;
  7 +import com.mumfrey.liteloader.LiteMod;
  8 +
  9 +/**
  10 + * Registry where we keep the mod config panel classes
  11 + *
  12 + * @author Adam Mummery-Smith
  13 + */
  14 +public class ConfigPanelManager
  15 +{
  16 + /**
  17 + * Mod config panel classes
  18 + */
  19 + private Map<Class<? extends LiteMod>, Class<? extends ConfigPanel>> configPanels = new HashMap<Class<? extends LiteMod>, Class<? extends ConfigPanel>>();
  20 +
  21 + /**
  22 + * Register a mod, adds the config panel class to the map if the mod implements Configurable
  23 + */
  24 + public void registerMod(LiteMod mod)
  25 + {
  26 + if (mod instanceof Configurable)
  27 + {
  28 + Class<? extends ConfigPanel> panelClass = ((Configurable)mod).getConfigPanelClass();
  29 + if (panelClass != null) this.configPanels.put(mod.getClass(), panelClass);
  30 + }
  31 + }
  32 +
  33 + /**
  34 + * Check whether a config panel is available for the specified class
  35 + *
  36 + * @param modClass
  37 + * @return
  38 + */
  39 + public boolean hasPanel(Class<? extends LiteMod> modClass)
  40 + {
  41 + return modClass != null && this.configPanels.containsKey(modClass);
  42 + }
  43 +
  44 + /**
  45 + * Instance a new config panel for the specified mod class if one is available
  46 + *
  47 + * @param modClass
  48 + * @return
  49 + */
  50 + public ConfigPanel getPanel(Class<? extends LiteMod> modClass)
  51 + {
  52 + if (modClass != null && this.configPanels.containsKey(modClass))
  53 + {
  54 + try
  55 + {
  56 + return this.configPanels.get(modClass).newInstance();
  57 + }
  58 + catch (InstantiationException ex) {}
  59 + catch (IllegalAccessException ex) {}
  60 +
  61 + // If instantiation fails, remove the panel
  62 + this.configPanels.remove(modClass);
  63 + }
  64 +
  65 + return null;
  66 + }
  67 +}
... ...
java/com/mumfrey/liteloader/permissions/PermissionsManagerClient.java
... ... @@ -14,6 +14,7 @@ import net.minecraft.src.Minecraft;
14 14 import net.minecraft.src.NetHandler;
15 15 import net.minecraft.src.Packet1Login;
16 16  
  17 +import com.mumfrey.liteloader.LiteMod;
17 18 import com.mumfrey.liteloader.Permissible;
18 19 import com.mumfrey.liteloader.PluginChannelListener;
19 20 import com.mumfrey.liteloader.core.PluginChannels;
... ... @@ -127,6 +128,19 @@ public class PermissionsManagerClient implements PermissionsManager, PluginChann
127 128 ServerPermissions modPermissions = this.serverPermissions.get(modName);
128 129 return modPermissions != null ? modPermissions.getReplicationTime() : 0;
129 130 }
  131 +
  132 + /**
  133 + * Register a new mod, if permissible
  134 + *
  135 + * @param mod
  136 + */
  137 + public void registerMod(LiteMod mod)
  138 + {
  139 + if (mod instanceof Permissible)
  140 + {
  141 + this.registerPermissible((Permissible)mod);
  142 + }
  143 + }
130 144  
131 145 /* (non-Javadoc)
132 146 * @see net.eq2online.permissions.PermissionsManager#registerListener(net.eq2online.permissions.PermissionsListener)
... ...