Browse Source

better scrolling api

Unknown 6 years ago
parent
commit
2988584a38

+ 22 - 0
src/main/java/me/shedaniel/clothconfig2/api/RunSixtyTimesEverySec.java

@@ -0,0 +1,22 @@
+package me.shedaniel.clothconfig2.api;
+
+import me.shedaniel.clothconfig2.impl.RunSixtyTimesEverySecImpl;
+
+public interface RunSixtyTimesEverySec {
+    
+    void run();
+    
+    default boolean isRegistered() {
+        return RunSixtyTimesEverySecImpl.TICKS_LIST.contains(this);
+    }
+    
+    default void registerTick() {
+        RunSixtyTimesEverySecImpl.TICKS_LIST.removeIf(runSixtyTimesEverySec -> runSixtyTimesEverySec == this);
+        RunSixtyTimesEverySecImpl.TICKS_LIST.add(this);
+    }
+    
+    default void unregisterTick() {
+        RunSixtyTimesEverySecImpl.TICKS_LIST.remove(this);
+    }
+    
+}

+ 41 - 51
src/main/java/me/shedaniel/clothconfig2/gui/widget/DynamicSmoothScrollingEntryListWidget.java

@@ -1,37 +1,51 @@
 package me.shedaniel.clothconfig2.gui.widget;
 
+import me.shedaniel.clothconfig2.api.RunSixtyTimesEverySec;
 import net.minecraft.client.MinecraftClient;
-import net.minecraft.client.gui.Element;
 import net.minecraft.client.render.BufferBuilder;
 import net.minecraft.client.render.Tessellator;
 import net.minecraft.client.render.VertexFormats;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.math.MathHelper;
 
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
 public abstract class DynamicSmoothScrollingEntryListWidget<E extends DynamicEntryListWidget.Entry<E>> extends DynamicEntryListWidget<E> {
     
-    private static final ScheduledExecutorService EXECUTOR_SERVICE = Executors.newSingleThreadScheduledExecutor();
-    
-    static {
-        EXECUTOR_SERVICE.scheduleWithFixedDelay(() -> {
-            if (MinecraftClient.getInstance() != null && MinecraftClient.getInstance().currentScreen != null)
-                for(Element child : MinecraftClient.getInstance().currentScreen.children())
-                    if (child instanceof DynamicSmoothScrollingEntryListWidget)
-                        ((DynamicSmoothScrollingEntryListWidget) child).updateScrolling();
-        }, 0, 1000 / 60, TimeUnit.MILLISECONDS);
-    }
-    
     protected double scrollVelocity;
     protected boolean smoothScrolling = true;
+    protected RunSixtyTimesEverySec scroller = () -> {
+        if (scrollVelocity == 0 && scroll >= 0 && scroll <= getMaxScroll())
+            scrollerUnregisterTick();
+        else {
+            // Basic scrolling
+            double change = scrollVelocity * 0.3d;
+            if (scrollVelocity != 0) {
+                scroll += change;
+                scrollVelocity -= scrollVelocity * (scroll >= 0 && scroll <= getMaxScroll() ? 0.2d : .4d);
+                if (Math.abs(scrollVelocity) < .1)
+                    scrollVelocity = 0d;
+            }
+            
+            // Scrolling back aka bounce
+            if (scroll < 0d && scrollVelocity == 0d) {
+                scroll = Math.min(scroll + (0 - scroll) * 0.2d, 0);
+                if (scroll > -0.1d && scroll < 0d)
+                    scroll = 0d;
+            } else if (scroll > getMaxScroll() && scrollVelocity == 0d) {
+                scroll = Math.max(scroll - (scroll - getMaxScroll()) * 0.2d, getMaxScroll());
+                if (scroll > getMaxScroll() && scroll < getMaxScroll() + 0.1d)
+                    scroll = getMaxScroll();
+            }
+        }
+    };
     
     public DynamicSmoothScrollingEntryListWidget(MinecraftClient client, int width, int height, int top, int bottom, Identifier backgroundLocation) {
         super(client, width, height, top, bottom, backgroundLocation);
     }
     
+    protected void scrollerUnregisterTick() {
+        scroller.unregisterTick();
+    }
+    
     public double getScrollVelocity() {
         return scrollVelocity;
     }
@@ -56,31 +70,6 @@ public abstract class DynamicSmoothScrollingEntryListWidget<E extends DynamicEnt
             this.scroll = MathHelper.clamp(double_1, 0.0D, (double) this.getMaxScroll());
     }
     
