Rewrite main menu button offset to be more compatible (closes #341)
In particular, we now position it relative to the realms (fallback to multiplayer) button. This removes the need for special-casing ModMenu and fixes compatibility with Better Mod Button.
This commit is contained in:
@@ -5,7 +5,6 @@ import com.replaymod.compat.ReplayModCompat;
|
|||||||
import com.replaymod.core.gui.GuiBackgroundProcesses;
|
import com.replaymod.core.gui.GuiBackgroundProcesses;
|
||||||
import com.replaymod.core.gui.GuiReplaySettings;
|
import com.replaymod.core.gui.GuiReplaySettings;
|
||||||
import com.replaymod.core.gui.RestoreReplayGui;
|
import com.replaymod.core.gui.RestoreReplayGui;
|
||||||
import com.replaymod.core.handler.MainMenuHandler;
|
|
||||||
import com.replaymod.core.mixin.MinecraftAccessor;
|
import com.replaymod.core.mixin.MinecraftAccessor;
|
||||||
import com.replaymod.core.versions.MCVer;
|
import com.replaymod.core.versions.MCVer;
|
||||||
import com.replaymod.editor.ReplayModEditor;
|
import com.replaymod.editor.ReplayModEditor;
|
||||||
@@ -324,8 +323,6 @@ public class ReplayMod implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initClient() {
|
public void initClient() {
|
||||||
new MainMenuHandler().register();
|
|
||||||
|
|
||||||
//#if MC<=10710
|
//#if MC<=10710
|
||||||
//$$ FML_BUS.register(this); // For runLater(Runnable)
|
//$$ FML_BUS.register(this); // For runLater(Runnable)
|
||||||
//#endif
|
//#endif
|
||||||
|
|||||||
@@ -1,124 +0,0 @@
|
|||||||
package com.replaymod.core.handler;
|
|
||||||
|
|
||||||
import com.replaymod.core.mixin.GuiMainMenuAccessor;
|
|
||||||
import de.johni0702.minecraft.gui.utils.EventRegistrations;
|
|
||||||
import net.minecraft.client.MinecraftClient;
|
|
||||||
import net.minecraft.client.gui.screen.TitleScreen;
|
|
||||||
import net.minecraft.client.gui.screen.Screen;
|
|
||||||
import org.lwjgl.opengl.GL11;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static com.replaymod.core.versions.MCVer.*;
|
|
||||||
|
|
||||||
//#if MC>=11400 && MC<11600
|
|
||||||
//$$ import net.minecraft.realms.RealmsScreenProxy;
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
//#if FABRIC>=1
|
|
||||||
import de.johni0702.minecraft.gui.versions.callbacks.InitScreenCallback;
|
|
||||||
//#else
|
|
||||||
//$$ import net.minecraftforge.client.event.GuiScreenEvent;
|
|
||||||
//$$ import net.minecraftforge.common.MinecraftForge;
|
|
||||||
//$$ import net.minecraftforge.eventbus.api.SubscribeEvent;
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
//#if MC>=11400
|
|
||||||
import net.minecraft.client.gui.widget.AbstractButtonWidget;
|
|
||||||
import net.minecraft.client.resource.language.I18n;
|
|
||||||
//#else
|
|
||||||
//$$ import net.minecraft.client.gui.GuiButton;
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Moves certain buttons on the main menu upwards so we can inject our own.
|
|
||||||
*/
|
|
||||||
public class MainMenuHandler extends EventRegistrations {
|
|
||||||
//#if FABRIC>=1
|
|
||||||
{ on(InitScreenCallback.EVENT, this::onInit); }
|
|
||||||
public void onInit(Screen guiScreen, List<AbstractButtonWidget> buttonList) {
|
|
||||||
//#else
|
|
||||||
//$$ @SubscribeEvent
|
|
||||||
//$$ public void onInit(GuiScreenEvent.InitGuiEvent.Post event) {
|
|
||||||
//$$ Screen guiScreen = getGui(event);
|
|
||||||
//$$ List<Widget> buttonList = getButtonList(event);
|
|
||||||
//#endif
|
|
||||||
if (guiScreen instanceof TitleScreen) {
|
|
||||||
TitleScreen gui = (TitleScreen) guiScreen;
|
|
||||||
int realmsOffset = 0;
|
|
||||||
//#if MC>=11400
|
|
||||||
final String BUTTON_REALMS = I18n.translate("menu.online");
|
|
||||||
for (AbstractButtonWidget button : buttonList) {
|
|
||||||
//#else
|
|
||||||
//$$ for (GuiButton button : buttonList) {
|
|
||||||
//#endif
|
|
||||||
// Buttons that aren't in a rectangle directly above our space don't need moving
|
|
||||||
if (button.x + width(button) < gui.width / 2 - 100
|
|
||||||
|| button.x > gui.width / 2 + 100
|
|
||||||
|| button.y > gui.height / 4 + 10 + 4 * 24 + 20) continue;
|
|
||||||
// Move button up to make space for one rows of buttons
|
|
||||||
// and then move back down by 10 to compensate for the space to the exit button that was already there
|
|
||||||
int offset = -1 * 24 + 10;
|
|
||||||
button.y += offset;
|
|
||||||
|
|
||||||
//#if MC>=11400
|
|
||||||
//#if MC>=11400
|
|
||||||
if (BUTTON_REALMS.equals(button.getMessage())) {
|
|
||||||
//#else
|
|
||||||
//$$ if (button.id == 14) {
|
|
||||||
//#endif
|
|
||||||
realmsOffset = offset;
|
|
||||||
}
|
|
||||||
//#endif
|
|
||||||
}
|
|
||||||
//#if MC>=11400 && MC<11600
|
|
||||||
//$$ GuiMainMenuAccessor guiA = (GuiMainMenuAccessor) gui;
|
|
||||||
//$$ if (realmsOffset != 0 && guiA.getRealmsNotification() instanceof RealmsScreenProxy) {
|
|
||||||
//$$ guiA.setRealmsNotification(new RealmsNotificationProxy((RealmsScreenProxy) guiA.getRealmsNotification(), realmsOffset));
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//#if MC>=11400 && MC<11600
|
|
||||||
//$$ private static class RealmsNotificationProxy extends Screen {
|
|
||||||
//$$ private final RealmsScreenProxy proxy;
|
|
||||||
//$$ private final int offset;
|
|
||||||
//$$
|
|
||||||
//$$ private RealmsNotificationProxy(RealmsScreenProxy proxy, int offset) {
|
|
||||||
//#if MC>=11400
|
|
||||||
//$$ super(null);
|
|
||||||
//#endif
|
|
||||||
//$$ this.proxy = proxy;
|
|
||||||
//$$ this.offset = offset;
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ @Override
|
|
||||||
//$$ public void init(MinecraftClient mc, int width, int height) {
|
|
||||||
//$$ proxy.init(mc, width, height);
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ @Override
|
|
||||||
//$$ public void tick() {
|
|
||||||
//$$ proxy.tick();
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ @Override
|
|
||||||
//$$ public void render(int mouseX, int mouseY, float partialTicks) {
|
|
||||||
//$$ GL11.glTranslated(0, offset, 0);
|
|
||||||
//$$ proxy.render(mouseX, mouseY - offset, partialTicks);
|
|
||||||
//$$ GL11.glTranslated(0, -offset, 0);
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ @Override
|
|
||||||
//$$ public boolean mouseClicked(double mouseX, double mouseY, int mouseButton) {
|
|
||||||
//$$ return proxy.mouseClicked(mouseX, mouseY - offset, mouseButton);
|
|
||||||
//$$ }
|
|
||||||
//$$
|
|
||||||
//$$ @Override
|
|
||||||
//$$ public void removed() {
|
|
||||||
//$$ proxy.removed();
|
|
||||||
//$$ }
|
|
||||||
//$$ }
|
|
||||||
//#endif
|
|
||||||
}
|
|
||||||
@@ -38,7 +38,6 @@ import java.util.ArrayList;
|
|||||||
//#if MC>=11400
|
//#if MC>=11400
|
||||||
import com.replaymod.core.mixin.AbstractButtonWidgetAccessor;
|
import com.replaymod.core.mixin.AbstractButtonWidgetAccessor;
|
||||||
import net.minecraft.SharedConstants;
|
import net.minecraft.SharedConstants;
|
||||||
import net.minecraft.client.gui.screen.TitleScreen;
|
|
||||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||||
import net.minecraft.client.gui.widget.AbstractButtonWidget;
|
import net.minecraft.client.gui.widget.AbstractButtonWidget;
|
||||||
|
|
||||||
@@ -598,13 +597,6 @@ public class MCVer {
|
|||||||
//#endif
|
//#endif
|
||||||
) {
|
) {
|
||||||
GuiScreenAccessor acc = (GuiScreenAccessor) screen;
|
GuiScreenAccessor acc = (GuiScreenAccessor) screen;
|
||||||
//#if MC>=11400
|
|
||||||
if (screen instanceof TitleScreen && isModLoaded("modmenu")) {
|
|
||||||
// Since we bypass the usual addButton, we need to manually move our buttons down
|
|
||||||
// https://github.com/Prospector/ModMenu/blob/eea70ec37581a7229142cf21df795fdacc6a7b4c/src/main/java/io/github/prospector/modmenu/mixin/TitleScreenMixin.java#L42
|
|
||||||
button.y += 12;
|
|
||||||
}
|
|
||||||
//#endif
|
|
||||||
acc.getButtons().add(button);
|
acc.getButtons().add(button);
|
||||||
//#if MC>=11400
|
//#if MC>=11400
|
||||||
acc.getChildren().add(button);
|
acc.getChildren().add(button);
|
||||||
|
|||||||
@@ -8,11 +8,12 @@ import net.minecraft.client.gui.screen.TitleScreen;
|
|||||||
import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen;
|
import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen;
|
||||||
import net.minecraft.client.gui.screen.Screen;
|
import net.minecraft.client.gui.screen.Screen;
|
||||||
import net.minecraft.client.gui.widget.AbstractButtonWidget;
|
import net.minecraft.client.gui.widget.AbstractButtonWidget;
|
||||||
import net.minecraft.client.resource.language.I18n;
|
|
||||||
|
|
||||||
//#if MC>=11600
|
//#if MC>=11600
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
import net.minecraft.text.TranslatableText;
|
import net.minecraft.text.TranslatableText;
|
||||||
|
//#else
|
||||||
|
//$$ import net.minecraft.client.resource.language.I18n;
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
//#if FABRIC>=1
|
//#if FABRIC>=1
|
||||||
@@ -29,6 +30,7 @@ import net.minecraft.client.gui.widget.ButtonWidget;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import static com.replaymod.core.versions.MCVer.*;
|
import static com.replaymod.core.versions.MCVer.*;
|
||||||
@@ -152,40 +154,48 @@ public class GuiHandler extends EventRegistrations {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (achievements != null && stats != null) {
|
if (achievements != null && stats != null) {
|
||||||
moveAllButtonsDirectlyBelowUpwards(buttonList, achievements.y,
|
moveAllButtonsInRect(buttonList,
|
||||||
achievements.x, stats.x + width(stats));
|
achievements.x, stats.x + width(stats),
|
||||||
|
achievements.y, Integer.MAX_VALUE,
|
||||||
|
-24);
|
||||||
}
|
}
|
||||||
// In 1.13+ Forge, the Options button shares one row with the Open to LAN button
|
// In 1.13+ Forge, the Options button shares one row with the Open to LAN button
|
||||||
//#if MC<11400
|
//#if MC<11400
|
||||||
//$$ if (openToLan != null) {
|
//$$ if (openToLan != null) {
|
||||||
//$$ moveAllButtonsDirectlyBelowUpwards(buttonList, openToLan.y,
|
//$$ moveAllButtonsInRect(buttonList,
|
||||||
//$$ openToLan.x, openToLan.x + openToLan.width);
|
//$$ openToLan.x, openToLan.x + openToLan.width,
|
||||||
|
//$$ openToLan.y, Integer.MAX_VALUE,
|
||||||
|
//$$ -24);
|
||||||
//$$ }
|
//$$ }
|
||||||
//#endif
|
//#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Moves all buttons that are within a rectangle below a certain y coordinate upwards by 24 units.
|
* Moves all buttons that in any way intersect a rectangle by a given amount on the y axis.
|
||||||
* @param buttons List of buttons
|
* @param buttons List of buttons
|
||||||
* @param belowY The Y limit
|
* @param yStart Top y limit of the rectangle
|
||||||
|
* @param yEnd Bottom y limit of the rectangle
|
||||||
* @param xStart Left x limit of the rectangle
|
* @param xStart Left x limit of the rectangle
|
||||||
* @param xEnd Right x limit of the rectangle
|
* @param xEnd Right x limit of the rectangle
|
||||||
|
* @param moveBy Signed distance to move the buttons
|
||||||
*/
|
*/
|
||||||
private void moveAllButtonsDirectlyBelowUpwards(
|
private void moveAllButtonsInRect(
|
||||||
//#if MC>=11400
|
//#if MC>=11400
|
||||||
List<AbstractButtonWidget> buttons,
|
List<AbstractButtonWidget> buttons,
|
||||||
//#else
|
//#else
|
||||||
//$$ List<GuiButton> buttons,
|
//$$ List<GuiButton> buttons,
|
||||||
//#endif
|
//#endif
|
||||||
int belowY,
|
|
||||||
int xStart,
|
int xStart,
|
||||||
int xEnd
|
int xEnd,
|
||||||
|
int yStart,
|
||||||
|
int yEnd,
|
||||||
|
int moveBy
|
||||||
) {
|
) {
|
||||||
buttons.stream()
|
buttons.stream()
|
||||||
.filter(button -> button.y >= belowY)
|
|
||||||
.filter(button -> button.x <= xEnd && button.x + width(button) >= xStart)
|
.filter(button -> button.x <= xEnd && button.x + width(button) >= xStart)
|
||||||
.forEach(button -> button.y -= 24);
|
.filter(button -> button.y <= yEnd && button.y + height(button) >= yStart)
|
||||||
|
.forEach(button -> button.y += moveBy);
|
||||||
}
|
}
|
||||||
|
|
||||||
//#if FABRIC>=1
|
//#if FABRIC>=1
|
||||||
@@ -222,15 +232,35 @@ public class GuiHandler extends EventRegistrations {
|
|||||||
//$$ @SubscribeEvent
|
//$$ @SubscribeEvent
|
||||||
//$$ public void injectIntoMainMenu(GuiScreenEvent.InitGuiEvent event) {
|
//$$ public void injectIntoMainMenu(GuiScreenEvent.InitGuiEvent event) {
|
||||||
//$$ Screen guiScreen = getGui(event);
|
//$$ Screen guiScreen = getGui(event);
|
||||||
|
//$$ List<Widget> buttonList = getButtonList(event);
|
||||||
//#endif
|
//#endif
|
||||||
if (!(guiScreen instanceof TitleScreen)) {
|
if (!(guiScreen instanceof TitleScreen)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int x = guiScreen.width / 2 - 100;
|
||||||
|
// We want to position our button below the realms button
|
||||||
|
int y = findButton(buttonList, "menu.online", 14)
|
||||||
|
.map(Optional::of)
|
||||||
|
// or, if someone removed the realms button, we'll alternatively take the multiplayer one
|
||||||
|
.orElse(findButton(buttonList, "menu.multiplayer", 2))
|
||||||
|
// if we found some button, put our button at its position (we'll move it out of the way shortly)
|
||||||
|
.map(it -> it.y)
|
||||||
|
// and if we can't even find that one, then just guess
|
||||||
|
.orElse(guiScreen.height / 4 + 10 + 4 * 24);
|
||||||
|
|
||||||
|
// Move all buttons above or at our one upwards
|
||||||
|
moveAllButtonsInRect(buttonList,
|
||||||
|
x, x + 200,
|
||||||
|
Integer.MIN_VALUE, y,
|
||||||
|
-24);
|
||||||
|
|
||||||
|
// Add our button
|
||||||
InjectedButton button = new InjectedButton(
|
InjectedButton button = new InjectedButton(
|
||||||
guiScreen,
|
guiScreen,
|
||||||
BUTTON_REPLAY_VIEWER,
|
BUTTON_REPLAY_VIEWER,
|
||||||
guiScreen.width / 2 - 100,
|
x,
|
||||||
guiScreen.height / 4 + 10 + 4 * 24,
|
y,
|
||||||
200,
|
200,
|
||||||
20,
|
20,
|
||||||
"replaymod.gui.replayviewer",
|
"replaymod.gui.replayviewer",
|
||||||
|
|||||||
Reference in New Issue
Block a user