From 2fe03405453e2fa0e36834f90692e1cf47f4a0dd Mon Sep 17 00:00:00 2001 From: Patbox <39821509+Patbox@users.noreply.github.com> Date: Fri, 11 Aug 2023 16:40:36 +0200 Subject: [PATCH 1/2] Quick and dirty support for colored/formatted text --- build.gradle | 9 +++++ .../block/entity/TextBlockEntity.java | 40 +++++++++++++++++++ .../screen/ingame/TextBlockEditScreen.java | 34 ++++++++-------- 3 files changed, 67 insertions(+), 16 deletions(-) diff --git a/build.gradle b/build.gradle index ad59724..1ac5a1a 100644 --- a/build.gradle +++ b/build.gradle @@ -10,6 +10,13 @@ base { archivesName = project.archives_base_name } +repositories { + maven { + url "https://maven.nucleoid.xyz/" + name "Nucleoid" + } +} + loom { accessWidenerPath = file("src/main/resources/glowcase.accesswidener") } @@ -19,6 +26,8 @@ dependencies { mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" + modImplementation include("eu.pb4:placeholder-api:2.1.2+1.20.1") + } processResources { diff --git a/src/main/java/dev/hephaestus/glowcase/block/entity/TextBlockEntity.java b/src/main/java/dev/hephaestus/glowcase/block/entity/TextBlockEntity.java index 94143ef..3e99e73 100644 --- a/src/main/java/dev/hephaestus/glowcase/block/entity/TextBlockEntity.java +++ b/src/main/java/dev/hephaestus/glowcase/block/entity/TextBlockEntity.java @@ -6,6 +6,10 @@ import dev.hephaestus.glowcase.Glowcase; import dev.hephaestus.glowcase.client.render.block.entity.BakedBlockEntityRenderer.BakedBlockEntityRendererManager; +import eu.pb4.placeholders.api.ParserContext; +import eu.pb4.placeholders.api.parsers.NodeParser; +import eu.pb4.placeholders.api.parsers.TextParserV1; +import net.minecraft.text.Style; import org.jetbrains.annotations.Nullable; import net.minecraft.block.BlockState; @@ -24,6 +28,7 @@ import net.fabricmc.fabric.api.networking.v1.PlayerLookup; public class TextBlockEntity extends BlockEntity { + public static final NodeParser PARSER = TextParserV1.DEFAULT; public List lines = new ArrayList<>(); public TextAlignment textAlignment = TextAlignment.CENTER; public ZOffset zOffset = ZOffset.CENTER; @@ -97,6 +102,41 @@ public Packet toUpdatePacket() { return BlockEntityUpdateS2CPacket.create(this); } + public String getRawLine(int i) { + var line = this.lines.get(i); + + if (line.getStyle() == null) { + return line.getString(); + } + + var insert = line.getStyle().getInsertion(); + + if (insert == null) { + return line.getString(); + } + return insert; + } + + public void addRawLine(int i, String string) { + var parsed = PARSER.parseText(string, ParserContext.of()); + + if (parsed.getString().equals(string)) { + this.lines.add(i, Text.literal(string)); + } else { + this.lines.add(i, Text.empty().append(parsed).setStyle(Style.EMPTY.withInsertion(string))); + } + } + + public void setRawLine(int i, String string) { + var parsed = PARSER.parseText(string, ParserContext.of()); + + if (parsed.getString().equals(string)) { + this.lines.set(i, Text.literal(string)); + } else { + this.lines.set(i, Text.empty().append(parsed).setStyle(Style.EMPTY.withInsertion(string))); + } + } + public enum TextAlignment { LEFT, CENTER, RIGHT } diff --git a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/TextBlockEditScreen.java b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/TextBlockEditScreen.java index 577c159..d6811d7 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/TextBlockEditScreen.java +++ b/src/main/java/dev/hephaestus/glowcase/client/gui/screen/ingame/TextBlockEditScreen.java @@ -51,9 +51,9 @@ public void init() { // } this.selectionManager = new SelectionManager( - () -> this.textBlockEntity.lines.get(this.currentRow).getString(), + () -> this.textBlockEntity.getRawLine(this.currentRow), (string) -> { - textBlockEntity.lines.set(this.currentRow, Text.literal(string)); + textBlockEntity.setRawLine(this.currentRow, string); this.textBlockEntity.renderDirty = true; }, SelectionManager.makeClipboardGetter(this.client), @@ -138,11 +138,13 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { context.getMatrices().push(); context.getMatrices().translate(0, 40 + 2 * this.width / 100F, 0); for (int i = 0; i < this.textBlockEntity.lines.size(); ++i) { - int lineWidth = this.textRenderer.getWidth(this.textBlockEntity.lines.get(i)); + var text = this.currentRow == i ? Text.literal(this.textBlockEntity.getRawLine(i)) : this.textBlockEntity.lines.get(i); + + int lineWidth = this.textRenderer.getWidth(text); switch (this.textBlockEntity.textAlignment) { - case LEFT -> context.drawTextWithShadow(client.textRenderer, this.textBlockEntity.lines.get(i), this.width / 10, i * 12, this.textBlockEntity.color); - case CENTER -> context.drawTextWithShadow(client.textRenderer, this.textBlockEntity.lines.get(i), this.width / 2 - lineWidth / 2, i * 12, this.textBlockEntity.color); - case RIGHT -> context.drawTextWithShadow(client.textRenderer, this.textBlockEntity.lines.get(i), this.width - this.width / 10 - lineWidth, i * 12, this.textBlockEntity.color); + case LEFT -> context.drawTextWithShadow(client.textRenderer, text, this.width / 10, i * 12, this.textBlockEntity.color); + case CENTER -> context.drawTextWithShadow(client.textRenderer, text, this.width / 2 - lineWidth / 2, i * 12, this.textBlockEntity.color); + case RIGHT -> context.drawTextWithShadow(client.textRenderer, text, this.width - this.width / 10 - lineWidth, i * 12, this.textBlockEntity.color); } } @@ -150,7 +152,7 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { int caretEnd = this.selectionManager.getSelectionEnd(); if (caretStart >= 0) { - String line = this.textBlockEntity.lines.get(this.currentRow).getString(); + String line = this.textBlockEntity.getRawLine(this.currentRow); int selectionStart = MathHelper.clamp(Math.min(caretStart, caretEnd), 0, line.length()); int selectionEnd = MathHelper.clamp(Math.max(caretStart, caretEnd), 0, line.length()); @@ -224,12 +226,12 @@ public boolean keyPressed(int keyCode, int scanCode, int modifiers) { } else { this.focusOn(null); if (keyCode == GLFW.GLFW_KEY_ENTER || keyCode == GLFW.GLFW_KEY_KP_ENTER) { - this.textBlockEntity.lines.add(this.currentRow + 1, Text.literal( - this.textBlockEntity.lines.get(this.currentRow).getString().substring( - MathHelper.clamp(this.selectionManager.getSelectionStart(), 0, this.textBlockEntity.lines.get(this.currentRow).getString().length())) + this.textBlockEntity.addRawLine(this.currentRow + 1, + this.textBlockEntity.getRawLine(this.currentRow).substring( + MathHelper.clamp(this.selectionManager.getSelectionStart(), 0, this.textBlockEntity.getRawLine(this.currentRow).length()) )); - this.textBlockEntity.lines.set(this.currentRow, Text.literal( - this.textBlockEntity.lines.get(this.currentRow).getString().substring(0, MathHelper.clamp(this.selectionManager.getSelectionStart(), 0, this.textBlockEntity.lines.get(this.currentRow).getString().length())) + this.textBlockEntity.setRawLine(this.currentRow, + this.textBlockEntity.getRawLine(this.currentRow).substring(0, MathHelper.clamp(this.selectionManager.getSelectionStart(), 0, this.textBlockEntity.getRawLine(this.currentRow).length()) )); this.textBlockEntity.renderDirty = true; ++this.currentRow; @@ -248,7 +250,7 @@ public boolean keyPressed(int keyCode, int scanCode, int modifiers) { this.selectionManager.moveCursorToEnd(false); deleteLine(); return true; - } else if (keyCode == GLFW.GLFW_KEY_DELETE && this.currentRow < this.textBlockEntity.lines.size() - 1 && this.selectionManager.getSelectionEnd() == this.textBlockEntity.lines.get(this.currentRow).getString().length()) { + } else if (keyCode == GLFW.GLFW_KEY_DELETE && this.currentRow < this.textBlockEntity.lines.size() - 1 && this.selectionManager.getSelectionEnd() == this.textBlockEntity.getRawLine(this.currentRow).length()) { deleteLine(); return true; } else { @@ -264,8 +266,8 @@ public boolean keyPressed(int keyCode, int scanCode, int modifiers) { } private void deleteLine() { - this.textBlockEntity.lines.set(this.currentRow, - this.textBlockEntity.lines.get(this.currentRow).append(this.textBlockEntity.lines.get(this.currentRow + 1)) + this.textBlockEntity.setRawLine(this.currentRow, + this.textBlockEntity.getRawLine(this.currentRow) + this.textBlockEntity.getRawLine(this.currentRow + 1) ); this.textBlockEntity.lines.remove(this.currentRow + 1); @@ -281,7 +283,7 @@ public boolean mouseClicked(double mouseX, double mouseY, int button) { if (mouseY > topOffset) { this.currentRow = MathHelper.clamp((int) (mouseY - topOffset) / 12, 0, this.textBlockEntity.lines.size() - 1); this.setFocused(null); - String baseContents = this.textBlockEntity.lines.get(currentRow).getString(); + String baseContents = this.textBlockEntity.getRawLine(currentRow); int baseContentsWidth = this.textRenderer.getWidth(baseContents); int contentsStart; int contentsEnd; From 9d32400a9956f9c67a7b8ee357fc2a42aaed68e8 Mon Sep 17 00:00:00 2001 From: Patbox <39821509+Patbox@users.noreply.github.com> Date: Fri, 11 Aug 2023 16:58:28 +0200 Subject: [PATCH 2/2] Use vanilla shadow rendering as it looks better with colored text (and I didn't see any issues, so likely Mojang fixed it) --- .../render/block/entity/TextBlockEntityRenderer.java | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/TextBlockEntityRenderer.java b/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/TextBlockEntityRenderer.java index 81b87d6..682e7b0 100644 --- a/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/TextBlockEntityRenderer.java +++ b/src/main/java/dev/hephaestus/glowcase/client/render/block/entity/TextBlockEntityRenderer.java @@ -72,15 +72,7 @@ public void renderBaked(TextBlockEntity blockEntity, MatrixStack matrices, Verte matrices.translate(0, 0, 0.025D); } - if (blockEntity.shadowType == TextBlockEntity.ShadowType.DROP) { - // Don't use the vanilla shadow rendering - it breaks when you try to use it in 3D - int shadowColor = 0x88000000; - matrices.translate(0, 0, -0.025D); - textRenderer.draw(blockEntity.lines.get(i), 1, (i * 12) + 1, shadowColor, false, matrices.peek().getPositionMatrix(), vertexConsumers, TextLayerType.NORMAL, 0, LightmapTextureManager.MAX_LIGHT_COORDINATE); - matrices.translate(0, 0, 0.025D); - } - - textRenderer.draw(blockEntity.lines.get(i), 0, i * 12, blockEntity.color, false, matrices.peek().getPositionMatrix(), vertexConsumers, TextLayerType.NORMAL, 0, LightmapTextureManager.MAX_LIGHT_COORDINATE); + textRenderer.draw(blockEntity.lines.get(i), 0, i * 12, blockEntity.color, blockEntity.shadowType == TextBlockEntity.ShadowType.DROP, matrices.peek().getPositionMatrix(), vertexConsumers, TextLayerType.NORMAL, 0, LightmapTextureManager.MAX_LIGHT_COORDINATE); matrices.pop(); }