From b484d0287c8b7888ed79294b02cfdf491838a36c Mon Sep 17 00:00:00 2001 From: Martin Prokoph Date: Tue, 4 Nov 2025 18:22:11 +0100 Subject: [PATCH] dev: migrate mappings to mojmap --- build.gradle | 6 +- .../eu/midnightdust/core/MidnightLib.java | 4 +- .../core/mixin/MixinOptionsScreen.java | 26 ++-- .../screen/MidnightConfigOverviewScreen.java | 26 ++-- .../midnightdust/lib/config/AutoCommand.java | 35 +++-- .../midnightdust/lib/config/ButtonEntry.java | 61 ++++---- .../eu/midnightdust/lib/config/EntryInfo.java | 17 +- .../lib/config/MidnightConfig.java | 53 ++++--- .../lib/config/MidnightConfigListWidget.java | 29 ++-- .../lib/config/MidnightConfigScreen.java | 145 +++++++++--------- .../lib/config/MidnightSliderWidget.java | 10 +- .../lib/util/MidnightColorUtil.java | 0 .../lib/util/PlatformFunctions.java | 5 +- .../midnightdust/test/MidnightLibExtras.java | 68 ++++---- .../test/config/MidnightConfigExample.java | 31 ++-- .../midnightdust/lib/config/AutoModMenu.java | 0 .../util/fabric/PlatformFunctionsImpl.java | 5 +- gradle.properties | 12 +- .../util/neoforge/PlatformFunctionsImpl.java | 4 +- .../neoforge/MidnightLibNeoForge.java | 4 +- 20 files changed, 269 insertions(+), 272 deletions(-) mode change 100755 => 100644 common/src/main/java/eu/midnightdust/core/MidnightLib.java mode change 100755 => 100644 common/src/main/java/eu/midnightdust/core/screen/MidnightConfigOverviewScreen.java mode change 100755 => 100644 common/src/main/java/eu/midnightdust/lib/config/MidnightConfig.java mode change 100755 => 100644 common/src/main/java/eu/midnightdust/lib/util/MidnightColorUtil.java mode change 100755 => 100644 fabric/src/main/java/eu/midnightdust/lib/config/AutoModMenu.java diff --git a/build.gradle b/build.gradle index 3e9cb1d..e7c4b26 100644 --- a/build.gradle +++ b/build.gradle @@ -17,11 +17,7 @@ subprojects { dependencies { minecraft "com.mojang:minecraft:${rootProject.minecraft_version}" - // The following line declares the yarn mappings you may select this one as well. - mappings loom.layered { - it.mappings("net.fabricmc:yarn:$rootProject.yarn_mappings:v2") - it.mappings("dev.architectury:yarn-mappings-patch-neoforge:$rootProject.yarn_mappings_patch_neoforge_version") - } + mappings loom.officialMojangMappings() } } diff --git a/common/src/main/java/eu/midnightdust/core/MidnightLib.java b/common/src/main/java/eu/midnightdust/core/MidnightLib.java old mode 100755 new mode 100644 index 7057d20..e533f39 --- a/common/src/main/java/eu/midnightdust/core/MidnightLib.java +++ b/common/src/main/java/eu/midnightdust/core/MidnightLib.java @@ -3,11 +3,11 @@ package eu.midnightdust.core; import eu.midnightdust.core.config.MidnightLibConfig; import eu.midnightdust.lib.config.AutoCommand; import eu.midnightdust.lib.config.MidnightConfig; -import net.minecraft.util.Util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.swing.UIManager; +import net.minecraft.Util; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; @@ -19,7 +19,7 @@ public class MidnightLib { public static void onInitializeClient() { try { - if (Util.getOperatingSystem() != Util.OperatingSystem.OSX) { + if (Util.getPlatform() != Util.OS.OSX) { System.setProperty("java.awt.headless", "false"); UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } diff --git a/common/src/main/java/eu/midnightdust/core/mixin/MixinOptionsScreen.java b/common/src/main/java/eu/midnightdust/core/mixin/MixinOptionsScreen.java index 13203b7..bfac090 100644 --- a/common/src/main/java/eu/midnightdust/core/mixin/MixinOptionsScreen.java +++ b/common/src/main/java/eu/midnightdust/core/mixin/MixinOptionsScreen.java @@ -1,12 +1,6 @@ package eu.midnightdust.core.mixin; import eu.midnightdust.core.screen.MidnightConfigOverviewScreen; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.screen.option.OptionsScreen; -import net.minecraft.client.gui.widget.TextIconButtonWidget; -import net.minecraft.client.gui.widget.ThreePartsLayoutWidget; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -16,28 +10,34 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.util.Objects; +import net.minecraft.client.gui.components.SpriteIconButton; +import net.minecraft.client.gui.layouts.HeaderAndFooterLayout; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.gui.screens.options.OptionsScreen; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; import static eu.midnightdust.core.MidnightLib.MOD_ID; import static eu.midnightdust.core.config.MidnightLibConfig.shouldShowButton; @Mixin(OptionsScreen.class) public abstract class MixinOptionsScreen extends Screen { - @Shadow @Final private ThreePartsLayoutWidget layout; - @Unique TextIconButtonWidget midnightlib$button = TextIconButtonWidget.builder(Text.translatable("midnightlib.overview.title"), ( - buttonWidget) -> Objects.requireNonNull(client).setScreen(new MidnightConfigOverviewScreen(this)), true) - .texture(Identifier.of(MOD_ID,"icon/"+MOD_ID), 16, 16).dimension(20, 20).build(); + @Shadow @Final private HeaderAndFooterLayout layout; + @Unique SpriteIconButton midnightlib$button = SpriteIconButton.builder(Component.translatable("midnightlib.overview.title"), ( + buttonWidget) -> Objects.requireNonNull(minecraft).setScreen(new MidnightConfigOverviewScreen(this)), true) + .sprite(ResourceLocation.fromNamespaceAndPath(MOD_ID,"icon/"+MOD_ID), 16, 16).size(20, 20).build(); - private MixinOptionsScreen(Text title) {super(title);} + private MixinOptionsScreen(Component title) {super(title);} @Inject(at = @At("HEAD"), method = "init") public void midnightlib$onInit(CallbackInfo ci) { if (shouldShowButton()) { this.midnightlib$setButtonPos(); - this.addDrawableChild(midnightlib$button); + this.addRenderableWidget(midnightlib$button); } } - @Inject(at = @At("TAIL"), method = "refreshWidgetPositions") + @Inject(at = @At("TAIL"), method = "repositionElements") public void midnightlib$onResize(CallbackInfo ci) { if (shouldShowButton()) this.midnightlib$setButtonPos(); } diff --git a/common/src/main/java/eu/midnightdust/core/screen/MidnightConfigOverviewScreen.java b/common/src/main/java/eu/midnightdust/core/screen/MidnightConfigOverviewScreen.java old mode 100755 new mode 100644 index 54a5806..9cacb79 --- a/common/src/main/java/eu/midnightdust/core/screen/MidnightConfigOverviewScreen.java +++ b/common/src/main/java/eu/midnightdust/core/screen/MidnightConfigOverviewScreen.java @@ -2,23 +2,21 @@ package eu.midnightdust.core.screen; import eu.midnightdust.core.MidnightLib; import eu.midnightdust.lib.config.MidnightConfig; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.screen.ScreenTexts; -import net.minecraft.text.Text; - import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; - +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.CommonComponents; +import net.minecraft.network.chat.Component; import eu.midnightdust.lib.config.MidnightConfigListWidget; public class MidnightConfigOverviewScreen extends Screen { public MidnightConfigOverviewScreen(Screen parent) { - super(Text.translatable( "midnightlib.overview.title")); + super(Component.translatable( "midnightlib.overview.title")); this.parent = parent; } private final Screen parent; @@ -26,22 +24,22 @@ public class MidnightConfigOverviewScreen extends Screen { @Override protected void init() { - this.addDrawableChild(ButtonWidget.builder(ScreenTexts.DONE, (button) -> Objects.requireNonNull(client).setScreen(parent)).dimensions(this.width / 2 - 100, this.height - 26, 200, 20).build()); + this.addRenderableWidget(Button.builder(CommonComponents.GUI_DONE, (button) -> Objects.requireNonNull(minecraft).setScreen(parent)).bounds(this.width / 2 - 100, this.height - 26, 200, 20).build()); - this.addSelectableChild(this.list = new MidnightConfigListWidget(this.client, this.width, this.height - 57, 24, 25)); + this.addWidget(this.list = new MidnightConfigListWidget(this.minecraft, this.width, this.height - 57, 24, 25)); List sortedMods = new ArrayList<>(MidnightConfig.configInstances.keySet()); Collections.sort(sortedMods); sortedMods.forEach((modid) -> { if (!MidnightLib.hiddenMods.contains(modid)) { - list.addButton(List.of(ButtonWidget.builder(Text.translatable(modid +".midnightconfig.title"), (button) -> - Objects.requireNonNull(client).setScreen(MidnightConfig.getScreen(this, modid))).dimensions(this.width / 2 - 125, this.height - 28, 250, 20).build()), null, null); + list.addButton(List.of(Button.builder(Component.translatable(modid +".midnightconfig.title"), (button) -> + Objects.requireNonNull(minecraft).setScreen(MidnightConfig.getScreen(this, modid))).bounds(this.width / 2 - 125, this.height - 28, 250, 20).build()), null, null); }}); super.init(); } @Override - public void render(DrawContext context, int mouseX, int mouseY, float delta) { + public void render(GuiGraphics context, int mouseX, int mouseY, float delta) { super.render(context, mouseX, mouseY, delta); this.list.render(context, mouseX, mouseY, delta); - context.drawCenteredTextWithShadow(textRenderer, title, width / 2, 10, 0xFFFFFFFF); + context.drawCenteredString(font, title, width / 2, 10, 0xFFFFFFFF); } } \ No newline at end of file diff --git a/common/src/main/java/eu/midnightdust/lib/config/AutoCommand.java b/common/src/main/java/eu/midnightdust/lib/config/AutoCommand.java index e41f920..58bb91c 100644 --- a/common/src/main/java/eu/midnightdust/lib/config/AutoCommand.java +++ b/common/src/main/java/eu/midnightdust/lib/config/AutoCommand.java @@ -1,15 +1,16 @@ package eu.midnightdust.lib.config; import com.mojang.brigadier.arguments.*; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.context.CommandContext; +import eu.midnightdust.lib.config.MidnightConfig.Entry; import eu.midnightdust.lib.util.PlatformFunctions; -import net.minecraft.server.command.CommandManager; -import net.minecraft.server.command.ServerCommandSource; -import net.minecraft.text.Text; - import java.lang.reflect.Field; import java.util.List; import java.util.Objects; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.Commands; +import net.minecraft.network.chat.Component; import static eu.midnightdust.lib.config.MidnightConfig.Entry; @@ -25,19 +26,19 @@ public class AutoCommand { this.type = MidnightConfig.getUnderlyingType(field); this.isList = field.getType() == List.class; - var command = CommandManager.literal(field.getName()).executes(this::getValue); + var command = Commands.literal(field.getName()).executes(this::getValue); if (type.isEnum()) { for (Object enumValue : field.getType().getEnumConstants()) - command = command.then(CommandManager.literal(enumValue.toString()) + command = command.then(Commands.literal(enumValue.toString()) .executes(ctx -> this.setValue(ctx.getSource(), enumValue, ""))); } else if (isList) { for (String action : new String[]{"add", "remove"}) - command = command.then(CommandManager.literal(action) - .then(CommandManager.argument(VALUE, getArgType()).executes(ctx -> setValueFromArg(ctx, action)))); - } else command = command.then(CommandManager.argument(VALUE, getArgType()).executes(ctx -> setValueFromArg(ctx, ""))); + command = command.then(Commands.literal(action) + .then(Commands.argument(VALUE, getArgType()).executes(ctx -> setValueFromArg(ctx, action)))); + } else command = command.then(Commands.argument(VALUE, getArgType()).executes(ctx -> setValueFromArg(ctx, ""))); - PlatformFunctions.registerCommand(CommandManager.literal("midnightconfig").requires(source -> source.hasPermissionLevel(2)).then(CommandManager.literal(modid).then(command))); + PlatformFunctions.registerCommand(Commands.literal("midnightconfig").requires(source -> source.hasPermission(2)).then(Commands.literal(modid).then(command))); } public ArgumentType getArgType() { @@ -49,14 +50,14 @@ public class AutoCommand { return StringArgumentType.string(); } - public int setValueFromArg(CommandContext context, String action) { + public int setValueFromArg(CommandContext context, String action) { if (type == int.class) return setValue(context.getSource(), IntegerArgumentType.getInteger(context, VALUE), action); else if (type == double.class) return setValue(context.getSource(), DoubleArgumentType.getDouble(context, VALUE), action); else if (type == float.class) return setValue(context.getSource(), FloatArgumentType.getFloat(context, VALUE), action); else if (type == boolean.class) return setValue(context.getSource(), BoolArgumentType.getBool(context, VALUE), action); return setValue(context.getSource(), StringArgumentType.getString(context, VALUE), action); } - private int setValue(ServerCommandSource source, Object value, String action) { + private int setValue(CommandSourceStack source, Object value, String action) { boolean add = Objects.equals(action, "add"); try { if (!isList) field.set(null, value); @@ -69,16 +70,16 @@ public class AutoCommand { MidnightConfig.write(modid); } catch (Exception e) { - source.sendError(Text.literal(isList ? "Could not %s %s %s %s: %s".formatted(add ? "add" : "remove", value, add ? "to" : "from", field.getName(), e) : "Could not set %s to value %s: %s".formatted(field.getName(), value, e))); + source.sendFailure(Component.literal(isList ? "Could not %s %s %s %s: %s".formatted(add ? "add" : "remove", value, add ? "to" : "from", field.getName(), e) : "Could not set %s to value %s: %s".formatted(field.getName(), value, e))); return 0; } - source.sendFeedback(() -> Text.literal(isList ? "Successfully %s %s %s %s".formatted(add ? "added" : "removed", value, add ? "to" : "from", field.getName()) : + source.sendSuccess(() -> Component.literal(isList ? "Successfully %s %s %s %s".formatted(add ? "added" : "removed", value, add ? "to" : "from", field.getName()) : "Successfully set %s to %s".formatted(field.getName(), value)), true); return 1; } - private int getValue(CommandContext context) { - context.getSource().sendFeedback(() -> { - try { return Text.literal("The value of %s is %s".formatted(field.getName(), field.get(null))); + private int getValue(CommandContext context) { + context.getSource().sendSuccess(() -> { + try { return Component.literal("The value of %s is %s".formatted(field.getName(), field.get(null))); } catch (IllegalAccessException e) {throw new RuntimeException(e);} }, true); return 0; diff --git a/common/src/main/java/eu/midnightdust/lib/config/ButtonEntry.java b/common/src/main/java/eu/midnightdust/lib/config/ButtonEntry.java index 3b0f6e3..4b567f9 100644 --- a/common/src/main/java/eu/midnightdust/lib/config/ButtonEntry.java +++ b/common/src/main/java/eu/midnightdust/lib/config/ButtonEntry.java @@ -1,40 +1,39 @@ package eu.midnightdust.lib.config; import com.google.common.collect.Lists; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.Click; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.Element; -import net.minecraft.client.gui.Selectable; -import net.minecraft.client.gui.screen.ConfirmLinkScreen; -import net.minecraft.client.gui.widget.ClickableWidget; -import net.minecraft.client.gui.widget.ElementListWidget; -import net.minecraft.client.gui.widget.MultilineTextWidget; -import net.minecraft.registry.Registries; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; - import java.util.List; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Font; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.AbstractWidget; +import net.minecraft.client.gui.components.ContainerObjectSelectionList; +import net.minecraft.client.gui.components.MultiLineTextWidget; +import net.minecraft.client.gui.components.events.GuiEventListener; +import net.minecraft.client.gui.narration.NarratableEntry; +import net.minecraft.client.gui.screens.ConfirmLinkScreen; +import net.minecraft.client.input.MouseButtonEvent; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; -public class ButtonEntry extends ElementListWidget.Entry { - private static final TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; - public final Text text; - public final List buttons; +public class ButtonEntry extends ContainerObjectSelectionList.Entry { + private static final Font textRenderer = Minecraft.getInstance().font; + public final Component text; + public final List buttons; public final EntryInfo info; public boolean centered = false; - public MultilineTextWidget title; + public MultiLineTextWidget title; - public ButtonEntry(List buttons, Text text, EntryInfo info) { + public ButtonEntry(List buttons, Component text, EntryInfo info) { this.buttons = buttons; this.text = text; this.info = info; if (info != null && info.comment != null) this.centered = info.comment.centered(); - int scaledWidth = MinecraftClient.getInstance().getWindow().getScaledWidth(); + int scaledWidth = Minecraft.getInstance().getWindow().getGuiScaledWidth(); if (text != null && (!text.getString().contains("spacer") || !buttons.isEmpty())) { - title = new MultilineTextWidget(12, 0, Text.of(text), textRenderer).setCentered(centered); + title = new MultiLineTextWidget(12, 0, Component.translationArg(text), textRenderer).setCentered(centered); if (info != null) title.setTooltip(info.getTooltip(false)); title.setMaxWidth(!buttons.isEmpty() ? buttons.get(buttons.size() > 2 ? buttons.size() - 1 : 0).getX() - 16 : scaledWidth - 24); @@ -42,7 +41,7 @@ public class ButtonEntry extends ElementListWidget.Entry { } } - public void render(DrawContext context, int mouseX, int mouseY, boolean hovered, float tickDelta) { + public void renderContent(GuiGraphics context, int mouseX, int mouseY, boolean hovered, float tickDelta) { buttons.forEach(b -> { b.setY(this.getY()); b.render(context, mouseX, mouseY, tickDelta); @@ -51,28 +50,28 @@ public class ButtonEntry extends ElementListWidget.Entry { title.setY(this.getY() + 5); title.render(context, mouseX, mouseY, tickDelta); - if (info.entry != null && !this.buttons.isEmpty() && this.buttons.getFirst() instanceof ClickableWidget widget) { + if (info.entry != null && !this.buttons.isEmpty() && this.buttons.getFirst() instanceof AbstractWidget widget) { int idMode = this.info.entry.idMode(); - if (idMode != -1) context.drawItem(idMode == 0 ? - Registries.ITEM.get(Identifier.tryParse(this.info.tempValue)).getDefaultStack() - : Registries.BLOCK.get(Identifier.tryParse(this.info.tempValue)).asItem().getDefaultStack(), + if (idMode != -1) context.renderItem(idMode == 0 ? + BuiltInRegistries.ITEM.getValue(ResourceLocation.tryParse(this.info.tempValue)).getDefaultInstance() + : BuiltInRegistries.BLOCK.getValue(ResourceLocation.tryParse(this.info.tempValue)).asItem().getDefaultInstance(), widget.getX() + widget.getWidth() - 18, this.getY() + 2); } } } @Override - public boolean mouseClicked(Click click, boolean doubled) { + public boolean mouseClicked(MouseButtonEvent click, boolean doubled) { if (this.info != null && this.info.comment != null && !this.info.comment.url().isBlank()) - ConfirmLinkScreen.open(MinecraftClient.getInstance().currentScreen, this.info.comment.url(), true); + ConfirmLinkScreen.confirmLinkNow(Minecraft.getInstance().screen, this.info.comment.url(), true); return super.mouseClicked(click, doubled); } - public List children() { + public List children() { return Lists.newArrayList(buttons); } - public List selectableChildren() { + public List narratables() { return Lists.newArrayList(buttons); } } diff --git a/common/src/main/java/eu/midnightdust/lib/config/EntryInfo.java b/common/src/main/java/eu/midnightdust/lib/config/EntryInfo.java index a5cba28..fc05bad 100644 --- a/common/src/main/java/eu/midnightdust/lib/config/EntryInfo.java +++ b/common/src/main/java/eu/midnightdust/lib/config/EntryInfo.java @@ -1,14 +1,13 @@ package eu.midnightdust.lib.config; import eu.midnightdust.lib.util.PlatformFunctions; -import net.minecraft.client.gui.tab.Tab; -import net.minecraft.client.gui.tooltip.Tooltip; -import net.minecraft.client.gui.widget.ClickableWidget; -import net.minecraft.client.resource.language.I18n; -import net.minecraft.text.Text; - import java.lang.reflect.Field; import java.util.List; +import net.minecraft.client.gui.components.AbstractWidget; +import net.minecraft.client.gui.components.Tooltip; +import net.minecraft.client.gui.components.tabs.Tab; +import net.minecraft.client.resources.language.I18n; +import net.minecraft.network.chat.Component; public class EntryInfo { public MidnightConfig.Entry entry; @@ -21,8 +20,8 @@ public class EntryInfo { Object defaultValue, value, function; String tempValue; // The value visible in the config screen boolean inLimits = true; - Text error; - ClickableWidget actionButton; // color picker button / explorer button + Component error; + AbstractWidget actionButton; // color picker button / explorer button Tab tab; boolean conditionsMet = true; @@ -99,6 +98,6 @@ public class EntryInfo { public Tooltip getTooltip(boolean isButton) { String key = translationKey + (!isButton ? ".label" : "") + ".tooltip"; - return Tooltip.of(isButton && this.error != null ? this.error : I18n.hasTranslation(key) ? Text.translatable(key) : Text.empty()); + return Tooltip.create(isButton && this.error != null ? this.error : I18n.exists(key) ? Component.translatable(key) : Component.empty()); } } diff --git a/common/src/main/java/eu/midnightdust/lib/config/MidnightConfig.java b/common/src/main/java/eu/midnightdust/lib/config/MidnightConfig.java old mode 100755 new mode 100644 index db1fc7c..0903c5a --- a/common/src/main/java/eu/midnightdust/lib/config/MidnightConfig.java +++ b/common/src/main/java/eu/midnightdust/lib/config/MidnightConfig.java @@ -3,11 +3,14 @@ package eu.midnightdust.lib.config; import com.google.gson.*; import com.google.gson.stream.*; import eu.midnightdust.lib.util.PlatformFunctions; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.widget.*; -import net.minecraft.client.resource.language.I18n; -import net.minecraft.text.Style; -import net.minecraft.text.Text; +import net.minecraft.ChatFormatting; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.EditBox; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.resources.language.I18n; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.Style; +import net.minecraft.resources.ResourceLocation; import net.minecraft.util.*; import org.jetbrains.annotations.Nullable; @@ -42,9 +45,9 @@ public abstract class MidnightConfig { public boolean shouldSkipClass(Class clazz) { return false; } public boolean shouldSkipField(FieldAttributes fieldAttributes) { return fieldAttributes.getAnnotation(Entry.class) == null; } }) - .registerTypeAdapter(Identifier.class, new TypeAdapter() { - public void write(JsonWriter out, Identifier id) throws IOException { out.value(id.toString()); } - public Identifier read(JsonReader in) throws IOException { return Identifier.of(in.nextString()); } + .registerTypeAdapter(ResourceLocation.class, new TypeAdapter() { + public void write(JsonWriter out, ResourceLocation id) throws IOException { out.value(id.toString()); } + public ResourceLocation read(JsonReader in) throws IOException { return ResourceLocation.parse(in.nextString()); } }).setPrettyPrinting().create(); protected static final LinkedHashMap entries = new LinkedHashMap<>(); // modid:fieldName -> EntryInfo @@ -86,16 +89,16 @@ public abstract class MidnightConfig { if (info.dataType == int.class) textField(info, Integer::parseInt, INTEGER_ONLY, (int) e.min(), (int) e.max(), true); else if (info.dataType == float.class) textField(info, Float::parseFloat, DECIMAL_ONLY, (float) e.min(), (float) e.max(), false); else if (info.dataType == double.class) textField(info, Double::parseDouble, DECIMAL_ONLY, e.min(), e.max(), false); - else if (info.dataType == String.class || info.dataType == Identifier.class) textField(info, String::length, null, Math.min(e.min(), 0), Math.max(e.max(), 1), true); + else if (info.dataType == String.class || info.dataType == ResourceLocation.class) textField(info, String::length, null, Math.min(e.min(), 0), Math.max(e.max(), 1), true); else if (info.dataType == boolean.class) { - Function func = value -> Text.translatable((Boolean) value ? "gui.yes" : "gui.no").formatted((Boolean) value ? Formatting.GREEN : Formatting.RED); - info.function = new AbstractMap.SimpleEntry>(button -> { + Function func = value -> Component.translatable((Boolean) value ? "gui.yes" : "gui.no").withStyle((Boolean) value ? ChatFormatting.GREEN : ChatFormatting.RED); + info.function = new AbstractMap.SimpleEntry>(button -> { info.setValue(!(Boolean) info.value); button.setMessage(func.apply(info.value)); }, func); } else if (info.dataType.isEnum()) { List values = Arrays.asList(field.getType().getEnumConstants()); - Function func = value -> getEnumTranslatableText(value, info); - info.function = new AbstractMap.SimpleEntry>(button -> { + Function func = value -> getEnumTranslatableText(value, info); + info.function = new AbstractMap.SimpleEntry>(button -> { int index = values.indexOf(info.value) + 1; info.setValue(values.get(index >= values.size() ? 0 : index)); button.setMessage(func.apply(info.value)); @@ -118,47 +121,47 @@ public abstract class MidnightConfig { private static void textField(EntryInfo info, Function f, Pattern pattern, double min, double max, boolean cast) { boolean isNumber = pattern != null; - info.function = (BiFunction>) (t, b) -> s -> { + info.function = (BiFunction>) (t, b) -> s -> { s = s.trim(); if (!(s.isEmpty() || !isNumber || pattern.matcher(s).matches()) || - (info.dataType == Identifier.class && Identifier.validate(s).isError())) return false; + (info.dataType == ResourceLocation.class && ResourceLocation.read(s).isError())) return false; Number value = 0; boolean inLimits = false; info.error = null; if (!(isNumber && s.isEmpty()) && !s.equals("-") && !s.equals(".")) { try { value = f.apply(s); } catch(NumberFormatException e){ return false; } inLimits = value.doubleValue() >= min && value.doubleValue() <= max; - info.error = inLimits? null : Text.literal(value.doubleValue() < min ? + info.error = inLimits? null : Component.literal(value.doubleValue() < min ? "§cMinimum " + (isNumber? "value" : "length") + (cast? " is " + (int)min : " is " + min) : - "§cMaximum " + (isNumber? "value" : "length") + (cast? " is " + (int)max : " is " + max)).formatted(Formatting.RED); + "§cMaximum " + (isNumber? "value" : "length") + (cast? " is " + (int)max : " is " + max)).withStyle(ChatFormatting.RED); t.setTooltip(info.getTooltip(true)); } info.tempValue = s; - t.setEditableColor(inLimits? 0xFFFFFFFF : 0xFFFF7777); + t.setTextColor(inLimits? 0xFFFFFFFF : 0xFFFF7777); info.inLimits = inLimits; b.active = entries.values().stream().allMatch(e -> e.inLimits); if (inLimits) { - if (info.dataType == Identifier.class) - info.setValue(Identifier.tryParse(s)); + if (info.dataType == ResourceLocation.class) + info.setValue(ResourceLocation.tryParse(s)); else info.setValue(isNumber ? value : s); } if (info.entry.isColor()) { if (!s.contains("#")) s = '#' + s; if (!HEXADECIMAL_ONLY.matcher(s).matches()) return false; - try { info.actionButton.setMessage(Text.literal("⬛").setStyle(Style.EMPTY.withColor(Color.decode(info.tempValue).getRGB()))); + try { info.actionButton.setMessage(Component.literal("⬛").setStyle(Style.EMPTY.withColor(Color.decode(info.tempValue).getRGB()))); } catch (Exception ignored) {} } return true; }; } - protected Text getEnumTranslatableText(Object value, EntryInfo info) { - if (value instanceof TranslatableOption translatableOption) return translatableOption.getText(); + protected Component getEnumTranslatableText(Object value, EntryInfo info) { + if (value instanceof OptionEnum translatableOption) return translatableOption.getCaption(); String translationKey = "%s.midnightconfig.enum.%s.%s".formatted(modid, info.dataType.getSimpleName(), info.toTemporaryValue()); - return I18n.hasTranslation(translationKey) ? Text.translatable(translationKey) : Text.literal(info.toTemporaryValue()); + return I18n.exists(translationKey) ? Component.translatable(translationKey) : Component.literal(info.toTemporaryValue()); } public void loadValuesFromJson() { @@ -220,7 +223,7 @@ public abstract class MidnightConfig { /** * Entry Annotation
- * - width: The maximum character length of the {@link String}, {@link Identifier} or String/Identifier {@link List<>} field
+ * - width: The maximum character length of the {@link String}, {@link ResourceLocation} or String/Identifier {@link List<>} field
* - min: The minimum value of the int, float or double field
* - max: The maximum value of the int, float or double field
* - name: Will be used instead of the default translation key, if not empty
diff --git a/common/src/main/java/eu/midnightdust/lib/config/MidnightConfigListWidget.java b/common/src/main/java/eu/midnightdust/lib/config/MidnightConfigListWidget.java index 476ef90..8455062 100644 --- a/common/src/main/java/eu/midnightdust/lib/config/MidnightConfigListWidget.java +++ b/common/src/main/java/eu/midnightdust/lib/config/MidnightConfigListWidget.java @@ -1,36 +1,35 @@ package eu.midnightdust.lib.config; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gl.RenderPipelines; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.widget.ClickableWidget; -import net.minecraft.client.gui.widget.ElementListWidget; -import net.minecraft.text.Text; - import java.util.List; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.AbstractWidget; +import net.minecraft.client.gui.components.ContainerObjectSelectionList; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.renderer.RenderPipelines; +import net.minecraft.network.chat.Component; -public class MidnightConfigListWidget extends ElementListWidget { +public class MidnightConfigListWidget extends ContainerObjectSelectionList { public boolean renderHeaderSeparator = true; - public MidnightConfigListWidget(MinecraftClient client, int width, int height, int y, int itemHeight) { + public MidnightConfigListWidget(Minecraft client, int width, int height, int y, int itemHeight) { super(client, width, height, y, itemHeight); } @Override - public int getScrollbarX() { + public int scrollBarX() { return this.width - 7; } @Override - public void drawHeaderAndFooterSeparators(DrawContext context) { + public void renderListSeparators(GuiGraphics context) { if (renderHeaderSeparator) - super.drawHeaderAndFooterSeparators(context); + super.renderListSeparators(context); else - context.drawTexture(RenderPipelines.GUI_TEXTURED, this.client.world == null ? Screen.FOOTER_SEPARATOR_TEXTURE : Screen.INWORLD_FOOTER_SEPARATOR_TEXTURE, this.getX(), this.getBottom(), 0, 0, this.getWidth(), 2, 32, 2); + context.blit(RenderPipelines.GUI_TEXTURED, this.minecraft.level == null ? Screen.FOOTER_SEPARATOR : Screen.INWORLD_FOOTER_SEPARATOR, this.getX(), this.getBottom(), 0, 0, this.getWidth(), 2, 32, 2); } - public void addButton(List buttons, Text text, EntryInfo info) { + public void addButton(List buttons, Component text, EntryInfo info) { this.addEntry(new ButtonEntry(buttons, text, info)); } diff --git a/common/src/main/java/eu/midnightdust/lib/config/MidnightConfigScreen.java b/common/src/main/java/eu/midnightdust/lib/config/MidnightConfigScreen.java index dda2f58..1f7e990 100644 --- a/common/src/main/java/eu/midnightdust/lib/config/MidnightConfigScreen.java +++ b/common/src/main/java/eu/midnightdust/lib/config/MidnightConfigScreen.java @@ -1,23 +1,26 @@ package eu.midnightdust.lib.config; import com.google.common.collect.Lists; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.tab.GridScreenTab; -import net.minecraft.client.gui.tab.Tab; -import net.minecraft.client.gui.tab.TabManager; -import net.minecraft.client.gui.tooltip.Tooltip; -import net.minecraft.client.gui.widget.*; -import net.minecraft.client.input.KeyInput; -import net.minecraft.client.resource.language.I18n; -import net.minecraft.screen.ScreenTexts; -import net.minecraft.text.Style; -import net.minecraft.text.Text; -import net.minecraft.text.TranslatableTextContent; -import net.minecraft.util.Formatting; -import net.minecraft.util.Identifier; -import net.minecraft.util.Util; - +import net.minecraft.ChatFormatting; +import net.minecraft.Util; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.AbstractWidget; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.EditBox; +import net.minecraft.client.gui.components.SpriteIconButton; +import net.minecraft.client.gui.components.Tooltip; +import net.minecraft.client.gui.components.tabs.GridLayoutTab; +import net.minecraft.client.gui.components.tabs.Tab; +import net.minecraft.client.gui.components.tabs.TabManager; +import net.minecraft.client.gui.components.tabs.TabNavigationBar; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.input.KeyEvent; +import net.minecraft.client.resources.language.I18n; +import net.minecraft.network.chat.CommonComponents; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.Style; +import net.minecraft.network.chat.contents.TranslatableContents; +import net.minecraft.resources.ResourceLocation; import javax.swing.*; import javax.swing.filechooser.FileNameExtensionFilter; import java.awt.*; @@ -35,12 +38,12 @@ public class MidnightConfigScreen extends Screen { public TabManager tabManager = new TabManager(a -> {}, a -> {}); public Map tabs = new LinkedHashMap<>(); public Tab prevTab; - public TabNavigationWidget tabNavigation; - public ButtonWidget done; + public TabNavigationBar tabNavigation; + public Button done; public double scrollProgress = 0d; public MidnightConfigScreen(Screen parent, String modid) { - super(Text.translatable(modid + ".midnightconfig.title")); + super(Component.translatable(modid + ".midnightconfig.title")); this.parent = parent; this.modid = modid; this.translationPrefix = modid + ".midnightconfig."; @@ -50,17 +53,17 @@ public class MidnightConfigScreen extends Screen { if (Objects.equals(info.modid, modid)) { String tabId = info.entry != null ? info.entry.category() : info.comment.category(); String name = translationPrefix + "category." + tabId; - if (!I18n.hasTranslation(name) && tabId.equals("default")) + if (!I18n.exists(name) && tabId.equals("default")) name = translationPrefix + "title"; if (!tabs.containsKey(name)) { - info.tab = new GridScreenTab(Text.translatable(name)); + info.tab = new GridLayoutTab(Component.translatable(name)); tabs.put(name, info.tab); } else info.tab = tabs.get(name); } }); - tabNavigation = TabNavigationWidget.builder(tabManager, this.width).tabs(tabs.values().toArray(new Tab[0])).build(); + tabNavigation = TabNavigationBar.builder(tabManager, this.width).addTabs(tabs.values().toArray(new Tab[0])).build(); tabNavigation.selectTab(0, false); - tabNavigation.init(); + tabNavigation.arrangeElements(); prevTab = tabManager.getCurrentTab(); } @@ -71,9 +74,9 @@ public class MidnightConfigScreen extends Screen { if (prevTab != null && prevTab != tabManager.getCurrentTab()) { prevTab = tabManager.getCurrentTab(); updateList(); - list.setScrollY(0); + list.setScrollAmount(0); } - scrollProgress = list.getScrollY(); + scrollProgress = list.scrollAmount(); for (EntryInfo info : MidnightConfig.entries.values()) if (Objects.equals(modid, info.modid)) info.updateFieldValue(); updateButtons(); @@ -88,22 +91,22 @@ public class MidnightConfigScreen extends Screen { for (ButtonEntry entry : this.list.children()) { if (entry.buttons != null && entry.buttons.size() > 1 && entry.info.field != null) { - if (entry.buttons.get(0) instanceof ClickableWidget widget) + if (entry.buttons.get(0) instanceof AbstractWidget widget) if (widget.isFocused() || widget.isHovered()) widget.setTooltip(entry.info.getTooltip(true)); - if (entry.buttons.get(1) instanceof ButtonWidget button) + if (entry.buttons.get(1) instanceof Button button) button.active = !Objects.equals(String.valueOf(entry.info.value), String.valueOf(entry.info.defaultValue)) && entry.info.conditionsMet; } } } @Override - public boolean keyPressed(KeyInput input) { + public boolean keyPressed(KeyEvent input) { return this.tabNavigation.keyPressed(input) || super.keyPressed(input); } @Override - public void close() { + public void onClose() { instance.loadValuesFromJson(); MidnightConfig.entries.values().forEach(info -> { info.error = null; @@ -114,28 +117,28 @@ public class MidnightConfigScreen extends Screen { info.tab = null; info.inLimits = true; }); - Objects.requireNonNull(client).setScreen(parent); + Objects.requireNonNull(minecraft).setScreen(parent); } @Override public void init() { super.init(); tabNavigation.setWidth(this.width); - tabNavigation.init(); + tabNavigation.arrangeElements(); if (tabs.size() > 1) - this.addDrawableChild(tabNavigation); + this.addRenderableWidget(tabNavigation); - this.addDrawableChild(ButtonWidget.builder(ScreenTexts.CANCEL, button -> this.close()).dimensions(this.width / 2 - 154, this.height - 26, 150, 20).build()); - done = this.addDrawableChild(ButtonWidget.builder(ScreenTexts.DONE, (button) -> { + this.addRenderableWidget(Button.builder(CommonComponents.GUI_CANCEL, button -> this.onClose()).bounds(this.width / 2 - 154, this.height - 26, 150, 20).build()); + done = this.addRenderableWidget(Button.builder(CommonComponents.GUI_DONE, (button) -> { for (EntryInfo info : MidnightConfig.entries.values()) if (info.modid.equals(modid)) info.updateFieldValue(); MidnightConfig.write(modid); - close(); - }).dimensions(this.width / 2 + 4, this.height - 26, 150, 20).build()); + onClose(); + }).bounds(this.width / 2 + 4, this.height - 26, 150, 20).build()); - this.list = new MidnightConfigListWidget(this.client, this.width, this.height - 57, 24, 25); - this.addSelectableChild(this.list); + this.list = new MidnightConfigListWidget(this.minecraft, this.width, this.height - 57, 24, 25); + this.addWidget(this.list); updateList(); if (tabs.size() > 1) list.renderHeaderSeparator = false; @@ -143,8 +146,8 @@ public class MidnightConfigScreen extends Screen { public void updateList() { this.list.clear(); - instance.onTabInit(prevTab.getTitle().getContent() instanceof TranslatableTextContent translatable ? - translatable.getKey().substring(translatable.getKey().lastIndexOf('.') + 1) : prevTab.getTitle().toString(), list, this); + instance.onTabInit(prevTab.getTabTitle().getContents() instanceof TranslatableContents translatable ? + translatable.getKey().substring(translatable.getKey().lastIndexOf('.') + 1) : prevTab.getTabTitle().toString(), list, this); for (EntryInfo info : MidnightConfig.entries.values()) { info.updateConditions(); if (!info.conditionsMet) { @@ -154,85 +157,85 @@ public class MidnightConfigScreen extends Screen { if (!visibleButLocked) continue; } if (info.modid.equals(modid) && (info.tab == null || info.tab == tabManager.getCurrentTab())) { - TextIconButtonWidget resetButton = TextIconButtonWidget.builder(Text.translatable("controls.reset"), (button -> { + SpriteIconButton resetButton = SpriteIconButton.builder(Component.translatable("controls.reset"), (button -> { info.value = info.defaultValue; info.listIndex = 0; info.tempValue = info.toTemporaryValue(); updateList(); - }), true).texture(Identifier.of("midnightlib", "icon/reset"), 12, 12).dimension(20, 20).build(); + }), true).sprite(ResourceLocation.fromNamespaceAndPath("midnightlib", "icon/reset"), 12, 12).size(20, 20).build(); resetButton.setPosition(width - 205 + 150 + 25, 0); if (info.function != null) { - ClickableWidget widget; + AbstractWidget widget; MidnightConfig.Entry e = info.entry; if (info.function instanceof Map.Entry) { // Enums & booleans - var values = (Map.Entry>) info.function; + var values = (Map.Entry>) info.function; if (info.dataType.isEnum()) { values.setValue(value -> instance.getEnumTranslatableText(value, info)); } - widget = ButtonWidget.builder(values.getValue().apply(info.value), values.getKey()).dimensions(width - 185, 0, 150, 20).tooltip(info.getTooltip(true)).build(); + widget = Button.builder(values.getValue().apply(info.value), values.getKey()).bounds(width - 185, 0, 150, 20).tooltip(info.getTooltip(true)).build(); } else if (e.isSlider()) - widget = new MidnightSliderWidget(width - 185, 0, 150, 20, Text.of(info.tempValue), (Double.parseDouble(info.tempValue) - e.min()) / (e.max() - e.min()), info); + widget = new MidnightSliderWidget(width - 185, 0, 150, 20, Component.nullToEmpty(info.tempValue), (Double.parseDouble(info.tempValue) - e.min()) / (e.max() - e.min()), info); else - widget = new TextFieldWidget(textRenderer, width - 185, 0, 150, 20, Text.empty()); + widget = new EditBox(font, width - 185, 0, 150, 20, Component.empty()); - if (widget instanceof TextFieldWidget textField) { + if (widget instanceof EditBox textField) { textField.setMaxLength(e.width()); - textField.setText(info.tempValue); - Predicate processor = ((BiFunction>) info.function).apply(textField, done); - textField.setTextPredicate(processor); + textField.setValue(info.tempValue); + Predicate processor = ((BiFunction>) info.function).apply(textField, done); + textField.setFilter(processor); } widget.setTooltip(info.getTooltip(true)); - ButtonWidget cycleButton = null; + Button cycleButton = null; if (info.field.getType() == List.class) { - cycleButton = ButtonWidget.builder(Text.literal(String.valueOf(info.listIndex)).formatted(Formatting.GOLD), (button -> { + cycleButton = Button.builder(Component.literal(String.valueOf(info.listIndex)).withStyle(ChatFormatting.GOLD), (button -> { var values = (List) info.value; values.remove(""); info.listIndex = info.listIndex != values.size() ? info.listIndex + 1 : 0; info.tempValue = info.listIndex != values.size() ? info.toTemporaryValue() : ""; updateList(); - })).dimensions(width - 185, 0, 20, 20).tooltip(Tooltip.of(Text.translatable("midnightconfig.action.list_index", info.listIndex))).build(); + })).bounds(width - 185, 0, 20, 20).tooltip(Tooltip.create(Component.translatable("midnightconfig.action.list_index", info.listIndex))).build(); } if (e.isColor()) { - ButtonWidget colorButton = ButtonWidget.builder(Text.literal("⬛"), + Button colorButton = Button.builder(Component.literal("⬛"), button -> new Thread(() -> { - Color newColor = JColorChooser.showDialog(null, Text.translatable("midnightconfig.colorChooser.title").getString(), Color.decode(!Objects.equals(info.tempValue, "") ? info.tempValue : "#FFFFFF")); + Color newColor = JColorChooser.showDialog(null, Component.translatable("midnightconfig.colorChooser.title").getString(), Color.decode(!Objects.equals(info.tempValue, "") ? info.tempValue : "#FFFFFF")); if (newColor != null) { info.setValue("#" + Integer.toHexString(newColor.getRGB()).substring(2)); updateList(); } }).start() - ).dimensions(width - 185, 0, 20, 20).tooltip(Tooltip.of(Text.translatable("midnightconfig.action.color_chooser"))).build(); + ).bounds(width - 185, 0, 20, 20).tooltip(Tooltip.create(Component.translatable("midnightconfig.action.color_chooser"))).build(); try { - colorButton.setMessage(Text.literal("⬛").setStyle(Style.EMPTY.withColor(Color.decode(info.tempValue).getRGB()))); + colorButton.setMessage(Component.literal("⬛").setStyle(Style.EMPTY.withColor(Color.decode(info.tempValue).getRGB()))); } catch (Exception ignored) { } info.actionButton = colorButton; } else if (e.selectionMode() > -1) { - ButtonWidget explorerButton = TextIconButtonWidget.builder(Text.empty(), + Button explorerButton = SpriteIconButton.builder(Component.empty(), button -> new Thread(() -> { JFileChooser fileChooser = new JFileChooser(info.tempValue); fileChooser.setFileSelectionMode(e.selectionMode()); fileChooser.setDialogType(e.fileChooserType()); - fileChooser.setDialogTitle(Text.translatable(translationPrefix + info.fieldName + ".fileChooser").getString()); + fileChooser.setDialogTitle(Component.translatable(translationPrefix + info.fieldName + ".fileChooser").getString()); if ((e.selectionMode() == JFileChooser.FILES_ONLY || e.selectionMode() == JFileChooser.FILES_AND_DIRECTORIES) && Arrays.stream(e.fileExtensions()).noneMatch("*"::equals)) fileChooser.setFileFilter(new FileNameExtensionFilter( - Text.translatable(translationPrefix + info.fieldName + ".fileFilter").getString(), e.fileExtensions())); + Component.translatable(translationPrefix + info.fieldName + ".fileFilter").getString(), e.fileExtensions())); if (fileChooser.showDialog(null, null) == JFileChooser.APPROVE_OPTION) { info.setValue(fileChooser.getSelectedFile().getAbsolutePath()); updateList(); } }).start(), true - ).texture(Identifier.of("midnightlib", "icon/explorer"), 12, 12).dimension(20, 20).build(); - explorerButton.setTooltip(Tooltip.of(Text.translatable("midnightconfig.action.file_chooser"))); + ).sprite(ResourceLocation.fromNamespaceAndPath("midnightlib", "icon/explorer"), 12, 12).size(20, 20).build(); + explorerButton.setTooltip(Tooltip.create(Component.translatable("midnightconfig.action.file_chooser"))); explorerButton.setPosition(width - 185, 0); info.actionButton = explorerButton; } - List widgets = Lists.newArrayList(widget, resetButton); + List widgets = Lists.newArrayList(widget, resetButton); if (info.actionButton != null) { - if (Util.getOperatingSystem() == Util.OperatingSystem.OSX) info.actionButton.active = false; + if (Util.getPlatform() == Util.OS.OSX) info.actionButton.active = false; widget.setWidth(widget.getWidth() - 22); widget.setX(widget.getX() + 22); widgets.add(info.actionButton); @@ -244,18 +247,18 @@ public class MidnightConfigScreen extends Screen { widgets.add(cycleButton); } if (!info.conditionsMet) widgets.forEach(w -> w.active = false); - this.list.addButton(widgets, Text.translatable(info.translationKey), info); - } else this.list.addButton(List.of(), Text.translatable(info.translationKey), info); + this.list.addButton(widgets, Component.translatable(info.translationKey), info); + } else this.list.addButton(List.of(), Component.translatable(info.translationKey), info); } - list.setScrollY(scrollProgress); + list.setScrollAmount(scrollProgress); updateButtons(); } } @Override - public void render(DrawContext context, int mouseX, int mouseY, float delta) { + public void render(GuiGraphics context, int mouseX, int mouseY, float delta) { super.render(context, mouseX, mouseY, delta); this.list.render(context, mouseX, mouseY, delta); - if (tabs.size() < 2) context.drawCenteredTextWithShadow(textRenderer, title, width / 2, 10, 0xFFFFFFFF); + if (tabs.size() < 2) context.drawCenteredString(font, title, width / 2, 10, 0xFFFFFFFF); } } diff --git a/common/src/main/java/eu/midnightdust/lib/config/MidnightSliderWidget.java b/common/src/main/java/eu/midnightdust/lib/config/MidnightSliderWidget.java index 0a04c10..0759f3b 100644 --- a/common/src/main/java/eu/midnightdust/lib/config/MidnightSliderWidget.java +++ b/common/src/main/java/eu/midnightdust/lib/config/MidnightSliderWidget.java @@ -1,13 +1,13 @@ package eu.midnightdust.lib.config; -import net.minecraft.client.gui.widget.SliderWidget; -import net.minecraft.text.Text; +import net.minecraft.client.gui.components.AbstractSliderButton; +import net.minecraft.network.chat.Component; -public class MidnightSliderWidget extends SliderWidget { +public class MidnightSliderWidget extends AbstractSliderButton { private final EntryInfo info; private final MidnightConfig.Entry e; - public MidnightSliderWidget(int x, int y, int width, int height, Text text, double value, EntryInfo info) { + public MidnightSliderWidget(int x, int y, int width, int height, Component text, double value, EntryInfo info) { super(x, y, width, height, text, value); this.e = info.entry; this.info = info; @@ -15,7 +15,7 @@ public class MidnightSliderWidget extends SliderWidget { @Override public void updateMessage() { - this.setMessage(Text.of(info.tempValue)); + this.setMessage(Component.nullToEmpty(info.tempValue)); } @Override diff --git a/common/src/main/java/eu/midnightdust/lib/util/MidnightColorUtil.java b/common/src/main/java/eu/midnightdust/lib/util/MidnightColorUtil.java old mode 100755 new mode 100644 diff --git a/common/src/main/java/eu/midnightdust/lib/util/PlatformFunctions.java b/common/src/main/java/eu/midnightdust/lib/util/PlatformFunctions.java index aabefb3..1707e3b 100644 --- a/common/src/main/java/eu/midnightdust/lib/util/PlatformFunctions.java +++ b/common/src/main/java/eu/midnightdust/lib/util/PlatformFunctions.java @@ -2,9 +2,8 @@ package eu.midnightdust.lib.util; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import dev.architectury.injectables.annotations.ExpectPlatform; -import net.minecraft.server.command.ServerCommandSource; - import java.nio.file.Path; +import net.minecraft.commands.CommandSourceStack; public class PlatformFunctions { @ExpectPlatform @@ -28,7 +27,7 @@ public class PlatformFunctions { throw new AssertionError(); } @ExpectPlatform - public static void registerCommand(LiteralArgumentBuilder command) { + public static void registerCommand(LiteralArgumentBuilder command) { // Just throw an error, the content should get replaced at runtime. throw new AssertionError(); } diff --git a/common/src/test/java/eu/midnightdust/test/MidnightLibExtras.java b/common/src/test/java/eu/midnightdust/test/MidnightLibExtras.java index 36de2a0..206307c 100644 --- a/common/src/test/java/eu/midnightdust/test/MidnightLibExtras.java +++ b/common/src/test/java/eu/midnightdust/test/MidnightLibExtras.java @@ -1,21 +1,21 @@ package eu.midnightdust.test; import com.google.common.collect.Lists; +import com.mojang.blaze3d.platform.InputConstants; import eu.midnightdust.lib.config.EntryInfo; import eu.midnightdust.lib.config.MidnightConfigListWidget; import eu.midnightdust.lib.config.MidnightConfigScreen; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.tooltip.Tooltip; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.client.gui.widget.ClickableWidget; -import net.minecraft.client.gui.widget.TextIconButtonWidget; -import net.minecraft.client.input.KeyInput; -import net.minecraft.client.option.KeyBinding; -import net.minecraft.client.util.InputUtil; -import net.minecraft.text.MutableText; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import net.minecraft.util.Identifier; +import net.minecraft.ChatFormatting; +import net.minecraft.client.KeyMapping; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.components.AbstractButton; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.SpriteIconButton; +import net.minecraft.client.gui.components.Tooltip; +import net.minecraft.client.input.KeyEvent; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.resources.ResourceLocation; import org.jetbrains.annotations.Nullable; import org.lwjgl.glfw.GLFW; @@ -24,40 +24,40 @@ import org.lwjgl.glfw.GLFW; Feel free to copy the parts you need :) */ public class MidnightLibExtras { - public static class KeybindButton extends ButtonWidget { - public static ButtonWidget focusedButton; + public static class KeybindButton extends Button { + public static Button focusedButton; - public static void add(KeyBinding binding, MidnightConfigListWidget list, MidnightConfigScreen screen) { + public static void add(KeyMapping binding, MidnightConfigListWidget list, MidnightConfigScreen screen) { KeybindButton editButton = new KeybindButton(screen.width - 185, 0, 150, 20, binding); - TextIconButtonWidget resetButton = TextIconButtonWidget.builder(Text.translatable("controls.reset"), (button -> { - binding.setBoundKey(binding.getDefaultKey()); + SpriteIconButton resetButton = SpriteIconButton.builder(Component.translatable("controls.reset"), (button -> { + binding.setKey(binding.getDefaultKey()); screen.updateList(); - }), true).texture(Identifier.of("midnightlib","icon/reset"), 12, 12).dimension(20, 20).build(); + }), true).sprite(ResourceLocation.fromNamespaceAndPath("midnightlib","icon/reset"), 12, 12).size(20, 20).build(); resetButton.setPosition(screen.width - 205 + 150 + 25, 0); editButton.resetButton = resetButton; editButton.updateMessage(false); EntryInfo info = new EntryInfo(null, screen.modid); - list.addButton(Lists.newArrayList(editButton, resetButton), Text.translatable(binding.getId()), info); + list.addButton(Lists.newArrayList(editButton, resetButton), Component.translatable(binding.getName()), info); } - private final KeyBinding binding; - private @Nullable ClickableWidget resetButton; - public KeybindButton(int x, int y, int width, int height, KeyBinding binding) { - super(x, y, width, height, binding.getBoundKeyLocalizedText(), (button) -> { + private final KeyMapping binding; + private @Nullable AbstractButton resetButton; + public KeybindButton(int x, int y, int width, int height, KeyMapping binding) { + super(x, y, width, height, binding.getTranslatedKeyMessage(), (button) -> { ((KeybindButton) button).updateMessage(true); focusedButton = button; - }, (textSupplier) -> binding.isUnbound() ? Text.translatable("narrator.controls.unbound", binding.getId()) : Text.translatable("narrator.controls.bound", binding.getId(), textSupplier.get())); + }, (textSupplier) -> binding.isUnbound() ? Component.translatable("narrator.controls.unbound", binding.getName()) : Component.translatable("narrator.controls.bound", binding.getName(), textSupplier.get())); this.binding = binding; updateMessage(false); } @Override - public boolean keyPressed(KeyInput input) { + public boolean keyPressed(KeyEvent input) { if (focusedButton == this) { if (input.key() == GLFW.GLFW_KEY_ESCAPE) { - this.binding.setBoundKey(InputUtil.UNKNOWN_KEY); + this.binding.setKey(InputConstants.UNKNOWN); } else { - this.binding.setBoundKey(InputUtil.fromKeyCode(input)); + this.binding.setKey(InputConstants.getKey(input)); } updateMessage(false); @@ -69,18 +69,18 @@ public class MidnightLibExtras { public void updateMessage(boolean focused) { boolean hasConflicts = false; - MutableText conflictingBindings = Text.empty(); - if (focused) this.setMessage(Text.literal("> ").append(this.binding.getBoundKeyLocalizedText().copy().formatted(Formatting.WHITE, Formatting.UNDERLINE)).append(" <").formatted(Formatting.YELLOW)); + MutableComponent conflictingBindings = Component.empty(); + if (focused) this.setMessage(Component.literal("> ").append(this.binding.getTranslatedKeyMessage().copy().withStyle(ChatFormatting.WHITE, ChatFormatting.UNDERLINE)).append(" <").withStyle(ChatFormatting.YELLOW)); else { - this.setMessage(this.binding.getBoundKeyLocalizedText()); + this.setMessage(this.binding.getTranslatedKeyMessage()); if (!this.binding.isUnbound()) { - for(KeyBinding keyBinding : MinecraftClient.getInstance().options.allKeys) { + for(KeyMapping keyBinding : Minecraft.getInstance().options.keyMappings) { if (keyBinding != this.binding && this.binding.equals(keyBinding)) { if (hasConflicts) conflictingBindings.append(", "); hasConflicts = true; - conflictingBindings.append(Text.translatable(keyBinding.getId())); + conflictingBindings.append(Component.translatable(keyBinding.getName())); } } } @@ -89,8 +89,8 @@ public class MidnightLibExtras { if (this.resetButton != null) this.resetButton.active = !this.binding.isDefault(); if (hasConflicts) { - this.setMessage(Text.literal("[ ").append(this.getMessage().copy().formatted(Formatting.WHITE)).append(" ]").formatted(Formatting.RED)); - this.setTooltip(Tooltip.of(Text.translatable("controls.keybinds.duplicateKeybinds", conflictingBindings))); + this.setMessage(Component.literal("[ ").append(this.getMessage().copy().withStyle(ChatFormatting.WHITE)).append(" ]").withStyle(ChatFormatting.RED)); + this.setTooltip(Tooltip.create(Component.translatable("controls.keybinds.duplicateKeybinds", conflictingBindings))); } else { this.setTooltip(null); } diff --git a/common/src/test/java/eu/midnightdust/test/config/MidnightConfigExample.java b/common/src/test/java/eu/midnightdust/test/config/MidnightConfigExample.java index a2a249c..5d8ed09 100644 --- a/common/src/test/java/eu/midnightdust/test/config/MidnightConfigExample.java +++ b/common/src/test/java/eu/midnightdust/test/config/MidnightConfigExample.java @@ -5,12 +5,13 @@ import eu.midnightdust.lib.config.MidnightConfigListWidget; import eu.midnightdust.lib.config.MidnightConfigScreen; import eu.midnightdust.test.MidnightLibExtras; import eu.midnightdust.lib.config.MidnightConfig; -import net.minecraft.text.MutableText; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import net.minecraft.client.MinecraftClient; -import net.minecraft.util.Identifier; -import net.minecraft.util.TranslatableOption; +import net.minecraft.ChatFormatting; +import net.minecraft.client.Minecraft; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.OptionEnum; +import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.util.ArrayList; @@ -36,7 +37,7 @@ public class MidnightConfigExample extends MidnightConfig { @Entry(category = TEXT, name="I am a (non-primitive) Boolean") public static Boolean nonPrimitive = true; // Example for a non-primative boolean option @Entry(category = TEXT) public static String name = "Hello World!"; // Example for a string option, which is in a category! @Entry(category = TEXT, width = 7, min = 7, isColor = true, name = "I am a color!") public static String titleColor = "#ffffff"; // The isColor property adds a color chooser for a hexadecimal color - @Entry(category = TEXT, idMode = 0) public static Identifier id = Identifier.ofVanilla("diamond"); // Example for an identifier with matching items displayed next to it! + @Entry(category = TEXT, idMode = 0) public static ResourceLocation id = ResourceLocation.withDefaultNamespace("diamond"); // Example for an identifier with matching items displayed next to it! @Entry(category = TEXT) public static ModPlatform modPlatform = ModPlatform.FABRIC; // Example for an enum option public enum ModPlatform { // Enums allow the user to cycle through predefined options QUILT, FABRIC, FORGE, NEOFORGE, VANILLA @@ -54,7 +55,7 @@ public class MidnightConfigExample extends MidnightConfig { // The name field can be used to specify a custom translation string or plain text @Entry(category = LISTS, name = "I am a string list!") public static List stringList = Lists.newArrayList("String1", "String2"); // Array String Lists are also supported @Entry(category = LISTS, isColor = true, name = "I am a color list!") public static List colorList = Lists.newArrayList("#ac5f99", "#11aa44"); // Lists also support colors - @Entry(category = LISTS, name = "I am an identifier list!", idMode = 1) public static List idList = Lists.newArrayList(Identifier.ofVanilla("dirt")); // A list of block identifiers + @Entry(category = LISTS, name = "I am an identifier list!", idMode = 1) public static List idList = Lists.newArrayList(ResourceLocation.withDefaultNamespace("dirt")); // A list of block identifiers @Entry(category = LISTS, name = "I am an integer list!") public static List intList = Lists.newArrayList(69, 420); @Entry(category = LISTS, name = "I am a float list!") public static List floatList = Lists.newArrayList(4.1f, -1.3f, -1f); @@ -128,7 +129,7 @@ public class MidnightConfigExample extends MidnightConfig { public static int imposter = 16777215; // - Entries without an @Entry or @Comment annotation are ignored - public enum GraphicsSteps implements TranslatableOption { + public enum GraphicsSteps implements OptionEnum { FAST(0, "options.graphics.fast"), FANCY(1, "options.graphics.fancy"), FABULOUS(2, "options.graphics.fabulous"); @@ -142,9 +143,9 @@ public class MidnightConfigExample extends MidnightConfig { } @Override - public Text getText() { - MutableText mutableText = Text.translatable(this.getTranslationKey()); - return this == GraphicsSteps.FABULOUS ? mutableText.formatted(Formatting.ITALIC).formatted(Formatting.AQUA) : mutableText; + public @NotNull Component getCaption() { + MutableComponent mutableText = Component.translatable(this.getKey()); + return this == GraphicsSteps.FABULOUS ? mutableText.withStyle(ChatFormatting.ITALIC, ChatFormatting.AQUA) : mutableText; } @Override @@ -153,7 +154,7 @@ public class MidnightConfigExample extends MidnightConfig { } @Override - public String getTranslationKey() { + public @NotNull String getKey() { return this.translationKey; } } @@ -164,8 +165,8 @@ public class MidnightConfigExample extends MidnightConfig { @Override public void onTabInit(String tabName, MidnightConfigListWidget list, MidnightConfigScreen screen) { if (Objects.equals(tabName, EXTRAS)) { - MidnightLibExtras.KeybindButton.add(MinecraftClient.getInstance().options.advancementsKey, list, screen); - MidnightLibExtras.KeybindButton.add(MinecraftClient.getInstance().options.dropKey, list, screen); + MidnightLibExtras.KeybindButton.add(Minecraft.getInstance().options.keyAdvancements, list, screen); + MidnightLibExtras.KeybindButton.add(Minecraft.getInstance().options.keyDrop, list, screen); } } diff --git a/fabric/src/main/java/eu/midnightdust/lib/config/AutoModMenu.java b/fabric/src/main/java/eu/midnightdust/lib/config/AutoModMenu.java old mode 100755 new mode 100644 diff --git a/fabric/src/main/java/eu/midnightdust/lib/util/fabric/PlatformFunctionsImpl.java b/fabric/src/main/java/eu/midnightdust/lib/util/fabric/PlatformFunctionsImpl.java index 5615bd8..f0bdfb8 100644 --- a/fabric/src/main/java/eu/midnightdust/lib/util/fabric/PlatformFunctionsImpl.java +++ b/fabric/src/main/java/eu/midnightdust/lib/util/fabric/PlatformFunctionsImpl.java @@ -5,8 +5,7 @@ import eu.midnightdust.lib.util.PlatformFunctions; import net.fabricmc.api.EnvType; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; import net.fabricmc.loader.api.FabricLoader; -import net.minecraft.server.command.ServerCommandSource; - +import net.minecraft.commands.CommandSourceStack; import java.nio.file.Path; public class PlatformFunctionsImpl { @@ -25,7 +24,7 @@ public class PlatformFunctionsImpl { public static boolean isModLoaded(String modid) { return FabricLoader.getInstance().isModLoaded(modid); } - public static void registerCommand(LiteralArgumentBuilder command) { + public static void registerCommand(LiteralArgumentBuilder command) { CommandRegistrationCallback.EVENT.register((dispatcher, dedicated, registrationEnvironment) -> dispatcher.register(command)); } } diff --git a/gradle.properties b/gradle.properties index 82a98a1..f2f1f95 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,8 +1,8 @@ org.gradle.jvmargs=-Xmx3172M -minecraft_version=1.21.9 -supported_versions= -yarn_mappings=1.21.9+build.1 +minecraft_version=1.21.10 +supported_versions=1.21.9 +yarn_mappings=1.21.10+build.2 enabled_platforms=fabric,neoforge archives_base_name=midnightlib @@ -12,10 +12,10 @@ release_type=release curseforge_id=488090 modrinth_id=codAaoxh -fabric_loader_version=0.17.2 -fabric_api_version=0.133.14+1.21.9 +fabric_loader_version=0.17.3 +fabric_api_version=0.138.0+1.21.10 -neoforge_version=21.9.9-beta +neoforge_version=21.10.47-beta yarn_mappings_patch_neoforge_version = 1.21+build.4 mod_menu_version = 9.0.0 \ No newline at end of file diff --git a/neoforge/src/main/java/eu/midnightdust/lib/util/neoforge/PlatformFunctionsImpl.java b/neoforge/src/main/java/eu/midnightdust/lib/util/neoforge/PlatformFunctionsImpl.java index c6ea4c9..026b70e 100644 --- a/neoforge/src/main/java/eu/midnightdust/lib/util/neoforge/PlatformFunctionsImpl.java +++ b/neoforge/src/main/java/eu/midnightdust/lib/util/neoforge/PlatformFunctionsImpl.java @@ -2,7 +2,7 @@ package eu.midnightdust.lib.util.neoforge; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import eu.midnightdust.lib.util.PlatformFunctions; -import net.minecraft.server.command.ServerCommandSource; +import net.minecraft.commands.CommandSourceStack; import net.neoforged.fml.ModList; import net.neoforged.fml.loading.FMLEnvironment; import net.neoforged.fml.loading.FMLPaths; @@ -27,7 +27,7 @@ public class PlatformFunctionsImpl { public static boolean isModLoaded(String modid) { return ModList.get().isLoaded(modid); } - public static void registerCommand(LiteralArgumentBuilder command) { + public static void registerCommand(LiteralArgumentBuilder command) { commands.add(command); } } diff --git a/neoforge/src/main/java/eu/midnightdust/neoforge/MidnightLibNeoForge.java b/neoforge/src/main/java/eu/midnightdust/neoforge/MidnightLibNeoForge.java index 2ccbb3f..4ffaec0 100644 --- a/neoforge/src/main/java/eu/midnightdust/neoforge/MidnightLibNeoForge.java +++ b/neoforge/src/main/java/eu/midnightdust/neoforge/MidnightLibNeoForge.java @@ -3,7 +3,7 @@ package eu.midnightdust.neoforge; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import eu.midnightdust.core.MidnightLib; import eu.midnightdust.lib.config.MidnightConfig; -import net.minecraft.server.command.ServerCommandSource; +import net.minecraft.commands.CommandSourceStack; import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.ModList; @@ -20,7 +20,7 @@ import java.util.List; @Mod("midnightlib") public class MidnightLibNeoForge { - public static List> commands = new ArrayList<>(); + public static List> commands = new ArrayList<>(); public MidnightLibNeoForge() { if (FMLEnvironment.getDist() == Dist.CLIENT) MidnightLib.onInitializeClient();