Skip to content

Commit ff0edf4

Browse files
committed
feat: add structured texts to 1.8.9
1 parent 16f8f04 commit ff0edf4

File tree

14 files changed

+230
-111
lines changed

14 files changed

+230
-111
lines changed

common/src/main/java/io/github/notenoughupdates/moulconfig/common/IMinecraft.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ interface IMinecraft {
5555
/**
5656
* Create a structured text from an untyped platform object. Must be a platform type exactly, not a string or a structured text.
5757
*/
58-
@ApiStatus.Experimental
58+
@ApiStatus.Internal
5959
fun createStructuredTextInternal(obj: Any): StructuredText?
6060

6161
/**

common/src/main/java/io/github/notenoughupdates/moulconfig/common/text/DefaultFormattingColour.java

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,29 +14,32 @@
1414
* A list of (named) colours available on most backends
1515
*/
1616
public enum DefaultFormattingColour {
17-
BLACK(0x000000),
18-
DARK_BLUE(0x0000aa),
19-
DARK_GREEN(0x00aa00),
20-
DARK_AQUA(0x00aaaa),
21-
DARK_RED(0xaa0000),
22-
DARK_PURPLE(0xaa00aa),
23-
GOLD(0xffaa00),
24-
GREY(0xaaaaaa),
25-
DARK_GREY(0x555555),
26-
BLUE(0x5555ff),
27-
GREEN(0x55ff55),
28-
AQUA(0x55ffff),
29-
RED(0xff5555),
30-
LIGHT_PURPLE(0xff55ff),
31-
YELLOW(0xffff55),
32-
WHITE(0xffffff),
17+
BLACK(0x000000, 0),
18+
DARK_BLUE(0x0000aa, 1),
19+
DARK_GREEN(0x00aa00, 2),
20+
DARK_AQUA(0x00aaaa, 3),
21+
DARK_RED(0xaa0000, 4),
22+
DARK_PURPLE(0xaa00aa, 5),
23+
GOLD(0xffaa00, 6),
24+
GREY(0xaaaaaa, 7),
25+
DARK_GREY(0x555555, 8),
26+
BLUE(0x5555ff, 9),
27+
GREEN(0x55ff55, 10),
28+
AQUA(0x55ffff, 11),
29+
RED(0xff5555, 12),
30+
LIGHT_PURPLE(0xff55ff, 13),
31+
YELLOW(0xffff55, 14),
32+
WHITE(0xffffff, 15),
3333
;
3434

3535
@Getter
3636
final int rgb;
37+
@Getter
38+
final int colorHexDigit;
3739

38-
DefaultFormattingColour(int rgb) {
40+
DefaultFormattingColour(int rgb, int colorHexDigit) {
3941
this.rgb = rgb;
42+
this.colorHexDigit = colorHexDigit;
4043
}
4144

4245
public static @NotNull DefaultFormattingColour estimate(int rgb) {

common/src/main/java/io/github/notenoughupdates/moulconfig/common/text/StructuredText.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,16 @@ public interface StructuredText {
2929
@NotNull
3030
Stream<@NotNull StructuredText> getChildren();
3131

32-
@NotNull StructuredText append(StructuredText text);
33-
default @NotNull StructuredText append(String text) {
32+
@NotNull StructuredText append(@NotNull StructuredText text);
33+
default @NotNull StructuredText append(@NotNull String text) {
3434
return append(StructuredText.of(text));
3535
}
3636

3737
@NotNull StructuredStyle getStyle();
3838

3939
void setStyle(StructuredStyle style);
4040

41-
default @NotNull StructuredText withStyle(StructuredStyle style) {
41+
default @NotNull StructuredText withStyle(@NotNull StructuredStyle style) {
4242
setStyle(style);
4343
return this;
4444
}

legacy/src/main/java/io/github/notenoughupdates/moulconfig/forge/ForgeItemStack.kt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,20 @@ package io.github.notenoughupdates.moulconfig.forge
22

33
import io.github.notenoughupdates.moulconfig.common.IItemStack
44
import io.github.notenoughupdates.moulconfig.common.MyResourceLocation
5+
import io.github.notenoughupdates.moulconfig.common.text.StructuredText
56
import io.github.notenoughupdates.moulconfig.internal.ForgeMinecraft
6-
import io.github.notenoughupdates.moulconfig.internal.StructuredTextHelper
77
import net.minecraft.client.Minecraft
88
import net.minecraft.item.Item
99
import net.minecraft.item.ItemStack
1010

1111
class ForgeItemStack private constructor(val backing: ItemStack) : IItemStack {
12-
override fun getLore(): List<StructuredTextHelper> {
12+
override fun getLore(): List<StructuredText> {
1313
return backing.getTooltip(Minecraft.getMinecraft().thePlayer, false)
14+
.map { StructuredText.of(it) }
1415
}
1516

16-
override fun getDisplayName(): String {
17-
return backing.displayName
17+
override fun getDisplayName(): StructuredText {
18+
return StructuredText.of(backing.displayName)
1819
}
1920

2021
override fun getStackSize(): Int {

legacy/src/main/java/io/github/notenoughupdates/moulconfig/gui/editors/GuiOptionEditorKeybindL.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import io.github.notenoughupdates.moulconfig.common.IMinecraft;
2525
import io.github.notenoughupdates.moulconfig.common.RenderContext;
2626
import io.github.notenoughupdates.moulconfig.common.TextureFilter;
27+
import io.github.notenoughupdates.moulconfig.common.text.StructuredText;
2728
import io.github.notenoughupdates.moulconfig.gui.GuiOptionEditor;
2829
import io.github.notenoughupdates.moulconfig.internal.KeybindHelper;
2930
import io.github.notenoughupdates.moulconfig.internal.TextRenderUtils;
@@ -74,7 +75,7 @@ public void render(RenderContext renderContext, int x, int y, int width) {
7475
renderContext.scheduleDrawTooltip(
7576
mc.getMouseX(), mc.getMouseY(),
7677
Collections.singletonList(
77-
"§cReset to Default"
78+
StructuredText.of("Reset to Default").darkRed()
7879
));
7980
}
8081
}
Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11
package io.github.notenoughupdates.moulconfig.internal
22

33
import io.github.notenoughupdates.moulconfig.common.IFontRenderer
4+
import io.github.notenoughupdates.moulconfig.common.text.StructuredText
45
import net.minecraft.client.gui.FontRenderer
56
import net.minecraft.client.gui.GuiUtilRenderComponents
6-
import net.minecraft.util.ChatComponentText
77
import java.util.regex.Pattern
88

99

1010
class ForgeFontRenderer(val font: FontRenderer) : IFontRenderer {
1111
override val height: Int
1212
get() = font.FONT_HEIGHT
1313

14+
override fun getStringWidth(string: StructuredText): Int {
15+
return font.getStringWidth(StructuredTextImpl.unwrap(string).formattedText)
16+
}
17+
1418
override fun getStringWidth(string: String): Int {
1519
return font.getStringWidth(string)
1620
}
@@ -19,28 +23,17 @@ class ForgeFontRenderer(val font: FontRenderer) : IFontRenderer {
1923
return font.getCharWidth(char)
2024
}
2125

22-
companion object {
23-
private val colorPattern: Pattern = Pattern.compile("§[a-f0-9r]")
24-
}
25-
26-
override fun splitText(text: String, width: Int): List<String> {
26+
override fun splitText(text: StructuredText, width: Int): List<StructuredText> {
2727
val iChatComponents =
28-
GuiUtilRenderComponents.splitText(ChatComponentText(text), width, font, false, false)
29-
var lastFormat = "§r"
30-
val strings: MutableList<String> = ArrayList(iChatComponents.size)
31-
for (iChatComponent in iChatComponents) {
32-
val formattedText = lastFormat + iChatComponent.formattedText.replace("^((§.)*) *".toRegex(), "$1")
33-
strings.add(formattedText)
34-
val matcher = colorPattern.matcher(formattedText)
35-
while (matcher.find()) {
36-
lastFormat = matcher.group(0)
37-
}
38-
}
39-
return strings
28+
GuiUtilRenderComponents.splitText(StructuredTextImpl.unwrap(text), width, font, false, false)
29+
return iChatComponents.map { StructuredTextImpl.wrap(it) }
4030
}
4131

42-
override fun trimStringToWidth(string: String, maxWidth: Int, reverse: Boolean): String {
43-
return font.trimStringToWidth(string, maxWidth, reverse)
32+
override fun splitLines(text: StructuredText): List<StructuredText> {
33+
return splitText(text, Integer.MAX_VALUE)
4434
}
4535

36+
override fun trimStringToWidth(string: String, width: Int, reverse: Boolean): String {
37+
return font.trimStringToWidth(string, width, reverse)
38+
}
4639
}

legacy/src/main/java/io/github/notenoughupdates/moulconfig/internal/ForgeMinecraft.kt

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import io.github.notenoughupdates.moulconfig.annotations.ConfigEditorKeybind
44
import io.github.notenoughupdates.moulconfig.annotations.ConfigEditorSlider
55
import io.github.notenoughupdates.moulconfig.annotations.ConfigEditorText
66
import io.github.notenoughupdates.moulconfig.common.*
7+
import io.github.notenoughupdates.moulconfig.common.text.StructuredText
78
import io.github.notenoughupdates.moulconfig.gui.GuiComponentWrapper
89
import io.github.notenoughupdates.moulconfig.gui.GuiContext
910
import io.github.notenoughupdates.moulconfig.gui.GuiElement
@@ -19,7 +20,8 @@ import net.minecraft.client.renderer.texture.DynamicTexture
1920
import net.minecraft.event.ClickEvent
2021
import net.minecraft.launchwrapper.Launch
2122
import net.minecraft.util.ChatComponentText
22-
import net.minecraft.util.ChatStyle
23+
import net.minecraft.util.ChatComponentTranslation
24+
import net.minecraft.util.IChatComponent
2325
import net.minecraft.util.ResourceLocation
2426
import org.apache.logging.log4j.LogManager
2527
import org.lwjgl.input.Keyboard
@@ -94,21 +96,23 @@ class ForgeMinecraft : IMinecraft {
9496
override val scaleFactor: Int
9597
get() = ScaledResolution(Minecraft.getMinecraft()).scaleFactor
9698

97-
override fun sendClickableChatMessage(message: String, action: String, type: ClickType) {
98-
Minecraft.getMinecraft().ingameGUI.chatGUI.printChatMessage(
99-
ChatComponentText(message)
100-
.setChatStyle(
101-
ChatStyle()
102-
.setChatClickEvent(
103-
ClickEvent(
104-
when (type) {
105-
ClickType.OPEN_LINK -> ClickEvent.Action.OPEN_URL
106-
ClickType.RUN_COMMAND -> ClickEvent.Action.RUN_COMMAND
107-
}, action
108-
)
109-
)
99+
override fun sendClickableChatMessage(message: StructuredText, action: String, type: ClickType) {
100+
val component = StructuredTextImpl.unwrap(message)
101+
component.setChatStyle(
102+
component.chatStyle
103+
.setChatClickEvent(
104+
ClickEvent(
105+
when (type) {
106+
ClickType.OPEN_LINK -> ClickEvent.Action.OPEN_URL
107+
ClickType.RUN_COMMAND -> ClickEvent.Action.RUN_COMMAND
108+
}, action
109+
)
110110
)
111111
)
112+
Minecraft.getMinecraft().ingameGUI.chatGUI.printChatMessage(
113+
component
114+
115+
)
112116
}
113117

114118
override fun generateDynamicTexture(image: BufferedImage): DynamicTextureReference {
@@ -137,8 +141,22 @@ class ForgeMinecraft : IMinecraft {
137141
return resourceLocation.root == "moulconfigdyn" // technically this will also start with dynamic/ but i dont control that, so i will just use another namespace smilers
138142
}
139143

140-
override fun getKeyName(keyCode: Int): String {
141-
return KeybindHelper.getKeyName(keyCode)
144+
override fun getKeyName(keyCode: Int): StructuredText {
145+
return StructuredText.of(KeybindHelper.getKeyName(keyCode))
146+
}
147+
148+
override fun createLiteral(text: String): StructuredText {
149+
return StructuredTextImpl.wrap(ChatComponentText(text))
150+
}
151+
152+
override fun createTranslatable(key: String, vararg args: StructuredText): StructuredText {
153+
return StructuredTextImpl.wrap(ChatComponentTranslation(key, *args))
154+
}
155+
156+
override fun createStructuredTextInternal(obj: Any): StructuredText? {
157+
if (obj is IChatComponent)
158+
return StructuredTextImpl.wrap(obj)
159+
return null
142160
}
143161

144162
override fun isMouseButtonDown(mouseButton: Int): Boolean {

legacy/src/main/java/io/github/notenoughupdates/moulconfig/internal/ForgeRenderContext.kt

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.github.notenoughupdates.moulconfig.internal
22

33
import io.github.notenoughupdates.moulconfig.common.*
4+
import io.github.notenoughupdates.moulconfig.common.text.StructuredText
45
import io.github.notenoughupdates.moulconfig.forge.ForgeItemStack
56
import net.minecraft.client.Minecraft
67
import net.minecraft.client.gui.ScaledResolution
@@ -38,8 +39,8 @@ class ForgeRenderContext : RenderContext {
3839
return Keyboard.isKeyDown(keyboardKey)
3940
}
4041

41-
override fun drawString(renderer: IFontRenderer, text: String, x: Int, y: Int, color: Int, shadow: Boolean) {
42-
(renderer as ForgeFontRenderer).font.drawString(text, x.toFloat(), y.toFloat(), color, shadow)
42+
override fun drawString(fontRenderer: IFontRenderer, text: StructuredText, x: Int, y: Int, color: Int, shadow: Boolean) {
43+
(fontRenderer as ForgeFontRenderer).font.drawString(StructuredTextImpl.unwrap(text).formattedText, x.toFloat(), y.toFloat(), color, shadow)
4344
}
4445

4546

@@ -174,7 +175,7 @@ class ForgeRenderContext : RenderContext {
174175
GlScissorStack.clear()
175176
}
176177

177-
override fun renderItemStack(itemStack: IItemStack, x: Int, y: Int, overlayText: String?) {
178+
override fun renderItemStack(itemStack: IItemStack, x: Int, y: Int, overlayText: StructuredText?) {
178179
val forgeStack = itemStack as ForgeItemStack
179180
val backing = forgeStack.backing
180181
val renderItem = Minecraft.getMinecraft().renderItem
@@ -185,20 +186,20 @@ class ForgeRenderContext : RenderContext {
185186
backing,
186187
x,
187188
y,
188-
overlayText
189+
overlayText.text
189190
)
190191
RenderHelper.disableStandardItemLighting()
191192
}
192193

193194

194-
override fun drawTooltipNow(x: Int, y: Int, tooltipLines: List<String>) {
195+
override fun drawTooltipNow(x: Int, y: Int, tooltipLines: List<StructuredText>) {
195196
val scaledResolution = ScaledResolution(Minecraft.getMinecraft())
196197
val width = scaledResolution.scaledWidth
197198
val height = scaledResolution.scaledHeight
198199
val mouseX = Mouse.getX() * width / Minecraft.getMinecraft().displayWidth
199200
val mouseY = height - Mouse.getY() * height / Minecraft.getMinecraft().displayHeight - 1
200201
TextRenderUtils.drawHoveringText(
201-
tooltipLines, mouseX, mouseY,
202+
tooltipLines.map { StructuredTextImpl.unwrap(it) }, mouseX, mouseY,
202203
width, height, -1, Minecraft.getMinecraft().fontRendererObj
203204
)
204205
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package io.github.notenoughupdates.moulconfig.internal;
2+
3+
import io.github.notenoughupdates.moulconfig.common.text.DefaultFormattingColour;
4+
import io.github.notenoughupdates.moulconfig.common.text.StructuredStyle;
5+
import lombok.Value;
6+
import net.minecraft.util.ChatStyle;
7+
import net.minecraft.util.EnumChatFormatting;
8+
import org.jetbrains.annotations.NotNull;
9+
10+
import java.util.HashMap;
11+
import java.util.Map;
12+
import java.util.Objects;
13+
14+
@Value
15+
public class StructuredStyleImpl implements StructuredStyle {
16+
ChatStyle chatStyle;
17+
18+
public static @NotNull StructuredStyle wrap(@NotNull ChatStyle chatStyle) {
19+
return new StructuredStyleImpl(chatStyle);
20+
}
21+
22+
@Override
23+
public @NotNull StructuredStyle withColour(int rgb) {
24+
return withColour(DefaultFormattingColour.estimate(rgb));
25+
}
26+
27+
private static final Map<DefaultFormattingColour, EnumChatFormatting> FORMATTINGS = InitUtil.make(new HashMap<>(), colourMap -> {
28+
for (DefaultFormattingColour formattingColour : DefaultFormattingColour.values()) {
29+
for (EnumChatFormatting enumChatFormatting : EnumChatFormatting.values()) {
30+
if (enumChatFormatting.getColorIndex() == formattingColour.getColorHexDigit())
31+
colourMap.put(formattingColour, enumChatFormatting);
32+
}
33+
}
34+
});
35+
36+
@Override
37+
public @NotNull StructuredStyle withColour(@NotNull DefaultFormattingColour colour) {
38+
chatStyle.setColor(Objects.requireNonNull(FORMATTINGS.get(colour)));
39+
return this;
40+
}
41+
42+
@Override
43+
public @NotNull StructuredStyle withBold(boolean bold) {
44+
chatStyle.setBold(bold);
45+
return this;
46+
}
47+
48+
@Override
49+
public @NotNull StructuredStyle withItalic(boolean italic) {
50+
chatStyle.setItalic(italic);
51+
return this;
52+
}
53+
54+
@Override
55+
public @NotNull StructuredStyle withUnderline(boolean underline) {
56+
chatStyle.setUnderlined(underline);
57+
return this;
58+
}
59+
60+
@Override
61+
public @NotNull StructuredStyle withStrikethrough(boolean strikethrough) {
62+
chatStyle.setStrikethrough(strikethrough);
63+
return this;
64+
}
65+
66+
@Override
67+
public @NotNull StructuredStyle withObfuscated(boolean obfuscated) {
68+
chatStyle.setObfuscated(obfuscated);
69+
return this;
70+
}
71+
}

0 commit comments

Comments
 (0)