shedaniel пре 5 година
родитељ
комит
275739c5a5

+ 1 - 1
gradle.properties

@@ -2,6 +2,6 @@ minecraft_version=1.15
 yarn_version=1.15+build.1
 yarn_version=1.15+build.1
 fabric_loader_version=0.7.2+build.174
 fabric_loader_version=0.7.2+build.174
 fabric_version=0.4.20+build.273-1.15
 fabric_version=0.4.20+build.273-1.15
-mod_version=2.6.6
+mod_version=2.7
 modmenu_version=1.7.14-unstable.19w42a+build.10
 modmenu_version=1.7.14-unstable.19w42a+build.10
 nec_version=1.1.5+1.15.1
 nec_version=1.1.5+1.15.1

+ 156 - 11
src/main/java/me/shedaniel/clothconfig2/ClothConfigInitializer.java

@@ -1,6 +1,12 @@
 package me.shedaniel.clothconfig2;
 package me.shedaniel.clothconfig2;
 
 
+import com.google.common.collect.ImmutableList;
 import me.shedaniel.clothconfig2.api.*;
 import me.shedaniel.clothconfig2.api.*;
+import me.shedaniel.clothconfig2.gui.entries.DoubleListEntry;
+import me.shedaniel.clothconfig2.gui.entries.DropdownBoxEntry;
+import me.shedaniel.clothconfig2.gui.entries.LongSliderEntry;
+import me.shedaniel.clothconfig2.gui.entries.TooltipListEntry;
+import me.shedaniel.clothconfig2.gui.widget.DynamicEntryListWidget;
 import me.shedaniel.clothconfig2.impl.EasingMethod;
 import me.shedaniel.clothconfig2.impl.EasingMethod;
 import me.shedaniel.clothconfig2.impl.EasingMethod.EasingMethodImpl;
 import me.shedaniel.clothconfig2.impl.EasingMethod.EasingMethodImpl;
 import me.shedaniel.clothconfig2.impl.EasingMethods;
 import me.shedaniel.clothconfig2.impl.EasingMethods;
@@ -8,10 +14,16 @@ import me.shedaniel.clothconfig2.impl.builders.DropdownMenuBuilder;
 import net.fabricmc.api.ClientModInitializer;
 import net.fabricmc.api.ClientModInitializer;
 import net.fabricmc.loader.api.FabricLoader;
 import net.fabricmc.loader.api.FabricLoader;
 import net.minecraft.client.MinecraftClient;
 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.InputUtil;
+import net.minecraft.client.util.Window;
 import net.minecraft.item.Item;
 import net.minecraft.item.Item;
 import net.minecraft.item.Items;
 import net.minecraft.item.Items;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.Identifier;
+import net.minecraft.util.math.MathHelper;
 import net.minecraft.util.registry.Registry;
 import net.minecraft.util.registry.Registry;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.Logger;
@@ -21,9 +33,7 @@ import java.io.FileInputStream;
 import java.io.FileWriter;
 import java.io.FileWriter;
 import java.lang.reflect.Method;
 import java.lang.reflect.Method;
 import java.nio.file.Files;
 import java.nio.file.Files;
-import java.util.Comparator;
-import java.util.LinkedHashSet;
-import java.util.Properties;
+import java.util.*;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
 
 
 @SuppressWarnings("unchecked")
 @SuppressWarnings("unchecked")
