Browse Source

New SelectorBuilder

Danielshe 5 years ago
parent
commit
17952072da

+ 1 - 1
README.md

@@ -22,7 +22,7 @@ There are multiple builtin option types:
 - Long -> LongListEntry (Text Field), LongSliderEntry (Slider)
 - Float -> FloatListEntry
 - Double -> DoubleListEntry
-- Enum -> EnumListEntry (Override enumNameProvider for custom names, or make the enum implement Translatable, or override `toString()` in the enum for names)
+- Enum -> EnumListEntry (Override nameProvider for custom names, or make the enum implement Translatable, or override `toString()` in the enum for names)
 - Text for Description -> TextListEntry
 
 And you can always build your own entry. Example of a boolean entry:

+ 2 - 2
gradle.properties

@@ -2,5 +2,5 @@ minecraft_version=19w41a
 yarn_version=19w41a+build.3
 fabric_loader_version=0.6.3+build.167
 fabric_version=0.4.4+build.248-1.15
-mod_version=2.0.1-unstable
-modmenu_version=1.7.6+build.115
+mod_version=2.0.2-unstable
+modmenu_version=1.7.14-unstable.19w41a+build.9

+ 8 - 8
src/main/java/me/shedaniel/clothconfig2/ClothConfigInitializer.java

