workaround for java 8 and forgix
Java 8 doesn't support "_" in the class name after "$". In other words inner classes can't have underscores in their names, which forgix adds for changed classes. Moving the DhConfigScreen/ClassicConfigGUI into separate classes mitigates the problem until forgix has a long-term fix.
This commit is contained in:
+1
-1
@@ -25,7 +25,7 @@ import com.seibel.distanthorizons.common.render.blaze.BlazeDhRenderApiDefinition
|
||||
import com.seibel.distanthorizons.common.render.openGl.GlDhRenderApiDefinition;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.render.renderer.GenericRenderObjectFactory;
|
||||
import com.seibel.distanthorizons.common.wrappers.gui.ClassicConfigGUI;
|
||||
import com.seibel.distanthorizons.common.wrappers.gui.classicConfig.ClassicConfigGUI;
|
||||
import com.seibel.distanthorizons.common.wrappers.gui.LangWrapper;
|
||||
import com.seibel.distanthorizons.common.wrappers.level.KeyedClientLevelManager;
|
||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftServerWrapper;
|
||||
|
||||
-1125
File diff suppressed because it is too large
Load Diff
+1
@@ -1,5 +1,6 @@
|
||||
package com.seibel.distanthorizons.common.wrappers.gui;
|
||||
|
||||
import com.seibel.distanthorizons.common.wrappers.gui.classicConfig.ClassicConfigGUI;
|
||||
import com.seibel.distanthorizons.core.config.ConfigHandler;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||
|
||||
+384
@@ -0,0 +1,384 @@
|
||||
package com.seibel.distanthorizons.common.wrappers.gui.classicConfig;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.seibel.distanthorizons.core.config.types.*;
|
||||
|
||||
import com.seibel.distanthorizons.core.config.types.enums.EConfigCommentTextPosition;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.config.IConfigGui;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.gui.components.AbstractWidget;
|
||||
import net.minecraft.client.gui.components.ContainerObjectSelectionList;
|
||||
import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
#if MC_VER < MC_1_20_1
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.gui.GuiComponent;
|
||||
#elif MC_VER <= MC_1_21_11
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
#else
|
||||
import net.minecraft.client.gui.GuiGraphicsExtractor;
|
||||
#endif
|
||||
|
||||
#if MC_VER >= MC_1_17_1
|
||||
import net.minecraft.client.gui.narration.NarratableEntry;
|
||||
#endif
|
||||
|
||||
#if MC_VER <= MC_1_21_10
|
||||
#else
|
||||
import net.minecraft.resources.Identifier;
|
||||
#endif
|
||||
|
||||
import static com.seibel.distanthorizons.common.wrappers.gui.GuiHelper.*;
|
||||
|
||||
|
||||
/*
|
||||
* Based upon TinyConfig but is highly modified
|
||||
* https://github.com/Minenash/TinyConfig
|
||||
*
|
||||
* @author coolGi
|
||||
* @author Motschen
|
||||
* @author James Seibel
|
||||
* @version 5-21-2022
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public class ClassicConfigGUI
|
||||
{
|
||||
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||
public static final DhLogger RATE_LIMITED_LOGGER = new DhLoggerBuilder()
|
||||
.maxCountPerSecond(1)
|
||||
.build();
|
||||
|
||||
public static final ConfigCoreInterface CONFIG_CORE_INTERFACE = new ConfigCoreInterface();
|
||||
|
||||
|
||||
|
||||
//==============//
|
||||
// Initializers //
|
||||
//==============//
|
||||
|
||||
// Some regexes to check if an input is valid
|
||||
public static final Pattern INTEGER_ONLY_REGEX = Pattern.compile("(-?[0-9]*)");
|
||||
public static final Pattern DECIMAL_ONLY_REGEX = Pattern.compile("-?([\\d]+\\.?[\\d]*|[\\d]*\\.?[\\d]+|\\.)");
|
||||
|
||||
public static class ConfigScreenConfigs
|
||||
{
|
||||
// This contains all the configs for the configs
|
||||
public static final int SPACE_FROM_RIGHT_SCREEN = 10;
|
||||
public static final int SPACE_BETWEEN_TEXT_AND_OPTION_FIELD = 8;
|
||||
public static final int BUTTON_WIDTH_SPACING = 5;
|
||||
public static final int RESET_BUTTON_WIDTH = 60;
|
||||
public static final int RESET_BUTTON_HEIGHT = 20;
|
||||
public static final int OPTION_FIELD_WIDTH = 150;
|
||||
public static final int OPTION_FIELD_HEIGHT = 20;
|
||||
public static final int CATEGORY_BUTTON_WIDTH = 200;
|
||||
public static final int CATEGORY_BUTTON_HEIGHT = 20;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==============//
|
||||
// GUI handling //
|
||||
//==============//
|
||||
|
||||
/** if you want to get this config gui's screen call this */
|
||||
public static Screen getScreen(Screen parent, String category)
|
||||
{ return new DhConfigScreen(parent, category); }
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
// helper classes //
|
||||
//================//
|
||||
|
||||
public static class ConfigListWidget extends ContainerObjectSelectionList<DhButtonEntry>
|
||||
{
|
||||
Font textRenderer;
|
||||
|
||||
public ConfigListWidget(Minecraft minecraftClient, int canvasWidth, int canvasHeight, int topMargin, int botMargin, int itemSpacing)
|
||||
{
|
||||
#if MC_VER < MC_1_20_4
|
||||
super(minecraftClient, canvasWidth, canvasHeight, topMargin, canvasHeight - botMargin, itemSpacing);
|
||||
#else
|
||||
super(minecraftClient, canvasWidth, canvasHeight - (topMargin + botMargin), topMargin, itemSpacing);
|
||||
#endif
|
||||
|
||||
this.centerListVertically = false;
|
||||
this.textRenderer = minecraftClient.font;
|
||||
}
|
||||
|
||||
public void addButton(DhConfigScreen gui, AbstractConfigBase dhConfigType, AbstractWidget button, AbstractWidget resetButton, AbstractWidget indexButton, Component text)
|
||||
{ this.addEntry(new DhButtonEntry(gui, dhConfigType, button, text, resetButton, indexButton)); }
|
||||
|
||||
@Override
|
||||
public int getRowWidth() { return 10_000; }
|
||||
|
||||
public AbstractWidget getHoveredButton(double mouseX, double mouseY)
|
||||
{
|
||||
for (DhButtonEntry buttonEntry : this.children())
|
||||
{
|
||||
AbstractWidget button = buttonEntry.button;
|
||||
if (button != null
|
||||
&& button.visible)
|
||||
{
|
||||
#if MC_VER < MC_1_19_4
|
||||
double minX = button.x;
|
||||
double minY = button.y;
|
||||
#else
|
||||
double minX = button.getX();
|
||||
double minY = button.getY();
|
||||
#endif
|
||||
|
||||
double maxX = minX + button.getWidth();
|
||||
double maxY = minY + button.getHeight();
|
||||
|
||||
if (mouseX >= minX && mouseX < maxX
|
||||
&& mouseY >= minY && mouseY < maxY)
|
||||
{
|
||||
return button;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static class DhButtonEntry extends ContainerObjectSelectionList.Entry<DhButtonEntry>
|
||||
{
|
||||
private static final Font textRenderer = Minecraft.getInstance().font;
|
||||
|
||||
private final AbstractWidget button;
|
||||
|
||||
private final DhConfigScreen gui;
|
||||
|
||||
private final AbstractWidget resetButton;
|
||||
private final AbstractWidget indexButton;
|
||||
private final Component text;
|
||||
private final List<AbstractWidget> children = new ArrayList<>();
|
||||
|
||||
@NotNull
|
||||
private final EConfigCommentTextPosition textPosition;
|
||||
public final AbstractConfigBase dhConfigType;
|
||||
|
||||
public static final Map<AbstractWidget, Component> TEXT_BY_WIDGET = new HashMap<>();
|
||||
public static final Map<AbstractWidget, DhButtonEntry> BUTTON_BY_WIDGET = new HashMap<>();
|
||||
|
||||
|
||||
|
||||
public DhButtonEntry(
|
||||
DhConfigScreen gui, AbstractConfigBase dhConfigType,
|
||||
AbstractWidget button, Component text, AbstractWidget resetButton, AbstractWidget indexButton)
|
||||
{
|
||||
TEXT_BY_WIDGET.put(button, text);
|
||||
BUTTON_BY_WIDGET.put(button, this);
|
||||
|
||||
this.gui = gui;
|
||||
this.dhConfigType = dhConfigType;
|
||||
|
||||
this.button = button;
|
||||
this.resetButton = resetButton;
|
||||
this.text = text;
|
||||
this.indexButton = indexButton;
|
||||
|
||||
if (button != null) { this.children.add(button); }
|
||||
if (resetButton != null) { this.children.add(resetButton); }
|
||||
if (indexButton != null) { this.children.add(indexButton); }
|
||||
|
||||
|
||||
EConfigCommentTextPosition textPosition = null;
|
||||
if (this.dhConfigType instanceof ConfigUIComment)
|
||||
{
|
||||
textPosition = ((ConfigUIComment)this.dhConfigType).textPosition;
|
||||
}
|
||||
|
||||
if (textPosition == null)
|
||||
{
|
||||
if (this.button != null)
|
||||
{
|
||||
// if a button is present
|
||||
textPosition = EConfigCommentTextPosition.RIGHT_JUSTIFIED;
|
||||
}
|
||||
else
|
||||
{
|
||||
textPosition = EConfigCommentTextPosition.CENTERED_OVER_BUTTONS;
|
||||
}
|
||||
}
|
||||
this.textPosition = textPosition;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
#if MC_VER < MC_1_20_1
|
||||
public void render(PoseStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta)
|
||||
#elif MC_VER < MC_1_21_9
|
||||
public void render(GuiGraphics matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta)
|
||||
#elif MC_VER <= MC_1_21_11
|
||||
public void renderContent(GuiGraphics matrices, int mouseX, int mouseY, boolean hovered, float tickDelta)
|
||||
#else
|
||||
public void extractContent(GuiGraphicsExtractor matrices, int mouseX, int mouseY, boolean hovered, float tickDelta)
|
||||
#endif
|
||||
{
|
||||
try
|
||||
{
|
||||
// setting the "y" variable is necessary so each child item
|
||||
// renders at the correct height,
|
||||
// if not set they will render off-screen.
|
||||
#if MC_VER < MC_1_21_9
|
||||
// Y value passed in from method args
|
||||
#else
|
||||
int y = this.getY();
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
if (this.button != null)
|
||||
{
|
||||
SetY(this.button, y);
|
||||
#if MC_VER <= MC_1_21_11
|
||||
this.button.render(matrices, mouseX, mouseY, tickDelta);
|
||||
#else
|
||||
this.button.extractRenderState(matrices, mouseX, mouseY, tickDelta);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (this.resetButton != null)
|
||||
{
|
||||
SetY(this.resetButton, y);
|
||||
#if MC_VER <= MC_1_21_11
|
||||
this.resetButton.render(matrices, mouseX, mouseY, tickDelta);
|
||||
#else
|
||||
this.resetButton.extractRenderState(matrices, mouseX, mouseY, tickDelta);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (this.indexButton != null)
|
||||
{
|
||||
SetY(this.indexButton, y);
|
||||
#if MC_VER <= MC_1_21_11
|
||||
this.indexButton.render(matrices, mouseX, mouseY, tickDelta);
|
||||
#else
|
||||
this.indexButton.extractRenderState(matrices, mouseX, mouseY, tickDelta);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (this.text != null)
|
||||
{
|
||||
int translatedLength = textRenderer.width(this.text);
|
||||
|
||||
int textXPos;
|
||||
if (this.textPosition == EConfigCommentTextPosition.RIGHT_JUSTIFIED)
|
||||
{
|
||||
// text right justified aligned against the buttons
|
||||
textXPos = this.gui.width
|
||||
- translatedLength
|
||||
- ConfigScreenConfigs.SPACE_BETWEEN_TEXT_AND_OPTION_FIELD
|
||||
- ConfigScreenConfigs.SPACE_FROM_RIGHT_SCREEN
|
||||
- ConfigScreenConfigs.OPTION_FIELD_WIDTH
|
||||
- ConfigScreenConfigs.BUTTON_WIDTH_SPACING
|
||||
- ConfigScreenConfigs.RESET_BUTTON_WIDTH;
|
||||
}
|
||||
else if (this.textPosition == EConfigCommentTextPosition.CENTERED_OVER_BUTTONS)
|
||||
{
|
||||
// have button centered relative to a category button
|
||||
textXPos = this.gui.width
|
||||
- (translatedLength / 2)
|
||||
- (ConfigScreenConfigs.CATEGORY_BUTTON_WIDTH / 2)
|
||||
- ConfigScreenConfigs.SPACE_FROM_RIGHT_SCREEN;
|
||||
}
|
||||
else if (this.textPosition == EConfigCommentTextPosition.CENTER_OF_SCREEN)
|
||||
{
|
||||
// have button centered in the screen
|
||||
textXPos = (this.gui.width / 2)
|
||||
- (translatedLength / 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new UnsupportedOperationException("No text position render defined for [" + this.textPosition + "]");
|
||||
}
|
||||
|
||||
|
||||
#if MC_VER < MC_1_20_1
|
||||
GuiComponent.drawString(matrices, textRenderer,
|
||||
this.text,
|
||||
textXPos, y + 5,
|
||||
0xFFFFFF);
|
||||
#elif MC_VER < MC_1_21_6
|
||||
matrices.drawString(textRenderer,
|
||||
this.text,
|
||||
textXPos, y + 5,
|
||||
0xFFFFFF);
|
||||
#elif MC_VER <= MC_1_21_11
|
||||
matrices.drawString(textRenderer,
|
||||
this.text,
|
||||
textXPos, y + 5,
|
||||
0xFFFFFFFF);
|
||||
#else
|
||||
matrices.text(textRenderer,
|
||||
this.text,
|
||||
textXPos, y + 5,
|
||||
0xFFFFFFFF);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// should prevent crashing the game if there's an issue
|
||||
RATE_LIMITED_LOGGER.error("Unexpected gui rendering issue: ["+e.getMessage()+"]", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<? extends GuiEventListener> children()
|
||||
{ return this.children; }
|
||||
|
||||
#if MC_VER >= MC_1_17_1
|
||||
@Override
|
||||
public @NotNull List<? extends NarratableEntry> narratables()
|
||||
{ return this.children; }
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
// event handling //
|
||||
//================//
|
||||
|
||||
public static class ConfigCoreInterface implements IConfigGui
|
||||
{
|
||||
/**
|
||||
* in the future it would be good to pass in the current page and other variables,
|
||||
* but for now just knowing when the page is closed is good enough
|
||||
*/
|
||||
public final ArrayList<Runnable> onScreenChangeListenerList = new ArrayList<>();
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void addOnScreenChangeListener(Runnable newListener) { this.onScreenChangeListenerList.add(newListener); }
|
||||
@Override
|
||||
public void removeOnScreenChangeListener(Runnable oldListener) { this.onScreenChangeListenerList.remove(oldListener); }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+799
@@ -0,0 +1,799 @@
|
||||
package com.seibel.distanthorizons.common.wrappers.gui.classicConfig;
|
||||
|
||||
import java.util.AbstractMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.seibel.distanthorizons.api.enums.config.DisallowSelectingViaConfigGui;
|
||||
import com.seibel.distanthorizons.common.wrappers.gui.DhScreen;
|
||||
import com.seibel.distanthorizons.common.wrappers.gui.TexturedButtonWidget;
|
||||
import com.seibel.distanthorizons.common.wrappers.gui.config.ConfigGuiInfo;
|
||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftClientWrapper;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.config.ConfigHandler;
|
||||
import com.seibel.distanthorizons.core.config.types.*;
|
||||
import com.seibel.distanthorizons.common.wrappers.gui.updater.ChangelogScreen;
|
||||
|
||||
import com.seibel.distanthorizons.core.config.types.enums.EConfigCommentTextPosition;
|
||||
import com.seibel.distanthorizons.core.config.types.enums.EConfigValidity;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.jar.updater.SelfUpdater;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.util.AnnotationUtil;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.config.IConfigGui;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.config.ILangWrapper;
|
||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.gui.components.AbstractWidget;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.components.ContainerObjectSelectionList;
|
||||
import net.minecraft.client.gui.components.EditBox;
|
||||
import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
|
||||
#if MC_VER < MC_1_20_1
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.gui.GuiComponent;
|
||||
#elif MC_VER <= MC_1_21_11
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
#else
|
||||
import net.minecraft.client.gui.GuiGraphicsExtractor;
|
||||
#endif
|
||||
|
||||
#if MC_VER >= MC_1_17_1
|
||||
import net.minecraft.client.gui.narration.NarratableEntry;
|
||||
#endif
|
||||
|
||||
#if MC_VER <= MC_1_21_10
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
#else
|
||||
import net.minecraft.resources.Identifier;
|
||||
#endif
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import com.mojang.blaze3d.platform.InputConstants;
|
||||
|
||||
import static com.seibel.distanthorizons.common.wrappers.gui.GuiHelper.*;
|
||||
import static com.seibel.distanthorizons.common.wrappers.gui.GuiHelper.Translatable;
|
||||
|
||||
class DhConfigScreen extends DhScreen
|
||||
{
|
||||
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||
private static final ILangWrapper LANG_WRAPPER = SingletonInjector.INSTANCE.get(ILangWrapper.class);
|
||||
|
||||
private static final String TRANSLATION_PREFIX = ModInfo.ID + ".config.";
|
||||
|
||||
private static final MinecraftClientWrapper MC_CLIENT = MinecraftClientWrapper.INSTANCE;
|
||||
|
||||
|
||||
private final Screen parent;
|
||||
private final String category;
|
||||
private ClassicConfigGUI.ConfigListWidget configListWidget;
|
||||
private boolean reload = false;
|
||||
|
||||
private Button doneButton;
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
|
||||
protected DhConfigScreen(Screen parent, String category)
|
||||
{
|
||||
super(Translatable(
|
||||
LANG_WRAPPER.langExists(ModInfo.ID + ".config" + (category.isEmpty() ? "." + category : "") + ".title") ?
|
||||
ModInfo.ID + ".config.title" :
|
||||
ModInfo.ID + ".config" + (category.isEmpty() ? "" : "." + category) + ".title")
|
||||
);
|
||||
this.parent = parent;
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void tick() { super.tick(); }
|
||||
|
||||
|
||||
|
||||
//==================//
|
||||
// menu UI creation //
|
||||
//==================//
|
||||
|
||||
@Override
|
||||
protected void init()
|
||||
{
|
||||
super.init();
|
||||
if (!this.reload)
|
||||
{
|
||||
ConfigHandler.INSTANCE.configFileHandler.loadFromFile();
|
||||
}
|
||||
|
||||
// Changelog button
|
||||
if (Config.Client.Advanced.AutoUpdater.enableAutoUpdater.get()
|
||||
// we only have changelogs for stable builds
|
||||
&& !ModInfo.IS_DEV_BUILD)
|
||||
{
|
||||
this.addBtn(new TexturedButtonWidget(
|
||||
// Where the button is on the screen
|
||||
this.width - 28, this.height - 28,
|
||||
// Width and height of the button
|
||||
20, 20,
|
||||
// texture UV Offset
|
||||
0, 0,
|
||||
// Some texture stuff
|
||||
0,
|
||||
#if MC_VER < MC_1_21_1
|
||||
new ResourceLocation(ModInfo.ID, "textures/gui/changelog.png"),
|
||||
#elif MC_VER <= MC_1_21_10
|
||||
ResourceLocation.fromNamespaceAndPath(ModInfo.ID, "textures/gui/changelog.png"),
|
||||
#else
|
||||
Identifier.fromNamespaceAndPath(ModInfo.ID, "textures/gui/changelog.png"),
|
||||
#endif
|
||||
20, 20,
|
||||
// Create the button and tell it where to go
|
||||
(buttonWidget) -> {
|
||||
ChangelogScreen changelogScreen = new ChangelogScreen(this);
|
||||
if (changelogScreen.usable)
|
||||
{
|
||||
Objects.requireNonNull(this.minecraft).setScreen(changelogScreen);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGGER.warn("Changelog was not able to open");
|
||||
}
|
||||
},
|
||||
// Add a title to the button
|
||||
Translatable(ModInfo.ID + ".updater.title")
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
// back button
|
||||
this.addBtn(MakeBtn(Translatable("distanthorizons.general.back"),
|
||||
(this.width / 2) - 154, this.height - 28,
|
||||
ClassicConfigGUI.ConfigScreenConfigs.OPTION_FIELD_WIDTH, ClassicConfigGUI.ConfigScreenConfigs.OPTION_FIELD_HEIGHT,
|
||||
(button) ->
|
||||
{
|
||||
ConfigHandler.INSTANCE.configFileHandler.loadFromFile();
|
||||
Objects.requireNonNull(this.minecraft).setScreen(this.parent);
|
||||
}));
|
||||
|
||||
// done/close button
|
||||
this.doneButton = this.addBtn(
|
||||
MakeBtn(Translatable("distanthorizons.general.done"),
|
||||
(this.width / 2) + 4, this.height - 28,
|
||||
ClassicConfigGUI.ConfigScreenConfigs.OPTION_FIELD_WIDTH, ClassicConfigGUI.ConfigScreenConfigs.OPTION_FIELD_HEIGHT,
|
||||
(button) ->
|
||||
{
|
||||
ConfigHandler.INSTANCE.configFileHandler.saveToFile();
|
||||
Objects.requireNonNull(this.minecraft).setScreen(this.parent);
|
||||
}));
|
||||
|
||||
this.configListWidget = new ClassicConfigGUI.ConfigListWidget(this.minecraft, this.width * 2, this.height, 32, 32, 25);
|
||||
|
||||
#if MC_VER < MC_1_20_6 // no background is rendered in MC 1.20.6+
|
||||
if (this.minecraft != null && this.minecraft.level != null)
|
||||
{
|
||||
this.configListWidget.setRenderBackground(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
this.addWidget(this.configListWidget);
|
||||
|
||||
for (AbstractConfigBase<?> configEntry : ConfigHandler.INSTANCE.configBaseList)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (configEntry.getCategory().matches(this.category)
|
||||
&& configEntry.getAppearance().showInGui)
|
||||
{
|
||||
this.addMenuItem(configEntry);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
String message = "ERROR: Failed to show [" + configEntry.getNameAndCategory() + "], error: [" + e.getMessage() + "]";
|
||||
if (configEntry.get() != null)
|
||||
{
|
||||
message += " with the value [" + configEntry.get() + "] with type [" + configEntry.getType() + "]";
|
||||
}
|
||||
|
||||
LOGGER.error(message, e);
|
||||
}
|
||||
}
|
||||
|
||||
ClassicConfigGUI.CONFIG_CORE_INTERFACE.onScreenChangeListenerList.forEach((listener) -> listener.run());
|
||||
}
|
||||
private void addMenuItem(AbstractConfigBase<?> configEntry)
|
||||
{
|
||||
trySetupConfigEntry(configEntry);
|
||||
|
||||
if (this.tryCreateInputField(configEntry)) return;
|
||||
if (this.tryCreateCategoryButton(configEntry)) return;
|
||||
if (this.tryCreateButton(configEntry)) return;
|
||||
if (this.tryCreateComment(configEntry)) return;
|
||||
if (this.tryCreateSpacer(configEntry)) return;
|
||||
if (this.tryCreateLinkedEntry(configEntry)) return;
|
||||
|
||||
LOGGER.warn("Config [" + configEntry.getNameAndCategory() + "] failed to show. Please try something like changing its type.");
|
||||
}
|
||||
|
||||
private static void trySetupConfigEntry(AbstractConfigBase<?> configMenuOption)
|
||||
{
|
||||
configMenuOption.guiValue = new ConfigGuiInfo();
|
||||
Class<?> configValueClass = configMenuOption.getType();
|
||||
|
||||
if (configMenuOption instanceof ConfigEntry)
|
||||
{
|
||||
ConfigEntry<?> configEntry = (ConfigEntry<?>) configMenuOption;
|
||||
|
||||
if (configValueClass == Integer.class)
|
||||
{
|
||||
setupTextMenuOption(configEntry, Integer::parseInt, ClassicConfigGUI.INTEGER_ONLY_REGEX, true);
|
||||
}
|
||||
else if (configValueClass == Double.class)
|
||||
{
|
||||
setupTextMenuOption(configEntry, Double::parseDouble, ClassicConfigGUI.DECIMAL_ONLY_REGEX, false);
|
||||
}
|
||||
else if (configValueClass == Float.class)
|
||||
{
|
||||
setupTextMenuOption(configEntry, Float::parseFloat, ClassicConfigGUI.DECIMAL_ONLY_REGEX, false);
|
||||
}
|
||||
else if (configValueClass == String.class || configValueClass == List.class)
|
||||
{
|
||||
// For string or list
|
||||
setupTextMenuOption(configEntry, String::length, null, true);
|
||||
}
|
||||
else if (configValueClass == Boolean.class)
|
||||
{
|
||||
ConfigEntry<Boolean> booleanConfigEntry = (ConfigEntry<Boolean>) configEntry;
|
||||
setupBooleanMenuOption(booleanConfigEntry);
|
||||
}
|
||||
else if (configValueClass.isEnum())
|
||||
{
|
||||
ConfigEntry<Enum<?>> enumConfigEntry = (ConfigEntry<Enum<?>>) configEntry;
|
||||
Class<? extends Enum<?>> configEnumClass = (Class<? extends Enum<?>>) configValueClass;
|
||||
setupEnumMenuOption(enumConfigEntry, configEnumClass);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGGER.error("No definition for config with type: [" + configValueClass.getName() + "], for config: [" + configMenuOption.name + "].");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
private static void setupTextMenuOption(AbstractConfigBase<?> configMenuOption, Function<String, Number> parsingFunc, @Nullable Pattern pattern, boolean cast)
|
||||
{
|
||||
final ConfigGuiInfo configGuiInfo = ((ConfigGuiInfo) configMenuOption.guiValue);
|
||||
|
||||
configGuiInfo.tooltipFunction =
|
||||
(editBox, button) ->
|
||||
(stringValue) ->
|
||||
{
|
||||
boolean isNumber = (pattern != null);
|
||||
|
||||
stringValue = stringValue.trim();
|
||||
if (!(stringValue.isEmpty() || !isNumber || pattern.matcher(stringValue).matches()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Number numberValue = configMenuOption.typeIsFloatingPointNumber() ? 0.0 : 0; // different default values are needed so implicit casting works correctly (if not done casting from 0 (an int) to a double will cause an exception)
|
||||
configGuiInfo.errorMessage = null;
|
||||
if (isNumber
|
||||
&& !stringValue.isEmpty()
|
||||
&& !stringValue.equals("-")
|
||||
&& !stringValue.equals("."))
|
||||
{
|
||||
ConfigEntry<Number> numberConfigEntry = (ConfigEntry<Number>) configMenuOption;
|
||||
|
||||
try
|
||||
{
|
||||
numberValue = parsingFunc.apply(stringValue);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
numberValue = null;
|
||||
}
|
||||
|
||||
EConfigValidity validity = numberConfigEntry.getValidity(numberValue);
|
||||
switch (validity)
|
||||
{
|
||||
case VALID:
|
||||
configGuiInfo.errorMessage = null;
|
||||
break;
|
||||
case NUMBER_TOO_LOW:
|
||||
configGuiInfo.errorMessage = TextOrTranslatable("§cMinimum length is " + numberConfigEntry.getMin());
|
||||
break;
|
||||
case NUMBER_TOO_HIGH:
|
||||
configGuiInfo.errorMessage = TextOrTranslatable("§cMaximum length is " + numberConfigEntry.getMax());
|
||||
break;
|
||||
case INVALID:
|
||||
configGuiInfo.errorMessage = TextOrTranslatable("§cValue is invalid");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
editBox.setTextColor(((ConfigEntry<Number>) configMenuOption).getValidity(numberValue) == EConfigValidity.VALID ? 0xFFFFFFFF : 0xFFFF7777); // white and red
|
||||
|
||||
|
||||
if (configMenuOption.getType() == String.class
|
||||
|| configMenuOption.getType() == List.class)
|
||||
{
|
||||
((ConfigEntry<String>) configMenuOption).uiSetWithoutSaving(stringValue);
|
||||
}
|
||||
else if (((ConfigEntry<Number>) configMenuOption).getValidity(numberValue) == EConfigValidity.VALID)
|
||||
{
|
||||
if (!cast)
|
||||
{
|
||||
((ConfigEntry<Number>) configMenuOption).uiSetWithoutSaving(numberValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
((ConfigEntry<Number>) configMenuOption).uiSetWithoutSaving(numberValue != null ? numberValue.intValue() : 0);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
}
|
||||
private static void setupBooleanMenuOption(ConfigEntry<Boolean> booleanConfigEntry)
|
||||
{
|
||||
// For boolean
|
||||
Function<Object, Component> func = value -> Translatable("distanthorizons.general." + ((Boolean) value ? "true" : "false")).withStyle((Boolean) value ? ChatFormatting.GREEN : ChatFormatting.RED);
|
||||
|
||||
final ConfigGuiInfo configGuiInfo = ((ConfigGuiInfo) booleanConfigEntry.guiValue);
|
||||
|
||||
configGuiInfo.buttonOptionMap =
|
||||
new AbstractMap.SimpleEntry<Button.OnPress, Function<Object, Component>>(
|
||||
(button) ->
|
||||
{
|
||||
button.active = !booleanConfigEntry.apiIsOverriding();
|
||||
|
||||
booleanConfigEntry.uiSetWithoutSaving(!booleanConfigEntry.get());
|
||||
button.setMessage(func.apply(booleanConfigEntry.get()));
|
||||
}, func);
|
||||
}
|
||||
private static void setupEnumMenuOption(ConfigEntry<Enum<?>> enumConfigEntry, Class<? extends Enum<?>> enumClass)
|
||||
{
|
||||
List<Enum<?>> enumList = Arrays.asList(enumClass.getEnumConstants());
|
||||
|
||||
final ConfigGuiInfo configGuiInfo = ((ConfigGuiInfo) enumConfigEntry.guiValue);
|
||||
|
||||
Function<Object, Component> getEnumTranslatableFunc = (value) -> Translatable(TRANSLATION_PREFIX + "enum." + enumClass.getSimpleName() + "." + enumConfigEntry.get().toString());
|
||||
configGuiInfo.buttonOptionMap =
|
||||
new AbstractMap.SimpleEntry<Button.OnPress, Function<Object, Component>>(
|
||||
(button) ->
|
||||
{
|
||||
// get the currently selected enum and enum index
|
||||
int startingIndex = enumList.indexOf(enumConfigEntry.get());
|
||||
Enum<?> enumValue = enumList.get(startingIndex);
|
||||
|
||||
boolean shiftPressed =
|
||||
InputConstants.isKeyDown(MC_CLIENT.getGlfwWindowId(), GLFW.GLFW_KEY_LEFT_SHIFT)
|
||||
|| InputConstants.isKeyDown(MC_CLIENT.getGlfwWindowId(), GLFW.GLFW_KEY_RIGHT_SHIFT);
|
||||
|
||||
|
||||
|
||||
// move forward or backwards depending on if the shift key is pressed
|
||||
int index = shiftPressed ? startingIndex - 1 : startingIndex + 1;
|
||||
|
||||
// wrap around to the other side of the array when necessary
|
||||
if (index >= enumList.size())
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
else if (index < 0)
|
||||
{
|
||||
index = enumList.size() - 1;
|
||||
}
|
||||
|
||||
|
||||
// walk through the enums to find the next selectable one
|
||||
while (index != startingIndex)
|
||||
{
|
||||
enumValue = enumList.get(index);
|
||||
if (!AnnotationUtil.doesEnumHaveAnnotation(enumValue, DisallowSelectingViaConfigGui.class))
|
||||
{
|
||||
// this enum shouldn't be selectable via the UI,
|
||||
// skip it
|
||||
break;
|
||||
}
|
||||
|
||||
// move forward or backwards depending on if the shift key is pressed
|
||||
index = shiftPressed ? index - 1 : index + 1;
|
||||
|
||||
// wrap around to the other side of the array when necessary
|
||||
if (index >= enumList.size())
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
else if (index < 0)
|
||||
{
|
||||
index = enumList.size() - 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (index == startingIndex)
|
||||
{
|
||||
// one of the enums should be selectable, this is a programmer error
|
||||
enumValue = enumList.get(startingIndex);
|
||||
LOGGER.warn("Enum [" + enumValue.getClass() + "] doesn't contain any values that should be selectable via the UI, sticking to the currently selected value [" + enumValue + "].");
|
||||
}
|
||||
|
||||
|
||||
enumConfigEntry.uiSetWithoutSaving(enumValue);
|
||||
|
||||
button.active = !enumConfigEntry.apiIsOverriding();
|
||||
|
||||
button.setMessage(getEnumTranslatableFunc.apply(enumConfigEntry.get()));
|
||||
}, getEnumTranslatableFunc);
|
||||
}
|
||||
|
||||
private boolean tryCreateInputField(AbstractConfigBase<?> configBase)
|
||||
{
|
||||
final ConfigGuiInfo configGuiInfo = ((ConfigGuiInfo) configBase.guiValue);
|
||||
|
||||
if (configBase instanceof ConfigEntry)
|
||||
{
|
||||
ConfigEntry configEntry = (ConfigEntry) configBase;
|
||||
|
||||
|
||||
//==============//
|
||||
// reset button //
|
||||
//==============//
|
||||
|
||||
Button.OnPress btnAction = (button) ->
|
||||
{
|
||||
configEntry.uiSetWithoutSaving(configEntry.getDefaultValue());
|
||||
this.reload = true;
|
||||
Objects.requireNonNull(this.minecraft).setScreen(this);
|
||||
};
|
||||
|
||||
int resetButtonPosX = this.width
|
||||
- ClassicConfigGUI.ConfigScreenConfigs.RESET_BUTTON_WIDTH
|
||||
- ClassicConfigGUI.ConfigScreenConfigs.SPACE_FROM_RIGHT_SCREEN;
|
||||
int resetButtonPosZ = 0;
|
||||
|
||||
Button resetButton = MakeBtn(
|
||||
Translatable("distanthorizons.general.reset").withStyle(ChatFormatting.RED),
|
||||
resetButtonPosX, resetButtonPosZ,
|
||||
ClassicConfigGUI.ConfigScreenConfigs.RESET_BUTTON_WIDTH, ClassicConfigGUI.ConfigScreenConfigs.RESET_BUTTON_HEIGHT,
|
||||
btnAction);
|
||||
|
||||
if (configEntry.apiIsOverriding())
|
||||
{
|
||||
resetButton.active = false;
|
||||
resetButton.setMessage(Translatable("distanthorizons.general.apiOverride").withStyle(ChatFormatting.DARK_GRAY));
|
||||
}
|
||||
else
|
||||
{
|
||||
resetButton.active = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==============//
|
||||
// option field //
|
||||
//==============//
|
||||
|
||||
Component textComponent = this.GetTranslatableTextComponentForConfig(configEntry);
|
||||
|
||||
int optionFieldPosX = this.width
|
||||
- ClassicConfigGUI.ConfigScreenConfigs.SPACE_FROM_RIGHT_SCREEN
|
||||
- ClassicConfigGUI.ConfigScreenConfigs.RESET_BUTTON_WIDTH
|
||||
- ClassicConfigGUI.ConfigScreenConfigs.BUTTON_WIDTH_SPACING
|
||||
- ClassicConfigGUI.ConfigScreenConfigs.OPTION_FIELD_WIDTH;
|
||||
int optionFieldPosZ = 0;
|
||||
|
||||
if (configGuiInfo.buttonOptionMap != null)
|
||||
{
|
||||
// enum/multi option input button
|
||||
|
||||
Map.Entry<Button.OnPress, Function<Object, Component>> widget = configGuiInfo.buttonOptionMap;
|
||||
if (configEntry.getType().isEnum())
|
||||
{
|
||||
widget.setValue((value) -> Translatable(TRANSLATION_PREFIX + "enum." + configEntry.getType().getSimpleName() + "." + configEntry.get().toString()));
|
||||
}
|
||||
|
||||
Button button = MakeBtn(
|
||||
widget.getValue().apply(configEntry.get()),
|
||||
optionFieldPosX, optionFieldPosZ,
|
||||
ClassicConfigGUI.ConfigScreenConfigs.OPTION_FIELD_WIDTH, ClassicConfigGUI.ConfigScreenConfigs.CATEGORY_BUTTON_HEIGHT,
|
||||
widget.getKey());
|
||||
|
||||
// deactivate the button if the API is overriding it
|
||||
button.active = !configEntry.apiIsOverriding();
|
||||
|
||||
|
||||
this.configListWidget.addButton(this, configEntry,
|
||||
button,
|
||||
resetButton,
|
||||
null,
|
||||
textComponent);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// text box input
|
||||
|
||||
EditBox widget = new EditBox(this.font,
|
||||
optionFieldPosX, optionFieldPosZ,
|
||||
ClassicConfigGUI.ConfigScreenConfigs.OPTION_FIELD_WIDTH - 4, ClassicConfigGUI.ConfigScreenConfigs.CATEGORY_BUTTON_HEIGHT,
|
||||
Translatable(""));
|
||||
widget.setMaxLength(3_000_000); // hopefully 3 million characters should be enough for any normal use-case, lol
|
||||
widget.insertText(String.valueOf(configEntry.get()));
|
||||
|
||||
Predicate<String> processor = configGuiInfo.tooltipFunction.apply(widget, this.doneButton);
|
||||
#if MC_VER <= MC_1_21_11
|
||||
widget.setFilter(processor);
|
||||
#else
|
||||
widget.setResponder(processor::test);
|
||||
#endif
|
||||
|
||||
this.configListWidget.addButton(this, configEntry, widget, resetButton, null, textComponent);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
private boolean tryCreateCategoryButton(AbstractConfigBase<?> configType)
|
||||
{
|
||||
if (configType instanceof ConfigCategory)
|
||||
{
|
||||
ConfigCategory configCategory = (ConfigCategory) configType;
|
||||
|
||||
Component textComponent = this.GetTranslatableTextComponentForConfig(configCategory);
|
||||
|
||||
int categoryPosX = this.width - ClassicConfigGUI.ConfigScreenConfigs.CATEGORY_BUTTON_WIDTH - ClassicConfigGUI.ConfigScreenConfigs.SPACE_FROM_RIGHT_SCREEN;
|
||||
int categoryPosZ = this.height - ClassicConfigGUI.ConfigScreenConfigs.CATEGORY_BUTTON_HEIGHT; // Note: the posZ value here seems to be ignored
|
||||
|
||||
Button widget = MakeBtn(textComponent,
|
||||
categoryPosX, categoryPosZ,
|
||||
ClassicConfigGUI.ConfigScreenConfigs.CATEGORY_BUTTON_WIDTH, ClassicConfigGUI.ConfigScreenConfigs.CATEGORY_BUTTON_HEIGHT,
|
||||
((button) ->
|
||||
{
|
||||
ConfigHandler.INSTANCE.configFileHandler.saveToFile();
|
||||
Objects.requireNonNull(this.minecraft).setScreen(ClassicConfigGUI.getScreen(this, configCategory.getDestination()));
|
||||
}));
|
||||
this.configListWidget.addButton(this, configType, widget, null, null, null);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
private boolean tryCreateButton(AbstractConfigBase<?> configType)
|
||||
{
|
||||
if (configType instanceof ConfigUIButton)
|
||||
{
|
||||
ConfigUIButton configUiButton = (ConfigUIButton) configType;
|
||||
|
||||
Component textComponent = this.GetTranslatableTextComponentForConfig(configUiButton);
|
||||
|
||||
int buttonPosX = this.width - ClassicConfigGUI.ConfigScreenConfigs.CATEGORY_BUTTON_WIDTH - ClassicConfigGUI.ConfigScreenConfigs.SPACE_FROM_RIGHT_SCREEN;
|
||||
|
||||
Button widget = MakeBtn(textComponent,
|
||||
buttonPosX, this.height - 28,
|
||||
ClassicConfigGUI.ConfigScreenConfigs.CATEGORY_BUTTON_WIDTH, ClassicConfigGUI.ConfigScreenConfigs.CATEGORY_BUTTON_HEIGHT,
|
||||
(button) -> ((ConfigUIButton) configType).runAction());
|
||||
this.configListWidget.addButton(this, configType, widget, null, null, null);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
private boolean tryCreateComment(AbstractConfigBase<?> configType)
|
||||
{
|
||||
if (configType instanceof ConfigUIComment)
|
||||
{
|
||||
ConfigUIComment configUiComment = (ConfigUIComment) configType;
|
||||
|
||||
Component textComponent = this.GetTranslatableTextComponentForConfig(configUiComment);
|
||||
if (configUiComment.parentConfigPath != null)
|
||||
{
|
||||
textComponent = Translatable(TRANSLATION_PREFIX + configUiComment.parentConfigPath);
|
||||
}
|
||||
|
||||
this.configListWidget.addButton(this, configType, null, null, null, textComponent);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
private boolean tryCreateSpacer(AbstractConfigBase<?> configType)
|
||||
{
|
||||
if (configType instanceof ConfigUISpacer)
|
||||
{
|
||||
Button spacerButton = MakeBtn(Translatable("distanthorizons.general.spacer"),
|
||||
10, 10, // having too small of a size causes division by 0 errors in older MC versions (IE 1.20.1)
|
||||
1, 1,
|
||||
(button) -> { });
|
||||
|
||||
spacerButton.visible = false;
|
||||
this.configListWidget.addButton(this, configType, spacerButton, null, null, null);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
private boolean tryCreateLinkedEntry(AbstractConfigBase<?> configType)
|
||||
{
|
||||
if (configType instanceof ConfigUiLinkedEntry)
|
||||
{
|
||||
this.addMenuItem(((ConfigUiLinkedEntry) configType).get());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private Component GetTranslatableTextComponentForConfig(AbstractConfigBase<?> configType)
|
||||
{ return Translatable(TRANSLATION_PREFIX + configType.getNameAndCategory()); }
|
||||
|
||||
|
||||
|
||||
//===========//
|
||||
// rendering //
|
||||
//===========//
|
||||
|
||||
@Override
|
||||
#if MC_VER < MC_1_20_1
|
||||
public void render(PoseStack matrices, int mouseX, int mouseY, float delta)
|
||||
#elif MC_VER <= MC_1_21_11
|
||||
public void render(GuiGraphics matrices, int mouseX, int mouseY, float delta)
|
||||
#else
|
||||
public void extractRenderState(GuiGraphicsExtractor matrices, int mouseX, int mouseY, float delta)
|
||||
#endif
|
||||
{
|
||||
#if MC_VER < MC_1_20_2 // 1.20.2 now enables this by default in the `this.list.render` function
|
||||
this.renderBackground(matrices);
|
||||
#elif MC_VER <= MC_1_21_11
|
||||
super.render(matrices, mouseX, mouseY, delta);
|
||||
#else
|
||||
super.extractRenderState(matrices, mouseX, mouseY, delta);
|
||||
#endif
|
||||
|
||||
// Render buttons
|
||||
#if MC_VER <= MC_1_21_11
|
||||
this.configListWidget.render(matrices, mouseX, mouseY, delta);
|
||||
#else
|
||||
this.configListWidget.extractRenderState(matrices, mouseX, mouseY, delta);
|
||||
#endif
|
||||
|
||||
|
||||
// Render config title
|
||||
this.DhDrawCenteredString(matrices, this.font, this.title,
|
||||
this.width / 2, 15,
|
||||
#if MC_VER < MC_1_21_6
|
||||
0xFFFFFF // RGB white
|
||||
#else
|
||||
0xFFFFFFFF // ARGB white
|
||||
#endif );
|
||||
|
||||
|
||||
// render DH version
|
||||
this.DhDrawString(matrices, this.font, TextOrLiteral(ModInfo.VERSION), 2, this.height - 10,
|
||||
#if MC_VER < MC_1_21_6
|
||||
0xAAAAAA // RGB white
|
||||
#else
|
||||
0xFFAAAAAA // ARGB white
|
||||
#endif );
|
||||
|
||||
// If the update is pending, display this message to inform the user that it will apply when the game restarts
|
||||
if (SelfUpdater.deleteOldJarOnJvmShutdown)
|
||||
{
|
||||
this.DhDrawString(matrices, this.font, Translatable(ModInfo.ID + ".updater.waitingForClose"), 4, this.height - 42,
|
||||
#if MC_VER < MC_1_21_6
|
||||
0xFFFFFF // RGB white
|
||||
#else
|
||||
0xFFFFFFFF // ARGB white
|
||||
#endif );
|
||||
}
|
||||
|
||||
|
||||
this.renderTooltip(matrices, mouseX, mouseY, delta);
|
||||
|
||||
#if MC_VER < MC_1_20_2
|
||||
super.render(matrices, mouseX, mouseY, delta);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if MC_VER < MC_1_20_1
|
||||
private void renderTooltip(PoseStack matrices, int mouseX, int mouseY, float delta)
|
||||
#elif MC_VER <= MC_1_21_11
|
||||
private void renderTooltip(GuiGraphics matrices, int mouseX, int mouseY, float delta)
|
||||
#else
|
||||
private void renderTooltip(GuiGraphicsExtractor matrices, int mouseX, int mouseY, float delta)
|
||||
#endif
|
||||
{
|
||||
AbstractWidget hoveredWidget = this.configListWidget.getHoveredButton(mouseX, mouseY);
|
||||
if (hoveredWidget == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ClassicConfigGUI.DhButtonEntry button = ClassicConfigGUI.DhButtonEntry.BUTTON_BY_WIDGET.get(hoveredWidget);
|
||||
|
||||
|
||||
// A quick fix for tooltips on linked entries
|
||||
AbstractConfigBase<?> configBase = ConfigUiLinkedEntry.class.isAssignableFrom(button.dhConfigType.getClass()) ?
|
||||
((ConfigUiLinkedEntry) button.dhConfigType).get() :
|
||||
button.dhConfigType;
|
||||
|
||||
boolean apiOverrideActive = false;
|
||||
if (configBase instanceof ConfigEntry)
|
||||
{
|
||||
apiOverrideActive = ((ConfigEntry<?>) configBase).apiIsOverriding();
|
||||
}
|
||||
|
||||
String key = TRANSLATION_PREFIX + (configBase.category.isEmpty() ? "" : configBase.category + ".") + configBase.getName() + ".@tooltip";
|
||||
|
||||
if (apiOverrideActive)
|
||||
{
|
||||
key = "distanthorizons.general.disabledByApi.@tooltip";
|
||||
}
|
||||
|
||||
// display the validation error tooltip if present
|
||||
final ConfigGuiInfo configGuiInfo = ((ConfigGuiInfo) configBase.guiValue);
|
||||
if (configGuiInfo.errorMessage != null)
|
||||
{
|
||||
this.DhRenderTooltip(matrices, this.font, configGuiInfo.errorMessage, mouseX, mouseY);
|
||||
}
|
||||
// display the tooltip if present
|
||||
else if (LANG_WRAPPER.langExists(key))
|
||||
{
|
||||
List<Component> list = new ArrayList<>();
|
||||
String lang = LANG_WRAPPER.getLang(key);
|
||||
for (String langLine : lang.split("\n"))
|
||||
{
|
||||
list.add(TextOrTranslatable(langLine));
|
||||
}
|
||||
|
||||
this.DhRenderComponentTooltip(matrices, this.font, list, mouseX, mouseY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==========//
|
||||
// shutdown //
|
||||
//==========//
|
||||
|
||||
/** When you close it, it goes to the previous screen and saves */
|
||||
@Override
|
||||
public void onClose()
|
||||
{
|
||||
ConfigHandler.INSTANCE.configFileHandler.saveToFile();
|
||||
Objects.requireNonNull(this.minecraft).setScreen(this.parent);
|
||||
|
||||
ClassicConfigGUI.CONFIG_CORE_INTERFACE.onScreenChangeListenerList.forEach((listener) -> listener.run());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user