shedaniel 5 лет назад
Родитель
Сommit
f5fd383fc5
77 измененных файлов с 1089 добавлено и 1213 удалено
  1. 7 5
      build.gradle
  2. 5 5
      gradle.properties
  3. 31 29
      src/main/java/me/shedaniel/clothconfig2/ClothConfigInitializer.java
  4. 8 6
      src/main/java/me/shedaniel/clothconfig2/api/AbstractConfigEntry.java
  5. 4 3
      src/main/java/me/shedaniel/clothconfig2/api/AbstractConfigListEntry.java
  6. 7 14
      src/main/java/me/shedaniel/clothconfig2/api/ConfigBuilder.java
  7. 2 1
      src/main/java/me/shedaniel/clothconfig2/api/ConfigCategory.java
  8. 60 44
      src/main/java/me/shedaniel/clothconfig2/api/ConfigEntryBuilder.java
  9. 2 3
      src/main/java/me/shedaniel/clothconfig2/api/ModifierKeyCode.java
  10. 8 22
      src/main/java/me/shedaniel/clothconfig2/api/QueuedTooltip.java
  11. 83 75
      src/main/java/me/shedaniel/clothconfig2/gui/ClothConfigScreen.java
  12. 5 3
      src/main/java/me/shedaniel/clothconfig2/gui/ClothConfigTabButton.java
  13. 1 2
      src/main/java/me/shedaniel/clothconfig2/gui/ClothRequiresRestartScreen.java
  14. 5 4
      src/main/java/me/shedaniel/clothconfig2/gui/entries/AbstractListListEntry.java
  15. 12 9
      src/main/java/me/shedaniel/clothconfig2/gui/entries/AbstractTextFieldListListEntry.java
  16. 7 5
      src/main/java/me/shedaniel/clothconfig2/gui/entries/BaseListCell.java
  17. 28 25
      src/main/java/me/shedaniel/clothconfig2/gui/entries/BaseListEntry.java
  18. 17 20
      src/main/java/me/shedaniel/clothconfig2/gui/entries/BooleanListEntry.java
  19. 9 7
      src/main/java/me/shedaniel/clothconfig2/gui/entries/ColorEntry.java
  20. 10 15
      src/main/java/me/shedaniel/clothconfig2/gui/entries/DoubleListEntry.java
  21. 9 8
      src/main/java/me/shedaniel/clothconfig2/gui/entries/DoubleListListEntry.java
  22. 76 75
      src/main/java/me/shedaniel/clothconfig2/gui/entries/DropdownBoxEntry.java
  23. 7 12
      src/main/java/me/shedaniel/clothconfig2/gui/entries/EnumListEntry.java
  24. 9 14
      src/main/java/me/shedaniel/clothconfig2/gui/entries/FloatListEntry.java
  25. 9 8
      src/main/java/me/shedaniel/clothconfig2/gui/entries/FloatListListEntry.java
  26. 12 17
      src/main/java/me/shedaniel/clothconfig2/gui/entries/IntegerListEntry.java
  27. 9 8
      src/main/java/me/shedaniel/clothconfig2/gui/entries/IntegerListListEntry.java
  28. 18 21
      src/main/java/me/shedaniel/clothconfig2/gui/entries/IntegerSliderEntry.java
  29. 15 12
      src/main/java/me/shedaniel/clothconfig2/gui/entries/KeyCodeEntry.java
  30. 9 14
      src/main/java/me/shedaniel/clothconfig2/gui/entries/LongListEntry.java
  31. 9 8
      src/main/java/me/shedaniel/clothconfig2/gui/entries/LongListListEntry.java
  32. 18 22
      src/main/java/me/shedaniel/clothconfig2/gui/entries/LongSliderEntry.java
  33. 17 15
      src/main/java/me/shedaniel/clothconfig2/gui/entries/MultiElementListEntry.java
  34. 6 4
      src/main/java/me/shedaniel/clothconfig2/gui/entries/NestedListListEntry.java
  35. 18 21
      src/main/java/me/shedaniel/clothconfig2/gui/entries/SelectionListEntry.java
  36. 4 9
      src/main/java/me/shedaniel/clothconfig2/gui/entries/StringListEntry.java
  37. 5 4
      src/main/java/me/shedaniel/clothconfig2/gui/entries/StringListListEntry.java
  38. 17 15
      src/main/java/me/shedaniel/clothconfig2/gui/entries/SubCategoryListEntry.java
  39. 17 15
      src/main/java/me/shedaniel/clothconfig2/gui/entries/TextFieldListEntry.java
  40. 13 11
      src/main/java/me/shedaniel/clothconfig2/gui/entries/TextListEntry.java
  41. 10 8
      src/main/java/me/shedaniel/clothconfig2/gui/entries/TooltipListEntry.java
  42. 7 5
      src/main/java/me/shedaniel/clothconfig2/gui/widget/ColorDisplayWidget.java
  43. 67 60
      src/main/java/me/shedaniel/clothconfig2/gui/widget/DynamicEntryListWidget.java
  44. 19 16
      src/main/java/me/shedaniel/clothconfig2/gui/widget/DynamicNewSmoothScrollingEntryListWidget.java
  45. 13 10
      src/main/java/me/shedaniel/clothconfig2/gui/widget/DynamicSmoothScrollingEntryListWidget.java
  46. 14 12
      src/main/java/me/shedaniel/clothconfig2/impl/ConfigBuilderImpl.java
  47. 5 4
      src/main/java/me/shedaniel/clothconfig2/impl/ConfigCategoryImpl.java
  48. 31 28
      src/main/java/me/shedaniel/clothconfig2/impl/ConfigEntryBuilderImpl.java
  49. 3 2
      src/main/java/me/shedaniel/clothconfig2/impl/FakeKeyBindings.java
  50. 11 21
      src/main/java/me/shedaniel/clothconfig2/impl/ModifierKeyCodeImpl.java
  51. 2 0
      src/main/java/me/shedaniel/clothconfig2/impl/ScissorsHandlerImpl.java
  52. 12 11
      src/main/java/me/shedaniel/clothconfig2/impl/builders/BooleanToggleBuilder.java
  53. 37 9
      src/main/java/me/shedaniel/clothconfig2/impl/builders/ColorFieldBuilder.java
  54. 8 7
      src/main/java/me/shedaniel/clothconfig2/impl/builders/DoubleFieldBuilder.java
  55. 15 13
      src/main/java/me/shedaniel/clothconfig2/impl/builders/DoubleListBuilder.java
  56. 53 50
      src/main/java/me/shedaniel/clothconfig2/impl/builders/DropdownMenuBuilder.java
  57. 10 9
      src/main/java/me/shedaniel/clothconfig2/impl/builders/EnumSelectorBuilder.java
  58. 7 6
      src/main/java/me/shedaniel/clothconfig2/impl/builders/FieldBuilder.java
  59. 8 7
      src/main/java/me/shedaniel/clothconfig2/impl/builders/FloatFieldBuilder.java
  60. 15 13
      src/main/java/me/shedaniel/clothconfig2/impl/builders/FloatListBuilder.java
  61. 8 7
      src/main/java/me/shedaniel/clothconfig2/impl/builders/IntFieldBuilder.java
  62. 15 14
      src/main/java/me/shedaniel/clothconfig2/impl/builders/IntListBuilder.java
  63. 10 9
      src/main/java/me/shedaniel/clothconfig2/impl/builders/IntSliderBuilder.java
  64. 10 9
      src/main/java/me/shedaniel/clothconfig2/impl/builders/KeyCodeBuilder.java
  65. 8 7
      src/main/java/me/shedaniel/clothconfig2/impl/builders/LongFieldBuilder.java
  66. 15 14
      src/main/java/me/shedaniel/clothconfig2/impl/builders/LongListBuilder.java
  67. 10 9
      src/main/java/me/shedaniel/clothconfig2/impl/builders/LongSliderBuilder.java
  68. 10 9
      src/main/java/me/shedaniel/clothconfig2/impl/builders/SelectorBuilder.java
  69. 8 7
      src/main/java/me/shedaniel/clothconfig2/impl/builders/StringFieldBuilder.java
  70. 15 13
      src/main/java/me/shedaniel/clothconfig2/impl/builders/StringListBuilder.java
  71. 7 6
      src/main/java/me/shedaniel/clothconfig2/impl/builders/SubCategoryBuilder.java
  72. 8 7
      src/main/java/me/shedaniel/clothconfig2/impl/builders/TextDescriptionBuilder.java
  73. 8 7
      src/main/java/me/shedaniel/clothconfig2/impl/builders/TextFieldBuilder.java
  74. 0 34
      src/main/java/me/shedaniel/math/api/Dimension.java
  75. 0 38
      src/main/java/me/shedaniel/math/api/Point.java
  76. 0 113
      src/main/java/me/shedaniel/math/api/Rectangle.java
  77. 2 9
      src/main/java/me/shedaniel/math/impl/PointHelper.java

+ 7 - 5
build.gradle

@@ -42,12 +42,14 @@ dependencies {
     mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
 
     modApi "net.fabricmc:fabric-loader:${project.loader_version}"
-    modApi "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
+    modApi ("net.fabricmc.fabric-api:fabric-api:${project.fabric_version}") {
+        exclude module: "fabric-biomes-v1"
+    }
 
-    modApi "me.shedaniel.cloth:basic-math:0.4.1"
-    include "me.shedaniel.cloth:basic-math:0.4.1"
+    modApi "me.shedaniel.cloth:basic-math:0.5.0"
+    include "me.shedaniel.cloth:basic-math:0.5.0"
 
-    modImplementation "io.github.prospector:modmenu:${modmenu_version}"
+    modCompileOnly "io.github.prospector:modmenu:${modmenu_version}"
 
 //    modRuntime "com.lettuce.fudge:notenoughcrashes:$nec_version"
 }
@@ -141,7 +143,7 @@ curseforge {
                 requiredDependency 'fabric-api'
             }
             mainArtifact(file("${project.buildDir}/libs/${project.archivesBaseName}-${project.version}.jar")) {
-                displayName = "[Fabric 20w14a] ClothConfig2-$project.version"
+                displayName = "[Fabric 20w17a] ClothConfig2-$project.version"
             }
             addArtifact(file("${project.buildDir}/libs/${project.archivesBaseName}-${project.version}-sources.jar"))
             afterEvaluate {

+ 5 - 5
gradle.properties

@@ -1,7 +1,7 @@
-minecraft_version=20w12a
-yarn_mappings=20w12a+build.3
-loader_version=0.7.8+build.186
-fabric_version=0.5.4+build.310-1.16
-mod_version=3.3.2-unstable
+minecraft_version=20w17a
+yarn_mappings=20w17a+build.2
+loader_version=0.8.2+build.194
+fabric_version=0.6.2+build.327-1.16
+mod_version=4.0.0-unstable
 modmenu_version=1.11.0+build.2
 nec_version=1.2.3+1.15.1

+ 31 - 29
src/main/java/me/shedaniel/clothconfig2/ClothConfigInitializer.java

@@ -21,11 +21,13 @@ import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.gui.widget.AbstractButtonWidget;
 import net.minecraft.client.gui.widget.AbstractPressableButtonWidget;
-import net.minecraft.client.resource.language.I18n;
 import net.minecraft.client.util.InputUtil;
 import net.minecraft.client.util.Window;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.item.Item;
 import net.minecraft.item.Items;
+import net.minecraft.text.LiteralText;
+import net.minecraft.text.TranslatableText;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.math.MathHelper;
 import net.minecraft.util.registry.Registry;
@@ -181,21 +183,21 @@ public class ClothConfigInitializer implements ClientModInitializer {
     
     @SuppressWarnings("deprecation")
     public static ConfigBuilder getConfigBuilder() {
-        ConfigBuilder builder = ConfigBuilder.create().setParentScreen(MinecraftClient.getInstance().currentScreen).setTitle("title.cloth-config.config");
+        ConfigBuilder builder = ConfigBuilder.create().setParentScreen(MinecraftClient.getInstance().currentScreen).setTitle(new TranslatableText("title.cloth-config.config"));
         builder.setDefaultBackgroundTexture(new Identifier("minecraft:textures/block/oak_planks.png"));
-        ConfigCategory scrolling = builder.getOrCreateCategory("category.cloth-config.scrolling");
+        ConfigCategory scrolling = builder.getOrCreateCategory(new TranslatableText("category.cloth-config.scrolling"));
         ConfigEntryBuilder entryBuilder = ConfigEntryBuilder.create();
-        DropdownBoxEntry<EasingMethod> easingMethodEntry = entryBuilder.startDropdownMenu("Easing Method", DropdownMenuBuilder.TopCellElementBuilder.of(easingMethod, str -> {
+        DropdownBoxEntry<EasingMethod> easingMethodEntry = entryBuilder.startDropdownMenu(new LiteralText("Easing Method"), DropdownMenuBuilder.TopCellElementBuilder.of(easingMethod, str -> {
             for (EasingMethod m : EasingMethods.getMethods())
                 if (m.toString().equals(str))
                     return m;
             return null;
         })).setDefaultValue(EasingMethodImpl.LINEAR).setSaveConsumer(o -> easingMethod = o).setSelections(EasingMethods.getMethods()).build();
-        LongSliderEntry scrollDurationEntry = entryBuilder.startLongSlider("option.cloth-config.scrollDuration", scrollDuration, 0, 5000).setTextGetter(integer -> integer <= 0 ? "Value: Disabled" : (integer > 1500 ? String.format("Value: %.1fs", integer / 1000f) : "Value: " + integer + "ms")).setDefaultValue(600).setSaveConsumer(i -> scrollDuration = i).build();
-        DoubleListEntry scrollStepEntry = entryBuilder.startDoubleField("option.cloth-config.scrollStep", scrollStep).setDefaultValue(19).setSaveConsumer(i -> scrollStep = i).build();
-        LongSliderEntry bounceMultiplierEntry = entryBuilder.startLongSlider("option.cloth-config.bounceBackMultiplier", (long) (bounceBackMultiplier * 1000), -10, 750).setTextGetter(integer -> integer < 0 ? "Value: Disabled" : String.format("Value: %s", integer / 1000d)).setDefaultValue(240).setSaveConsumer(i -> bounceBackMultiplier = i / 1000d).build();
+        LongSliderEntry scrollDurationEntry = entryBuilder.startLongSlider(new TranslatableText("option.cloth-config.scrollDuration"), scrollDuration, 0, 5000).setTextGetter(integer -> new LiteralText(integer <= 0 ? "Value: Disabled" : (integer > 1500 ? String.format("Value: %.1fs", integer / 1000f) : "Value: " + integer + "ms"))).setDefaultValue(600).setSaveConsumer(i -> scrollDuration = i).build();
+        DoubleListEntry scrollStepEntry = entryBuilder.startDoubleField(new TranslatableText("option.cloth-config.scrollStep"), scrollStep).setDefaultValue(19).setSaveConsumer(i -> scrollStep = i).build();
+        LongSliderEntry bounceMultiplierEntry = entryBuilder.startLongSlider(new TranslatableText("option.cloth-config.bounceBackMultiplier"), (long) (bounceBackMultiplier * 1000), -10, 750).setTextGetter(integer -> new LiteralText(integer < 0 ? "Value: Disabled" : String.format("Value: %s", integer / 1000d))).setDefaultValue(240).setSaveConsumer(i -> bounceBackMultiplier = i / 1000d).build();
         
-        scrolling.addEntry(new TooltipListEntry<Object>(I18n.translate("option.cloth-config.setDefaultSmoothScroll"), null) {
+        scrolling.addEntry(new TooltipListEntry<Object>(new TranslatableText("option.cloth-config.setDefaultSmoothScroll"), null) {
             final int width = 220;
             private final AbstractButtonWidget buttonWidget = new AbstractPressableButtonWidget(0, 0, 0, 20, getFieldName()) {
                 @Override
@@ -229,18 +231,18 @@ public class ClothConfigInitializer implements ClientModInitializer {
             }
             
             @Override
-            public void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
-                super.render(index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta);
+            public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
+                super.render(matrices, index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta);
                 Window window = MinecraftClient.getInstance().getWindow();
                 this.buttonWidget.active = this.isEditable();
                 this.buttonWidget.y = y;
                 this.buttonWidget.x = x + entryWidth / 2 - width / 2;
                 this.buttonWidget.setWidth(width);
-                this.buttonWidget.render(mouseX, mouseY, delta);
+                this.buttonWidget.render(matrices, mouseX, mouseY, delta);
             }
         });
         
-        scrolling.addEntry(new TooltipListEntry<Object>(I18n.translate("option.cloth-config.disableSmoothScroll"), null) {
+        scrolling.addEntry(new TooltipListEntry<Object>(new TranslatableText("option.cloth-config.disableSmoothScroll"), null) {
             final int width = 220;
             private final AbstractButtonWidget buttonWidget = new AbstractPressableButtonWidget(0, 0, 0, 20, getFieldName()) {
                 @Override
@@ -274,14 +276,14 @@ public class ClothConfigInitializer implements ClientModInitializer {
             }
             
             @Override
-            public void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
-                super.render(index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta);
+            public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
+                super.render(matrices, index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta);
                 Window window = MinecraftClient.getInstance().getWindow();
                 this.buttonWidget.active = this.isEditable();
                 this.buttonWidget.y = y;
                 this.buttonWidget.x = x + entryWidth / 2 - width / 2;
                 this.buttonWidget.setWidth(width);
-                this.buttonWidget.render(mouseX, mouseY, delta);
+                this.buttonWidget.render(matrices, mouseX, mouseY, delta);
             }
         });
         scrolling.addEntry(easingMethodEntry);
@@ -296,21 +298,21 @@ public class ClothConfigInitializer implements ClientModInitializer {
     public static ConfigBuilder getConfigBuilderWithDemo() {
         ConfigBuilder builder = getConfigBuilder();
         ConfigEntryBuilder entryBuilder = builder.entryBuilder();
-        ConfigCategory testing = builder.getOrCreateCategory("category.cloth-config.testing");
+        ConfigCategory testing = builder.getOrCreateCategory(new TranslatableText("category.cloth-config.testing"));
 //        testing.addEntry(entryBuilder.startDropdownMenu("lol apple", DropdownMenuBuilder.TopCellElementBuilder.ofItemObject(Items.APPLE), DropdownMenuBuilder.CellCreatorBuilder.ofItemObject()).setDefaultValue(Items.APPLE).setSelections(Registry.ITEM.stream().sorted(Comparator.comparing(Item::toString)).collect(Collectors.toCollection(LinkedHashSet::new))).setSaveConsumer(item -> System.out.println("save this " + item)).build());
-        testing.addEntry(entryBuilder.startKeyCodeField("Cool Key", InputUtil.UNKNOWN_KEYCODE).setDefaultValue(InputUtil.UNKNOWN_KEYCODE).build());
-        testing.addEntry(entryBuilder.startModifierKeyCodeField("Cool Modifier Key", ModifierKeyCode.of(InputUtil.Type.KEYSYM.createFromCode(79), Modifier.of(false, true, false))).setDefaultValue(ModifierKeyCode.of(InputUtil.Type.KEYSYM.createFromCode(79), Modifier.of(false, true, false))).build());
-        testing.addEntry(entryBuilder.startDoubleList("A list of Doubles", Arrays.asList(1d, 2d, 3d)).setDefaultValue(Arrays.asList(1d, 2d, 3d)).build());
-        testing.addEntry(entryBuilder.startLongList("A list of Longs", Arrays.asList(1L, 2L, 3L)).setDefaultValue(Arrays.asList(1L, 2L, 3L)).build());
-        testing.addEntry(entryBuilder.startStrList("A list of Strings", Arrays.asList("abc", "xyz")).setDefaultValue(Arrays.asList("abc", "xyz")).build());
-        SubCategoryBuilder colors = entryBuilder.startSubCategory("Colors").setExpanded(true);
-        colors.add(entryBuilder.startColorField("A color field", 0x00ffff).setDefaultValue(0x00ffff).build());
-        colors.add(entryBuilder.startColorField("An alpha color field", 0xff00ffff).setDefaultValue(0xff00ffff).setAlphaMode(true).build());
-        colors.add(entryBuilder.startDropdownMenu("lol apple", DropdownMenuBuilder.TopCellElementBuilder.ofItemObject(Items.APPLE), DropdownMenuBuilder.CellCreatorBuilder.ofItemObject()).setDefaultValue(Items.APPLE).setSelections(Registry.ITEM.stream().sorted(Comparator.comparing(Item::toString)).collect(Collectors.toCollection(LinkedHashSet::new))).setSaveConsumer(item -> System.out.println("save this " + item)).build());
-        colors.add(entryBuilder.startDropdownMenu("lol apple", DropdownMenuBuilder.TopCellElementBuilder.ofItemObject(Items.APPLE), DropdownMenuBuilder.CellCreatorBuilder.ofItemObject()).setDefaultValue(Items.APPLE).setSelections(Registry.ITEM.stream().sorted(Comparator.comparing(Item::toString)).collect(Collectors.toCollection(LinkedHashSet::new))).setSaveConsumer(item -> System.out.println("save this " + item)).build());
-        colors.add(entryBuilder.startDropdownMenu("lol apple", DropdownMenuBuilder.TopCellElementBuilder.ofItemObject(Items.APPLE), DropdownMenuBuilder.CellCreatorBuilder.ofItemObject()).setDefaultValue(Items.APPLE).setSelections(Registry.ITEM.stream().sorted(Comparator.comparing(Item::toString)).collect(Collectors.toCollection(LinkedHashSet::new))).setSaveConsumer(item -> System.out.println("save this " + item)).build());
-        colors.add(entryBuilder.startDropdownMenu("lol apple", DropdownMenuBuilder.TopCellElementBuilder.ofItemObject(Items.APPLE), DropdownMenuBuilder.CellCreatorBuilder.ofItemObject()).setDefaultValue(Items.APPLE).setSelections(Registry.ITEM.stream().sorted(Comparator.comparing(Item::toString)).collect(Collectors.toCollection(LinkedHashSet::new))).setSaveConsumer(item -> System.out.println("save this " + item)).build());
-        colors.add(entryBuilder.startDropdownMenu("lol apple", DropdownMenuBuilder.TopCellElementBuilder.ofItemObject(Items.APPLE), DropdownMenuBuilder.CellCreatorBuilder.ofItemObject()).setDefaultValue(Items.APPLE).setSelections(Registry.ITEM.stream().sorted(Comparator.comparing(Item::toString)).collect(Collectors.toCollection(LinkedHashSet::new))).setSaveConsumer(item -> System.out.println("save this " + item)).build());
+        testing.addEntry(entryBuilder.startKeyCodeField(new LiteralText("Cool Key"), InputUtil.UNKNOWN_KEYCODE).setDefaultValue(InputUtil.UNKNOWN_KEYCODE).build());
+        testing.addEntry(entryBuilder.startModifierKeyCodeField(new LiteralText("Cool Modifier Key"), ModifierKeyCode.of(InputUtil.Type.KEYSYM.createFromCode(79), Modifier.of(false, true, false))).setDefaultValue(ModifierKeyCode.of(InputUtil.Type.KEYSYM.createFromCode(79), Modifier.of(false, true, false))).build());
+        testing.addEntry(entryBuilder.startDoubleList(new LiteralText("A list of Doubles"), Arrays.asList(1d, 2d, 3d)).setDefaultValue(Arrays.asList(1d, 2d, 3d)).build());
+        testing.addEntry(entryBuilder.startLongList(new LiteralText("A list of Longs"), Arrays.asList(1L, 2L, 3L)).setDefaultValue(Arrays.asList(1L, 2L, 3L)).build());
+        testing.addEntry(entryBuilder.startStrList(new LiteralText("A list of Strings"), Arrays.asList("abc", "xyz")).setDefaultValue(Arrays.asList("abc", "xyz")).build());
+        SubCategoryBuilder colors = entryBuilder.startSubCategory(new LiteralText("Colors")).setExpanded(true);
+        colors.add(entryBuilder.startColorField(new LiteralText("A color field"), 0x00ffff).setDefaultValue(0x00ffff).build());
+        colors.add(entryBuilder.startColorField(new LiteralText("An alpha color field"), 0xff00ffff).setDefaultValue(0xff00ffff).setAlphaMode(true).build());
+        colors.add(entryBuilder.startDropdownMenu(new LiteralText("lol apple"), DropdownMenuBuilder.TopCellElementBuilder.ofItemObject(Items.APPLE), DropdownMenuBuilder.CellCreatorBuilder.ofItemObject()).setDefaultValue(Items.APPLE).setSelections(Registry.ITEM.stream().sorted(Comparator.comparing(Item::toString)).collect(Collectors.toCollection(LinkedHashSet::new))).setSaveConsumer(item -> System.out.println("save this " + item)).build());
+        colors.add(entryBuilder.startDropdownMenu(new LiteralText("lol apple"), DropdownMenuBuilder.TopCellElementBuilder.ofItemObject(Items.APPLE), DropdownMenuBuilder.CellCreatorBuilder.ofItemObject()).setDefaultValue(Items.APPLE).setSelections(Registry.ITEM.stream().sorted(Comparator.comparing(Item::toString)).collect(Collectors.toCollection(LinkedHashSet::new))).setSaveConsumer(item -> System.out.println("save this " + item)).build());
+        colors.add(entryBuilder.startDropdownMenu(new LiteralText("lol apple"), DropdownMenuBuilder.TopCellElementBuilder.ofItemObject(Items.APPLE), DropdownMenuBuilder.CellCreatorBuilder.ofItemObject()).setDefaultValue(Items.APPLE).setSelections(Registry.ITEM.stream().sorted(Comparator.comparing(Item::toString)).collect(Collectors.toCollection(LinkedHashSet::new))).setSaveConsumer(item -> System.out.println("save this " + item)).build());
+        colors.add(entryBuilder.startDropdownMenu(new LiteralText("lol apple"), DropdownMenuBuilder.TopCellElementBuilder.ofItemObject(Items.APPLE), DropdownMenuBuilder.CellCreatorBuilder.ofItemObject()).setDefaultValue(Items.APPLE).setSelections(Registry.ITEM.stream().sorted(Comparator.comparing(Item::toString)).collect(Collectors.toCollection(LinkedHashSet::new))).setSaveConsumer(item -> System.out.println("save this " + item)).build());
+        colors.add(entryBuilder.startDropdownMenu(new LiteralText("lol apple"), DropdownMenuBuilder.TopCellElementBuilder.ofItemObject(Items.APPLE), DropdownMenuBuilder.CellCreatorBuilder.ofItemObject()).setDefaultValue(Items.APPLE).setSelections(Registry.ITEM.stream().sorted(Comparator.comparing(Item::toString)).collect(Collectors.toCollection(LinkedHashSet::new))).setSaveConsumer(item -> System.out.println("save this " + item)).build());
         testing.addEntry(colors.build());
         return builder;
     }

+ 8 - 6
src/main/java/me/shedaniel/clothconfig2/api/AbstractConfigEntry.java

@@ -4,6 +4,8 @@ import me.shedaniel.clothconfig2.gui.ClothConfigScreen;
 import me.shedaniel.clothconfig2.gui.widget.DynamicElementListWidget;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.text.Text;
 
 import java.util.Optional;
 import java.util.function.Supplier;
@@ -11,29 +13,29 @@ import java.util.function.Supplier;
 @Environment(EnvType.CLIENT)
 public abstract class AbstractConfigEntry<T> extends DynamicElementListWidget.ElementEntry<AbstractConfigEntry<T>> {
     private ClothConfigScreen screen;
-    private Supplier<Optional<String>> errorSupplier;
+    private Supplier<Optional<Text>> errorSupplier;
     
     public abstract boolean isRequiresRestart();
     
     public abstract void setRequiresRestart(boolean requiresRestart);
     
-    public abstract String getFieldName();
+    public abstract Text getFieldName();
     
     public abstract T getValue();
     
-    public final Optional<String> getConfigError() {
+    public final Optional<Text> getConfigError() {
         if (errorSupplier != null && errorSupplier.get().isPresent())
             return errorSupplier.get();
         return getError();
     }
     
-    public void lateRender(int mouseX, int mouseY, float delta) {}
+    public void lateRender(MatrixStack matrices, int mouseX, int mouseY, float delta) {}
     
-    public void setErrorSupplier(Supplier<Optional<String>> errorSupplier) {
+    public void setErrorSupplier(Supplier<Optional<Text>> errorSupplier) {
         this.errorSupplier = errorSupplier;
     }
     
-    public Optional<String> getError() {
+    public Optional<Text> getError() {
         return Optional.empty();
     }
     

+ 4 - 3
src/main/java/me/shedaniel/clothconfig2/api/AbstractConfigListEntry.java

@@ -2,14 +2,15 @@ package me.shedaniel.clothconfig2.api;
 
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
+import net.minecraft.text.Text;
 
 @Environment(EnvType.CLIENT)
 public abstract class AbstractConfigListEntry<T> extends AbstractConfigEntry<T> {
-    private String fieldName;
+    private Text fieldName;
     private boolean editable = true;
     private boolean requiresRestart;
     
-    public AbstractConfigListEntry(String fieldName, boolean requiresRestart) {
+    public AbstractConfigListEntry(Text fieldName, boolean requiresRestart) {
         this.fieldName = fieldName;
         this.requiresRestart = requiresRestart;
     }
@@ -37,7 +38,7 @@ public abstract class AbstractConfigListEntry<T> extends AbstractConfigEntry<T>
     }
     
     @Override
-    public String getFieldName() {
+    public Text getFieldName() {
         return fieldName;
     }
 }

+ 7 - 14
src/main/java/me/shedaniel/clothconfig2/api/ConfigBuilder.java

@@ -5,6 +5,7 @@ import me.shedaniel.clothconfig2.impl.ConfigEntryBuilderImpl;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
 import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.text.Text;
 import net.minecraft.util.Identifier;
 
 import java.util.function.Consumer;
@@ -17,35 +18,27 @@ public interface ConfigBuilder {
         return new ConfigBuilderImpl();
     }
     
-    /**
-     * @deprecated Use {@link ConfigBuilder#create()}
-     */
-    @Deprecated
-    static ConfigBuilder create(Screen parent, String title) {
-        return create().setParentScreen(parent).setTitle(title);
-    }
-    
     ConfigBuilder setFallbackCategory(ConfigCategory fallbackCategory);
     
     Screen getParentScreen();
     
     ConfigBuilder setParentScreen(Screen parent);
     
-    String getTitle();
+    Text getTitle();
     
-    ConfigBuilder setTitle(String title);
+    ConfigBuilder setTitle(Text title);
     
     boolean isEditable();
     
     ConfigBuilder setEditable(boolean editable);
     
-    ConfigCategory getOrCreateCategory(String categoryKey);
+    ConfigCategory getOrCreateCategory(Text categoryKey);
     
-    ConfigBuilder removeCategory(String categoryKey);
+    ConfigBuilder removeCategory(Text categoryKey);
     
-    ConfigBuilder removeCategoryIfExists(String categoryKey);
+    ConfigBuilder removeCategoryIfExists(Text categoryKey);
     
-    boolean hasCategory(String category);
+    boolean hasCategory(Text category);
     
     ConfigBuilder setShouldTabsSmoothScroll(boolean shouldTabsSmoothScroll);
     

+ 2 - 1
src/main/java/me/shedaniel/clothconfig2/api/ConfigCategory.java

@@ -2,6 +2,7 @@ package me.shedaniel.clothconfig2.api;
 
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
+import net.minecraft.text.Text;
 import net.minecraft.util.Identifier;
 
 import java.util.List;
@@ -9,7 +10,7 @@ import java.util.List;
 @Environment(EnvType.CLIENT)
 public interface ConfigCategory {
     
-    String getCategoryKey();
+    Text getCategoryKey();
     
     @Deprecated
     List<Object> getEntries();

+ 60 - 44
src/main/java/me/shedaniel/clothconfig2/api/ConfigEntryBuilder.java

@@ -6,12 +6,16 @@ import me.shedaniel.clothconfig2.gui.entries.DropdownBoxEntry.SelectionTopCellEl
 import me.shedaniel.clothconfig2.impl.ConfigEntryBuilderImpl;
 import me.shedaniel.clothconfig2.impl.builders.*;
 import me.shedaniel.clothconfig2.impl.builders.DropdownMenuBuilder.TopCellElementBuilder;
+import me.shedaniel.math.Color;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
 import net.fabricmc.fabric.mixin.client.keybinding.KeyCodeAccessor;
+import net.minecraft.class_5251;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.options.KeyBinding;
 import net.minecraft.client.util.InputUtil;
+import net.minecraft.text.LiteralText;
+import net.minecraft.text.Text;
 
 import java.util.List;
 import java.util.function.Function;
@@ -23,61 +27,73 @@ public interface ConfigEntryBuilder {
         return ConfigEntryBuilderImpl.create();
     }
     
-    String getResetButtonKey();
+    Text getResetButtonKey();
     
-    ConfigEntryBuilder setResetButtonKey(String resetButtonKey);
+    ConfigEntryBuilder setResetButtonKey(Text resetButtonKey);
     
-    IntListBuilder startIntList(String fieldNameKey, List<Integer> value);
+    IntListBuilder startIntList(Text fieldNameKey, List<Integer> value);
     
-    LongListBuilder startLongList(String fieldNameKey, List<Long> value);
+    LongListBuilder startLongList(Text fieldNameKey, List<Long> value);
     
-    FloatListBuilder startFloatList(String fieldNameKey, List<Float> value);
+    FloatListBuilder startFloatList(Text fieldNameKey, List<Float> value);
     
-    DoubleListBuilder startDoubleList(String fieldNameKey, List<Double> value);
+    DoubleListBuilder startDoubleList(Text fieldNameKey, List<Double> value);
     
-    StringListBuilder startStrList(String fieldNameKey, List<String> value);
+    StringListBuilder startStrList(Text fieldNameKey, List<String> value);
     
-    SubCategoryBuilder startSubCategory(String fieldNameKey);
+    SubCategoryBuilder startSubCategory(Text fieldNameKey);
     
-    SubCategoryBuilder startSubCategory(String fieldNameKey, List<AbstractConfigListEntry> entries);
+    SubCategoryBuilder startSubCategory(Text fieldNameKey, List<AbstractConfigListEntry> entries);
     
-    BooleanToggleBuilder startBooleanToggle(String fieldNameKey, boolean value);
+    BooleanToggleBuilder startBooleanToggle(Text fieldNameKey, boolean value);
     
-    StringFieldBuilder startStrField(String fieldNameKey, String value);
+    StringFieldBuilder startStrField(Text fieldNameKey, String value);
     
-    ColorFieldBuilder startColorField(String fieldNameKey, int value);
+    ColorFieldBuilder startColorField(Text fieldNameKey, int value);
     
-    default ColorFieldBuilder startAlphaColorField(String fieldNameKey, int value) {
+    default ColorFieldBuilder startColorField(Text fieldNameKey, class_5251 color) {
+        return startColorField(fieldNameKey, color.method_27716());
+    }
+    
+    default ColorFieldBuilder startColorField(Text fieldNameKey, Color color) {
+        return startColorField(fieldNameKey, color.getColor() & 0xFFFFFF);
+    }
+    
+    default ColorFieldBuilder startAlphaColorField(Text fieldNameKey, int value) {
         return startColorField(fieldNameKey, value).setAlphaMode(true);
     }
     
-    TextFieldBuilder startTextField(String fieldNameKey, String value);
+    default ColorFieldBuilder startAlphaColorField(Text fieldNameKey, Color color) {
+        return startColorField(fieldNameKey, color.getColor());
+    }
+    
+    TextFieldBuilder startTextField(Text fieldNameKey, String value);
     
-    TextDescriptionBuilder startTextDescription(String value);
+    TextDescriptionBuilder startTextDescription(Text value);
     
-    <T extends Enum<?>> EnumSelectorBuilder<T> startEnumSelector(String fieldNameKey, Class<T> clazz, T value);
+    <T extends Enum<?>> EnumSelectorBuilder<T> startEnumSelector(Text fieldNameKey, Class<T> clazz, T value);
     
-    <T> SelectorBuilder<T> startSelector(String fieldNameKey, T[] valuesArray, T value);
+    <T> SelectorBuilder<T> startSelector(Text fieldNameKey, T[] valuesArray, T value);
     
-    IntFieldBuilder startIntField(String fieldNameKey, int value);
+    IntFieldBuilder startIntField(Text fieldNameKey, int value);
     
-    LongFieldBuilder startLongField(String fieldNameKey, long value);
+    LongFieldBuilder startLongField(Text fieldNameKey, long value);
     
-    FloatFieldBuilder startFloatField(String fieldNameKey, float value);
+    FloatFieldBuilder startFloatField(Text fieldNameKey, float value);
     
-    DoubleFieldBuilder startDoubleField(String fieldNameKey, double value);
+    DoubleFieldBuilder startDoubleField(Text fieldNameKey, double value);
     
-    IntSliderBuilder startIntSlider(String fieldNameKey, int value, int min, int max);
+    IntSliderBuilder startIntSlider(Text fieldNameKey, int value, int min, int max);
     
-    LongSliderBuilder startLongSlider(String fieldNameKey, long value, long min, long max);
+    LongSliderBuilder startLongSlider(Text fieldNameKey, long value, long min, long max);
     
-    KeyCodeBuilder startModifierKeyCodeField(String fieldNameKey, ModifierKeyCode value);
+    KeyCodeBuilder startModifierKeyCodeField(Text fieldNameKey, ModifierKeyCode value);
     
-    default KeyCodeBuilder startKeyCodeField(String fieldNameKey, InputUtil.KeyCode value) {
+    default KeyCodeBuilder startKeyCodeField(Text fieldNameKey, InputUtil.KeyCode value) {
         return startModifierKeyCodeField(fieldNameKey, ModifierKeyCode.of(value, Modifier.none())).setAllowModifiers(false);
     }
     
-    default KeyCodeBuilder fillKeybindingField(String fieldNameKey, KeyBinding value) {
+    default KeyCodeBuilder fillKeybindingField(Text fieldNameKey, KeyBinding value) {
         return startKeyCodeField(fieldNameKey, ((KeyCodeAccessor) value).getKeyCode()).setDefaultValue(value.getDefaultKeyCode()).setSaveConsumer(code -> {
             value.setKeyCode(code);
             KeyBinding.updateKeysByCode();
@@ -85,41 +101,41 @@ public interface ConfigEntryBuilder {
         });
     }
     
-    <T> DropdownMenuBuilder<T> startDropdownMenu(String fieldNameKey, SelectionTopCellElement<T> topCellElement, SelectionCellCreator<T> cellCreator);
+    <T> DropdownMenuBuilder<T> startDropdownMenu(Text fieldNameKey, SelectionTopCellElement<T> topCellElement, SelectionCellCreator<T> cellCreator);
     
-    default <T> DropdownMenuBuilder<T> startDropdownMenu(String fieldNameKey, SelectionTopCellElement<T> topCellElement) {
+    default <T> DropdownMenuBuilder<T> startDropdownMenu(Text fieldNameKey, SelectionTopCellElement<T> topCellElement) {
         return startDropdownMenu(fieldNameKey, topCellElement, new DefaultSelectionCellCreator<>());
     }
     
-    default <T> DropdownMenuBuilder<T> startDropdownMenu(String fieldNameKey, T value, Function<String, T> toObjectFunction, SelectionCellCreator<T> cellCreator) {
-        return startDropdownMenu(fieldNameKey, TopCellElementBuilder.of(value, toObjectFunction, Object::toString), cellCreator);
+    default <T> DropdownMenuBuilder<T> startDropdownMenu(Text fieldNameKey, T value, Function<String, T> toObjectFunction, SelectionCellCreator<T> cellCreator) {
+        return startDropdownMenu(fieldNameKey, TopCellElementBuilder.of(value, toObjectFunction), cellCreator);
     }
     
-    default <T> DropdownMenuBuilder<T> startDropdownMenu(String fieldNameKey, T value, Function<String, T> toObjectFunction, Function<T, String> toStringFunction, SelectionCellCreator<T> cellCreator) {
-        return startDropdownMenu(fieldNameKey, TopCellElementBuilder.of(value, toObjectFunction, toStringFunction), cellCreator);
+    default <T> DropdownMenuBuilder<T> startDropdownMenu(Text fieldNameKey, T value, Function<String, T> toObjectFunction, Function<T, Text> toTextFunction, SelectionCellCreator<T> cellCreator) {
+        return startDropdownMenu(fieldNameKey, TopCellElementBuilder.of(value, toObjectFunction, toTextFunction), cellCreator);
     }
     
-    default <T> DropdownMenuBuilder<T> startDropdownMenu(String fieldNameKey, T value, Function<String, T> toObjectFunction) {
-        return startDropdownMenu(fieldNameKey, TopCellElementBuilder.of(value, toObjectFunction, Object::toString), new DefaultSelectionCellCreator<>());
+    default <T> DropdownMenuBuilder<T> startDropdownMenu(Text fieldNameKey, T value, Function<String, T> toObjectFunction) {
+        return startDropdownMenu(fieldNameKey, TopCellElementBuilder.of(value, toObjectFunction), new DefaultSelectionCellCreator<>());
     }
     
-    default <T> DropdownMenuBuilder<T> startDropdownMenu(String fieldNameKey, T value, Function<String, T> toObjectFunction, Function<T, String> toStringFunction) {
-        return startDropdownMenu(fieldNameKey, TopCellElementBuilder.of(value, toObjectFunction, toStringFunction), new DefaultSelectionCellCreator<>());
+    default <T> DropdownMenuBuilder<T> startDropdownMenu(Text fieldNameKey, T value, Function<String, T> toObjectFunction, Function<T, Text> toTextFunction) {
+        return startDropdownMenu(fieldNameKey, TopCellElementBuilder.of(value, toObjectFunction, toTextFunction), new DefaultSelectionCellCreator<>());
     }
     
-    default DropdownMenuBuilder<String> startStringDropdownMenu(String fieldNameKey, String value, SelectionCellCreator<String> cellCreator) {
-        return startDropdownMenu(fieldNameKey, TopCellElementBuilder.of(value, s -> s, s -> s), cellCreator);
+    default DropdownMenuBuilder<String> startStringDropdownMenu(Text fieldNameKey, String value, SelectionCellCreator<String> cellCreator) {
+        return startDropdownMenu(fieldNameKey, TopCellElementBuilder.of(value, s -> s, LiteralText::new), cellCreator);
     }
     
-    default DropdownMenuBuilder<String> startStringDropdownMenu(String fieldNameKey, String value, Function<String, String> toStringFunction, SelectionCellCreator<String> cellCreator) {
-        return startDropdownMenu(fieldNameKey, TopCellElementBuilder.of(value, s -> s, toStringFunction), cellCreator);
+    default DropdownMenuBuilder<String> startStringDropdownMenu(Text fieldNameKey, String value, Function<String, Text> toTextFunction, SelectionCellCreator<String> cellCreator) {
+        return startDropdownMenu(fieldNameKey, TopCellElementBuilder.of(value, s -> s, toTextFunction), cellCreator);
     }
     
-    default DropdownMenuBuilder<String> startStringDropdownMenu(String fieldNameKey, String value) {
-        return startDropdownMenu(fieldNameKey, TopCellElementBuilder.of(value, s -> s, s -> s), new DefaultSelectionCellCreator<>());
+    default DropdownMenuBuilder<String> startStringDropdownMenu(Text fieldNameKey, String value) {
+        return startDropdownMenu(fieldNameKey, TopCellElementBuilder.of(value, s -> s, LiteralText::new), new DefaultSelectionCellCreator<>());
     }
     
-    default DropdownMenuBuilder<String> startStringDropdownMenu(String fieldNameKey, String value, Function<String, String> toStringFunction) {
-        return startDropdownMenu(fieldNameKey, TopCellElementBuilder.of(value, s -> s, toStringFunction), new DefaultSelectionCellCreator<>());
+    default DropdownMenuBuilder<String> startStringDropdownMenu(Text fieldNameKey, String value, Function<String, Text> toTextFunction) {
+        return startDropdownMenu(fieldNameKey, TopCellElementBuilder.of(value, s -> s, toTextFunction), new DefaultSelectionCellCreator<>());
     }
 }

+ 2 - 3
src/main/java/me/shedaniel/clothconfig2/api/ModifierKeyCode.java

@@ -6,6 +6,7 @@ import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.util.InputUtil;
+import net.minecraft.text.Text;
 
 @Environment(EnvType.CLIENT)
 public interface ModifierKeyCode {
@@ -77,9 +78,7 @@ public interface ModifierKeyCode {
     
     String toString();
     
-    default String getLocalizedName() {
-        return toString();
-    }
+    Text getLocalizedName();
     
     default boolean isUnknown() {
         return getKeyCode().equals(InputUtil.UNKNOWN_KEYCODE);

+ 8 - 22
src/main/java/me/shedaniel/clothconfig2/api/QueuedTooltip.java

@@ -2,7 +2,7 @@ package me.shedaniel.clothconfig2.api;
 
 import com.google.common.collect.Lists;
 import me.shedaniel.math.Point;
-import org.jetbrains.annotations.ApiStatus;
+import net.minecraft.text.Text;
 
 import java.util.Collections;
 import java.util.List;
@@ -10,48 +10,34 @@ import java.util.List;
 public class QueuedTooltip {
     
     private Point location;
-    private List<String> text;
+    private List<Text> text;
     
-    private QueuedTooltip(Point location, List<String> text) {
+    private QueuedTooltip(Point location, List<Text> text) {
         this.location = location;
         this.text = Collections.unmodifiableList(text);
     }
     
-    public static QueuedTooltip create(me.shedaniel.math.api.Point location, List<String> text) {
+    public static QueuedTooltip create(Point location, List<Text> text) {
         return new QueuedTooltip(location, text);
     }
     
-    public static QueuedTooltip create(me.shedaniel.math.api.Point location, String... text) {
+    public static QueuedTooltip create(Point location, Text... text) {
         return QueuedTooltip.create(location, Lists.newArrayList(text));
     }
     
-    public static QueuedTooltip create(Point location, List<String> text) {
-        return new QueuedTooltip(location, text);
-    }
-    
-    public static QueuedTooltip create(Point location, String... text) {
-        return QueuedTooltip.create(location, Lists.newArrayList(text));
-    }
-    
-    @Deprecated
-    @ApiStatus.ScheduledForRemoval
-    public me.shedaniel.math.api.Point getLocation() {
-        return new me.shedaniel.math.api.Point(getPoint());
-    }
-    
     public Point getPoint() {
         return location;
     }
     
     public int getX() {
-        return getLocation().x;
+        return location.x;
     }
     
     public int getY() {
-        return getLocation().y;
+        return location.y;
     }
     
-    public List<String> getText() {
+    public List<Text> getText() {
         return text;
     }
     

+ 83 - 75
src/main/java/me/shedaniel/clothconfig2/gui/ClothConfigScreen.java

@@ -24,12 +24,15 @@ import net.minecraft.client.render.Tessellator;
 import net.minecraft.client.render.VertexFormats;
 import net.minecraft.client.resource.language.I18n;
 import net.minecraft.client.util.InputUtil;
-import net.minecraft.text.LiteralText;
+import net.minecraft.client.util.NarratorManager;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.text.Text;
 import net.minecraft.text.TranslatableText;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.Pair;
 import net.minecraft.util.Tickable;
 import net.minecraft.util.math.MathHelper;
+import net.minecraft.util.math.Matrix4f;
 import org.jetbrains.annotations.Nullable;
 
 import java.util.LinkedHashMap;
@@ -51,38 +54,36 @@ public abstract class ClothConfigScreen extends Screen {
     public ListWidget<AbstractConfigEntry<AbstractConfigEntry>> listWidget;
     private KeyCodeEntry focusedBinding;
     private final Screen parent;
-    private final LinkedHashMap<String, List<AbstractConfigEntry>> tabbedEntries;
-    private final List<Pair<String, Integer>> tabs;
+    private final LinkedHashMap<Text, List<AbstractConfigEntry>> tabbedEntries;
+    private final List<Pair<Text, Integer>> tabs;
     private boolean edited;
     private boolean requiresRestart;
     private final boolean confirmSave;
     private AbstractButtonWidget quitButton, saveButton, applyButton, buttonLeftTab, buttonRightTab;
     private Rectangle tabsBounds, tabsLeftBounds, tabsRightBounds;
-    private final String title;
     private double tabsMaximumScrolled = -1d;
     private final boolean displayErrors;
     private final List<ClothConfigTabButton> tabButtons;
     private boolean smoothScrollingTabs = true;
     private boolean smoothScrollingList;
     private final Identifier defaultBackgroundLocation;
-    private final Map<String, Identifier> categoryBackgroundLocation;
+    private final Map<Text, Identifier> categoryBackgroundLocation;
     private boolean transparentBackground = false;
     private boolean editable = true;
-    @Nullable private String defaultFallbackCategory = null;
+    @Nullable private Text defaultFallbackCategory = null;
     private boolean alwaysShowTabs = false;
     private ModifierKeyCode startedKeyCode = null;
     
     @Deprecated
-    public ClothConfigScreen(Screen parent, String title, Map<String, List<Pair<String, Object>>> o, boolean confirmSave, boolean displayErrors, boolean smoothScrollingList, Identifier defaultBackgroundLocation, Map<String, Identifier> categoryBackgroundLocation) {
-        super(new LiteralText(""));
+    public ClothConfigScreen(Screen parent, Text title, Map<Text, List<Pair<Text, Object>>> o, boolean confirmSave, boolean displayErrors, boolean smoothScrollingList, Identifier defaultBackgroundLocation, Map<Text, Identifier> categoryBackgroundLocation) {
+        super(title);
         this.parent = parent;
-        this.title = title;
         this.tabbedEntries = Maps.newLinkedHashMap();
         this.smoothScrollingList = smoothScrollingList;
         this.defaultBackgroundLocation = defaultBackgroundLocation;
         o.forEach((tab, pairs) -> {
             List<AbstractConfigEntry> list = Lists.newArrayList();
-            for (Pair<String, Object> pair : pairs) {
+            for (Pair<Text, Object> pair : pairs) {
                 if (pair.getRight() instanceof AbstractConfigListEntry) {
                     list.add((AbstractConfigListEntry) pair.getRight());
                 } else {
@@ -93,11 +94,11 @@ public abstract class ClothConfigScreen extends Screen {
             tabbedEntries.put(tab, list);
         });
         TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer;
-        this.tabs = tabbedEntries.keySet().stream().map(s -> new Pair<>(s, textRenderer.getStringWidth(I18n.translate(s)) + 8)).collect(Collectors.toList());
+        this.tabs = tabbedEntries.keySet().stream().map(s -> new Pair<>(s, textRenderer.method_27525(s) + 8)).collect(Collectors.toList());
         this.nextTabIndex = 0;
         this.selectedTabIndex = 0;
         for (int i = 0; i < tabs.size(); i++) {
-            Pair<String, Integer> pair = tabs.get(i);
+            Pair<Text, Integer> pair = tabs.get(i);
             if (pair.getLeft().equals(getFallbackCategory())) {
                 this.nextTabIndex = i;
                 this.selectedTabIndex = i;
@@ -135,14 +136,14 @@ public abstract class ClothConfigScreen extends Screen {
         this.transparentBackground = transparentBackground;
     }
     
-    public String getFallbackCategory() {
+    public Text getFallbackCategory() {
         if (defaultFallbackCategory != null)
             return defaultFallbackCategory;
         return tabs.get(0).getLeft();
     }
     
     @Deprecated
-    public void setFallbackCategory(@Nullable String defaultFallbackCategory) {
+    public void setFallbackCategory(@Nullable Text defaultFallbackCategory) {
         this.defaultFallbackCategory = defaultFallbackCategory;
     }
     
@@ -185,7 +186,7 @@ public abstract class ClothConfigScreen extends Screen {
     @Deprecated
     public void setEdited(boolean edited) {
         this.edited = edited;
-        quitButton.setMessage(edited ? I18n.translate("text.cloth-config.cancel_discard") : I18n.translate("gui.cancel"));
+        quitButton.setMessage(edited ? new TranslatableText("text.cloth-config.cancel_discard") : new TranslatableText("gui.cancel"));
         saveButton.active = edited;
     }
     
@@ -223,20 +224,20 @@ public abstract class ClothConfigScreen extends Screen {
         if (tabbedEntries.size() > selectedTabIndex)
             Lists.newArrayList(tabbedEntries.values()).get(selectedTabIndex).forEach(entry -> listWidget.children().add(entry));
         int buttonWidths = (width - 50 - 12) / 3;
-        addButton(quitButton = new ButtonWidget(25, height - 26, buttonWidths, 20, edited ? I18n.translate("text.cloth-config.cancel_discard") : I18n.translate("gui.cancel"), widget -> {
+        addButton(quitButton = new ButtonWidget(25, height - 26, buttonWidths, 20, edited ? new TranslatableText("text.cloth-config.cancel_discard") : new TranslatableText("gui.cancel"), widget -> {
             if (confirmSave && edited)
-                client.openScreen(new ConfirmScreen(new QuitSaveConsumer(), new TranslatableText("text.cloth-config.quit_config"), new TranslatableText("text.cloth-config.quit_config_sure"), I18n.translate("text.cloth-config.quit_discard"), I18n.translate("gui.cancel")));
+                client.openScreen(new ConfirmScreen(new QuitSaveConsumer(), new TranslatableText("text.cloth-config.quit_config"), new TranslatableText("text.cloth-config.quit_config_sure"), new TranslatableText("text.cloth-config.quit_discard"), new TranslatableText("gui.cancel")));
             else
                 client.openScreen(parent);
         }));
-        addButton(saveButton = new AbstractPressableButtonWidget(25 + 6 + buttonWidths, height - 26, buttonWidths, 20, "") {
+        addButton(saveButton = new AbstractPressableButtonWidget(25 + 6 + buttonWidths, height - 26, buttonWidths, 20, NarratorManager.EMPTY) {
             @Override
             public void onPress() {
                 saveAll(true);
             }
             
             @Override
-            public void render(int int_1, int int_2, float float_1) {
+            public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
                 boolean hasErrors = false;
                 if (displayErrors)
                     for (List<AbstractConfigEntry> entries : Lists.newArrayList(tabbedEntries.values())) {
@@ -249,20 +250,20 @@ public abstract class ClothConfigScreen extends Screen {
                             break;
                     }
                 active = edited && !hasErrors;
-                setMessage(displayErrors && hasErrors ? I18n.translate("text.cloth-config.error_cannot_save") : I18n.translate("text.cloth-config.save_and_done"));
-                super.render(int_1, int_2, float_1);
+                setMessage(displayErrors && hasErrors ? new TranslatableText("text.cloth-config.error_cannot_save") : new TranslatableText("text.cloth-config.save_and_done"));
+                super.render(matrices, mouseX, mouseY, delta);
             }
         });
-        addButton(applyButton = new AbstractPressableButtonWidget(25 + (6 + buttonWidths) * 2, height - 26, buttonWidths, 20, I18n.translate("text.cloth-config.apply")) {
+        addButton(applyButton = new AbstractPressableButtonWidget(25 + (6 + buttonWidths) * 2, height - 26, buttonWidths, 20, new TranslatableText("text.cloth-config.apply")) {
             @Override
             public void onPress() {
                 saveAll(false);
             }
             
             @Override
-            public void render(int int_1, int int_2, float float_1) {
+            public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
                 active = saveButton.active;
-                super.render(int_1, int_2, float_1);
+                super.render(matrices, mouseX, mouseY, delta);
             }
         });
         saveButton.active = edited;
@@ -270,7 +271,7 @@ public abstract class ClothConfigScreen extends Screen {
             tabsBounds = new Rectangle(0, 41, width, 24);
             tabsLeftBounds = new Rectangle(0, 41, 18, 24);
             tabsRightBounds = new Rectangle(width - 18, 41, 18, 24);
-            children.add(buttonLeftTab = new AbstractPressableButtonWidget(4, 44, 12, 18, "") {
+            children.add(buttonLeftTab = new AbstractPressableButtonWidget(4, 44, 12, 18, NarratorManager.EMPTY) {
                 @Override
                 public void onPress() {
                     tabsScrollProgress = Integer.MIN_VALUE;
@@ -279,23 +280,23 @@ public abstract class ClothConfigScreen extends Screen {
                 }
                 
                 @Override
-                public void renderButton(int int_1, int int_2, float float_1) {
+                public void renderButton(MatrixStack matrices, int mouseX, int mouseY, float delta) {
                     client.getTextureManager().bindTexture(CONFIG_TEX);
                     RenderSystem.color4f(1.0F, 1.0F, 1.0F, this.alpha);
                     int int_3 = this.getYImage(this.isHovered());
                     RenderSystem.enableBlend();
                     RenderSystem.blendFuncSeparate(770, 771, 0, 1);
                     RenderSystem.blendFunc(770, 771);
-                    this.drawTexture(x, y, 12, 18 * int_3, width, height);
+                    this.drawTexture(matrices, x, y, 12, 18 * int_3, width, height);
                 }
             });
             int j = 0;
-            for (Pair<String, Integer> tab : tabs) {
-                tabButtons.add(new ClothConfigTabButton(this, j, -100, 43, tab.getRight(), 20, I18n.translate(tab.getLeft())));
+            for (Pair<Text, Integer> tab : tabs) {
+                tabButtons.add(new ClothConfigTabButton(this, j, -100, 43, tab.getRight(), 20, tab.getLeft()));
                 j++;
             }
             children.addAll(tabButtons);
-            children.add(buttonRightTab = new AbstractPressableButtonWidget(width - 16, 44, 12, 18, "") {
+            children.add(buttonRightTab = new AbstractPressableButtonWidget(width - 16, 44, 12, 18, NarratorManager.EMPTY) {
                 @Override
                 public void onPress() {
                     tabsScrollProgress = Integer.MAX_VALUE;
@@ -304,14 +305,14 @@ public abstract class ClothConfigScreen extends Screen {
                 }
                 
                 @Override
-                public void renderButton(int int_1, int int_2, float float_1) {
+                public void renderButton(MatrixStack matrices, int mouseX, int mouseY, float delta) {
                     client.getTextureManager().bindTexture(CONFIG_TEX);
                     RenderSystem.color4f(1.0F, 1.0F, 1.0F, this.alpha);
                     int int_3 = this.getYImage(this.isHovered());
                     RenderSystem.enableBlend();
                     RenderSystem.blendFuncSeparate(770, 771, 0, 1);
                     RenderSystem.blendFunc(770, 771);
-                    this.drawTexture(x, y, 0, 18 * int_3, width, height);
+                    this.drawTexture(matrices, x, y, 0, 18 * int_3, width, height);
                 }
             });
         } else {
@@ -356,7 +357,7 @@ public abstract class ClothConfigScreen extends Screen {
     }
     
     @Override
-    public void render(int int_1, int int_2, float float_1) {
+    public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
         if (isShowingTabs()) {
             if (smoothScrollingTabs) {
                 double change = tabsScrollVelocity * 0.2f;
@@ -385,30 +386,30 @@ public abstract class ClothConfigScreen extends Screen {
             buttonRightTab.active = tabsScrollProgress < getTabsMaximumScrolled() - width + 40;
         }
         if (isTransparentBackground()) {
-            fillGradient(0, 0, this.width, this.height, -1072689136, -804253680);
+            fillGradient(matrices, 0, 0, this.width, this.height, -1072689136, -804253680);
         } else {
             renderDirtBackground(0);
         }
-        listWidget.render(int_1, int_2, float_1);
+        listWidget.render(matrices, mouseX, mouseY, delta);
         ScissorsHandler.INSTANCE.scissor(new Rectangle(listWidget.left, listWidget.top, listWidget.width, listWidget.bottom - listWidget.top));
         for (AbstractConfigEntry child : listWidget.children())
-            child.lateRender(int_1, int_2, float_1);
+            child.lateRender(matrices, mouseX, mouseY, delta);
         ScissorsHandler.INSTANCE.removeLastScissor();
         if (isShowingTabs()) {
-            drawCenteredString(client.textRenderer, title, width / 2, 18, -1);
+            method_27534(matrices, client.textRenderer, title, width / 2, 18, -1);
             Rectangle onlyInnerTabBounds = new Rectangle(tabsBounds.x + 20, tabsBounds.y, tabsBounds.width - 40, tabsBounds.height);
             ScissorsHandler.INSTANCE.scissor(onlyInnerTabBounds);
             if (isTransparentBackground())
-                fillGradient(onlyInnerTabBounds.x, onlyInnerTabBounds.y, onlyInnerTabBounds.getMaxX(), onlyInnerTabBounds.getMaxY(), 0x68000000, 0x68000000);
+                fillGradient(matrices, onlyInnerTabBounds.x, onlyInnerTabBounds.y, onlyInnerTabBounds.getMaxX(), onlyInnerTabBounds.getMaxY(), 0x68000000, 0x68000000);
             else
-                overlayBackground(onlyInnerTabBounds, 32, 32, 32, 255, 255);
-            tabButtons.forEach(widget -> widget.render(int_1, int_2, float_1));
-            drawTabsShades(0, isTransparentBackground() ? 120 : 255);
+                overlayBackground(matrices, onlyInnerTabBounds, 32, 32, 32, 255, 255);
+            tabButtons.forEach(widget -> widget.render(matrices, mouseX, mouseY, delta));
+            drawTabsShades(matrices, 0, isTransparentBackground() ? 120 : 255);
             ScissorsHandler.INSTANCE.removeLastScissor();
-            buttonLeftTab.render(int_1, int_2, float_1);
-            buttonRightTab.render(int_1, int_2, float_1);
+            buttonLeftTab.render(matrices, mouseX, mouseY, delta);
+            buttonRightTab.render(matrices, mouseX, mouseY, delta);
         } else
-            drawCenteredString(client.textRenderer, title, width / 2, 12, -1);
+            method_27534(matrices, client.textRenderer, title, width / 2, 12, -1);
         
         if (displayErrors && isEditable()) {
             List<String> errors = Lists.newArrayList();
@@ -422,10 +423,10 @@ public abstract class ClothConfigScreen extends Screen {
                 String text = "§c" + (errors.size() == 1 ? errors.get(0) : I18n.translate("text.cloth-config.multi_error"));
                 if (isTransparentBackground()) {
                     int stringWidth = client.textRenderer.getStringWidth(text);
-                    fillGradient(8, 9, 20 + stringWidth, 14 + client.textRenderer.fontHeight, 0x68000000, 0x68000000);
+                    fillGradient(matrices, 8, 9, 20 + stringWidth, 14 + client.textRenderer.fontHeight, 0x68000000, 0x68000000);
                 }
-                drawTexture(10, 10, 0, 54, 3, 11);
-                drawString(client.textRenderer, text, 18, 12, -1);
+                drawTexture(matrices, 10, 10, 0, 54, 3, 11);
+                drawString(matrices, client.textRenderer, text, 18, 12, -1);
             }
         } else if (!isEditable()) {
             client.getTextureManager().bindTexture(CONFIG_TEX);
@@ -433,13 +434,13 @@ public abstract class ClothConfigScreen extends Screen {
             String text = "§c" + I18n.translate("text.cloth-config.not_editable");
             if (isTransparentBackground()) {
                 int stringWidth = client.textRenderer.getStringWidth(text);
-                fillGradient(8, 9, 20 + stringWidth, 14 + client.textRenderer.fontHeight, 0x68000000, 0x68000000);
+                fillGradient(matrices, 8, 9, 20 + stringWidth, 14 + client.textRenderer.fontHeight, 0x68000000, 0x68000000);
             }
-            drawTexture(10, 10, 0, 54, 3, 11);
-            drawString(client.textRenderer, text, 18, 12, -1);
+            drawTexture(matrices, 10, 10, 0, 54, 3, 11);
+            drawString(matrices, client.textRenderer, text, 18, 12, -1);
         }
-        super.render(int_1, int_2, float_1);
-        queuedTooltips.forEach(queuedTooltip -> renderTooltip(queuedTooltip.getText(), queuedTooltip.getX(), queuedTooltip.getY()));
+        super.render(matrices, mouseX, mouseY, delta);
+        queuedTooltips.forEach(queuedTooltip -> renderTooltip(matrices, queuedTooltip.getText(), queuedTooltip.getX(), queuedTooltip.getY()));
         queuedTooltips.clear();
     }
     
@@ -447,7 +448,11 @@ public abstract class ClothConfigScreen extends Screen {
         queuedTooltips.add(queuedTooltip);
     }
     
-    private void drawTabsShades(int lightColor, int darkColor) {
+    private void drawTabsShades(MatrixStack matrices, int lightColor, int darkColor) {
+        drawTabsShades(matrices.peek().getModel(), lightColor, darkColor);
+    }
+    
+    private void drawTabsShades(Matrix4f matrix, int lightColor, int darkColor) {
         RenderSystem.enableBlend();
         RenderSystem.blendFuncSeparate(770, 771, 0, 1);
         RenderSystem.disableAlphaTest();
@@ -456,16 +461,16 @@ public abstract class ClothConfigScreen extends Screen {
         Tessellator tessellator = Tessellator.getInstance();
         BufferBuilder buffer = tessellator.getBuffer();
         buffer.begin(7, VertexFormats.POSITION_TEXTURE_COLOR);
-        buffer.vertex(tabsBounds.getMinX() + 20, tabsBounds.getMinY() + 4, 0.0D).texture(0, 1f).color(0, 0, 0, lightColor).next();
-        buffer.vertex(tabsBounds.getMaxX() - 20, tabsBounds.getMinY() + 4, 0.0D).texture(1f, 1f).color(0, 0, 0, lightColor).next();
-        buffer.vertex(tabsBounds.getMaxX() - 20, tabsBounds.getMinY(), 0.0D).texture(1f, 0).color(0, 0, 0, darkColor).next();
-        buffer.vertex(tabsBounds.getMinX() + 20, tabsBounds.getMinY(), 0.0D).texture(0, 0).color(0, 0, 0, darkColor).next();
+        buffer.vertex(matrix, tabsBounds.getMinX() + 20, tabsBounds.getMinY() + 4, 0.0F).texture(0, 1f).color(0, 0, 0, lightColor).next();
+        buffer.vertex(matrix, tabsBounds.getMaxX() - 20, tabsBounds.getMinY() + 4, 0.0F).texture(1f, 1f).color(0, 0, 0, lightColor).next();
+        buffer.vertex(matrix, tabsBounds.getMaxX() - 20, tabsBounds.getMinY(), 0.0F).texture(1f, 0).color(0, 0, 0, darkColor).next();
+        buffer.vertex(matrix, tabsBounds.getMinX() + 20, tabsBounds.getMinY(), 0.0F).texture(0, 0).color(0, 0, 0, darkColor).next();
         tessellator.draw();
         buffer.begin(7, VertexFormats.POSITION_TEXTURE_COLOR);
-        buffer.vertex(tabsBounds.getMinX() + 20, tabsBounds.getMaxY(), 0.0D).texture(0, 1f).color(0, 0, 0, darkColor).next();
-        buffer.vertex(tabsBounds.getMaxX() - 20, tabsBounds.getMaxY(), 0.0D).texture(1f, 1f).color(0, 0, 0, darkColor).next();
-        buffer.vertex(tabsBounds.getMaxX() - 20, tabsBounds.getMaxY() - 4, 0.0D).texture(1f, 0).color(0, 0, 0, lightColor).next();
-        buffer.vertex(tabsBounds.getMinX() + 20, tabsBounds.getMaxY() - 4, 0.0D).texture(0, 0).color(0, 0, 0, lightColor).next();
+        buffer.vertex(matrix, tabsBounds.getMinX() + 20, tabsBounds.getMaxY(), 0.0F).texture(0, 1f).color(0, 0, 0, darkColor).next();
+        buffer.vertex(matrix, tabsBounds.getMaxX() - 20, tabsBounds.getMaxY(), 0.0F).texture(1f, 1f).color(0, 0, 0, darkColor).next();
+        buffer.vertex(matrix, tabsBounds.getMaxX() - 20, tabsBounds.getMaxY() - 4, 0.0F).texture(1f, 0).color(0, 0, 0, lightColor).next();
+        buffer.vertex(matrix, tabsBounds.getMinX() + 20, tabsBounds.getMaxY() - 4, 0.0F).texture(0, 0).color(0, 0, 0, lightColor).next();
         tessellator.draw();
         RenderSystem.enableTexture();
         RenderSystem.shadeModel(7424);
@@ -473,8 +478,11 @@ public abstract class ClothConfigScreen extends Screen {
         RenderSystem.disableBlend();
     }
     
-    @SuppressWarnings("deprecation")
-    protected void overlayBackground(Rectangle rect, int red, int green, int blue, int startAlpha, int endAlpha) {
+    protected void overlayBackground(MatrixStack matrices, Rectangle rect, int red, int green, int blue, int startAlpha, int endAlpha) {
+        overlayBackground(matrices.peek().getModel(), rect, red, green, blue, startAlpha, endAlpha);
+    }
+    
+    protected void overlayBackground(Matrix4f matrix, Rectangle rect, int red, int green, int blue, int startAlpha, int endAlpha) {
         if (isTransparentBackground())
             return;
         Tessellator tessellator = Tessellator.getInstance();
@@ -483,10 +491,10 @@ public abstract class ClothConfigScreen extends Screen {
         RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
         float f = 32.0F;
         buffer.begin(7, VertexFormats.POSITION_TEXTURE_COLOR);
-        buffer.vertex(rect.getMinX(), rect.getMaxY(), 0.0D).texture(rect.getMinX() / 32.0F, rect.getMaxY() / 32.0F).color(red, green, blue, endAlpha).next();
-        buffer.vertex(rect.getMaxX(), rect.getMaxY(), 0.0D).texture(rect.getMaxX() / 32.0F, rect.getMaxY() / 32.0F).color(red, green, blue, endAlpha).next();
-        buffer.vertex(rect.getMaxX(), rect.getMinY(), 0.0D).texture(rect.getMaxX() / 32.0F, rect.getMinY() / 32.0F).color(red, green, blue, startAlpha).next();
-        buffer.vertex(rect.getMinX(), rect.getMinY(), 0.0D).texture(rect.getMinX() / 32.0F, rect.getMinY() / 32.0F).color(red, green, blue, startAlpha).next();
+        buffer.vertex(matrix, rect.getMinX(), rect.getMaxY(), 0.0F).texture(rect.getMinX() / 32.0F, rect.getMaxY() / 32.0F).color(red, green, blue, endAlpha).next();
+        buffer.vertex(matrix, rect.getMaxX(), rect.getMaxY(), 0.0F).texture(rect.getMaxX() / 32.0F, rect.getMaxY() / 32.0F).color(red, green, blue, endAlpha).next();
+        buffer.vertex(matrix, rect.getMaxX(), rect.getMinY(), 0.0F).texture(rect.getMaxX() / 32.0F, rect.getMinY() / 32.0F).color(red, green, blue, startAlpha).next();
+        buffer.vertex(matrix, rect.getMinX(), rect.getMinY(), 0.0F).texture(rect.getMinX() / 32.0F, rect.getMinY() / 32.0F).color(red, green, blue, startAlpha).next();
         tessellator.draw();
     }
     
@@ -602,7 +610,7 @@ public abstract class ClothConfigScreen extends Screen {
             return true;
         if (int_1 == 256 && this.shouldCloseOnEsc()) {
             if (confirmSave && edited)
-                client.openScreen(new ConfirmScreen(new QuitSaveConsumer(), new TranslatableText("text.cloth-config.quit_config"), new TranslatableText("text.cloth-config.quit_config_sure"), I18n.translate("text.cloth-config.quit_discard"), I18n.translate("gui.cancel")));
+                client.openScreen(new ConfirmScreen(new QuitSaveConsumer(), new TranslatableText("text.cloth-config.quit_config"), new TranslatableText("text.cloth-config.quit_config_sure"), new TranslatableText("text.cloth-config.quit_discard"), new TranslatableText("gui.cancel")));
             else
                 client.openScreen(parent);
             return true;
@@ -657,10 +665,10 @@ public abstract class ClothConfigScreen extends Screen {
         }
         
         @Override
-        protected void renderItem(R item, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
+        protected void renderItem(MatrixStack matrices, R item, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
             if (item instanceof AbstractConfigEntry)
                 ((AbstractConfigEntry) item).updateSelected(getFocused() == item);
-            super.renderItem(item, index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta);
+            super.renderItem(matrices, item, index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta);
         }
         
         @Override
@@ -686,18 +694,18 @@ public abstract class ClothConfigScreen extends Screen {
         }
         
         @Override
-        protected void renderBackBackground(BufferBuilder buffer, Tessellator tessellator) {
+        protected void renderBackBackground(MatrixStack matrices, BufferBuilder buffer, Tessellator tessellator) {
             if (!isTransparentBackground())
-                super.renderBackBackground(buffer, tessellator);
+                super.renderBackBackground(matrices, buffer, tessellator);
             else {
-                fillGradient(left, top, right, bottom, 0x68000000, 0x68000000);
+                fillGradient(matrices, left, top, right, bottom, 0x68000000, 0x68000000);
             }
         }
         
         @Override
-        protected void renderHoleBackground(int int_1, int int_2, int int_3, int int_4) {
+        protected void renderHoleBackground(MatrixStack matrices, int int_1, int int_2, int int_3, int int_4) {
             if (!isTransparentBackground())
-                super.renderHoleBackground(int_1, int_2, int_3, int_4);
+                super.renderHoleBackground(matrices, int_1, int_2, int_3, int_4);
         }
     }
     

+ 5 - 3
src/main/java/me/shedaniel/clothconfig2/gui/ClothConfigTabButton.java

@@ -3,6 +3,8 @@ package me.shedaniel.clothconfig2.gui;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
 import net.minecraft.client.gui.widget.AbstractPressableButtonWidget;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.text.Text;
 
 @Environment(EnvType.CLIENT)
 public class ClothConfigTabButton extends AbstractPressableButtonWidget {
@@ -10,7 +12,7 @@ public class ClothConfigTabButton extends AbstractPressableButtonWidget {
     private final int index;
     private final ClothConfigScreen screen;
     
-    public ClothConfigTabButton(ClothConfigScreen screen, int index, int int_1, int int_2, int int_3, int int_4, String string_1) {
+    public ClothConfigTabButton(ClothConfigScreen screen, int index, int int_1, int int_2, int int_3, int int_4, Text string_1) {
         super(int_1, int_2, int_3, int_4, string_1);
         this.index = index;
         this.screen = screen;
@@ -25,9 +27,9 @@ public class ClothConfigTabButton extends AbstractPressableButtonWidget {
     }
     
     @Override
-    public void render(int int_1, int int_2, float float_1) {
+    public void render(MatrixStack matrices, int int_1, int int_2, float float_1) {
         active = index != screen.selectedTabIndex;
-        super.render(int_1, int_2, float_1);
+        super.render(matrices, int_1, int_2, float_1);
     }
     
     @Override

+ 1 - 2
src/main/java/me/shedaniel/clothconfig2/gui/ClothRequiresRestartScreen.java

@@ -5,7 +5,6 @@ import net.fabricmc.api.Environment;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.screen.ConfirmScreen;
 import net.minecraft.client.gui.screen.Screen;
-import net.minecraft.client.resource.language.I18n;
 import net.minecraft.text.TranslatableText;
 
 @Environment(EnvType.CLIENT)
@@ -17,7 +16,7 @@ public class ClothRequiresRestartScreen extends ConfirmScreen {
                 MinecraftClient.getInstance().scheduleStop();
             else
                 MinecraftClient.getInstance().openScreen(parent);
-        }, new TranslatableText("text.cloth-config.restart_required"), new TranslatableText("text.cloth-config.restart_required_sub"), I18n.translate("text.cloth-config.exit_minecraft"), I18n.translate("text.cloth-config.ignore_restart"));
+        }, new TranslatableText("text.cloth-config.restart_required"), new TranslatableText("text.cloth-config.restart_required_sub"), new TranslatableText("text.cloth-config.exit_minecraft"), new TranslatableText("text.cloth-config.ignore_restart"));
     }
     
 }

+ 5 - 4
src/main/java/me/shedaniel/clothconfig2/gui/entries/AbstractListListEntry.java

@@ -2,6 +2,7 @@ package me.shedaniel.clothconfig2.gui.entries;
 
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
+import net.minecraft.text.Text;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.Nullable;
 
@@ -23,10 +24,10 @@ import java.util.stream.Collectors;
 public abstract class AbstractListListEntry<T, C extends AbstractListListEntry.AbstractListCell<T, C, SELF>, SELF extends AbstractListListEntry<T, C, SELF>> extends BaseListEntry<T, C, SELF> {
     
     protected final BiFunction<T, SELF, C> createNewCell;
-    protected Function<T, Optional<String>> cellErrorSupplier;
+    protected Function<T, Optional<Text>> cellErrorSupplier;
     
     @ApiStatus.Internal
-    public AbstractListListEntry(String fieldName, List<T> value, boolean defaultExpanded, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<T>> saveConsumer, Supplier<List<T>> defaultValue, String resetButtonKey, boolean requiresRestart, boolean deleteButtonEnabled, boolean insertInFront, BiFunction<T, SELF, C> createNewCell) {
+    public AbstractListListEntry(Text fieldName, List<T> value, boolean defaultExpanded, Supplier<Optional<Text[]>> tooltipSupplier, Consumer<List<T>> saveConsumer, Supplier<List<T>> defaultValue, Text resetButtonKey, boolean requiresRestart, boolean deleteButtonEnabled, boolean insertInFront, BiFunction<T, SELF, C> createNewCell) {
         super(fieldName, tooltipSupplier, defaultValue, abstractListListEntry -> createNewCell.apply(null, abstractListListEntry), saveConsumer, resetButtonKey, requiresRestart, deleteButtonEnabled, insertInFront);
         this.createNewCell = createNewCell;
         for (T f : value)
@@ -35,11 +36,11 @@ public abstract class AbstractListListEntry<T, C extends AbstractListListEntry.A
         expanded = defaultExpanded;
     }
     
-    public Function<T, Optional<String>> getCellErrorSupplier() {
+    public Function<T, Optional<Text>> getCellErrorSupplier() {
         return cellErrorSupplier;
     }
     
-    public void setCellErrorSupplier(Function<T, Optional<String>> cellErrorSupplier) {
+    public void setCellErrorSupplier(Function<T, Optional<Text>> cellErrorSupplier) {
         this.cellErrorSupplier = cellErrorSupplier;
     }
     

+ 12 - 9
src/main/java/me/shedaniel/clothconfig2/gui/entries/AbstractTextFieldListListEntry.java

@@ -5,6 +5,9 @@ import net.fabricmc.api.Environment;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.gui.widget.TextFieldWidget;
+import net.minecraft.client.util.NarratorManager;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.text.Text;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -29,7 +32,7 @@ import java.util.function.Supplier;
 public abstract class AbstractTextFieldListListEntry<T, C extends AbstractTextFieldListListEntry.AbstractTextFieldListCell<T, C, SELF>, SELF extends AbstractTextFieldListListEntry<T, C, SELF>> extends AbstractListListEntry<T, C, SELF> {
     
     @ApiStatus.Internal
-    public AbstractTextFieldListListEntry(String fieldName, List<T> value, boolean defaultExpanded, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<T>> saveConsumer, Supplier<List<T>> defaultValue, String resetButtonKey, boolean requiresRestart, boolean deleteButtonEnabled, boolean insertInFront, BiFunction<T, SELF, C> createNewCell) {
+    public AbstractTextFieldListListEntry(Text fieldName, List<T> value, boolean defaultExpanded, Supplier<Optional<Text[]>> tooltipSupplier, Consumer<List<T>> saveConsumer, Supplier<List<T>> defaultValue, Text resetButtonKey, boolean requiresRestart, boolean deleteButtonEnabled, boolean insertInFront, BiFunction<T, SELF, C> createNewCell) {
         super(fieldName, value, defaultExpanded, tooltipSupplier, saveConsumer, defaultValue, resetButtonKey, requiresRestart, deleteButtonEnabled, insertInFront, createNewCell);
     }
     
@@ -50,11 +53,11 @@ public abstract class AbstractTextFieldListListEntry<T, C extends AbstractTextFi
             
             final T finalValue = substituteDefault(value);
             
-            widget = new TextFieldWidget(MinecraftClient.getInstance().textRenderer, 0, 0, 100, 18, "") {
+            widget = new TextFieldWidget(MinecraftClient.getInstance().textRenderer, 0, 0, 100, 18, NarratorManager.EMPTY) {
                 @Override
-                public void render(int mouseX, int mouseY, float delta) {
+                public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
                     setFocused(isSelected);
-                    super.render(mouseX, mouseY, delta);
+                    super.render(matrices, mouseX, mouseY, delta);
                 }
             };
             widget.setTextPredicate(this::isValidText);
@@ -68,12 +71,12 @@ public abstract class AbstractTextFieldListListEntry<T, C extends AbstractTextFi
                 }
             });
         }
-    
+        
         @Override
         public void updateSelected(boolean isSelected) {
             this.isSelected = isSelected;
         }
-    
+        
         /**
          * Allows subclasses to substitute default values.
          *
@@ -97,14 +100,14 @@ public abstract class AbstractTextFieldListListEntry<T, C extends AbstractTextFi
         }
         
         @Override
-        public void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
+        public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
             widget.setWidth(entryWidth - 12);
             widget.x = x;
             widget.y = y + 1;
             widget.setEditable(listListEntry.isEditable());
-            widget.render(mouseX, mouseY, delta);
+            widget.render(matrices, mouseX, mouseY, delta);
             if (isSelected && listListEntry.isEditable())
-                fill(x, y + 12, x + entryWidth - 12, y + 13, getConfigError().isPresent() ? 0xffff5555 : 0xffe0e0e0);
+                fill(matrices, x, y + 12, x + entryWidth - 12, y + 13, getConfigError().isPresent() ? 0xffff5555 : 0xffe0e0e0);
         }
         
         @Override

+ 7 - 5
src/main/java/me/shedaniel/clothconfig2/gui/entries/BaseListCell.java

@@ -3,6 +3,8 @@ package me.shedaniel.clothconfig2.gui.entries;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
 import net.minecraft.client.gui.AbstractParentElement;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.text.Text;
 
 import java.util.Optional;
 import java.util.function.Supplier;
@@ -10,27 +12,27 @@ import java.util.function.Supplier;
 @Environment(EnvType.CLIENT)
 public abstract class BaseListCell extends AbstractParentElement {
     
-    private Supplier<Optional<String>> errorSupplier;
+    private Supplier<Optional<Text>> errorSupplier;
     
     public final int getPreferredTextColor() {
         return getConfigError().isPresent() ? 16733525 : 14737632;
     }
     
-    public final Optional<String> getConfigError() {
+    public final Optional<Text> getConfigError() {
         if (errorSupplier != null && errorSupplier.get().isPresent())
             return errorSupplier.get();
         return getError();
     }
     
-    public void setErrorSupplier(Supplier<Optional<String>> errorSupplier) {
+    public void setErrorSupplier(Supplier<Optional<Text>> errorSupplier) {
         this.errorSupplier = errorSupplier;
     }
     
-    public abstract Optional<String> getError();
+    public abstract Optional<Text> getError();
     
     public abstract int getCellHeight();
     
-    public abstract void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta);
+    public abstract void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta);
     
     public void updateSelected(boolean isSelected) {}
     

+ 28 - 25
src/main/java/me/shedaniel/clothconfig2/gui/entries/BaseListEntry.java

@@ -4,7 +4,7 @@ import com.google.common.collect.Lists;
 import com.mojang.blaze3d.systems.RenderSystem;
 import me.shedaniel.clothconfig2.api.QueuedTooltip;
 import me.shedaniel.math.Point;
-import me.shedaniel.math.api.Rectangle;
+import me.shedaniel.math.Rectangle;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
 import net.minecraft.client.MinecraftClient;
@@ -12,9 +12,11 @@ import net.minecraft.client.gui.Element;
 import net.minecraft.client.gui.widget.AbstractButtonWidget;
 import net.minecraft.client.gui.widget.ButtonWidget;
 import net.minecraft.client.render.DiffuseLighting;
-import net.minecraft.client.resource.language.I18n;
 import net.minecraft.client.sound.PositionedSoundInstance;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.sound.SoundEvents;
+import net.minecraft.text.Text;
+import net.minecraft.text.TranslatableText;
 import net.minecraft.util.Identifier;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.NotNull;
@@ -48,30 +50,31 @@ public abstract class BaseListEntry<T, C extends BaseListCell, SELF extends Base
     protected AbstractButtonWidget resetWidget;
     @NotNull protected Function<SELF, C> createNewInstance;
     @NotNull protected Supplier<List<T>> defaultValue;
-    @Nullable protected String addTooltip = I18n.translate("text.cloth-config.list.add"), removeTooltip = I18n.translate("text.cloth-config.list.remove");
+    @Nullable
+    protected Text addTooltip = new TranslatableText("text.cloth-config.list.add"), removeTooltip = new TranslatableText("text.cloth-config.list.remove");
     
     @ApiStatus.Internal
     @Deprecated
-    public BaseListEntry(@NotNull String fieldName, @Nullable Supplier<Optional<String[]>> tooltipSupplier, @NotNull Supplier<List<T>> defaultValue, @NotNull Function<SELF, C> createNewInstance, @Nullable Consumer<List<T>> saveConsumer, String resetButtonKey) {
+    public BaseListEntry(@NotNull Text fieldName, @Nullable Supplier<Optional<Text[]>> tooltipSupplier, @NotNull Supplier<List<T>> defaultValue, @NotNull Function<SELF, C> createNewInstance, @Nullable Consumer<List<T>> saveConsumer, Text resetButtonKey) {
         this(fieldName, tooltipSupplier, defaultValue, createNewInstance, saveConsumer, resetButtonKey, false);
     }
     
     @ApiStatus.Internal
     @Deprecated
-    public BaseListEntry(@NotNull String fieldName, @Nullable Supplier<Optional<String[]>> tooltipSupplier, @NotNull Supplier<List<T>> defaultValue, @NotNull Function<SELF, C> createNewInstance, @Nullable Consumer<List<T>> saveConsumer, String resetButtonKey, boolean requiresRestart) {
+    public BaseListEntry(@NotNull Text fieldName, @Nullable Supplier<Optional<Text[]>> tooltipSupplier, @NotNull Supplier<List<T>> defaultValue, @NotNull Function<SELF, C> createNewInstance, @Nullable Consumer<List<T>> saveConsumer, Text resetButtonKey, boolean requiresRestart) {
         this(fieldName, tooltipSupplier, defaultValue, createNewInstance, saveConsumer, resetButtonKey, requiresRestart, true, true);
     }
     
     @ApiStatus.Internal
     @Deprecated
-    public BaseListEntry(@NotNull String fieldName, @Nullable Supplier<Optional<String[]>> tooltipSupplier, @NotNull Supplier<List<T>> defaultValue, @NotNull Function<SELF, C> createNewInstance, @Nullable Consumer<List<T>> saveConsumer, String resetButtonKey, boolean requiresRestart, boolean deleteButtonEnabled, boolean insertInFront) {
+    public BaseListEntry(@NotNull Text fieldName, @Nullable Supplier<Optional<Text[]>> tooltipSupplier, @NotNull Supplier<List<T>> defaultValue, @NotNull Function<SELF, C> createNewInstance, @Nullable Consumer<List<T>> saveConsumer, Text resetButtonKey, boolean requiresRestart, boolean deleteButtonEnabled, boolean insertInFront) {
         super(fieldName, tooltipSupplier, requiresRestart);
         this.deleteButtonEnabled = deleteButtonEnabled;
         this.insertInFront = insertInFront;
         this.cells = Lists.newArrayList();
         this.labelWidget = new ListLabelWidget();
         this.widgets = Lists.newArrayList(labelWidget);
-        this.resetWidget = new ButtonWidget(0, 0, MinecraftClient.getInstance().textRenderer.getStringWidth(I18n.translate(resetButtonKey)) + 6, 20, I18n.translate(resetButtonKey), widget -> {
+        this.resetWidget = new ButtonWidget(0, 0, MinecraftClient.getInstance().textRenderer.method_27525(resetButtonKey) + 6, 20, resetButtonKey, widget -> {
             widgets.removeAll(cells);
             cells.clear();
             defaultValue.get().stream().map(this::getFromValue).forEach(cells::add);
@@ -102,20 +105,20 @@ public abstract class BaseListEntry<T, C extends BaseListCell, SELF extends Base
     }
     
     @Nullable
-    public String getAddTooltip() {
+    public Text getAddTooltip() {
         return addTooltip;
     }
     
-    public void setAddTooltip(@Nullable String addTooltip) {
+    public void setAddTooltip(@Nullable Text addTooltip) {
         this.addTooltip = addTooltip;
     }
     
     @Nullable
-    public String getRemoveTooltip() {
+    public Text getRemoveTooltip() {
         return removeTooltip;
     }
     
-    public void setRemoveTooltip(@Nullable String removeTooltip) {
+    public void setRemoveTooltip(@Nullable Text removeTooltip) {
         this.removeTooltip = removeTooltip;
     }
     
@@ -146,11 +149,11 @@ public abstract class BaseListEntry<T, C extends BaseListCell, SELF extends Base
     }
     
     @Override
-    public Optional<String> getError() {
-        List<String> errors = cells.stream().map(C::getConfigError).filter(Optional::isPresent).map(Optional::get).collect(Collectors.toList());
+    public Optional<Text> getError() {
+        List<Text> errors = cells.stream().map(C::getConfigError).filter(Optional::isPresent).map(Optional::get).collect(Collectors.toList());
         
         if (errors.size() > 1)
-            return Optional.of(I18n.translate("text.cloth-config.multi_error"));
+            return Optional.of(new TranslatableText("text.cloth-config.multi_error"));
         else
             return errors.stream().findFirst();
     }
@@ -178,24 +181,24 @@ public abstract class BaseListEntry<T, C extends BaseListCell, SELF extends Base
         return isDeleteButtonEnabled() && mouseX >= labelWidget.rectangle.x + 25 && mouseY >= labelWidget.rectangle.y + 3 && mouseX <= labelWidget.rectangle.x + 25 + 11 && mouseY <= labelWidget.rectangle.y + 3 + 11;
     }
     
-    public Optional<String[]> getTooltip(int mouseX, int mouseY) {
+    public Optional<Text[]> getTooltip(int mouseX, int mouseY) {
         if (addTooltip != null && isInsideCreateNew(mouseX, mouseY))
-            return Optional.of(new String[]{addTooltip});
+            return Optional.of(new Text[]{addTooltip});
         if (removeTooltip != null && isInsideDelete(mouseX, mouseY))
-            return Optional.of(new String[]{removeTooltip});
+            return Optional.of(new Text[]{removeTooltip});
         if (getTooltipSupplier() != null)
             return getTooltipSupplier().get();
         return Optional.empty();
     }
     
     @Override
-    public void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
+    public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
         labelWidget.rectangle.x = x - 19;
         labelWidget.rectangle.y = y;
         labelWidget.rectangle.width = entryWidth + 19;
         labelWidget.rectangle.height = 24;
         if (isMouseInside(mouseX, mouseY, x, y, entryWidth, entryHeight)) {
-            Optional<String[]> tooltip = getTooltip(mouseX, mouseY);
+            Optional<Text[]> tooltip = getTooltip(mouseX, mouseY);
             if (tooltip.isPresent() && tooltip.get().length > 0)
                 getScreen().queueTooltip(QueuedTooltip.create(new Point(mouseX, mouseY), tooltip.get()));
         }
@@ -205,19 +208,19 @@ public abstract class BaseListEntry<T, C extends BaseListCell, SELF extends Base
         BaseListCell focused = !expanded || getFocused() == null || !(getFocused() instanceof BaseListCell) ? null : (BaseListCell) getFocused();
         boolean insideCreateNew = isInsideCreateNew(mouseX, mouseY);
         boolean insideDelete = isInsideDelete(mouseX, mouseY);
-        drawTexture(x - 15, y + 4, 24 + 9, (labelWidget.rectangle.contains(mouseX, mouseY) && !insideCreateNew && !insideDelete ? 18 : 0) + (expanded ? 9 : 0), 9, 9);
-        drawTexture(x - 15 + 13, y + 4, 24 + 18, insideCreateNew ? 9 : 0, 9, 9);
+        drawTexture(matrices, x - 15, y + 4, 24 + 9, (labelWidget.rectangle.contains(mouseX, mouseY) && !insideCreateNew && !insideDelete ? 18 : 0) + (expanded ? 9 : 0), 9, 9);
+        drawTexture(matrices, x - 15 + 13, y + 4, 24 + 18, insideCreateNew ? 9 : 0, 9, 9);
         if (isDeleteButtonEnabled())
-            drawTexture(x - 15 + 26, y + 4, 24 + 27, focused == null ? 0 : insideDelete ? 18 : 9, 9, 9);
+            drawTexture(matrices, x - 15 + 26, y + 4, 24 + 27, focused == null ? 0 : insideDelete ? 18 : 9, 9, 9);
         resetWidget.x = x + entryWidth - resetWidget.getWidth();
         resetWidget.y = y;
         resetWidget.active = isEditable() && getDefaultValue().isPresent();
-        resetWidget.render(mouseX, mouseY, delta);
-        MinecraftClient.getInstance().textRenderer.drawWithShadow(I18n.translate(getFieldName()), isDeleteButtonEnabled() ? x + 24 : x + 24 - 9, y + 5, labelWidget.rectangle.contains(mouseX, mouseY) && !resetWidget.isMouseOver(mouseX, mouseY) && !insideDelete && !insideCreateNew ? 0xffe6fe16 : getPreferredTextColor());
+        resetWidget.render(matrices, mouseX, mouseY, delta);
+        MinecraftClient.getInstance().textRenderer.method_27517(matrices, getFieldName(), isDeleteButtonEnabled() ? x + 24 : x + 24 - 9, y + 5, labelWidget.rectangle.contains(mouseX, mouseY) && !resetWidget.isMouseOver(mouseX, mouseY) && !insideDelete && !insideCreateNew ? 0xffe6fe16 : getPreferredTextColor());
         if (expanded) {
             int yy = y + 24;
             for (BaseListCell cell : cells) {
-                cell.render(-1, yy, x + 14, entryWidth - 14, cell.getCellHeight(), mouseX, mouseY, getParent().getFocused() != null && getParent().getFocused().equals(this) && getFocused() != null && getFocused().equals(cell), delta);
+                cell.render(matrices, -1, yy, x + 14, entryWidth - 14, cell.getCellHeight(), mouseX, mouseY, getParent().getFocused() != null && getParent().getFocused().equals(this) && getFocused() != null && getFocused().equals(cell), delta);
                 yy += cell.getCellHeight();
             }
         }

+ 17 - 20
src/main/java/me/shedaniel/clothconfig2/gui/entries/BooleanListEntry.java

@@ -6,8 +6,11 @@ import net.fabricmc.api.Environment;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.gui.widget.ButtonWidget;
-import net.minecraft.client.resource.language.I18n;
+import net.minecraft.client.util.NarratorManager;
 import net.minecraft.client.util.Window;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.text.Text;
+import net.minecraft.text.TranslatableText;
 import org.jetbrains.annotations.ApiStatus;
 
 import java.util.List;
@@ -28,33 +31,27 @@ public class BooleanListEntry extends TooltipListEntry<Boolean> {
     
     @ApiStatus.Internal
     @Deprecated
-    public BooleanListEntry(String fieldName, boolean bool, Consumer<Boolean> saveConsumer) {
-        this(fieldName, bool, "text.cloth-config.reset_value", null, saveConsumer);
-    }
-    
-    @ApiStatus.Internal
-    @Deprecated
-    public BooleanListEntry(String fieldName, boolean bool, String resetButtonKey, Supplier<Boolean> defaultValue, Consumer<Boolean> saveConsumer) {
+    public BooleanListEntry(Text fieldName, boolean bool, Text resetButtonKey, Supplier<Boolean> defaultValue, Consumer<Boolean> saveConsumer) {
         this(fieldName, bool, resetButtonKey, defaultValue, saveConsumer, null);
     }
     
     @ApiStatus.Internal
     @Deprecated
-    public BooleanListEntry(String fieldName, boolean bool, String resetButtonKey, Supplier<Boolean> defaultValue, Consumer<Boolean> saveConsumer, Supplier<Optional<String[]>> tooltipSupplier) {
+    public BooleanListEntry(Text fieldName, boolean bool, Text resetButtonKey, Supplier<Boolean> defaultValue, Consumer<Boolean> saveConsumer, Supplier<Optional<Text[]>> tooltipSupplier) {
         this(fieldName, bool, resetButtonKey, defaultValue, saveConsumer, tooltipSupplier, false);
     }
     
     @ApiStatus.Internal
     @Deprecated
-    public BooleanListEntry(String fieldName, boolean bool, String resetButtonKey, Supplier<Boolean> defaultValue, Consumer<Boolean> saveConsumer, Supplier<Optional<String[]>> tooltipSupplier, boolean requiresRestart) {
+    public BooleanListEntry(Text fieldName, boolean bool, Text resetButtonKey, Supplier<Boolean> defaultValue, Consumer<Boolean> saveConsumer, Supplier<Optional<Text[]>> tooltipSupplier, boolean requiresRestart) {
         super(fieldName, tooltipSupplier, requiresRestart);
         this.defaultValue = defaultValue;
         this.bool = new AtomicBoolean(bool);
-        this.buttonWidget = new ButtonWidget(0, 0, 150, 20, "", widget -> {
+        this.buttonWidget = new ButtonWidget(0, 0, 150, 20, NarratorManager.EMPTY, widget -> {
             BooleanListEntry.this.bool.set(!BooleanListEntry.this.bool.get());
             getScreen().setEdited(true, isRequiresRestart());
         });
-        this.resetButton = new ButtonWidget(0, 0, MinecraftClient.getInstance().textRenderer.getStringWidth(I18n.translate(resetButtonKey)) + 6, 20, I18n.translate(resetButtonKey), widget -> {
+        this.resetButton = new ButtonWidget(0, 0, MinecraftClient.getInstance().textRenderer.method_27525(resetButtonKey) + 6, 20, resetButtonKey, widget -> {
             BooleanListEntry.this.bool.set(defaultValue.get());
             getScreen().setEdited(true, isRequiresRestart());
         });
@@ -79,8 +76,8 @@ public class BooleanListEntry extends TooltipListEntry<Boolean> {
     }
     
     @Override
-    public void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
-        super.render(index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta);
+    public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
+        super.render(matrices, index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta);
         Window window = MinecraftClient.getInstance().getWindow();
         this.resetButton.active = isEditable() && getDefaultValue().isPresent() && defaultValue.get() != bool.get();
         this.resetButton.y = y;
@@ -88,21 +85,21 @@ public class BooleanListEntry extends TooltipListEntry<Boolean> {
         this.buttonWidget.y = y;
         this.buttonWidget.setMessage(getYesNoText(bool.get()));
         if (MinecraftClient.getInstance().textRenderer.isRightToLeft()) {
-            MinecraftClient.getInstance().textRenderer.drawWithShadow(I18n.translate(getFieldName()), window.getScaledWidth() - x - MinecraftClient.getInstance().textRenderer.getStringWidth(I18n.translate(getFieldName())), y + 5, 16777215);
+            MinecraftClient.getInstance().textRenderer.method_27517(matrices, getFieldName(), window.getScaledWidth() - x - MinecraftClient.getInstance().textRenderer.method_27525(getFieldName()), y + 5, 16777215);
             this.resetButton.x = x;
             this.buttonWidget.x = x + resetButton.getWidth() + 2;
         } else {
-            MinecraftClient.getInstance().textRenderer.drawWithShadow(I18n.translate(getFieldName()), x, y + 5, getPreferredTextColor());
+            MinecraftClient.getInstance().textRenderer.method_27517(matrices, getFieldName(), x, y + 5, getPreferredTextColor());
             this.resetButton.x = x + entryWidth - resetButton.getWidth();
             this.buttonWidget.x = x + entryWidth - 150;
         }
         this.buttonWidget.setWidth(150 - resetButton.getWidth() - 2);
-        resetButton.render(mouseX, mouseY, delta);
-        buttonWidget.render(mouseX, mouseY, delta);
+        resetButton.render(matrices, mouseX, mouseY, delta);
+        buttonWidget.render(matrices, mouseX, mouseY, delta);
     }
     
-    public String getYesNoText(boolean bool) {
-        return I18n.translate("text.cloth-config.boolean.value." + bool);
+    public Text getYesNoText(boolean bool) {
+        return new TranslatableText("text.cloth-config.boolean.value." + bool);
     }
     
     @Override

+ 9 - 7
src/main/java/me/shedaniel/clothconfig2/gui/entries/ColorEntry.java

@@ -4,7 +4,9 @@ import me.shedaniel.clothconfig2.gui.widget.ColorDisplayWidget;
 import me.shedaniel.clothconfig2.mixin.ButtonWidgetHooks;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.widget.TextFieldWidget;
-import net.minecraft.client.resource.language.I18n;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.text.Text;
+import net.minecraft.text.TranslatableText;
 import org.apache.commons.lang3.StringUtils;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.Nullable;
@@ -22,7 +24,7 @@ public class ColorEntry extends TextFieldListEntry<Integer> {
     
     @ApiStatus.Internal
     @Deprecated
-    public ColorEntry(String fieldName, int value, String resetButtonKey, Supplier<Integer> defaultValue, Consumer<Integer> saveConsumer, Supplier<Optional<String[]>> tooltipSupplier, boolean requiresRestart) {
+    public ColorEntry(Text fieldName, int value, Text resetButtonKey, Supplier<Integer> defaultValue, Consumer<Integer> saveConsumer, Supplier<Optional<Text[]>> tooltipSupplier, boolean requiresRestart) {
         super(fieldName, 0, resetButtonKey, defaultValue, tooltipSupplier, requiresRestart);
         this.alpha = true;
         ColorValue colorValue = getColorValue(String.valueOf(value));
@@ -40,8 +42,8 @@ public class ColorEntry extends TextFieldListEntry<Integer> {
     }
     
     @Override
-    public void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
-        super.render(index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta);
+    public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
+        super.render(matrices, index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta);
         this.colorDisplayWidget.y = y;
         ColorValue value = getColorValue(textFieldWidget.getText());
         if (!value.hasError())
@@ -51,7 +53,7 @@ public class ColorEntry extends TextFieldListEntry<Integer> {
         } else {
             this.colorDisplayWidget.x = textFieldWidget.x - 23;
         }
-        colorDisplayWidget.render(mouseX, mouseY, delta);
+        colorDisplayWidget.render(matrices, mouseX, mouseY, delta);
     }
     
     @Override
@@ -88,10 +90,10 @@ public class ColorEntry extends TextFieldListEntry<Integer> {
     }
     
     @Override
-    public Optional<String> getError() {
+    public Optional<Text> getError() {
         ColorValue colorValue = getColorValue(this.textFieldWidget.getText());
         if (colorValue.hasError())
-            return Optional.of(I18n.translate("text.cloth-config.error.color." + colorValue.getError().name().toLowerCase(Locale.ROOT)));
+            return Optional.of(new TranslatableText("text.cloth-config.error.color." + colorValue.getError().name().toLowerCase(Locale.ROOT)));
         return super.getError();
     }
     

+ 10 - 15
src/main/java/me/shedaniel/clothconfig2/gui/entries/DoubleListEntry.java

@@ -3,7 +3,8 @@ package me.shedaniel.clothconfig2.gui.entries;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
 import net.minecraft.client.gui.widget.TextFieldWidget;
-import net.minecraft.client.resource.language.I18n;
+import net.minecraft.text.Text;
+import net.minecraft.text.TranslatableText;
 import org.jetbrains.annotations.ApiStatus;
 
 import java.util.Optional;
@@ -18,7 +19,7 @@ public class DoubleListEntry extends TextFieldListEntry<Double> {
         StringBuilder stringBuilder_1 = new StringBuilder();
         char[] var2 = s.toCharArray();
         int var3 = var2.length;
-    
+        
         for (char c : var2)
             if (Character.isDigit(c) || c == '-' || c == '.')
                 stringBuilder_1.append(c);
@@ -30,13 +31,7 @@ public class DoubleListEntry extends TextFieldListEntry<Double> {
     
     @ApiStatus.Internal
     @Deprecated
-    public DoubleListEntry(String fieldName, Double value, Consumer<Double> saveConsumer) {
-        this(fieldName, value, "text.cloth-config.reset_value", null, saveConsumer);
-    }
-    
-    @ApiStatus.Internal
-    @Deprecated
-    public DoubleListEntry(String fieldName, Double value, String resetButtonKey, Supplier<Double> defaultValue, Consumer<Double> saveConsumer) {
+    public DoubleListEntry(Text fieldName, Double value, Text resetButtonKey, Supplier<Double> defaultValue, Consumer<Double> saveConsumer) {
         super(fieldName, value, resetButtonKey, defaultValue);
         this.minimum = -Double.MAX_VALUE;
         this.maximum = Double.MAX_VALUE;
@@ -45,13 +40,13 @@ public class DoubleListEntry extends TextFieldListEntry<Double> {
     
     @ApiStatus.Internal
     @Deprecated
-    public DoubleListEntry(String fieldName, Double value, String resetButtonKey, Supplier<Double> defaultValue, Consumer<Double> saveConsumer, Supplier<Optional<String[]>> tooltipSupplier) {
+    public DoubleListEntry(Text fieldName, Double value, Text resetButtonKey, Supplier<Double> defaultValue, Consumer<Double> saveConsumer, Supplier<Optional<Text[]>> tooltipSupplier) {
         this(fieldName, value, resetButtonKey, defaultValue, saveConsumer, tooltipSupplier, false);
     }
     
     @ApiStatus.Internal
     @Deprecated
-    public DoubleListEntry(String fieldName, Double value, String resetButtonKey, Supplier<Double> defaultValue, Consumer<Double> saveConsumer, Supplier<Optional<String[]>> tooltipSupplier, boolean requiresRestart) {
+    public DoubleListEntry(Text fieldName, Double value, Text resetButtonKey, Supplier<Double> defaultValue, Consumer<Double> saveConsumer, Supplier<Optional<Text[]>> tooltipSupplier, boolean requiresRestart) {
         super(fieldName, value, resetButtonKey, defaultValue, tooltipSupplier, requiresRestart);
         this.minimum = -Double.MAX_VALUE;
         this.maximum = Double.MAX_VALUE;
@@ -107,15 +102,15 @@ public class DoubleListEntry extends TextFieldListEntry<Double> {
     }
     
     @Override
-    public Optional<String> getError() {
+    public Optional<Text> getError() {
         try {
             double i = Double.parseDouble(textFieldWidget.getText());
             if (i > maximum)
-                return Optional.of(I18n.translate("text.cloth-config.error.too_large", maximum));
+                return Optional.of(new TranslatableText("text.cloth-config.error.too_large", maximum));
             else if (i < minimum)
-                return Optional.of(I18n.translate("text.cloth-config.error.too_small", minimum));
+                return Optional.of(new TranslatableText("text.cloth-config.error.too_small", minimum));
         } catch (NumberFormatException ex) {
-            return Optional.of(I18n.translate("text.cloth-config.error.not_valid_number_double"));
+            return Optional.of(new TranslatableText("text.cloth-config.error.not_valid_number_double"));
         }
         return super.getError();
     }

+ 9 - 8
src/main/java/me/shedaniel/clothconfig2/gui/entries/DoubleListListEntry.java

@@ -2,7 +2,8 @@ package me.shedaniel.clothconfig2.gui.entries;
 
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
-import net.minecraft.client.resource.language.I18n;
+import net.minecraft.text.Text;
+import net.minecraft.text.TranslatableText;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -19,19 +20,19 @@ public class DoubleListListEntry extends AbstractTextFieldListListEntry<Double,
     
     @ApiStatus.Internal
     @Deprecated
-    public DoubleListListEntry(String fieldName, List<Double> value, boolean defaultExpanded, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<Double>> saveConsumer, Supplier<List<Double>> defaultValue, String resetButtonKey) {
+    public DoubleListListEntry(Text fieldName, List<Double> value, boolean defaultExpanded, Supplier<Optional<Text[]>> tooltipSupplier, Consumer<List<Double>> saveConsumer, Supplier<List<Double>> defaultValue, Text resetButtonKey) {
         this(fieldName, value, defaultExpanded, tooltipSupplier, saveConsumer, defaultValue, resetButtonKey, false);
     }
     
     @ApiStatus.Internal
     @Deprecated
-    public DoubleListListEntry(String fieldName, List<Double> value, boolean defaultExpanded, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<Double>> saveConsumer, Supplier<List<Double>> defaultValue, String resetButtonKey, boolean requiresRestart) {
+    public DoubleListListEntry(Text fieldName, List<Double> value, boolean defaultExpanded, Supplier<Optional<Text[]>> tooltipSupplier, Consumer<List<Double>> saveConsumer, Supplier<List<Double>> defaultValue, Text resetButtonKey, boolean requiresRestart) {
         this(fieldName, value, defaultExpanded, tooltipSupplier, saveConsumer, defaultValue, resetButtonKey, requiresRestart, true, true);
     }
     
     @ApiStatus.Internal
     @Deprecated
-    public DoubleListListEntry(String fieldName, List<Double> value, boolean defaultExpanded, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<Double>> saveConsumer, Supplier<List<Double>> defaultValue, String resetButtonKey, boolean requiresRestart, boolean deleteButtonEnabled, boolean insertInFront) {
+    public DoubleListListEntry(Text fieldName, List<Double> value, boolean defaultExpanded, Supplier<Optional<Text[]>> tooltipSupplier, Consumer<List<Double>> saveConsumer, Supplier<List<Double>> defaultValue, Text resetButtonKey, boolean requiresRestart, boolean deleteButtonEnabled, boolean insertInFront) {
         super(fieldName, value, defaultExpanded, tooltipSupplier, saveConsumer, defaultValue, resetButtonKey, requiresRestart, deleteButtonEnabled, insertInFront, DoubleListCell::new);
         this.minimum = Double.NEGATIVE_INFINITY;
         this.maximum = Double.POSITIVE_INFINITY;
@@ -81,15 +82,15 @@ public class DoubleListListEntry extends AbstractTextFieldListListEntry<Double,
         }
         
         @Override
-        public Optional<String> getError() {
+        public Optional<Text> getError() {
             try {
                 double i = Double.parseDouble(widget.getText());
                 if (i > listListEntry.maximum)
-                    return Optional.of(I18n.translate("text.cloth-config.error.too_large", listListEntry.maximum));
+                    return Optional.of(new TranslatableText("text.cloth-config.error.too_large", listListEntry.maximum));
                 else if (i < listListEntry.minimum)
-                    return Optional.of(I18n.translate("text.cloth-config.error.too_small", listListEntry.minimum));
+                    return Optional.of(new TranslatableText("text.cloth-config.error.too_small", listListEntry.minimum));
             } catch (NumberFormatException ex) {
-                return Optional.of(I18n.translate("text.cloth-config.error.not_valid_number_double"));
+                return Optional.of(new TranslatableText("text.cloth-config.error.not_valid_number_double"));
             }
             return Optional.empty();
         }

+ 76 - 75
src/main/java/me/shedaniel/clothconfig2/gui/entries/DropdownBoxEntry.java

@@ -5,10 +5,7 @@ import com.google.common.collect.Lists;
 import com.mojang.blaze3d.systems.RenderSystem;
 import me.shedaniel.clothconfig2.ClothConfigInitializer;
 import me.shedaniel.clothconfig2.api.ScissorsHandler;
-import me.shedaniel.clothconfig2.gui.widget.DynamicEntryListWidget.SmoothScrollingSettings;
-import me.shedaniel.clothconfig2.gui.widget.DynamicNewSmoothScrollingEntryListWidget.Interpolation;
-import me.shedaniel.clothconfig2.gui.widget.DynamicNewSmoothScrollingEntryListWidget.Precision;
-import me.shedaniel.math.api.Rectangle;
+import me.shedaniel.math.Rectangle;
 import me.shedaniel.math.impl.PointHelper;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
@@ -22,8 +19,12 @@ import net.minecraft.client.gui.widget.TextFieldWidget;
 import net.minecraft.client.render.BufferBuilder;
 import net.minecraft.client.render.Tessellator;
 import net.minecraft.client.render.VertexFormats;
-import net.minecraft.client.resource.language.I18n;
+import net.minecraft.client.util.NarratorManager;
 import net.minecraft.client.util.Window;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.text.LiteralText;
+import net.minecraft.text.Text;
+import net.minecraft.text.TranslatableText;
 import net.minecraft.util.math.MathHelper;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.NotNull;
@@ -47,11 +48,11 @@ public class DropdownBoxEntry<T> extends TooltipListEntry<T> {
     
     @ApiStatus.Internal
     @Deprecated
-    public DropdownBoxEntry(String fieldName, @NotNull String resetButtonKey, @Nullable Supplier<Optional<String[]>> tooltipSupplier, boolean requiresRestart, @Nullable Supplier<T> defaultValue, @Nullable Consumer<T> saveConsumer, @Nullable Iterable<T> selections, @NotNull SelectionTopCellElement<T> topRenderer, @NotNull SelectionCellCreator<T> cellCreator) {
-        super(I18n.translate(fieldName), tooltipSupplier, requiresRestart);
+    public DropdownBoxEntry(Text fieldName, @NotNull Text resetButtonKey, @Nullable Supplier<Optional<Text[]>> tooltipSupplier, boolean requiresRestart, @Nullable Supplier<T> defaultValue, @Nullable Consumer<T> saveConsumer, @Nullable Iterable<T> selections, @NotNull SelectionTopCellElement<T> topRenderer, @NotNull SelectionCellCreator<T> cellCreator) {
+        super(fieldName, tooltipSupplier, requiresRestart);
         this.defaultValue = defaultValue;
         this.saveConsumer = saveConsumer;
-        this.resetButton = new ButtonWidget(0, 0, MinecraftClient.getInstance().textRenderer.getStringWidth(I18n.translate(resetButtonKey)) + 6, 20, I18n.translate(resetButtonKey), widget -> {
+        this.resetButton = new ButtonWidget(0, 0, MinecraftClient.getInstance().textRenderer.method_27525(resetButtonKey) + 6, 20, resetButtonKey, widget -> {
             selectionElement.topRenderer.setValue(defaultValue.get());
             getScreen().setEdited(true, isRequiresRestart());
         });
@@ -59,25 +60,25 @@ public class DropdownBoxEntry<T> extends TooltipListEntry<T> {
     }
     
     @Override
-    public void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
-        super.render(index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta);
+    public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
+        super.render(matrices, index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta);
         Window window = MinecraftClient.getInstance().getWindow();
         this.resetButton.active = isEditable() && getDefaultValue().isPresent() && (!defaultValue.get().equals(getValue()) || getConfigError().isPresent());
         this.resetButton.y = y;
         this.selectionElement.active = isEditable();
         this.selectionElement.bounds.y = y;
         if (MinecraftClient.getInstance().textRenderer.isRightToLeft()) {
-            MinecraftClient.getInstance().textRenderer.drawWithShadow(I18n.translate(getFieldName()), window.getScaledWidth() - x - MinecraftClient.getInstance().textRenderer.getStringWidth(I18n.translate(getFieldName())), y + 5, getPreferredTextColor());
+            MinecraftClient.getInstance().textRenderer.method_27517(matrices, getFieldName(), window.getScaledWidth() - x - MinecraftClient.getInstance().textRenderer.method_27525(getFieldName()), y + 5, getPreferredTextColor());
             this.resetButton.x = x;
             this.selectionElement.bounds.x = x + resetButton.getWidth() + 1;
         } else {
-            MinecraftClient.getInstance().textRenderer.drawWithShadow(I18n.translate(getFieldName()), x, y + 5, getPreferredTextColor());
+            MinecraftClient.getInstance().textRenderer.method_27517(matrices, getFieldName(), x, y + 5, getPreferredTextColor());
             this.resetButton.x = x + entryWidth - resetButton.getWidth();
             this.selectionElement.bounds.x = x + entryWidth - 150 + 1;
         }
         this.selectionElement.bounds.width = 150 - resetButton.getWidth() - 4;
-        resetButton.render(mouseX, mouseY, delta);
-        selectionElement.render(mouseX, mouseY, delta);
+        resetButton.render(matrices, mouseX, mouseY, delta);
+        selectionElement.render(matrices, mouseX, mouseY, delta);
     }
     
     @Override
@@ -118,13 +119,13 @@ public class DropdownBoxEntry<T> extends TooltipListEntry<T> {
     }
     
     @Override
-    public Optional<String> getError() {
+    public Optional<Text> getError() {
         return selectionElement.topRenderer.getError();
     }
     
     @Override
-    public void lateRender(int mouseX, int mouseY, float delta) {
-        selectionElement.lateRender(mouseX, mouseY, delta);
+    public void lateRender(MatrixStack matrices, int mouseX, int mouseY, float delta) {
+        selectionElement.lateRender(matrices, mouseX, mouseY, delta);
     }
     
     @Override
@@ -157,12 +158,12 @@ public class DropdownBoxEntry<T> extends TooltipListEntry<T> {
         }
         
         @Override
-        public void render(int mouseX, int mouseY, float delta) {
-            fill(bounds.x, bounds.y, bounds.x + bounds.width, bounds.y + bounds.height, -6250336);
-            fill(bounds.x + 1, bounds.y + 1, bounds.x + bounds.width - 1, bounds.y + bounds.height - 1, -16777216);
-            topRenderer.render(mouseX, mouseY, bounds.x, bounds.y, bounds.width, bounds.height, delta);
+        public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
+            fill(matrices, bounds.x, bounds.y, bounds.x + bounds.width, bounds.y + bounds.height, -6250336);
+            fill(matrices, bounds.x + 1, bounds.y + 1, bounds.x + bounds.width - 1, bounds.y + bounds.height - 1, -16777216);
+            topRenderer.render(matrices, mouseX, mouseY, bounds.x, bounds.y, bounds.width, bounds.height, delta);
             if (menu.isExpanded())
-                menu.render(mouseX, mouseY, bounds, delta);
+                menu.render(matrices, mouseX, mouseY, bounds, delta);
         }
         
         @Deprecated
@@ -177,9 +178,9 @@ public class DropdownBoxEntry<T> extends TooltipListEntry<T> {
             return false;
         }
         
-        public void lateRender(int mouseX, int mouseY, float delta) {
+        public void lateRender(MatrixStack matrices, int mouseX, int mouseY, float delta) {
             if (menu.isExpanded())
-                menu.lateRender(mouseX, mouseY, delta);
+                menu.lateRender(matrices, mouseX, mouseY, delta);
         }
         
         public int getMorePossibleHeight() {
@@ -229,9 +230,9 @@ public class DropdownBoxEntry<T> extends TooltipListEntry<T> {
         
         public abstract void initCells();
         
-        public abstract void render(int mouseX, int mouseY, Rectangle rectangle, float delta);
+        public abstract void render(MatrixStack matrices, int mouseX, int mouseY, Rectangle rectangle, float delta);
         
-        public abstract void lateRender(int mouseX, int mouseY, float delta);
+        public abstract void lateRender(MatrixStack matrices, int mouseX, int mouseY, float delta);
         
         public abstract int getHeight();
         
@@ -247,7 +248,7 @@ public class DropdownBoxEntry<T> extends TooltipListEntry<T> {
         @NotNull protected ImmutableList<R> selections;
         @NotNull protected List<SelectionCellElement<R>> cells;
         @NotNull protected List<SelectionCellElement<R>> currentElements;
-        protected String lastSearchKeyword = "";
+        protected Text lastSearchKeyword = NarratorManager.EMPTY;
         protected Rectangle lastRectangle;
         protected boolean scrolling;
         protected double scroll, target;
@@ -287,14 +288,14 @@ public class DropdownBoxEntry<T> extends TooltipListEntry<T> {
         
         public void search() {
             currentElements.clear();
-            String keyword = this.lastSearchKeyword.toLowerCase();
+            String keyword = this.lastSearchKeyword.getString().toLowerCase();
             for (SelectionCellElement<R> cell : cells) {
-                String key = cell.getSearchKey();
-                if (key == null || key.toLowerCase().contains(keyword))
+                Text key = cell.getSearchKey();
+                if (key == null || key.getString().toLowerCase().contains(keyword))
                     currentElements.add(cell);
             }
             if (!keyword.isEmpty()) {
-                Comparator<SelectionCellElement<?>> c = Comparator.comparingDouble(i -> i.getSearchKey() == null ? Double.MAX_VALUE : similarity(i.getSearchKey(), keyword));
+                Comparator<SelectionCellElement<?>> c = Comparator.comparingDouble(i -> i.getSearchKey() == null ? Double.MAX_VALUE : similarity(i.getSearchKey().getString(), keyword));
                 currentElements.sort(c.reversed());
             }
             scrollTo(0, false);
@@ -340,7 +341,7 @@ public class DropdownBoxEntry<T> extends TooltipListEntry<T> {
         }
         
         @Override
-        public void render(int mouseX, int mouseY, Rectangle rectangle, float delta) {
+        public void render(MatrixStack matrices, int mouseX, int mouseY, Rectangle rectangle, float delta) {
             if (!getEntry().selectionElement.topRenderer.getSearchTerm().equals(lastSearchKeyword)) {
                 lastSearchKeyword = getEntry().selectionElement.topRenderer.getSearchTerm();
                 search();
@@ -357,11 +358,11 @@ public class DropdownBoxEntry<T> extends TooltipListEntry<T> {
         }
         
         @Override
-        public void lateRender(int mouseX, int mouseY, float delta) {
+        public void lateRender(MatrixStack matrices, int mouseX, int mouseY, float delta) {
             int last10Height = getHeight();
             int cWidth = getCellCreator().getCellWidth();
-            fill(lastRectangle.x, lastRectangle.y + lastRectangle.height, lastRectangle.x + cWidth, lastRectangle.y + lastRectangle.height + last10Height + 1, -6250336);
-            fill(lastRectangle.x + 1, lastRectangle.y + lastRectangle.height + 1, lastRectangle.x + cWidth - 1, lastRectangle.y + lastRectangle.height + last10Height, -16777216);
+            fill(matrices, lastRectangle.x, lastRectangle.y + lastRectangle.height, lastRectangle.x + cWidth, lastRectangle.y + lastRectangle.height + last10Height + 1, -6250336);
+            fill(matrices, lastRectangle.x + 1, lastRectangle.y + lastRectangle.height + 1, lastRectangle.x + cWidth - 1, lastRectangle.y + lastRectangle.height + last10Height, -16777216);
             RenderSystem.pushMatrix();
             RenderSystem.translatef(0, 0, 300f);
             
@@ -369,17 +370,17 @@ public class DropdownBoxEntry<T> extends TooltipListEntry<T> {
             double yy = lastRectangle.y + lastRectangle.height - scroll;
             for (SelectionCellElement<R> cell : currentElements) {
                 if (yy + getCellCreator().getCellHeight() >= lastRectangle.y + lastRectangle.height && yy <= lastRectangle.y + lastRectangle.height + last10Height + 1)
-                    cell.render(mouseX, mouseY, lastRectangle.x, (int) yy, getMaxScrollPosition() > 6 ? getCellCreator().getCellWidth() - 6 : getCellCreator().getCellWidth(), getCellCreator().getCellHeight(), delta);
+                    cell.render(matrices, mouseX, mouseY, lastRectangle.x, (int) yy, getMaxScrollPosition() > 6 ? getCellCreator().getCellWidth() - 6 : getCellCreator().getCellWidth(), getCellCreator().getCellHeight(), delta);
                 else
-                    cell.dontRender(delta);
+                    cell.dontRender(matrices, delta);
                 yy += getCellCreator().getCellHeight();
             }
             ScissorsHandler.INSTANCE.removeLastScissor();
             
             if (currentElements.isEmpty()) {
                 TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer;
-                String s = I18n.translate("text.cloth-config.dropdown.value.unknown");
-                textRenderer.drawWithShadow(s, lastRectangle.x + getCellCreator().getCellWidth() / 2f - textRenderer.getStringWidth(s) / 2f, lastRectangle.y + lastRectangle.height + 3, -1);
+                Text text = new TranslatableText("text.cloth-config.dropdown.value.unknown");
+                textRenderer.method_27517(matrices, text, lastRectangle.x + getCellCreator().getCellWidth() / 2f - textRenderer.method_27525(text) / 2f, lastRectangle.y + lastRectangle.height + 3, -1);
             }
             
             if (getMaxScrollPosition() > 6) {
@@ -509,19 +510,19 @@ public class DropdownBoxEntry<T> extends TooltipListEntry<T> {
     }
     
     public static class DefaultSelectionCellCreator<R> extends SelectionCellCreator<R> {
-        protected Function<R, String> toStringFunction;
+        protected Function<R, Text> toTextFunction;
         
-        public DefaultSelectionCellCreator(Function<R, String> toStringFunction) {
-            this.toStringFunction = toStringFunction;
+        public DefaultSelectionCellCreator(Function<R, Text> toTextFunction) {
+            this.toTextFunction = toTextFunction;
         }
         
         public DefaultSelectionCellCreator() {
-            this(Object::toString);
+            this(r -> new LiteralText(r.toString()));
         }
         
         @Override
         public SelectionCellElement<R> create(R selection) {
-            return new DefaultSelectionCellElement<>(selection, toStringFunction);
+            return new DefaultSelectionCellElement<>(selection, toTextFunction);
         }
         
         @Override
@@ -543,12 +544,12 @@ public class DropdownBoxEntry<T> extends TooltipListEntry<T> {
             return entry;
         }
         
-        public abstract void render(int mouseX, int mouseY, int x, int y, int width, int height, float delta);
+        public abstract void render(MatrixStack matrices, int mouseX, int mouseY, int x, int y, int width, int height, float delta);
         
-        public abstract void dontRender(float delta);
+        public abstract void dontRender(MatrixStack matrices, float delta);
         
         @Nullable
-        public abstract String getSearchKey();
+        public abstract Text getSearchKey();
         
         @Nullable
         public abstract R getSelection();
@@ -561,15 +562,15 @@ public class DropdownBoxEntry<T> extends TooltipListEntry<T> {
         protected int width;
         protected int height;
         protected boolean rendering;
-        protected Function<R, String> toStringFunction;
+        protected Function<R, Text> toTextFunction;
         
-        public DefaultSelectionCellElement(R r, Function<R, String> toStringFunction) {
+        public DefaultSelectionCellElement(R r, Function<R, Text> toTextFunction) {
             this.r = r;
-            this.toStringFunction = toStringFunction;
+            this.toTextFunction = toTextFunction;
         }
         
         @Override
-        public void render(int mouseX, int mouseY, int x, int y, int width, int height, float delta) {
+        public void render(MatrixStack matrices, int mouseX, int mouseY, int x, int y, int width, int height, float delta) {
             rendering = true;
             this.x = x;
             this.y = y;
@@ -577,19 +578,19 @@ public class DropdownBoxEntry<T> extends TooltipListEntry<T> {
             this.height = height;
             boolean b = mouseX >= x && mouseX <= x + width && mouseY >= y && mouseY <= y + height;
             if (b)
-                fill(x + 1, y + 1, x + width - 1, y + height - 1, -15132391);
-            MinecraftClient.getInstance().textRenderer.drawWithShadow(toStringFunction.apply(r), x + 6, y + 3, b ? 16777215 : 8947848);
+                fill(matrices, x + 1, y + 1, x + width - 1, y + height - 1, -15132391);
+            MinecraftClient.getInstance().textRenderer.method_27517(matrices, toTextFunction.apply(r), x + 6, y + 3, b ? 16777215 : 8947848);
         }
         
         @Override
-        public void dontRender(float delta) {
+        public void dontRender(MatrixStack matrices, float delta) {
             rendering = false;
         }
         
         @Nullable
         @Override
-        public String getSearchKey() {
-            return toStringFunction.apply(r);
+        public Text getSearchKey() {
+            return toTextFunction.apply(r);
         }
         
         @Nullable
@@ -624,11 +625,11 @@ public class DropdownBoxEntry<T> extends TooltipListEntry<T> {
         
         public abstract void setValue(R value);
         
-        public abstract String getSearchTerm();
+        public abstract Text getSearchTerm();
         
-        public abstract Optional<String> getError();
+        public abstract Optional<Text> getError();
         
-        public final Optional<String> getConfigError() {
+        public final Optional<Text> getConfigError() {
             return entry.getConfigError();
         }
         
@@ -655,24 +656,24 @@ public class DropdownBoxEntry<T> extends TooltipListEntry<T> {
             }
         }
         
-        public abstract void render(int mouseX, int mouseY, int x, int y, int width, int height, float delta);
+        public abstract void render(MatrixStack matrices, int mouseX, int mouseY, int x, int y, int width, int height, float delta);
     }
     
     public static class DefaultSelectionTopCellElement<R> extends SelectionTopCellElement<R> {
         protected TextFieldWidget textFieldWidget;
         protected Function<String, R> toObjectFunction;
-        protected Function<R, String> toStringFunction;
+        protected Function<R, Text> toTextFunction;
         protected R value;
         
-        public DefaultSelectionTopCellElement(R value, Function<String, R> toObjectFunction, Function<R, String> toStringFunction) {
+        public DefaultSelectionTopCellElement(R value, Function<String, R> toObjectFunction, Function<R, Text> toTextFunction) {
             this.value = Objects.requireNonNull(value);
             this.toObjectFunction = Objects.requireNonNull(toObjectFunction);
-            this.toStringFunction = Objects.requireNonNull(toStringFunction);
-            textFieldWidget = new TextFieldWidget(MinecraftClient.getInstance().textRenderer, 0, 0, 148, 18, "") {
+            this.toTextFunction = Objects.requireNonNull(toTextFunction);
+            textFieldWidget = new TextFieldWidget(MinecraftClient.getInstance().textRenderer, 0, 0, 148, 18, NarratorManager.EMPTY) {
                 @Override
-                public void render(int int_1, int int_2, float float_1) {
+                public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
                     setFocused(isSelected && DefaultSelectionTopCellElement.this.getParent().getFocused() == DefaultSelectionTopCellElement.this.getParent().selectionElement && DefaultSelectionTopCellElement.this.getParent().selectionElement.getFocused() == DefaultSelectionTopCellElement.this && DefaultSelectionTopCellElement.this.getFocused() == this);
-                    super.render(int_1, int_2, float_1);
+                    super.render(matrices, mouseX, mouseY, delta);
                 }
                 
                 @Override
@@ -686,21 +687,21 @@ public class DropdownBoxEntry<T> extends TooltipListEntry<T> {
             };
             textFieldWidget.setHasBorder(false);
             textFieldWidget.setMaxLength(999999);
-            textFieldWidget.setText(toStringFunction.apply(value));
+            textFieldWidget.setText(toTextFunction.apply(value).getString());
             textFieldWidget.setChangedListener(s -> {
-                if (getParent() != null && getParent().getScreen() != null && !toStringFunction.apply(value).equals(s))
+                if (getParent() != null && getParent().getScreen() != null && !toTextFunction.apply(value).getString().equals(s))
                     getParent().getScreen().setEdited(true, getParent().isRequiresRestart());
             });
         }
         
         @Override
-        public void render(int mouseX, int mouseY, int x, int y, int width, int height, float delta) {
+        public void render(MatrixStack matrices, int mouseX, int mouseY, int x, int y, int width, int height, float delta) {
             textFieldWidget.x = x + 4;
             textFieldWidget.y = y + 6;
             textFieldWidget.setWidth(width - 8);
             textFieldWidget.setEditable(getParent().isEditable());
             textFieldWidget.setEditableColor(getPreferredTextColor());
-            textFieldWidget.render(mouseX, mouseY, delta);
+            textFieldWidget.render(matrices, mouseX, mouseY, delta);
         }
         
         @Override
@@ -712,20 +713,20 @@ public class DropdownBoxEntry<T> extends TooltipListEntry<T> {
         
         @Override
         public void setValue(R value) {
-            textFieldWidget.setText(toStringFunction.apply(value));
+            textFieldWidget.setText(toTextFunction.apply(value).getString());
             textFieldWidget.setCursor(0);
         }
         
         @Override
-        public String getSearchTerm() {
-            return textFieldWidget.getText();
+        public Text getSearchTerm() {
+            return new LiteralText(textFieldWidget.getText());
         }
         
         @Override
-        public Optional<String> getError() {
+        public Optional<Text> getError() {
             if (toObjectFunction.apply(textFieldWidget.getText()) != null)
                 return Optional.empty();
-            return Optional.of("Invalid Value!");
+            return Optional.of(new LiteralText("Invalid Value!"));
         }
         
         @Override

+ 7 - 12
src/main/java/me/shedaniel/clothconfig2/gui/entries/EnumListEntry.java

@@ -2,7 +2,8 @@ package me.shedaniel.clothconfig2.gui.entries;
 
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
-import net.minecraft.client.resource.language.I18n;
+import net.minecraft.text.Text;
+import net.minecraft.text.TranslatableText;
 import org.jetbrains.annotations.ApiStatus;
 
 import java.util.Optional;
@@ -13,35 +14,29 @@ import java.util.function.Supplier;
 @Environment(EnvType.CLIENT)
 public class EnumListEntry<T extends Enum<?>> extends SelectionListEntry<T> {
     
-    public static final Function<Enum, String> DEFAULT_NAME_PROVIDER = t -> I18n.translate(t instanceof Translatable ? ((Translatable) t).getKey() : t.toString());
+    public static final Function<Enum, Text> DEFAULT_NAME_PROVIDER = t -> new TranslatableText(t instanceof Translatable ? ((Translatable) t).getKey() : t.toString());
     
     @ApiStatus.Internal
     @Deprecated
-    public EnumListEntry(String fieldName, Class<T> clazz, T value, Consumer<T> saveConsumer) {
-        super(fieldName, clazz.getEnumConstants(), value, "text.cloth-config.reset_value", null, saveConsumer);
-    }
-    
-    @ApiStatus.Internal
-    @Deprecated
-    public EnumListEntry(String fieldName, Class<T> clazz, T value, String resetButtonKey, Supplier<T> defaultValue, Consumer<T> saveConsumer) {
+    public EnumListEntry(Text fieldName, Class<T> clazz, T value, Text resetButtonKey, Supplier<T> defaultValue, Consumer<T> saveConsumer) {
         super(fieldName, clazz.getEnumConstants(), value, resetButtonKey, defaultValue, saveConsumer, DEFAULT_NAME_PROVIDER::apply);
     }
     
     @ApiStatus.Internal
     @Deprecated
-    public EnumListEntry(String fieldName, Class<T> clazz, T value, String resetButtonKey, Supplier<T> defaultValue, Consumer<T> saveConsumer, Function<Enum, String> enumNameProvider) {
+    public EnumListEntry(Text fieldName, Class<T> clazz, T value, Text resetButtonKey, Supplier<T> defaultValue, Consumer<T> saveConsumer, Function<Enum, Text> enumNameProvider) {
         super(fieldName, clazz.getEnumConstants(), value, resetButtonKey, defaultValue, saveConsumer, enumNameProvider::apply, null);
     }
     
     @ApiStatus.Internal
     @Deprecated
-    public EnumListEntry(String fieldName, Class<T> clazz, T value, String resetButtonKey, Supplier<T> defaultValue, Consumer<T> saveConsumer, Function<Enum, String> enumNameProvider, Supplier<Optional<String[]>> tooltipSupplier) {
+    public EnumListEntry(Text fieldName, Class<T> clazz, T value, Text resetButtonKey, Supplier<T> defaultValue, Consumer<T> saveConsumer, Function<Enum, Text> enumNameProvider, Supplier<Optional<Text[]>> tooltipSupplier) {
         super(fieldName, clazz.getEnumConstants(), value, resetButtonKey, defaultValue, saveConsumer, enumNameProvider::apply, tooltipSupplier, false);
     }
     
     @ApiStatus.Internal
     @Deprecated
-    public EnumListEntry(String fieldName, Class<T> clazz, T value, String resetButtonKey, Supplier<T> defaultValue, Consumer<T> saveConsumer, Function<Enum, String> enumNameProvider, Supplier<Optional<String[]>> tooltipSupplier, boolean requiresRestart) {
+    public EnumListEntry(Text fieldName, Class<T> clazz, T value, Text resetButtonKey, Supplier<T> defaultValue, Consumer<T> saveConsumer, Function<Enum, Text> enumNameProvider, Supplier<Optional<Text[]>> tooltipSupplier, boolean requiresRestart) {
         super(fieldName, clazz.getEnumConstants(), value, resetButtonKey, defaultValue, saveConsumer, enumNameProvider::apply, tooltipSupplier, requiresRestart);
     }
     

+ 9 - 14
src/main/java/me/shedaniel/clothconfig2/gui/entries/FloatListEntry.java

@@ -3,7 +3,8 @@ package me.shedaniel.clothconfig2.gui.entries;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
 import net.minecraft.client.gui.widget.TextFieldWidget;
-import net.minecraft.client.resource.language.I18n;
+import net.minecraft.text.Text;
+import net.minecraft.text.TranslatableText;
 import org.jetbrains.annotations.ApiStatus;
 
 import java.util.Optional;
@@ -30,13 +31,7 @@ public class FloatListEntry extends TextFieldListEntry<Float> {
     
     @ApiStatus.Internal
     @Deprecated
-    public FloatListEntry(String fieldName, Float value, Consumer<Float> saveConsumer) {
-        this(fieldName, value, "text.cloth-config.reset_value", null, saveConsumer);
-    }
-    
-    @ApiStatus.Internal
-    @Deprecated
-    public FloatListEntry(String fieldName, Float value, String resetButtonKey, Supplier<Float> defaultValue, Consumer<Float> saveConsumer) {
+    public FloatListEntry(Text fieldName, Float value, Text resetButtonKey, Supplier<Float> defaultValue, Consumer<Float> saveConsumer) {
         super(fieldName, value, resetButtonKey, defaultValue);
         this.minimum = -Float.MAX_VALUE;
         this.maximum = Float.MAX_VALUE;
@@ -45,13 +40,13 @@ public class FloatListEntry extends TextFieldListEntry<Float> {
     
     @ApiStatus.Internal
     @Deprecated
-    public FloatListEntry(String fieldName, Float value, String resetButtonKey, Supplier<Float> defaultValue, Consumer<Float> saveConsumer, Supplier<Optional<String[]>> tooltipSupplier) {
+    public FloatListEntry(Text fieldName, Float value, Text resetButtonKey, Supplier<Float> defaultValue, Consumer<Float> saveConsumer, Supplier<Optional<Text[]>> tooltipSupplier) {
         this(fieldName, value, resetButtonKey, defaultValue, saveConsumer, tooltipSupplier, false);
     }
     
     @ApiStatus.Internal
     @Deprecated
-    public FloatListEntry(String fieldName, Float value, String resetButtonKey, Supplier<Float> defaultValue, Consumer<Float> saveConsumer, Supplier<Optional<String[]>> tooltipSupplier, boolean requiresRestart) {
+    public FloatListEntry(Text fieldName, Float value, Text resetButtonKey, Supplier<Float> defaultValue, Consumer<Float> saveConsumer, Supplier<Optional<Text[]>> tooltipSupplier, boolean requiresRestart) {
         super(fieldName, value, resetButtonKey, defaultValue, tooltipSupplier, requiresRestart);
         this.minimum = -Float.MAX_VALUE;
         this.maximum = Float.MAX_VALUE;
@@ -107,15 +102,15 @@ public class FloatListEntry extends TextFieldListEntry<Float> {
     }
     
     @Override
-    public Optional<String> getError() {
+    public Optional<Text> getError() {
         try {
             float i = Float.parseFloat(textFieldWidget.getText());
             if (i > maximum)
-                return Optional.of(I18n.translate("text.cloth-config.error.too_large", maximum));
+                return Optional.of(new TranslatableText("text.cloth-config.error.too_large", maximum));
             else if (i < minimum)
-                return Optional.of(I18n.translate("text.cloth-config.error.too_small", minimum));
+                return Optional.of(new TranslatableText("text.cloth-config.error.too_small", minimum));
         } catch (NumberFormatException ex) {
-            return Optional.of(I18n.translate("text.cloth-config.error.not_valid_number_float"));
+            return Optional.of(new TranslatableText("text.cloth-config.error.not_valid_number_float"));
         }
         return super.getError();
     }

+ 9 - 8
src/main/java/me/shedaniel/clothconfig2/gui/entries/FloatListListEntry.java

@@ -2,7 +2,8 @@ package me.shedaniel.clothconfig2.gui.entries;
 
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
-import net.minecraft.client.resource.language.I18n;
+import net.minecraft.text.Text;
+import net.minecraft.text.TranslatableText;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -19,19 +20,19 @@ public class FloatListListEntry extends AbstractTextFieldListListEntry<Float, Fl
     
     @ApiStatus.Internal
     @Deprecated
-    public FloatListListEntry(String fieldName, List<Float> value, boolean defaultExpanded, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<Float>> saveConsumer, Supplier<List<Float>> defaultValue, String resetButtonKey) {
+    public FloatListListEntry(Text fieldName, List<Float> value, boolean defaultExpanded, Supplier<Optional<Text[]>> tooltipSupplier, Consumer<List<Float>> saveConsumer, Supplier<List<Float>> defaultValue, Text resetButtonKey) {
         this(fieldName, value, defaultExpanded, tooltipSupplier, saveConsumer, defaultValue, resetButtonKey, false);
     }
     
     @ApiStatus.Internal
     @Deprecated
-    public FloatListListEntry(String fieldName, List<Float> value, boolean defaultExpanded, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<Float>> saveConsumer, Supplier<List<Float>> defaultValue, String resetButtonKey, boolean requiresRestart) {
+    public FloatListListEntry(Text fieldName, List<Float> value, boolean defaultExpanded, Supplier<Optional<Text[]>> tooltipSupplier, Consumer<List<Float>> saveConsumer, Supplier<List<Float>> defaultValue, Text resetButtonKey, boolean requiresRestart) {
         this(fieldName, value, defaultExpanded, tooltipSupplier, saveConsumer, defaultValue, resetButtonKey, requiresRestart, true, true);
     }
     
     @ApiStatus.Internal
     @Deprecated
-    public FloatListListEntry(String fieldName, List<Float> value, boolean defaultExpanded, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<Float>> saveConsumer, Supplier<List<Float>> defaultValue, String resetButtonKey, boolean requiresRestart, boolean deleteButtonEnabled, boolean insertInFront) {
+    public FloatListListEntry(Text fieldName, List<Float> value, boolean defaultExpanded, Supplier<Optional<Text[]>> tooltipSupplier, Consumer<List<Float>> saveConsumer, Supplier<List<Float>> defaultValue, Text resetButtonKey, boolean requiresRestart, boolean deleteButtonEnabled, boolean insertInFront) {
         super(fieldName, value, defaultExpanded, tooltipSupplier, saveConsumer, defaultValue, resetButtonKey, requiresRestart, deleteButtonEnabled, insertInFront, FloatListCell::new);
         this.minimum = Float.NEGATIVE_INFINITY;
         this.maximum = Float.POSITIVE_INFINITY;
@@ -81,15 +82,15 @@ public class FloatListListEntry extends AbstractTextFieldListListEntry<Float, Fl
         }
         
         @Override
-        public Optional<String> getError() {
+        public Optional<Text> getError() {
             try {
                 float i = Float.parseFloat(widget.getText());
                 if (i > listListEntry.maximum)
-                    return Optional.of(I18n.translate("text.cloth-config.error.too_large", listListEntry.maximum));
+                    return Optional.of(new TranslatableText("text.cloth-config.error.too_large", listListEntry.maximum));
                 else if (i < listListEntry.minimum)
-                    return Optional.of(I18n.translate("text.cloth-config.error.too_small", listListEntry.minimum));
+                    return Optional.of(new TranslatableText("text.cloth-config.error.too_small", listListEntry.minimum));
             } catch (NumberFormatException ex) {
-                return Optional.of(I18n.translate("text.cloth-config.error.not_valid_number_float"));
+                return Optional.of(new TranslatableText("text.cloth-config.error.not_valid_number_float"));
             }
             return Optional.empty();
         }

+ 12 - 17
src/main/java/me/shedaniel/clothconfig2/gui/entries/IntegerListEntry.java

@@ -3,7 +3,8 @@ package me.shedaniel.clothconfig2.gui.entries;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
 import net.minecraft.client.gui.widget.TextFieldWidget;
-import net.minecraft.client.resource.language.I18n;
+import net.minecraft.text.Text;
+import net.minecraft.text.TranslatableText;
 import org.jetbrains.annotations.ApiStatus;
 
 import java.util.Optional;
@@ -15,28 +16,22 @@ import java.util.function.Supplier;
 public class IntegerListEntry extends TextFieldListEntry<Integer> {
     
     private static Function<String, String> stripCharacters = s -> {
-        StringBuilder stringBuilder_1 = new StringBuilder();
+        StringBuilder builder = new StringBuilder();
         char[] var2 = s.toCharArray();
         int var3 = var2.length;
         
         for (char c : var2)
             if (Character.isDigit(c) || c == '-')
-                stringBuilder_1.append(c);
+                builder.append(c);
         
-        return stringBuilder_1.toString();
+        return builder.toString();
     };
     private int minimum, maximum;
     private Consumer<Integer> saveConsumer;
     
     @ApiStatus.Internal
     @Deprecated
-    public IntegerListEntry(String fieldName, Integer value, Consumer<Integer> saveConsumer) {
-        this(fieldName, value, "text.cloth-config.reset_value", null, saveConsumer);
-    }
-    
-    @ApiStatus.Internal
-    @Deprecated
-    public IntegerListEntry(String fieldName, Integer value, String resetButtonKey, Supplier<Integer> defaultValue, Consumer<Integer> saveConsumer) {
+    public IntegerListEntry(Text fieldName, Integer value, Text resetButtonKey, Supplier<Integer> defaultValue, Consumer<Integer> saveConsumer) {
         super(fieldName, value, resetButtonKey, defaultValue);
         this.minimum = -Integer.MAX_VALUE;
         this.maximum = Integer.MAX_VALUE;
@@ -45,13 +40,13 @@ public class IntegerListEntry extends TextFieldListEntry<Integer> {
     
     @ApiStatus.Internal
     @Deprecated
-    public IntegerListEntry(String fieldName, Integer value, String resetButtonKey, Supplier<Integer> defaultValue, Consumer<Integer> saveConsumer, Supplier<Optional<String[]>> tooltipSupplier) {
+    public IntegerListEntry(Text fieldName, Integer value, Text resetButtonKey, Supplier<Integer> defaultValue, Consumer<Integer> saveConsumer, Supplier<Optional<Text[]>> tooltipSupplier) {
         this(fieldName, value, resetButtonKey, defaultValue, saveConsumer, tooltipSupplier, false);
     }
     
     @ApiStatus.Internal
     @Deprecated
-    public IntegerListEntry(String fieldName, Integer value, String resetButtonKey, Supplier<Integer> defaultValue, Consumer<Integer> saveConsumer, Supplier<Optional<String[]>> tooltipSupplier, boolean requiresRestart) {
+    public IntegerListEntry(Text fieldName, Integer value, Text resetButtonKey, Supplier<Integer> defaultValue, Consumer<Integer> saveConsumer, Supplier<Optional<Text[]>> tooltipSupplier, boolean requiresRestart) {
         super(fieldName, value, resetButtonKey, defaultValue, tooltipSupplier, requiresRestart);
         this.minimum = -Integer.MAX_VALUE;
         this.maximum = Integer.MAX_VALUE;
@@ -107,15 +102,15 @@ public class IntegerListEntry extends TextFieldListEntry<Integer> {
     }
     
     @Override
-    public Optional<String> getError() {
+    public Optional<Text> getError() {
         try {
             int i = Integer.parseInt(textFieldWidget.getText());
             if (i > maximum)
-                return Optional.of(I18n.translate("text.cloth-config.error.too_large", maximum));
+                return Optional.of(new TranslatableText("text.cloth-config.error.too_large", maximum));
             else if (i < minimum)
-                return Optional.of(I18n.translate("text.cloth-config.error.too_small", minimum));
+                return Optional.of(new TranslatableText("text.cloth-config.error.too_small", minimum));
         } catch (NumberFormatException ex) {
-            return Optional.of(I18n.translate("text.cloth-config.error.not_valid_number_int"));
+            return Optional.of(new TranslatableText("text.cloth-config.error.not_valid_number_int"));
         }
         return super.getError();
     }

+ 9 - 8
src/main/java/me/shedaniel/clothconfig2/gui/entries/IntegerListListEntry.java

@@ -2,7 +2,8 @@ package me.shedaniel.clothconfig2.gui.entries;
 
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
-import net.minecraft.client.resource.language.I18n;
+import net.minecraft.text.Text;
+import net.minecraft.text.TranslatableText;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -19,19 +20,19 @@ public class IntegerListListEntry extends AbstractTextFieldListListEntry<Integer
     
     @ApiStatus.Internal
     @Deprecated
-    public IntegerListListEntry(String fieldName, List<Integer> value, boolean defaultExpanded, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<Integer>> saveConsumer, Supplier<List<Integer>> defaultValue, String resetButtonKey) {
+    public IntegerListListEntry(Text fieldName, List<Integer> value, boolean defaultExpanded, Supplier<Optional<Text[]>> tooltipSupplier, Consumer<List<Integer>> saveConsumer, Supplier<List<Integer>> defaultValue, Text resetButtonKey) {
         this(fieldName, value, defaultExpanded, tooltipSupplier, saveConsumer, defaultValue, resetButtonKey, false);
     }
     
     @ApiStatus.Internal
     @Deprecated
-    public IntegerListListEntry(String fieldName, List<Integer> value, boolean defaultExpanded, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<Integer>> saveConsumer, Supplier<List<Integer>> defaultValue, String resetButtonKey, boolean requiresRestart) {
+    public IntegerListListEntry(Text fieldName, List<Integer> value, boolean defaultExpanded, Supplier<Optional<Text[]>> tooltipSupplier, Consumer<List<Integer>> saveConsumer, Supplier<List<Integer>> defaultValue, Text resetButtonKey, boolean requiresRestart) {
         this(fieldName, value, defaultExpanded, tooltipSupplier, saveConsumer, defaultValue, resetButtonKey, requiresRestart, true, true);
     }
     
     @ApiStatus.Internal
     @Deprecated
-    public IntegerListListEntry(String fieldName, List<Integer> value, boolean defaultExpanded, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<Integer>> saveConsumer, Supplier<List<Integer>> defaultValue, String resetButtonKey, boolean requiresRestart, boolean deleteButtonEnabled, boolean insertInFront) {
+    public IntegerListListEntry(Text fieldName, List<Integer> value, boolean defaultExpanded, Supplier<Optional<Text[]>> tooltipSupplier, Consumer<List<Integer>> saveConsumer, Supplier<List<Integer>> defaultValue, Text resetButtonKey, boolean requiresRestart, boolean deleteButtonEnabled, boolean insertInFront) {
         super(fieldName, value, defaultExpanded, tooltipSupplier, saveConsumer, defaultValue, resetButtonKey, requiresRestart, deleteButtonEnabled, insertInFront, IntegerListCell::new);
         this.minimum = Integer.MIN_VALUE;
         this.maximum = Integer.MAX_VALUE;
@@ -81,15 +82,15 @@ public class IntegerListListEntry extends AbstractTextFieldListListEntry<Integer
         }
         
         @Override
-        public Optional<String> getError() {
+        public Optional<Text> getError() {
             try {
                 int i = Integer.parseInt(widget.getText());
                 if (i > listListEntry.maximum)
-                    return Optional.of(I18n.translate("text.cloth-config.error.too_large", listListEntry.maximum));
+                    return Optional.of(new TranslatableText("text.cloth-config.error.too_large", listListEntry.maximum));
                 else if (i < listListEntry.minimum)
-                    return Optional.of(I18n.translate("text.cloth-config.error.too_small", listListEntry.minimum));
+                    return Optional.of(new TranslatableText("text.cloth-config.error.too_small", listListEntry.minimum));
             } catch (NumberFormatException ex) {
-                return Optional.of(I18n.translate("text.cloth-config.error.not_valid_number_int"));
+                return Optional.of(new TranslatableText("text.cloth-config.error.not_valid_number_int"));
             }
             return Optional.empty();
         }

+ 18 - 21
src/main/java/me/shedaniel/clothconfig2/gui/entries/IntegerSliderEntry.java

@@ -7,8 +7,11 @@ import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.gui.widget.ButtonWidget;
 import net.minecraft.client.gui.widget.SliderWidget;
-import net.minecraft.client.resource.language.I18n;
+import net.minecraft.client.util.NarratorManager;
 import net.minecraft.client.util.Window;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.text.LiteralText;
+import net.minecraft.text.Text;
 import net.minecraft.util.math.MathHelper;
 import org.jetbrains.annotations.ApiStatus;
 
@@ -28,30 +31,24 @@ public class IntegerSliderEntry extends TooltipListEntry<Integer> {
     private int minimum, maximum;
     private Consumer<Integer> saveConsumer;
     private Supplier<Integer> defaultValue;
-    private Function<Integer, String> textGetter = integer -> String.format("Value: %d", integer);
+    private Function<Integer, Text> textGetter = integer -> new LiteralText(String.format("Value: %d", integer));
     private List<Element> widgets;
     
     @ApiStatus.Internal
     @Deprecated
-    public IntegerSliderEntry(String fieldName, int minimum, int maximum, int value, Consumer<Integer> saveConsumer) {
-        this(fieldName, minimum, maximum, value, "text.cloth-config.reset_value", null, saveConsumer);
-    }
-    
-    @ApiStatus.Internal
-    @Deprecated
-    public IntegerSliderEntry(String fieldName, int minimum, int maximum, int value, String resetButtonKey, Supplier<Integer> defaultValue, Consumer<Integer> saveConsumer) {
+    public IntegerSliderEntry(Text fieldName, int minimum, int maximum, int value, Text resetButtonKey, Supplier<Integer> defaultValue, Consumer<Integer> saveConsumer) {
         this(fieldName, minimum, maximum, value, resetButtonKey, defaultValue, saveConsumer, null);
     }
     
     @ApiStatus.Internal
     @Deprecated
-    public IntegerSliderEntry(String fieldName, int minimum, int maximum, int value, String resetButtonKey, Supplier<Integer> defaultValue, Consumer<Integer> saveConsumer, Supplier<Optional<String[]>> tooltipSupplier) {
+    public IntegerSliderEntry(Text fieldName, int minimum, int maximum, int value, Text resetButtonKey, Supplier<Integer> defaultValue, Consumer<Integer> saveConsumer, Supplier<Optional<Text[]>> tooltipSupplier) {
         this(fieldName, minimum, maximum, value, resetButtonKey, defaultValue, saveConsumer, tooltipSupplier, false);
     }
     
     @ApiStatus.Internal
     @Deprecated
-    public IntegerSliderEntry(String fieldName, int minimum, int maximum, int value, String resetButtonKey, Supplier<Integer> defaultValue, Consumer<Integer> saveConsumer, Supplier<Optional<String[]>> tooltipSupplier, boolean requiresRestart) {
+    public IntegerSliderEntry(Text fieldName, int minimum, int maximum, int value, Text resetButtonKey, Supplier<Integer> defaultValue, Consumer<Integer> saveConsumer, Supplier<Optional<Text[]>> tooltipSupplier, boolean requiresRestart) {
         super(fieldName, tooltipSupplier, requiresRestart);
         this.defaultValue = defaultValue;
         this.value = new AtomicInteger(value);
@@ -59,7 +56,7 @@ public class IntegerSliderEntry extends TooltipListEntry<Integer> {
         this.maximum = maximum;
         this.minimum = minimum;
         this.sliderWidget = new Slider(0, 0, 152, 20, ((double) this.value.get() - minimum) / Math.abs(maximum - minimum));
-        this.resetButton = new ButtonWidget(0, 0, MinecraftClient.getInstance().textRenderer.getStringWidth(I18n.translate(resetButtonKey)) + 6, 20, I18n.translate(resetButtonKey), widget -> {
+        this.resetButton = new ButtonWidget(0, 0, MinecraftClient.getInstance().textRenderer.method_27525(resetButtonKey) + 6, 20, resetButtonKey, widget -> {
             sliderWidget.setProgress((MathHelper.clamp(this.defaultValue.get(), minimum, maximum) - minimum) / (double) Math.abs(maximum - minimum));
             this.value.set(MathHelper.clamp(this.defaultValue.get(), minimum, maximum));
             sliderWidget.updateMessage();
@@ -75,11 +72,11 @@ public class IntegerSliderEntry extends TooltipListEntry<Integer> {
             saveConsumer.accept(getValue());
     }
     
-    public Function<Integer, String> getTextGetter() {
+    public Function<Integer, Text> getTextGetter() {
         return textGetter;
     }
     
-    public IntegerSliderEntry setTextGetter(Function<Integer, String> textGetter) {
+    public IntegerSliderEntry setTextGetter(Function<Integer, Text> textGetter) {
         this.textGetter = textGetter;
         this.sliderWidget.setMessage(textGetter.apply(IntegerSliderEntry.this.value.get()));
         return this;
@@ -111,30 +108,30 @@ public class IntegerSliderEntry extends TooltipListEntry<Integer> {
     }
     
     @Override
-    public void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
-        super.render(index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta);
+    public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
+        super.render(matrices, index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta);
         Window window = MinecraftClient.getInstance().getWindow();
         this.resetButton.active = isEditable() && getDefaultValue().isPresent() && defaultValue.get() != value.get();
         this.resetButton.y = y;
         this.sliderWidget.active = isEditable();
         this.sliderWidget.y = y;
         if (MinecraftClient.getInstance().textRenderer.isRightToLeft()) {
-            MinecraftClient.getInstance().textRenderer.drawWithShadow(I18n.translate(getFieldName()), window.getScaledWidth() - x - MinecraftClient.getInstance().textRenderer.getStringWidth(I18n.translate(getFieldName())), y + 5, getPreferredTextColor());
+            MinecraftClient.getInstance().textRenderer.method_27517(matrices, getFieldName(), window.getScaledWidth() - x - MinecraftClient.getInstance().textRenderer.method_27525(getFieldName()), y + 5, getPreferredTextColor());
             this.resetButton.x = x;
             this.sliderWidget.x = x + resetButton.getWidth() + 1;
         } else {
-            MinecraftClient.getInstance().textRenderer.drawWithShadow(I18n.translate(getFieldName()), x, y + 5, getPreferredTextColor());
+            MinecraftClient.getInstance().textRenderer.method_27517(matrices, getFieldName(), x, y + 5, getPreferredTextColor());
             this.resetButton.x = x + entryWidth - resetButton.getWidth();
             this.sliderWidget.x = x + entryWidth - 150;
         }
         this.sliderWidget.setWidth(150 - resetButton.getWidth() - 2);
-        resetButton.render(mouseX, mouseY, delta);
-        sliderWidget.render(mouseX, mouseY, delta);
+        resetButton.render(matrices, mouseX, mouseY, delta);
+        sliderWidget.render(matrices, mouseX, mouseY, delta);
     }
     
     private class Slider extends SliderWidget {
         protected Slider(int int_1, int int_2, int int_3, int int_4, double double_1) {
-            super(int_1, int_2, int_3, int_4, "", double_1);
+            super(int_1, int_2, int_3, int_4, NarratorManager.EMPTY, double_1);
         }
         
         @Override

+ 15 - 12
src/main/java/me/shedaniel/clothconfig2/gui/entries/KeyCodeEntry.java

@@ -7,8 +7,11 @@ import net.fabricmc.api.Environment;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.gui.widget.ButtonWidget;
-import net.minecraft.client.resource.language.I18n;
+import net.minecraft.client.util.NarratorManager;
 import net.minecraft.client.util.Window;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.text.LiteralText;
+import net.minecraft.text.Text;
 import net.minecraft.util.Formatting;
 import org.jetbrains.annotations.ApiStatus;
 
@@ -30,15 +33,15 @@ public class KeyCodeEntry extends TooltipListEntry<ModifierKeyCode> {
     
     @ApiStatus.Internal
     @Deprecated
-    public KeyCodeEntry(String fieldName, ModifierKeyCode value, String resetButtonKey, Supplier<ModifierKeyCode> defaultValue, Consumer<ModifierKeyCode> saveConsumer, Supplier<Optional<String[]>> tooltipSupplier, boolean requiresRestart) {
+    public KeyCodeEntry(Text fieldName, ModifierKeyCode value, Text resetButtonKey, Supplier<ModifierKeyCode> defaultValue, Consumer<ModifierKeyCode> saveConsumer, Supplier<Optional<Text[]>> tooltipSupplier, boolean requiresRestart) {
         super(fieldName, tooltipSupplier, requiresRestart);
         this.defaultValue = defaultValue;
         this.value = value;
-        this.buttonWidget = new ButtonWidget(0, 0, 150, 20, "", widget -> {
+        this.buttonWidget = new ButtonWidget(0, 0, 150, 20, NarratorManager.EMPTY, widget -> {
             getScreen().setFocusedBinding(this);
             getScreen().setEdited(true, isRequiresRestart());
         });
-        this.resetButton = new ButtonWidget(0, 0, MinecraftClient.getInstance().textRenderer.getStringWidth(I18n.translate(resetButtonKey)) + 6, 20, I18n.translate(resetButtonKey), widget -> {
+        this.resetButton = new ButtonWidget(0, 0, MinecraftClient.getInstance().textRenderer.method_27525(resetButtonKey) + 6, 20, resetButtonKey, widget -> {
             KeyCodeEntry.this.value = getDefaultValue().orElse(null);
             getScreen().setFocusedBinding(null);
             getScreen().setEdited(true, isRequiresRestart());
@@ -91,13 +94,13 @@ public class KeyCodeEntry extends TooltipListEntry<ModifierKeyCode> {
         return Optional.ofNullable(defaultValue).map(Supplier::get);
     }
     
-    private String getLocalizedName() {
+    private Text getLocalizedName() {
         return this.value.getLocalizedName();
     }
     
     @Override
-    public void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
-        super.render(index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta);
+    public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
+        super.render(matrices, index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta);
         Window window = MinecraftClient.getInstance().getWindow();
         this.resetButton.active = isEditable() && getDefaultValue().isPresent() && !getDefaultValue().get().equals(value);
         this.resetButton.y = y;
@@ -105,19 +108,19 @@ public class KeyCodeEntry extends TooltipListEntry<ModifierKeyCode> {
         this.buttonWidget.y = y;
         this.buttonWidget.setMessage(getLocalizedName());
         if (getScreen().getFocusedBinding() == this)
-            this.buttonWidget.setMessage(Formatting.WHITE + "> " + Formatting.YELLOW + this.buttonWidget.getMessage() + Formatting.WHITE + " <");
+            this.buttonWidget.setMessage(new LiteralText(Formatting.WHITE + "> " + Formatting.YELLOW + this.buttonWidget.getMessage() + Formatting.WHITE + " <"));
         if (MinecraftClient.getInstance().textRenderer.isRightToLeft()) {
-            MinecraftClient.getInstance().textRenderer.drawWithShadow(I18n.translate(getFieldName()), window.getScaledWidth() - x - MinecraftClient.getInstance().textRenderer.getStringWidth(I18n.translate(getFieldName())), y + 5, 16777215);
+            MinecraftClient.getInstance().textRenderer.method_27517(matrices, getFieldName(), window.getScaledWidth() - x - MinecraftClient.getInstance().textRenderer.method_27525(getFieldName()), y + 5, 16777215);
             this.resetButton.x = x;
             this.buttonWidget.x = x + resetButton.getWidth() + 2;
         } else {
-            MinecraftClient.getInstance().textRenderer.drawWithShadow(I18n.translate(getFieldName()), x, y + 5, getPreferredTextColor());
+            MinecraftClient.getInstance().textRenderer.method_27517(matrices, getFieldName(), x, y + 5, getPreferredTextColor());
             this.resetButton.x = x + entryWidth - resetButton.getWidth();
             this.buttonWidget.x = x + entryWidth - 150;
         }
         this.buttonWidget.setWidth(150 - resetButton.getWidth() - 2);
-        resetButton.render(mouseX, mouseY, delta);
-        buttonWidget.render(mouseX, mouseY, delta);
+        resetButton.render(matrices, mouseX, mouseY, delta);
+        buttonWidget.render(matrices, mouseX, mouseY, delta);
     }
     
     @Override

+ 9 - 14
src/main/java/me/shedaniel/clothconfig2/gui/entries/LongListEntry.java

@@ -3,7 +3,8 @@ package me.shedaniel.clothconfig2.gui.entries;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
 import net.minecraft.client.gui.widget.TextFieldWidget;
-import net.minecraft.client.resource.language.I18n;
+import net.minecraft.text.Text;
+import net.minecraft.text.TranslatableText;
 import org.jetbrains.annotations.ApiStatus;
 
 import java.util.Optional;
@@ -30,13 +31,7 @@ public class LongListEntry extends TextFieldListEntry<Long> {
     
     @ApiStatus.Internal
     @Deprecated
-    public LongListEntry(String fieldName, Long value, Consumer<Long> saveConsumer) {
-        this(fieldName, value, "text.cloth-config.reset_value", null, saveConsumer);
-    }
-    
-    @ApiStatus.Internal
-    @Deprecated
-    public LongListEntry(String fieldName, Long value, String resetButtonKey, Supplier<Long> defaultValue, Consumer<Long> saveConsumer) {
+    public LongListEntry(Text fieldName, Long value, Text resetButtonKey, Supplier<Long> defaultValue, Consumer<Long> saveConsumer) {
         super(fieldName, value, resetButtonKey, defaultValue);
         this.minimum = -Long.MAX_VALUE;
         this.maximum = Long.MAX_VALUE;
@@ -45,13 +40,13 @@ public class LongListEntry extends TextFieldListEntry<Long> {
     
     @ApiStatus.Internal
     @Deprecated
-    public LongListEntry(String fieldName, Long value, String resetButtonKey, Supplier<Long> defaultValue, Consumer<Long> saveConsumer, Supplier<Optional<String[]>> tooltipSupplier) {
+    public LongListEntry(Text fieldName, Long value, Text resetButtonKey, Supplier<Long> defaultValue, Consumer<Long> saveConsumer, Supplier<Optional<Text[]>> tooltipSupplier) {
         this(fieldName, value, resetButtonKey, defaultValue, saveConsumer, tooltipSupplier, false);
     }
     
     @ApiStatus.Internal
     @Deprecated
-    public LongListEntry(String fieldName, Long value, String resetButtonKey, Supplier<Long> defaultValue, Consumer<Long> saveConsumer, Supplier<Optional<String[]>> tooltipSupplier, boolean requiresRestart) {
+    public LongListEntry(Text fieldName, Long value, Text resetButtonKey, Supplier<Long> defaultValue, Consumer<Long> saveConsumer, Supplier<Optional<Text[]>> tooltipSupplier, boolean requiresRestart) {
         super(fieldName, value, resetButtonKey, defaultValue, tooltipSupplier, requiresRestart);
         this.minimum = -Long.MAX_VALUE;
         this.maximum = Long.MAX_VALUE;
@@ -107,15 +102,15 @@ public class LongListEntry extends TextFieldListEntry<Long> {
     }
     
     @Override
-    public Optional<String> getError() {
+    public Optional<Text> getError() {
         try {
             long i = Long.parseLong(textFieldWidget.getText());
             if (i > maximum)
-                return Optional.of(I18n.translate("text.cloth-config.error.too_large", maximum));
+                return Optional.of(new TranslatableText("text.cloth-config.error.too_large", maximum));
             else if (i < minimum)
-                return Optional.of(I18n.translate("text.cloth-config.error.too_small", minimum));
+                return Optional.of(new TranslatableText("text.cloth-config.error.too_small", minimum));
         } catch (NumberFormatException ex) {
-            return Optional.of(I18n.translate("text.cloth-config.error.not_valid_number_long"));
+            return Optional.of(new TranslatableText("text.cloth-config.error.not_valid_number_long"));
         }
         return super.getError();
     }

+ 9 - 8
src/main/java/me/shedaniel/clothconfig2/gui/entries/LongListListEntry.java

@@ -2,7 +2,8 @@ package me.shedaniel.clothconfig2.gui.entries;
 
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
-import net.minecraft.client.resource.language.I18n;
+import net.minecraft.text.Text;
+import net.minecraft.text.TranslatableText;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -19,19 +20,19 @@ public class LongListListEntry extends AbstractTextFieldListListEntry<Long, Long
     
     @ApiStatus.Internal
     @Deprecated
-    public LongListListEntry(String fieldName, List<Long> value, boolean defaultExpanded, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<Long>> saveConsumer, Supplier<List<Long>> defaultValue, String resetButtonKey) {
+    public LongListListEntry(Text fieldName, List<Long> value, boolean defaultExpanded, Supplier<Optional<Text[]>> tooltipSupplier, Consumer<List<Long>> saveConsumer, Supplier<List<Long>> defaultValue, Text resetButtonKey) {
         this(fieldName, value, defaultExpanded, tooltipSupplier, saveConsumer, defaultValue, resetButtonKey, false);
     }
     
     @ApiStatus.Internal
     @Deprecated
-    public LongListListEntry(String fieldName, List<Long> value, boolean defaultExpanded, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<Long>> saveConsumer, Supplier<List<Long>> defaultValue, String resetButtonKey, boolean requiresRestart) {
+    public LongListListEntry(Text fieldName, List<Long> value, boolean defaultExpanded, Supplier<Optional<Text[]>> tooltipSupplier, Consumer<List<Long>> saveConsumer, Supplier<List<Long>> defaultValue, Text resetButtonKey, boolean requiresRestart) {
         this(fieldName, value, defaultExpanded, tooltipSupplier, saveConsumer, defaultValue, resetButtonKey, requiresRestart, true, true);
     }
     
     @ApiStatus.Internal
     @Deprecated
-    public LongListListEntry(String fieldName, List<Long> value, boolean defaultExpanded, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<Long>> saveConsumer, Supplier<List<Long>> defaultValue, String resetButtonKey, boolean requiresRestart, boolean deleteButtonEnabled, boolean insertInFront) {
+    public LongListListEntry(Text fieldName, List<Long> value, boolean defaultExpanded, Supplier<Optional<Text[]>> tooltipSupplier, Consumer<List<Long>> saveConsumer, Supplier<List<Long>> defaultValue, Text resetButtonKey, boolean requiresRestart, boolean deleteButtonEnabled, boolean insertInFront) {
         super(fieldName, value, defaultExpanded, tooltipSupplier, saveConsumer, defaultValue, resetButtonKey, requiresRestart, deleteButtonEnabled, insertInFront, LongListCell::new);
         this.minimum = Long.MIN_VALUE;
         this.maximum = Long.MAX_VALUE;
@@ -81,15 +82,15 @@ public class LongListListEntry extends AbstractTextFieldListListEntry<Long, Long
         }
         
         @Override
-        public Optional<String> getError() {
+        public Optional<Text> getError() {
             try {
                 long l = Long.parseLong(widget.getText());
                 if (l > listListEntry.maximum)
-                    return Optional.of(I18n.translate("text.cloth-config.error.too_large", listListEntry.maximum));
+                    return Optional.of(new TranslatableText("text.cloth-config.error.too_large", listListEntry.maximum));
                 else if (l < listListEntry.minimum)
-                    return Optional.of(I18n.translate("text.cloth-config.error.too_small", listListEntry.minimum));
+                    return Optional.of(new TranslatableText("text.cloth-config.error.too_small", listListEntry.minimum));
             } catch (NumberFormatException ex) {
-                return Optional.of(I18n.translate("text.cloth-config.error.not_valid_number_long"));
+                return Optional.of(new TranslatableText("text.cloth-config.error.not_valid_number_long"));
             }
             return Optional.empty();
         }

+ 18 - 22
src/main/java/me/shedaniel/clothconfig2/gui/entries/LongSliderEntry.java

@@ -7,8 +7,11 @@ import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.gui.widget.ButtonWidget;
 import net.minecraft.client.gui.widget.SliderWidget;
-import net.minecraft.client.resource.language.I18n;
+import net.minecraft.client.util.NarratorManager;
 import net.minecraft.client.util.Window;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.text.LiteralText;
+import net.minecraft.text.Text;
 import net.minecraft.util.math.MathHelper;
 import org.jetbrains.annotations.ApiStatus;
 
@@ -28,30 +31,24 @@ public class LongSliderEntry extends TooltipListEntry<Long> {
     private long minimum, maximum;
     private Consumer<Long> saveConsumer;
     private Supplier<Long> defaultValue;
-    private Function<Long, String> textGetter = value -> String.format("Value: %d", value);
+    private Function<Long, Text> textGetter = value -> new LiteralText(String.format("Value: %d", value));
     private List<Element> widgets;
     
     @ApiStatus.Internal
     @Deprecated
-    public LongSliderEntry(String fieldName, long minimum, long maximum, long value, Consumer<Long> saveConsumer) {
-        this(fieldName, minimum, maximum, value, saveConsumer, "text.cloth-config.reset_value", null);
-    }
-    
-    @ApiStatus.Internal
-    @Deprecated
-    public LongSliderEntry(String fieldName, long minimum, long maximum, long value, Consumer<Long> saveConsumer, String resetButtonKey, Supplier<Long> defaultValue) {
+    public LongSliderEntry(Text fieldName, long minimum, long maximum, long value, Consumer<Long> saveConsumer, Text resetButtonKey, Supplier<Long> defaultValue) {
         this(fieldName, minimum, maximum, value, saveConsumer, resetButtonKey, defaultValue, null);
     }
     
     @ApiStatus.Internal
     @Deprecated
-    public LongSliderEntry(String fieldName, long minimum, long maximum, long value, Consumer<Long> saveConsumer, String resetButtonKey, Supplier<Long> defaultValue, Supplier<Optional<String[]>> tooltipSupplier) {
+    public LongSliderEntry(Text fieldName, long minimum, long maximum, long value, Consumer<Long> saveConsumer, Text resetButtonKey, Supplier<Long> defaultValue, Supplier<Optional<Text[]>> tooltipSupplier) {
         this(fieldName, minimum, maximum, value, saveConsumer, resetButtonKey, defaultValue, tooltipSupplier, false);
     }
     
     @ApiStatus.Internal
     @Deprecated
-    public LongSliderEntry(String fieldName, long minimum, long maximum, long value, Consumer<Long> saveConsumer, String resetButtonKey, Supplier<Long> defaultValue, Supplier<Optional<String[]>> tooltipSupplier, boolean requiresRestart) {
+    public LongSliderEntry(Text fieldName, long minimum, long maximum, long value, Consumer<Long> saveConsumer, Text resetButtonKey, Supplier<Long> defaultValue, Supplier<Optional<Text[]>> tooltipSupplier, boolean requiresRestart) {
         super(fieldName, tooltipSupplier, requiresRestart);
         this.defaultValue = defaultValue;
         this.value = new AtomicLong(value);
@@ -59,7 +56,7 @@ public class LongSliderEntry extends TooltipListEntry<Long> {
         this.maximum = maximum;
         this.minimum = minimum;
         this.sliderWidget = new Slider(0, 0, 152, 20, ((double) LongSliderEntry.this.value.get() - minimum) / Math.abs(maximum - minimum));
-        this.resetButton = new ButtonWidget(0, 0, MinecraftClient.getInstance().textRenderer.getStringWidth(I18n.translate(resetButtonKey)) + 6, 20, I18n.translate(resetButtonKey), widget -> {
+        this.resetButton = new ButtonWidget(0, 0, MinecraftClient.getInstance().textRenderer.method_27525(resetButtonKey) + 6, 20, resetButtonKey, widget -> {
             setValue(defaultValue.get());
             getScreen().setEdited(true, isRequiresRestart());
         });
@@ -73,11 +70,11 @@ public class LongSliderEntry extends TooltipListEntry<Long> {
             saveConsumer.accept(getValue());
     }
     
-    public Function<Long, String> getTextGetter() {
+    public Function<Long, Text> getTextGetter() {
         return textGetter;
     }
     
-    public LongSliderEntry setTextGetter(Function<Long, String> textGetter) {
+    public LongSliderEntry setTextGetter(Function<Long, Text> textGetter) {
         this.textGetter = textGetter;
         this.sliderWidget.setMessage(textGetter.apply(LongSliderEntry.this.value.get()));
         return this;
@@ -116,31 +113,30 @@ public class LongSliderEntry extends TooltipListEntry<Long> {
     }
     
     @Override
-    public void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
-        super.render(index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta);
+    public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
+        super.render(matrices, index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta);
         Window window = MinecraftClient.getInstance().getWindow();
         this.resetButton.active = isEditable() && getDefaultValue().isPresent() && defaultValue.get() != value.get();
         this.resetButton.y = y;
         this.sliderWidget.active = isEditable();
         this.sliderWidget.y = y;
         if (MinecraftClient.getInstance().textRenderer.isRightToLeft()) {
-            MinecraftClient.getInstance().textRenderer.drawWithShadow(I18n.translate(getFieldName()), window.getScaledWidth() - x - MinecraftClient.getInstance().textRenderer.getStringWidth(I18n.translate(getFieldName())), y + 5, getPreferredTextColor());
+            MinecraftClient.getInstance().textRenderer.method_27517(matrices, getFieldName(), window.getScaledWidth() - x - MinecraftClient.getInstance().textRenderer.method_27525(getFieldName()), y + 5, getPreferredTextColor());
             this.resetButton.x = x;
             this.sliderWidget.x = x + resetButton.getWidth() + 1;
         } else {
-            MinecraftClient.getInstance().textRenderer.drawWithShadow(I18n.translate(getFieldName()), x, y + 5, getPreferredTextColor());
+            MinecraftClient.getInstance().textRenderer.method_27517(matrices, getFieldName(), x, y + 5, getPreferredTextColor());
             this.resetButton.x = x + entryWidth - resetButton.getWidth();
             this.sliderWidget.x = x + entryWidth - 150;
         }
         this.sliderWidget.setWidth(150 - resetButton.getWidth() - 2);
-        resetButton.render(mouseX, mouseY, delta);
-        sliderWidget.render(mouseX, mouseY, delta);
+        resetButton.render(matrices, mouseX, mouseY, delta);
+        sliderWidget.render(matrices, mouseX, mouseY, delta);
     }
     
     private class Slider extends SliderWidget {
-        
         protected Slider(int int_1, int int_2, int int_3, int int_4, double double_1) {
-            super(int_1, int_2, int_3, int_4, "", double_1);
+            super(int_1, int_2, int_3, int_4, NarratorManager.EMPTY, double_1);
         }
         
         @Override

+ 17 - 15
src/main/java/me/shedaniel/clothconfig2/gui/entries/MultiElementListEntry.java

@@ -9,9 +9,11 @@ import net.fabricmc.api.Environment;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.render.DiffuseLighting;
-import net.minecraft.client.resource.language.I18n;
 import net.minecraft.client.sound.PositionedSoundInstance;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.sound.SoundEvents;
+import net.minecraft.text.Text;
+import net.minecraft.text.TranslatableText;
 import net.minecraft.util.Identifier;
 import org.jetbrains.annotations.ApiStatus;
 
@@ -26,7 +28,7 @@ public class MultiElementListEntry<T> extends TooltipListEntry<T> {
     
     private static final Identifier CONFIG_TEX = new Identifier("cloth-config2", "textures/gui/cloth_config.png");
     private final T object;
-    private String categoryName;
+    private Text categoryName;
     private List<AbstractConfigListEntry<?>> entries;
     private MultiElementListEntry<T>.CategoryLabelWidget widget;
     private List<Element> children;
@@ -34,7 +36,7 @@ public class MultiElementListEntry<T> extends TooltipListEntry<T> {
     
     @ApiStatus.Internal
     @Deprecated
-    public MultiElementListEntry(String categoryName, T object, List<AbstractConfigListEntry<?>> entries, boolean defaultExpanded) {
+    public MultiElementListEntry(Text categoryName, T object, List<AbstractConfigListEntry<?>> entries, boolean defaultExpanded) {
         super(categoryName, null);
         this.categoryName = categoryName;
         this.object = object;
@@ -55,10 +57,10 @@ public class MultiElementListEntry<T> extends TooltipListEntry<T> {
     
     @Override
     public void setRequiresRestart(boolean requiresRestart) {
-    
+        
     }
     
-    public String getCategoryName() {
+    public Text getCategoryName() {
         return categoryName;
     }
     
@@ -73,8 +75,8 @@ public class MultiElementListEntry<T> extends TooltipListEntry<T> {
     }
     
     @Override
-    public void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
-        super.render(index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta);
+    public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
+        super.render(matrices, index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta);
         widget.rectangle.x = x - 19;
         widget.rectangle.y = y;
         widget.rectangle.width = entryWidth + 19;
@@ -82,8 +84,8 @@ public class MultiElementListEntry<T> extends TooltipListEntry<T> {
         MinecraftClient.getInstance().getTextureManager().bindTexture(CONFIG_TEX);
         DiffuseLighting.disable();
         RenderSystem.color4f(1, 1, 1, 1);
-        drawTexture(x - 15, y + 4, 24, (widget.rectangle.contains(mouseX, mouseY) ? 18 : 0) + (expanded ? 9 : 0), 9, 9);
-        MinecraftClient.getInstance().textRenderer.drawWithShadow(I18n.translate(categoryName), x, y + 5, widget.rectangle.contains(mouseX, mouseY) ? 0xffe6fe16 : -1);
+        drawTexture(matrices, x - 15, y + 4, 24, (widget.rectangle.contains(mouseX, mouseY) ? 18 : 0) + (expanded ? 9 : 0), 9, 9);
+        MinecraftClient.getInstance().textRenderer.method_27517(matrices, categoryName, x, y + 5, widget.rectangle.contains(mouseX, mouseY) ? 0xffe6fe16 : -1);
         for (AbstractConfigListEntry<?> entry : entries) {
             entry.setParent(getParent());
             entry.setScreen(getScreen());
@@ -91,7 +93,7 @@ public class MultiElementListEntry<T> extends TooltipListEntry<T> {
         if (expanded) {
             int yy = y + 24;
             for (AbstractConfigListEntry<?> entry : entries) {
-                entry.render(-1, yy, x + 14, entryWidth - 14, entry.getItemHeight(), mouseX, mouseY, isSelected, delta);
+                entry.render(matrices, -1, yy, x + 14, entryWidth - 14, entry.getItemHeight(), mouseX, mouseY, isSelected, delta);
                 yy += entry.getItemHeight();
                 yy += Math.max(0, entry.getMorePossibleHeight());
             }
@@ -126,10 +128,10 @@ public class MultiElementListEntry<T> extends TooltipListEntry<T> {
     }
     
     @Override
-    public void lateRender(int mouseX, int mouseY, float delta) {
+    public void lateRender(MatrixStack matrices, int mouseX, int mouseY, float delta) {
         if (expanded) {
             for (AbstractConfigListEntry<?> entry : entries) {
-                entry.lateRender(mouseX, mouseY, delta);
+                entry.lateRender(matrices, mouseX, mouseY, delta);
             }
         }
     }
@@ -161,11 +163,11 @@ public class MultiElementListEntry<T> extends TooltipListEntry<T> {
     }
     
     @Override
-    public Optional<String> getError() {
-        List<String> errors = entries.stream().map(AbstractConfigListEntry::getConfigError).filter(Optional::isPresent).map(Optional::get).collect(Collectors.toList());
+    public Optional<Text> getError() {
+        List<Text> errors = entries.stream().map(AbstractConfigListEntry::getConfigError).filter(Optional::isPresent).map(Optional::get).collect(Collectors.toList());
         
         if (errors.size() > 1)
-            return Optional.of(I18n.translate("text.cloth-config.multi_error"));
+            return Optional.of(new TranslatableText("text.cloth-config.multi_error"));
         else
             return errors.stream().findFirst();
     }

+ 6 - 4
src/main/java/me/shedaniel/clothconfig2/gui/entries/NestedListListEntry.java

@@ -5,6 +5,8 @@ import me.shedaniel.clothconfig2.gui.entries.NestedListListEntry.NestedListCell;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
 import net.minecraft.client.gui.Element;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.text.Text;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.Nullable;
 
@@ -24,7 +26,7 @@ public final class NestedListListEntry<T, INNER extends AbstractConfigListEntry<
     
     @ApiStatus.Internal
     @Deprecated
-    public NestedListListEntry(String fieldName, List<T> value, boolean defaultExpanded, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<T>> saveConsumer, Supplier<List<T>> defaultValue, String resetButtonKey, boolean deleteButtonEnabled, boolean insertInFront, BiFunction<T, NestedListListEntry<T, INNER>, INNER> createNewCell) {
+    public NestedListListEntry(Text fieldName, List<T> value, boolean defaultExpanded, Supplier<Optional<Text[]>> tooltipSupplier, Consumer<List<T>> saveConsumer, Supplier<List<T>> defaultValue, Text resetButtonKey, boolean deleteButtonEnabled, boolean insertInFront, BiFunction<T, NestedListListEntry<T, INNER>, INNER> createNewCell) {
         super(fieldName, value, defaultExpanded, null, null, defaultValue, resetButtonKey, false, deleteButtonEnabled, insertInFront, (t, nestedListListEntry) -> new NestedListCell<>(t, nestedListListEntry, createNewCell.apply(t, nestedListListEntry)));
     }
     
@@ -62,7 +64,7 @@ public final class NestedListListEntry<T, INNER extends AbstractConfigListEntry<
         }
         
         @Override
-        public Optional<String> getError() {
+        public Optional<Text> getError() {
             return nestedEntry.getError();
         }
         
@@ -72,9 +74,9 @@ public final class NestedListListEntry<T, INNER extends AbstractConfigListEntry<
         }
         
         @Override
-        public void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
+        public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
             nestedEntry.setScreen(listListEntry.getScreen());
-            nestedEntry.render(index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta);
+            nestedEntry.render(matrices, index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta);
         }
         
         @Override

+ 18 - 21
src/main/java/me/shedaniel/clothconfig2/gui/entries/SelectionListEntry.java

@@ -7,8 +7,11 @@ import net.fabricmc.api.Environment;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.gui.widget.ButtonWidget;
-import net.minecraft.client.resource.language.I18n;
+import net.minecraft.client.util.NarratorManager;
 import net.minecraft.client.util.Window;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.text.Text;
+import net.minecraft.text.TranslatableText;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.NotNull;
 
@@ -28,35 +31,29 @@ public class SelectionListEntry<T> extends TooltipListEntry<T> {
     private Consumer<T> saveConsumer;
     private Supplier<T> defaultValue;
     private List<Element> widgets;
-    private Function<T, String> nameProvider;
+    private Function<T, Text> nameProvider;
     
     @ApiStatus.Internal
     @Deprecated
-    public SelectionListEntry(String fieldName, T[] valuesArray, T value, Consumer<T> saveConsumer) {
-        this(fieldName, valuesArray, value, "text.cloth-config.reset_value", null, saveConsumer);
-    }
-    
-    @ApiStatus.Internal
-    @Deprecated
-    public SelectionListEntry(String fieldName, T[] valuesArray, T value, String resetButtonKey, Supplier<T> defaultValue, Consumer<T> saveConsumer) {
+    public SelectionListEntry(Text fieldName, T[] valuesArray, T value, Text resetButtonKey, Supplier<T> defaultValue, Consumer<T> saveConsumer) {
         this(fieldName, valuesArray, value, resetButtonKey, defaultValue, saveConsumer, null);
     }
     
     @ApiStatus.Internal
     @Deprecated
-    public SelectionListEntry(String fieldName, T[] valuesArray, T value, String resetButtonKey, Supplier<T> defaultValue, Consumer<T> saveConsumer, Function<T, String> nameProvider) {
+    public SelectionListEntry(Text fieldName, T[] valuesArray, T value, Text resetButtonKey, Supplier<T> defaultValue, Consumer<T> saveConsumer, Function<T, Text> nameProvider) {
         this(fieldName, valuesArray, value, resetButtonKey, defaultValue, saveConsumer, nameProvider, null);
     }
     
     @ApiStatus.Internal
     @Deprecated
-    public SelectionListEntry(String fieldName, T[] valuesArray, T value, String resetButtonKey, Supplier<T> defaultValue, Consumer<T> saveConsumer, Function<T, String> nameProvider, Supplier<Optional<String[]>> tooltipSupplier) {
+    public SelectionListEntry(Text fieldName, T[] valuesArray, T value, Text resetButtonKey, Supplier<T> defaultValue, Consumer<T> saveConsumer, Function<T, Text> nameProvider, Supplier<Optional<Text[]>> tooltipSupplier) {
         this(fieldName, valuesArray, value, resetButtonKey, defaultValue, saveConsumer, nameProvider, tooltipSupplier, false);
     }
     
     @ApiStatus.Internal
     @Deprecated
-    public SelectionListEntry(String fieldName, T[] valuesArray, T value, String resetButtonKey, Supplier<T> defaultValue, Consumer<T> saveConsumer, Function<T, String> nameProvider, Supplier<Optional<String[]>> tooltipSupplier, boolean requiresRestart) {
+    public SelectionListEntry(Text fieldName, T[] valuesArray, T value, Text resetButtonKey, Supplier<T> defaultValue, Consumer<T> saveConsumer, Function<T, Text> nameProvider, Supplier<Optional<Text[]>> tooltipSupplier, boolean requiresRestart) {
         super(fieldName, tooltipSupplier, requiresRestart);
         if (valuesArray != null)
             this.values = ImmutableList.copyOf(valuesArray);
@@ -65,18 +62,18 @@ public class SelectionListEntry<T> extends TooltipListEntry<T> {
         this.defaultValue = defaultValue;
         this.index = new AtomicInteger(this.values.indexOf(value));
         this.index.compareAndSet(-1, 0);
-        this.buttonWidget = new ButtonWidget(0, 0, 150, 20, "", widget -> {
+        this.buttonWidget = new ButtonWidget(0, 0, 150, 20, NarratorManager.EMPTY, widget -> {
             SelectionListEntry.this.index.incrementAndGet();
             SelectionListEntry.this.index.compareAndSet(SelectionListEntry.this.values.size(), 0);
             getScreen().setEdited(true, isRequiresRestart());
         });
-        this.resetButton = new ButtonWidget(0, 0, MinecraftClient.getInstance().textRenderer.getStringWidth(I18n.translate(resetButtonKey)) + 6, 20, I18n.translate(resetButtonKey), widget -> {
+        this.resetButton = new ButtonWidget(0, 0, MinecraftClient.getInstance().textRenderer.method_27525(resetButtonKey) + 6, 20, resetButtonKey, widget -> {
             SelectionListEntry.this.index.set(getDefaultIndex());
             getScreen().setEdited(true, isRequiresRestart());
         });
         this.saveConsumer = saveConsumer;
         this.widgets = Lists.newArrayList(buttonWidget, resetButton);
-        this.nameProvider = nameProvider == null ? (t -> I18n.translate(t instanceof Translatable ? ((Translatable) t).getKey() : t.toString())) : nameProvider;
+        this.nameProvider = nameProvider == null ? (t -> new TranslatableText(t instanceof Translatable ? ((Translatable) t).getKey() : t.toString())) : nameProvider;
     }
     
     @Override
@@ -96,8 +93,8 @@ public class SelectionListEntry<T> extends TooltipListEntry<T> {
     }
     
     @Override
-    public void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
-        super.render(index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta);
+    public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
+        super.render(matrices, index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta);
         Window window = MinecraftClient.getInstance().getWindow();
         this.resetButton.active = isEditable() && getDefaultValue().isPresent() && getDefaultIndex() != this.index.get();
         this.resetButton.y = y;
@@ -105,17 +102,17 @@ public class SelectionListEntry<T> extends TooltipListEntry<T> {
         this.buttonWidget.y = y;
         this.buttonWidget.setMessage(nameProvider.apply(getValue()));
         if (MinecraftClient.getInstance().textRenderer.isRightToLeft()) {
-            MinecraftClient.getInstance().textRenderer.drawWithShadow(I18n.translate(getFieldName()), window.getScaledWidth() - x - MinecraftClient.getInstance().textRenderer.getStringWidth(I18n.translate(getFieldName())), y + 5, getPreferredTextColor());
+            MinecraftClient.getInstance().textRenderer.method_27517(matrices, getFieldName(), window.getScaledWidth() - x - MinecraftClient.getInstance().textRenderer.method_27525(getFieldName()), y + 5, getPreferredTextColor());
             this.resetButton.x = x;
             this.buttonWidget.x = x + resetButton.getWidth() + 2;
         } else {
-            MinecraftClient.getInstance().textRenderer.drawWithShadow(I18n.translate(getFieldName()), x, y + 5, getPreferredTextColor());
+            MinecraftClient.getInstance().textRenderer.method_27517(matrices, getFieldName(), x, y + 5, getPreferredTextColor());
             this.resetButton.x = x + entryWidth - resetButton.getWidth();
             this.buttonWidget.x = x + entryWidth - 150;
         }
         this.buttonWidget.setWidth(150 - resetButton.getWidth() - 2);
-        resetButton.render(mouseX, mouseY, delta);
-        buttonWidget.render(mouseX, mouseY, delta);
+        resetButton.render(matrices, mouseX, mouseY, delta);
+        buttonWidget.render(matrices, mouseX, mouseY, delta);
     }
     
     private int getDefaultIndex() {

+ 4 - 9
src/main/java/me/shedaniel/clothconfig2/gui/entries/StringListEntry.java

@@ -2,6 +2,7 @@ package me.shedaniel.clothconfig2.gui.entries;
 
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
+import net.minecraft.text.Text;
 import org.jetbrains.annotations.ApiStatus;
 
 import java.util.Optional;
@@ -15,26 +16,20 @@ public class StringListEntry extends TextFieldListEntry<String> {
     
     @ApiStatus.Internal
     @Deprecated
-    public StringListEntry(String fieldName, String value, Consumer<String> saveConsumer) {
-        this(fieldName, value, "text.cloth-config.reset_value", null, saveConsumer);
-    }
-    
-    @ApiStatus.Internal
-    @Deprecated
-    public StringListEntry(String fieldName, String value, String resetButtonKey, Supplier<String> defaultValue, Consumer<String> saveConsumer) {
+    public StringListEntry(Text fieldName, String value, Text resetButtonKey, Supplier<String> defaultValue, Consumer<String> saveConsumer) {
         super(fieldName, value, resetButtonKey, defaultValue);
         this.saveConsumer = saveConsumer;
     }
     
     @ApiStatus.Internal
     @Deprecated
-    public StringListEntry(String fieldName, String value, String resetButtonKey, Supplier<String> defaultValue, Consumer<String> saveConsumer, Supplier<Optional<String[]>> tooltipSupplier) {
+    public StringListEntry(Text fieldName, String value, Text resetButtonKey, Supplier<String> defaultValue, Consumer<String> saveConsumer, Supplier<Optional<Text[]>> tooltipSupplier) {
         this(fieldName, value, resetButtonKey, defaultValue, saveConsumer, tooltipSupplier, false);
     }
     
     @ApiStatus.Internal
     @Deprecated
-    public StringListEntry(String fieldName, String value, String resetButtonKey, Supplier<String> defaultValue, Consumer<String> saveConsumer, Supplier<Optional<String[]>> tooltipSupplier, boolean requiresRestart) {
+    public StringListEntry(Text fieldName, String value, Text resetButtonKey, Supplier<String> defaultValue, Consumer<String> saveConsumer, Supplier<Optional<Text[]>> tooltipSupplier, boolean requiresRestart) {
         super(fieldName, value, resetButtonKey, defaultValue, tooltipSupplier, requiresRestart);
         this.saveConsumer = saveConsumer;
     }

+ 5 - 4
src/main/java/me/shedaniel/clothconfig2/gui/entries/StringListListEntry.java

@@ -2,6 +2,7 @@ package me.shedaniel.clothconfig2.gui.entries;
 
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
+import net.minecraft.text.Text;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -16,19 +17,19 @@ public class StringListListEntry extends AbstractTextFieldListListEntry<String,
     
     @ApiStatus.Internal
     @Deprecated
-    public StringListListEntry(String fieldName, List<String> value, boolean defaultExpanded, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<String>> saveConsumer, Supplier<List<String>> defaultValue, String resetButtonKey) {
+    public StringListListEntry(Text fieldName, List<String> value, boolean defaultExpanded, Supplier<Optional<Text[]>> tooltipSupplier, Consumer<List<String>> saveConsumer, Supplier<List<String>> defaultValue, Text resetButtonKey) {
         this(fieldName, value, defaultExpanded, tooltipSupplier, saveConsumer, defaultValue, resetButtonKey, false);
     }
     
     @ApiStatus.Internal
     @Deprecated
-    public StringListListEntry(String fieldName, List<String> value, boolean defaultExpanded, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<String>> saveConsumer, Supplier<List<String>> defaultValue, String resetButtonKey, boolean requiresRestart) {
+    public StringListListEntry(Text fieldName, List<String> value, boolean defaultExpanded, Supplier<Optional<Text[]>> tooltipSupplier, Consumer<List<String>> saveConsumer, Supplier<List<String>> defaultValue, Text resetButtonKey, boolean requiresRestart) {
         this(fieldName, value, defaultExpanded, tooltipSupplier, saveConsumer, defaultValue, resetButtonKey, requiresRestart, true, true);
     }
     
     @ApiStatus.Internal
     @Deprecated
-    public StringListListEntry(String fieldName, List<String> value, boolean defaultExpanded, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<String>> saveConsumer, Supplier<List<String>> defaultValue, String resetButtonKey, boolean requiresRestart, boolean deleteButtonEnabled, boolean insertInFront) {
+    public StringListListEntry(Text fieldName, List<String> value, boolean defaultExpanded, Supplier<Optional<Text[]>> tooltipSupplier, Consumer<List<String>> saveConsumer, Supplier<List<String>> defaultValue, Text resetButtonKey, boolean requiresRestart, boolean deleteButtonEnabled, boolean insertInFront) {
         super(fieldName, value, defaultExpanded, tooltipSupplier, saveConsumer, defaultValue, resetButtonKey, requiresRestart, deleteButtonEnabled, insertInFront, StringListCell::new);
     }
     
@@ -63,7 +64,7 @@ public class StringListListEntry extends AbstractTextFieldListListEntry<String,
         }
         
         @Override
-        public Optional<String> getError() {
+        public Optional<Text> getError() {
             return Optional.empty();
         }
         

+ 17 - 15
src/main/java/me/shedaniel/clothconfig2/gui/entries/SubCategoryListEntry.java

@@ -9,9 +9,11 @@ import net.fabricmc.api.Environment;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.render.DiffuseLighting;
-import net.minecraft.client.resource.language.I18n;
 import net.minecraft.client.sound.PositionedSoundInstance;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.sound.SoundEvents;
+import net.minecraft.text.Text;
+import net.minecraft.text.TranslatableText;
 import net.minecraft.util.Identifier;
 
 import java.util.ArrayList;
@@ -23,14 +25,14 @@ import java.util.Optional;
 public class SubCategoryListEntry extends TooltipListEntry<List<AbstractConfigListEntry>> {
     
     private static final Identifier CONFIG_TEX = new Identifier("cloth-config2", "textures/gui/cloth_config.png");
-    private String categoryName;
+    private Text categoryName;
     private List<AbstractConfigListEntry> entries;
     private CategoryLabelWidget widget;
     private List<Element> children;
     private boolean expanded;
     
     @Deprecated
-    public SubCategoryListEntry(String categoryName, List<AbstractConfigListEntry> entries, boolean defaultExpanded) {
+    public SubCategoryListEntry(Text categoryName, List<AbstractConfigListEntry> entries, boolean defaultExpanded) {
         super(categoryName, null);
         this.categoryName = categoryName;
         this.entries = entries;
@@ -50,10 +52,10 @@ public class SubCategoryListEntry extends TooltipListEntry<List<AbstractConfigLi
     
     @Override
     public void setRequiresRestart(boolean requiresRestart) {
-    
+        
     }
     
-    public String getCategoryName() {
+    public Text getCategoryName() {
         return categoryName;
     }
     
@@ -68,8 +70,8 @@ public class SubCategoryListEntry extends TooltipListEntry<List<AbstractConfigLi
     }
     
     @Override
-    public void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isHovered, float delta) {
-        super.render(index, y, x, entryWidth, entryHeight, mouseX, mouseY, isHovered, delta);
+    public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isHovered, float delta) {
+        super.render(matrices, index, y, x, entryWidth, entryHeight, mouseX, mouseY, isHovered, delta);
         widget.rectangle.x = x - 19;
         widget.rectangle.y = y;
         widget.rectangle.width = entryWidth + 19;
@@ -77,8 +79,8 @@ public class SubCategoryListEntry extends TooltipListEntry<List<AbstractConfigLi
         MinecraftClient.getInstance().getTextureManager().bindTexture(CONFIG_TEX);
         DiffuseLighting.disable();
         RenderSystem.color4f(1, 1, 1, 1);
-        drawTexture(x - 15, y + 4, 24, (widget.rectangle.contains(mouseX, mouseY) ? 18 : 0) + (expanded ? 9 : 0), 9, 9);
-        MinecraftClient.getInstance().textRenderer.drawWithShadow(I18n.translate(categoryName), x, y + 5, widget.rectangle.contains(mouseX, mouseY) ? 0xffe6fe16 : -1);
+        drawTexture(matrices, x - 15, y + 4, 24, (widget.rectangle.contains(mouseX, mouseY) ? 18 : 0) + (expanded ? 9 : 0), 9, 9);
+        MinecraftClient.getInstance().textRenderer.method_27517(matrices, categoryName, x, y + 5, widget.rectangle.contains(mouseX, mouseY) ? 0xffe6fe16 : -1);
         for (AbstractConfigListEntry<?> entry : entries) {
             entry.setParent(getParent());
             entry.setScreen(getScreen());
@@ -86,7 +88,7 @@ public class SubCategoryListEntry extends TooltipListEntry<List<AbstractConfigLi
         if (expanded) {
             int yy = y + 24;
             for (AbstractConfigListEntry<?> entry : entries) {
-                entry.render(-1, yy, x + 14, entryWidth - 14, entry.getItemHeight(), mouseX, mouseY, isHovered && getFocused() == entry, delta);
+                entry.render(matrices, -1, yy, x + 14, entryWidth - 14, entry.getItemHeight(), mouseX, mouseY, isHovered && getFocused() == entry, delta);
                 yy += entry.getItemHeight();
             }
         }
@@ -100,10 +102,10 @@ public class SubCategoryListEntry extends TooltipListEntry<List<AbstractConfigLi
     }
     
     @Override
-    public void lateRender(int mouseX, int mouseY, float delta) {
+    public void lateRender(MatrixStack matrices, int mouseX, int mouseY, float delta) {
         if (expanded) {
             for (AbstractConfigListEntry<?> entry : entries) {
-                entry.lateRender(mouseX, mouseY, delta);
+                entry.lateRender(matrices, mouseX, mouseY, delta);
             }
         }
     }
@@ -155,12 +157,12 @@ public class SubCategoryListEntry extends TooltipListEntry<List<AbstractConfigLi
     }
     
     @Override
-    public Optional<String> getError() {
-        String error = null;
+    public Optional<Text> getError() {
+        Text error = null;
         for (AbstractConfigListEntry<?> entry : entries)
             if (entry.getError().isPresent()) {
                 if (error != null)
-                    return Optional.ofNullable(I18n.translate("text.cloth-config.multi_error"));
+                    return Optional.ofNullable(new TranslatableText("text.cloth-config.multi_error"));
                 return entry.getError();
             }
         return Optional.ofNullable(error);

+ 17 - 15
src/main/java/me/shedaniel/clothconfig2/gui/entries/TextFieldListEntry.java

@@ -7,8 +7,10 @@ import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.gui.widget.ButtonWidget;
 import net.minecraft.client.gui.widget.TextFieldWidget;
-import net.minecraft.client.resource.language.I18n;
+import net.minecraft.client.util.NarratorManager;
 import net.minecraft.client.util.Window;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.text.Text;
 import org.jetbrains.annotations.ApiStatus;
 
 import java.util.List;
@@ -27,29 +29,29 @@ public abstract class TextFieldListEntry<T> extends TooltipListEntry<T> {
     
     @ApiStatus.Internal
     @Deprecated
-    protected TextFieldListEntry(String fieldName, T original, String resetButtonKey, Supplier<T> defaultValue) {
+    protected TextFieldListEntry(Text fieldName, T original, Text resetButtonKey, Supplier<T> defaultValue) {
         this(fieldName, original, resetButtonKey, defaultValue, null);
     }
     
     @ApiStatus.Internal
     @Deprecated
-    protected TextFieldListEntry(String fieldName, T original, String resetButtonKey, Supplier<T> defaultValue, Supplier<Optional<String[]>> tooltipSupplier) {
+    protected TextFieldListEntry(Text fieldName, T original, Text resetButtonKey, Supplier<T> defaultValue, Supplier<Optional<Text[]>> tooltipSupplier) {
         this(fieldName, original, resetButtonKey, defaultValue, tooltipSupplier, false);
     }
     
     @ApiStatus.Internal
     @Deprecated
-    protected TextFieldListEntry(String fieldName, T original, String resetButtonKey, Supplier<T> defaultValue, Supplier<Optional<String[]>> tooltipSupplier, boolean requiresRestart) {
+    protected TextFieldListEntry(Text fieldName, T original, Text resetButtonKey, Supplier<T> defaultValue, Supplier<Optional<Text[]>> tooltipSupplier, boolean requiresRestart) {
         super(fieldName, tooltipSupplier);
         this.defaultValue = defaultValue;
         this.original = original;
-        this.textFieldWidget = new TextFieldWidget(MinecraftClient.getInstance().textRenderer, 0, 0, 148, 18, "") {
+        this.textFieldWidget = new TextFieldWidget(MinecraftClient.getInstance().textRenderer, 0, 0, 148, 18, NarratorManager.EMPTY) {
             @Override
-            public void render(int int_1, int int_2, float float_1) {
+            public void render(MatrixStack matrices, int int_1, int int_2, float float_1) {
 //                boolean f = isFocused();
                 setFocused(isSelected);
                 textFieldPreRender(this);
-                super.render(int_1, int_2, float_1);
+                super.render(matrices, int_1, int_2, float_1);
 //                setFocused(f);
             }
             
@@ -64,7 +66,7 @@ public abstract class TextFieldListEntry<T> extends TooltipListEntry<T> {
             if (getScreen() != null && !original.equals(s))
                 getScreen().setEdited(true, isRequiresRestart());
         });
-        this.resetButton = new ButtonWidget(0, 0, MinecraftClient.getInstance().textRenderer.getStringWidth(I18n.translate(resetButtonKey)) + 6, 20, I18n.translate(resetButtonKey), widget -> {
+        this.resetButton = new ButtonWidget(0, 0, MinecraftClient.getInstance().textRenderer.method_27525(resetButtonKey) + 6, 20, resetButtonKey, widget -> {
             TextFieldListEntry.this.textFieldWidget.setText(String.valueOf(defaultValue.get()));
             getScreen().setEdited(true, isRequiresRestart());
         });
@@ -85,7 +87,7 @@ public abstract class TextFieldListEntry<T> extends TooltipListEntry<T> {
     }
     
     protected void textFieldPreRender(TextFieldWidget widget) {
-    
+        
     }
     
     @Override
@@ -94,25 +96,25 @@ public abstract class TextFieldListEntry<T> extends TooltipListEntry<T> {
     }
     
     @Override
-    public void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
-        super.render(index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta);
+    public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
+        super.render(matrices, index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta);
         Window window = MinecraftClient.getInstance().getWindow();
         this.resetButton.active = isEditable() && getDefaultValue().isPresent() && !isMatchDefault(textFieldWidget.getText());
         this.resetButton.y = y;
         this.textFieldWidget.setEditable(isEditable());
         this.textFieldWidget.y = y + 1;
         if (MinecraftClient.getInstance().textRenderer.isRightToLeft()) {
-            MinecraftClient.getInstance().textRenderer.drawWithShadow(I18n.translate(getFieldName()), window.getScaledWidth() - x - MinecraftClient.getInstance().textRenderer.getStringWidth(I18n.translate(getFieldName())), y + 5, getPreferredTextColor());
+            MinecraftClient.getInstance().textRenderer.method_27517(matrices, getFieldName(), window.getScaledWidth() - x - MinecraftClient.getInstance().textRenderer.method_27525(getFieldName()), y + 5, getPreferredTextColor());
             this.resetButton.x = x;
             this.textFieldWidget.x = x + resetButton.getWidth();
         } else {
-            MinecraftClient.getInstance().textRenderer.drawWithShadow(I18n.translate(getFieldName()), x, y + 5, getPreferredTextColor());
+            MinecraftClient.getInstance().textRenderer.method_27517(matrices, getFieldName(), x, y + 5, getPreferredTextColor());
             this.resetButton.x = x + entryWidth - resetButton.getWidth();
             this.textFieldWidget.x = x + entryWidth - 148;
         }
         setTextFieldWidth(textFieldWidget, 148 - resetButton.getWidth() - 4);
-        resetButton.render(mouseX, mouseY, delta);
-        textFieldWidget.render(mouseX, mouseY, delta);
+        resetButton.render(matrices, mouseX, mouseY, delta);
+        textFieldWidget.render(matrices, mouseX, mouseY, delta);
     }
     
     protected abstract boolean isMatchDefault(String text);

+ 13 - 11
src/main/java/me/shedaniel/clothconfig2/gui/entries/TextListEntry.java

@@ -4,6 +4,8 @@ import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.Element;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.text.Text;
 import org.jetbrains.annotations.ApiStatus;
 
 import java.util.Collections;
@@ -16,36 +18,36 @@ public class TextListEntry extends TooltipListEntry<Object> {
     
     private int savedWidth = -1;
     private int color;
-    private String text;
+    private Text text;
     
     @ApiStatus.Internal
     @Deprecated
-    public TextListEntry(String fieldName, String text) {
+    public TextListEntry(Text fieldName, Text text) {
         this(fieldName, text, -1);
     }
     
     @ApiStatus.Internal
     @Deprecated
-    public TextListEntry(String fieldName, String text, int color) {
+    public TextListEntry(Text fieldName, Text text, int color) {
         this(fieldName, text, color, null);
     }
     
     @ApiStatus.Internal
     @Deprecated
-    public TextListEntry(String fieldName, String text, int color, Supplier<Optional<String[]>> tooltipSupplier) {
+    public TextListEntry(Text fieldName, Text text, int color, Supplier<Optional<Text[]>> tooltipSupplier) {
         super(fieldName, tooltipSupplier);
         this.text = text;
         this.color = color;
     }
     
     @Override
-    public void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
-        super.render(index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta);
+    public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
+        super.render(matrices, index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta);
         this.savedWidth = entryWidth;
         int yy = y + 4;
-        List<String> strings = MinecraftClient.getInstance().textRenderer.wrapStringToWidthAsList(text, savedWidth);
-        for (String string : strings) {
-            MinecraftClient.getInstance().textRenderer.drawWithShadow(string, x, yy, color);
+        List<Text> strings = MinecraftClient.getInstance().textRenderer.wrapStringToWidthAsList(text, savedWidth);
+        for (Text string : strings) {
+            MinecraftClient.getInstance().textRenderer.method_27517(matrices, string, x, yy, color);
             yy += MinecraftClient.getInstance().textRenderer.fontHeight + 3;
         }
     }
@@ -54,7 +56,7 @@ public class TextListEntry extends TooltipListEntry<Object> {
     public int getItemHeight() {
         if (savedWidth == -1)
             return 12;
-        List<String> strings = MinecraftClient.getInstance().textRenderer.wrapStringToWidthAsList(text, savedWidth);
+        List<Text> strings = MinecraftClient.getInstance().textRenderer.wrapStringToWidthAsList(text, savedWidth);
         if (strings.isEmpty())
             return 0;
         return 15 + strings.size() * 12;
@@ -62,7 +64,7 @@ public class TextListEntry extends TooltipListEntry<Object> {
     
     @Override
     public void save() {
-    
+        
     }
     
     @Override

+ 10 - 8
src/main/java/me/shedaniel/clothconfig2/gui/entries/TooltipListEntry.java

@@ -5,6 +5,8 @@ import me.shedaniel.clothconfig2.api.QueuedTooltip;
 import me.shedaniel.math.Point;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.text.Text;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.Nullable;
 
@@ -14,25 +16,25 @@ import java.util.function.Supplier;
 @Environment(EnvType.CLIENT)
 public abstract class TooltipListEntry<T> extends AbstractConfigListEntry<T> {
     
-    @Nullable private Supplier<Optional<String[]>> tooltipSupplier;
+    @Nullable private Supplier<Optional<Text[]>> tooltipSupplier;
     
     @ApiStatus.Internal
     @Deprecated
-    public TooltipListEntry(String fieldName, @Nullable Supplier<Optional<String[]>> tooltipSupplier) {
+    public TooltipListEntry(Text fieldName, @Nullable Supplier<Optional<Text[]>> tooltipSupplier) {
         this(fieldName, tooltipSupplier, false);
     }
     
     @ApiStatus.Internal
     @Deprecated
-    public TooltipListEntry(String fieldName, @Nullable Supplier<Optional<String[]>> tooltipSupplier, boolean requiresRestart) {
+    public TooltipListEntry(Text fieldName, @Nullable Supplier<Optional<Text[]>> tooltipSupplier, boolean requiresRestart) {
         super(fieldName, requiresRestart);
         this.tooltipSupplier = tooltipSupplier;
     }
     
     @Override
-    public void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isHovered, float delta) {
+    public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isHovered, float delta) {
         if (isMouseInside(mouseX, mouseY, x, y, entryWidth, entryHeight)) {
-            Optional<String[]> tooltip = getTooltip();
+            Optional<Text[]> tooltip = getTooltip();
             if (tooltip.isPresent() && tooltip.get().length > 0)
                 getScreen().queueTooltip(QueuedTooltip.create(new Point(mouseX, mouseY), tooltip.get()));
         }
@@ -42,18 +44,18 @@ public abstract class TooltipListEntry<T> extends AbstractConfigListEntry<T> {
         return mouseX >= x && mouseY >= y && mouseX <= x + entryWidth && mouseY <= y + entryHeight && getParent().isMouseOver(mouseX, mouseY);
     }
     
-    public Optional<String[]> getTooltip() {
+    public Optional<Text[]> getTooltip() {
         if (tooltipSupplier != null)
             return tooltipSupplier.get();
         return Optional.empty();
     }
     
     @Nullable
-    public Supplier<Optional<String[]>> getTooltipSupplier() {
+    public Supplier<Optional<Text[]>> getTooltipSupplier() {
         return tooltipSupplier;
     }
     
-    public void setTooltipSupplier(@Nullable Supplier<Optional<String[]>> tooltipSupplier) {
+    public void setTooltipSupplier(@Nullable Supplier<Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = tooltipSupplier;
     }
     

+ 7 - 5
src/main/java/me/shedaniel/clothconfig2/gui/widget/ColorDisplayWidget.java

@@ -1,6 +1,8 @@
 package me.shedaniel.clothconfig2.gui.widget;
 
 import net.minecraft.client.gui.widget.AbstractButtonWidget;
+import net.minecraft.client.util.NarratorManager;
+import net.minecraft.client.util.math.MatrixStack;
 
 public class ColorDisplayWidget extends AbstractButtonWidget {
     
@@ -8,16 +10,16 @@ public class ColorDisplayWidget extends AbstractButtonWidget {
     protected int size;
     
     public ColorDisplayWidget(int x, int y, int size, int color) {
-        super(x, y, size, size, "");
+        super(x, y, size, size, NarratorManager.EMPTY);
         this.color = color;
         this.size = size;
     }
     
     @Override
-    public void renderButton(int mouseX, int mouseY, float delta) {
-        fillGradient(this.x, this.y, this.x + size, this.y + size, -0x5F5F60, -0x5F5F60);
-        fillGradient(this.x + 1, this.y + 1, this.x + size - 1, this.y + size - 1, 0xffffffff, 0xffffffff);
-        fillGradient(this.x + 1, this.y + 1, this.x + size - 1, this.y + size - 1, color, color);
+    public void renderButton(MatrixStack matrices, int mouseX, int mouseY, float delta) {
+        fillGradient(matrices, this.x, this.y, this.x + size, this.y + size, -0x5F5F60, -0x5F5F60);
+        fillGradient(matrices, this.x + 1, this.y + 1, this.x + size - 1, this.y + size - 1, 0xffffffff, 0xffffffff);
+        fillGradient(matrices, this.x + 1, this.y + 1, this.x + size - 1, this.y + size - 1, color, color);
     }
     
     @Override

+ 67 - 60
src/main/java/me/shedaniel/clothconfig2/gui/widget/DynamicEntryListWidget.java

@@ -15,8 +15,10 @@ import net.minecraft.client.render.BufferBuilder;
 import net.minecraft.client.render.DiffuseLighting;
 import net.minecraft.client.render.Tessellator;
 import net.minecraft.client.render.VertexFormats;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.math.MathHelper;
+import net.minecraft.util.math.Matrix4f;
 
 import java.util.AbstractList;
 import java.util.ArrayList;
@@ -155,30 +157,32 @@ public abstract class DynamicEntryListWidget<E extends DynamicEntryListWidget.En
     protected void clickedHeader(int int_1, int int_2) {
     }
     
-    protected void renderHeader(int int_1, int int_2, Tessellator tessellator) {
+    protected void renderHeader(MatrixStack matrices, int rowLeft, int startY, Tessellator tessellator) {
     }
     
     protected void drawBackground() {
     }
     
-    protected void renderDecorations(int int_1, int int_2) {
+    protected void renderDecorations(MatrixStack matrices, int mouseX, int mouseY) {
     }
     
     @Deprecated
-    protected void renderBackBackground(BufferBuilder buffer, Tessellator tessellator) {
+    protected void renderBackBackground(MatrixStack matrices, BufferBuilder buffer, Tessellator tessellator) {
         this.client.getTextureManager().bindTexture(backgroundLocation);
         RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
+        Matrix4f matrix = matrices.peek().getModel();
         float float_2 = 32.0F;
         buffer.begin(7, VertexFormats.POSITION_TEXTURE_COLOR);
-        buffer.vertex(this.left, this.bottom, 0.0D).texture(this.left / 32.0F, ((this.bottom + (int) this.getScroll()) / 32.0F)).color(32, 32, 32, 255).next();
-        buffer.vertex(this.right, this.bottom, 0.0D).texture(this.right / 32.0F, ((this.bottom + (int) this.getScroll()) / 32.0F)).color(32, 32, 32, 255).next();
-        buffer.vertex(this.right, this.top, 0.0D).texture(this.right / 32.0F, ((this.top + (int) this.getScroll()) / 32.0F)).color(32, 32, 32, 255).next();
-        buffer.vertex(this.left, this.top, 0.0D).texture(this.left / 32.0F, ((this.top + (int) this.getScroll()) / 32.0F)).color(32, 32, 32, 255).next();
+        buffer.vertex(matrix, this.left, this.bottom, 0.0F).texture(this.left / 32.0F, ((this.bottom + (int) this.getScroll()) / 32.0F)).color(32, 32, 32, 255).next();
+        buffer.vertex(matrix, this.right, this.bottom, 0.0F).texture(this.right / 32.0F, ((this.bottom + (int) this.getScroll()) / 32.0F)).color(32, 32, 32, 255).next();
+        buffer.vertex(matrix, this.right, this.top, 0.0F).texture(this.right / 32.0F, ((this.top + (int) this.getScroll()) / 32.0F)).color(32, 32, 32, 255).next();
+        buffer.vertex(matrix, this.left, this.top, 0.0F).texture(this.left / 32.0F, ((this.top + (int) this.getScroll()) / 32.0F)).color(32, 32, 32, 255).next();
         tessellator.draw();
     }
     
     @SuppressWarnings("deprecation")
-    public void render(int mouseX, int mouseY, float delta) {
+    @Override
+    public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
         this.drawBackground();
         int scrollbarPosition = this.getScrollbarPosition();
         int int_4 = scrollbarPosition + 6;
@@ -186,38 +190,39 @@ public abstract class DynamicEntryListWidget<E extends DynamicEntryListWidget.En
         RenderSystem.disableFog();
         Tessellator tessellator = Tessellator.getInstance();
         BufferBuilder buffer = tessellator.getBuffer();
-        renderBackBackground(buffer, tessellator);
+        renderBackBackground(matrices, buffer, tessellator);
         int rowLeft = this.getRowLeft();
         int startY = this.top + 4 - (int) this.getScroll();
         if (this.renderSelection)
-            this.renderHeader(rowLeft, startY, tessellator);
+            this.renderHeader(matrices, rowLeft, startY, tessellator);
         ScissorsHandler.INSTANCE.scissor(new Rectangle(left, top, width, bottom - top));
-        this.renderList(rowLeft, startY, mouseX, mouseY, delta);
+        this.renderList(matrices, rowLeft, startY, mouseX, mouseY, delta);
         ScissorsHandler.INSTANCE.removeLastScissor();
         RenderSystem.disableDepthTest();
-        this.renderHoleBackground(0, this.top, 255, 255);
-        this.renderHoleBackground(this.bottom, this.height, 255, 255);
+        this.renderHoleBackground(matrices, 0, this.top, 255, 255);
+        this.renderHoleBackground(matrices, this.bottom, this.height, 255, 255);
         RenderSystem.enableBlend();
         RenderSystem.blendFuncSeparate(770, 771, 0, 1);
         RenderSystem.disableAlphaTest();
         RenderSystem.shadeModel(7425);
         RenderSystem.disableTexture();
+        Matrix4f matrix = matrices.peek().getModel();
         buffer.begin(7, VertexFormats.POSITION_TEXTURE_COLOR);
-        buffer.vertex(this.left, this.top + 4, 0.0D).texture(0, 1).color(0, 0, 0, 0).next();
-        buffer.vertex(this.right, this.top + 4, 0.0D).texture(1, 1).color(0, 0, 0, 0).next();
-        buffer.vertex(this.right, this.top, 0.0D).texture(1, 0).color(0, 0, 0, 255).next();
-        buffer.vertex(this.left, this.top, 0.0D).texture(0, 0).color(0, 0, 0, 255).next();
+        buffer.vertex(matrix, this.left, this.top + 4, 0.0F).texture(0, 1).color(0, 0, 0, 0).next();
+        buffer.vertex(matrix, this.right, this.top + 4, 0.0F).texture(1, 1).color(0, 0, 0, 0).next();
+        buffer.vertex(matrix, this.right, this.top, 0.0F).texture(1, 0).color(0, 0, 0, 255).next();
+        buffer.vertex(matrix, this.left, this.top, 0.0F).texture(0, 0).color(0, 0, 0, 255).next();
         tessellator.draw();
         buffer.begin(7, VertexFormats.POSITION_TEXTURE_COLOR);
-        buffer.vertex(this.left, this.bottom, 0.0D).texture(0, 1).color(0, 0, 0, 255).next();
-        buffer.vertex(this.right, this.bottom, 0.0D).texture(1, 1).color(0, 0, 0, 255).next();
-        buffer.vertex(this.right, this.bottom - 4, 0.0D).texture(1, 0).color(0, 0, 0, 0).next();
-        buffer.vertex(this.left, this.bottom - 4, 0.0D).texture(0, 0).color(0, 0, 0, 0).next();
+        buffer.vertex(matrix, this.left, this.bottom, 0.0F).texture(0, 1).color(0, 0, 0, 255).next();
+        buffer.vertex(matrix, this.right, this.bottom, 0.0F).texture(1, 1).color(0, 0, 0, 255).next();
+        buffer.vertex(matrix, this.right, this.bottom - 4, 0.0F).texture(1, 0).color(0, 0, 0, 0).next();
+        buffer.vertex(matrix, this.left, this.bottom - 4, 0.0F).texture(0, 0).color(0, 0, 0, 0).next();
         tessellator.draw();
         int maxScroll = this.getMaxScroll();
-        renderScrollBar(tessellator, buffer, maxScroll, scrollbarPosition, int_4);
+        renderScrollBar(matrices, tessellator, buffer, maxScroll, scrollbarPosition, int_4);
         
-        this.renderDecorations(mouseX, mouseY);
+        this.renderDecorations(matrices, mouseX, mouseY);
         RenderSystem.enableTexture();
         RenderSystem.shadeModel(7424);
         RenderSystem.enableAlphaTest();
@@ -225,7 +230,7 @@ public abstract class DynamicEntryListWidget<E extends DynamicEntryListWidget.En
     }
     
     @SuppressWarnings("deprecation")
-    protected void renderScrollBar(Tessellator tessellator, BufferBuilder buffer, int maxScroll, int scrollbarPositionMinX, int scrollbarPositionMaxX) {
+    protected void renderScrollBar(MatrixStack matrices, Tessellator tessellator, BufferBuilder buffer, int maxScroll, int scrollbarPositionMinX, int scrollbarPositionMaxX) {
         if (maxScroll > 0) {
             int int_9 = ((this.bottom - this.top) * (this.bottom - this.top)) / this.getMaxScrollPosition();
             int_9 = MathHelper.clamp(int_9, 32, this.bottom - this.top - 8);
@@ -234,23 +239,24 @@ public abstract class DynamicEntryListWidget<E extends DynamicEntryListWidget.En
                 int_10 = this.top;
             }
             
+            Matrix4f matrix = matrices.peek().getModel();
             buffer.begin(7, VertexFormats.POSITION_TEXTURE_COLOR);
-            buffer.vertex(scrollbarPositionMinX, this.bottom, 0.0D).texture(0, 1).color(0, 0, 0, 255).next();
-            buffer.vertex(scrollbarPositionMaxX, this.bottom, 0.0D).texture(1, 1).color(0, 0, 0, 255).next();
-            buffer.vertex(scrollbarPositionMaxX, this.top, 0.0D).texture(1, 0).color(0, 0, 0, 255).next();
-            buffer.vertex(scrollbarPositionMinX, this.top, 0.0D).texture(0, 0).color(0, 0, 0, 255).next();
+            buffer.vertex(matrix, scrollbarPositionMinX, this.bottom, 0.0F).texture(0, 1).color(0, 0, 0, 255).next();
+            buffer.vertex(matrix, scrollbarPositionMaxX, this.bottom, 0.0F).texture(1, 1).color(0, 0, 0, 255).next();
+            buffer.vertex(matrix, scrollbarPositionMaxX, this.top, 0.0F).texture(1, 0).color(0, 0, 0, 255).next();
+            buffer.vertex(matrix, scrollbarPositionMinX, this.top, 0.0F).texture(0, 0).color(0, 0, 0, 255).next();
             tessellator.draw();
             buffer.begin(7, VertexFormats.POSITION_TEXTURE_COLOR);
-            buffer.vertex(scrollbarPositionMinX, int_10 + int_9, 0.0D).texture(0, 1).color(128, 128, 128, 255).next();
-            buffer.vertex(scrollbarPositionMaxX, int_10 + int_9, 0.0D).texture(1, 1).color(128, 128, 128, 255).next();
-            buffer.vertex(scrollbarPositionMaxX, int_10, 0.0D).texture(1, 0).color(128, 128, 128, 255).next();
-            buffer.vertex(scrollbarPositionMinX, int_10, 0.0D).texture(0, 0).color(128, 128, 128, 255).next();
+            buffer.vertex(matrix, scrollbarPositionMinX, int_10 + int_9, 0.0F).texture(0, 1).color(128, 128, 128, 255).next();
+            buffer.vertex(matrix, scrollbarPositionMaxX, int_10 + int_9, 0.0F).texture(1, 1).color(128, 128, 128, 255).next();
+            buffer.vertex(matrix, scrollbarPositionMaxX, int_10, 0.0F).texture(1, 0).color(128, 128, 128, 255).next();
+            buffer.vertex(matrix, scrollbarPositionMinX, int_10, 0.0F).texture(0, 0).color(128, 128, 128, 255).next();
             tessellator.draw();
             buffer.begin(7, VertexFormats.POSITION_TEXTURE_COLOR);
-            buffer.vertex(scrollbarPositionMinX, (int_10 + int_9 - 1), 0.0D).texture(0, 1).color(192, 192, 192, 255).next();
-            buffer.vertex((scrollbarPositionMaxX - 1), (int_10 + int_9 - 1), 0.0D).texture(1, 1).color(192, 192, 192, 255).next();
-            buffer.vertex((scrollbarPositionMaxX - 1), int_10, 0.0D).texture(1, 0).color(192, 192, 192, 255).next();
-            buffer.vertex(scrollbarPositionMinX, int_10, 0.0D).texture(0, 0).color(192, 192, 192, 255).next();
+            buffer.vertex(scrollbarPositionMinX, (int_10 + int_9 - 1), 0.0F).texture(0, 1).color(192, 192, 192, 255).next();
+            buffer.vertex((scrollbarPositionMaxX - 1), (int_10 + int_9 - 1), 0.0F).texture(1, 1).color(192, 192, 192, 255).next();
+            buffer.vertex((scrollbarPositionMaxX - 1), int_10, 0.0F).texture(1, 0).color(192, 192, 192, 255).next();
+            buffer.vertex(scrollbarPositionMinX, int_10, 0.0F).texture(0, 0).color(192, 192, 192, 255).next();
             tessellator.draw();
         }
     }
@@ -282,7 +288,7 @@ public abstract class DynamicEntryListWidget<E extends DynamicEntryListWidget.En
     }
     
     public void capYPosition(double double_1) {
-        this.scroll = MathHelper.clamp(double_1, 0.0D, this.getMaxScroll());
+        this.scroll = MathHelper.clamp(double_1, 0.0F, this.getMaxScroll());
     }
     
     protected int getMaxScroll() {
@@ -335,7 +341,7 @@ public abstract class DynamicEntryListWidget<E extends DynamicEntryListWidget.En
             return true;
         } else if (int_1 == 0 && this.scrolling) {
             if (double_2 < (double) this.top) {
-                this.capYPosition(0.0D);
+                this.capYPosition(0.0F);
             } else if (double_2 > (double) this.bottom) {
                 this.capYPosition(this.getMaxScroll());
             } else {
@@ -391,7 +397,7 @@ public abstract class DynamicEntryListWidget<E extends DynamicEntryListWidget.En
         return double_2 >= (double) this.top && double_2 <= (double) this.bottom && double_1 >= (double) this.left && double_1 <= (double) this.right;
     }
     
-    protected void renderList(int startX, int startY, int int_3, int int_4, float float_1) {
+    protected void renderList(MatrixStack matrices, int startX, int startY, int int_3, int int_4, float float_1) {
         int itemCount = this.getItemCount();
         Tessellator tessellator = Tessellator.getInstance();
         BufferBuilder buffer = tessellator.getBuffer();
@@ -409,19 +415,19 @@ public abstract class DynamicEntryListWidget<E extends DynamicEntryListWidget.En
                 itemMaxX = itemMinX + itemWidth;
                 RenderSystem.disableTexture();
                 float float_2 = this.isFocused() ? 1.0F : 0.5F;
-                RenderSystem.color4f(float_2, float_2, float_2, 1.0F);
-                buffer.begin(7, VertexFormats.POSITION);
-                buffer.vertex(itemMinX, itemY + itemHeight + 2, 0.0D).next();
-                buffer.vertex(itemMaxX, itemY + itemHeight + 2, 0.0D).next();
-                buffer.vertex(itemMaxX, itemY - 2, 0.0D).next();
-                buffer.vertex(itemMinX, itemY - 2, 0.0D).next();
+                Matrix4f matrix = matrices.peek().getModel();
+                RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
+                buffer.begin(7, VertexFormats.POSITION_COLOR);
+                buffer.vertex(matrix, itemMinX, itemY + itemHeight + 2, 0.0F).color(float_2, float_2, float_2, 1.0F).next();
+                buffer.vertex(matrix, itemMaxX, itemY + itemHeight + 2, 0.0F).color(float_2, float_2, float_2, 1.0F).next();
+                buffer.vertex(matrix, itemMaxX, itemY - 2, 0.0F).color(float_2, float_2, float_2, 1.0F).next();
+                buffer.vertex(matrix, itemMinX, itemY - 2, 0.0F).color(float_2, float_2, float_2, 1.0F).next();
                 tessellator.draw();
-                RenderSystem.color4f(0.0F, 0.0F, 0.0F, 1.0F);
-                buffer.begin(7, VertexFormats.POSITION);
-                buffer.vertex(itemMinX + 1, itemY + itemHeight + 1, 0.0D).next();
-                buffer.vertex(itemMaxX - 1, itemY + itemHeight + 1, 0.0D).next();
-                buffer.vertex(itemMaxX - 1, itemY - 1, 0.0D).next();
-                buffer.vertex(itemMinX + 1, itemY - 1, 0.0D).next();
+                buffer.begin(7, VertexFormats.POSITION_COLOR);
+                buffer.vertex(matrix, itemMinX + 1, itemY + itemHeight + 1, 0.0F).color(0.0F, 0.0F, 0.0F, 1.0F).next();
+                buffer.vertex(matrix, itemMaxX - 1, itemY + itemHeight + 1, 0.0F).color(0.0F, 0.0F, 0.0F, 1.0F).next();
+                buffer.vertex(matrix, itemMaxX - 1, itemY - 1, 0.0F).color(0.0F, 0.0F, 0.0F, 1.0F).next();
+                buffer.vertex(matrix, itemMinX + 1, itemY - 1, 0.0F).color(0.0F, 0.0F, 0.0F, 1.0F).next();
                 tessellator.draw();
                 RenderSystem.enableTexture();
             }
@@ -429,13 +435,13 @@ public abstract class DynamicEntryListWidget<E extends DynamicEntryListWidget.En
             int y = this.getRowTop(renderIndex);
             int x = this.getRowLeft();
             DiffuseLighting.disable();
-            renderItem(item, renderIndex, y, x, itemWidth, itemHeight, int_3, int_4, this.isMouseOver(int_3, int_4) && Objects.equals(this.getItemAtPosition(int_3, int_4), item), float_1);
+            renderItem(matrices, item, renderIndex, y, x, itemWidth, itemHeight, int_3, int_4, this.isMouseOver(int_3, int_4) && Objects.equals(this.getItemAtPosition(int_3, int_4), item), float_1);
         }
         
     }
     
-    protected void renderItem(E item, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
-        item.render(index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta);
+    protected void renderItem(MatrixStack matrices, E item, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
+        item.render(matrices, index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta);
     }
     
     protected int getRowLeft() {
@@ -454,17 +460,18 @@ public abstract class DynamicEntryListWidget<E extends DynamicEntryListWidget.En
     }
     
     @SuppressWarnings("deprecation")
-    protected void renderHoleBackground(int int_1, int int_2, int int_3, int int_4) {
+    protected void renderHoleBackground(MatrixStack matrices, int int_1, int int_2, int int_3, int int_4) {
         Tessellator tessellator = Tessellator.getInstance();
         BufferBuilder buffer = tessellator.getBuffer();
         this.client.getTextureManager().bindTexture(backgroundLocation);
+        Matrix4f matrix = matrices.peek().getModel();
         RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
         float float_1 = 32.0F;
         buffer.begin(7, VertexFormats.POSITION_TEXTURE_COLOR);
-        buffer.vertex(this.left, int_2, 0.0D).texture(0, ((float) int_2 / 32.0F)).color(64, 64, 64, int_4).next();
-        buffer.vertex(this.left + this.width, int_2, 0.0D).texture(((float) this.width / 32.0F), ((float) int_2 / 32.0F)).color(64, 64, 64, int_4).next();
-        buffer.vertex(this.left + this.width, int_1, 0.0D).texture(((float) this.width / 32.0F), ((float) int_1 / 32.0F)).color(64, 64, 64, int_3).next();
-        buffer.vertex(this.left, int_1, 0.0D).texture(0, ((float) int_1 / 32.0F)).color(64, 64, 64, int_3).next();
+        buffer.vertex(matrix, this.left, int_2, 0.0F).texture(0, ((float) int_2 / 32.0F)).color(64, 64, 64, int_4).next();
+        buffer.vertex(matrix, this.left + this.width, int_2, 0.0F).texture(((float) this.width / 32.0F), ((float) int_2 / 32.0F)).color(64, 64, 64, int_4).next();
+        buffer.vertex(matrix, this.left + this.width, int_1, 0.0F).texture(((float) this.width / 32.0F), ((float) int_1 / 32.0F)).color(64, 64, 64, int_3).next();
+        buffer.vertex(matrix, this.left, int_1, 0.0F).texture(0, ((float) int_1 / 32.0F)).color(64, 64, 64, int_3).next();
         tessellator.draw();
     }
     
@@ -495,7 +502,7 @@ public abstract class DynamicEntryListWidget<E extends DynamicEntryListWidget.En
         public Entry() {
         }
         
-        public abstract void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isHovered, float delta);
+        public abstract void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isHovered, float delta);
         
         public boolean isMouseOver(double double_1, double double_2) {
             return Objects.equals(this.parent.getItemAtPosition(double_1, double_2), this);

+ 19 - 16
src/main/java/me/shedaniel/clothconfig2/gui/widget/DynamicNewSmoothScrollingEntryListWidget.java

@@ -9,8 +9,10 @@ import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.render.BufferBuilder;
 import net.minecraft.client.render.Tessellator;
 import net.minecraft.client.render.VertexFormats;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.math.MathHelper;
+import net.minecraft.util.math.Matrix4f;
 
 import static me.shedaniel.clothconfig2.ClothConfigInitializer.clamp;
 import static me.shedaniel.clothconfig2.ClothConfigInitializer.handleScrollingPosition;
@@ -103,18 +105,18 @@ public abstract class DynamicNewSmoothScrollingEntryListWidget<E extends Dynamic
     }
     
     @Override
-    public void render(int mouseX, int mouseY, float delta) {
+    public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
         double[] target = {this.target};
         scroll = handleScrollingPosition(target, scroll, getMaxScroll(), delta, start, duration);
         this.target = target[0];
-        super.render(mouseX, mouseY, delta);
+        super.render(matrices, mouseX, mouseY, delta);
     }
     
     @SuppressWarnings("deprecation")
     @Override
-    protected void renderScrollBar(Tessellator tessellator, BufferBuilder buffer, int maxScroll, int scrollbarPositionMinX, int scrollbarPositionMaxX) {
+    protected void renderScrollBar(MatrixStack matrices, Tessellator tessellator, BufferBuilder buffer, int maxScroll, int scrollbarPositionMinX, int scrollbarPositionMaxX) {
         if (!smoothScrolling)
-            super.renderScrollBar(tessellator, buffer, maxScroll, scrollbarPositionMinX, scrollbarPositionMaxX);
+            super.renderScrollBar(matrices, tessellator, buffer, maxScroll, scrollbarPositionMinX, scrollbarPositionMaxX);
         else if (maxScroll > 0) {
             int height = ((this.bottom - this.top) * (this.bottom - this.top)) / this.getMaxScrollPosition();
             height = MathHelper.clamp(height, 32, this.bottom - this.top - 8);
@@ -125,28 +127,29 @@ public abstract class DynamicNewSmoothScrollingEntryListWidget<E extends Dynamic
             int bottomc = new Rectangle(scrollbarPositionMinX, minY, scrollbarPositionMaxX - scrollbarPositionMinX, height).contains(PointHelper.ofMouse()) ? 168 : 128;
             int topc = new Rectangle(scrollbarPositionMinX, minY, scrollbarPositionMaxX - scrollbarPositionMinX, height).contains(PointHelper.ofMouse()) ? 222 : 172;
             
+            Matrix4f matrix = matrices.peek().getModel();
             // Black Bar
             buffer.begin(7, VertexFormats.POSITION_TEXTURE_COLOR);
-            buffer.vertex(scrollbarPositionMinX, this.bottom, 0.0D).texture(0, 1).color(0, 0, 0, 255).next();
-            buffer.vertex(scrollbarPositionMaxX, this.bottom, 0.0D).texture(1, 1).color(0, 0, 0, 255).next();
-            buffer.vertex(scrollbarPositionMaxX, this.top, 0.0D).texture(1, 0).color(0, 0, 0, 255).next();
-            buffer.vertex(scrollbarPositionMinX, this.top, 0.0D).texture(0, 0).color(0, 0, 0, 255).next();
+            buffer.vertex(matrix, scrollbarPositionMinX, this.bottom, 0.0F).texture(0, 1).color(0, 0, 0, 255).next();
+            buffer.vertex(matrix, scrollbarPositionMaxX, this.bottom, 0.0F).texture(1, 1).color(0, 0, 0, 255).next();
+            buffer.vertex(matrix, scrollbarPositionMaxX, this.top, 0.0F).texture(1, 0).color(0, 0, 0, 255).next();
+            buffer.vertex(matrix, scrollbarPositionMinX, this.top, 0.0F).texture(0, 0).color(0, 0, 0, 255).next();
             tessellator.draw();
             
             // Bottom
             buffer.begin(7, VertexFormats.POSITION_TEXTURE_COLOR);
-            buffer.vertex(scrollbarPositionMinX, minY + height, 0.0D).texture(0, 1).color(bottomc, bottomc, bottomc, 255).next();
-            buffer.vertex(scrollbarPositionMaxX, minY + height, 0.0D).texture(1, 1).color(bottomc, bottomc, bottomc, 255).next();
-            buffer.vertex(scrollbarPositionMaxX, minY, 0.0D).texture(1, 0).color(bottomc, bottomc, bottomc, 255).next();
-            buffer.vertex(scrollbarPositionMinX, minY, 0.0D).texture(0, 0).color(bottomc, bottomc, bottomc, 255).next();
+            buffer.vertex(matrix, scrollbarPositionMinX, minY + height, 0.0F).texture(0, 1).color(bottomc, bottomc, bottomc, 255).next();
+            buffer.vertex(matrix, scrollbarPositionMaxX, minY + height, 0.0F).texture(1, 1).color(bottomc, bottomc, bottomc, 255).next();
+            buffer.vertex(matrix, scrollbarPositionMaxX, minY, 0.0F).texture(1, 0).color(bottomc, bottomc, bottomc, 255).next();
+            buffer.vertex(matrix, scrollbarPositionMinX, minY, 0.0F).texture(0, 0).color(bottomc, bottomc, bottomc, 255).next();
             tessellator.draw();
             
             // Top
             buffer.begin(7, VertexFormats.POSITION_TEXTURE_COLOR);
-            buffer.vertex(scrollbarPositionMinX, (minY + height - 1), 0.0D).texture(0, 1).color(topc, topc, topc, 255).next();
-            buffer.vertex((scrollbarPositionMaxX - 1), (minY + height - 1), 0.0D).texture(1, 1).color(topc, topc, topc, 255).next();
-            buffer.vertex((scrollbarPositionMaxX - 1), minY, 0.0D).texture(1, 0).color(topc, topc, topc, 255).next();
-            buffer.vertex(scrollbarPositionMinX, minY, 0.0D).texture(0, 0).color(topc, topc, topc, 255).next();
+            buffer.vertex(matrix, scrollbarPositionMinX, (minY + height - 1), 0.0F).texture(0, 1).color(topc, topc, topc, 255).next();
+            buffer.vertex(matrix, (scrollbarPositionMaxX - 1), (minY + height - 1), 0.0F).texture(1, 1).color(topc, topc, topc, 255).next();
+            buffer.vertex(matrix, (scrollbarPositionMaxX - 1), minY, 0.0F).texture(1, 0).color(topc, topc, topc, 255).next();
+            buffer.vertex(matrix, scrollbarPositionMinX, minY, 0.0F).texture(0, 0).color(topc, topc, topc, 255).next();
             tessellator.draw();
         }
     }

+ 13 - 10
src/main/java/me/shedaniel/clothconfig2/gui/widget/DynamicSmoothScrollingEntryListWidget.java

@@ -7,8 +7,10 @@ import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.render.BufferBuilder;
 import net.minecraft.client.render.Tessellator;
 import net.minecraft.client.render.VertexFormats;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.math.MathHelper;
+import net.minecraft.util.math.Matrix4f;
 
 @Deprecated
 @Environment(EnvType.CLIENT)
@@ -126,10 +128,11 @@ public abstract class DynamicSmoothScrollingEntryListWidget<E extends DynamicEnt
     }
     
     @Override
-    protected void renderScrollBar(Tessellator tessellator, BufferBuilder buffer, int maxScroll, int scrollbarPositionMinX, int scrollbarPositionMaxX) {
+    protected void renderScrollBar(MatrixStack matrices, Tessellator tessellator, BufferBuilder buffer, int maxScroll, int scrollbarPositionMinX, int scrollbarPositionMaxX) {
         if (!smoothScrolling)
-            super.renderScrollBar(tessellator, buffer, maxScroll, scrollbarPositionMinX, scrollbarPositionMaxX);
+            super.renderScrollBar(matrices, tessellator, buffer, maxScroll, scrollbarPositionMinX, scrollbarPositionMaxX);
         else if (maxScroll > 0) {
+            Matrix4f matrix = matrices.peek().getModel();
             int height = ((this.bottom - this.top) * (this.bottom - this.top)) / this.getMaxScrollPosition();
             height = MathHelper.clamp(height, 32, this.bottom - this.top - 8);
             height -= Math.min((scroll < 0 ? (int) -scroll : scroll > getMaxScroll() ? (int) scroll - getMaxScroll() : 0), height * .75);
@@ -137,18 +140,18 @@ public abstract class DynamicSmoothScrollingEntryListWidget<E extends DynamicEnt
             
             // Black Bar
             buffer.begin(7, VertexFormats.POSITION_TEXTURE_COLOR);
-            buffer.vertex(scrollbarPositionMinX, this.bottom, 0.0D).texture(0, 1).color(0, 0, 0, 255).next();
-            buffer.vertex(scrollbarPositionMaxX, this.bottom, 0.0D).texture(1, 1).color(0, 0, 0, 255).next();
-            buffer.vertex(scrollbarPositionMaxX, this.top, 0.0D).texture(1, 0).color(0, 0, 0, 255).next();
-            buffer.vertex(scrollbarPositionMinX, this.top, 0.0D).texture(0, 0).color(0, 0, 0, 255).next();
+            buffer.vertex(matrix, scrollbarPositionMinX, this.bottom, 0.0F).texture(0, 1).color(0, 0, 0, 255).next();
+            buffer.vertex(matrix, scrollbarPositionMaxX, this.bottom, 0.0F).texture(1, 1).color(0, 0, 0, 255).next();
+            buffer.vertex(matrix, scrollbarPositionMaxX, this.top, 0.0F).texture(1, 0).color(0, 0, 0, 255).next();
+            buffer.vertex(matrix, scrollbarPositionMinX, this.top, 0.0F).texture(0, 0).color(0, 0, 0, 255).next();
             tessellator.draw();
             
             // Top
             buffer.begin(7, VertexFormats.POSITION_TEXTURE_COLOR);
-            buffer.vertex(scrollbarPositionMinX, minY + height, 0.0D).texture(0, 1).color(128, 128, 128, 255).next();
-            buffer.vertex(scrollbarPositionMaxX, minY + height, 0.0D).texture(1, 1).color(128, 128, 128, 255).next();
-            buffer.vertex(scrollbarPositionMaxX, minY, 0.0D).texture(1, 0).color(128, 128, 128, 255).next();
-            buffer.vertex(scrollbarPositionMinX, minY, 0.0D).texture(0, 0).color(128, 128, 128, 255).next();
+            buffer.vertex(matrix, scrollbarPositionMinX, minY + height, 0.0F).texture(0, 1).color(128, 128, 128, 255).next();
+            buffer.vertex(matrix, scrollbarPositionMaxX, minY + height, 0.0F).texture(1, 1).color(128, 128, 128, 255).next();
+            buffer.vertex(matrix, scrollbarPositionMaxX, minY, 0.0F).texture(1, 0).color(128, 128, 128, 255).next();
+            buffer.vertex(matrix, scrollbarPositionMinX, minY, 0.0F).texture(0, 0).color(128, 128, 128, 255).next();
             tessellator.draw();
             
             // Bottom

+ 14 - 12
src/main/java/me/shedaniel/clothconfig2/impl/ConfigBuilderImpl.java

@@ -10,6 +10,8 @@ import net.fabricmc.api.Environment;
 import net.minecraft.client.gui.DrawableHelper;
 import net.minecraft.client.gui.screen.Screen;
 import net.minecraft.client.resource.language.I18n;
+import net.minecraft.text.Text;
+import net.minecraft.text.TranslatableText;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.Pair;
 
@@ -24,7 +26,7 @@ public class ConfigBuilderImpl implements ConfigBuilder {
     
     private Runnable savingRunnable;
     private Screen parent;
-    private String title = "text.cloth-config.config";
+    private Text title = new TranslatableText("text.cloth-config.config");
     private boolean editable = true;
     private boolean tabsSmoothScroll = true;
     private boolean listSmoothScroll = true;
@@ -33,14 +35,14 @@ public class ConfigBuilderImpl implements ConfigBuilder {
     private boolean transparentBackground = false;
     private Identifier defaultBackground = DrawableHelper.BACKGROUND_TEXTURE;
     private Consumer<Screen> afterInitConsumer = screen -> {};
-    private final Map<String, Identifier> categoryBackground = Maps.newHashMap();
-    private final Map<String, List<Pair<String, Object>>> dataMap = Maps.newLinkedHashMap();
-    private String fallbackCategory = null;
+    private final Map<Text, Identifier> categoryBackground = Maps.newHashMap();
+    private final Map<Text, List<Pair<Text, Object>>> dataMap = Maps.newLinkedHashMap();
+    private Text fallbackCategory = null;
     private boolean alwaysShowTabs = false;
     
     @Deprecated
     public ConfigBuilderImpl() {
-    
+        
     }
     
     @Override
@@ -84,12 +86,12 @@ public class ConfigBuilderImpl implements ConfigBuilder {
     }
     
     @Override
-    public String getTitle() {
+    public Text getTitle() {
         return title;
     }
     
     @Override
-    public ConfigBuilder setTitle(String title) {
+    public ConfigBuilder setTitle(Text title) {
         this.title = title;
         return this;
     }
@@ -106,7 +108,7 @@ public class ConfigBuilderImpl implements ConfigBuilder {
     }
     
     @Override
-    public ConfigCategory getOrCreateCategory(String categoryKey) {
+    public ConfigCategory getOrCreateCategory(Text categoryKey) {
         if (dataMap.containsKey(categoryKey))
             return new ConfigCategoryImpl(categoryKey, identifier -> {
                 if (transparentBackground)
@@ -124,7 +126,7 @@ public class ConfigBuilderImpl implements ConfigBuilder {
     }
     
     @Override
-    public ConfigBuilder removeCategory(String category) {
+    public ConfigBuilder removeCategory(Text category) {
         if (dataMap.containsKey(category) && fallbackCategory.equals(category))
             fallbackCategory = null;
         if (!dataMap.containsKey(category))
@@ -134,7 +136,7 @@ public class ConfigBuilderImpl implements ConfigBuilder {
     }
     
     @Override
-    public ConfigBuilder removeCategoryIfExists(String category) {
+    public ConfigBuilder removeCategoryIfExists(Text category) {
         if (dataMap.containsKey(category) && fallbackCategory.equals(category))
             fallbackCategory = null;
         dataMap.remove(category);
@@ -142,7 +144,7 @@ public class ConfigBuilderImpl implements ConfigBuilder {
     }
     
     @Override
-    public boolean hasCategory(String category) {
+    public boolean hasCategory(Text category) {
         return dataMap.containsKey(category);
     }
     
@@ -216,7 +218,7 @@ public class ConfigBuilderImpl implements ConfigBuilder {
     public Screen build() {
         if (dataMap.isEmpty() || fallbackCategory == null)
             throw new NullPointerException("There cannot be no categories or fallback category!");
-        ClothConfigScreen screen = new ClothConfigScreen(parent, I18n.translate(title), dataMap, doesConfirmSave, doesProcessErrors, listSmoothScroll, defaultBackground, categoryBackground) {
+        ClothConfigScreen screen = new ClothConfigScreen(parent, title, dataMap, doesConfirmSave, doesProcessErrors, listSmoothScroll, defaultBackground, categoryBackground) {
             @Override
             public void save() {
                 if (savingRunnable != null)

+ 5 - 4
src/main/java/me/shedaniel/clothconfig2/impl/ConfigCategoryImpl.java

@@ -4,6 +4,7 @@ import me.shedaniel.clothconfig2.api.AbstractConfigListEntry;
 import me.shedaniel.clothconfig2.api.ConfigCategory;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
+import net.minecraft.text.Text;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.Pair;
 
@@ -15,12 +16,12 @@ import java.util.stream.Collectors;
 @Environment(EnvType.CLIENT)
 public class ConfigCategoryImpl implements ConfigCategory {
     
-    private final Supplier<List<Pair<String, Object>>> listSupplier;
+    private final Supplier<List<Pair<Text, Object>>> listSupplier;
     private final Consumer<Identifier> backgroundConsumer;
     private final Runnable destroyCategory;
-    private final String categoryKey;
+    private final Text categoryKey;
     
-    ConfigCategoryImpl(String categoryKey, Consumer<Identifier> backgroundConsumer, Supplier<List<Pair<String, Object>>> listSupplier, Runnable destroyCategory) {
+    ConfigCategoryImpl(Text categoryKey, Consumer<Identifier> backgroundConsumer, Supplier<List<Pair<Text, Object>>> listSupplier, Runnable destroyCategory) {
         this.listSupplier = listSupplier;
         this.backgroundConsumer = backgroundConsumer;
         this.categoryKey = categoryKey;
@@ -28,7 +29,7 @@ public class ConfigCategoryImpl implements ConfigCategory {
     }
     
     @Override
-    public String getCategoryKey() {
+    public Text getCategoryKey() {
         return categoryKey;
     }
     

+ 31 - 28
src/main/java/me/shedaniel/clothconfig2/impl/ConfigEntryBuilderImpl.java

@@ -8,6 +8,9 @@ import me.shedaniel.clothconfig2.gui.entries.DropdownBoxEntry.SelectionTopCellEl
 import me.shedaniel.clothconfig2.impl.builders.*;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
+import net.minecraft.text.LiteralText;
+import net.minecraft.text.Text;
+import net.minecraft.text.TranslatableText;
 
 import java.util.List;
 import java.util.UUID;
@@ -15,7 +18,7 @@ import java.util.UUID;
 @Environment(EnvType.CLIENT)
 public class ConfigEntryBuilderImpl implements ConfigEntryBuilder {
     
-    private String resetButtonKey = "text.cloth-config.reset_value";
+    private Text resetButtonKey = new TranslatableText("text.cloth-config.reset_value");
     
     private ConfigEntryBuilderImpl() {
     }
@@ -27,132 +30,132 @@ public class ConfigEntryBuilderImpl implements ConfigEntryBuilder {
     public static ConfigEntryBuilderImpl createImmutable() {
         return new ConfigEntryBuilderImpl() {
             @Override
-            public ConfigEntryBuilder setResetButtonKey(String resetButtonKey) {
+            public ConfigEntryBuilder setResetButtonKey(Text resetButtonKey) {
                 throw new UnsupportedOperationException("This is an immutable entry builder!");
             }
         };
     }
     
     @Override
-    public String getResetButtonKey() {
+    public Text getResetButtonKey() {
         return resetButtonKey;
     }
     
     @Override
-    public ConfigEntryBuilder setResetButtonKey(String resetButtonKey) {
+    public ConfigEntryBuilder setResetButtonKey(Text resetButtonKey) {
         this.resetButtonKey = resetButtonKey;
         return this;
     }
     
     @Override
-    public IntListBuilder startIntList(String fieldNameKey, List<Integer> value) {
+    public IntListBuilder startIntList(Text fieldNameKey, List<Integer> value) {
         return new IntListBuilder(resetButtonKey, fieldNameKey, value);
     }
     
     @Override
-    public LongListBuilder startLongList(String fieldNameKey, List<Long> value) {
+    public LongListBuilder startLongList(Text fieldNameKey, List<Long> value) {
         return new LongListBuilder(resetButtonKey, fieldNameKey, value);
     }
     
     @Override
-    public FloatListBuilder startFloatList(String fieldNameKey, List<Float> value) {
+    public FloatListBuilder startFloatList(Text fieldNameKey, List<Float> value) {
         return new FloatListBuilder(resetButtonKey, fieldNameKey, value);
     }
     
     @Override
-    public DoubleListBuilder startDoubleList(String fieldNameKey, List<Double> value) {
+    public DoubleListBuilder startDoubleList(Text fieldNameKey, List<Double> value) {
         return new DoubleListBuilder(resetButtonKey, fieldNameKey, value);
     }
     
     @Override
-    public StringListBuilder startStrList(String fieldNameKey, List<String> value) {
+    public StringListBuilder startStrList(Text fieldNameKey, List<String> value) {
         return new StringListBuilder(resetButtonKey, fieldNameKey, value);
     }
     
     @Override
-    public SubCategoryBuilder startSubCategory(String fieldNameKey) {
+    public SubCategoryBuilder startSubCategory(Text fieldNameKey) {
         return new SubCategoryBuilder(resetButtonKey, fieldNameKey);
     }
     
     @Override
-    public SubCategoryBuilder startSubCategory(String fieldNameKey, List<AbstractConfigListEntry> entries) {
+    public SubCategoryBuilder startSubCategory(Text fieldNameKey, List<AbstractConfigListEntry> entries) {
         SubCategoryBuilder builder = new SubCategoryBuilder(resetButtonKey, fieldNameKey);
         builder.addAll(entries);
         return builder;
     }
     
     @Override
-    public BooleanToggleBuilder startBooleanToggle(String fieldNameKey, boolean value) {
+    public BooleanToggleBuilder startBooleanToggle(Text fieldNameKey, boolean value) {
         return new BooleanToggleBuilder(resetButtonKey, fieldNameKey, value);
     }
     
     @Override
-    public StringFieldBuilder startStrField(String fieldNameKey, String value) {
+    public StringFieldBuilder startStrField(Text fieldNameKey, String value) {
         return new StringFieldBuilder(resetButtonKey, fieldNameKey, value);
     }
-
+    
     @Override
-    public ColorFieldBuilder startColorField(String fieldNameKey, int value) {
+    public ColorFieldBuilder startColorField(Text fieldNameKey, int value) {
         return new ColorFieldBuilder(resetButtonKey, fieldNameKey, value);
     }
     
     @Override
-    public TextFieldBuilder startTextField(String fieldNameKey, String value) {
+    public TextFieldBuilder startTextField(Text fieldNameKey, String value) {
         return new TextFieldBuilder(resetButtonKey, fieldNameKey, value);
     }
     
     @Override
-    public TextDescriptionBuilder startTextDescription(String value) {
-        return new TextDescriptionBuilder(resetButtonKey, UUID.randomUUID().toString(), value);
+    public TextDescriptionBuilder startTextDescription(Text value) {
+        return new TextDescriptionBuilder(resetButtonKey, new LiteralText(UUID.randomUUID().toString()), value);
     }
     
     @Override
-    public <T extends Enum<?>> EnumSelectorBuilder<T> startEnumSelector(String fieldNameKey, Class<T> clazz, T value) {
+    public <T extends Enum<?>> EnumSelectorBuilder<T> startEnumSelector(Text fieldNameKey, Class<T> clazz, T value) {
         return new EnumSelectorBuilder<>(resetButtonKey, fieldNameKey, clazz, value);
     }
     
     @Override
-    public <T> SelectorBuilder<T> startSelector(String fieldNameKey, T[] valuesArray, T value) {
+    public <T> SelectorBuilder<T> startSelector(Text fieldNameKey, T[] valuesArray, T value) {
         return new SelectorBuilder<>(resetButtonKey, fieldNameKey, valuesArray, value);
     }
     
     @Override
-    public IntFieldBuilder startIntField(String fieldNameKey, int value) {
+    public IntFieldBuilder startIntField(Text fieldNameKey, int value) {
         return new IntFieldBuilder(resetButtonKey, fieldNameKey, value);
     }
     
     @Override
-    public LongFieldBuilder startLongField(String fieldNameKey, long value) {
+    public LongFieldBuilder startLongField(Text fieldNameKey, long value) {
         return new LongFieldBuilder(resetButtonKey, fieldNameKey, value);
     }
     
     @Override
-    public FloatFieldBuilder startFloatField(String fieldNameKey, float value) {
+    public FloatFieldBuilder startFloatField(Text fieldNameKey, float value) {
         return new FloatFieldBuilder(resetButtonKey, fieldNameKey, value);
     }
     
     @Override
-    public DoubleFieldBuilder startDoubleField(String fieldNameKey, double value) {
+    public DoubleFieldBuilder startDoubleField(Text fieldNameKey, double value) {
         return new DoubleFieldBuilder(resetButtonKey, fieldNameKey, value);
     }
     
     @Override
-    public IntSliderBuilder startIntSlider(String fieldNameKey, int value, int min, int max) {
+    public IntSliderBuilder startIntSlider(Text fieldNameKey, int value, int min, int max) {
         return new IntSliderBuilder(resetButtonKey, fieldNameKey, value, min, max);
     }
     
     @Override
-    public LongSliderBuilder startLongSlider(String fieldNameKey, long value, long min, long max) {
+    public LongSliderBuilder startLongSlider(Text fieldNameKey, long value, long min, long max) {
         return new LongSliderBuilder(resetButtonKey, fieldNameKey, value, min, max);
     }
     
     @Override
-    public KeyCodeBuilder startModifierKeyCodeField(String fieldNameKey, ModifierKeyCode value) {
+    public KeyCodeBuilder startModifierKeyCodeField(Text fieldNameKey, ModifierKeyCode value) {
         return new KeyCodeBuilder(resetButtonKey, fieldNameKey, value);
     }
     
     @Override
-    public <T> DropdownMenuBuilder<T> startDropdownMenu(String fieldNameKey, SelectionTopCellElement<T> topCellElement, SelectionCellCreator<T> cellCreator) {
+    public <T> DropdownMenuBuilder<T> startDropdownMenu(Text fieldNameKey, SelectionTopCellElement<T> topCellElement, SelectionCellCreator<T> cellCreator) {
         return new DropdownMenuBuilder<>(resetButtonKey, fieldNameKey, topCellElement, cellCreator);
     }
     

+ 3 - 2
src/main/java/me/shedaniel/clothconfig2/impl/FakeKeyBindings.java

@@ -6,6 +6,7 @@ import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
 import net.minecraft.client.options.KeyBinding;
 import net.minecraft.client.util.InputUtil;
+import net.minecraft.text.Text;
 
 import java.util.UUID;
 import java.util.function.Consumer;
@@ -59,7 +60,7 @@ public class FakeKeyBindings extends KeyBinding {
     }
     
     @Override
-    public String getLocalizedName() {
+    public Text getLocalizedName() {
         return keyCode.getLocalizedName();
     }
     
@@ -70,7 +71,7 @@ public class FakeKeyBindings extends KeyBinding {
     
     @Override
     public String getName() {
-        return keyCode.getLocalizedName();
+        return keyCode.getLocalizedName().getString();
     }
     
     @Override

+ 11 - 21
src/main/java/me/shedaniel/clothconfig2/impl/ModifierKeyCodeImpl.java

@@ -4,10 +4,9 @@ import me.shedaniel.clothconfig2.api.Modifier;
 import me.shedaniel.clothconfig2.api.ModifierKeyCode;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
-import net.minecraft.client.resource.language.I18n;
 import net.minecraft.client.util.InputUtil;
-
-import java.util.Objects;
+import net.minecraft.text.Text;
+import net.minecraft.text.TranslatableText;
 
 @Environment(EnvType.CLIENT)
 public class ModifierKeyCodeImpl implements ModifierKeyCode {
@@ -43,27 +42,18 @@ public class ModifierKeyCodeImpl implements ModifierKeyCode {
     
     @Override
     public String toString() {
-        String string_1 = this.keyCode.getName();
-        int int_1 = this.keyCode.getKeyCode();
-        String string_2 = null;
-        switch (this.keyCode.getCategory()) {
-            case KEYSYM:
-                string_2 = InputUtil.getKeycodeName(int_1);
-                break;
-            case SCANCODE:
-                string_2 = InputUtil.getScancodeName(int_1);
-                break;
-            case MOUSE:
-                String string_3 = I18n.translate(string_1);
-                string_2 = Objects.equals(string_3, string_1) ? I18n.translate(InputUtil.Type.MOUSE.getName(), int_1 + 1) : string_3;
-        }
-        String base = string_2 == null ? I18n.translate(string_1) : string_2;
+        return getLocalizedName().getString();
+    }
+    
+    @Override
+    public Text getLocalizedName() {
+        Text base = this.keyCode.method_27445();
         if (modifier.hasShift())
-            base = I18n.translate("modifier.cloth-config.shift", base);
+            base = new TranslatableText("modifier.cloth-config.shift", base);
         if (modifier.hasControl())
-            base = I18n.translate("modifier.cloth-config.ctrl", base);
+            base = new TranslatableText("modifier.cloth-config.ctrl", base);
         if (modifier.hasAlt())
-            base = I18n.translate("modifier.cloth-config.alt", base);
+            base = new TranslatableText("modifier.cloth-config.alt", base);
         return base;
     }
     

+ 2 - 0
src/main/java/me/shedaniel/clothconfig2/impl/ScissorsHandlerImpl.java

@@ -10,6 +10,7 @@ import net.fabricmc.api.Environment;
 import net.fabricmc.loader.api.FabricLoader;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.util.Window;
+import net.minecraft.util.math.MathHelper;
 import org.lwjgl.opengl.GL11;
 
 import java.util.Collections;
@@ -73,6 +74,7 @@ public final class ScissorsHandlerImpl implements ScissorsHandler {
             for (int i = 1; i < scissorsAreas.size(); i++) {
                 r.setBounds(r.intersection(scissorsAreas.get(i)));
             }
+            r.setBounds(Math.min(r.x, r.x + r.width), Math.min(r.y, r.y + r.height), Math.abs(r.width), Math.abs(r.height));
             Window window = MinecraftClient.getInstance().getWindow();
             double scaleFactor = window.getScaleFactor();
             GL11.glEnable(GL11.GL_SCISSOR_TEST);

+ 12 - 11
src/main/java/me/shedaniel/clothconfig2/impl/builders/BooleanToggleBuilder.java

@@ -3,6 +3,7 @@ package me.shedaniel.clothconfig2.impl.builders;
 import me.shedaniel.clothconfig2.gui.entries.BooleanListEntry;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
+import net.minecraft.text.Text;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -15,16 +16,16 @@ import java.util.function.Supplier;
 public class BooleanToggleBuilder extends FieldBuilder<Boolean, BooleanListEntry> {
     
     @Nullable private Consumer<Boolean> saveConsumer = null;
-    @NotNull private Function<Boolean, Optional<String[]>> tooltipSupplier = bool -> Optional.empty();
+    @NotNull private Function<Boolean, Optional<Text[]>> tooltipSupplier = bool -> Optional.empty();
     private final boolean value;
-    @Nullable private Function<Boolean, String> yesNoTextSupplier = null;
+    @Nullable private Function<Boolean, Text> yesNoTextSupplier = null;
     
-    public BooleanToggleBuilder(String resetButtonKey, String fieldNameKey, boolean value) {
+    public BooleanToggleBuilder(Text resetButtonKey, Text fieldNameKey, boolean value) {
         super(resetButtonKey, fieldNameKey);
         this.value = value;
     }
     
-    public BooleanToggleBuilder setErrorSupplier(@Nullable Function<Boolean, Optional<String>> errorSupplier) {
+    public BooleanToggleBuilder setErrorSupplier(@Nullable Function<Boolean, Optional<Text>> errorSupplier) {
         this.errorSupplier = errorSupplier;
         return this;
     }
@@ -49,32 +50,32 @@ public class BooleanToggleBuilder extends FieldBuilder<Boolean, BooleanListEntry
         return this;
     }
     
-    public BooleanToggleBuilder setTooltipSupplier(@NotNull Function<Boolean, Optional<String[]>> tooltipSupplier) {
+    public BooleanToggleBuilder setTooltipSupplier(@NotNull Function<Boolean, Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = tooltipSupplier;
         return this;
     }
     
-    public BooleanToggleBuilder setTooltipSupplier(@NotNull Supplier<Optional<String[]>> tooltipSupplier) {
+    public BooleanToggleBuilder setTooltipSupplier(@NotNull Supplier<Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = bool -> tooltipSupplier.get();
         return this;
     }
     
-    public BooleanToggleBuilder setTooltip(Optional<String[]> tooltip) {
+    public BooleanToggleBuilder setTooltip(Optional<Text[]> tooltip) {
         this.tooltipSupplier = bool -> tooltip;
         return this;
     }
     
-    public BooleanToggleBuilder setTooltip(@Nullable String... tooltip) {
+    public BooleanToggleBuilder setTooltip(@Nullable Text... tooltip) {
         this.tooltipSupplier = bool -> Optional.ofNullable(tooltip);
         return this;
     }
     
     @Nullable
-    public Function<Boolean, String> getYesNoTextSupplier() {
+    public Function<Boolean, Text> getYesNoTextSupplier() {
         return yesNoTextSupplier;
     }
     
-    public BooleanToggleBuilder setYesNoTextSupplier(@Nullable Function<Boolean, String> yesNoTextSupplier) {
+    public BooleanToggleBuilder setYesNoTextSupplier(@Nullable Function<Boolean, Text> yesNoTextSupplier) {
         this.yesNoTextSupplier = yesNoTextSupplier;
         return this;
     }
@@ -84,7 +85,7 @@ public class BooleanToggleBuilder extends FieldBuilder<Boolean, BooleanListEntry
     public BooleanListEntry build() {
         BooleanListEntry entry = new BooleanListEntry(getFieldNameKey(), value, getResetButtonKey(), defaultValue, saveConsumer, null, isRequireRestart()) {
             @Override
-            public String getYesNoText(boolean bool) {
+            public Text getYesNoText(boolean bool) {
                 if (yesNoTextSupplier == null)
                     return super.getYesNoText(bool);
                 return yesNoTextSupplier.apply(bool);

+ 37 - 9
src/main/java/me/shedaniel/clothconfig2/impl/builders/ColorFieldBuilder.java

@@ -1,8 +1,11 @@
 package me.shedaniel.clothconfig2.impl.builders;
 
 import me.shedaniel.clothconfig2.gui.entries.ColorEntry;
+import me.shedaniel.math.Color;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
+import net.minecraft.class_5251;
+import net.minecraft.text.Text;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.Objects;
@@ -15,18 +18,18 @@ import java.util.function.Supplier;
 public class ColorFieldBuilder extends FieldBuilder<String, ColorEntry> {
     
     private Consumer<Integer> saveConsumer = null;
-    private Function<Integer, Optional<String>> errorSupplier;
-    private Function<Integer, Optional<String[]>> tooltipSupplier = str -> Optional.empty();
+    private Function<Integer, Optional<Text>> errorSupplier;
+    private Function<Integer, Optional<Text[]>> tooltipSupplier = str -> Optional.empty();
     private final int value;
     private Supplier<Integer> defaultValue;
     private boolean alpha = false;
     
-    public ColorFieldBuilder(String resetButtonKey, String fieldNameKey, int value) {
+    public ColorFieldBuilder(Text resetButtonKey, Text fieldNameKey, int value) {
         super(resetButtonKey, fieldNameKey);
         this.value = value;
     }
     
-    public ColorFieldBuilder setErrorSupplier(Function<Integer, Optional<String>> errorSupplier) {
+    public ColorFieldBuilder setErrorSupplier(Function<Integer, Optional<Text>> errorSupplier) {
         this.errorSupplier = errorSupplier;
         return this;
     }
@@ -41,37 +44,62 @@ public class ColorFieldBuilder extends FieldBuilder<String, ColorEntry> {
         return this;
     }
     
+    public ColorFieldBuilder setSaveConsumer2(Consumer<Color> saveConsumer) {
+        this.saveConsumer = integer -> saveConsumer.accept(alpha ? Color.ofTransparent(integer) : Color.ofOpaque(integer));
+        return this;
+    }
+    
+    public ColorFieldBuilder setSaveConsumer3(Consumer<class_5251> saveConsumer) {
+        this.saveConsumer = integer -> saveConsumer.accept(class_5251.method_27717(integer));
+        return this;
+    }
+    
     public ColorFieldBuilder setDefaultValue(Supplier<Integer> defaultValue) {
         this.defaultValue = defaultValue;
         return this;
     }
     
+    public ColorFieldBuilder setDefaultValue2(Supplier<Color> defaultValue) {
+        this.defaultValue = () -> defaultValue.get().getColor();
+        return this;
+    }
+    
+    public ColorFieldBuilder setDefaultValue3(Supplier<class_5251> defaultValue) {
+        this.defaultValue = () -> defaultValue.get().method_27716();
+        return this;
+    }
+    
     public ColorFieldBuilder setAlphaMode(boolean withAlpha) {
         this.alpha = withAlpha;
         return this;
     }
     
     public ColorFieldBuilder setDefaultValue(int defaultValue) {
-        this.defaultValue = () -> Objects.requireNonNull(defaultValue);
+        this.defaultValue = () -> defaultValue;
+        return this;
+    }
+    
+    public ColorFieldBuilder setDefaultValue(class_5251 defaultValue) {
+        this.defaultValue = () -> Objects.requireNonNull(defaultValue).method_27716();
         return this;
     }
     
-    public ColorFieldBuilder setTooltipSupplier(Supplier<Optional<String[]>> tooltipSupplier) {
+    public ColorFieldBuilder setTooltipSupplier(Supplier<Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = str -> tooltipSupplier.get();
         return this;
     }
     
-    public ColorFieldBuilder setTooltipSupplier(Function<Integer, Optional<String[]>> tooltipSupplier) {
+    public ColorFieldBuilder setTooltipSupplier(Function<Integer, Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = tooltipSupplier;
         return this;
     }
     
-    public ColorFieldBuilder setTooltip(Optional<String[]> tooltip) {
+    public ColorFieldBuilder setTooltip(Optional<Text[]> tooltip) {
         this.tooltipSupplier = str -> tooltip;
         return this;
     }
     
-    public ColorFieldBuilder setTooltip(String... tooltip) {
+    public ColorFieldBuilder setTooltip(Text... tooltip) {
         this.tooltipSupplier = str -> Optional.ofNullable(tooltip);
         return this;
     }

+ 8 - 7
src/main/java/me/shedaniel/clothconfig2/impl/builders/DoubleFieldBuilder.java

@@ -3,6 +3,7 @@ package me.shedaniel.clothconfig2.impl.builders;
 import me.shedaniel.clothconfig2.gui.entries.DoubleListEntry;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
+import net.minecraft.text.Text;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.Optional;
@@ -14,16 +15,16 @@ import java.util.function.Supplier;
 public class DoubleFieldBuilder extends FieldBuilder<Double, DoubleListEntry> {
     
     private Consumer<Double> saveConsumer = null;
-    private Function<Double, Optional<String[]>> tooltipSupplier = d -> Optional.empty();
+    private Function<Double, Optional<Text[]>> tooltipSupplier = d -> Optional.empty();
     private final double value;
     private Double min = null, max = null;
     
-    public DoubleFieldBuilder(String resetButtonKey, String fieldNameKey, double value) {
+    public DoubleFieldBuilder(Text resetButtonKey, Text fieldNameKey, double value) {
         super(resetButtonKey, fieldNameKey);
         this.value = value;
     }
     
-    public DoubleFieldBuilder setErrorSupplier(Function<Double, Optional<String>> errorSupplier) {
+    public DoubleFieldBuilder setErrorSupplier(Function<Double, Optional<Text>> errorSupplier) {
         this.errorSupplier = errorSupplier;
         return this;
     }
@@ -68,22 +69,22 @@ public class DoubleFieldBuilder extends FieldBuilder<Double, DoubleListEntry> {
         return this;
     }
     
-    public DoubleFieldBuilder setTooltipSupplier(Function<Double, Optional<String[]>> tooltipSupplier) {
+    public DoubleFieldBuilder setTooltipSupplier(Function<Double, Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = tooltipSupplier;
         return this;
     }
     
-    public DoubleFieldBuilder setTooltipSupplier(Supplier<Optional<String[]>> tooltipSupplier) {
+    public DoubleFieldBuilder setTooltipSupplier(Supplier<Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = d -> tooltipSupplier.get();
         return this;
     }
     
-    public DoubleFieldBuilder setTooltip(Optional<String[]> tooltip) {
+    public DoubleFieldBuilder setTooltip(Optional<Text[]> tooltip) {
         this.tooltipSupplier = d -> tooltip;
         return this;
     }
     
-    public DoubleFieldBuilder setTooltip(String... tooltip) {
+    public DoubleFieldBuilder setTooltip(Text... tooltip) {
         this.tooltipSupplier = d -> Optional.ofNullable(tooltip);
         return this;
     }

+ 15 - 13
src/main/java/me/shedaniel/clothconfig2/impl/builders/DoubleListBuilder.java

@@ -4,6 +4,8 @@ import me.shedaniel.clothconfig2.gui.entries.DoubleListListEntry;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
 import net.minecraft.client.resource.language.I18n;
+import net.minecraft.text.Text;
+import net.minecraft.text.TranslatableText;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.NotNull;
 
@@ -16,31 +18,31 @@ import java.util.function.Supplier;
 @Environment(EnvType.CLIENT)
 public class DoubleListBuilder extends FieldBuilder<List<Double>, DoubleListListEntry> {
     
-    protected Function<Double, Optional<String>> cellErrorSupplier;
+    protected Function<Double, Optional<Text>> cellErrorSupplier;
     private Consumer<List<Double>> saveConsumer = null;
-    private Function<List<Double>, Optional<String[]>> tooltipSupplier = list -> Optional.empty();
+    private Function<List<Double>, Optional<Text[]>> tooltipSupplier = list -> Optional.empty();
     private final List<Double> value;
     private boolean expanded = false;
     private Double min = null, max = null;
     private Function<DoubleListListEntry, DoubleListListEntry.DoubleListCell> createNewInstance;
-    private String addTooltip = I18n.translate("text.cloth-config.list.add"), removeTooltip = I18n.translate("text.cloth-config.list.remove");
+    private Text addTooltip = new TranslatableText("text.cloth-config.list.add"), removeTooltip = new TranslatableText("text.cloth-config.list.remove");
     private boolean deleteButtonEnabled = true, insertInFront = true;
     
-    public DoubleListBuilder(String resetButtonKey, String fieldNameKey, List<Double> value) {
+    public DoubleListBuilder(Text resetButtonKey, Text fieldNameKey, List<Double> value) {
         super(resetButtonKey, fieldNameKey);
         this.value = value;
     }
     
-    public Function<Double, Optional<String>> getCellErrorSupplier() {
+    public Function<Double, Optional<Text>> getCellErrorSupplier() {
         return cellErrorSupplier;
     }
     
-    public DoubleListBuilder setCellErrorSupplier(Function<Double, Optional<String>> cellErrorSupplier) {
+    public DoubleListBuilder setCellErrorSupplier(Function<Double, Optional<Text>> cellErrorSupplier) {
         this.cellErrorSupplier = cellErrorSupplier;
         return this;
     }
     
-    public DoubleListBuilder setErrorSupplier(Function<List<Double>, Optional<String>> errorSupplier) {
+    public DoubleListBuilder setErrorSupplier(Function<List<Double>, Optional<Text>> errorSupplier) {
         this.errorSupplier = errorSupplier;
         return this;
     }
@@ -55,12 +57,12 @@ public class DoubleListBuilder extends FieldBuilder<List<Double>, DoubleListList
         return this;
     }
     
-    public DoubleListBuilder setAddButtonTooltip(String addTooltip) {
+    public DoubleListBuilder setAddButtonTooltip(Text addTooltip) {
         this.addTooltip = addTooltip;
         return this;
     }
     
-    public DoubleListBuilder setRemoveButtonTooltip(String removeTooltip) {
+    public DoubleListBuilder setRemoveButtonTooltip(Text removeTooltip) {
         this.removeTooltip = removeTooltip;
         return this;
     }
@@ -121,22 +123,22 @@ public class DoubleListBuilder extends FieldBuilder<List<Double>, DoubleListList
         return this;
     }
     
-    public DoubleListBuilder setTooltipSupplier(Function<List<Double>, Optional<String[]>> tooltipSupplier) {
+    public DoubleListBuilder setTooltipSupplier(Function<List<Double>, Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = tooltipSupplier;
         return this;
     }
     
-    public DoubleListBuilder setTooltipSupplier(Supplier<Optional<String[]>> tooltipSupplier) {
+    public DoubleListBuilder setTooltipSupplier(Supplier<Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = list -> tooltipSupplier.get();
         return this;
     }
     
-    public DoubleListBuilder setTooltip(Optional<String[]> tooltip) {
+    public DoubleListBuilder setTooltip(Optional<Text[]> tooltip) {
         this.tooltipSupplier = list -> tooltip;
         return this;
     }
     
-    public DoubleListBuilder setTooltip(String... tooltip) {
+    public DoubleListBuilder setTooltip(Text... tooltip) {
         this.tooltipSupplier = list -> Optional.ofNullable(tooltip);
         return this;
     }

+ 53 - 50
src/main/java/me/shedaniel/clothconfig2/impl/builders/DropdownMenuBuilder.java

@@ -10,9 +10,12 @@ import net.fabricmc.api.Environment;
 import net.minecraft.block.Block;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.render.item.ItemRenderer;
+import net.minecraft.client.util.math.MatrixStack;
 import net.minecraft.item.Item;
 import net.minecraft.item.ItemStack;
 import net.minecraft.item.Items;
+import net.minecraft.text.LiteralText;
+import net.minecraft.text.Text;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.registry.Registry;
 import org.jetbrains.annotations.NotNull;
@@ -28,11 +31,11 @@ import java.util.function.Supplier;
 public class DropdownMenuBuilder<T> extends FieldBuilder<T, DropdownBoxEntry<T>> {
     protected SelectionTopCellElement<T> topCellElement;
     protected SelectionCellCreator<T> cellCreator;
-    protected Function<T, Optional<String[]>> tooltipSupplier = str -> Optional.empty();
+    protected Function<T, Optional<Text[]>> tooltipSupplier = str -> Optional.empty();
     protected Consumer<T> saveConsumer = null;
     protected Iterable<T> selections = Collections.emptyList();
     
-    public DropdownMenuBuilder(String resetButtonKey, String fieldNameKey, SelectionTopCellElement<T> topCellElement, SelectionCellCreator<T> cellCreator) {
+    public DropdownMenuBuilder(Text resetButtonKey, Text fieldNameKey, SelectionTopCellElement<T> topCellElement, SelectionCellCreator<T> cellCreator) {
         super(resetButtonKey, fieldNameKey);
         this.topCellElement = Objects.requireNonNull(topCellElement);
         this.cellCreator = Objects.requireNonNull(cellCreator);
@@ -58,22 +61,22 @@ public class DropdownMenuBuilder<T> extends FieldBuilder<T, DropdownBoxEntry<T>>
         return this;
     }
     
-    public DropdownMenuBuilder<T> setTooltipSupplier(Supplier<Optional<String[]>> tooltipSupplier) {
+    public DropdownMenuBuilder<T> setTooltipSupplier(Supplier<Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = str -> tooltipSupplier.get();
         return this;
     }
     
-    public DropdownMenuBuilder<T> setTooltipSupplier(Function<T, Optional<String[]>> tooltipSupplier) {
+    public DropdownMenuBuilder<T> setTooltipSupplier(Function<T, Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = tooltipSupplier;
         return this;
     }
     
-    public DropdownMenuBuilder<T> setTooltip(Optional<String[]> tooltip) {
+    public DropdownMenuBuilder<T> setTooltip(Optional<Text[]> tooltip) {
         this.tooltipSupplier = str -> tooltip;
         return this;
     }
     
-    public DropdownMenuBuilder<T> setTooltip(String... tooltip) {
+    public DropdownMenuBuilder<T> setTooltip(Text... tooltip) {
         this.tooltipSupplier = str -> Optional.ofNullable(tooltip);
         return this;
     }
@@ -83,7 +86,7 @@ public class DropdownMenuBuilder<T> extends FieldBuilder<T, DropdownBoxEntry<T>>
         return this;
     }
     
-    public DropdownMenuBuilder<T> setErrorSupplier(Function<T, Optional<String>> errorSupplier) {
+    public DropdownMenuBuilder<T> setErrorSupplier(Function<T, Optional<Text>> errorSupplier) {
         this.errorSupplier = errorSupplier;
         return this;
     }
@@ -141,23 +144,23 @@ public class DropdownMenuBuilder<T> extends FieldBuilder<T, DropdownBoxEntry<T>>
         private static final ItemStack BARRIER = new ItemStack(Items.BARRIER);
         
         public static <T> SelectionTopCellElement<T> of(T value, Function<String, T> toObjectFunction) {
-            return of(value, toObjectFunction, Object::toString);
+            return of(value, toObjectFunction, t -> new LiteralText(t.toString()));
         }
         
-        public static <T> SelectionTopCellElement<T> of(T value, Function<String, T> toObjectFunction, Function<T, String> toStringFunction) {
-            return new DefaultSelectionTopCellElement<>(value, toObjectFunction, toStringFunction);
+        public static <T> SelectionTopCellElement<T> of(T value, Function<String, T> toObjectFunction, Function<T, Text> toTextFunction) {
+            return new DefaultSelectionTopCellElement<>(value, toObjectFunction, toTextFunction);
         }
         
         public static SelectionTopCellElement<Identifier> ofItemIdentifier(Item item) {
-            return new DefaultSelectionTopCellElement<Identifier>(Registry.ITEM.getId(item), ITEM_IDENTIFIER_FUNCTION, Identifier::toString) {
+            return new DefaultSelectionTopCellElement<Identifier>(Registry.ITEM.getId(item), ITEM_IDENTIFIER_FUNCTION, identifier -> new LiteralText(identifier.toString())) {
                 @Override
-                public void render(int mouseX, int mouseY, int x, int y, int width, int height, float delta) {
+                public void render(MatrixStack matrices, int mouseX, int mouseY, int x, int y, int width, int height, float delta) {
                     textFieldWidget.x = x + 4;
                     textFieldWidget.y = y + 6;
                     textFieldWidget.setWidth(width - 4 - 20);
                     textFieldWidget.setEditable(getParent().isEditable());
                     textFieldWidget.setEditableColor(getPreferredTextColor());
-                    textFieldWidget.render(mouseX, mouseY, delta);
+                    textFieldWidget.render(matrices, mouseX, mouseY, delta);
                     ItemRenderer itemRenderer = MinecraftClient.getInstance().getItemRenderer();
                     ItemStack stack = hasConfigError() ? BARRIER : new ItemStack(Registry.ITEM.get(getValue()));
                     itemRenderer.renderGuiItemIcon(stack, x + width - 18, y + 2);
@@ -166,15 +169,15 @@ public class DropdownMenuBuilder<T> extends FieldBuilder<T, DropdownBoxEntry<T>>
         }
         
         public static SelectionTopCellElement<Identifier> ofBlockIdentifier(Block block) {
-            return new DefaultSelectionTopCellElement<Identifier>(Registry.BLOCK.getId(block), BLOCK_IDENTIFIER_FUNCTION, Identifier::toString) {
+            return new DefaultSelectionTopCellElement<Identifier>(Registry.BLOCK.getId(block), BLOCK_IDENTIFIER_FUNCTION, identifier -> new LiteralText(identifier.toString())) {
                 @Override
-                public void render(int mouseX, int mouseY, int x, int y, int width, int height, float delta) {
+                public void render(MatrixStack matrices, int mouseX, int mouseY, int x, int y, int width, int height, float delta) {
                     textFieldWidget.x = x + 4;
                     textFieldWidget.y = y + 6;
                     textFieldWidget.setWidth(width - 4 - 20);
                     textFieldWidget.setEditable(getParent().isEditable());
                     textFieldWidget.setEditableColor(getPreferredTextColor());
-                    textFieldWidget.render(mouseX, mouseY, delta);
+                    textFieldWidget.render(matrices, mouseX, mouseY, delta);
                     ItemRenderer itemRenderer = MinecraftClient.getInstance().getItemRenderer();
                     ItemStack stack = hasConfigError() ? BARRIER : new ItemStack(Registry.BLOCK.get(getValue()));
                     itemRenderer.renderGuiItemIcon(stack, x + width - 18, y + 2);
@@ -183,15 +186,15 @@ public class DropdownMenuBuilder<T> extends FieldBuilder<T, DropdownBoxEntry<T>>
         }
         
         public static SelectionTopCellElement<Item> ofItemObject(Item item) {
-            return new DefaultSelectionTopCellElement<Item>(item, ITEM_FUNCTION, i -> Registry.ITEM.getId(i).toString()) {
+            return new DefaultSelectionTopCellElement<Item>(item, ITEM_FUNCTION, i -> new LiteralText(Registry.ITEM.getId(i).toString())) {
                 @Override
-                public void render(int mouseX, int mouseY, int x, int y, int width, int height, float delta) {
+                public void render(MatrixStack matrices, int mouseX, int mouseY, int x, int y, int width, int height, float delta) {
                     textFieldWidget.x = x + 4;
                     textFieldWidget.y = y + 6;
                     textFieldWidget.setWidth(width - 4 - 20);
                     textFieldWidget.setEditable(getParent().isEditable());
                     textFieldWidget.setEditableColor(getPreferredTextColor());
-                    textFieldWidget.render(mouseX, mouseY, delta);
+                    textFieldWidget.render(matrices, mouseX, mouseY, delta);
                     ItemRenderer itemRenderer = MinecraftClient.getInstance().getItemRenderer();
                     ItemStack stack = hasConfigError() ? BARRIER : new ItemStack(getValue());
                     itemRenderer.renderGuiItemIcon(stack, x + width - 18, y + 2);
@@ -200,15 +203,15 @@ public class DropdownMenuBuilder<T> extends FieldBuilder<T, DropdownBoxEntry<T>>
         }
         
         public static SelectionTopCellElement<Block> ofBlockObject(Block block) {
-            return new DefaultSelectionTopCellElement<Block>(block, BLOCK_FUNCTION, i -> Registry.BLOCK.getId(i).toString()) {
+            return new DefaultSelectionTopCellElement<Block>(block, BLOCK_FUNCTION, i -> new LiteralText(Registry.BLOCK.getId(i).toString())) {
                 @Override
-                public void render(int mouseX, int mouseY, int x, int y, int width, int height, float delta) {
+                public void render(MatrixStack matrices, int mouseX, int mouseY, int x, int y, int width, int height, float delta) {
                     textFieldWidget.x = x + 4;
                     textFieldWidget.y = y + 6;
                     textFieldWidget.setWidth(width - 4 - 20);
                     textFieldWidget.setEditable(getParent().isEditable());
                     textFieldWidget.setEditableColor(getPreferredTextColor());
-                    textFieldWidget.render(mouseX, mouseY, delta);
+                    textFieldWidget.render(matrices, mouseX, mouseY, delta);
                     ItemRenderer itemRenderer = MinecraftClient.getInstance().getItemRenderer();
                     ItemStack stack = hasConfigError() ? BARRIER : new ItemStack(getValue());
                     itemRenderer.renderGuiItemIcon(stack, x + width - 18, y + 2);
@@ -222,8 +225,8 @@ public class DropdownMenuBuilder<T> extends FieldBuilder<T, DropdownBoxEntry<T>>
             return new DefaultSelectionCellCreator<>();
         }
         
-        public static <T> SelectionCellCreator<T> of(Function<T, String> toStringFunction) {
-            return new DefaultSelectionCellCreator<>(toStringFunction);
+        public static <T> SelectionCellCreator<T> of(Function<T, Text> toTextFunction) {
+            return new DefaultSelectionCellCreator<>(toTextFunction);
         }
         
         public static <T> SelectionCellCreator<T> ofWidth(int cellWidth) {
@@ -235,8 +238,8 @@ public class DropdownMenuBuilder<T> extends FieldBuilder<T, DropdownBoxEntry<T>>
             };
         }
         
-        public static <T> SelectionCellCreator<T> ofWidth(int cellWidth, Function<T, String> toStringFunction) {
-            return new DefaultSelectionCellCreator<T>(toStringFunction) {
+        public static <T> SelectionCellCreator<T> ofWidth(int cellWidth, Function<T, Text> toTextFunction) {
+            return new DefaultSelectionCellCreator<T>(toTextFunction) {
                 @Override
                 public int getCellWidth() {
                     return cellWidth;
@@ -253,8 +256,8 @@ public class DropdownMenuBuilder<T> extends FieldBuilder<T, DropdownBoxEntry<T>>
             };
         }
         
-        public static <T> SelectionCellCreator<T> ofCellCount(int maxItems, Function<T, String> toStringFunction) {
-            return new DefaultSelectionCellCreator<T>(toStringFunction) {
+        public static <T> SelectionCellCreator<T> ofCellCount(int maxItems, Function<T, Text> toTextFunction) {
+            return new DefaultSelectionCellCreator<T>(toTextFunction) {
                 @Override
                 public int getDropBoxMaxHeight() {
                     return getCellHeight() * maxItems;
@@ -276,8 +279,8 @@ public class DropdownMenuBuilder<T> extends FieldBuilder<T, DropdownBoxEntry<T>>
             };
         }
         
-        public static <T> SelectionCellCreator<T> of(int cellWidth, int maxItems, Function<T, String> toStringFunction) {
-            return new DefaultSelectionCellCreator<T>(toStringFunction) {
+        public static <T> SelectionCellCreator<T> of(int cellWidth, int maxItems, Function<T, Text> toTextFunction) {
+            return new DefaultSelectionCellCreator<T>(toTextFunction) {
                 @Override
                 public int getCellWidth() {
                     return cellWidth;
@@ -309,8 +312,8 @@ public class DropdownMenuBuilder<T> extends FieldBuilder<T, DropdownBoxEntry<T>>
             };
         }
         
-        public static <T> SelectionCellCreator<T> of(int cellHeight, int cellWidth, int maxItems, Function<T, String> toStringFunction) {
-            return new DefaultSelectionCellCreator<T>(toStringFunction) {
+        public static <T> SelectionCellCreator<T> of(int cellHeight, int cellWidth, int maxItems, Function<T, Text> toTextFunction) {
+            return new DefaultSelectionCellCreator<T>(toTextFunction) {
                 @Override
                 public int getCellHeight() {
                     return cellHeight;
@@ -341,9 +344,9 @@ public class DropdownMenuBuilder<T> extends FieldBuilder<T, DropdownBoxEntry<T>>
                 @Override
                 public DropdownBoxEntry.SelectionCellElement<Identifier> create(Identifier selection) {
                     ItemStack s = new ItemStack(Registry.ITEM.get(selection));
-                    return new DropdownBoxEntry.DefaultSelectionCellElement<Identifier>(selection, toStringFunction) {
+                    return new DropdownBoxEntry.DefaultSelectionCellElement<Identifier>(selection, toTextFunction) {
                         @Override
-                        public void render(int mouseX, int mouseY, int x, int y, int width, int height, float delta) {
+                        public void render(MatrixStack matrices, int mouseX, int mouseY, int x, int y, int width, int height, float delta) {
                             rendering = true;
                             this.x = x;
                             this.y = y;
@@ -351,8 +354,8 @@ public class DropdownMenuBuilder<T> extends FieldBuilder<T, DropdownBoxEntry<T>>
                             this.height = height;
                             boolean b = mouseX >= x && mouseX <= x + width && mouseY >= y && mouseY <= y + height;
                             if (b)
-                                fill(x + 1, y + 1, x + width - 1, y + height - 1, -15132391);
-                            MinecraftClient.getInstance().textRenderer.drawWithShadow(toStringFunction.apply(r), x + 6 + 18, y + 6, b ? 16777215 : 8947848);
+                                fill(matrices, x + 1, y + 1, x + width - 1, y + height - 1, -15132391);
+                            MinecraftClient.getInstance().textRenderer.method_27517(matrices, toTextFunction.apply(r), x + 6 + 18, y + 6, b ? 16777215 : 8947848);
                             ItemRenderer itemRenderer = MinecraftClient.getInstance().getItemRenderer();
                             itemRenderer.renderGuiItemIcon(s, x + 4, y + 2);
                         }
@@ -390,9 +393,9 @@ public class DropdownMenuBuilder<T> extends FieldBuilder<T, DropdownBoxEntry<T>>
                 @Override
                 public DropdownBoxEntry.SelectionCellElement<Identifier> create(Identifier selection) {
                     ItemStack s = new ItemStack(Registry.BLOCK.get(selection));
-                    return new DropdownBoxEntry.DefaultSelectionCellElement<Identifier>(selection, toStringFunction) {
+                    return new DropdownBoxEntry.DefaultSelectionCellElement<Identifier>(selection, toTextFunction) {
                         @Override
-                        public void render(int mouseX, int mouseY, int x, int y, int width, int height, float delta) {
+                        public void render(MatrixStack matrices, int mouseX, int mouseY, int x, int y, int width, int height, float delta) {
                             rendering = true;
                             this.x = x;
                             this.y = y;
@@ -400,8 +403,8 @@ public class DropdownMenuBuilder<T> extends FieldBuilder<T, DropdownBoxEntry<T>>
                             this.height = height;
                             boolean b = mouseX >= x && mouseX <= x + width && mouseY >= y && mouseY <= y + height;
                             if (b)
-                                fill(x + 1, y + 1, x + width - 1, y + height - 1, -15132391);
-                            MinecraftClient.getInstance().textRenderer.drawWithShadow(toStringFunction.apply(r), x + 6 + 18, y + 6, b ? 16777215 : 8947848);
+                                fill(matrices, x + 1, y + 1, x + width - 1, y + height - 1, -15132391);
+                            MinecraftClient.getInstance().textRenderer.method_27517(matrices, toTextFunction.apply(r), x + 6 + 18, y + 6, b ? 16777215 : 8947848);
                             ItemRenderer itemRenderer = MinecraftClient.getInstance().getItemRenderer();
                             itemRenderer.renderGuiItemIcon(s, x + 4, y + 2);
                         }
@@ -434,13 +437,13 @@ public class DropdownMenuBuilder<T> extends FieldBuilder<T, DropdownBoxEntry<T>>
         }
         
         public static SelectionCellCreator<Item> ofItemObject(int cellHeight, int cellWidth, int maxItems) {
-            return new DefaultSelectionCellCreator<Item>(i -> Registry.ITEM.getId(i).toString()) {
+            return new DefaultSelectionCellCreator<Item>(i -> new LiteralText(Registry.ITEM.getId(i).toString())) {
                 @Override
                 public DropdownBoxEntry.SelectionCellElement<Item> create(Item selection) {
                     ItemStack s = new ItemStack(selection);
-                    return new DropdownBoxEntry.DefaultSelectionCellElement<Item>(selection, toStringFunction) {
+                    return new DropdownBoxEntry.DefaultSelectionCellElement<Item>(selection, toTextFunction) {
                         @Override
-                        public void render(int mouseX, int mouseY, int x, int y, int width, int height, float delta) {
+                        public void render(MatrixStack matrices, int mouseX, int mouseY, int x, int y, int width, int height, float delta) {
                             rendering = true;
                             this.x = x;
                             this.y = y;
@@ -448,8 +451,8 @@ public class DropdownMenuBuilder<T> extends FieldBuilder<T, DropdownBoxEntry<T>>
                             this.height = height;
                             boolean b = mouseX >= x && mouseX <= x + width && mouseY >= y && mouseY <= y + height;
                             if (b)
-                                fill(x + 1, y + 1, x + width - 1, y + height - 1, -15132391);
-                            MinecraftClient.getInstance().textRenderer.drawWithShadow(toStringFunction.apply(r), x + 6 + 18, y + 6, b ? 16777215 : 8947848);
+                                fill(matrices, x + 1, y + 1, x + width - 1, y + height - 1, -15132391);
+                            MinecraftClient.getInstance().textRenderer.method_27517(matrices, toTextFunction.apply(r), x + 6 + 18, y + 6, b ? 16777215 : 8947848);
                             ItemRenderer itemRenderer = MinecraftClient.getInstance().getItemRenderer();
                             itemRenderer.renderGuiItemIcon(s, x + 4, y + 2);
                         }
@@ -482,13 +485,13 @@ public class DropdownMenuBuilder<T> extends FieldBuilder<T, DropdownBoxEntry<T>>
         }
         
         public static SelectionCellCreator<Block> ofBlockObject(int cellHeight, int cellWidth, int maxItems) {
-            return new DefaultSelectionCellCreator<Block>(i -> Registry.BLOCK.getId(i).toString()) {
+            return new DefaultSelectionCellCreator<Block>(i -> new LiteralText(Registry.BLOCK.getId(i).toString())) {
                 @Override
                 public DropdownBoxEntry.SelectionCellElement<Block> create(Block selection) {
                     ItemStack s = new ItemStack(selection);
-                    return new DropdownBoxEntry.DefaultSelectionCellElement<Block>(selection, toStringFunction) {
+                    return new DropdownBoxEntry.DefaultSelectionCellElement<Block>(selection, toTextFunction) {
                         @Override
-                        public void render(int mouseX, int mouseY, int x, int y, int width, int height, float delta) {
+                        public void render(MatrixStack matrices, int mouseX, int mouseY, int x, int y, int width, int height, float delta) {
                             rendering = true;
                             this.x = x;
                             this.y = y;
@@ -496,8 +499,8 @@ public class DropdownMenuBuilder<T> extends FieldBuilder<T, DropdownBoxEntry<T>>
                             this.height = height;
                             boolean b = mouseX >= x && mouseX <= x + width && mouseY >= y && mouseY <= y + height;
                             if (b)
-                                fill(x + 1, y + 1, x + width - 1, y + height - 1, -15132391);
-                            MinecraftClient.getInstance().textRenderer.drawWithShadow(toStringFunction.apply(r), x + 6 + 18, y + 6, b ? 16777215 : 8947848);
+                                fill(matrices, x + 1, y + 1, x + width - 1, y + height - 1, -15132391);
+                            MinecraftClient.getInstance().textRenderer.method_27517(matrices, toTextFunction.apply(r), x + 6 + 18, y + 6, b ? 16777215 : 8947848);
                             ItemRenderer itemRenderer = MinecraftClient.getInstance().getItemRenderer();
                             itemRenderer.renderGuiItemIcon(s, x + 4, y + 2);
                         }

+ 10 - 9
src/main/java/me/shedaniel/clothconfig2/impl/builders/EnumSelectorBuilder.java

@@ -3,6 +3,7 @@ package me.shedaniel.clothconfig2.impl.builders;
 import me.shedaniel.clothconfig2.gui.entries.EnumListEntry;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
+import net.minecraft.text.Text;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.Objects;
@@ -15,12 +16,12 @@ import java.util.function.Supplier;
 public class EnumSelectorBuilder<T extends Enum<?>> extends FieldBuilder<T, EnumListEntry<T>> {
     
     private Consumer<T> saveConsumer = null;
-    private Function<T, Optional<String[]>> tooltipSupplier = e -> Optional.empty();
+    private Function<T, Optional<Text[]>> tooltipSupplier = e -> Optional.empty();
     private final T value;
     private final Class<T> clazz;
-    private Function<Enum, String> enumNameProvider = EnumListEntry.DEFAULT_NAME_PROVIDER;
+    private Function<Enum, Text> enumNameProvider = EnumListEntry.DEFAULT_NAME_PROVIDER;
     
-    public EnumSelectorBuilder(String resetButtonKey, String fieldNameKey, Class<T> clazz, T value) {
+    public EnumSelectorBuilder(Text resetButtonKey, Text fieldNameKey, Class<T> clazz, T value) {
         super(resetButtonKey, fieldNameKey);
         Objects.requireNonNull(clazz);
         Objects.requireNonNull(value);
@@ -28,7 +29,7 @@ public class EnumSelectorBuilder<T extends Enum<?>> extends FieldBuilder<T, Enum
         this.clazz = clazz;
     }
     
-    public EnumSelectorBuilder<T> setErrorSupplier(Function<T, Optional<String>> errorSupplier) {
+    public EnumSelectorBuilder<T> setErrorSupplier(Function<T, Optional<Text>> errorSupplier) {
         this.errorSupplier = errorSupplier;
         return this;
     }
@@ -54,27 +55,27 @@ public class EnumSelectorBuilder<T extends Enum<?>> extends FieldBuilder<T, Enum
         return this;
     }
     
-    public EnumSelectorBuilder<T> setTooltipSupplier(Function<T, Optional<String[]>> tooltipSupplier) {
+    public EnumSelectorBuilder<T> setTooltipSupplier(Function<T, Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = tooltipSupplier;
         return this;
     }
     
-    public EnumSelectorBuilder<T> setTooltipSupplier(Supplier<Optional<String[]>> tooltipSupplier) {
+    public EnumSelectorBuilder<T> setTooltipSupplier(Supplier<Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = e -> tooltipSupplier.get();
         return this;
     }
     
-    public EnumSelectorBuilder<T> setTooltip(Optional<String[]> tooltip) {
+    public EnumSelectorBuilder<T> setTooltip(Optional<Text[]> tooltip) {
         this.tooltipSupplier = e -> tooltip;
         return this;
     }
     
-    public EnumSelectorBuilder<T> setTooltip(String... tooltip) {
+    public EnumSelectorBuilder<T> setTooltip(Text... tooltip) {
         this.tooltipSupplier = e -> Optional.ofNullable(tooltip);
         return this;
     }
     
-    public EnumSelectorBuilder<T> setEnumNameProvider(Function<Enum, String> enumNameProvider) {
+    public EnumSelectorBuilder<T> setEnumNameProvider(Function<Enum, Text> enumNameProvider) {
         Objects.requireNonNull(enumNameProvider);
         this.enumNameProvider = enumNameProvider;
         return this;

+ 7 - 6
src/main/java/me/shedaniel/clothconfig2/impl/builders/FieldBuilder.java

@@ -3,6 +3,7 @@ package me.shedaniel.clothconfig2.impl.builders;
 import me.shedaniel.clothconfig2.api.AbstractConfigListEntry;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
+import net.minecraft.text.Text;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -13,13 +14,13 @@ import java.util.function.Supplier;
 
 @Environment(EnvType.CLIENT)
 public abstract class FieldBuilder<T, A extends AbstractConfigListEntry> {
-    @NotNull private final String fieldNameKey;
-    @NotNull private final String resetButtonKey;
+    @NotNull private final Text fieldNameKey;
+    @NotNull private final Text resetButtonKey;
     protected boolean requireRestart = false;
     @Nullable protected Supplier<T> defaultValue = null;
-    @Nullable protected Function<T, Optional<String>> errorSupplier;
+    @Nullable protected Function<T, Optional<Text>> errorSupplier;
     
-    protected FieldBuilder(String resetButtonKey, String fieldNameKey) {
+    protected FieldBuilder(Text resetButtonKey, Text fieldNameKey) {
         this.resetButtonKey = Objects.requireNonNull(resetButtonKey);
         this.fieldNameKey = Objects.requireNonNull(fieldNameKey);
     }
@@ -39,12 +40,12 @@ public abstract class FieldBuilder<T, A extends AbstractConfigListEntry> {
     public abstract A build();
     
     @NotNull
-    public final String getFieldNameKey() {
+    public final Text getFieldNameKey() {
         return fieldNameKey;
     }
     
     @NotNull
-    public final String getResetButtonKey() {
+    public final Text getResetButtonKey() {
         return resetButtonKey;
     }
     

+ 8 - 7
src/main/java/me/shedaniel/clothconfig2/impl/builders/FloatFieldBuilder.java

@@ -3,6 +3,7 @@ package me.shedaniel.clothconfig2.impl.builders;
 import me.shedaniel.clothconfig2.gui.entries.FloatListEntry;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
+import net.minecraft.text.Text;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.Optional;
@@ -14,16 +15,16 @@ import java.util.function.Supplier;
 public class FloatFieldBuilder extends FieldBuilder<Float, FloatListEntry> {
     
     private Consumer<Float> saveConsumer = null;
-    private Function<Float, Optional<String[]>> tooltipSupplier = f -> Optional.empty();
+    private Function<Float, Optional<Text[]>> tooltipSupplier = f -> Optional.empty();
     private final float value;
     private Float min = null, max = null;
     
-    public FloatFieldBuilder(String resetButtonKey, String fieldNameKey, float value) {
+    public FloatFieldBuilder(Text resetButtonKey, Text fieldNameKey, float value) {
         super(resetButtonKey, fieldNameKey);
         this.value = value;
     }
     
-    public FloatFieldBuilder setErrorSupplier(Function<Float, Optional<String>> errorSupplier) {
+    public FloatFieldBuilder setErrorSupplier(Function<Float, Optional<Text>> errorSupplier) {
         this.errorSupplier = errorSupplier;
         return this;
     }
@@ -48,22 +49,22 @@ public class FloatFieldBuilder extends FieldBuilder<Float, FloatListEntry> {
         return this;
     }
     
-    public FloatFieldBuilder setTooltipSupplier(Function<Float, Optional<String[]>> tooltipSupplier) {
+    public FloatFieldBuilder setTooltipSupplier(Function<Float, Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = tooltipSupplier;
         return this;
     }
     
-    public FloatFieldBuilder setTooltipSupplier(Supplier<Optional<String[]>> tooltipSupplier) {
+    public FloatFieldBuilder setTooltipSupplier(Supplier<Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = f -> tooltipSupplier.get();
         return this;
     }
     
-    public FloatFieldBuilder setTooltip(Optional<String[]> tooltip) {
+    public FloatFieldBuilder setTooltip(Optional<Text[]> tooltip) {
         this.tooltipSupplier = f -> tooltip;
         return this;
     }
     
-    public FloatFieldBuilder setTooltip(String... tooltip) {
+    public FloatFieldBuilder setTooltip(Text... tooltip) {
         this.tooltipSupplier = f -> Optional.ofNullable(tooltip);
         return this;
     }

+ 15 - 13
src/main/java/me/shedaniel/clothconfig2/impl/builders/FloatListBuilder.java

@@ -4,6 +4,8 @@ import me.shedaniel.clothconfig2.gui.entries.FloatListListEntry;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
 import net.minecraft.client.resource.language.I18n;
+import net.minecraft.text.Text;
+import net.minecraft.text.TranslatableText;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.NotNull;
 
@@ -16,26 +18,26 @@ import java.util.function.Supplier;
 @Environment(EnvType.CLIENT)
 public class FloatListBuilder extends FieldBuilder<List<Float>, FloatListListEntry> {
     
-    protected Function<Float, Optional<String>> cellErrorSupplier;
+    protected Function<Float, Optional<Text>> cellErrorSupplier;
     private Consumer<List<Float>> saveConsumer = null;
-    private Function<List<Float>, Optional<String[]>> tooltipSupplier = list -> Optional.empty();
+    private Function<List<Float>, Optional<Text[]>> tooltipSupplier = list -> Optional.empty();
     private final List<Float> value;
     private boolean expanded = false;
     private Float min = null, max = null;
     private Function<FloatListListEntry, FloatListListEntry.FloatListCell> createNewInstance;
-    private String addTooltip = I18n.translate("text.cloth-config.list.add"), removeTooltip = I18n.translate("text.cloth-config.list.remove");
+    private Text addTooltip = new TranslatableText("text.cloth-config.list.add"), removeTooltip = new TranslatableText("text.cloth-config.list.remove");
     private boolean deleteButtonEnabled = true, insertInFront = true;
     
-    public FloatListBuilder(String resetButtonKey, String fieldNameKey, List<Float> value) {
+    public FloatListBuilder(Text resetButtonKey, Text fieldNameKey, List<Float> value) {
         super(resetButtonKey, fieldNameKey);
         this.value = value;
     }
     
-    public Function<Float, Optional<String>> getCellErrorSupplier() {
+    public Function<Float, Optional<Text>> getCellErrorSupplier() {
         return cellErrorSupplier;
     }
     
-    public FloatListBuilder setCellErrorSupplier(Function<Float, Optional<String>> cellErrorSupplier) {
+    public FloatListBuilder setCellErrorSupplier(Function<Float, Optional<Text>> cellErrorSupplier) {
         this.cellErrorSupplier = cellErrorSupplier;
         return this;
     }
@@ -45,7 +47,7 @@ public class FloatListBuilder extends FieldBuilder<List<Float>, FloatListListEnt
         return this;
     }
     
-    public FloatListBuilder setErrorSupplier(Function<List<Float>, Optional<String>> errorSupplier) {
+    public FloatListBuilder setErrorSupplier(Function<List<Float>, Optional<Text>> errorSupplier) {
         this.errorSupplier = errorSupplier;
         return this;
     }
@@ -55,12 +57,12 @@ public class FloatListBuilder extends FieldBuilder<List<Float>, FloatListListEnt
         return this;
     }
     
-    public FloatListBuilder setAddButtonTooltip(String addTooltip) {
+    public FloatListBuilder setAddButtonTooltip(Text addTooltip) {
         this.addTooltip = addTooltip;
         return this;
     }
     
-    public FloatListBuilder setRemoveButtonTooltip(String removeTooltip) {
+    public FloatListBuilder setRemoveButtonTooltip(Text removeTooltip) {
         this.removeTooltip = removeTooltip;
         return this;
     }
@@ -121,22 +123,22 @@ public class FloatListBuilder extends FieldBuilder<List<Float>, FloatListListEnt
         return this;
     }
     
-    public FloatListBuilder setTooltipSupplier(Supplier<Optional<String[]>> tooltipSupplier) {
+    public FloatListBuilder setTooltipSupplier(Supplier<Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = list -> tooltipSupplier.get();
         return this;
     }
     
-    public FloatListBuilder setTooltipSupplier(Function<List<Float>, Optional<String[]>> tooltipSupplier) {
+    public FloatListBuilder setTooltipSupplier(Function<List<Float>, Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = tooltipSupplier;
         return this;
     }
     
-    public FloatListBuilder setTooltip(Optional<String[]> tooltip) {
+    public FloatListBuilder setTooltip(Optional<Text[]> tooltip) {
         this.tooltipSupplier = list -> tooltip;
         return this;
     }
     
-    public FloatListBuilder setTooltip(String... tooltip) {
+    public FloatListBuilder setTooltip(Text... tooltip) {
         this.tooltipSupplier = list -> Optional.ofNullable(tooltip);
         return this;
     }

+ 8 - 7
src/main/java/me/shedaniel/clothconfig2/impl/builders/IntFieldBuilder.java

@@ -3,6 +3,7 @@ package me.shedaniel.clothconfig2.impl.builders;
 import me.shedaniel.clothconfig2.gui.entries.IntegerListEntry;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
+import net.minecraft.text.Text;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.Optional;
@@ -14,11 +15,11 @@ import java.util.function.Supplier;
 public class IntFieldBuilder extends FieldBuilder<Integer, IntegerListEntry> {
     
     private Consumer<Integer> saveConsumer = null;
-    private Function<Integer, Optional<String[]>> tooltipSupplier = i -> Optional.empty();
+    private Function<Integer, Optional<Text[]>> tooltipSupplier = i -> Optional.empty();
     private final int value;
     private Integer min = null, max = null;
     
-    public IntFieldBuilder(String resetButtonKey, String fieldNameKey, int value) {
+    public IntFieldBuilder(Text resetButtonKey, Text fieldNameKey, int value) {
         super(resetButtonKey, fieldNameKey);
         this.value = value;
     }
@@ -28,7 +29,7 @@ public class IntFieldBuilder extends FieldBuilder<Integer, IntegerListEntry> {
         return this;
     }
     
-    public IntFieldBuilder setErrorSupplier(Function<Integer, Optional<String>> errorSupplier) {
+    public IntFieldBuilder setErrorSupplier(Function<Integer, Optional<Text>> errorSupplier) {
         this.errorSupplier = errorSupplier;
         return this;
     }
@@ -48,22 +49,22 @@ public class IntFieldBuilder extends FieldBuilder<Integer, IntegerListEntry> {
         return this;
     }
     
-    public IntFieldBuilder setTooltipSupplier(Function<Integer, Optional<String[]>> tooltipSupplier) {
+    public IntFieldBuilder setTooltipSupplier(Function<Integer, Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = tooltipSupplier;
         return this;
     }
     
-    public IntFieldBuilder setTooltipSupplier(Supplier<Optional<String[]>> tooltipSupplier) {
+    public IntFieldBuilder setTooltipSupplier(Supplier<Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = i -> tooltipSupplier.get();
         return this;
     }
     
-    public IntFieldBuilder setTooltip(Optional<String[]> tooltip) {
+    public IntFieldBuilder setTooltip(Optional<Text[]> tooltip) {
         this.tooltipSupplier = i -> tooltip;
         return this;
     }
     
-    public IntFieldBuilder setTooltip(String... tooltip) {
+    public IntFieldBuilder setTooltip(Text... tooltip) {
         this.tooltipSupplier = i -> Optional.ofNullable(tooltip);
         return this;
     }

+ 15 - 14
src/main/java/me/shedaniel/clothconfig2/impl/builders/IntListBuilder.java

@@ -3,7 +3,8 @@ package me.shedaniel.clothconfig2.impl.builders;
 import me.shedaniel.clothconfig2.gui.entries.IntegerListListEntry;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
-import net.minecraft.client.resource.language.I18n;
+import net.minecraft.text.Text;
+import net.minecraft.text.TranslatableText;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.NotNull;
 
@@ -16,31 +17,31 @@ import java.util.function.Supplier;
 @Environment(EnvType.CLIENT)
 public class IntListBuilder extends FieldBuilder<List<Integer>, IntegerListListEntry> {
     
-    protected Function<Integer, Optional<String>> cellErrorSupplier;
+    protected Function<Integer, Optional<Text>> cellErrorSupplier;
     private Consumer<List<Integer>> saveConsumer = null;
-    private Function<List<Integer>, Optional<String[]>> tooltipSupplier = list -> Optional.empty();
+    private Function<List<Integer>, Optional<Text[]>> tooltipSupplier = list -> Optional.empty();
     private final List<Integer> value;
     private boolean expanded = false;
     private Integer min = null, max = null;
     private Function<IntegerListListEntry, IntegerListListEntry.IntegerListCell> createNewInstance;
-    private String addTooltip = I18n.translate("text.cloth-config.list.add"), removeTooltip = I18n.translate("text.cloth-config.list.remove");
+    private Text addTooltip = new TranslatableText("text.cloth-config.list.add"), removeTooltip = new TranslatableText("text.cloth-config.list.remove");
     private boolean deleteButtonEnabled = true, insertInFront = true;
     
-    public IntListBuilder(String resetButtonKey, String fieldNameKey, List<Integer> value) {
+    public IntListBuilder(Text resetButtonKey, Text fieldNameKey, List<Integer> value) {
         super(resetButtonKey, fieldNameKey);
         this.value = value;
     }
     
-    public Function<Integer, Optional<String>> getCellErrorSupplier() {
+    public Function<Integer, Optional<Text>> getCellErrorSupplier() {
         return cellErrorSupplier;
     }
     
-    public IntListBuilder setCellErrorSupplier(Function<Integer, Optional<String>> cellErrorSupplier) {
+    public IntListBuilder setCellErrorSupplier(Function<Integer, Optional<Text>> cellErrorSupplier) {
         this.cellErrorSupplier = cellErrorSupplier;
         return this;
     }
     
-    public IntListBuilder setErrorSupplier(Function<List<Integer>, Optional<String>> errorSupplier) {
+    public IntListBuilder setErrorSupplier(Function<List<Integer>, Optional<Text>> errorSupplier) {
         this.errorSupplier = errorSupplier;
         return this;
     }
@@ -55,12 +56,12 @@ public class IntListBuilder extends FieldBuilder<List<Integer>, IntegerListListE
         return this;
     }
     
-    public IntListBuilder setAddButtonTooltip(String addTooltip) {
+    public IntListBuilder setAddButtonTooltip(Text addTooltip) {
         this.addTooltip = addTooltip;
         return this;
     }
     
-    public IntListBuilder setRemoveButtonTooltip(String removeTooltip) {
+    public IntListBuilder setRemoveButtonTooltip(Text removeTooltip) {
         this.removeTooltip = removeTooltip;
         return this;
     }
@@ -121,22 +122,22 @@ public class IntListBuilder extends FieldBuilder<List<Integer>, IntegerListListE
         return this;
     }
     
-    public IntListBuilder setTooltipSupplier(Function<List<Integer>, Optional<String[]>> tooltipSupplier) {
+    public IntListBuilder setTooltipSupplier(Function<List<Integer>, Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = tooltipSupplier;
         return this;
     }
     
-    public IntListBuilder setTooltipSupplier(Supplier<Optional<String[]>> tooltipSupplier) {
+    public IntListBuilder setTooltipSupplier(Supplier<Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = list -> tooltipSupplier.get();
         return this;
     }
     
-    public IntListBuilder setTooltip(Optional<String[]> tooltip) {
+    public IntListBuilder setTooltip(Optional<Text[]> tooltip) {
         this.tooltipSupplier = list -> tooltip;
         return this;
     }
     
-    public IntListBuilder setTooltip(String... tooltip) {
+    public IntListBuilder setTooltip(Text... tooltip) {
         this.tooltipSupplier = list -> Optional.ofNullable(tooltip);
         return this;
     }

+ 10 - 9
src/main/java/me/shedaniel/clothconfig2/impl/builders/IntSliderBuilder.java

@@ -3,6 +3,7 @@ package me.shedaniel.clothconfig2.impl.builders;
 import me.shedaniel.clothconfig2.gui.entries.IntegerSliderEntry;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
+import net.minecraft.text.Text;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.Optional;
@@ -14,20 +15,20 @@ import java.util.function.Supplier;
 public class IntSliderBuilder extends FieldBuilder<Integer, IntegerSliderEntry> {
     
     private Consumer<Integer> saveConsumer = null;
-    private Function<Integer, Optional<String[]>> tooltipSupplier = i -> Optional.empty();
+    private Function<Integer, Optional<Text[]>> tooltipSupplier = i -> Optional.empty();
     private final int value;
     private int max;
     private int min;
-    private Function<Integer, String> textGetter = null;
+    private Function<Integer, Text> textGetter = null;
     
-    public IntSliderBuilder(String resetButtonKey, String fieldNameKey, int value, int min, int max) {
+    public IntSliderBuilder(Text resetButtonKey, Text fieldNameKey, int value, int min, int max) {
         super(resetButtonKey, fieldNameKey);
         this.value = value;
         this.max = max;
         this.min = min;
     }
     
-    public IntSliderBuilder setErrorSupplier(Function<Integer, Optional<String>> errorSupplier) {
+    public IntSliderBuilder setErrorSupplier(Function<Integer, Optional<Text>> errorSupplier) {
         this.errorSupplier = errorSupplier;
         return this;
     }
@@ -37,7 +38,7 @@ public class IntSliderBuilder extends FieldBuilder<Integer, IntegerSliderEntry>
         return this;
     }
     
-    public IntSliderBuilder setTextGetter(Function<Integer, String> textGetter) {
+    public IntSliderBuilder setTextGetter(Function<Integer, Text> textGetter) {
         this.textGetter = textGetter;
         return this;
     }
@@ -57,22 +58,22 @@ public class IntSliderBuilder extends FieldBuilder<Integer, IntegerSliderEntry>
         return this;
     }
     
-    public IntSliderBuilder setTooltipSupplier(Function<Integer, Optional<String[]>> tooltipSupplier) {
+    public IntSliderBuilder setTooltipSupplier(Function<Integer, Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = tooltipSupplier;
         return this;
     }
     
-    public IntSliderBuilder setTooltipSupplier(Supplier<Optional<String[]>> tooltipSupplier) {
+    public IntSliderBuilder setTooltipSupplier(Supplier<Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = i -> tooltipSupplier.get();
         return this;
     }
     
-    public IntSliderBuilder setTooltip(Optional<String[]> tooltip) {
+    public IntSliderBuilder setTooltip(Optional<Text[]> tooltip) {
         this.tooltipSupplier = i -> tooltip;
         return this;
     }
     
-    public IntSliderBuilder setTooltip(String... tooltip) {
+    public IntSliderBuilder setTooltip(Text... tooltip) {
         this.tooltipSupplier = i -> Optional.ofNullable(tooltip);
         return this;
     }

+ 10 - 9
src/main/java/me/shedaniel/clothconfig2/impl/builders/KeyCodeBuilder.java

@@ -6,6 +6,7 @@ import me.shedaniel.clothconfig2.gui.entries.KeyCodeEntry;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
 import net.minecraft.client.util.InputUtil;
+import net.minecraft.text.Text;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -18,11 +19,11 @@ import java.util.function.Supplier;
 public class KeyCodeBuilder extends FieldBuilder<ModifierKeyCode, KeyCodeEntry> {
     
     @Nullable private Consumer<ModifierKeyCode> saveConsumer = null;
-    @NotNull private Function<ModifierKeyCode, Optional<String[]>> tooltipSupplier = bool -> Optional.empty();
+    @NotNull private Function<ModifierKeyCode, Optional<Text[]>> tooltipSupplier = bool -> Optional.empty();
     private final ModifierKeyCode value;
     private boolean allowKey = true, allowMouse = true, allowModifiers = true;
     
-    public KeyCodeBuilder(String resetButtonKey, String fieldNameKey, ModifierKeyCode value) {
+    public KeyCodeBuilder(Text resetButtonKey, Text fieldNameKey, ModifierKeyCode value) {
         super(resetButtonKey, fieldNameKey);
         this.value = ModifierKeyCode.copyOf(value);
     }
@@ -48,11 +49,11 @@ public class KeyCodeBuilder extends FieldBuilder<ModifierKeyCode, KeyCodeEntry>
         return this;
     }
     
-    public KeyCodeBuilder setErrorSupplier(@Nullable Function<InputUtil.KeyCode, Optional<String>> errorSupplier) {
+    public KeyCodeBuilder setErrorSupplier(@Nullable Function<InputUtil.KeyCode, Optional<Text>> errorSupplier) {
         return setModifierErrorSupplier(keyCode -> errorSupplier.apply(keyCode.getKeyCode()));
     }
     
-    public KeyCodeBuilder setModifierErrorSupplier(@Nullable Function<ModifierKeyCode, Optional<String>> errorSupplier) {
+    public KeyCodeBuilder setModifierErrorSupplier(@Nullable Function<ModifierKeyCode, Optional<Text>> errorSupplier) {
         this.errorSupplier = errorSupplier;
         return this;
     }
@@ -89,26 +90,26 @@ public class KeyCodeBuilder extends FieldBuilder<ModifierKeyCode, KeyCodeEntry>
         return this;
     }
     
-    public KeyCodeBuilder setTooltipSupplier(@NotNull Function<InputUtil.KeyCode, Optional<String[]>> tooltipSupplier) {
+    public KeyCodeBuilder setTooltipSupplier(@NotNull Function<InputUtil.KeyCode, Optional<Text[]>> tooltipSupplier) {
         return setModifierTooltipSupplier(keyCode -> tooltipSupplier.apply(keyCode.getKeyCode()));
     }
     
-    public KeyCodeBuilder setModifierTooltipSupplier(@NotNull Function<ModifierKeyCode, Optional<String[]>> tooltipSupplier) {
+    public KeyCodeBuilder setModifierTooltipSupplier(@NotNull Function<ModifierKeyCode, Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = tooltipSupplier;
         return this;
     }
     
-    public KeyCodeBuilder setTooltipSupplier(@NotNull Supplier<Optional<String[]>> tooltipSupplier) {
+    public KeyCodeBuilder setTooltipSupplier(@NotNull Supplier<Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = bool -> tooltipSupplier.get();
         return this;
     }
     
-    public KeyCodeBuilder setTooltip(Optional<String[]> tooltip) {
+    public KeyCodeBuilder setTooltip(Optional<Text[]> tooltip) {
         this.tooltipSupplier = bool -> tooltip;
         return this;
     }
     
-    public KeyCodeBuilder setTooltip(@Nullable String... tooltip) {
+    public KeyCodeBuilder setTooltip(@Nullable Text... tooltip) {
         this.tooltipSupplier = bool -> Optional.ofNullable(tooltip);
         return this;
     }

+ 8 - 7
src/main/java/me/shedaniel/clothconfig2/impl/builders/LongFieldBuilder.java

@@ -3,6 +3,7 @@ package me.shedaniel.clothconfig2.impl.builders;
 import me.shedaniel.clothconfig2.gui.entries.LongListEntry;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
+import net.minecraft.text.Text;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.Optional;
@@ -14,16 +15,16 @@ import java.util.function.Supplier;
 public class LongFieldBuilder extends FieldBuilder<Long, LongListEntry> {
     
     private Consumer<Long> saveConsumer = null;
-    private Function<Long, Optional<String[]>> tooltipSupplier = l -> Optional.empty();
+    private Function<Long, Optional<Text[]>> tooltipSupplier = l -> Optional.empty();
     private final long value;
     private Long min = null, max = null;
     
-    public LongFieldBuilder(String resetButtonKey, String fieldNameKey, long value) {
+    public LongFieldBuilder(Text resetButtonKey, Text fieldNameKey, long value) {
         super(resetButtonKey, fieldNameKey);
         this.value = value;
     }
     
-    public LongFieldBuilder setErrorSupplier(Function<Long, Optional<String>> errorSupplier) {
+    public LongFieldBuilder setErrorSupplier(Function<Long, Optional<Text>> errorSupplier) {
         this.errorSupplier = errorSupplier;
         return this;
     }
@@ -48,22 +49,22 @@ public class LongFieldBuilder extends FieldBuilder<Long, LongListEntry> {
         return this;
     }
     
-    public LongFieldBuilder setTooltipSupplier(Supplier<Optional<String[]>> tooltipSupplier) {
+    public LongFieldBuilder setTooltipSupplier(Supplier<Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = l -> tooltipSupplier.get();
         return this;
     }
     
-    public LongFieldBuilder setTooltipSupplier(Function<Long, Optional<String[]>> tooltipSupplier) {
+    public LongFieldBuilder setTooltipSupplier(Function<Long, Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = tooltipSupplier;
         return this;
     }
     
-    public LongFieldBuilder setTooltip(Optional<String[]> tooltip) {
+    public LongFieldBuilder setTooltip(Optional<Text[]> tooltip) {
         this.tooltipSupplier = l -> tooltip;
         return this;
     }
     
-    public LongFieldBuilder setTooltip(String... tooltip) {
+    public LongFieldBuilder setTooltip(Text... tooltip) {
         this.tooltipSupplier = l -> Optional.ofNullable(tooltip);
         return this;
     }

+ 15 - 14
src/main/java/me/shedaniel/clothconfig2/impl/builders/LongListBuilder.java

@@ -3,7 +3,8 @@ package me.shedaniel.clothconfig2.impl.builders;
 import me.shedaniel.clothconfig2.gui.entries.LongListListEntry;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
-import net.minecraft.client.resource.language.I18n;
+import net.minecraft.text.Text;
+import net.minecraft.text.TranslatableText;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.NotNull;
 
@@ -16,31 +17,31 @@ import java.util.function.Supplier;
 @Environment(EnvType.CLIENT)
 public class LongListBuilder extends FieldBuilder<List<Long>, LongListListEntry> {
     
-    protected Function<Long, Optional<String>> cellErrorSupplier;
+    protected Function<Long, Optional<Text>> cellErrorSupplier;
     private Consumer<List<Long>> saveConsumer = null;
-    private Function<List<Long>, Optional<String[]>> tooltipSupplier = list -> Optional.empty();
+    private Function<List<Long>, Optional<Text[]>> tooltipSupplier = list -> Optional.empty();
     private final List<Long> value;
     private boolean expanded = false;
     private Long min = null, max = null;
     private Function<LongListListEntry, LongListListEntry.LongListCell> createNewInstance;
-    private String addTooltip = I18n.translate("text.cloth-config.list.add"), removeTooltip = I18n.translate("text.cloth-config.list.remove");
+    private Text addTooltip = new TranslatableText("text.cloth-config.list.add"), removeTooltip = new TranslatableText("text.cloth-config.list.remove");
     private boolean deleteButtonEnabled = true, insertInFront = true;
     
-    public LongListBuilder(String resetButtonKey, String fieldNameKey, List<Long> value) {
+    public LongListBuilder(Text resetButtonKey, Text fieldNameKey, List<Long> value) {
         super(resetButtonKey, fieldNameKey);
         this.value = value;
     }
     
-    public Function<Long, Optional<String>> getCellErrorSupplier() {
+    public Function<Long, Optional<Text>> getCellErrorSupplier() {
         return cellErrorSupplier;
     }
     
-    public LongListBuilder setCellErrorSupplier(Function<Long, Optional<String>> cellErrorSupplier) {
+    public LongListBuilder setCellErrorSupplier(Function<Long, Optional<Text>> cellErrorSupplier) {
         this.cellErrorSupplier = cellErrorSupplier;
         return this;
     }
     
-    public LongListBuilder setErrorSupplier(Function<List<Long>, Optional<String>> errorSupplier) {
+    public LongListBuilder setErrorSupplier(Function<List<Long>, Optional<Text>> errorSupplier) {
         this.errorSupplier = errorSupplier;
         return this;
     }
@@ -55,12 +56,12 @@ public class LongListBuilder extends FieldBuilder<List<Long>, LongListListEntry>
         return this;
     }
     
-    public LongListBuilder setAddButtonTooltip(String addTooltip) {
+    public LongListBuilder setAddButtonTooltip(Text addTooltip) {
         this.addTooltip = addTooltip;
         return this;
     }
     
-    public LongListBuilder setRemoveButtonTooltip(String removeTooltip) {
+    public LongListBuilder setRemoveButtonTooltip(Text removeTooltip) {
         this.removeTooltip = removeTooltip;
         return this;
     }
@@ -121,22 +122,22 @@ public class LongListBuilder extends FieldBuilder<List<Long>, LongListListEntry>
         return this;
     }
     
-    public LongListBuilder setTooltipSupplier(Supplier<Optional<String[]>> tooltipSupplier) {
+    public LongListBuilder setTooltipSupplier(Supplier<Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = list -> tooltipSupplier.get();
         return this;
     }
     
-    public LongListBuilder setTooltipSupplier(Function<List<Long>, Optional<String[]>> tooltipSupplier) {
+    public LongListBuilder setTooltipSupplier(Function<List<Long>, Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = tooltipSupplier;
         return this;
     }
     
-    public LongListBuilder setTooltip(Optional<String[]> tooltip) {
+    public LongListBuilder setTooltip(Optional<Text[]> tooltip) {
         this.tooltipSupplier = list -> tooltip;
         return this;
     }
     
-    public LongListBuilder setTooltip(String... tooltip) {
+    public LongListBuilder setTooltip(Text... tooltip) {
         this.tooltipSupplier = list -> Optional.ofNullable(tooltip);
         return this;
     }

+ 10 - 9
src/main/java/me/shedaniel/clothconfig2/impl/builders/LongSliderBuilder.java

@@ -3,6 +3,7 @@ package me.shedaniel.clothconfig2.impl.builders;
 import me.shedaniel.clothconfig2.gui.entries.LongSliderEntry;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
+import net.minecraft.text.Text;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.Optional;
@@ -14,20 +15,20 @@ import java.util.function.Supplier;
 public class LongSliderBuilder extends FieldBuilder<Long, LongSliderEntry> {
     
     private Consumer<Long> saveConsumer = null;
-    private Function<Long, Optional<String[]>> tooltipSupplier = l -> Optional.empty();
+    private Function<Long, Optional<Text[]>> tooltipSupplier = l -> Optional.empty();
     private final long value;
     private final long max;
     private final long min;
-    private Function<Long, String> textGetter = null;
+    private Function<Long, Text> textGetter = null;
     
-    public LongSliderBuilder(String resetButtonKey, String fieldNameKey, long value, long min, long max) {
+    public LongSliderBuilder(Text resetButtonKey, Text fieldNameKey, long value, long min, long max) {
         super(resetButtonKey, fieldNameKey);
         this.value = value;
         this.max = max;
         this.min = min;
     }
     
-    public LongSliderBuilder setErrorSupplier(Function<Long, Optional<String>> errorSupplier) {
+    public LongSliderBuilder setErrorSupplier(Function<Long, Optional<Text>> errorSupplier) {
         this.errorSupplier = errorSupplier;
         return this;
     }
@@ -37,7 +38,7 @@ public class LongSliderBuilder extends FieldBuilder<Long, LongSliderEntry> {
         return this;
     }
     
-    public LongSliderBuilder setTextGetter(Function<Long, String> textGetter) {
+    public LongSliderBuilder setTextGetter(Function<Long, Text> textGetter) {
         this.textGetter = textGetter;
         return this;
     }
@@ -57,22 +58,22 @@ public class LongSliderBuilder extends FieldBuilder<Long, LongSliderEntry> {
         return this;
     }
     
-    public LongSliderBuilder setTooltipSupplier(Function<Long, Optional<String[]>> tooltipSupplier) {
+    public LongSliderBuilder setTooltipSupplier(Function<Long, Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = tooltipSupplier;
         return this;
     }
     
-    public LongSliderBuilder setTooltipSupplier(Supplier<Optional<String[]>> tooltipSupplier) {
+    public LongSliderBuilder setTooltipSupplier(Supplier<Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = i -> tooltipSupplier.get();
         return this;
     }
     
-    public LongSliderBuilder setTooltip(Optional<String[]> tooltip) {
+    public LongSliderBuilder setTooltip(Optional<Text[]> tooltip) {
         this.tooltipSupplier = i -> tooltip;
         return this;
     }
     
-    public LongSliderBuilder setTooltip(String... tooltip) {
+    public LongSliderBuilder setTooltip(Text... tooltip) {
         this.tooltipSupplier = i -> Optional.ofNullable(tooltip);
         return this;
     }

+ 10 - 9
src/main/java/me/shedaniel/clothconfig2/impl/builders/SelectorBuilder.java

@@ -3,6 +3,7 @@ package me.shedaniel.clothconfig2.impl.builders;
 import me.shedaniel.clothconfig2.gui.entries.SelectionListEntry;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
+import net.minecraft.text.Text;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.Objects;
@@ -15,19 +16,19 @@ import java.util.function.Supplier;
 public class SelectorBuilder<T> extends FieldBuilder<T, SelectionListEntry<T>> {
     
     private Consumer<T> saveConsumer = null;
-    private Function<T, Optional<String[]>> tooltipSupplier = e -> Optional.empty();
+    private Function<T, Optional<Text[]>> tooltipSupplier = e -> Optional.empty();
     private final T value;
     private final T[] valuesArray;
-    private Function<T, String> nameProvider = null;
+    private Function<T, Text> nameProvider = null;
     
-    public SelectorBuilder(String resetButtonKey, String fieldNameKey, T[] valuesArray, T value) {
+    public SelectorBuilder(Text resetButtonKey, Text fieldNameKey, T[] valuesArray, T value) {
         super(resetButtonKey, fieldNameKey);
         Objects.requireNonNull(value);
         this.valuesArray = valuesArray;
         this.value = value;
     }
     
-    public SelectorBuilder<T> setErrorSupplier(Function<T, Optional<String>> errorSupplier) {
+    public SelectorBuilder<T> setErrorSupplier(Function<T, Optional<Text>> errorSupplier) {
         this.errorSupplier = errorSupplier;
         return this;
     }
@@ -53,27 +54,27 @@ public class SelectorBuilder<T> extends FieldBuilder<T, SelectionListEntry<T>> {
         return this;
     }
     
-    public SelectorBuilder<T> setTooltipSupplier(Function<T, Optional<String[]>> tooltipSupplier) {
+    public SelectorBuilder<T> setTooltipSupplier(Function<T, Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = tooltipSupplier;
         return this;
     }
     
-    public SelectorBuilder<T> setTooltipSupplier(Supplier<Optional<String[]>> tooltipSupplier) {
+    public SelectorBuilder<T> setTooltipSupplier(Supplier<Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = e -> tooltipSupplier.get();
         return this;
     }
     
-    public SelectorBuilder<T> setTooltip(Optional<String[]> tooltip) {
+    public SelectorBuilder<T> setTooltip(Optional<Text[]> tooltip) {
         this.tooltipSupplier = e -> tooltip;
         return this;
     }
     
-    public SelectorBuilder<T> setTooltip(String... tooltip) {
+    public SelectorBuilder<T> setTooltip(Text... tooltip) {
         this.tooltipSupplier = e -> Optional.ofNullable(tooltip);
         return this;
     }
     
-    public SelectorBuilder<T> setNameProvider(Function<T, String> enumNameProvider) {
+    public SelectorBuilder<T> setNameProvider(Function<T, Text> enumNameProvider) {
         this.nameProvider = enumNameProvider;
         return this;
     }

+ 8 - 7
src/main/java/me/shedaniel/clothconfig2/impl/builders/StringFieldBuilder.java

@@ -3,6 +3,7 @@ package me.shedaniel.clothconfig2.impl.builders;
 import me.shedaniel.clothconfig2.gui.entries.StringListEntry;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
+import net.minecraft.text.Text;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.Objects;
@@ -15,16 +16,16 @@ import java.util.function.Supplier;
 public class StringFieldBuilder extends FieldBuilder<String, StringListEntry> {
     
     private Consumer<String> saveConsumer = null;
-    private Function<String, Optional<String[]>> tooltipSupplier = str -> Optional.empty();
+    private Function<String, Optional<Text[]>> tooltipSupplier = str -> Optional.empty();
     private final String value;
     
-    public StringFieldBuilder(String resetButtonKey, String fieldNameKey, String value) {
+    public StringFieldBuilder(Text resetButtonKey, Text fieldNameKey, String value) {
         super(resetButtonKey, fieldNameKey);
         Objects.requireNonNull(value);
         this.value = value;
     }
     
-    public StringFieldBuilder setErrorSupplier(Function<String, Optional<String>> errorSupplier) {
+    public StringFieldBuilder setErrorSupplier(Function<String, Optional<Text>> errorSupplier) {
         this.errorSupplier = errorSupplier;
         return this;
     }
@@ -49,22 +50,22 @@ public class StringFieldBuilder extends FieldBuilder<String, StringListEntry> {
         return this;
     }
     
-    public StringFieldBuilder setTooltipSupplier(Supplier<Optional<String[]>> tooltipSupplier) {
+    public StringFieldBuilder setTooltipSupplier(Supplier<Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = str -> tooltipSupplier.get();
         return this;
     }
     
-    public StringFieldBuilder setTooltipSupplier(Function<String, Optional<String[]>> tooltipSupplier) {
+    public StringFieldBuilder setTooltipSupplier(Function<String, Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = tooltipSupplier;
         return this;
     }
     
-    public StringFieldBuilder setTooltip(Optional<String[]> tooltip) {
+    public StringFieldBuilder setTooltip(Optional<Text[]> tooltip) {
         this.tooltipSupplier = str -> tooltip;
         return this;
     }
     
-    public StringFieldBuilder setTooltip(String... tooltip) {
+    public StringFieldBuilder setTooltip(Text... tooltip) {
         this.tooltipSupplier = str -> Optional.ofNullable(tooltip);
         return this;
     }

+ 15 - 13
src/main/java/me/shedaniel/clothconfig2/impl/builders/StringListBuilder.java

@@ -4,6 +4,8 @@ import me.shedaniel.clothconfig2.gui.entries.StringListListEntry;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
 import net.minecraft.client.resource.language.I18n;
+import net.minecraft.text.Text;
+import net.minecraft.text.TranslatableText;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.NotNull;
 
@@ -16,30 +18,30 @@ import java.util.function.Supplier;
 @Environment(EnvType.CLIENT)
 public class StringListBuilder extends FieldBuilder<List<String>, StringListListEntry> {
     
-    private Function<String, Optional<String>> cellErrorSupplier;
+    private Function<String, Optional<Text>> cellErrorSupplier;
     private Consumer<List<String>> saveConsumer = null;
-    private Function<List<String>, Optional<String[]>> tooltipSupplier = list -> Optional.empty();
+    private Function<List<String>, Optional<Text[]>> tooltipSupplier = list -> Optional.empty();
     private final List<String> value;
     private boolean expanded = false;
     private Function<StringListListEntry, StringListListEntry.StringListCell> createNewInstance;
-    private String addTooltip = I18n.translate("text.cloth-config.list.add"), removeTooltip = I18n.translate("text.cloth-config.list.remove");
+    private Text addTooltip = new TranslatableText("text.cloth-config.list.add"), removeTooltip = new TranslatableText("text.cloth-config.list.remove");
     private boolean deleteButtonEnabled = true, insertInFront = true;
     
-    public StringListBuilder(String resetButtonKey, String fieldNameKey, List<String> value) {
+    public StringListBuilder(Text resetButtonKey, Text fieldNameKey, List<String> value) {
         super(resetButtonKey, fieldNameKey);
         this.value = value;
     }
     
-    public Function<String, Optional<String>> getCellErrorSupplier() {
+    public Function<String, Optional<Text>> getCellErrorSupplier() {
         return cellErrorSupplier;
     }
     
-    public StringListBuilder setCellErrorSupplier(Function<String, Optional<String>> cellErrorSupplier) {
+    public StringListBuilder setCellErrorSupplier(Function<String, Optional<Text>> cellErrorSupplier) {
         this.cellErrorSupplier = cellErrorSupplier;
         return this;
     }
     
-    public StringListBuilder setErrorSupplier(Function<List<String>, Optional<String>> errorSupplier) {
+    public StringListBuilder setErrorSupplier(Function<List<String>, Optional<Text>> errorSupplier) {
         this.errorSupplier = errorSupplier;
         return this;
     }
@@ -54,12 +56,12 @@ public class StringListBuilder extends FieldBuilder<List<String>, StringListList
         return this;
     }
     
-    public StringListBuilder setAddButtonTooltip(String addTooltip) {
+    public StringListBuilder setAddButtonTooltip(Text addTooltip) {
         this.addTooltip = addTooltip;
         return this;
     }
     
-    public StringListBuilder setRemoveButtonTooltip(String removeTooltip) {
+    public StringListBuilder setRemoveButtonTooltip(Text removeTooltip) {
         this.removeTooltip = removeTooltip;
         return this;
     }
@@ -100,22 +102,22 @@ public class StringListBuilder extends FieldBuilder<List<String>, StringListList
         return this;
     }
     
-    public StringListBuilder setTooltipSupplier(Supplier<Optional<String[]>> tooltipSupplier) {
+    public StringListBuilder setTooltipSupplier(Supplier<Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = list -> tooltipSupplier.get();
         return this;
     }
     
-    public StringListBuilder setTooltipSupplier(Function<List<String>, Optional<String[]>> tooltipSupplier) {
+    public StringListBuilder setTooltipSupplier(Function<List<String>, Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = tooltipSupplier;
         return this;
     }
     
-    public StringListBuilder setTooltip(Optional<String[]> tooltip) {
+    public StringListBuilder setTooltip(Optional<Text[]> tooltip) {
         this.tooltipSupplier = list -> tooltip;
         return this;
     }
     
-    public StringListBuilder setTooltip(String... tooltip) {
+    public StringListBuilder setTooltip(Text... tooltip) {
         this.tooltipSupplier = list -> Optional.ofNullable(tooltip);
         return this;
     }

+ 7 - 6
src/main/java/me/shedaniel/clothconfig2/impl/builders/SubCategoryBuilder.java

@@ -5,6 +5,7 @@ import me.shedaniel.clothconfig2.api.AbstractConfigListEntry;
 import me.shedaniel.clothconfig2.gui.entries.SubCategoryListEntry;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
+import net.minecraft.text.Text;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.NotNull;
 
@@ -16,10 +17,10 @@ import java.util.function.Supplier;
 public class SubCategoryBuilder extends FieldBuilder<Object, SubCategoryListEntry> implements List<AbstractConfigListEntry> {
     
     private final List<AbstractConfigListEntry> entries;
-    private Function<List<AbstractConfigListEntry>, Optional<String[]>> tooltipSupplier = list -> Optional.empty();
+    private Function<List<AbstractConfigListEntry>, Optional<Text[]>> tooltipSupplier = list -> Optional.empty();
     private boolean expanded = false;
     
-    public SubCategoryBuilder(String resetButtonKey, String fieldNameKey) {
+    public SubCategoryBuilder(Text resetButtonKey, Text fieldNameKey) {
         super(resetButtonKey, fieldNameKey);
         this.entries = Lists.newArrayList();
     }
@@ -29,22 +30,22 @@ public class SubCategoryBuilder extends FieldBuilder<Object, SubCategoryListEntr
         throw new UnsupportedOperationException();
     }
     
-    public SubCategoryBuilder setTooltipSupplier(Supplier<Optional<String[]>> tooltipSupplier) {
+    public SubCategoryBuilder setTooltipSupplier(Supplier<Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = list -> tooltipSupplier.get();
         return this;
     }
     
-    public SubCategoryBuilder setTooltipSupplier(Function<List<AbstractConfigListEntry>, Optional<String[]>> tooltipSupplier) {
+    public SubCategoryBuilder setTooltipSupplier(Function<List<AbstractConfigListEntry>, Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = tooltipSupplier;
         return this;
     }
     
-    public SubCategoryBuilder setTooltip(Optional<String[]> tooltip) {
+    public SubCategoryBuilder setTooltip(Optional<Text[]> tooltip) {
         this.tooltipSupplier = list -> tooltip;
         return this;
     }
     
-    public SubCategoryBuilder setTooltip(String... tooltip) {
+    public SubCategoryBuilder setTooltip(Text... tooltip) {
         this.tooltipSupplier = list -> Optional.ofNullable(tooltip);
         return this;
     }

+ 8 - 7
src/main/java/me/shedaniel/clothconfig2/impl/builders/TextDescriptionBuilder.java

@@ -3,6 +3,7 @@ package me.shedaniel.clothconfig2.impl.builders;
 import me.shedaniel.clothconfig2.gui.entries.TextListEntry;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
+import net.minecraft.text.Text;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -10,13 +11,13 @@ import java.util.Optional;
 import java.util.function.Supplier;
 
 @Environment(EnvType.CLIENT)
-public class TextDescriptionBuilder extends FieldBuilder<String, TextListEntry> {
+public class TextDescriptionBuilder extends FieldBuilder<Text, TextListEntry> {
     
     private int color = -1;
-    @Nullable private Supplier<Optional<String[]>> tooltipSupplier = null;
-    private final String value;
+    @Nullable private Supplier<Optional<Text[]>> tooltipSupplier = null;
+    private final Text value;
     
-    public TextDescriptionBuilder(String resetButtonKey, String fieldNameKey, String value) {
+    public TextDescriptionBuilder(Text resetButtonKey, Text fieldNameKey, Text value) {
         super(resetButtonKey, fieldNameKey);
         this.value = value;
     }
@@ -26,17 +27,17 @@ public class TextDescriptionBuilder extends FieldBuilder<String, TextListEntry>
         throw new UnsupportedOperationException();
     }
     
-    public TextDescriptionBuilder setTooltipSupplier(Supplier<Optional<String[]>> tooltipSupplier) {
+    public TextDescriptionBuilder setTooltipSupplier(Supplier<Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = tooltipSupplier;
         return this;
     }
     
-    public TextDescriptionBuilder setTooltip(Optional<String[]> tooltip) {
+    public TextDescriptionBuilder setTooltip(Optional<Text[]> tooltip) {
         this.tooltipSupplier = () -> tooltip;
         return this;
     }
     
-    public TextDescriptionBuilder setTooltip(String... tooltip) {
+    public TextDescriptionBuilder setTooltip(Text... tooltip) {
         this.tooltipSupplier = () -> Optional.ofNullable(tooltip);
         return this;
     }

+ 8 - 7
src/main/java/me/shedaniel/clothconfig2/impl/builders/TextFieldBuilder.java

@@ -3,6 +3,7 @@ package me.shedaniel.clothconfig2.impl.builders;
 import me.shedaniel.clothconfig2.gui.entries.StringListEntry;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
+import net.minecraft.text.Text;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.Objects;
@@ -15,16 +16,16 @@ import java.util.function.Supplier;
 public class TextFieldBuilder extends FieldBuilder<String, StringListEntry> {
     
     private Consumer<String> saveConsumer = null;
-    private Function<String, Optional<String[]>> tooltipSupplier = str -> Optional.empty();
+    private Function<String, Optional<Text[]>> tooltipSupplier = str -> Optional.empty();
     private final String value;
     
-    public TextFieldBuilder(String resetButtonKey, String fieldNameKey, String value) {
+    public TextFieldBuilder(Text resetButtonKey, Text fieldNameKey, String value) {
         super(resetButtonKey, fieldNameKey);
         Objects.requireNonNull(value);
         this.value = value;
     }
     
-    public TextFieldBuilder setErrorSupplier(Function<String, Optional<String>> errorSupplier) {
+    public TextFieldBuilder setErrorSupplier(Function<String, Optional<Text>> errorSupplier) {
         this.errorSupplier = errorSupplier;
         return this;
     }
@@ -49,22 +50,22 @@ public class TextFieldBuilder extends FieldBuilder<String, StringListEntry> {
         return this;
     }
     
-    public TextFieldBuilder setTooltipSupplier(Supplier<Optional<String[]>> tooltipSupplier) {
+    public TextFieldBuilder setTooltipSupplier(Supplier<Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = str -> tooltipSupplier.get();
         return this;
     }
     
-    public TextFieldBuilder setTooltipSupplier(Function<String, Optional<String[]>> tooltipSupplier) {
+    public TextFieldBuilder setTooltipSupplier(Function<String, Optional<Text[]>> tooltipSupplier) {
         this.tooltipSupplier = tooltipSupplier;
         return this;
     }
     
-    public TextFieldBuilder setTooltip(Optional<String[]> tooltip) {
+    public TextFieldBuilder setTooltip(Optional<Text[]> tooltip) {
         this.tooltipSupplier = str -> tooltip;
         return this;
     }
     
-    public TextFieldBuilder setTooltip(String... tooltip) {
+    public TextFieldBuilder setTooltip(Text... tooltip) {
         this.tooltipSupplier = str -> Optional.ofNullable(tooltip);
         return this;
     }

+ 0 - 34
src/main/java/me/shedaniel/math/api/Dimension.java

@@ -1,34 +0,0 @@
-package me.shedaniel.math.api;
-
-import org.jetbrains.annotations.ApiStatus;
-
-/**
- * @deprecated Use {@link me.shedaniel.math.Dimension}
- */
-@Deprecated
-@ApiStatus.ScheduledForRemoval
-public class Dimension extends me.shedaniel.math.Dimension {
-    public Dimension() {
-        super();
-    }
-    
-    public Dimension(Dimension d) {
-        super(d);
-    }
-    
-    public Dimension(me.shedaniel.math.Dimension d) {
-        super(d);
-    }
-    
-    public Dimension(int width, int height) {
-        super(width, height);
-    }
-    
-    public Dimension getSize() {
-        return new Dimension(width, height);
-    }
-    
-    public void setSize(Dimension d) {
-        setSize(d.width, d.height);
-    }
-}

+ 0 - 38
src/main/java/me/shedaniel/math/api/Point.java

@@ -1,38 +0,0 @@
-package me.shedaniel.math.api;
-
-import org.jetbrains.annotations.ApiStatus;
-
-/**
- * @deprecated Use {@link me.shedaniel.math.Point}
- */
-@Deprecated
-@ApiStatus.ScheduledForRemoval
-public class Point extends me.shedaniel.math.Point {
-    public Point() {
-        super();
-    }
-    
-    public Point(Point p) {
-        super(p);
-    }
-    
-    public Point(me.shedaniel.math.Point p) {
-        super(p);
-    }
-    
-    public Point(double x, double y) {
-        super(x, y);
-    }
-    
-    public Point(int x, int y) {
-        super(x, y);
-    }
-    
-    public Point getLocation() {
-        return new Point(x, y);
-    }
-    
-    public Point clone() {
-        return getLocation();
-    }
-}

+ 0 - 113
src/main/java/me/shedaniel/math/api/Rectangle.java

@@ -1,113 +0,0 @@
-package me.shedaniel.math.api;
-
-import org.jetbrains.annotations.ApiStatus;
-
-/**
- * @deprecated Use {@link me.shedaniel.math.Rectangle}
- */
-@Deprecated
-@ApiStatus.ScheduledForRemoval
-public class Rectangle extends me.shedaniel.math.Rectangle {
-    public Rectangle() {
-        super();
-    }
-    
-    public Rectangle(Rectangle r) {
-        super(r);
-    }
-    
-    public Rectangle(int width, int height) {
-        super(width, height);
-    }
-    
-    public Rectangle(Point p, Dimension d) {
-        super(p, d);
-    }
-    
-    public Rectangle(Point p) {
-        super(p);
-    }
-    
-    public Rectangle(Dimension d) {
-        super(d);
-    }
-    
-    public Rectangle(me.shedaniel.math.Rectangle r) {
-        super(r);
-    }
-    
-    public Rectangle(me.shedaniel.math.Point p, me.shedaniel.math.Dimension d) {
-        super(p, d);
-    }
-    
-    public Rectangle(me.shedaniel.math.Point p) {
-        super(p);
-    }
-    
-    public Rectangle(me.shedaniel.math.Dimension d) {
-        super(d);
-    }
-    
-    public Rectangle(int x, int y, int width, int height) {
-        super(x, y, width, height);
-    }
-    
-    @Override
-    public Rectangle getBounds() {
-        return new Rectangle(x, y, width, height);
-    }
-    
-    public void setBounds(Rectangle r) {
-        setBounds((me.shedaniel.math.Rectangle) r);
-    }
-    
-    @Override
-    public Point getLocation() {
-        return new Point(x, y);
-    }
-    
-    public void setLocation(Point p) {
-        setLocation((me.shedaniel.math.Point) p);
-    }
-    
-    @Override
-    public Rectangle clone() {
-        return getBounds();
-    }
-    
-    public Dimension getSize() {
-        return new Dimension(width, height);
-    }
-    
-    public void setSize(Dimension d) {
-        setSize((me.shedaniel.math.Dimension) d);
-    }
-    
-    public boolean contains(Point p) {
-        return contains(p.x, p.y);
-    }
-    
-    public boolean contains(Rectangle r) {
-        return contains(r.x, r.y, r.width, r.height);
-    }
-    
-    public boolean intersects(Rectangle r) {
-        return intersects((me.shedaniel.math.Rectangle) r);
-    }
-    
-    public Rectangle intersection(Rectangle r) {
-        return new Rectangle(intersection((me.shedaniel.math.Rectangle) r));
-    }
-    
-    public Rectangle union(Rectangle r) {
-        return new Rectangle(union((me.shedaniel.math.Rectangle) r));
-    }
-    
-    public void add(Point r) {
-        add((me.shedaniel.math.Point) r);
-    }
-    
-    public void add(Rectangle r) {
-        add((me.shedaniel.math.Rectangle) r);
-    }
-}

+ 2 - 9
src/main/java/me/shedaniel/math/impl/PointHelper.java

@@ -4,21 +4,14 @@ import me.shedaniel.math.Point;
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
 import net.minecraft.client.MinecraftClient;
-import org.jetbrains.annotations.ApiStatus;
 
 @Environment(EnvType.CLIENT)
 public class PointHelper {
-    @Deprecated
-    @ApiStatus.ScheduledForRemoval
-    public static me.shedaniel.math.api.Point fromMouse() {
+    public static Point ofMouse() {
         MinecraftClient client = MinecraftClient.getInstance();
         double mx = client.mouse.getX() * (double) client.getWindow().getScaledWidth() / (double) client.getWindow().getWidth();
         double my = client.mouse.getY() * (double) client.getWindow().getScaledHeight() / (double) client.getWindow().getHeight();
-        return new me.shedaniel.math.api.Point(mx, my);
-    }
-    
-    public static Point ofMouse() {
-        return fromMouse();
+        return new Point(mx, my);
     }
     
     public static int getMouseX() {