-    public void updateScrolling() {
-        if (smoothScrolling) {
-            double change = scrollVelocity * 0.3d;
-            if (scrollVelocity != 0) {
-                scroll += change;
-                scrollVelocity -= scrollVelocity * (scroll >= 0 && scroll <= getMaxScroll() ? 0.2d : .4d);
-                if (Math.abs(scrollVelocity) < .1)
-                    scrollVelocity = 0d;
-            }
-            if (scroll < 0d && scrollVelocity == 0d) {
-                scroll = Math.min(scroll + (0 - scroll) * 0.2d, 0);
-                if (scroll > -0.1d && scroll < 0d)
-                    scroll = 0d;
-            } else if (scroll > getMaxScroll() && scrollVelocity == 0d) {
-                scroll = Math.max(scroll - (scroll - getMaxScroll()) * 0.2d, getMaxScroll());
-                if (scroll > getMaxScroll() && scroll < getMaxScroll() + 0.1d)
-                    scroll = getMaxScroll();
-            }
-        } else {
-            scroll += scrollVelocity;
-            scrollVelocity = 0d;
-            capYPosition(scroll);
-        }
-    }
-    
     @Override
     public boolean mouseDragged(double double_1, double double_2, int int_1, double double_3, double double_4) {
         if (!smoothScrolling)
@@ -113,20 +102,21 @@ public abstract class DynamicSmoothScrollingEntryListWidget<E extends DynamicEnt
     @Override
     public boolean mouseScrolled(double double_1, double double_2, double double_3) {
         if (!smoothScrolling) {
+            this.scrollVelocity = 0d;
             if (double_3 < 0)
-                scrollVelocity += 16;
+                scroll += 16;
             if (double_3 > 0)
-                scrollVelocity -= 16;
-            return true;
-        }
-        if (true) {
-            if (scroll <= getMaxScroll() && double_3 < 0)
-                scrollVelocity += 16;
-            if (scroll >= 0 && double_3 > 0)
-                scrollVelocity -= 16;
+                scroll -= 16;
+            this.scroll = MathHelper.clamp(double_1, 0.0D, (double) this.getMaxScroll());
             return true;
         }
-        return false;
+        if (scroll <= getMaxScroll() && double_3 < 0)
+            scrollVelocity += 16;
+        if (scroll >= 0 && double_3 > 0)
+            scrollVelocity -= 16;
+        if (!scroller.isRegistered())
+            scroller.registerTick();
+        return true;
     }
     
     @Override

+ 24 - 0
src/main/java/me/shedaniel/clothconfig2/impl/RunSixtyTimesEverySecImpl.java

@@ -0,0 +1,24 @@
+package me.shedaniel.clothconfig2.impl;
+
+import com.google.common.collect.Lists;
+import me.shedaniel.clothconfig2.api.RunSixtyTimesEverySec;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+public class RunSixtyTimesEverySecImpl {
+    
+    public static final List<RunSixtyTimesEverySec> TICKS_LIST = Lists.newCopyOnWriteArrayList();
+    private static final ScheduledExecutorService EXECUTOR_SERVICE = Executors.newSingleThreadScheduledExecutor();
+    
+    static {
+        EXECUTOR_SERVICE.scheduleAtFixedRate(() -> {
+            TICKS_LIST.removeIf(Objects::isNull);
+            TICKS_LIST.iterator().forEachRemaining(RunSixtyTimesEverySec::run);
+        }, 0, 1000 / 60, TimeUnit.MILLISECONDS);
+    }
+    
+}