Browse Source

Migrate all list entries to extend from AbstractListListEntry

Mitchell Skaggs 5 years ago
parent
commit
22a5d8d56c

+ 37 - 57
src/main/java/me/shedaniel/clothconfig2/gui/entries/DoubleListListEntry.java

@@ -4,19 +4,20 @@ import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.gui.widget.TextFieldWidget;
 import net.minecraft.client.resource.language.I18n;
+import org.jetbrains.annotations.ApiStatus;
 
 import java.util.Collections;
 import java.util.List;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.function.Consumer;
-import java.util.function.Function;
 import java.util.function.Supplier;
 import java.util.stream.Collectors;
 
-public class DoubleListListEntry extends BaseListEntry<Double, DoubleListListEntry.DoubleListCell, DoubleListListEntry> {
+@ApiStatus.Internal
+public class DoubleListListEntry extends AbstractListListEntry<Double, DoubleListListEntry.DoubleListCell, DoubleListListEntry> {
 
     private double minimum, maximum;
-    private Function<Double, Optional<String>> cellErrorSupplier;
 
     @Deprecated
     public DoubleListListEntry(String fieldName, List<Double> value, boolean defaultExpanded, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<Double>> saveConsumer, Supplier<List<Double>> defaultValue, String resetButtonKey) {
@@ -28,22 +29,21 @@ public class DoubleListListEntry extends BaseListEntry<Double, DoubleListListEnt
         this(fieldName, value, defaultExpanded, tooltipSupplier, saveConsumer, defaultValue, resetButtonKey, requiresRestart, true, true);
     }
 
-    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) {
-        super(fieldName, tooltipSupplier, defaultValue, baseListEntry -> new DoubleListCell(0d, (DoubleListListEntry) baseListEntry), saveConsumer, resetButtonKey, requiresRestart, deleteButtonEnabled, insertInFront);
-        this.minimum = -Double.MAX_VALUE;
-        this.maximum = Double.MAX_VALUE;
-        for (Double f : value)
-            cells.add(new DoubleListCell(f, this));
-        this.widgets.addAll(cells);
-        expanded = defaultExpanded;
-    }
-
-    public Function<Double, Optional<String>> getCellErrorSupplier() {
-        return cellErrorSupplier;
-    }
-
-    public void setCellErrorSupplier(Function<Double, Optional<String>> cellErrorSupplier) {
-        this.cellErrorSupplier = cellErrorSupplier;
+    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
+    ) {
+        super(fieldName, value, defaultExpanded, tooltipSupplier, saveConsumer, defaultValue, resetButtonKey, requiresRestart, deleteButtonEnabled, insertInFront, DoubleListCell::new);
+        this.minimum = Double.NEGATIVE_INFINITY;
+        this.maximum = Double.POSITIVE_INFINITY;
     }
 
     @Override
@@ -71,51 +71,32 @@ public class DoubleListListEntry extends BaseListEntry<Double, DoubleListListEnt
         return new DoubleListCell(value, this);
     }
 
