Merge pull request #614 from tterrag1098/betterModList
Improve mod list GUI, adds sort buttons and a search bar
This commit is contained in:
commit
5ac394de0e
|
@ -19,6 +19,9 @@ import java.awt.image.BufferedImage;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
|
|
||||||
|
@ -26,6 +29,7 @@ import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.FontRenderer;
|
import net.minecraft.client.gui.FontRenderer;
|
||||||
import net.minecraft.client.gui.GuiButton;
|
import net.minecraft.client.gui.GuiButton;
|
||||||
import net.minecraft.client.gui.GuiScreen;
|
import net.minecraft.client.gui.GuiScreen;
|
||||||
|
import net.minecraft.client.gui.GuiTextField;
|
||||||
import net.minecraft.client.renderer.Tessellator;
|
import net.minecraft.client.renderer.Tessellator;
|
||||||
import net.minecraft.client.renderer.WorldRenderer;
|
import net.minecraft.client.renderer.WorldRenderer;
|
||||||
import net.minecraft.client.renderer.texture.DynamicTexture;
|
import net.minecraft.client.renderer.texture.DynamicTexture;
|
||||||
|
@ -49,6 +53,28 @@ import com.google.common.base.Strings;
|
||||||
*/
|
*/
|
||||||
public class GuiModList extends GuiScreen
|
public class GuiModList extends GuiScreen
|
||||||
{
|
{
|
||||||
|
private enum SortType
|
||||||
|
{
|
||||||
|
NORMAL(24), A_TO_Z(25), Z_TO_A(26);
|
||||||
|
|
||||||
|
private int buttonID;
|
||||||
|
|
||||||
|
private SortType(int buttonID)
|
||||||
|
{
|
||||||
|
this.buttonID = buttonID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SortType getTypeForButton(GuiButton button)
|
||||||
|
{
|
||||||
|
for (SortType t : values()) {
|
||||||
|
if (t.buttonID == button.id) {
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private GuiScreen mainMenu;
|
private GuiScreen mainMenu;
|
||||||
private GuiSlotModList modList;
|
private GuiSlotModList modList;
|
||||||
private int selected = -1;
|
private int selected = -1;
|
||||||
|
@ -60,6 +86,15 @@ public class GuiModList extends GuiScreen
|
||||||
private ResourceLocation cachedLogo;
|
private ResourceLocation cachedLogo;
|
||||||
private Dimension cachedLogoDimensions;
|
private Dimension cachedLogoDimensions;
|
||||||
|
|
||||||
|
private int buttonMargin = 1;
|
||||||
|
private int numButtons = SortType.values().length;
|
||||||
|
|
||||||
|
private String lastFilterText = "";
|
||||||
|
|
||||||
|
private GuiTextField search;
|
||||||
|
private boolean sorted = false;
|
||||||
|
private SortType sortType = SortType.NORMAL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mainMenu
|
* @param mainMenu
|
||||||
*/
|
*/
|
||||||
|
@ -68,6 +103,7 @@ public class GuiModList extends GuiScreen
|
||||||
this.mainMenu=mainMenu;
|
this.mainMenu=mainMenu;
|
||||||
this.mods=new ArrayList<ModContainer>();
|
this.mods=new ArrayList<ModContainer>();
|
||||||
FMLClientHandler.instance().addSpecialModEntries(mods);
|
FMLClientHandler.instance().addSpecialModEntries(mods);
|
||||||
|
// Add child mods to their parent's list
|
||||||
for (ModContainer mod : Loader.instance().getModList()) {
|
for (ModContainer mod : Loader.instance().getModList()) {
|
||||||
if (mod.getMetadata()!=null && mod.getMetadata().parentMod==null && !Strings.isNullOrEmpty(mod.getMetadata().parent)) {
|
if (mod.getMetadata()!=null && mod.getMetadata().parentMod==null && !Strings.isNullOrEmpty(mod.getMetadata().parent)) {
|
||||||
String parentMod = mod.getMetadata().parent;
|
String parentMod = mod.getMetadata().parent;
|
||||||
|
@ -81,7 +117,7 @@ public class GuiModList extends GuiScreen
|
||||||
}
|
}
|
||||||
else if (mod.getMetadata()!=null && mod.getMetadata().parentMod!=null)
|
else if (mod.getMetadata()!=null && mod.getMetadata().parentMod!=null)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
mods.add(mod);
|
mods.add(mod);
|
||||||
}
|
}
|
||||||
|
@ -96,21 +132,133 @@ public class GuiModList extends GuiScreen
|
||||||
listWidth=Math.max(listWidth,getFontRenderer().getStringWidth(mod.getVersion()) + 10);
|
listWidth=Math.max(listWidth,getFontRenderer().getStringWidth(mod.getVersion()) + 10);
|
||||||
}
|
}
|
||||||
listWidth=Math.min(listWidth, 150);
|
listWidth=Math.min(listWidth, 150);
|
||||||
this.buttonList.add(new GuiButton(6, this.width / 2 - 75, this.height - 38, I18n.format("gui.done")));
|
|
||||||
configModButton = new GuiButton(20, 10, this.height - 60, this.listWidth, 20, "Config");
|
|
||||||
disableModButton = new GuiButton(21, 10, this.height - 38, this.listWidth, 20, "Disable");
|
|
||||||
this.buttonList.add(configModButton);
|
|
||||||
this.buttonList.add(disableModButton);
|
|
||||||
this.modList=new GuiSlotModList(this, mods, listWidth);
|
this.modList=new GuiSlotModList(this, mods, listWidth);
|
||||||
this.modList.registerScrollButtons(this.buttonList, 7, 8);
|
this.modList.registerScrollButtons(this.buttonList, 7, 8);
|
||||||
|
|
||||||
|
this.buttonList.add(new GuiButton(6, ((modList.right + this.width) / 2) - 100, this.height - 38, I18n.format("gui.done")));
|
||||||
|
configModButton = new GuiButton(20, 10, this.height - 49, this.listWidth, 20, "Config");
|
||||||
|
disableModButton = new GuiButton(21, 10, this.height - 27, this.listWidth, 20, "Disable");
|
||||||
|
this.buttonList.add(configModButton);
|
||||||
|
this.buttonList.add(disableModButton);
|
||||||
|
|
||||||
|
search = new GuiTextField(0, getFontRenderer(), 12, modList.bottom + 17, modList.listWidth - 4, 14);
|
||||||
|
search.setFocused(true);
|
||||||
|
search.setCanLoseFocus(true);
|
||||||
|
|
||||||
|
int width = (modList.listWidth / numButtons);
|
||||||
|
int x = 10, y = 10;
|
||||||
|
GuiButton normalSort = new GuiButton(SortType.NORMAL.buttonID, x, y, width - buttonMargin, 20, I18n.format("fml.menu.mods.normal"));
|
||||||
|
normalSort.enabled = false;
|
||||||
|
buttonList.add(normalSort);
|
||||||
|
x += width + buttonMargin;
|
||||||
|
buttonList.add(new GuiButton(SortType.A_TO_Z.buttonID, x, y, width - buttonMargin, 20, "A-Z"));
|
||||||
|
x += width + buttonMargin;
|
||||||
|
buttonList.add(new GuiButton(SortType.Z_TO_A.buttonID, x, y, width - buttonMargin, 20, "Z-A"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void mouseClicked(int x, int y, int button) throws IOException
|
||||||
|
{
|
||||||
|
super.mouseClicked(x, y, button);
|
||||||
|
search.mouseClicked(x, y, button);
|
||||||
|
if (button == 1 && x >= search.xPosition && x < search.xPosition + this.width && y >= search.yPosition && y < search.yPosition + this.height) {
|
||||||
|
search.setText("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void keyTyped(char c, int keyCode) throws IOException
|
||||||
|
{
|
||||||
|
super.keyTyped(c, keyCode);
|
||||||
|
search.textboxKeyTyped(c, keyCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateScreen()
|
||||||
|
{
|
||||||
|
super.updateScreen();
|
||||||
|
search.updateCursorCounter();
|
||||||
|
|
||||||
|
if (!search.getText().equals(lastFilterText))
|
||||||
|
{
|
||||||
|
reloadMods();
|
||||||
|
sorted = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sorted)
|
||||||
|
{
|
||||||
|
switch (sortType)
|
||||||
|
{
|
||||||
|
case A_TO_Z:
|
||||||
|
Collections.sort(modList.getMods(), new Comparator<ModContainer>()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public int compare(ModContainer o1, ModContainer o2)
|
||||||
|
{
|
||||||
|
return o1.getName().toLowerCase().compareTo(o2.getName().toLowerCase());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case Z_TO_A:
|
||||||
|
Collections.sort(modList.getMods(), new Comparator<ModContainer>()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public int compare(ModContainer o1, ModContainer o2)
|
||||||
|
{
|
||||||
|
return o2.getName().toLowerCase().compareTo(o1.getName().toLowerCase());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
reloadMods();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mods = modList.getMods();
|
||||||
|
selected = modList.selectedIndex = mods.indexOf(selectedMod);
|
||||||
|
sorted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void reloadMods()
|
||||||
|
{
|
||||||
|
ArrayList<ModContainer> mods = modList.getMods();
|
||||||
|
mods.clear();
|
||||||
|
for (ModContainer m : Loader.instance().getActiveModList())
|
||||||
|
{
|
||||||
|
// If it passes the filter, and is not a child mod
|
||||||
|
if (m.getName().toLowerCase().contains(search.getText().toLowerCase()) && m.getMetadata().parentMod == null)
|
||||||
|
{
|
||||||
|
mods.add(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.mods = mods;
|
||||||
|
lastFilterText = search.getText();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void actionPerformed(GuiButton button) throws IOException {
|
protected void actionPerformed(GuiButton button) throws IOException {
|
||||||
if (button.enabled)
|
if (button.enabled)
|
||||||
{
|
{
|
||||||
switch (button.id)
|
SortType type = SortType.getTypeForButton(button);
|
||||||
|
|
||||||
|
if (type != null)
|
||||||
{
|
{
|
||||||
|
for (GuiButton b : (List<GuiButton>) buttonList)
|
||||||
|
{
|
||||||
|
if (SortType.getTypeForButton(b) != null)
|
||||||
|
{
|
||||||
|
b.enabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
button.enabled = false;
|
||||||
|
sorted = false;
|
||||||
|
sortType = type;
|
||||||
|
this.mods = modList.getMods();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (button.id)
|
||||||
|
{
|
||||||
case 6:
|
case 6:
|
||||||
this.mc.displayGuiScreen(this.mainMenu);
|
this.mc.displayGuiScreen(this.mainMenu);
|
||||||
return;
|
return;
|
||||||
|
@ -126,6 +274,7 @@ public class GuiModList extends GuiScreen
|
||||||
FMLLog.log(Level.ERROR, e, "There was a critical issue trying to build the config GUI for %s", selectedMod.getModId());
|
FMLLog.log(Level.ERROR, e, "There was a critical issue trying to build the config GUI for %s", selectedMod.getModId());
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
super.actionPerformed(button);
|
super.actionPerformed(button);
|
||||||
|
@ -274,6 +423,11 @@ public class GuiModList extends GuiScreen
|
||||||
disableModButton.visible = false;
|
disableModButton.visible = false;
|
||||||
}
|
}
|
||||||
super.drawScreen(p_571_1_, p_571_2_, p_571_3_);
|
super.drawScreen(p_571_1_, p_571_2_, p_571_3_);
|
||||||
|
|
||||||
|
String text = I18n.format("fml.menu.mods.search");
|
||||||
|
int x = ((10 + modList.right) / 2) - (getFontRenderer().getStringWidth(text) / 2);
|
||||||
|
getFontRenderer().drawString(text, x, modList.bottom + 5, 0xFFFFFF);
|
||||||
|
search.drawTextBox();
|
||||||
}
|
}
|
||||||
|
|
||||||
Minecraft getMinecraftInstance() {
|
Minecraft getMinecraftInstance() {
|
||||||
|
|
|
@ -31,7 +31,7 @@ public abstract class GuiScrollingList
|
||||||
protected final int listHeight;
|
protected final int listHeight;
|
||||||
protected final int top;
|
protected final int top;
|
||||||
protected final int bottom;
|
protected final int bottom;
|
||||||
private final int right;
|
protected final int right;
|
||||||
protected final int left;
|
protected final int left;
|
||||||
protected final int slotHeight;
|
protected final int slotHeight;
|
||||||
private int scrollUpActionId;
|
private int scrollUpActionId;
|
||||||
|
@ -41,7 +41,7 @@ public abstract class GuiScrollingList
|
||||||
private float initialMouseClickY = -2.0F;
|
private float initialMouseClickY = -2.0F;
|
||||||
private float scrollFactor;
|
private float scrollFactor;
|
||||||
private float scrollDistance;
|
private float scrollDistance;
|
||||||
private int selectedIndex = -1;
|
protected int selectedIndex = -1;
|
||||||
private long lastClickTime = 0L;
|
private long lastClickTime = 0L;
|
||||||
private boolean field_25123_p = true;
|
private boolean field_25123_p = true;
|
||||||
private boolean field_27262_q;
|
private boolean field_27262_q;
|
||||||
|
|
|
@ -16,8 +16,8 @@ import java.util.ArrayList;
|
||||||
|
|
||||||
import net.minecraft.client.renderer.Tessellator;
|
import net.minecraft.client.renderer.Tessellator;
|
||||||
import net.minecraftforge.fml.common.Loader;
|
import net.minecraftforge.fml.common.Loader;
|
||||||
import net.minecraftforge.fml.common.ModContainer;
|
|
||||||
import net.minecraftforge.fml.common.LoaderState.ModState;
|
import net.minecraftforge.fml.common.LoaderState.ModState;
|
||||||
|
import net.minecraftforge.fml.common.ModContainer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author cpw
|
* @author cpw
|
||||||
|
@ -30,7 +30,7 @@ public class GuiSlotModList extends GuiScrollingList
|
||||||
|
|
||||||
public GuiSlotModList(GuiModList parent, ArrayList<ModContainer> mods, int listWidth)
|
public GuiSlotModList(GuiModList parent, ArrayList<ModContainer> mods, int listWidth)
|
||||||
{
|
{
|
||||||
super(parent.getMinecraftInstance(), listWidth, parent.height, 32, parent.height - 66 + 4, 10, 35);
|
super(parent.getMinecraftInstance(), listWidth, parent.height, 32, parent.height - 88 + 4, 10, 35);
|
||||||
this.parent=parent;
|
this.parent=parent;
|
||||||
this.mods=mods;
|
this.mods=mods;
|
||||||
}
|
}
|
||||||
|
@ -65,6 +65,11 @@ public class GuiSlotModList extends GuiScrollingList
|
||||||
return (this.getSize()) * 35 + 1;
|
return (this.getSize()) * 35 + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ArrayList<ModContainer> getMods()
|
||||||
|
{
|
||||||
|
return mods;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void drawSlot(int listIndex, int var2, int var3, int var4, Tessellator var5)
|
protected void drawSlot(int listIndex, int var2, int var3, int var4, Tessellator var5)
|
||||||
{
|
{
|
||||||
|
|
|
@ -82,4 +82,6 @@ fml.configgui.tooltip.default=[default: %s]
|
||||||
fml.configgui.tooltip.defaultNumeric=[range: %s ~ %s, default: %s]
|
fml.configgui.tooltip.defaultNumeric=[range: %s ~ %s, default: %s]
|
||||||
|
|
||||||
fml.menu.mods=Mods
|
fml.menu.mods=Mods
|
||||||
|
fml.menu.mods.normal=Normal
|
||||||
|
fml.menu.mods.search=Search:
|
||||||
fml.menu.modoptions=Mod Options...
|
fml.menu.modoptions=Mod Options...
|
||||||
|
|
Loading…
Reference in New Issue