Skip to content

Commit 6d3a784

Browse files
committed
GuiModMenu kiva edition.
1 parent 7616ec7 commit 6d3a784

File tree

11 files changed

+280
-53
lines changed

11 files changed

+280
-53
lines changed

loader/src/main/java/com/fox2code/foxloader/client/gui/GuiModMenu.java

Lines changed: 158 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -29,24 +29,29 @@
2929
import com.fox2code.foxloader.loader.ModContainer;
3030
import com.fox2code.foxloader.loader.ModInfo;
3131
import com.fox2code.foxloader.loader.ModLoader;
32+
import com.fox2code.foxloader.loader.ModLoaderInit;
3233
import com.fox2code.foxloader.updater.UpdateManager;
34+
import com.fox2code.foxloader.utils.io.URLUtils;
3335
import net.minecraft.client.Minecraft;
34-
import net.minecraft.client.gui.FontRenderer;
35-
import net.minecraft.client.gui.GuiButton;
36-
import net.minecraft.client.gui.GuiScreen;
37-
import net.minecraft.client.gui.GuiSmallButton;
36+
import net.minecraft.client.gui.*;
37+
import net.minecraft.common.util.Utils;
3838
import net.minecraft.common.util.i18n.StringTranslate;
39-
import org.lwjgl.Sys;
39+
40+
import java.util.Arrays;
4041