@@ -35,6 +45,47 @@ public class ClothConfigInitializer implements ClientModInitializer {
     private static double scrollStep = 19;
     private static double scrollStep = 19;
     private static double bounceBackMultiplier = .24;
     private static double bounceBackMultiplier = .24;
     
     
+    public static double handleScrollingPosition(double[] target, double scroll, double maxScroll, float delta, double start, double duration) {
+        if (getBounceBackMultiplier() >= 0) {
+            target[0] = clamp(target[0], maxScroll);
+            if (target[0] < 0) {
+                target[0] -= target[0] * (1 - getBounceBackMultiplier()) * delta / 3;
+            } else if (target[0] > maxScroll) {
+                target[0] = (target[0] - maxScroll) * (1 - (1 - getBounceBackMultiplier()) * delta / 3) + maxScroll;
+            }
+        } else
+            target[0] = clamp(target[0], maxScroll, 0);
+        if (!Precision.almostEquals(scroll, target[0], Precision.FLOAT_EPSILON))
+            return expoEase(scroll, target[0], Math.min((System.currentTimeMillis() - start) / duration, 1));
+        else
+            return target[0];
+    }
+    
+    public static double expoEase(double start, double end, double amount) {
+        return start + (end - start) * getEasingMethod().apply(amount);
+    }
+    
+    public static class Precision {
+        public static final float FLOAT_EPSILON = 1e-3f;
+        public static final double DOUBLE_EPSILON = 1e-7;
+        
+        public static boolean almostEquals(float value1, float value2, float acceptableDifference) {
+            return Math.abs(value1 - value2) <= acceptableDifference;
+        }
+        
+        public static boolean almostEquals(double value1, double value2, double acceptableDifference) {
+            return Math.abs(value1 - value2) <= acceptableDifference;
+        }
+    }
+    
+    public static double clamp(double v, double maxScroll) {
+        return clamp(v, maxScroll, DynamicEntryListWidget.SmoothScrollingSettings.CLAMP_EXTENSION);
+    }
+    
+    public static double clamp(double v, double maxScroll, double clampExtension) {
+        return MathHelper.clamp(v, -clampExtension, maxScroll + clampExtension);
+    }
+    
     public static EasingMethod getEasingMethod() {
     public static EasingMethod getEasingMethod() {
         return easingMethod;
         return easingMethod;
     }
     }
@@ -117,20 +168,114 @@ public class ClothConfigInitializer implements ClientModInitializer {
                 Method method = clazz.getMethod("addConfigOverride", String.class, Runnable.class);
                 Method method = clazz.getMethod("addConfigOverride", String.class, Runnable.class);
                 method.invoke(null, "cloth-config2", (Runnable) () -> {
                 method.invoke(null, "cloth-config2", (Runnable) () -> {
                     try {
                     try {
-                        ConfigBuilder builder = ConfigBuilder.create().setParentScreen(MinecraftClient.getInstance().currentScreen).setTitle("Cloth Mod Config Config");
+                        ConfigBuilder builder = ConfigBuilder.create().setParentScreen(MinecraftClient.getInstance().currentScreen).setTitle("title.cloth-config.config");
                         builder.setDefaultBackgroundTexture(new Identifier("minecraft:textures/block/oak_planks.png"));
                         builder.setDefaultBackgroundTexture(new Identifier("minecraft:textures/block/oak_planks.png"));
-                        ConfigCategory scrolling = builder.getOrCreateCategory("Scrolling");
+                        ConfigCategory scrolling = builder.getOrCreateCategory("category.cloth-config.scrolling");
                         ConfigEntryBuilder entryBuilder = ConfigEntryBuilder.create();
                         ConfigEntryBuilder entryBuilder = ConfigEntryBuilder.create();
-                        scrolling.addEntry(entryBuilder.startDropdownMenu("Easing Method", DropdownMenuBuilder.TopCellElementBuilder.of(easingMethod, str -> {
+                        DropdownBoxEntry<EasingMethod> easingMethodEntry = entryBuilder.startDropdownMenu("Easing Method", DropdownMenuBuilder.TopCellElementBuilder.of(easingMethod, str -> {
                             for (EasingMethod m : EasingMethods.getMethods())
                             for (EasingMethod m : EasingMethods.getMethods())
                                 if (m.toString().equals(str))
                                 if (m.toString().equals(str))
                                     return m;
                                     return m;
                             return null;
                             return null;
-                        })).setDefaultValue(EasingMethodImpl.LINEAR).setSaveConsumer(o -> easingMethod = (EasingMethod) o).setSelections(EasingMethods.getMethods()).build());
-                        scrolling.addEntry(entryBuilder.startLongSlider("Scroll Duration", 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());
-                        scrolling.addEntry(entryBuilder.startDoubleField("Scroll Step", scrollStep).setDefaultValue(19).setSaveConsumer(i -> scrollStep = i).build());
-                        scrolling.addEntry(entryBuilder.startDoubleField("Bounce Multiplier", bounceBackMultiplier).setDefaultValue(0.24).setSaveConsumer(i -> bounceBackMultiplier = i).build());
-                        ConfigCategory testing = builder.getOrCreateCategory("Testing");
+                        })).setDefaultValue(EasingMethodImpl.LINEAR).setSaveConsumer(o -> easingMethod = (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();
+                        
+                        scrolling.addEntry(new TooltipListEntry<Object>(I18n.translate("option.cloth-config.setDefaultSmoothScroll"), null) {
+                            int width = 220;
+                            private AbstractButtonWidget buttonWidget = new AbstractPressableButtonWidget(0, 0, 0, 20, getFieldName()) {
+                                @Override
+                                public void onPress() {
+                                    easingMethodEntry.getSelectionElement().getTopRenderer().setValue(EasingMethodImpl.LINEAR);
+                                    scrollDurationEntry.setValue(600);
+                                    scrollStepEntry.setValue("19.0");
+                                    bounceMultiplierEntry.setValue(240);
+                                    getScreen().setEdited(true, isRequiresRestart());
+                                }
+                            };
+                            private List<AbstractButtonWidget> children = ImmutableList.of(buttonWidget);
+                            
+                            @Override
+                            public Object getValue() {
+                                return null;
+                            }
+                            
+                            @Override
+                            public Optional<Object> getDefaultValue() {
+                                return Optional.empty();
+                            }
+                            
+                            @Override
+                            public void save() {
+                            }
+                            
+                            @Override
+                            public List<? extends Element> children() {
+                                return children;
+                            }
+                            
+                            @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.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);
+                            }
+                        });
+                        
+                        scrolling.addEntry(new TooltipListEntry<Object>(I18n.translate("option.cloth-config.disableSmoothScroll"), null) {
+                            int width = 220;
+                            private AbstractButtonWidget buttonWidget = new AbstractPressableButtonWidget(0, 0, 0, 20, getFieldName()) {
+                                @Override
+                                public void onPress() {
+                                    easingMethodEntry.getSelectionElement().getTopRenderer().setValue(EasingMethodImpl.NONE);
+                                    scrollDurationEntry.setValue(0);
+                                    scrollStepEntry.setValue("16.0");
+                                    bounceMultiplierEntry.setValue(-10);
+                                    getScreen().setEdited(true, isRequiresRestart());
+                                }
+                            };
+                            private List<AbstractButtonWidget> children = ImmutableList.of(buttonWidget);
+                            
+                            @Override
+                            public Object getValue() {
+                                return null;
+                            }
+                            
+                            @Override
+                            public Optional<Object> getDefaultValue() {
+                                return Optional.empty();
+                            }
+                            
+                            @Override
+                            public void save() {
+                            }
+                            
+                            @Override
+                            public List<? extends Element> children() {
+                                return children;
+                            }
+                            
+                            @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.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);
+                            }
+                        });
+                        scrolling.addEntry(easingMethodEntry);
+                        scrolling.addEntry(scrollDurationEntry);
+                        scrolling.addEntry(scrollStepEntry);
+                        scrolling.addEntry(bounceMultiplierEntry);
+                        ConfigCategory testing = builder.getOrCreateCategory("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.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.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.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());

+ 11 - 1
src/main/java/me/shedaniel/clothconfig2/gui/entries/DropdownBoxEntry.java

@@ -89,6 +89,11 @@ public class DropdownBoxEntry<T> extends TooltipListEntry<T> {
         return selectionElement.getValue();
         return selectionElement.getValue();
     }
     }
     
     
+    @Deprecated
+    public SelectionElement<T> getSelectionElement() {
+        return selectionElement;
+    }
+    
     @Override
     @Override
     public Optional<T> getDefaultValue() {
     public Optional<T> getDefaultValue() {
         return defaultValue == null ? Optional.empty() : Optional.ofNullable(defaultValue.get());
         return defaultValue == null ? Optional.empty() : Optional.ofNullable(defaultValue.get());
@@ -152,7 +157,12 @@ public class DropdownBoxEntry<T> extends TooltipListEntry<T> {
             if (menu.isExpended())
             if (menu.isExpended())
                 menu.render(mouseX, mouseY, bounds, delta);
                 menu.render(mouseX, mouseY, bounds, delta);
         }
         }
-        
+    
+        @Deprecated
+        public SelectionTopCellElement<R> getTopRenderer() {
+            return topRenderer;
+        }
+    
         @Override
         @Override
         public boolean mouseScrolled(double double_1, double double_2, double double_3) {
         public boolean mouseScrolled(double double_1, double double_2, double double_3) {
             if (menu.isExpended())
             if (menu.isExpended())

+ 8 - 3
src/main/java/me/shedaniel/clothconfig2/gui/entries/LongSliderEntry.java

@@ -52,9 +52,7 @@ public class LongSliderEntry extends TooltipListEntry<Long> {
         this.minimum = minimum;
         this.minimum = minimum;
         this.sliderWidget = new Slider(0, 0, 152, 20, ((double) LongSliderEntry.this.value.get() - minimum) / Math.abs(maximum - 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.getStringWidth(I18n.translate(resetButtonKey)) + 6, 20, I18n.translate(resetButtonKey), widget -> {
-            sliderWidget.setValue((MathHelper.clamp(this.defaultValue.get(), minimum, maximum) - minimum) / (double) Math.abs(maximum - minimum));
-            this.value.set(Math.min(Math.max(this.defaultValue.get(), minimum), maximum));
-            sliderWidget.updateMessage();
+            setValue(defaultValue.get());
             getScreen().setEdited(true, isRequiresRestart());
             getScreen().setEdited(true, isRequiresRestart());
         });
         });
         this.sliderWidget.setMessage(textGetter.apply(LongSliderEntry.this.value.get()));
         this.sliderWidget.setMessage(textGetter.apply(LongSliderEntry.this.value.get()));
@@ -82,6 +80,13 @@ public class LongSliderEntry extends TooltipListEntry<Long> {
         return value.get();
         return value.get();
     }
     }
     
     
+    @Deprecated
+    public void setValue(long value) {
+        sliderWidget.setValue((MathHelper.clamp(value, minimum, maximum) - minimum) / (double) Math.abs(maximum - minimum));
+        this.value.set(Math.min(Math.max(value, minimum), maximum));
+        sliderWidget.updateMessage();
+    }
+    
     @Override
     @Override
     public Optional<Long> getDefaultValue() {
     public Optional<Long> getDefaultValue() {
         return defaultValue == null ? Optional.empty() : Optional.ofNullable(defaultValue.get());
         return defaultValue == null ? Optional.empty() : Optional.ofNullable(defaultValue.get());

+ 5 - 0
src/main/java/me/shedaniel/clothconfig2/gui/entries/TextFieldListEntry.java

@@ -60,6 +60,11 @@ public abstract class TextFieldListEntry<T> extends TooltipListEntry<T> {
         this.widgets = Lists.newArrayList(textFieldWidget, resetButton);
         this.widgets = Lists.newArrayList(textFieldWidget, resetButton);
     }
     }
     
     
+    @Deprecated
+    public void setValue(String s) {
+        textFieldWidget.setText(String.valueOf(s));
+    }
+    
     protected static void setTextFieldWidth(TextFieldWidget widget, int width) {
     protected static void setTextFieldWidth(TextFieldWidget widget, int width) {
         widget.setWidth(width);
         widget.setWidth(width);
     }
     }

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

@@ -10,6 +10,9 @@ import net.minecraft.client.render.VertexFormats;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.math.MathHelper;
 import net.minecraft.util.math.MathHelper;
 
 
+import static me.shedaniel.clothconfig2.ClothConfigInitializer.clamp;
+import static me.shedaniel.clothconfig2.ClothConfigInitializer.handleScrollingPosition;
+
 public abstract class DynamicNewSmoothScrollingEntryListWidget<E extends DynamicEntryListWidget.Entry<E>> extends DynamicEntryListWidget<E> {
 public abstract class DynamicNewSmoothScrollingEntryListWidget<E extends DynamicEntryListWidget.Entry<E>> extends DynamicEntryListWidget<E> {
     
     
     protected double target;
     protected double target;
@@ -21,14 +24,6 @@ public abstract class DynamicNewSmoothScrollingEntryListWidget<E extends Dynamic
         super(client, width, height, top, bottom, backgroundLocation);
         super(client, width, height, top, bottom, backgroundLocation);
     }
     }
     
     
-    public final double clamp(double v) {
-        return clamp(v, SmoothScrollingSettings.CLAMP_EXTENSION);
-    }
-    
-    public final double clamp(double v, double clampExtension) {
-        return MathHelper.clamp(v, -clampExtension, getMaxScroll() + clampExtension);
-    }
-    
     public boolean isSmoothScrolling() {
     public boolean isSmoothScrolling() {
         return smoothScrolling;
         return smoothScrolling;
     }
     }
@@ -40,10 +35,10 @@ public abstract class DynamicNewSmoothScrollingEntryListWidget<E extends Dynamic
     @Override
     @Override
     public void capYPosition(double double_1) {
     public void capYPosition(double double_1) {
         if (!smoothScrolling)
         if (!smoothScrolling)
-            this.scroll = MathHelper.clamp(double_1, 0.0D, (double) this.getMaxScroll());
+            this.scroll = MathHelper.clamp(double_1, 0.0D, this.getMaxScroll());
         else {
         else {
-            scroll = clamp(double_1);
-            target = clamp(double_1);
+            scroll = clamp(double_1, getMaxScroll());
+            target = clamp(double_1, getMaxScroll());
         }
         }
     }
     }
     
     
@@ -51,15 +46,15 @@ public abstract class DynamicNewSmoothScrollingEntryListWidget<E extends Dynamic
     public boolean mouseDragged(double double_1, double double_2, int int_1, double double_3, double double_4) {
     public boolean mouseDragged(double double_1, double double_2, int int_1, double double_3, double double_4) {
         if (!smoothScrolling)
         if (!smoothScrolling)
             return super.mouseDragged(double_1, double_2, int_1, double_3, double_4);
             return super.mouseDragged(double_1, double_2, int_1, double_3, double_4);
-        if (this.getFocused() != null && this.isDragging() && int_1 == 0 ? this.getFocused().mouseDragged(double_1, double_2, int_1, double_3, double_4) : false) {
+        if ((this.getFocused() != null && this.isDragging() && int_1 == 0) && this.getFocused().mouseDragged(double_1, double_2, int_1, double_3, double_4)) {
             return true;
             return true;
         } else if (int_1 == 0 && this.scrolling) {
         } else if (int_1 == 0 && this.scrolling) {
             if (double_2 < (double) this.top) {
             if (double_2 < (double) this.top) {
                 this.capYPosition(0.0D);
                 this.capYPosition(0.0D);
             } else if (double_2 > (double) this.bottom) {
             } else if (double_2 > (double) this.bottom) {
-                this.capYPosition((double) this.getMaxScroll());
+                this.capYPosition(this.getMaxScroll());
             } else {
             } else {
-                double double_5 = (double) Math.max(1, this.getMaxScroll());
+                double double_5 = Math.max(1, this.getMaxScroll());
                 int int_2 = this.bottom - this.top;
                 int int_2 = this.bottom - this.top;
                 int int_3 = MathHelper.clamp((int) ((float) (int_2 * int_2) / (float) this.getMaxScrollPosition()), 32, int_2 - 8);
                 int int_3 = MathHelper.clamp((int) ((float) (int_2 * int_2) / (float) this.getMaxScrollPosition()), 32, int_2 - 8);
                 double double_6 = Math.max(1.0D, double_5 / (double) (int_2 - int_3));
                 double double_6 = Math.max(1.0D, double_5 / (double) (int_2 - int_3));
@@ -72,14 +67,14 @@ public abstract class DynamicNewSmoothScrollingEntryListWidget<E extends Dynamic
     
     
     @Override
     @Override
     public boolean mouseScrolled(double double_1, double double_2, double double_3) {
     public boolean mouseScrolled(double double_1, double double_2, double double_3) {
-        for(E entry : children()) {
+        for (E entry : children()) {
             if (entry.mouseScrolled(double_1, double_2, double_3)) {
             if (entry.mouseScrolled(double_1, double_2, double_3)) {
                 return true;
                 return true;
             }
             }
         }
         }
         if (!smoothScrolling) {
         if (!smoothScrolling) {
             scroll += 16 * -double_3;
             scroll += 16 * -double_3;
-            this.scroll = MathHelper.clamp(double_3, 0.0D, (double) this.getMaxScroll());
+            this.scroll = MathHelper.clamp(double_3, 0.0D, this.getMaxScroll());
             return true;
             return true;
         }
         }
         offset(ClothConfigInitializer.getScrollStep() * -double_3, true);
         offset(ClothConfigInitializer.getScrollStep() * -double_3, true);
@@ -95,7 +90,7 @@ public abstract class DynamicNewSmoothScrollingEntryListWidget<E extends Dynamic
     }
     }
     
     
     public void scrollTo(double value, boolean animated, long duration) {
     public void scrollTo(double value, boolean animated, long duration) {
-        target = clamp(value);
+        target = clamp(value, getMaxScroll());
         
         
         if (animated) {
         if (animated) {
             start = System.currentTimeMillis();
             start = System.currentTimeMillis();
@@ -106,30 +101,19 @@ public abstract class DynamicNewSmoothScrollingEntryListWidget<E extends Dynamic
     
     
     @Override
     @Override
     public void render(int mouseX, int mouseY, float delta) {
     public void render(int mouseX, int mouseY, float delta) {
-        updatePosition(delta);
+        double[] target = {this.target};
+        scroll = handleScrollingPosition(target, scroll, getMaxScroll(), delta, start, duration);
+        this.target = target[0];
         super.render(mouseX, mouseY, delta);
         super.render(mouseX, mouseY, delta);
     }
     }
     
     
-    private void updatePosition(float delta) {
-        target = clamp(target);
-        if (target < 0) {
-            target -= target * (1 - ClothConfigInitializer.getBounceBackMultiplier()) * delta / 3;
-        } else if (target > getMaxScroll()) {
-            target = (target - getMaxScroll()) * (1 - (1 - ClothConfigInitializer.getBounceBackMultiplier()) * delta / 3) + getMaxScroll();
-        }
-        if (!Precision.almostEquals(scroll, target, Precision.FLOAT_EPSILON))
-            scroll = (float) Interpolation.expoEase(scroll, target, Math.min((System.currentTimeMillis() - start) / ((double) duration), 1));
-        else
-            scroll = target;
-    }
-    
     @SuppressWarnings("deprecation")
     @SuppressWarnings("deprecation")
     @Override
     @Override
     protected void renderScrollBar(Tessellator tessellator, BufferBuilder buffer, int maxScroll, int scrollbarPositionMinX, int scrollbarPositionMaxX) {
     protected void renderScrollBar(Tessellator tessellator, BufferBuilder buffer, int maxScroll, int scrollbarPositionMinX, int scrollbarPositionMaxX) {
         if (!smoothScrolling)
         if (!smoothScrolling)
             super.renderScrollBar(tessellator, buffer, maxScroll, scrollbarPositionMinX, scrollbarPositionMaxX);
             super.renderScrollBar(tessellator, buffer, maxScroll, scrollbarPositionMinX, scrollbarPositionMaxX);
         else if (maxScroll > 0) {
         else if (maxScroll > 0) {
-            int height = (int) (((this.bottom - this.top) * (this.bottom - this.top)) / this.getMaxScrollPosition());
+            int height = ((this.bottom - this.top) * (this.bottom - this.top)) / this.getMaxScrollPosition();
             height = MathHelper.clamp(height, 32, this.bottom - this.top - 8);
             height = MathHelper.clamp(height, 32, this.bottom - this.top - 8);
             height -= Math.min((scroll < 0 ? (int) -scroll : scroll > getMaxScroll() ? (int) scroll - getMaxScroll() : 0), height * .95);
             height -= Math.min((scroll < 0 ? (int) -scroll : scroll > getMaxScroll() ? (int) scroll - getMaxScroll() : 0), height * .95);
             height = Math.max(10, height);
             height = Math.max(10, height);

+ 9 - 1
src/main/resources/assets/cloth-config2/lang/en_us.json

@@ -27,5 +27,13 @@
   "text.cloth-config.dropdown.value.unknown": "§cNo suggestions",
   "text.cloth-config.dropdown.value.unknown": "§cNo suggestions",
   "modifier.cloth-config.alt": "Alt + %s",
   "modifier.cloth-config.alt": "Alt + %s",
   "modifier.cloth-config.ctrl": "Ctrl + %s",
   "modifier.cloth-config.ctrl": "Ctrl + %s",
-  "modifier.cloth-config.shift": "Shift + %s"
+  "modifier.cloth-config.shift": "Shift + %s",
+  "title.cloth-config.config": "Cloth Mod Config Config",
+  "category.cloth-config.scrolling": "Scrolling",
+  "category.cloth-config.testing": "Config Demo",
+  "option.cloth-config.scrollDuration": "Scroll Duration",
+  "option.cloth-config.scrollStep": "Scroll Step",
+  "option.cloth-config.bounceBackMultiplier": "Bounce Multiplier",
+  "option.cloth-config.setDefaultSmoothScroll": "Set Default Smooth Scroll",
+  "option.cloth-config.disableSmoothScroll": "Disable Smooth Scroll"
 }
 }