-    public static class DoubleListCell extends BaseListCell {
+    public static class DoubleListCell extends AbstractListListEntry.AbstractListCell<Double, DoubleListCell, DoubleListListEntry> {
 
-        private Function<String, String> stripCharacters = s -> {
-            StringBuilder stringBuilder_1 = new StringBuilder();
-            char[] var2 = s.toCharArray();
-            int var3 = var2.length;
+        private TextFieldWidget widget;
 
-            for (int var4 = 0; var4 < var3; ++var4)
-                if (Character.isDigit(var2[var4]) || var2[var4] == '-' || var2[var4] == '.')
-                    stringBuilder_1.append(var2[var4]);
+        public DoubleListCell(Double value, final DoubleListListEntry listListEntry) {
+            super(value, listListEntry);
 
-            return stringBuilder_1.toString();
-        };
-        private TextFieldWidget widget;
-        private boolean isSelected;
-        private DoubleListListEntry listListEntry;
-
-        public DoubleListCell(double value, DoubleListListEntry listListEntry) {
-            this.listListEntry = listListEntry;
-            this.setErrorSupplier(() -> listListEntry.cellErrorSupplier == null ? Optional.empty() : listListEntry.getCellErrorSupplier().apply(getValue()));
-            widget = new TextFieldWidget(MinecraftClient.getInstance().textRenderer, 0, 0, 100, 18, "") {
-                @Override
-                public void render(int int_1, int int_2, float Double_1) {
-                    boolean f = isFocused();
-                    setFocused(isSelected);
-                    widget.setEditableColor(getPreferredTextColor());
-                    super.render(int_1, int_2, Double_1);
-                    setFocused(f);
-                }
+            if (value == null)
+                value = 0d;
+            Double finalValue = value;
 
-                @Override
-                public void write(String string_1) {
-                    super.write(stripCharacters.apply(string_1));
-                }
-            };
-            widget.setMaxLength(999999);
+            this.setErrorSupplier(() -> Optional.ofNullable(listListEntry.cellErrorSupplier).flatMap(fn -> fn.apply(this.getValue())));
+            widget = new TextFieldWidget(MinecraftClient.getInstance().textRenderer, 0, 0, 100, 18, "");
+            widget.setTextPredicate(s -> s.chars().allMatch(c -> Character.isDigit(c) || c == '-' || c == '.'));
+            widget.setMaxLength(Integer.MAX_VALUE);
             widget.setHasBorder(false);
-            widget.setText(value + "");
+            widget.setText(value.toString());
             widget.setChangedListener(s -> {
-                if (!(value + "").equalsIgnoreCase(s))
-                    listListEntry.getScreen().setEdited(true, listListEntry.isRequiresRestart());
+                widget.setEditableColor(getPreferredTextColor());
+                if (!Objects.equals(s, finalValue.toString())) {
+                    this.listListEntry.getScreen().setEdited(true, this.listListEntry.isRequiresRestart());
+                }
             });
         }
 
-        public double getValue() {
+        public Double getValue() {
             try {
                 return Double.valueOf(widget.getText());
             } catch (NumberFormatException e) {
@@ -126,7 +107,7 @@ public class DoubleListListEntry extends BaseListEntry<Double, DoubleListListEnt
         @Override
         public Optional<String> getError() {
             try {
-                double i = Double.valueOf(widget.getText());
+                double i = Double.parseDouble(widget.getText());
                 if (i > listListEntry.maximum)
                     return Optional.of(I18n.translate("text.cloth-config.error.too_large", listListEntry.maximum));
                 else if (i < listListEntry.minimum)
@@ -148,7 +129,6 @@ public class DoubleListListEntry extends BaseListEntry<Double, DoubleListListEnt
             widget.x = x;
             widget.y = y + 1;
             widget.setEditable(listListEntry.isEditable());
-            this.isSelected = isSelected;
             widget.render(mouseX, mouseY, delta);
             if (isSelected && listListEntry.isEditable())
                 fill(x, y + 12, x + entryWidth - 12, y + 13, getConfigError().isPresent() ? 0xffff5555 : 0xffe0e0e0);

+ 37 - 57
src/main/java/me/shedaniel/clothconfig2/gui/entries/FloatListListEntry.java

@@ -4,19 +4,20 @@ import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.gui.widget.TextFieldWidget;
 import net.minecraft.client.resource.language.I18n;
+import org.jetbrains.annotations.ApiStatus;
 
 import java.util.Collections;
 import java.util.List;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.function.Consumer;
-import java.util.function.Function;
 import java.util.function.Supplier;
 import java.util.stream.Collectors;
 
-public class FloatListListEntry extends BaseListEntry<Float, FloatListListEntry.FloatListCell, FloatListListEntry> {
+@ApiStatus.Internal
+public class FloatListListEntry extends AbstractListListEntry<Float, FloatListListEntry.FloatListCell, FloatListListEntry> {
 
     private float minimum, maximum;
-    private Function<Float, Optional<String>> cellErrorSupplier;
 
     @Deprecated
     public FloatListListEntry(String fieldName, List<Float> value, boolean defaultExpanded, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<Float>> saveConsumer, Supplier<List<Float>> defaultValue, String resetButtonKey) {
@@ -28,22 +29,21 @@ public class FloatListListEntry extends BaseListEntry<Float, FloatListListEntry.
         this(fieldName, value, defaultExpanded, tooltipSupplier, saveConsumer, defaultValue, resetButtonKey, requiresRestart, true, true);
     }
 
-    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) {
-        super(fieldName, tooltipSupplier, defaultValue, floatListListEntry -> new FloatListCell(0, floatListListEntry), saveConsumer, resetButtonKey, requiresRestart, deleteButtonEnabled, insertInFront);
-        this.minimum = -Float.MAX_VALUE;
-        this.maximum = Float.MAX_VALUE;
-        for (float f : value)
-            cells.add(new FloatListCell(f, this));
-        this.widgets.addAll(cells);
-        expanded = defaultExpanded;
-    }
-
-    public Function<Float, Optional<String>> getCellErrorSupplier() {
-        return cellErrorSupplier;
-    }
-
-    public void setCellErrorSupplier(Function<Float, Optional<String>> cellErrorSupplier) {
-        this.cellErrorSupplier = cellErrorSupplier;
+    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
+    ) {
+        super(fieldName, value, defaultExpanded, tooltipSupplier, saveConsumer, defaultValue, resetButtonKey, requiresRestart, deleteButtonEnabled, insertInFront, FloatListCell::new);
+        this.minimum = Float.NEGATIVE_INFINITY;
+        this.maximum = Float.POSITIVE_INFINITY;
     }
 
     @Override
@@ -71,51 +71,32 @@ public class FloatListListEntry extends BaseListEntry<Float, FloatListListEntry.
         return new FloatListCell(value, this);
     }
 
-    public static class FloatListCell extends BaseListCell {
+    public static class FloatListCell extends AbstractListListEntry.AbstractListCell<Float, FloatListCell, FloatListListEntry> {
 
-        private Function<String, String> stripCharacters = s -> {
-            StringBuilder stringBuilder_1 = new StringBuilder();
-            char[] var2 = s.toCharArray();
-            int var3 = var2.length;
+        private TextFieldWidget widget;
 
-            for (int var4 = 0; var4 < var3; ++var4)
-                if (Character.isDigit(var2[var4]) || var2[var4] == '-' || var2[var4] == '.')
-                    stringBuilder_1.append(var2[var4]);
+        public FloatListCell(Float value, FloatListListEntry listListEntry) {
+            super(value, listListEntry);
 
-            return stringBuilder_1.toString();
-        };
-        private TextFieldWidget widget;
-        private boolean isSelected;
-        private FloatListListEntry listListEntry;
-
-        public FloatListCell(float value, FloatListListEntry listListEntry) {
-            this.listListEntry = listListEntry;
-            this.setErrorSupplier(() -> listListEntry.cellErrorSupplier == null ? Optional.empty() : listListEntry.getCellErrorSupplier().apply(getValue()));
-            widget = new TextFieldWidget(MinecraftClient.getInstance().textRenderer, 0, 0, 100, 18, "") {
-                @Override
-                public void render(int int_1, int int_2, float float_1) {
-                    boolean f = isFocused();
-                    setFocused(isSelected);
-                    widget.setEditableColor(getPreferredTextColor());
-                    super.render(int_1, int_2, float_1);
-                    setFocused(f);
-                }
+            if (value == null)
+                value = 0f;
+            Float finalValue = value;
 
-                @Override
-                public void write(String string_1) {
-                    super.write(stripCharacters.apply(string_1));
-                }
-            };
-            widget.setMaxLength(999999);
+            this.setErrorSupplier(() -> Optional.ofNullable(listListEntry.cellErrorSupplier).flatMap(fn -> fn.apply(this.getValue())));
+            widget = new TextFieldWidget(MinecraftClient.getInstance().textRenderer, 0, 0, 100, 18, "");
+            widget.setTextPredicate(s -> s.chars().allMatch(c -> Character.isDigit(c) || c == '-' || c == '.'));
+            widget.setMaxLength(Integer.MAX_VALUE);
             widget.setHasBorder(false);
-            widget.setText(value + "");
+            widget.setText(value.toString());
             widget.setChangedListener(s -> {
-                if (!(value + "").equalsIgnoreCase(s))
-                    listListEntry.getScreen().setEdited(true, listListEntry.isRequiresRestart());
+                widget.setEditableColor(getPreferredTextColor());
+                if (!Objects.equals(s, finalValue.toString())) {
+                    this.listListEntry.getScreen().setEdited(true, this.listListEntry.isRequiresRestart());
+                }
             });
         }
 
-        public float getValue() {
+        public Float getValue() {
             try {
                 return Float.valueOf(widget.getText());
             } catch (NumberFormatException e) {
@@ -126,7 +107,7 @@ public class FloatListListEntry extends BaseListEntry<Float, FloatListListEntry.
         @Override
         public Optional<String> getError() {
             try {
-                float i = Float.valueOf(widget.getText());
+                float i = Float.parseFloat(widget.getText());
                 if (i > listListEntry.maximum)
                     return Optional.of(I18n.translate("text.cloth-config.error.too_large", listListEntry.maximum));
                 else if (i < listListEntry.minimum)
@@ -148,7 +129,6 @@ public class FloatListListEntry extends BaseListEntry<Float, FloatListListEntry.
             widget.x = x;
             widget.y = y + 1;
             widget.setEditable(listListEntry.isEditable());
-            this.isSelected = isSelected;
             widget.render(mouseX, mouseY, delta);
             if (isSelected && listListEntry.isEditable())
                 fill(x, y + 12, x + entryWidth - 12, y + 13, getConfigError().isPresent() ? 0xffff5555 : 0xffe0e0e0);

+ 36 - 56
src/main/java/me/shedaniel/clothconfig2/gui/entries/IntegerListListEntry.java

@@ -4,19 +4,20 @@ import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.gui.widget.TextFieldWidget;
 import net.minecraft.client.resource.language.I18n;
+import org.jetbrains.annotations.ApiStatus;
 
 import java.util.Collections;
 import java.util.List;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.function.Consumer;
-import java.util.function.Function;
 import java.util.function.Supplier;
 import java.util.stream.Collectors;
 
-public class IntegerListListEntry extends BaseListEntry<Integer, IntegerListListEntry.IntegerListCell, IntegerListListEntry> {
+@ApiStatus.Internal
+public class IntegerListListEntry extends AbstractListListEntry<Integer, IntegerListListEntry.IntegerListCell, IntegerListListEntry> {
 
     private int minimum, maximum;
-    private Function<Integer, Optional<String>> cellErrorSupplier;
 
     @Deprecated
     public IntegerListListEntry(String fieldName, List<Integer> value, boolean defaultExpanded, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<Integer>> saveConsumer, Supplier<List<Integer>> defaultValue, String resetButtonKey) {
@@ -28,22 +29,21 @@ public class IntegerListListEntry extends BaseListEntry<Integer, IntegerListList
         this(fieldName, value, defaultExpanded, tooltipSupplier, saveConsumer, defaultValue, resetButtonKey, requiresRestart, true, true);
     }
 
-    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) {
-        super(fieldName, tooltipSupplier, defaultValue, integerListListEntry -> new IntegerListCell(0, integerListListEntry), saveConsumer, resetButtonKey, requiresRestart, deleteButtonEnabled, insertInFront);
-        this.minimum = -Integer.MAX_VALUE;
+    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
+    ) {
+        super(fieldName, value, defaultExpanded, tooltipSupplier, saveConsumer, defaultValue, resetButtonKey, requiresRestart, deleteButtonEnabled, insertInFront, IntegerListCell::new);
+        this.minimum = Integer.MIN_VALUE;
         this.maximum = Integer.MAX_VALUE;
-        for (int integer : value)
-            cells.add(new IntegerListCell(integer, this));
-        this.widgets.addAll(cells);
-        expanded = defaultExpanded;
-    }
-
-    public Function<Integer, Optional<String>> getCellErrorSupplier() {
-        return cellErrorSupplier;
-    }
-
-    public void setCellErrorSupplier(Function<Integer, Optional<String>> cellErrorSupplier) {
-        this.cellErrorSupplier = cellErrorSupplier;
     }
 
     @Override
@@ -71,51 +71,32 @@ public class IntegerListListEntry extends BaseListEntry<Integer, IntegerListList
         return new IntegerListCell(value, this);
     }
 
-    public static class IntegerListCell extends BaseListCell {
+    public static class IntegerListCell extends AbstractListListEntry.AbstractListCell<Integer, IntegerListCell, IntegerListListEntry> {
 
-        private Function<String, String> stripCharacters = s -> {
-            StringBuilder stringBuilder_1 = new StringBuilder();
-            char[] var2 = s.toCharArray();
-            int var3 = var2.length;
+        private TextFieldWidget widget;
 
-            for (int var4 = 0; var4 < var3; ++var4)
-                if (Character.isDigit(var2[var4]) || var2[var4] == '-')
-                    stringBuilder_1.append(var2[var4]);
+        public IntegerListCell(Integer value, IntegerListListEntry listListEntry) {
+            super(value, listListEntry);
 
-            return stringBuilder_1.toString();
-        };
-        private TextFieldWidget widget;
-        private boolean isSelected;
-        private IntegerListListEntry listListEntry;
-
-        public IntegerListCell(int value, IntegerListListEntry listListEntry) {
-            this.listListEntry = listListEntry;
-            this.setErrorSupplier(() -> listListEntry.cellErrorSupplier == null ? Optional.empty() : listListEntry.getCellErrorSupplier().apply(getValue()));
-            widget = new TextFieldWidget(MinecraftClient.getInstance().textRenderer, 0, 0, 100, 18, "") {
-                @Override
-                public void render(int int_1, int int_2, float float_1) {
-                    boolean f = isFocused();
-                    setFocused(isSelected);
-                    widget.setEditableColor(getPreferredTextColor());
-                    super.render(int_1, int_2, float_1);
-                    setFocused(f);
-                }
+            if (value == null)
+                value = 0;
+            Integer finalValue = value;
 
-                @Override
-                public void write(String string_1) {
-                    super.write(stripCharacters.apply(string_1));
-                }
-            };
-            widget.setMaxLength(999999);
+            this.setErrorSupplier(() -> Optional.ofNullable(listListEntry.cellErrorSupplier).flatMap(fn -> fn.apply(this.getValue())));
+            widget = new TextFieldWidget(MinecraftClient.getInstance().textRenderer, 0, 0, 100, 18, "");
+            widget.setTextPredicate(s -> s.chars().allMatch(c -> Character.isDigit(c) || c == '-'));
+            widget.setMaxLength(Integer.MAX_VALUE);
             widget.setHasBorder(false);
-            widget.setText(value + "");
+            widget.setText(value.toString());
             widget.setChangedListener(s -> {
-                if (!(value + "").equalsIgnoreCase(s))
-                    listListEntry.getScreen().setEdited(true, listListEntry.isRequiresRestart());
+                widget.setEditableColor(getPreferredTextColor());
+                if (!Objects.equals(s, finalValue.toString())) {
+                    this.listListEntry.getScreen().setEdited(true, this.listListEntry.isRequiresRestart());
+                }
             });
         }
 
-        public int getValue() {
+        public Integer getValue() {
             try {
                 return Integer.valueOf(widget.getText());
             } catch (NumberFormatException e) {
@@ -126,7 +107,7 @@ public class IntegerListListEntry extends BaseListEntry<Integer, IntegerListList
         @Override
         public Optional<String> getError() {
             try {
-                int i = Integer.valueOf(widget.getText());
+                int i = Integer.parseInt(widget.getText());
                 if (i > listListEntry.maximum)
                     return Optional.of(I18n.translate("text.cloth-config.error.too_large", listListEntry.maximum));
                 else if (i < listListEntry.minimum)
@@ -148,7 +129,6 @@ public class IntegerListListEntry extends BaseListEntry<Integer, IntegerListList
             widget.x = x;
             widget.y = y + 1;
             widget.setEditable(listListEntry.isEditable());
-            this.isSelected = isSelected;
             widget.render(mouseX, mouseY, delta);
             if (isSelected && listListEntry.isEditable())
                 fill(x, y + 12, x + entryWidth - 12, y + 13, getConfigError().isPresent() ? 0xffff5555 : 0xffe0e0e0);

+ 25 - 56
src/main/java/me/shedaniel/clothconfig2/gui/entries/LongListListEntry.java

@@ -4,19 +4,20 @@ import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.gui.widget.TextFieldWidget;
 import net.minecraft.client.resource.language.I18n;
+import org.jetbrains.annotations.ApiStatus;
 
 import java.util.Collections;
 import java.util.List;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.function.Consumer;
-import java.util.function.Function;
 import java.util.function.Supplier;
 import java.util.stream.Collectors;
 
-public class LongListListEntry extends BaseListEntry<Long, LongListListEntry.LongListCell, LongListListEntry> {
+@ApiStatus.Internal
+public class LongListListEntry extends AbstractListListEntry<Long, LongListListEntry.LongListCell, LongListListEntry> {
 
     private long minimum, maximum;
-    private Function<Long, Optional<String>> cellErrorSupplier;
 
     @Deprecated
     public LongListListEntry(String fieldName, List<Long> value, boolean defaultExpanded, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<Long>> saveConsumer, Supplier<List<Long>> defaultValue, String resetButtonKey) {
@@ -29,21 +30,9 @@ public class LongListListEntry extends BaseListEntry<Long, LongListListEntry.Lon
     }
 
     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) {
-        super(fieldName, tooltipSupplier, defaultValue, baseListEntry -> new LongListCell(0, baseListEntry), saveConsumer, resetButtonKey, requiresRestart, deleteButtonEnabled, insertInFront);
-        this.minimum = -Long.MAX_VALUE;
+        super(fieldName, value, defaultExpanded, tooltipSupplier, saveConsumer, defaultValue, resetButtonKey, requiresRestart, deleteButtonEnabled, insertInFront, LongListCell::new);
+        this.minimum = Long.MIN_VALUE;
         this.maximum = Long.MAX_VALUE;
-        for (long l : value)
-            cells.add(new LongListCell(l, this));
-        this.widgets.addAll(cells);
-        expanded = defaultExpanded;
-    }
-
-    public Function<Long, Optional<String>> getCellErrorSupplier() {
-        return cellErrorSupplier;
-    }
-
-    public void setCellErrorSupplier(Function<Long, Optional<String>> cellErrorSupplier) {
-        this.cellErrorSupplier = cellErrorSupplier;
     }
 
     @Override
@@ -71,62 +60,43 @@ public class LongListListEntry extends BaseListEntry<Long, LongListListEntry.Lon
         return new LongListCell(value, this);
     }
 
-    public static class LongListCell extends BaseListCell {
+    public static class LongListCell extends AbstractListListEntry.AbstractListCell<Long, LongListCell, LongListListEntry> {
 
-        private Function<String, String> stripCharacters = s -> {
-            StringBuilder stringBuilder_1 = new StringBuilder();
-            char[] var2 = s.toCharArray();
-            int var3 = var2.length;
+        private TextFieldWidget widget;
 
-            for (int var4 = 0; var4 < var3; ++var4)
-                if (Character.isDigit(var2[var4]) || var2[var4] == '-')
-                    stringBuilder_1.append(var2[var4]);
+        public LongListCell(Long value, LongListListEntry listListEntry) {
+            super(value, listListEntry);
 
-            return stringBuilder_1.toString();
-        };
-        private TextFieldWidget widget;
-        private boolean isSelected;
-        private LongListListEntry listListEntry;
-
-        public LongListCell(long value, LongListListEntry listListEntry) {
-            this.listListEntry = listListEntry;
-            this.setErrorSupplier(() -> listListEntry.cellErrorSupplier == null ? Optional.empty() : listListEntry.getCellErrorSupplier().apply(getValue()));
-            widget = new TextFieldWidget(MinecraftClient.getInstance().textRenderer, 0, 0, 100, 18, "") {
-                @Override
-                public void render(int int_1, int int_2, float float_1) {
-                    boolean f = isFocused();
-                    setFocused(isSelected);
-                    widget.setEditableColor(getPreferredTextColor());
-                    super.render(int_1, int_2, float_1);
-                    setFocused(f);
-                }
+            if (value == null)
+                value = 0L;
+            Long finalValue = value;
 
-                @Override
-                public void write(String string_1) {
-                    super.write(stripCharacters.apply(string_1));
-                }
-            };
-            widget.setMaxLength(999999);
+            this.setErrorSupplier(() -> Optional.ofNullable(listListEntry.cellErrorSupplier).flatMap(fn -> fn.apply(this.getValue())));
+            widget = new TextFieldWidget(MinecraftClient.getInstance().textRenderer, 0, 0, 100, 18, "");
+            widget.setTextPredicate(s -> s.chars().allMatch(c -> Character.isDigit(c) || c == '-'));
+            widget.setMaxLength(Integer.MAX_VALUE);
             widget.setHasBorder(false);
-            widget.setText(value + "");
+            widget.setText(value.toString());
             widget.setChangedListener(s -> {
-                if (!(value + "").equalsIgnoreCase(s))
-                    listListEntry.getScreen().setEdited(true, listListEntry.isRequiresRestart());
+                widget.setEditableColor(getPreferredTextColor());
+                if (!Objects.equals(s, finalValue.toString())) {
+                    this.listListEntry.getScreen().setEdited(true, this.listListEntry.isRequiresRestart());
+                }
             });
         }
 
-        public long getValue() {
+        public Long getValue() {
             try {
                 return Long.valueOf(widget.getText());
             } catch (NumberFormatException e) {
-                return 0;
+                return 0L;
             }
         }
 
         @Override
         public Optional<String> getError() {
             try {
-                long l = Long.valueOf(widget.getText());
+                long l = Long.parseLong(widget.getText());
                 if (l > listListEntry.maximum)
                     return Optional.of(I18n.translate("text.cloth-config.error.too_large", listListEntry.maximum));
                 else if (l < listListEntry.minimum)
@@ -148,7 +118,6 @@ public class LongListListEntry extends BaseListEntry<Long, LongListListEntry.Lon
             widget.x = x;
             widget.y = y + 1;
             widget.setEditable(listListEntry.isEditable());
-            this.isSelected = isSelected;
             widget.render(mouseX, mouseY, delta);
             if (isSelected && listListEntry.isEditable())
                 fill(x, y + 12, x + entryWidth - 12, y + 13, getConfigError().isPresent() ? 0xffff5555 : 0xffe0e0e0);

+ 24 - 36
src/main/java/me/shedaniel/clothconfig2/gui/entries/StringListListEntry.java

@@ -3,18 +3,18 @@ package me.shedaniel.clothconfig2.gui.entries;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.gui.widget.TextFieldWidget;
+import org.jetbrains.annotations.ApiStatus;
 
 import java.util.Collections;
 import java.util.List;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.function.Consumer;
-import java.util.function.Function;
 import java.util.function.Supplier;
 import java.util.stream.Collectors;
 
-public class StringListListEntry extends BaseListEntry<String, StringListListEntry.StringListCell, StringListListEntry> {
-
-    private Function<String, Optional<String>> cellErrorSupplier;
+@ApiStatus.Internal
+public class StringListListEntry extends AbstractListListEntry<String, StringListListEntry.StringListCell, StringListListEntry> {
 
     @Deprecated
     public StringListListEntry(String fieldName, List<String> value, boolean defaultExpanded, Supplier<Optional<String[]>> tooltipSupplier, Consumer<List<String>> saveConsumer, Supplier<List<String>> defaultValue, String resetButtonKey) {
@@ -27,19 +27,7 @@ public class StringListListEntry extends BaseListEntry<String, StringListListEnt
     }
 
     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) {
-        super(fieldName, tooltipSupplier, defaultValue, baseListEntry -> new StringListCell("", baseListEntry), saveConsumer, resetButtonKey, requiresRestart, deleteButtonEnabled, insertInFront);
-        for (String str : value)
-            cells.add(new StringListCell(str, this));
-        this.widgets.addAll(cells);
-        expanded = defaultExpanded;
-    }
-
-    public Function<String, Optional<String>> getCellErrorSupplier() {
-        return cellErrorSupplier;
-    }
-
-    public void setCellErrorSupplier(Function<String, Optional<String>> cellErrorSupplier) {
-        this.cellErrorSupplier = cellErrorSupplier;
+        super(fieldName, value, defaultExpanded, tooltipSupplier, saveConsumer, defaultValue, resetButtonKey, requiresRestart, deleteButtonEnabled, insertInFront, StringListCell::new);
     }
 
     @Override
@@ -57,34 +45,35 @@ public class StringListListEntry extends BaseListEntry<String, StringListListEnt
         return new StringListCell(value, this);
     }
 
-    public static class StringListCell extends BaseListCell {
+    public static class StringListCell extends AbstractListListEntry.AbstractListCell<String, StringListCell, StringListListEntry> {
 
         private TextFieldWidget widget;
-        private boolean isSelected;
-        private StringListListEntry listListEntry;
 
         public StringListCell(String value, StringListListEntry listListEntry) {
-            this.listListEntry = listListEntry;
-            this.setErrorSupplier(() -> listListEntry.cellErrorSupplier == null ? Optional.empty() : listListEntry.getCellErrorSupplier().apply(widget.getText()));
-            widget = new TextFieldWidget(MinecraftClient.getInstance().textRenderer, 0, 0, 100, 18, "") {
-                @Override
-                public void render(int int_1, int int_2, float float_1) {
-                    boolean f = isFocused();
-                    setFocused(isSelected);
-                    widget.setEditableColor(getPreferredTextColor());
-                    super.render(int_1, int_2, float_1);
-                    setFocused(f);
-                }
-            };
-            widget.setMaxLength(999999);
+            super(value, listListEntry);
+
+            if (value == null)
+                value = "";
+            String finalValue = value;
+
+            this.setErrorSupplier(() -> Optional.ofNullable(listListEntry.cellErrorSupplier).flatMap(fn -> fn.apply(this.getValue())));
+            widget = new TextFieldWidget(MinecraftClient.getInstance().textRenderer, 0, 0, 100, 18, "");
+            widget.setMaxLength(Integer.MAX_VALUE);
             widget.setHasBorder(false);
             widget.setText(value);
             widget.setChangedListener(s -> {
-                if (!value.contentEquals(s))
-                    listListEntry.getScreen().setEdited(true, listListEntry.isRequiresRestart());
+                widget.setEditableColor(getPreferredTextColor());
+                if (!Objects.equals(s, finalValue)) {
+                    this.listListEntry.getScreen().setEdited(true, this.listListEntry.isRequiresRestart());
+                }
             });
         }
 
+        @Override
+        public String getValue() {
+            return widget.getText();
+        }
+
         @Override
         public Optional<String> getError() {
             return Optional.empty();
@@ -101,7 +90,6 @@ public class StringListListEntry extends BaseListEntry<String, StringListListEnt
             widget.x = x;
             widget.y = y + 1;
             widget.setEditable(listListEntry.isEditable());
-            this.isSelected = isSelected;
             widget.render(mouseX, mouseY, delta);
             if (isSelected && listListEntry.isEditable())
                 fill(x, y + 12, x + entryWidth - 12, y + 13, getConfigError().isPresent() ? 0xffff5555 : 0xffe0e0e0);