4142
public class GuiModMenu extends GuiScreen {
43+
private static final int BUTTON_MARGIN = 4;
4244
private GuiModMenuContainer modListContainer;
4345
GuiModMenuDescription modListDescription;
44-
private GuiSmallButton guiUpdateAll, guiConfigureMod;
45-
private Object guiScreen;
46+
private GuiSmallButton guiUpdateAll;
47+
private final GuiButton[] modActionButtons = new GuiButton[4];
48+
private final ModActionButtonType[] modActionButtonsTypes = new ModActionButtonType[4];
4649
private int selectedBackup = 0;
50+
private String screenTitle;
4751

4852
public GuiModMenu(GuiScreen parent) {
4953
this.parentScreen = parent;
54+
this.screenTitle = "Mod Menu";
5055
}
5156

5257
@Override
@@ -57,42 +62,54 @@ public void initGui() {
5762
this.modListDescription = new GuiModMenuDescription(this);
5863
this.controlList.add(this.modListDescription);
5964
StringTranslate st = StringTranslate.getInstance();
65+
this.screenTitle = st.translateKeyFormat(
66+
"mods.title", ModLoaderInit.getModContainers().size());
67+
int widthOneSixth = Math.min(this.width / 6, 50 + (BUTTON_MARGIN * 6));
68+
int midWidth = this.width / 2;
69+
int buttonWidth = Math.max(Math.min(150, (widthOneSixth - BUTTON_MARGIN) * 2), 50);
6070
this.controlList.add(new GuiSmallButton(0,
61-
this.width / 2 - 154, this.height - 48,
71+
midWidth - (widthOneSixth * 3) + BUTTON_MARGIN,
72+
this.height - 24, buttonWidth, 20,
6273
st.translateKey("mods.openFolder")));
6374
this.controlList.add(new GuiSmallButton(1,
64-
this.width / 2 + 4, this.height - 48,
75+
midWidth - widthOneSixth + BUTTON_MARGIN,
76+
this.height - 24, buttonWidth, 20,
6577
st.translateKey("gui.done")));
6678
this.controlList.add(this.guiUpdateAll = new GuiSmallButton(2,
67-
this.width / 2 - 154, this.height - 24,
79+
midWidth + widthOneSixth + BUTTON_MARGIN,
80+
this.height - 24, buttonWidth, 20,
6881
st.translateKey("mods.updateAllMods")));
69-
this.controlList.add(this.guiConfigureMod = new GuiSmallButton(3,
70-
this.width / 2 + 4, this.height - 24,
71-
st.translateKey("mods.configureMod")));
82+
// Mod Actions buttons
83+
for (int i = 0; i < this.modActionButtons.length; i++) {
84+
GuiSmallButton guiSmallButton = new GuiSmallButton(4 + i, 240, 32, "#" + i);
85+
this.modActionButtons[i] = guiSmallButton;
86+
this.controlList.add(guiSmallButton);
87+
guiSmallButton.visible = false;
88+
}
89+
Arrays.fill(this.modActionButtonsTypes, null);
7290
// Update GUI state after init
7391
this.modListContainer.elementClicked(this.selectedBackup, false);
7492
}
7593

7694
@Override
7795
public void drawScreen(float var1, float var2, float deltaTicks) {
7896
this.drawDefaultBackground();
97+
this.drawCenteredString(this.fontRenderer, this.screenTitle, (int) (this.width / 2), 13, 0xffffff);
7998
super.drawScreen(var1, var2, deltaTicks);
8099
}
81100

82101
@Override
83102
protected void actionPerformed(GuiButton var1) {
84103
if (var1.id == 0) {
85-
Sys.openURL("file://" + ModLoader.getModsFolder().getPath());
104+
Utils.openURL("file://" + ModLoader.getModsFolder().getPath());
86105
} else if (var1.id == 1) {
87106
this.mc.displayGuiScreen(this.parentScreen);
88107
} else if (var1.id == 2) {
89108
UpdateManager.getInstance().doUpdates();
90-
} else if (var1.id == 3) {
91-
if (this.guiScreen instanceof GuiConfigProvider) {
92-
Minecraft.getInstance().displayGuiScreen(
93-
((GuiConfigProvider) this.guiScreen).provideConfigScreen(this));
94-
} else {
95-
this.openModConfigScreen(this.modListContainer.getSelectedModContainer());
109+
} else if (var1.id >= 4 && var1.id < 8) {
110+
ModActionButtonType type = this.modActionButtonsTypes[var1.id - 4];
111+
if (type != null) {
112+
type.doAction(this.modListContainer.getSelectedModContainer(), this);
96113
}
97114
} else {
98115
this.modListContainer.actionPerformed(var1);
@@ -110,20 +127,10 @@ public FontRenderer getFontRenderer() {
110127

111128
void updateGuiState() {
112129
this.selectedBackup = this.modListContainer.getSelectedIndex();
113-
final StringTranslate st = StringTranslate.getInstance();
114130
final ModContainer modContainer = this.modListContainer.getSelectedModContainer();
115131
this.guiUpdateAll.enabled = UpdateManager.getInstance().canUpdate();
116-
this.guiScreen = null;
117-
this.guiConfigureMod.displayString = st.translateKey("mods.configureMod");
118-
Object configObject = modContainer.getConfigObject();
119-
if (configObject instanceof GuiConfigProvider) {
120-
this.guiScreen = modContainer.getConfigObject();
121-
this.guiConfigureMod.enabled = true;
122-
} else if (configObject == null) {
123-
this.guiConfigureMod.enabled = false;
124-
} else {
125-
this.guiConfigureMod.enabled = !(configObject instanceof NoConfigObject);
126-
}
132+
// Update mod action buttons
133+
this.updateActionButtons();
127134
// Update mod description
128135
ModInfo modInfo = modContainer.getModInfo();
129136
String fileName = modInfo.fileName;
@@ -138,4 +145,123 @@ void updateGuiState() {
138145
this.modListDescription.addText("Authors: " + modInfo.authors);
139146
this.modListDescription.addText("Description: " + modInfo.description);
140147
}
148+
149+
void updateActionButtons() {
150+
final ModContainer modContainer = this.modListContainer.getSelectedModContainer();
151+
this.resetModButtonAction(0);
152+
Object configObject = modContainer.getConfigObject();
153+
ModInfo modInfo = modContainer.getModInfo();
154+
if (UpdateManager.getInstance().canUpdate(modContainer.getModId())) {
155+
this.addModButtonAction(ModActionButtonType.UPDATE);
156+
}
157+
if (configObject instanceof GuiConfigProvider ||
158+
(configObject != null && !(configObject instanceof NoConfigObject))) {
159+
this.addModButtonAction(ModActionButtonType.CONFIGURE);
160+
}
161+
if (URLUtils.isValidHttpURL(modInfo.website)) {
162+
this.addModButtonAction(ModActionButtonType.WEBSITE);
163+
}
164+
int buttonCount = this.countButtonActions();
165+
if (buttonCount == 0) {
166+
this.addModButtonAction(ModActionButtonType.CONFIGURE);
167+
this.modActionButtons[0].enabled = false;
168+
buttonCount = 1;
169+
}
170+
if (buttonCount == 1 && this.modActionButtonsTypes[0] == ModActionButtonType.CONFIGURE) {
171+
this.modActionButtons[0].displayString =
172+
StringTranslate.getInstance().translateKey("mods.configureMod");
173+
}
174+
int leftMost = 240 - BUTTON_MARGIN;
175+
int rightMost = this.width + BUTTON_MARGIN - 10;
176+
int mostPossibleButtons = (rightMost - leftMost) / (50 + (BUTTON_MARGIN * 2));
177+
if (mostPossibleButtons <= 0) {
178+
this.resetModButtonAction(0);
179+
return;
180+
} else if (mostPossibleButtons < buttonCount) {
181+
this.resetModButtonAction(mostPossibleButtons);
182+
buttonCount = mostPossibleButtons;
183+
}
184+
int totalWidth = rightMost - leftMost;
185+
int buttonSpace = totalWidth / buttonCount;
186+
int leakingWidth = totalWidth % buttonCount;
187+
int buttonWidth = buttonSpace - (BUTTON_MARGIN * 2);
188+
for (int i = 0; i < buttonCount; i++) {
189+
GuiButton guiButton = this.modActionButtons[i];
190+
guiButton.width = buttonWidth;
191+
guiButton.xPosition = leftMost + BUTTON_MARGIN + (buttonSpace * i);
192+
if (i != 0) {
193+
guiButton.xPosition += ((leakingWidth * i) / (buttonCount - 1));
194+
}
195+
}
196+
}
197+
198+
private void resetModButtonAction(int fromId) {
199+
for (int i = fromId; i < this.modActionButtons.length; i++) {
200+
this.modActionButtonsTypes[i] = null;
201+
GuiButton guiButton = this.modActionButtons[i];
202+
if (guiButton != null) {
203+
guiButton.visible = false;
204+
guiButton.enabled = true;
205+
}
206+
}
207+
}
208+
209+
private void addModButtonAction(ModActionButtonType modActionButtonType) {
210+
for (int i = 0; i < this.modActionButtons.length; i++) {
211+
if (this.modActionButtonsTypes[i] == null) {
212+
this.modActionButtonsTypes[i] = modActionButtonType;
213+
GuiButton guiButton = this.modActionButtons[i];
214+
guiButton.displayString = StringTranslate.getInstance()
215+
.translateKey(modActionButtonType.titleTranslate);
216+
guiButton.visible = true;
217+
break;
218+
}
219+
}
220+
}
221+
222+
private int countButtonActions() {
223+
for (int i = 0; i < this.modActionButtons.length; i++) {
224+
if (this.modActionButtonsTypes[i] == null) {
225+
return i;
226+
}
227+
}
228+
return this.modActionButtons.length;
229+
}
230+
231+
private enum ModActionButtonType {
232+
UPDATE("mods.update") {
233+
@Override
234+
void doAction(ModContainer modContainer, GuiModMenu guiModMenu) {
235+
UpdateManager.getInstance().doUpdate(modContainer.getModId());
236+
guiModMenu.updateActionButtons();
237+
}
238+
}, CONFIGURE("mods.configure") {
239+
@Override
240+
void doAction(ModContainer modContainer, GuiModMenu guiModMenu) {
241+
Object configObject = modContainer.getConfigObject();
242+
if (configObject instanceof GuiConfigProvider) {
243+
Minecraft.getInstance().displayGuiScreen(
244+
((GuiConfigProvider) configObject).provideConfigScreen(guiModMenu));
245+
} else if (!(configObject instanceof NoConfigObject)) {
246+
guiModMenu.openModConfigScreen(modContainer);
247+
}
248+
}
249+
}, WEBSITE("mods.website") {
250+
@Override
251+
void doAction(ModContainer modContainer, GuiModMenu guiModMenu) {
252+
String website = modContainer.getModInfo().website;
253+
if (URLUtils.isValidHttpURL(website)) {
254+
Utils.openURL(website);
255+
}
256+
}
257+
};
258+
259+
final String titleTranslate;
260+
261+
ModActionButtonType(String titleTranslate) {
262+
this.titleTranslate = titleTranslate;
263+
}
264+
265+
abstract void doAction(ModContainer modContainer, GuiModMenu guiModMenu);
266+
}
141267
}

loader/src/main/java/com/fox2code/foxloader/client/gui/GuiModMenuContainer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public class GuiModMenuContainer extends GuiSlotSimple {
4848

4949
public GuiModMenuContainer(GuiModMenu guiModList) {
5050
super(guiModList.width, guiModList.height,
51-
32, guiModList.height - 51, 36, ENTRY_WIDTH);
51+
32, guiModList.height - 26, 36, ENTRY_WIDTH);
5252
this.left = SIDE_OFFSET;
5353
this.right = ENTRY_WIDTH + SIDE_OFFSET + (CONTENT_MARGIN * 2);
5454
this.scrollbarOffset = CONTENT_MARGIN;

loader/src/main/java/com/fox2code/foxloader/client/gui/GuiModMenuDescription.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,14 @@
3333
public class GuiModMenuDescription extends GuiSlot {
3434
private static final int SIDE_PANEL_WIDTH = 240;
3535
private static final int EXTRA_PADDING = 10;
36+
private static final int ACTION_BUTTONS_HEIGHT = 20;
3637
private final ArrayList<String> description = new ArrayList<>();
3738
private final FontRenderer fontRenderer;
3839
private int usedContentHeight = 0;
3940

4041
GuiModMenuDescription(GuiModMenu guiModList) {
4142
super(guiModList.width, guiModList.height,
42-
32, guiModList.height - 51,
43+
32 + ACTION_BUTTONS_HEIGHT, guiModList.height - 26,
4344
guiModList.getFontRenderer().FONT_HEIGHT,
4445
guiModList.width - SIDE_PANEL_WIDTH - EXTRA_PADDING);
4546
this.left = SIDE_PANEL_WIDTH;

loader/src/main/java/com/fox2code/foxloader/loader/ModInfo.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ public class ModInfo extends FileInfo implements IMixinConfigSource {
4545
private static final Attributes.Name MOD_AUTHORS = new Attributes.Name("ModAuthors");
4646
private static final Attributes.Name MOD_ICON = new Attributes.Name("ModIcon");
4747
private static final Attributes.Name MOD_ENVIRONMENT = new Attributes.Name("ModEnvironment");
48+
private static final Attributes.Name MOD_WEBSITE = new Attributes.Name("ModWebsite");
4849
private static final Attributes.Name UNOFFICIAL = new Attributes.Name("Unofficial");
4950
private static final Attributes.Name LOAD_ORDER_PRIORITY = new Attributes.Name("LoadOrderPriority");
5051

@@ -56,12 +57,13 @@ public class ModInfo extends FileInfo implements IMixinConfigSource {
5657
@NotNull public final String authors;
5758
@Nullable public final String iconPath;
5859
@NotNull public final String environment;
60+
@Nullable public final String website;
5961
public final boolean unofficial;
6062
public final long loadOrderPriority;
6163

6264
public ModInfo(@NotNull File file, @Nullable String jarPath, @NotNull String id,@Nullable String name,
6365
@Nullable String version,@Nullable String description,@Nullable String authors,
64-
@Nullable String iconPath,@Nullable String environment,
66+
@Nullable String iconPath,@Nullable String environment, @Nullable String website,
6567
boolean unofficial, long loadOrderPriority) throws IOException {
6668
super(file, jarPath);
6769
this.id = Objects.requireNonNull(id);
@@ -77,6 +79,7 @@ public ModInfo(@NotNull File file, @Nullable String jarPath, @NotNull String id,
7779
this.iconPath = iconPath;
7880
this.environment = environment != null &&
7981
!environment.isEmpty() ? environment : "any";
82+
this.website = website;
8083
this.unofficial = unofficial;
8184
this.loadOrderPriority = loadOrderPriority;
8285
}
@@ -91,6 +94,7 @@ public ModInfo(DataInputStream dataInputStream) throws IOException {
9194
this.authors = readStringSafest(dataInputStream, "Unknown");
9295
this.iconPath = readStringSafest(dataInputStream, null);
9396
this.environment = readStringSafest(dataInputStream, null);
97+
this.website = readStringSafest(dataInputStream, null);
9498
this.unofficial = dataInputStream.readBoolean();
9599
this.loadOrderPriority = dataInputStream.readLong();
96100
}
@@ -122,6 +126,7 @@ protected ModInfo(File file, String jarPath, Attributes mainAttributes) throws I
122126
String environment = mainAttributes.getValue(MOD_ENVIRONMENT);
123127
this.environment = environment != null &&
124128
!environment.isEmpty() ? environment : "any";
129+
this.website = mainAttributes.getValue(MOD_WEBSITE);
125130
this.unofficial = Boolean.parseBoolean(mainAttributes.getValue(UNOFFICIAL));
126131
String priorityText = mainAttributes.getValue(LOAD_ORDER_PRIORITY);
127132
long priority = 0;

loader/src/main/java/com/fox2code/foxloader/loader/java/JavaLoadingPlugin.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public ModInfo getReIndevModInfo() throws IOException {
6262
"A mod designed to bring back the old feel of Minecraft while also extending it, " +
6363
"by adding new biomes, blocks, mobs, items, and more!",
6464
"Silveros, DasJafss, Fox2Code, icanttellyou, Zero_DSRS_VX, kivattt",
65-
"icon32.png", "any", false, Long.MAX_VALUE, null);
65+
"icon32.png", "any", null, false, Long.MAX_VALUE, null);
6666
}
6767
return this.reIndevModInfo;
6868
}
@@ -92,7 +92,7 @@ public ModInfo getReIndevModInfo() throws IOException {
9292
injected.add(new JavaModInfo(spark, null, "spark", "Spark", BuildConfig.SPARK_VERSION,
9393
"Spark is a performance profiling plugin/mod for Minecraft clients, servers and proxies.\n\n" +
9494
"Note: This specific version is bundled with FoxLoader",
95-
"Luck", "assets/spark/icon.png", "any", true, 0,
95+
"Luck", "assets/spark/icon.png", "any", "https://spark.lucko.me/", true, 0,
9696
"com.fox2code.foxloader.spark.FoxLoaderSparkPlugin"));
9797
} catch (IOException e) {
9898
ModLoaderInit.getModLoaderLogger().log(Level.WARNING, "Failed to add spark as a ModInfo");

loader/src/main/java/com/fox2code/foxloader/loader/java/JavaModInfo.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ public final class JavaModInfo extends ModInfo {
5454
FOX_LOADER_MOD_INFO = new JavaModInfo(
5555
FoxLauncher.foxLoaderFile, null, "foxloader", "FoxLoader", BuildConfig.FOXLOADER_VERSION,
5656
"ReIndev mod loader with foxes!!!", "Fox2Code", "assets/foxloader/icon.png",
57-
"any", false, Long.MAX_VALUE, "com.fox2code.foxloader.loader.ModLoader");
57+
"any", "https://github.com/Fox2Code/FoxLoader", false,
58+
Long.MAX_VALUE, "com.fox2code.foxloader.loader.ModLoader");
5859
} catch (IOException e) {
5960
throw new IOError(e);
6061
}
@@ -96,8 +97,9 @@ private JavaModInfo(File file, String jarPath, Attributes mainAttributes) throws
9697
}
9798

9899
JavaModInfo(File file, String jarPath, String id, String name, String version, String description, String authors, String iconPath,
99-
String environment, boolean unofficial, long loadOrderPriority, String main) throws IOException {
100-
super(file, jarPath, id, name, version, description, authors, iconPath, environment, unofficial, loadOrderPriority);
100+
String environment, String website, boolean unofficial, long loadOrderPriority, String main) throws IOException {
101+
super(file, jarPath, id, name, version, description, authors,
102+
iconPath, environment, website, unofficial, loadOrderPriority);
101103
this.requestedDependencyBundles = Collections.emptyList();
102104
this.forFoxLoaderVersion = BuildConfig.FOXLOADER_VERSION;
103105
this.classTransformer = null;

loader/src/main/java/com/fox2code/foxloader/loader/packet/ClientHello.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,6 @@ public void readData(DataInputStream dataInputStream) throws IOException {
8686
int type = dataInputStream.readUnsignedByte();
8787
FileInfo fileInfo;
8888
switch (type) {
89-
default: {
90-
throw new RuntimeException("Server is outdated??? (Code: C)");
91-
}
9289
case 0: {
9390
fileInfo = new FileInfo(dataInputStream);
9491
break;
@@ -101,6 +98,9 @@ public void readData(DataInputStream dataInputStream) throws IOException {
10198
fileInfo = new ModInfo(dataInputStream);
10299
break;
103100
}
101+
default: {
102+
throw new RuntimeException("Server is outdated??? (Code: C)");
103+
}
104104
}
105105
this.clientClassPathData.add(fileInfo);
106106
}
@@ -127,6 +127,7 @@ public void writeData(DataOutputStream dataOutputStream) throws IOException {
127127
writeStringSafest(dataOutputStream, modInfo.authors, true);
128128
writeStringSafest(dataOutputStream, modInfo.iconPath, true);
129129
writeStringSafest(dataOutputStream, modInfo.environment, true);
130+
writeStringSafest(dataOutputStream, modInfo.website, true);
130131
dataOutputStream.writeBoolean(modInfo.unofficial);
131132
dataOutputStream.writeLong(modInfo.loadOrderPriority);
132133
} else if (fileInfo instanceof DependencyFileInfo) {

0 commit comments

Comments
 (0)