From d5d16c12656fd32e26c904e7ff60daddecf7d676 Mon Sep 17 00:00:00 2001 From: zbx1425 Date: Sun, 15 Dec 2024 19:55:18 +0800 Subject: [PATCH] Add hiding other comments when taking screenshot --- .../cn/zbx1425/worldcomment/ClientConfig.java | 4 +- .../data/client/ClientRayPicking.java | 3 +- .../worldcomment/data/client/Screenshot.java | 29 +++-- .../worldcomment/gui/CommentToolScreen.java | 24 ++-- .../zbx1425/worldcomment/gui/IGuiCommon.java | 1 + .../gui/ScreenshotConfigScreen.java | 108 ++++++++++++++++++ .../render/CommentWorldRenderer.java | 3 + .../assets/worldcomment/lang/en_us.json | 2 +- .../assets/worldcomment/lang/zh_cn.json | 4 +- 9 files changed, 148 insertions(+), 30 deletions(-) create mode 100644 common/src/main/java/cn/zbx1425/worldcomment/gui/ScreenshotConfigScreen.java diff --git a/common/src/main/java/cn/zbx1425/worldcomment/ClientConfig.java b/common/src/main/java/cn/zbx1425/worldcomment/ClientConfig.java index 7036243..6b06e36 100644 --- a/common/src/main/java/cn/zbx1425/worldcomment/ClientConfig.java +++ b/common/src/main/java/cn/zbx1425/worldcomment/ClientConfig.java @@ -1,6 +1,5 @@ package cn.zbx1425.worldcomment; -import cn.zbx1425.worldcomment.data.network.upload.ImageUploadConfig; import cn.zbx1425.worldcomment.data.network.upload.ImageUploader; import com.google.gson.JsonElement; import com.google.gson.JsonParser; @@ -13,6 +12,9 @@ public class ClientConfig { public boolean isCommentVisible = true; + public boolean screenshotIncludeGui = false; + public boolean screenshotIncludeComments = true; + public List imageUploader; public int allowMarkerUsage; diff --git a/common/src/main/java/cn/zbx1425/worldcomment/data/client/ClientRayPicking.java b/common/src/main/java/cn/zbx1425/worldcomment/data/client/ClientRayPicking.java index fb051fd..a51295c 100644 --- a/common/src/main/java/cn/zbx1425/worldcomment/data/client/ClientRayPicking.java +++ b/common/src/main/java/cn/zbx1425/worldcomment/data/client/ClientRayPicking.java @@ -50,8 +50,7 @@ public static void tick(float partialTicks, float hitDistance) { Optional clipPos = blockHitArea.clip(pickStart, pickEnd); boolean isPicked = clipPos.isPresent() && clipPos.get().distanceToSqr(pickStart) < vanillaDistSqr; for (CommentEntry comment : blockData.getValue()) { - boolean isVisible = (comment.messageType - 1) >= 4 - || MainClient.CLIENT_CONFIG.isCommentVisible; + boolean isVisible = (comment.messageType - 1) >= 4 || MainClient.CLIENT_CONFIG.isCommentVisible; if (isVisible) { visibleComments.computeIfAbsent(comment.location, ignored -> new ArrayList<>()).add(comment); if (isPicked) { diff --git a/common/src/main/java/cn/zbx1425/worldcomment/data/client/Screenshot.java b/common/src/main/java/cn/zbx1425/worldcomment/data/client/Screenshot.java index d04e9e2..aec2c29 100644 --- a/common/src/main/java/cn/zbx1425/worldcomment/data/client/Screenshot.java +++ b/common/src/main/java/cn/zbx1425/worldcomment/data/client/Screenshot.java @@ -1,6 +1,7 @@ package cn.zbx1425.worldcomment.data.client; import cn.zbx1425.worldcomment.Main; +import cn.zbx1425.worldcomment.MainClient; import cn.zbx1425.worldcomment.gui.CommentListScreen; import cn.zbx1425.worldcomment.gui.CommentToolScreen; import cn.zbx1425.worldcomment.item.CommentToolItem; @@ -68,18 +69,24 @@ public static boolean handleKeyF2() { if (CommentToolItem.getUploadJobId(item) != null) return false; if (minecraft.screen == null) { - minecraft.tell(() -> { - boolean prevHideGui = minecraft.options.hideGui; - minecraft.options.hideGui = !minecraft.options.keySprint.isDown(); - RenderSystem.recordRenderCall(() -> { - grabScreenshot(imageBytes -> minecraft.execute(() -> { - minecraft.player.playSound(shutterSoundEvent); - Minecraft.getInstance().setScreen(new CommentToolScreen(imageBytes)); - })); - minecraft.options.hideGui = prevHideGui; - }); - }); + boolean prevHideGui = minecraft.options.hideGui; + boolean prevIsCommentVisible = MainClient.CLIENT_CONFIG.isCommentVisible; + applyClientConfigForScreenshot(); + // This is a workaround for the issue that the screenshot will be taken before CommentWorldRenderer is hidden + minecraft.tell(() -> RenderSystem.recordRenderCall(() -> minecraft.tell(() -> RenderSystem.recordRenderCall(() -> { + grabScreenshot(imageBytes -> minecraft.execute(() -> { + minecraft.player.playSound(shutterSoundEvent); + Minecraft.getInstance().setScreen(new CommentToolScreen(imageBytes)); + })); + minecraft.options.hideGui = prevHideGui; + MainClient.CLIENT_CONFIG.isCommentVisible = prevIsCommentVisible; + })))); } return true; } + + public static void applyClientConfigForScreenshot() { + Minecraft.getInstance().options.hideGui = !MainClient.CLIENT_CONFIG.screenshotIncludeGui; + MainClient.CLIENT_CONFIG.isCommentVisible = MainClient.CLIENT_CONFIG.screenshotIncludeComments; + } } diff --git a/common/src/main/java/cn/zbx1425/worldcomment/gui/CommentToolScreen.java b/common/src/main/java/cn/zbx1425/worldcomment/gui/CommentToolScreen.java index a775408..8daa582 100644 --- a/common/src/main/java/cn/zbx1425/worldcomment/gui/CommentToolScreen.java +++ b/common/src/main/java/cn/zbx1425/worldcomment/gui/CommentToolScreen.java @@ -34,7 +34,6 @@ public class CommentToolScreen extends Screen implements IGuiCommon { private final byte[] imageBytes; - private static final int SQ_SIZE = 20; private static final int SIDEBAR_OFFSET = 100; private static final int CONTAINER_PADDING_X = 8; @@ -80,6 +79,7 @@ public void onClose() { protected void init() { super.init(); + clearWidgets(); Minecraft minecraft = Minecraft.getInstance(); int baseY = CONTAINER_PADDING_Y; @@ -153,7 +153,7 @@ protected void init() { btnScreenshotConfig = new WidgetColorButton( 0, baseY, CommentTypeButton.BTN_WIDTH * 2, SQ_SIZE, Component.translatable("gui.worldcomment.screenshot_config"), 0xFFAAAAAA, sender -> { - + minecraft.setScreen(new ScreenshotConfigScreen()); } ); addRenderableWidget(btnScreenshotConfig); @@ -168,14 +168,8 @@ protected void init() { .pos(0, baseY).selected(false).build(); addRenderableWidget(checkBoxAnonymous); - int maxX = 0, maxY = 0; - for (GuiEventListener child : children()) { - AbstractWidget widget = (AbstractWidget)child; - maxX = Math.max(maxX, widget #if MC_VERSION >= "11903" .getX() #else .x #endif + widget.getWidth()); - maxY = Math.max(maxY, widget #if MC_VERSION >= "11903" .getY() #else .y #endif + widget.getHeight()); - } - containerWidth = maxX; - containerHeight = maxY; + containerWidth = SIDEBAR_OFFSET - 4 + CommentTypeButton.BTN_WIDTH * 5 + 10; + containerHeight = btnSendFeedback #if MC_VERSION >= "11903" .getY() #else .y #endif + btnSendFeedback.getHeight(); containerOffsetX = (width - (containerWidth + CONTAINER_PADDING_X * 2)) / 2 + CONTAINER_PADDING_X; containerOffsetY = (height - (containerHeight + CONTAINER_PADDING_Y * 2)) / 2 + CONTAINER_PADDING_Y; @@ -242,7 +236,7 @@ public void render(#if MC_VERSION >= "12000" GuiGraphics #else PoseStack #endif GuiGraphics guiGraphics = #if MC_VERSION >= "12000" guiParam #else GuiGraphics.withPose(guiParam) #endif ; #if MC_VERSION < "12002" renderBackground(guiParam); #endif guiGraphics.pose().pushPose(); - setupAnimationTransform(guiGraphics); + boolean animationDone = setupAnimationTransform(guiGraphics); guiGraphics.pose().translate(0, 0, 1); super.render(guiParam, mouseX, mouseY, partialTick); guiGraphics.pose().popPose(); @@ -275,7 +269,8 @@ public void renderBackground(#if MC_VERSION >= "12000" GuiGraphics #else PoseSta private long timestampOpenGui = 0L; - private void setupAnimationTransform(GuiGraphics guiGraphics) { + /** @return true if animation is done */ + private boolean setupAnimationTransform(GuiGraphics guiGraphics) { long timestampNow = System.currentTimeMillis(); if (timestampOpenGui == 0) timestampOpenGui = timestampNow; @@ -289,13 +284,15 @@ private void setupAnimationTransform(GuiGraphics guiGraphics) { x2 = Mth.lerp(easedProgress, width, width - s1PadW); y1 = Mth.lerp(easedProgress, 0, s1PadH); y2 = Mth.lerp(easedProgress, height, height - s1PadH); - } else { + } else if (animProgress < 1) { float x = (float)Mth.map(animProgress, 0.4, 1, 0, 1); float easedProgress = x < 0.5f ? 4 * x * x * x : 1 - (float)Math.pow(-2 * x + 2, 3) / 2; x1 = Mth.lerp(easedProgress, s1PadW, containerOffsetX); x2 = Mth.lerp(easedProgress, width - s1PadW, containerOffsetX + widgetImage.getWidth()); y1 = Mth.lerp(easedProgress, s1PadH, containerOffsetY + CONTAINER_PADDING_Y); y2 = Mth.lerp(easedProgress, height - s1PadH, containerOffsetY + CONTAINER_PADDING_Y + widgetImage.getHeight()); + } else { + return true; } float scaleX = (x2 - x1) / widgetImage.getWidth(); @@ -303,6 +300,7 @@ private void setupAnimationTransform(GuiGraphics guiGraphics) { guiGraphics.pose().translate(x1, y1, 0); guiGraphics.pose().scale(scaleX, scaleY, 1); guiGraphics.pose().translate(-containerOffsetX, -(containerOffsetY + CONTAINER_PADDING_Y), 0); + return false; } @Override diff --git a/common/src/main/java/cn/zbx1425/worldcomment/gui/IGuiCommon.java b/common/src/main/java/cn/zbx1425/worldcomment/gui/IGuiCommon.java index a1fac2c..787df0f 100644 --- a/common/src/main/java/cn/zbx1425/worldcomment/gui/IGuiCommon.java +++ b/common/src/main/java/cn/zbx1425/worldcomment/gui/IGuiCommon.java @@ -10,6 +10,7 @@ public interface IGuiCommon { + int SQ_SIZE = 20; ResourceLocation ATLAS_LOCATION = Main.id("textures/gui/comment-tool.png"); default void graphicsBlit9(GuiGraphics guiGraphics, int x, int y, int width, int height, diff --git a/common/src/main/java/cn/zbx1425/worldcomment/gui/ScreenshotConfigScreen.java b/common/src/main/java/cn/zbx1425/worldcomment/gui/ScreenshotConfigScreen.java new file mode 100644 index 0000000..2957b1c --- /dev/null +++ b/common/src/main/java/cn/zbx1425/worldcomment/gui/ScreenshotConfigScreen.java @@ -0,0 +1,108 @@ +package cn.zbx1425.worldcomment.gui; + +import cn.zbx1425.worldcomment.MainClient; +import cn.zbx1425.worldcomment.data.client.Screenshot; +import com.mojang.blaze3d.systems.RenderSystem; +import net.minecraft.client.Minecraft; +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.Checkbox; +import net.minecraft.client.gui.components.events.GuiEventListener; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.Component; + +public class ScreenshotConfigScreen extends Screen implements IGuiCommon { + + private boolean prevHideGui; + private boolean prevHideComments; + + private static final int CONTAINER_PADDING_X = 8; + private static final int CONTAINER_PADDING_Y = 5; + public int containerWidth, containerHeight, containerOffsetX, containerOffsetY; + + private Checkbox cbIncludeHud, cbIncludeComments; + private Button btnOk; + + public ScreenshotConfigScreen() { + super(Component.literal("Screenshot Config")); + prevHideGui = Minecraft.getInstance().options.hideGui; + prevHideComments = !MainClient.CLIENT_CONFIG.isCommentVisible; + } + + @Override + protected void init() { + super.init(); + Screenshot.applyClientConfigForScreenshot(); + + int baseY = CONTAINER_PADDING_Y; + cbIncludeHud = Checkbox + .builder(Component.translatable("gui.worldcomment.config.screenshot_hud"), minecraft.font) + .pos(0, baseY).selected(MainClient.CLIENT_CONFIG.screenshotIncludeGui) + .onValueChange((sender, value) -> { + MainClient.CLIENT_CONFIG.screenshotIncludeGui = value; + Screenshot.applyClientConfigForScreenshot(); + }).build(); + addRenderableWidget(cbIncludeHud); + baseY += SQ_SIZE; + cbIncludeComments = Checkbox + .builder(Component.translatable("gui.worldcomment.config.screenshot_comments"), minecraft.font) + .pos(0, baseY).selected(MainClient.CLIENT_CONFIG.screenshotIncludeComments) + .onValueChange((sender, value) -> { + MainClient.CLIENT_CONFIG.screenshotIncludeComments = value; + Screenshot.applyClientConfigForScreenshot(); + }).build(); + addRenderableWidget(cbIncludeComments); + baseY += SQ_SIZE; + baseY += CONTAINER_PADDING_Y; + + containerWidth = 200; + btnOk = new WidgetColorButton( + containerWidth - CommentTypeButton.BTN_WIDTH * 2, baseY, CommentTypeButton.BTN_WIDTH * 2, SQ_SIZE, + Component.translatable("gui.ok"), 0xFFC5E1A5, + sender -> onClose() + ); + addRenderableWidget(btnOk); + + containerHeight = btnOk #if MC_VERSION >= "11903" .getY() #else .y #endif + btnOk.getHeight(); + + containerOffsetX = Math.max((width / 2 - (containerWidth + CONTAINER_PADDING_X * 2)) / 2 + CONTAINER_PADDING_X, 20); + containerOffsetY = (height - (containerHeight + CONTAINER_PADDING_Y * 2)) / 2 + CONTAINER_PADDING_Y; + for (GuiEventListener child : children()) { + AbstractWidget widget = (AbstractWidget)child; + widget #if MC_VERSION >= "11903" .setX #else .x = #endif (widget #if MC_VERSION >= "11903" .getX() #else .x #endif + containerOffsetX); + widget #if MC_VERSION >= "11903" .setY #else .y = #endif (widget #if MC_VERSION >= "11903" .getY() #else .y #endif + containerOffsetY); + } + } + + @Override + public void renderBackground(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) { + RenderSystem.enableBlend(); + guiGraphics.fill( + containerOffsetX - CONTAINER_PADDING_X, + containerOffsetY - CONTAINER_PADDING_Y, + containerOffsetX + containerWidth + CONTAINER_PADDING_X, + containerOffsetY + containerHeight + CONTAINER_PADDING_Y, + 0x99222222 + ); + guiGraphics.fill( + containerOffsetX - CONTAINER_PADDING_X, + containerOffsetY + containerHeight - SQ_SIZE + CONTAINER_PADDING_Y, + containerOffsetX + containerWidth + CONTAINER_PADDING_X, + containerOffsetY + containerHeight + CONTAINER_PADDING_Y, + 0x66546e7a + ); + } + + @Override + public boolean isPauseScreen() { + return false; + } + + @Override + public void onClose() { + minecraft.options.hideGui = prevHideGui; + MainClient.CLIENT_CONFIG.isCommentVisible = !prevHideComments; + super.onClose(); + } +} diff --git a/common/src/main/java/cn/zbx1425/worldcomment/render/CommentWorldRenderer.java b/common/src/main/java/cn/zbx1425/worldcomment/render/CommentWorldRenderer.java index 41119dc..362ae36 100644 --- a/common/src/main/java/cn/zbx1425/worldcomment/render/CommentWorldRenderer.java +++ b/common/src/main/java/cn/zbx1425/worldcomment/render/CommentWorldRenderer.java @@ -1,6 +1,7 @@ package cn.zbx1425.worldcomment.render; import cn.zbx1425.worldcomment.Main; +import cn.zbx1425.worldcomment.MainClient; import cn.zbx1425.worldcomment.data.CommentEntry; import cn.zbx1425.worldcomment.data.client.ClientRayPicking; import cn.zbx1425.worldcomment.gui.IGuiCommon; @@ -102,6 +103,8 @@ public static void renderComments(MultiBufferSource buffers, PoseStack matrices) for (Map.Entry> blockData : ClientRayPicking.visibleComments.entrySet()) { for (int i = 0; i < blockData.getValue().size(); i++) { CommentEntry comment = blockData.getValue().get(i); + boolean isVisible = (comment.messageType - 1) >= 4 || MainClient.CLIENT_CONFIG.isCommentVisible; + if (!isVisible) continue; boolean showIcon = blockData.getValue().size() < 2 || ((currentTime / 1000) % blockData.getValue().size() == i); renderComment(vertices, matrices, comment, ClientRayPicking.pickedComments.contains(comment), showIcon); diff --git a/common/src/main/resources/assets/worldcomment/lang/en_us.json b/common/src/main/resources/assets/worldcomment/lang/en_us.json index 690a7f3..b380e2e 100644 --- a/common/src/main/resources/assets/worldcomment/lang/en_us.json +++ b/common/src/main/resources/assets/worldcomment/lang/en_us.json @@ -14,7 +14,7 @@ "gui.worldcomment.message": "Enter feedback here (Optional)", "gui.worldcomment.message.placeholder": "(Example) Amazing Chest Ahead", - "gui.worldcomment.screenshot_config": "Don't hide ... in screenshot?", + "gui.worldcomment.screenshot_config": "Include ... in screenshot?", "gui.worldcomment.exclude_screenshot": "No Image", "gui.worldcomment.anonymous": "Anonymous", "gui.worldcomment.save_screenshot": "Save Screenshot", diff --git a/common/src/main/resources/assets/worldcomment/lang/zh_cn.json b/common/src/main/resources/assets/worldcomment/lang/zh_cn.json index 69fa5ea..935e9ac 100644 --- a/common/src/main/resources/assets/worldcomment/lang/zh_cn.json +++ b/common/src/main/resources/assets/worldcomment/lang/zh_cn.json @@ -14,8 +14,8 @@ "gui.worldcomment.message": "在此处留言 (非必填)", "gui.worldcomment.message.placeholder": "(示例) 前有巨大宝箱", - "gui.worldcomment.screenshot_config": "在截图中不要隐藏……?", - "gui.worldcomment.exclude_screenshot": "不包含截图", + "gui.worldcomment.screenshot_config": "在截图中包括…?", + "gui.worldcomment.exclude_screenshot": "不发送截图", "gui.worldcomment.anonymous": "匿名评论", "gui.worldcomment.save_screenshot": "另存截图", "gui.worldcomment.require_comment_type": "请选择一个表情符号",