@@ -25,7 +25,7 @@ public class ClothConfigInitializer implements ClientModInitializer {
     private static EasingMethod easingMethod = EasingMethodImpl.QUART;
     private static long scrollDuration = 1000;
     private static double scrollStep = 16;
-    private static double bounceBackMultiplier = .93;
+    private static double bounceBackMultiplier = .84;
     
     public static EasingMethod getEasingMethod() {
         return easingMethod;
@@ -50,7 +50,7 @@ public class ClothConfigInitializer implements ClientModInitializer {
             easingMethod = EasingMethodImpl.QUART;
             scrollDuration = 1000;
             scrollStep = 16;
-            bounceBackMultiplier = .93;
+            bounceBackMultiplier = .84;
             if (!file.exists()) {
                 saveConfig();
             }
@@ -65,13 +65,13 @@ public class ClothConfigInitializer implements ClientModInitializer {
             }
             scrollDuration = Long.parseLong(properties.getProperty("scrollDuration", "1000"));
             scrollStep = Double.parseDouble(properties.getProperty("scrollStep", "16"));
-            bounceBackMultiplier = Double.parseDouble(properties.getProperty("bounceBackMultiplier", "0.93"));
+            bounceBackMultiplier = Double.parseDouble(properties.getProperty("bounceBackMultiplier1", "0.84"));
         } catch (Exception e) {
             e.printStackTrace();
             easingMethod = EasingMethodImpl.QUART;
             scrollDuration = 1000;
             scrollStep = 16;
-            bounceBackMultiplier = .93;
+            bounceBackMultiplier = .84;
             try {
                 if (file.exists())
                     file.delete();
@@ -89,7 +89,7 @@ public class ClothConfigInitializer implements ClientModInitializer {
             properties.setProperty("easingMethod", easingMethod.toString());
             properties.setProperty("scrollDuration", scrollDuration + "");
             properties.setProperty("scrollStep", scrollStep + "");
-            properties.setProperty("bounceBackMultiplier", bounceBackMultiplier + "");
+            properties.setProperty("bounceBackMultiplier1", bounceBackMultiplier + "");
             properties.store(writer, null);
             writer.close();
         } catch (Exception e) {
@@ -97,7 +97,7 @@ public class ClothConfigInitializer implements ClientModInitializer {
             easingMethod = EasingMethodImpl.QUART;
             scrollDuration = 1000;
             scrollStep = 16;
-            bounceBackMultiplier = .93;
+            bounceBackMultiplier = .84;
         }
     }
     
@@ -114,12 +114,12 @@ public class ClothConfigInitializer implements ClientModInitializer {
                         builder.setDefaultBackgroundTexture(new Identifier("minecraft:textures/block/oak_planks.png"));
                         ConfigCategory scrolling = builder.getOrCreateCategory("Scrolling");
                         ConfigEntryBuilder entryBuilder = ConfigEntryBuilder.create();
-                        scrolling.addEntry(entryBuilder.startEnumSelector("Easing Method", EasingMethodImpl.class, easingMethod instanceof EasingMethodImpl ? (EasingMethodImpl) easingMethod : EasingMethodImpl.QUART).setDefaultValue(EasingMethodImpl.QUART).setSaveConsumer(o -> easingMethod = (EasingMethod) o).build());
+                        scrolling.addEntry(entryBuilder.startSelector("Easing Method", EasingMethods.getMethods().toArray(new EasingMethod[0]), easingMethod).setDefaultValue(EasingMethodImpl.QUART).setSaveConsumer(o -> easingMethod = (EasingMethod) o).build());
                         scrolling.addEntry(entryBuilder.startLongSlider("Scroll Duration", scrollDuration, 0, 5000).setTextGetter(integer -> {
                             return integer <= 0 ? "Value: Disabled" : (integer > 1500 ? String.format("Value: %.1fs", integer / 1000f) : "Value: " + integer + "ms");
                         }).setDefaultValue(1000).setSaveConsumer(i -> scrollDuration = i).build());
                         scrolling.addEntry(entryBuilder.startDoubleField("Scroll Step", scrollStep).setDefaultValue(16).setSaveConsumer(i -> scrollStep = i).build());
-                        scrolling.addEntry(entryBuilder.startDoubleField("Bounce Multiplier", bounceBackMultiplier).setDefaultValue(0.93).setSaveConsumer(i -> bounceBackMultiplier = i).build());
+                        scrolling.addEntry(entryBuilder.startDoubleField("Bounce Multiplier", bounceBackMultiplier).setDefaultValue(0.84).setSaveConsumer(i -> bounceBackMultiplier = i).build());
                         builder.setSavingRunnable(() -> {
                             saveConfig();
                         });

+ 5 - 1
src/main/java/me/shedaniel/clothconfig2/api/ConfigEntryBuilder.java

@@ -1,5 +1,7 @@
 package me.shedaniel.clothconfig2.api;
 
+import com.sun.istack.internal.NotNull;
+import com.sun.istack.internal.Nullable;
 import me.shedaniel.clothconfig2.impl.ConfigEntryBuilderImpl;
 import me.shedaniel.clothconfig2.impl.builders.*;
 
@@ -37,7 +39,9 @@ public interface ConfigEntryBuilder {
     
     TextDescriptionBuilder startTextDescription(String value);
     
-    <T extends Enum<?>> EnumSelectorBuilder<T> startEnumSelector(String fieldNameKey, Class<T> clazz, T value);
+    <T extends Enum<?>> EnumSelectorBuilder<T> startEnumSelector(String fieldNameKey, Class<T> clazz, @NotNull T value);
+    
+    <T> SelectorBuilder<T> startSelector(String fieldNameKey, @Nullable T[] valuesArray, @NotNull T value);
     
     IntFieldBuilder startIntField(String fieldNameKey, int value);
     

+ 6 - 94
src/main/java/me/shedaniel/clothconfig2/gui/entries/EnumListEntry.java

@@ -1,127 +1,39 @@
 package me.shedaniel.clothconfig2.gui.entries;
 
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-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.Window;
 
-import java.util.List;
 import java.util.Optional;
-import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Consumer;
 import java.util.function.Function;
 import java.util.function.Supplier;
 
-public class EnumListEntry<T extends Enum<?>> extends TooltipListEntry<T> {
+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());
-    private ImmutableList<T> values;
-    private AtomicInteger index;
-    private ButtonWidget buttonWidget, resetButton;
-    private Consumer<T> saveConsumer;
-    private Supplier<T> defaultValue;
-    private List<Element> widgets;
-    private Function<Enum, String> enumNameProvider;
     
     @Deprecated
     public EnumListEntry(String fieldName, Class<T> clazz, T value, Consumer<T> saveConsumer) {
-        this(fieldName, clazz, value, "text.cloth-config.reset_value", null, saveConsumer);
+        super(fieldName, clazz.getEnumConstants(), value, "text.cloth-config.reset_value", null, saveConsumer);
     }
     
     @Deprecated
     public EnumListEntry(String fieldName, Class<T> clazz, T value, String resetButtonKey, Supplier<T> defaultValue, Consumer<T> saveConsumer) {
-        this(fieldName, clazz, value, resetButtonKey, defaultValue, saveConsumer, DEFAULT_NAME_PROVIDER);
+        super(fieldName, clazz.getEnumConstants(), value, resetButtonKey, defaultValue, saveConsumer, v -> DEFAULT_NAME_PROVIDER.apply(v));
     }
     
     @Deprecated
     public EnumListEntry(String fieldName, Class<T> clazz, T value, String resetButtonKey, Supplier<T> defaultValue, Consumer<T> saveConsumer, Function<Enum, String> enumNameProvider) {
-        this(fieldName, clazz, value, resetButtonKey, defaultValue, saveConsumer, enumNameProvider, null);
+        super(fieldName, clazz.getEnumConstants(), value, resetButtonKey, defaultValue, saveConsumer, v -> enumNameProvider.apply(v), null);
     }
     
     @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) {
-        this(fieldName, clazz, value, resetButtonKey, defaultValue, saveConsumer, enumNameProvider, tooltipSupplier, false);
+        super(fieldName, clazz.getEnumConstants(), value, resetButtonKey, defaultValue, saveConsumer, v -> enumNameProvider.apply(v), tooltipSupplier, false);
     }
     
     @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) {
-        super(fieldName, tooltipSupplier, requiresRestart);
-        T[] valuesArray = clazz.getEnumConstants();
-        if (valuesArray != null)
-            this.values = ImmutableList.copyOf(valuesArray);
-        else
-            this.values = ImmutableList.of(value);
-        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 -> {
-            EnumListEntry.this.index.incrementAndGet();
-            EnumListEntry.this.index.compareAndSet(EnumListEntry.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 -> {
-            EnumListEntry.this.index.set(getDefaultIndex());
-            getScreen().setEdited(true, isRequiresRestart());
-        });
-        this.saveConsumer = saveConsumer;
-        this.widgets = Lists.newArrayList(buttonWidget, resetButton);
-        this.enumNameProvider = enumNameProvider;
-    }
-    
-    @Override
-    public void save() {
-        if (saveConsumer != null)
-            saveConsumer.accept(getValue());
-    }
-    
-    @Override
-    public T getValue() {
-        return this.values.get(this.index.get());
-    }
-    
-    @Override
-    public Optional<T> getDefaultValue() {
-        return defaultValue == null ? Optional.empty() : Optional.ofNullable(defaultValue.get());
-    }
-    
-    @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);
-        Window window = MinecraftClient.getInstance().getWindow();
-        this.resetButton.active = isEditable() && getDefaultValue().isPresent() && getDefaultIndex() != this.index.get();
-        this.resetButton.y = y;
-        this.buttonWidget.active = isEditable();
-        this.buttonWidget.y = y;
-        this.buttonWidget.setMessage(enumNameProvider.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());
-            this.resetButton.x = x;
-            this.buttonWidget.x = x + resetButton.getWidth() + 2;
-            this.buttonWidget.setWidth(150 - resetButton.getWidth() - 2);
-        } else {
-            MinecraftClient.getInstance().textRenderer.drawWithShadow(I18n.translate(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);
-    }
-    
-    private int getDefaultIndex() {
-        return Math.max(0, this.values.indexOf(this.defaultValue.get()));
-    }
-    
-    @Override
-    public List<? extends Element> children() {
-        return widgets;
-    }
-    
-    public static interface Translatable {
-        String getKey();
+        super(fieldName, clazz.getEnumConstants(), value, resetButtonKey, defaultValue, saveConsumer, v -> enumNameProvider.apply(v), tooltipSupplier, requiresRestart);
     }
     
 }

+ 129 - 0
src/main/java/me/shedaniel/clothconfig2/gui/entries/SelectionListEntry.java

@@ -0,0 +1,129 @@
+package me.shedaniel.clothconfig2.gui.entries;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.sun.istack.internal.Nullable;
+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.Window;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+public class SelectionListEntry<T> extends TooltipListEntry<T> {
+    
+    private ImmutableList<T> values;
+    private AtomicInteger index;
+    private ButtonWidget buttonWidget, resetButton;
+    private Consumer<T> saveConsumer;
+    private Supplier<T> defaultValue;
+    private List<Element> widgets;
+    private Function<T, String> nameProvider;
+    
+    @Deprecated
+    public SelectionListEntry(String fieldName, T[] valuesArray, T value, Consumer<T> saveConsumer) {
+        this(fieldName, valuesArray, value, "text.cloth-config.reset_value", null, saveConsumer);
+    }
+    
+    @Deprecated
+    public SelectionListEntry(String fieldName, T[] valuesArray, T value, String resetButtonKey, Supplier<T> defaultValue, Consumer<T> saveConsumer) {
+        this(fieldName, valuesArray, value, resetButtonKey, defaultValue, saveConsumer, null);
+    }
+    
+    @Deprecated
+    public SelectionListEntry(String fieldName, T[] valuesArray, T value, String resetButtonKey, Supplier<T> defaultValue, Consumer<T> saveConsumer,
+            @Nullable Function<T, String> nameProvider) {
+        this(fieldName, valuesArray, value, resetButtonKey, defaultValue, saveConsumer, nameProvider, null);
+    }
+    
+    @Deprecated
+    public SelectionListEntry(String fieldName, T[] valuesArray, T value, String resetButtonKey, Supplier<T> defaultValue, Consumer<T> saveConsumer,
+            @Nullable Function<T, String> nameProvider, Supplier<Optional<String[]>> tooltipSupplier) {
+        this(fieldName, valuesArray, value, resetButtonKey, defaultValue, saveConsumer, nameProvider, tooltipSupplier, false);
+    }
+    
+    @Deprecated
+    public SelectionListEntry(String fieldName, T[] valuesArray, T value, String resetButtonKey, Supplier<T> defaultValue, Consumer<T> saveConsumer,
+            @Nullable Function<T, String> nameProvider, Supplier<Optional<String[]>> tooltipSupplier, boolean requiresRestart) {
+        super(fieldName, tooltipSupplier, requiresRestart);
+        if (valuesArray != null)
+            this.values = ImmutableList.copyOf(valuesArray);
+        else
+            this.values = ImmutableList.of(value);
+        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 -> {
+            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 -> {
+            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;
+    }
+    
+    @Override
+    public void save() {
+        if (saveConsumer != null)
+            saveConsumer.accept(getValue());
+    }
+    
+    @Override
+    public T getValue() {
+        return this.values.get(this.index.get());
+    }
+    
+    @Override
+    public Optional<T> getDefaultValue() {
+        return defaultValue == null ? Optional.empty() : Optional.ofNullable(defaultValue.get());
+    }
+    
+    @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);
+        Window window = MinecraftClient.getInstance().getWindow();
+        this.resetButton.active = isEditable() && getDefaultValue().isPresent() && getDefaultIndex() != this.index.get();
+        this.resetButton.y = y;
+        this.buttonWidget.active = isEditable();
+        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());
+            this.resetButton.x = x;
+            this.buttonWidget.x = x + resetButton.getWidth() + 2;
+            this.buttonWidget.setWidth(150 - resetButton.getWidth() - 2);
+        } else {
+            MinecraftClient.getInstance().textRenderer.drawWithShadow(I18n.translate(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);
+    }
+    
+    private int getDefaultIndex() {
+        return Math.max(0, this.values.indexOf(this.defaultValue.get()));
+    }
+    
+    @Override
+    public List<? extends Element> children() {
+        return widgets;
+    }
+    
+    public static interface Translatable {
+        String getKey();
+    }
+    
+}

+ 9 - 1
src/main/java/me/shedaniel/clothconfig2/impl/ConfigEntryBuilderImpl.java

@@ -1,5 +1,7 @@
 package me.shedaniel.clothconfig2.impl;
 
+import com.sun.istack.internal.NotNull;
+import com.sun.istack.internal.Nullable;
 import me.shedaniel.clothconfig2.api.AbstractConfigListEntry;
 import me.shedaniel.clothconfig2.api.ConfigEntryBuilder;
 import me.shedaniel.clothconfig2.impl.builders.*;
@@ -96,10 +98,16 @@ public class ConfigEntryBuilderImpl implements ConfigEntryBuilder {
     }
     
     @Override
-    public <T extends Enum<?>> EnumSelectorBuilder<T> startEnumSelector(String fieldNameKey, Class<T> clazz, T value) {
+    public <T extends Enum<?>> EnumSelectorBuilder<T> startEnumSelector(String fieldNameKey, Class<T> clazz,
+            @NotNull T value) {
         return new EnumSelectorBuilder<T>(resetButtonKey, fieldNameKey, clazz, value);
     }
     
+    @Override
+    public <T> SelectorBuilder<T> startSelector(String fieldNameKey, @Nullable T[] valuesArray, T value) {
+        return new SelectorBuilder<T>(resetButtonKey, fieldNameKey, valuesArray, value);
+    }
+    
     @Override
     public IntFieldBuilder startIntField(String fieldNameKey, int value) {
         return new IntFieldBuilder(resetButtonKey, fieldNameKey, value);

+ 88 - 0
src/main/java/me/shedaniel/clothconfig2/impl/builders/SelectorBuilder.java

@@ -0,0 +1,88 @@
+package me.shedaniel.clothconfig2.impl.builders;
+
+import com.sun.istack.internal.NotNull;
+import com.sun.istack.internal.Nullable;
+import me.shedaniel.clothconfig2.gui.entries.SelectionListEntry;
+
+import java.util.Objects;
+import java.util.Optional;
+import java.util.function.Consumer;
+import java.util.function.Function;
+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 T value;
+    private T[] valuesArray;
+    @Nullable private Function<T, String> nameProvider = null;
+    
+    public SelectorBuilder(String resetButtonKey, String fieldNameKey, @Nullable T[] valuesArray, @NotNull T value) {
+        super(resetButtonKey, fieldNameKey);
+        Objects.requireNonNull(value);
+        this.valuesArray = valuesArray;
+        this.value = value;
+    }
+    
+    public SelectorBuilder<T> setErrorSupplier(Function<T, Optional<String>> errorSupplier) {
+        this.errorSupplier = errorSupplier;
+        return this;
+    }
+    
+    public SelectorBuilder<T> requireRestart() {
+        requireRestart(true);
+        return this;
+    }
+    
+    public SelectorBuilder setSaveConsumer(Consumer<T> saveConsumer) {
+        this.saveConsumer = saveConsumer;
+        return this;
+    }
+    
+    public SelectorBuilder setDefaultValue(Supplier<T> defaultValue) {
+        this.defaultValue = defaultValue;
+        return this;
+    }
+    
+    public SelectorBuilder setDefaultValue(T defaultValue) {
+        Objects.requireNonNull(defaultValue);
+        this.defaultValue = () -> defaultValue;
+        return this;
+    }
+    
+    public SelectorBuilder setTooltipSupplier(Function<T, Optional<String[]>> tooltipSupplier) {
+        this.tooltipSupplier = tooltipSupplier;
+        return this;
+    }
+    
+    public SelectorBuilder setTooltipSupplier(Supplier<Optional<String[]>> tooltipSupplier) {
+        this.tooltipSupplier = e -> tooltipSupplier.get();
+        return this;
+    }
+    
+    public SelectorBuilder setTooltip(Optional<String[]> tooltip) {
+        this.tooltipSupplier = e -> tooltip;
+        return this;
+    }
+    
+    public SelectorBuilder setTooltip(String... tooltip) {
+        this.tooltipSupplier = e -> Optional.ofNullable(tooltip);
+        return this;
+    }
+    
+    public SelectorBuilder setNameProvider(@Nullable Function<T, String> enumNameProvider) {
+        this.nameProvider = enumNameProvider;
+        return this;
+    }
+    
+    @Override
+    public SelectionListEntry<T> build() {
+        SelectionListEntry<T> entry = new SelectionListEntry<>(getFieldNameKey(), valuesArray, value, getResetButtonKey(), defaultValue, saveConsumer, nameProvider, null, isRequireRestart());
+        entry.setTooltipSupplier(() -> tooltipSupplier.apply(entry.getValue()));
+        if (errorSupplier != null)
+            entry.setErrorSupplier(() -> errorSupplier.apply(entry.getValue()));
+        return entry;
+    }
+    
+}