diff --git a/src/main/java/moe/caa/fabric/quitconfirm/client/config/Config.java b/src/main/java/moe/caa/fabric/quitconfirm/client/config/Config.java index e69d18f..dbe73f5 100644 --- a/src/main/java/moe/caa/fabric/quitconfirm/client/config/Config.java +++ b/src/main/java/moe/caa/fabric/quitconfirm/client/config/Config.java @@ -13,9 +13,9 @@ public class Config { private static final Gson gson = new Gson(); private static final Path path = Path.of("config/quitconfirm.json"); - public ConfirmType confirmTypeInFinalQuit = ConfirmType.SCREEN; - public ConfirmType confirmTypeInSinglePlayer = ConfirmType.TOAST; - public ConfirmType confirmTypeInMultiplayer = ConfirmType.TOAST; + public ConfirmTypeEnum confirmTypeInFinalQuit = ConfirmTypeEnum.SCREEN; + public ConfirmTypeEnum confirmTypeInSinglePlayer = ConfirmTypeEnum.TOAST; + public ConfirmTypeEnum confirmTypeInMultiplayer = ConfirmTypeEnum.TOAST; public boolean enableScreenShortcutKey = true; public long keepDarkInConfirmScreenTime = 1000L; public ConfirmScreenDisplayTypeEnum confirmScreenDisplayType = ConfirmScreenDisplayTypeEnum.BEDROCK; @@ -23,9 +23,9 @@ public class Config { public long toastConfirmStartAliveTime = 500L; public long toastConfirmEndAliveTime = 5000L; - public static void load(){ + public static void load() { try { - if (Files.notExists(path)){ + if (Files.notExists(path)) { save(); return; } @@ -35,7 +35,7 @@ public static void load(){ } } - public static void save(){ + public static void save() { try { Files.writeString(path, gson.toJson(config), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); } catch (IOException e) { @@ -43,9 +43,14 @@ public static void save(){ } } + public > T nextEnum(Class tClass, T value) { + int ordinal = value.ordinal(); + T[] constants = tClass.getEnumConstants(); + return constants[(ordinal + 1) % constants.length]; + } + public enum ConfirmScreenDisplayTypeEnum { CLASSIC("经典"), - CLASSIC_OPAQUE("经典(不透明)"), BEDROCK("基岩"), BEDROCK_OPAQUE("基岩(不透明)"); public final String displayName; @@ -56,13 +61,13 @@ public enum ConfirmScreenDisplayTypeEnum { } - public enum ConfirmType { + public enum ConfirmTypeEnum { TOAST("土司"), SCREEN("屏幕"), NONE("关闭"); public final String displayName; - ConfirmType(String displayName) { + ConfirmTypeEnum(String displayName) { this.displayName = displayName; } } diff --git a/src/main/java/moe/caa/fabric/quitconfirm/client/main/QuitConfirm.java b/src/main/java/moe/caa/fabric/quitconfirm/client/main/QuitConfirm.java index e1d9e70..8f87cb0 100644 --- a/src/main/java/moe/caa/fabric/quitconfirm/client/main/QuitConfirm.java +++ b/src/main/java/moe/caa/fabric/quitconfirm/client/main/QuitConfirm.java @@ -24,10 +24,10 @@ public class QuitConfirm implements ClientModInitializer { public void onInitializeClient() { Config.load(); ClientScheduleStopEvent.CLIENT_SCHEDULE_STOP.register(() -> { - if (Config.config.confirmTypeInFinalQuit == Config.ConfirmType.TOAST) { + if (Config.config.confirmTypeInFinalQuit == Config.ConfirmTypeEnum.TOAST) { return toastInFinalQuitHandler.trigger(); } - if (Config.config.confirmTypeInFinalQuit == Config.ConfirmType.SCREEN) { + if (Config.config.confirmTypeInFinalQuit == Config.ConfirmTypeEnum.SCREEN) { return toastInFinalQuitHandler.trigger(); } return EventResult.PASS; diff --git a/src/main/java/moe/caa/fabric/quitconfirm/client/modmenu/QuitConfirmModMenu.java b/src/main/java/moe/caa/fabric/quitconfirm/client/modmenu/QuitConfirmModMenu.java index d17007c..8b16fd6 100644 --- a/src/main/java/moe/caa/fabric/quitconfirm/client/modmenu/QuitConfirmModMenu.java +++ b/src/main/java/moe/caa/fabric/quitconfirm/client/modmenu/QuitConfirmModMenu.java @@ -2,7 +2,7 @@ import com.terraformersmc.modmenu.api.ConfigScreenFactory; import com.terraformersmc.modmenu.api.ModMenuApi; -import moe.caa.fabric.quitconfirm.client.screen.SettingScreen; +import moe.caa.fabric.quitconfirm.client.screen.setting.SettingScreen; import net.minecraft.client.gui.screen.Screen; public class QuitConfirmModMenu implements ModMenuApi { diff --git a/src/main/java/moe/caa/fabric/quitconfirm/client/screen/SettingScreen.java b/src/main/java/moe/caa/fabric/quitconfirm/client/screen/SettingScreen.java deleted file mode 100644 index b0321ba..0000000 --- a/src/main/java/moe/caa/fabric/quitconfirm/client/screen/SettingScreen.java +++ /dev/null @@ -1,50 +0,0 @@ -package moe.caa.fabric.quitconfirm.client.screen; - -import moe.caa.fabric.quitconfirm.client.config.Config; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.text.MutableText; -import net.minecraft.text.Text; - -public class SettingScreen extends Screen { - private final Screen parentScreen; - - public SettingScreen(Screen screen) { - super(Text.literal("设置")); - parentScreen = screen; - } - - @Override - protected void init() { - SettingElementListWidget listWidget = new SettingElementListWidget(this.client, this.width, this.height, 30 /* 上边距 */, height - 40/* 下边距 */, 24); - - listWidget.addEntry(listWidget.new CategoryEntry(Text.literal("设置退出二次确认的方式"), 11184810)); - - listWidget.addEntry(listWidget.new ButtonListEntry(ButtonWidget - .builder(Text.literal(Config.ConfirmType.TOAST.displayName), (button) -> {}) - .dimensions(0, 0, 35, 20).build(), Text.literal("关闭游戏窗口时的确认方式"))); - listWidget.addEntry(listWidget.new ButtonListEntry(ButtonWidget - .builder(Text.literal(Config.ConfirmType.TOAST.displayName), (button) -> {}) - .dimensions(0, 0, 35, 20).build(), Text.literal("退出单人游戏时的确认方式"))); - listWidget.addEntry(listWidget.new ButtonListEntry(ButtonWidget - .builder(Text.literal(Config.ConfirmType.TOAST.displayName), (button) -> {}) - .dimensions(0, 0, 35, 20).build(), Text.literal("退出多人游戏时的确认方式"))); - - this.addDrawableChild(listWidget); - } - - @Override - public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { - super.render(matrices, mouseX, mouseY, delta); - drawCenteredTextWithShadow(matrices, this.textRenderer, this.title, this.width / 2, 15, 16777215); - - MutableText literal = Text.literal("QuitConfirm"); - drawTextWithShadow(matrices, textRenderer, literal, 2, this.height - textRenderer.fontHeight, 5592405); - } - - @Override - public void close() { - client.setScreen(parentScreen); - } -} diff --git a/src/main/java/moe/caa/fabric/quitconfirm/client/screen/SettingElementListWidget.java b/src/main/java/moe/caa/fabric/quitconfirm/client/screen/setting/SettingElementListWidget.java similarity index 75% rename from src/main/java/moe/caa/fabric/quitconfirm/client/screen/SettingElementListWidget.java rename to src/main/java/moe/caa/fabric/quitconfirm/client/screen/setting/SettingElementListWidget.java index 653ba32..7ce4da6 100644 --- a/src/main/java/moe/caa/fabric/quitconfirm/client/screen/SettingElementListWidget.java +++ b/src/main/java/moe/caa/fabric/quitconfirm/client/screen/setting/SettingElementListWidget.java @@ -1,4 +1,4 @@ -package moe.caa.fabric.quitconfirm.client.screen; +package moe.caa.fabric.quitconfirm.client.screen.setting; import com.google.common.collect.ImmutableList; import net.minecraft.client.MinecraftClient; @@ -8,6 +8,7 @@ import net.minecraft.client.gui.screen.narration.NarrationPart; import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.client.gui.widget.ElementListWidget; +import net.minecraft.client.gui.widget.TextFieldWidget; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.text.Text; @@ -63,6 +64,34 @@ public void render(MatrixStack matrices, int index, int y, int x, int entryWidth } } + public class InputListEntry extends Entry { + private final TextFieldWidget fieldWidget; + private final Text describeText; + + public InputListEntry(TextFieldWidget fieldWidget, Text describeText) { + this.fieldWidget = fieldWidget; + this.describeText = describeText; + } + + @Override + public List children() { + return Collections.singletonList(fieldWidget); + } + + @Override + public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { + client.textRenderer.draw(matrices, describeText, x, (int) (y + client.textRenderer.fontHeight / 2.0), 16777215); + this.fieldWidget.setX(entryWidth - fieldWidget.getWidth() + x); + this.fieldWidget.setY(y); + this.fieldWidget.render(matrices, mouseX, mouseY, tickDelta); + } + + @Override + public List selectableChildren() { + return Collections.singletonList(fieldWidget); + } + } + public class ButtonListEntry extends Entry { private final ButtonWidget button; diff --git a/src/main/java/moe/caa/fabric/quitconfirm/client/screen/setting/SettingScreen.java b/src/main/java/moe/caa/fabric/quitconfirm/client/screen/setting/SettingScreen.java new file mode 100644 index 0000000..e25fa60 --- /dev/null +++ b/src/main/java/moe/caa/fabric/quitconfirm/client/screen/setting/SettingScreen.java @@ -0,0 +1,145 @@ +package moe.caa.fabric.quitconfirm.client.screen.setting; + +import moe.caa.fabric.quitconfirm.client.config.Config; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.gui.widget.TextFieldWidget; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.screen.ScreenTexts; +import net.minecraft.text.MutableText; +import net.minecraft.text.Text; + +import java.util.function.Consumer; + +public class SettingScreen extends Screen { + private final Screen parentScreen; + private ButtonWidget back; + + public SettingScreen(Screen screen) { + super(Text.literal("设置")); + parentScreen = screen; + } + + @Override + protected void init() { + + back = ButtonWidget.builder(ScreenTexts.BACK, (button) -> { + Config.save(); + client.setScreen(parentScreen); + }).dimensions(this.width / 2 - 100, this.height - 30, 200, 20).build(); + + + SettingElementListWidget listWidget = new SettingElementListWidget(this.client, this.width, this.height, 30 /* 上边距 */, height - 40/* 下边距 */, 24); + { + MutableText category = Text.literal("设置退出二次确认的方式"); + listWidget.addEntry(listWidget.new CategoryEntry(category.setStyle(category.getStyle().withBold(true)), 11184810)); + + listWidget.addEntry(listWidget.new ButtonListEntry(ButtonWidget + .builder(Text.literal(Config.config.confirmTypeInFinalQuit.displayName), (button) -> { + Config.config.confirmTypeInFinalQuit = Config.config.nextEnum(Config.ConfirmTypeEnum.class, Config.config.confirmTypeInFinalQuit); + button.setMessage(Text.literal(Config.config.confirmTypeInFinalQuit.displayName)); + }) + .dimensions(0, 0, 40, 20).build(), Text.literal("关闭游戏窗口时的确认方式"))); + + listWidget.addEntry(listWidget.new ButtonListEntry(ButtonWidget + .builder(Text.literal(Config.config.confirmTypeInSinglePlayer.displayName), (button) -> { + Config.config.confirmTypeInSinglePlayer = Config.config.nextEnum(Config.ConfirmTypeEnum.class, Config.config.confirmTypeInSinglePlayer); + button.setMessage(Text.literal(Config.config.confirmTypeInSinglePlayer.displayName)); + }) + .dimensions(0, 0, 40, 20).build(), Text.literal("退出单人游戏时的确认方式"))); + + listWidget.addEntry(listWidget.new ButtonListEntry(ButtonWidget + .builder(Text.literal(Config.config.confirmTypeInMultiplayer.displayName), (button) -> { + Config.config.confirmTypeInMultiplayer = Config.config.nextEnum(Config.ConfirmTypeEnum.class, Config.config.confirmTypeInMultiplayer); + button.setMessage(Text.literal(Config.config.confirmTypeInMultiplayer.displayName)); + }) + .dimensions(0, 0, 40, 20).build(), Text.literal("退出多人游戏时的确认方式"))); + } + { + MutableText category = Text.literal("二次确认界面屏幕设定"); + listWidget.addEntry(listWidget.new CategoryEntry(category.setStyle(category.getStyle().withBold(true)), 11184810)); + + listWidget.addEntry(listWidget.new ButtonListEntry(ButtonWidget + .builder(Text.literal(Config.config.confirmScreenDisplayType.displayName), (button) -> { + Config.config.confirmScreenDisplayType = Config.config.nextEnum(Config.ConfirmScreenDisplayTypeEnum.class, Config.config.confirmScreenDisplayType); + button.setMessage(Text.literal(Config.config.confirmScreenDisplayType.displayName)); + }) + .dimensions(0, 0, 40, 20).build(), Text.literal("确认屏幕样式"))); + + + listWidget.addEntry(listWidget.new ButtonListEntry(ButtonWidget + .builder(Config.config.enableScreenShortcutKey ? ScreenTexts.ON : ScreenTexts.OFF, (button) -> { + Config.config.enableScreenShortcutKey = !Config.config.enableScreenShortcutKey; + button.setMessage(Config.config.enableScreenShortcutKey ? ScreenTexts.ON : ScreenTexts.OFF); + }) + .dimensions(0, 0, 40, 20).build(), Text.literal("允许在二次确认屏幕上使用快捷键"))); + + TextFieldWidget keepDark = new TextFieldWidget(client.textRenderer, 0, 0, 38, 20, Text.empty()); + keepDark.setText(String.valueOf(Config.config.keepDarkInConfirmScreenTime)); + keepDark.setChangedListener(new PositiveLongParser(keepDark, (it) -> Config.config.keepDarkInConfirmScreenTime = it)); + listWidget.addEntry(listWidget.new InputListEntry(keepDark, Text.literal("保持确认屏幕按钮不可用时长"))); + } + { + MutableText category = Text.literal("二次确认土司设定"); + listWidget.addEntry(listWidget.new CategoryEntry(category.setStyle(category.getStyle().withBold(true)), 11184810)); + + TextFieldWidget toastDisplayTime = new TextFieldWidget(client.textRenderer, 0, 0, 38, 20, Text.empty()); + toastDisplayTime.setText(String.valueOf(Config.config.toastConfirmDisplayTime)); + toastDisplayTime.setChangedListener(new PositiveLongParser(toastDisplayTime, (it) -> Config.config.toastConfirmDisplayTime = it)); + listWidget.addEntry(listWidget.new InputListEntry(toastDisplayTime, Text.literal("土司持续时间"))); + + TextFieldWidget toastStartAliveTime = new TextFieldWidget(client.textRenderer, 0, 0, 38, 20, Text.empty()); + toastStartAliveTime.setText(String.valueOf(Config.config.toastConfirmStartAliveTime)); + toastStartAliveTime.setChangedListener(new PositiveLongParser(toastStartAliveTime, (it) -> Config.config.toastConfirmStartAliveTime = it)); + listWidget.addEntry(listWidget.new InputListEntry(toastStartAliveTime, Text.literal("土司响应开始时间"))); + + TextFieldWidget toastEndAliveTime = new TextFieldWidget(client.textRenderer, 0, 0, 38, 20, Text.empty()); + toastEndAliveTime.setText(String.valueOf(Config.config.toastConfirmEndAliveTime)); + toastEndAliveTime.setChangedListener(new PositiveLongParser(toastEndAliveTime, (it) -> Config.config.toastConfirmEndAliveTime = it)); + listWidget.addEntry(listWidget.new InputListEntry(toastEndAliveTime, Text.literal("土司响应结束时间"))); + } + this.addDrawableChild(listWidget); + this.addDrawableChild(back); + } + + @Override + public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { + super.render(matrices, mouseX, mouseY, delta); + drawCenteredTextWithShadow(matrices, this.textRenderer, this.title, this.width / 2, 15, 16777215); + + MutableText literal = Text.literal("QuitConfirm"); + drawTextWithShadow(matrices, textRenderer, literal, 2, this.height - textRenderer.fontHeight, 5592405); + } + + @Override + public void close() { + Config.save(); + client.setScreen(parentScreen); + } + + class PositiveLongParser implements Consumer { + private final TextFieldWidget fieldWidget; + private final Consumer longConsumer; + + PositiveLongParser(TextFieldWidget fieldWidget, Consumer longConsumer) { + this.fieldWidget = fieldWidget; + this.longConsumer = longConsumer; + } + + @Override + public void accept(String s) { + try { + long parsed = Long.parseLong(s); + if (parsed >= 0) { + fieldWidget.setEditableColor(14737632); + longConsumer.accept(parsed); + back.active = true; + return; + } + } catch (Exception ignored) { + } + back.active = false; + fieldWidget.setEditableColor(16711680); + } + } +} diff --git a/src/main/java/moe/caa/fabric/quitconfirm/client/toast/QuitToast.java b/src/main/java/moe/caa/fabric/quitconfirm/client/toast/QuitToast.java index 773c703..0c77f19 100644 --- a/src/main/java/moe/caa/fabric/quitconfirm/client/toast/QuitToast.java +++ b/src/main/java/moe/caa/fabric/quitconfirm/client/toast/QuitToast.java @@ -4,6 +4,7 @@ import net.minecraft.client.gui.DrawableHelper; import net.minecraft.client.toast.ToastManager; import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.text.Text; import java.awt.*; @@ -17,10 +18,8 @@ protected void drawToast(MatrixStack matrices, ToastManager manager) { RenderSystem.setShaderTexture(0, texture); RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); DrawableHelper.drawTexture(matrices, 0, 0, 0, 0, 160, 32); - ; DrawableHelper.drawTexture(matrices, 8, 0, 241, 0, 15, 30); - ; - manager.getClient().textRenderer.draw(matrices, title, 35.0f, 7.0f, Color.WHITE.getRed()); - manager.getClient().textRenderer.draw(matrices, message, 35.0f, 18.0f, Color.WHITE.getRed()); + manager.getClient().textRenderer.drawWithShadow(matrices, Text.literal(title), 35.0f, 7.0f, Color.WHITE.getRGB()); + manager.getClient().textRenderer.drawWithShadow(matrices, Text.literal(message), 35.0f, 18.0f, Color.WHITE.getRGB()); } }