Selaa lähdekoodia

Scrollable Entry List?

Unknown 5 vuotta sitten
vanhempi
sitoutus
b723f2bea2
45 muutettua tiedostoa jossa 359 lisäystä ja 203 poistoa
  1. 3 3
      src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java
  2. 1 1
      src/main/java/me/shedaniel/rei/api/AutoTransferHandler.java
  3. 1 1
      src/main/java/me/shedaniel/rei/api/ClientHelper.java
  4. 4 2
      src/main/java/me/shedaniel/rei/api/ConfigObject.java
  5. 1 1
      src/main/java/me/shedaniel/rei/api/DisplayHelper.java
  6. 2 2
      src/main/java/me/shedaniel/rei/api/Entry.java
  7. 1 1
      src/main/java/me/shedaniel/rei/api/RecipeCategory.java
  8. 1 1
      src/main/java/me/shedaniel/rei/api/RecipeHelper.java
  9. 105 90
      src/main/java/me/shedaniel/rei/gui/ContainerScreenOverlay.java
  10. 1 1
      src/main/java/me/shedaniel/rei/gui/PreRecipeViewingScreen.java
  11. 1 1
      src/main/java/me/shedaniel/rei/gui/RecipeViewingScreen.java
  12. 1 1
      src/main/java/me/shedaniel/rei/gui/VillagerRecipeViewingScreen.java
  13. 1 1
      src/main/java/me/shedaniel/rei/gui/credits/CreditsScreen.java
  14. 3 3
      src/main/java/me/shedaniel/rei/gui/renderers/ItemStackRenderer.java
  15. 1 1
      src/main/java/me/shedaniel/rei/gui/widget/AutoCraftingButtonWidget.java
  16. 1 1
      src/main/java/me/shedaniel/rei/gui/widget/ButtonWidget.java
  17. 1 1
      src/main/java/me/shedaniel/rei/gui/widget/ClickableLabelWidget.java
  18. 143 18
      src/main/java/me/shedaniel/rei/gui/widget/EntryListWidget.java
  19. 1 1
      src/main/java/me/shedaniel/rei/gui/widget/RecipeBaseWidget.java
  20. 2 2
      src/main/java/me/shedaniel/rei/gui/widget/RecipeChoosePageWidget.java
  21. 1 1
      src/main/java/me/shedaniel/rei/gui/widget/SlotBaseWidget.java
  22. 15 13
      src/main/java/me/shedaniel/rei/gui/widget/SlotWidget.java
  23. 1 1
      src/main/java/me/shedaniel/rei/gui/widget/TabWidget.java
  24. 1 1
      src/main/java/me/shedaniel/rei/impl/BaseBoundsHandlerImpl.java
  25. 1 1
      src/main/java/me/shedaniel/rei/impl/ClientHelperImpl.java
  26. 1 1
      src/main/java/me/shedaniel/rei/impl/ConfigManagerImpl.java
  27. 13 1
      src/main/java/me/shedaniel/rei/impl/ConfigObjectImpl.java
  28. 1 1
      src/main/java/me/shedaniel/rei/impl/DisplayHelperImpl.java
  29. 1 1
      src/main/java/me/shedaniel/rei/impl/EntryRegistryImpl.java
  30. 1 1
      src/main/java/me/shedaniel/rei/impl/FluidEntry.java
  31. 1 1
      src/main/java/me/shedaniel/rei/impl/ItemStackEntry.java
  32. 1 1
      src/main/java/me/shedaniel/rei/impl/RecipeHelperImpl.java
  33. 1 1
      src/main/java/me/shedaniel/rei/impl/ScreenHelper.java
  34. 1 1
      src/main/java/me/shedaniel/rei/impl/SearchArgument.java
  35. 1 1
      src/main/java/me/shedaniel/rei/impl/Weather.java
  36. 31 29
      src/main/java/me/shedaniel/rei/plugin/DefaultPlugin.java
  37. 1 1
      src/main/java/me/shedaniel/rei/plugin/DefaultPotionEffectExclusionZones.java
  38. 1 1
      src/main/java/me/shedaniel/rei/plugin/DefaultRecipeBookExclusionZones.java
  39. 1 1
      src/main/java/me/shedaniel/rei/plugin/autocrafting/AutoBlastingBookHandler.java
  40. 1 1
      src/main/java/me/shedaniel/rei/plugin/autocrafting/AutoCraftingTableBookHandler.java
  41. 1 1
      src/main/java/me/shedaniel/rei/plugin/autocrafting/AutoFurnaceBookHandler.java
  42. 1 1
      src/main/java/me/shedaniel/rei/plugin/autocrafting/AutoInventoryBookHandler.java
  43. 1 1
      src/main/java/me/shedaniel/rei/plugin/autocrafting/AutoSmokerBookHandler.java
  44. 1 1
      src/main/java/me/shedaniel/rei/plugin/campfire/DefaultCampfireCategory.java
  45. 4 6
      src/main/resources/fabric.mod.json

+ 3 - 3
src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java

@@ -11,9 +11,9 @@ import me.shedaniel.cloth.api.ClientUtils;
 import me.shedaniel.cloth.hooks.ClothClientHooks;
 import me.shedaniel.rei.api.*;
 import me.shedaniel.rei.api.plugins.REIPluginV0;
-import me.shedaniel.rei.client.*;
+import me.shedaniel.rei.impl.*;
 import me.shedaniel.rei.gui.ContainerScreenOverlay;
-import me.shedaniel.rei.gui.widget.EntryListOverlay;
+import me.shedaniel.rei.gui.widget.EntryListWidget;
 import me.shedaniel.rei.listeners.RecipeBookButtonWidgetHooks;
 import me.shedaniel.rei.listeners.RecipeBookGuiHooks;
 import net.fabricmc.api.ClientModInitializer;
@@ -143,7 +143,7 @@ public class RoughlyEnoughItemsCore implements ClientModInitializer {
         ClientSidePacketRegistry.INSTANCE.register(RoughlyEnoughItemsNetwork.CREATE_ITEMS_MESSAGE_PACKET, (packetContext, packetByteBuf) -> {
             ItemStack stack = packetByteBuf.readItemStack();
             String player = packetByteBuf.readString(32767);
-            packetContext.getPlayer().addChatMessage(new LiteralText(I18n.translate("text.rei.cheat_items").replaceAll("\\{item_name}", EntryListOverlay.tryGetItemStackName(stack.copy())).replaceAll("\\{item_count}", stack.copy().getCount() + "").replaceAll("\\{player_name}", player)), false);
+            packetContext.getPlayer().addChatMessage(new LiteralText(I18n.translate("text.rei.cheat_items").replaceAll("\\{item_name}", EntryListWidget.tryGetItemStackName(stack.copy())).replaceAll("\\{item_count}", stack.copy().getCount() + "").replaceAll("\\{player_name}", player)), false);
         });
         ClientSidePacketRegistry.INSTANCE.register(RoughlyEnoughItemsNetwork.NOT_ENOUGH_ITEMS_PACKET, (packetContext, packetByteBuf) -> {
             Screen currentScreen = MinecraftClient.getInstance().currentScreen;

+ 1 - 1
src/main/java/me/shedaniel/rei/api/AutoTransferHandler.java

@@ -7,7 +7,7 @@ package me.shedaniel.rei.api;
 
 import it.unimi.dsi.fastutil.ints.IntArrayList;
 import it.unimi.dsi.fastutil.ints.IntList;
-import me.shedaniel.rei.client.ScreenHelper;
+import me.shedaniel.rei.impl.ScreenHelper;
 import me.shedaniel.rei.gui.ContainerScreenOverlay;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.screen.ingame.AbstractContainerScreen;

+ 1 - 1
src/main/java/me/shedaniel/rei/api/ClientHelper.java

@@ -5,7 +5,7 @@
 
 package me.shedaniel.rei.api;
 
-import me.shedaniel.rei.client.ClientHelperImpl;
+import me.shedaniel.rei.impl.ClientHelperImpl;
 import net.fabricmc.fabric.api.client.keybinding.FabricKeyBinding;
 import net.minecraft.item.Item;
 import net.minecraft.item.ItemStack;

+ 4 - 2
src/main/java/me/shedaniel/rei/api/ConfigObject.java

@@ -9,16 +9,18 @@ public interface ConfigObject {
     
     ConfigNode getConfigNode();
     
-    void setCheating(boolean cheating);
-    
     boolean isCheating();
     
+    void setCheating(boolean cheating);
+    
     ItemListOrdering getItemListOrdering();
     
     boolean isItemListAscending();
     
     boolean isUsingDarkTheme();
     
+    boolean isEntryListWidgetScrolled();
+    
     boolean shouldAppendModNames();
     
     RecipeScreenType getRecipeScreenType();

+ 1 - 1
src/main/java/me/shedaniel/rei/api/DisplayHelper.java

@@ -112,7 +112,7 @@ public interface DisplayHelper {
          * @return the item list bounds
          */
         default Rectangle getItemListArea(Rectangle rectangle) {
-            return new Rectangle(rectangle.x + 2, rectangle.y + 24, rectangle.width - 4, rectangle.height - (RoughlyEnoughItemsCore.getConfigManager().getConfig().isSideSearchField() ? 27 + 22 : 27));
+            return new Rectangle(rectangle.x + 1, rectangle.y + 2 + (RoughlyEnoughItemsCore.getConfigManager().getConfig().isEntryListWidgetScrolled() ? 0 : 22), rectangle.width - 2, rectangle.height - (RoughlyEnoughItemsCore.getConfigManager().getConfig().isSideSearchField() ? 27 + 22 : 27) + (!RoughlyEnoughItemsCore.getConfigManager().getConfig().isEntryListWidgetScrolled() ? 0 : 22));
         }
         
         /**

+ 2 - 2
src/main/java/me/shedaniel/rei/api/Entry.java

@@ -1,7 +1,7 @@
 package me.shedaniel.rei.api;
 
-import me.shedaniel.rei.client.FluidEntry;
-import me.shedaniel.rei.client.ItemStackEntry;
+import me.shedaniel.rei.impl.FluidEntry;
+import me.shedaniel.rei.impl.ItemStackEntry;
 import net.minecraft.fluid.Fluid;
 import net.minecraft.item.ItemStack;
 

+ 1 - 1
src/main/java/me/shedaniel/rei/api/RecipeCategory.java

@@ -5,7 +5,7 @@
 
 package me.shedaniel.rei.api;
 
-import me.shedaniel.rei.client.ScreenHelper;
+import me.shedaniel.rei.impl.ScreenHelper;
 import me.shedaniel.rei.gui.RecipeViewingScreen;
 import me.shedaniel.rei.gui.renderers.RecipeRenderer;
 import me.shedaniel.rei.gui.widget.CategoryBaseWidget;

+ 1 - 1
src/main/java/me/shedaniel/rei/api/RecipeHelper.java

@@ -22,7 +22,7 @@ import java.util.function.Predicate;
 public interface RecipeHelper {
     
     /**
-     * @return the api instance of {@link me.shedaniel.rei.client.RecipeHelperImpl}
+     * @return the api instance of {@link me.shedaniel.rei.impl.RecipeHelperImpl}
      */
     static RecipeHelper getInstance() {
         return RoughlyEnoughItemsCore.getRecipeHelper();

+ 105 - 90
src/main/java/me/shedaniel/rei/gui/ContainerScreenOverlay.java

@@ -8,15 +8,16 @@ package me.shedaniel.rei.gui;
 import com.google.common.collect.Lists;
 import com.mojang.blaze3d.platform.GlStateManager;
 import me.shedaniel.cloth.api.ClientUtils;
+import me.shedaniel.clothconfig2.api.MouseUtils;
 import me.shedaniel.rei.RoughlyEnoughItemsCore;
 import me.shedaniel.rei.api.ClientHelper;
 import me.shedaniel.rei.api.DisplayHelper;
 import me.shedaniel.rei.api.Entry;
 import me.shedaniel.rei.api.RecipeHelper;
-import me.shedaniel.rei.client.RecipeHelperImpl;
-import me.shedaniel.rei.client.ScreenHelper;
-import me.shedaniel.rei.client.Weather;
 import me.shedaniel.rei.gui.widget.*;
+import me.shedaniel.rei.impl.RecipeHelperImpl;
+import me.shedaniel.rei.impl.ScreenHelper;
+import me.shedaniel.rei.impl.Weather;
 import me.shedaniel.rei.listeners.ContainerScreenHooks;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.font.TextRenderer;
@@ -48,7 +49,7 @@ public class ContainerScreenOverlay extends Widget {
     private static final List<QueuedTooltip> QUEUED_TOOLTIPS = Lists.newArrayList();
     public static String searchTerm = "";
     private static int page = 0;
-    private static EntryListOverlay entryListOverlay;
+    private static EntryListWidget entryListWidget;
     private final List<Widget> widgets = Lists.newLinkedList();
     public boolean shouldReInit = false;
     private Rectangle rectangle;
@@ -56,8 +57,12 @@ public class ContainerScreenOverlay extends Widget {
     private CraftableToggleButtonWidget toggleButtonWidget;
     private ButtonWidget buttonLeft, buttonRight;
     
-    public static EntryListOverlay getEntryListOverlay() {
-        return entryListOverlay;
+    public static EntryListWidget getEntryListWidget() {
+        return entryListWidget;
+    }
+    
+    public static void setPage(int page) {
+        ContainerScreenOverlay.page = page;
     }
     
     public void init() {
@@ -71,47 +76,49 @@ public class ContainerScreenOverlay extends Widget {
         this.window = MinecraftClient.getInstance().window;
         DisplayHelper.DisplayBoundsHandler boundsHandler = RoughlyEnoughItemsCore.getDisplayHelper().getResponsibleBoundsHandler(MinecraftClient.getInstance().currentScreen.getClass());
         this.rectangle = RoughlyEnoughItemsCore.getConfigManager().getConfig().isLeftHandSidePanel() ? boundsHandler.getLeftBounds(MinecraftClient.getInstance().currentScreen) : boundsHandler.getRightBounds(MinecraftClient.getInstance().currentScreen);
-        widgets.add(entryListOverlay = new EntryListOverlay(page));
-        entryListOverlay.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, false);
+        widgets.add(entryListWidget = new EntryListWidget(page));
+        entryListWidget.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, false);
         
-        widgets.add(buttonLeft = new ButtonWidget(rectangle.x, rectangle.y + 5, 16, 16, new TranslatableText("text.rei.left_arrow")) {
-            @Override
-            public void onPressed() {
-                page--;
-                if (page < 0)
-                    page = getTotalPage();
-                entryListOverlay.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, false);
-            }
-            
-            @Override
-            public Optional<String> getTooltips() {
-                return Optional.ofNullable(I18n.translate("text.rei.previous_page"));
-            }
-            
-            @Override
-            public boolean changeFocus(boolean boolean_1) {
-                return false;
-            }
-        });
-        widgets.add(buttonRight = new ButtonWidget(rectangle.x + rectangle.width - 18, rectangle.y + 5, 16, 16, new TranslatableText("text.rei.right_arrow")) {
-            @Override
-            public void onPressed() {
-                page++;
-                if (page > getTotalPage())
-                    page = 0;
-                entryListOverlay.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, false);
-            }
-            
-            @Override
-            public Optional<String> getTooltips() {
-                return Optional.ofNullable(I18n.translate("text.rei.next_page"));
-            }
-            
-            @Override
-            public boolean changeFocus(boolean boolean_1) {
-                return false;
-            }
-        });
+        if (!RoughlyEnoughItemsCore.getConfigManager().getConfig().isEntryListWidgetScrolled()) {
+            widgets.add(buttonLeft = new ButtonWidget(rectangle.x, rectangle.y + 5, 16, 16, new TranslatableText("text.rei.left_arrow")) {
+                @Override
+                public void onPressed() {
+                    page--;
+                    if (page < 0)
+                        page = getTotalPage();
+                    entryListWidget.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, false);
+                }
+                
+                @Override
+                public Optional<String> getTooltips() {
+                    return Optional.ofNullable(I18n.translate("text.rei.previous_page"));
+                }
+                
+                @Override
+                public boolean changeFocus(boolean boolean_1) {
+                    return false;
+                }
+            });
+            widgets.add(buttonRight = new ButtonWidget(rectangle.x + rectangle.width - 18, rectangle.y + 5, 16, 16, new TranslatableText("text.rei.right_arrow")) {
+                @Override
+                public void onPressed() {
+                    page++;
+                    if (page > getTotalPage())
+                        page = 0;
+                    entryListWidget.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, false);
+                }
+                
+                @Override
+                public Optional<String> getTooltips() {
+                    return Optional.ofNullable(I18n.translate("text.rei.next_page"));
+                }
+                
+                @Override
+                public boolean changeFocus(boolean boolean_1) {
+                    return false;
+                }
+            });
+        }
         
         if (setPage)
             page = MathHelper.clamp(page, 0, getTotalPage());
@@ -214,32 +221,34 @@ public class ContainerScreenOverlay extends Widget {
                 xxx += RoughlyEnoughItemsCore.getConfigManager().getConfig().isLeftHandSidePanel() ? -25 : 25;
             }
         }
-        widgets.add(new ClickableLabelWidget(rectangle.x + (rectangle.width / 2), rectangle.y + 10, "", getTotalPage() > 0) {
-            @Override
-            public void render(int mouseX, int mouseY, float delta) {
-                page = MathHelper.clamp(page, 0, getTotalPage());
-                this.text = String.format("%s/%s", page + 1, getTotalPage() + 1);
-                super.render(mouseX, mouseY, delta);
-            }
-            
-            @Override
-            public Optional<String> getTooltips() {
-                return Optional.ofNullable(I18n.translate("text.rei.go_back_first_page"));
-            }
-            
-            @Override
-            public void onLabelClicked() {
-                MinecraftClient.getInstance().getSoundManager().play(PositionedSoundInstance.master(SoundEvents.UI_BUTTON_CLICK, 1.0F));
-                page = 0;
-                entryListOverlay.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, false);
-            }
-            
-            @Override
-            public boolean changeFocus(boolean boolean_1) {
-                return false;
-            }
-        });
-        buttonLeft.enabled = buttonRight.enabled = getTotalPage() > 0;
+        if (!RoughlyEnoughItemsCore.getConfigManager().getConfig().isEntryListWidgetScrolled()) {
+            widgets.add(new ClickableLabelWidget(rectangle.x + (rectangle.width / 2), rectangle.y + 10, "", getTotalPage() > 0) {
+                @Override
+                public void render(int mouseX, int mouseY, float delta) {
+                    page = MathHelper.clamp(page, 0, getTotalPage());
+                    this.text = String.format("%s/%s", page + 1, getTotalPage() + 1);
+                    super.render(mouseX, mouseY, delta);
+                }
+                
+                @Override
+                public Optional<String> getTooltips() {
+                    return Optional.ofNullable(I18n.translate("text.rei.go_back_first_page"));
+                }
+                
+                @Override
+                public void onLabelClicked() {
+                    MinecraftClient.getInstance().getSoundManager().play(PositionedSoundInstance.master(SoundEvents.UI_BUTTON_CLICK, 1.0F));
+                    page = 0;
+                    entryListWidget.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, false);
+                }
+                
+                @Override
+                public boolean changeFocus(boolean boolean_1) {
+                    return false;
+                }
+            });
+            buttonLeft.enabled = buttonRight.enabled = getTotalPage() > 0;
+        }
         if (ScreenHelper.searchField == null)
             ScreenHelper.searchField = new SearchFieldWidget(0, 0, 0, 0);
         ScreenHelper.searchField.getBounds().setBounds(getTextFieldArea());
@@ -247,14 +256,14 @@ public class ContainerScreenOverlay extends Widget {
         ScreenHelper.searchField.setText(searchTerm);
         ScreenHelper.searchField.setChangedListener(s -> {
             searchTerm = s;
-            entryListOverlay.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, true);
+            entryListWidget.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, true);
         });
         if (RoughlyEnoughItemsCore.getConfigManager().getConfig().isCraftableFilterEnabled())
             this.widgets.add(toggleButtonWidget = new CraftableToggleButtonWidget(getCraftableToggleArea()) {
                 @Override
                 public void onPressed() {
                     RoughlyEnoughItemsCore.getConfigManager().toggleCraftableOnly();
-                    entryListOverlay.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, true);
+                    entryListWidget.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, true);
                 }
                 
                 @Override
@@ -265,7 +274,7 @@ public class ContainerScreenOverlay extends Widget {
             });
         else
             toggleButtonWidget = null;
-        this.entryListOverlay.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, false);
+        this.entryListWidget.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, false);
     }
     
     private Weather getNextWeather() {
@@ -357,7 +366,7 @@ public class ContainerScreenOverlay extends Widget {
         else if (RoughlyEnoughItemsCore.getConfigManager().isCraftableOnlyEnabled() && ((currentStacks.size() != ScreenHelper.inventoryStacks.size()) || !hasSameListContent(new LinkedList<>(ScreenHelper.inventoryStacks), currentStacks))) {
             ScreenHelper.inventoryStacks = currentStacks;
             DisplayHelper.DisplayBoundsHandler<?> boundsHandler = RoughlyEnoughItemsCore.getDisplayHelper().getResponsibleBoundsHandler(MinecraftClient.getInstance().currentScreen.getClass());
-            entryListOverlay.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, true);
+            entryListWidget.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, true);
         }
         if (SearchFieldWidget.isSearching) {
             GuiLighting.disable();
@@ -366,7 +375,7 @@ public class ContainerScreenOverlay extends Widget {
                 ContainerScreenHooks hooks = (ContainerScreenHooks) MinecraftClient.getInstance().currentScreen;
                 int left = hooks.rei_getContainerLeft(), top = hooks.rei_getContainerTop();
                 for (Slot slot : ((AbstractContainerScreen<?>) MinecraftClient.getInstance().currentScreen).getContainer().slotList)
-                    if (!slot.hasStack() || !entryListOverlay.filterEntry(Entry.create(slot.getStack()), entryListOverlay.getLastSearchArgument()))
+                    if (!slot.hasStack() || !entryListWidget.filterEntry(Entry.create(slot.getStack()), entryListWidget.getLastSearchArgument()))
                         fillGradient(left + slot.xPosition, top + slot.yPosition, left + slot.xPosition + 16, top + slot.yPosition + 16, -601874400, -601874400);
             }
             blitOffset = 0;
@@ -453,7 +462,8 @@ public class ContainerScreenOverlay extends Widget {
     public void renderWidgets(int int_1, int int_2, float float_1) {
         if (!ScreenHelper.isOverlayVisible())
             return;
-        buttonLeft.enabled = buttonRight.enabled = getTotalPage() > 0;
+        if (!RoughlyEnoughItemsCore.getConfigManager().getConfig().isEntryListWidgetScrolled())
+            buttonLeft.enabled = buttonRight.enabled = getTotalPage() > 0;
         widgets.forEach(widget -> {
             GuiLighting.disable();
             widget.render(int_1, int_2, float_1);
@@ -462,7 +472,7 @@ public class ContainerScreenOverlay extends Widget {
     }
     
     private int getTotalPage() {
-        return entryListOverlay.getTotalPage();
+        return entryListWidget.getTotalPage();
     }
     
     @Override
@@ -470,13 +480,17 @@ public class ContainerScreenOverlay extends Widget {
         if (!ScreenHelper.isOverlayVisible())
             return false;
         if (isInside(ClientUtils.getMouseLocation())) {
-            if (amount > 0 && buttonLeft.enabled)
-                buttonLeft.onPressed();
-            else if (amount < 0 && buttonRight.enabled)
-                buttonRight.onPressed();
-            else
-                return false;
-            return true;
+            if (!RoughlyEnoughItemsCore.getConfigManager().getConfig().isEntryListWidgetScrolled()) {
+                if (amount > 0 && buttonLeft.enabled)
+                    buttonLeft.onPressed();
+                else if (amount < 0 && buttonRight.enabled)
+                    buttonRight.onPressed();
+                else
+                    return false;
+                return true;
+            } else {
+                return entryListWidget.mouseScrolled(i, j, amount);
+            }
         }
         for (Widget widget : widgets)
             if (widget.mouseScrolled(i, j, amount))
@@ -486,7 +500,7 @@ public class ContainerScreenOverlay extends Widget {
     
     @Override
     public boolean keyPressed(int int_1, int int_2, int int_3) {
-        if (ScreenHelper.isOverlayVisible())
+        if (ScreenHelper.isOverlayVisible() && isInside(MouseUtils.getMouseLocation()))
             for (Element listener : widgets)
                 if (listener.keyPressed(int_1, int_2, int_3))
                     return true;
@@ -518,9 +532,10 @@ public class ContainerScreenOverlay extends Widget {
     public boolean charTyped(char char_1, int int_1) {
         if (!ScreenHelper.isOverlayVisible())
             return false;
-        for (Element listener : widgets)
-            if (listener.charTyped(char_1, int_1))
-                return true;
+        if (isInside(MouseUtils.getMouseLocation()))
+            for (Element listener : widgets)
+                if (listener.charTyped(char_1, int_1))
+                    return true;
         return false;
     }
     

+ 1 - 1
src/main/java/me/shedaniel/rei/gui/PreRecipeViewingScreen.java

@@ -10,7 +10,7 @@ import me.shedaniel.rei.RoughlyEnoughItemsCore;
 import me.shedaniel.rei.api.ClientHelper;
 import me.shedaniel.rei.api.RecipeCategory;
 import me.shedaniel.rei.api.RecipeDisplay;
-import me.shedaniel.rei.client.ScreenHelper;
+import me.shedaniel.rei.impl.ScreenHelper;
 import me.shedaniel.rei.gui.config.RecipeScreenType;
 import me.shedaniel.rei.gui.widget.ButtonWidget;
 import me.shedaniel.rei.gui.widget.Widget;

+ 1 - 1
src/main/java/me/shedaniel/rei/gui/RecipeViewingScreen.java

@@ -10,7 +10,7 @@ import com.mojang.blaze3d.platform.GlStateManager;
 import me.shedaniel.cloth.api.ClientUtils;
 import me.shedaniel.rei.RoughlyEnoughItemsCore;
 import me.shedaniel.rei.api.*;
-import me.shedaniel.rei.client.ScreenHelper;
+import me.shedaniel.rei.impl.ScreenHelper;
 import me.shedaniel.rei.gui.widget.*;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.Element;

+ 1 - 1
src/main/java/me/shedaniel/rei/gui/VillagerRecipeViewingScreen.java

@@ -12,7 +12,7 @@ import com.zeitheron.hammercore.client.utils.Scissors;
 import me.shedaniel.cloth.api.ClientUtils;
 import me.shedaniel.rei.RoughlyEnoughItemsCore;
 import me.shedaniel.rei.api.*;
-import me.shedaniel.rei.client.ScreenHelper;
+import me.shedaniel.rei.impl.ScreenHelper;
 import me.shedaniel.rei.gui.renderers.RecipeRenderer;
 import me.shedaniel.rei.gui.widget.*;
 import net.minecraft.client.MinecraftClient;

+ 1 - 1
src/main/java/me/shedaniel/rei/gui/credits/CreditsScreen.java

@@ -8,7 +8,7 @@ package me.shedaniel.rei.gui.credits;
 import com.google.common.collect.Lists;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonObject;
-import me.shedaniel.rei.client.ScreenHelper;
+import me.shedaniel.rei.impl.ScreenHelper;
 import me.shedaniel.rei.gui.credits.CreditsEntryListWidget.CreditsItem;
 import net.fabricmc.loader.api.FabricLoader;
 import net.minecraft.client.gui.screen.Screen;

+ 3 - 3
src/main/java/me/shedaniel/rei/gui/renderers/ItemStackRenderer.java

@@ -10,8 +10,8 @@ import com.mojang.blaze3d.platform.GlStateManager;
 import me.shedaniel.rei.RoughlyEnoughItemsCore;
 import me.shedaniel.rei.api.ClientHelper;
 import me.shedaniel.rei.api.Renderer;
-import me.shedaniel.rei.client.ScreenHelper;
-import me.shedaniel.rei.gui.widget.EntryListOverlay;
+import me.shedaniel.rei.impl.ScreenHelper;
+import me.shedaniel.rei.gui.widget.EntryListWidget;
 import me.shedaniel.rei.gui.widget.QueuedTooltip;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.render.GuiLighting;
@@ -56,7 +56,7 @@ public abstract class ItemStackRenderer extends Renderer {
     }
     
     protected List<String> getTooltip(ItemStack itemStack) {
-        List<String> toolTip = Lists.newArrayList(EntryListOverlay.tryGetItemStackToolTip(itemStack, true));
+        List<String> toolTip = Lists.newArrayList(EntryListWidget.tryGetItemStackToolTip(itemStack, true));
         if (RoughlyEnoughItemsCore.getConfigManager().getConfig().shouldAppendModNames()) {
             final String modString = ClientHelper.getInstance().getFormattedModFromItem(itemStack.getItem());
             toolTip.addAll(getExtraToolTips(itemStack));

+ 1 - 1
src/main/java/me/shedaniel/rei/gui/widget/AutoCraftingButtonWidget.java

@@ -8,7 +8,7 @@ package me.shedaniel.rei.gui.widget;
 import me.shedaniel.rei.api.AutoTransferHandler;
 import me.shedaniel.rei.api.RecipeDisplay;
 import me.shedaniel.rei.api.RecipeHelper;
-import me.shedaniel.rei.client.ScreenHelper;
+import me.shedaniel.rei.impl.ScreenHelper;
 import net.minecraft.client.gui.screen.ingame.AbstractContainerScreen;
 import net.minecraft.client.resource.language.I18n;
 import net.minecraft.util.Formatting;

+ 1 - 1
src/main/java/me/shedaniel/rei/gui/widget/ButtonWidget.java

@@ -6,7 +6,7 @@
 package me.shedaniel.rei.gui.widget;
 
 import com.mojang.blaze3d.platform.GlStateManager;
-import me.shedaniel.rei.client.ScreenHelper;
+import me.shedaniel.rei.impl.ScreenHelper;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.sound.PositionedSoundInstance;
 import net.minecraft.sound.SoundEvents;

+ 1 - 1
src/main/java/me/shedaniel/rei/gui/widget/ClickableLabelWidget.java

@@ -5,7 +5,7 @@
 
 package me.shedaniel.rei.gui.widget;
 
-import me.shedaniel.rei.client.ScreenHelper;
+import me.shedaniel.rei.impl.ScreenHelper;
 import net.minecraft.util.Formatting;
 
 import java.awt.*;

+ 143 - 18
src/main/java/me/shedaniel/rei/gui/widget/EntryListOverlay.java → src/main/java/me/shedaniel/rei/gui/widget/EntryListWidget.java

@@ -6,13 +6,16 @@
 package me.shedaniel.rei.gui.widget;
 
 import com.google.common.collect.Lists;
+import com.mojang.blaze3d.platform.GlStateManager;
+import com.zeitheron.hammercore.client.utils.Scissors;
 import me.shedaniel.cloth.api.ClientUtils;
+import me.shedaniel.clothconfig2.api.RunSixtyTimesEverySec;
 import me.shedaniel.rei.RoughlyEnoughItemsCore;
 import me.shedaniel.rei.api.*;
-import me.shedaniel.rei.client.ScreenHelper;
-import me.shedaniel.rei.client.SearchArgument;
 import me.shedaniel.rei.gui.config.ItemCheatingMode;
 import me.shedaniel.rei.gui.config.ItemListOrdering;
+import me.shedaniel.rei.impl.ScreenHelper;
+import me.shedaniel.rei.impl.SearchArgument;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.item.TooltipContext;
 import net.minecraft.client.network.ClientPlayerEntity;
@@ -35,11 +38,43 @@ import java.util.concurrent.atomic.AtomicReference;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
-public class EntryListOverlay extends Widget {
+public class EntryListWidget extends Widget {
     
     private static final String SPACE = " ", EMPTY = "";
     private static final Comparator<Entry> ASCENDING_COMPARATOR;
     private static List<Item> searchBlacklisted = Lists.newArrayList();
+    private static float scroll;
+    private static float scrollVelocity;
+    private static float maxScroll;
+    protected static RunSixtyTimesEverySec scroller = () -> {
+        try {
+            if (scrollVelocity == 0.0F && scroll >= 0.0F && scroll <= getMaxScroll()) {
+                scrollerUnregisterTick();
+            } else {
+                double change = scrollVelocity * 0.3D;
+                if (scrollVelocity != 0) {
+                    scroll += change;
+                    scrollVelocity -= scrollVelocity * (scroll >= 0.0F && scroll <= getMaxScroll() ? 0.2D : 0.4D);
+                    if (Math.abs(scrollVelocity) < 0.1D) {
+                        scrollVelocity = 0.0F;
+                    }
+                }
+                
+                if (scroll < 0.0F && scrollVelocity == 0.0F) {
+                    scroll = Math.min(scroll + (0.0F - scroll) * 0.2F, 0.0F);
+                    if (Math.abs(scroll) < 0.1F)
+                        scroll = 0.0F;
+                } else if (scroll > getMaxScroll() && scrollVelocity == 0.0F) {
+                    scroll = Math.max(scroll - (scroll - getMaxScroll()) * 0.2F, getMaxScroll());
+                    if (scroll > getMaxScroll() && scroll < getMaxScroll() + 0.1F) {
+                        scroll = getMaxScroll();
+                    }
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    };
     
     static {
         ASCENDING_COMPARATOR = (entry, entry1) -> {
@@ -59,11 +94,11 @@ public class EntryListOverlay extends Widget {
     
     private final List<SearchArgument[]> lastSearchArgument;
     private List<Entry> currentDisplayed;
-    private List<Widget> widgets;
+    private List<Slot> widgets;
     private int width, height, page;
     private Rectangle rectangle, listArea;
     
-    public EntryListOverlay(int page) {
+    public EntryListWidget(int page) {
         this.currentDisplayed = Lists.newArrayList();
         this.width = 0;
         this.height = 0;
@@ -168,14 +203,65 @@ public class EntryListOverlay extends Widget {
         return mod;
     }
     
+    private static void scrollerUnregisterTick() {
+        scroller.unregisterTick();
+    }
+    
+    public static float getMaxScroll() {
+        return Math.max(maxScroll - ScreenHelper.getLastOverlay().getEntryListWidget().rectangle.height, 0);
+    }
+    
+    public static float getScroll() {
+        return scroll;
+    }
+    
+    public static float getScrollVelocity() {
+        return scrollVelocity;
+    }
+    
     public int getFullTotalSlotsPerPage() {
         return width * height;
     }
     
+    @Override
+    public boolean mouseScrolled(double double_1, double double_2, double double_3) {
+        if (!this.scroller.isRegistered())
+            this.scroller.registerTick();
+        if (RoughlyEnoughItemsCore.getConfigManager().getConfig().isEntryListWidgetScrolled() && rectangle.contains(double_1, double_2)) {
+            if (this.scroll >= 0F && double_3 > 0)
+                scrollVelocity -= 24;
+            else if (this.scroll <= this.getMaxScroll() && double_3 < 0)
+                scrollVelocity += 24;
+            return true;
+        }
+        return super.mouseScrolled(double_1, double_2, double_3);
+    }
+    
     @Override
     public void render(int int_1, int int_2, float float_1) {
         GuiLighting.disable();
-        widgets.forEach(widget -> widget.render(int_1, int_2, float_1));
+        GlStateManager.pushMatrix();
+        boolean widgetScrolled = RoughlyEnoughItemsCore.getConfigManager().getConfig().isEntryListWidgetScrolled();
+        if (!widgetScrolled)
+            scroll = 0;
+        else {
+            page = 0;
+            ScreenHelper.getLastOverlay().setPage(0);
+            Scissors.begin();
+            Scissors.scissor(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
+        }
+        widgets.forEach(widget -> {
+            if (widgetScrolled) {
+                widget.y = (int) (widget.backupY - scroll);
+                if (widget.y <= rectangle.y + rectangle.height && widget.y + widget.getBounds().height >= rectangle.y)
+                    widget.render(int_1, int_2, float_1);
+            } else {
+                widget.render(int_1, int_2, float_1);
+            }
+        });
+        if (widgetScrolled)
+            Scissors.end();
+        GlStateManager.popMatrix();
         ClientPlayerEntity player = minecraft.player;
         if (rectangle.contains(ClientUtils.getMouseLocation()) && ClientHelper.getInstance().isCheating() && !player.inventory.getCursorStack().isEmpty() && RoughlyEnoughItemsCore.hasPermissionToUsePackets())
             ScreenHelper.getLastOverlay().addTooltip(QueuedTooltip.create(I18n.translate("text.rei.delete_items")));
@@ -184,7 +270,7 @@ public class EntryListOverlay extends Widget {
     public void updateList(DisplayHelper.DisplayBoundsHandler boundsHandler, Rectangle rectangle, int page, String searchTerm, boolean processSearchTerm) {
         this.rectangle = rectangle;
         this.page = page;
-        this.widgets = Lists.newLinkedList();
+        this.widgets = Lists.newCopyOnWriteArrayList();
         calculateListSize(rectangle);
         if (currentDisplayed.isEmpty() || processSearchTerm)
             currentDisplayed = processSearchTerm(searchTerm, RoughlyEnoughItemsCore.getEntryRegistry().getEntryList(), new ArrayList<>(ScreenHelper.inventoryStacks));
@@ -193,6 +279,10 @@ public class EntryListOverlay extends Widget {
         this.listArea = new Rectangle((int) startX, (int) startY, width * 18, height * 18);
         int fitSlotsPerPage = getTotalFitSlotsPerPage(startX, startY, listArea);
         int j = page * fitSlotsPerPage;
+        if (RoughlyEnoughItemsCore.getConfigManager().getConfig().isEntryListWidgetScrolled()) {
+            height = Integer.MAX_VALUE;
+            j = 0;
+        }
         for (int yy = 0; yy < height; yy++) {
             for (int xx = 0; xx < width; xx++) {
                 int x = startX + xx * 18, y = startY + yy * 18;
@@ -202,7 +292,8 @@ public class EntryListOverlay extends Widget {
                 if (j > currentDisplayed.size())
                     break;
                 final Entry entry = currentDisplayed.get(j - 1);
-                widgets.add(new SlotWidget(x, y, entry.getEntryType() == Entry.Type.ITEM ? Renderer.fromItemStackNoCounts(entry.getItemStack()) : Renderer.fromFluid(entry.getFluid()), false, true, true) {
+                maxScroll = y + 18;
+                widgets.add(new Slot(entry, xx, yy, x, y, entry.getEntryType() == Entry.Type.ITEM ? Renderer.fromItemStackNoCounts(entry.getItemStack()) : Renderer.fromFluid(entry.getFluid()), false, true, true) {
                     @Override
                     protected void queueTooltip(ItemStack itemStack, float delta) {
                         ClientPlayerEntity player = minecraft.player;
@@ -243,9 +334,13 @@ public class EntryListOverlay extends Widget {
             if (j > currentDisplayed.size())
                 break;
         }
+        if (!scroller.isRegistered())
+            scroller.registerTick();
     }
     
     public int getTotalPage() {
+        if (RoughlyEnoughItemsCore.getConfigManager().getConfig().isEntryListWidgetScrolled())
+            return 1;
         int fitSlotsPerPage = getTotalFitSlotsPerPage(listArea.x, listArea.y, listArea);
         if (fitSlotsPerPage > 0)
             return MathHelper.ceil(getCurrentDisplayed().size() / fitSlotsPerPage);
@@ -272,16 +367,13 @@ public class EntryListOverlay extends Widget {
     
     @Override
     public boolean keyPressed(int int_1, int int_2, int int_3) {
-        for (Widget widget : widgets)
-            if (widget.keyPressed(int_1, int_2, int_3))
-                return true;
+        if (rectangle.contains(ClientUtils.getMouseLocation()))
+            for (Widget widget : widgets)
+                if (widget.keyPressed(int_1, int_2, int_3))
+                    return true;
         return false;
     }
     
-    public Rectangle getListArea() {
-        return listArea;
-    }
-    
     public List<Entry> getCurrentDisplayed() {
         return currentDisplayed;
     }
@@ -328,8 +420,6 @@ public class EntryListOverlay extends Widget {
         List<Entry> newList = Lists.newArrayList();
         for (ItemStack workingItem : workingItems) {
             Optional<Entry> any = stacks.stream().filter(i -> i.getItemStack() != null && i.getItemStack().isItemEqualIgnoreDamage(workingItem)).findAny();
-            //            if (stacks.stream().anyMatch(i -> i.getItemStack() != null && i.getItemStack().isItemEqualIgnoreDamage(workingItem)))
-            //                newList.add(Entry.create(workingItem));
             if (any.isPresent())
                 newList.add(any.get());
         }
@@ -376,8 +466,43 @@ public class EntryListOverlay extends Widget {
     }
     
     @Override
-    public List<Widget> children() {
+    public List<Slot> children() {
         return widgets;
     }
     
+    public class Slot extends SlotWidget {
+        private final int backupY;
+        private int xx, yy;
+        private Entry entry;
+        
+        public Slot(Entry entry, int xx, int yy, int x, int y, Renderer renderer, boolean drawBackground, boolean showToolTips, boolean clickToMoreRecipes) {
+            super(x, y, renderer, drawBackground, showToolTips, clickToMoreRecipes);
+            this.xx = xx;
+            this.yy = yy;
+            this.backupY = y;
+            this.entry = entry;
+        }
+        
+        public int getBackupY() {
+            return backupY;
+        }
+        
+        public Entry getEntry() {
+            return entry;
+        }
+        
+        public int getXx() {
+            return xx;
+        }
+        
+        public int getYy() {
+            return yy;
+        }
+        
+        @Override
+        public boolean containsMouse(double mouseX, double mouseY) {
+            return super.containsMouse(mouseX, mouseY) && rectangle.contains(mouseX, mouseY);
+        }
+    }
+    
 }

+ 1 - 1
src/main/java/me/shedaniel/rei/gui/widget/RecipeBaseWidget.java

@@ -7,7 +7,7 @@ package me.shedaniel.rei.gui.widget;
 
 import com.mojang.blaze3d.platform.GlStateManager;
 import me.shedaniel.rei.RoughlyEnoughItemsCore;
-import me.shedaniel.rei.client.ScreenHelper;
+import me.shedaniel.rei.impl.ScreenHelper;
 import me.shedaniel.rei.gui.config.RecipeScreenType;
 import net.minecraft.client.render.GuiLighting;
 import net.minecraft.util.Identifier;

+ 2 - 2
src/main/java/me/shedaniel/rei/gui/widget/RecipeChoosePageWidget.java

@@ -9,8 +9,8 @@ import com.google.common.collect.Lists;
 import com.mojang.blaze3d.platform.GlStateManager;
 import me.shedaniel.rei.RoughlyEnoughItemsCore;
 import me.shedaniel.rei.api.ConfigManager;
-import me.shedaniel.rei.client.ConfigObjectImpl;
-import me.shedaniel.rei.client.ScreenHelper;
+import me.shedaniel.rei.impl.ConfigObjectImpl;
+import me.shedaniel.rei.impl.ScreenHelper;
 import me.shedaniel.rei.gui.RecipeViewingScreen;
 import me.zeroeightsix.fiber.exception.FiberException;
 import net.minecraft.client.MinecraftClient;

+ 1 - 1
src/main/java/me/shedaniel/rei/gui/widget/SlotBaseWidget.java

@@ -5,7 +5,7 @@
 
 package me.shedaniel.rei.gui.widget;
 
-import me.shedaniel.rei.client.ScreenHelper;
+import me.shedaniel.rei.impl.ScreenHelper;
 
 import java.awt.*;
 

+ 15 - 13
src/main/java/me/shedaniel/rei/gui/widget/SlotWidget.java

@@ -11,7 +11,7 @@ import me.shedaniel.cloth.api.ClientUtils;
 import me.shedaniel.rei.RoughlyEnoughItemsCore;
 import me.shedaniel.rei.api.ClientHelper;
 import me.shedaniel.rei.api.Renderer;
-import me.shedaniel.rei.client.ScreenHelper;
+import me.shedaniel.rei.impl.ScreenHelper;
 import me.shedaniel.rei.gui.renderers.FluidRenderer;
 import me.shedaniel.rei.gui.renderers.ItemStackRenderer;
 import net.minecraft.client.gui.Element;
@@ -121,16 +121,6 @@ public class SlotWidget extends WidgetWithBounds {
             blit(this.x - 1, this.y - 1, 0, 222, 18, 18);
         }
         boolean highlighted = containsMouse(mouseX, mouseY);
-        if (drawHighlightedBackground && highlighted) {
-            GlStateManager.disableLighting();
-            GlStateManager.disableDepthTest();
-            GlStateManager.colorMask(true, true, true, false);
-            int color = darkTheme ? 0xFF5E5E5E : -2130706433;
-            fillGradient(x, y, x + 16, y + 16, color, color);
-            GlStateManager.colorMask(true, true, true, true);
-            GlStateManager.enableLighting();
-            GlStateManager.enableDepthTest();
-        }
         if (isCurrentRendererItem() && !getCurrentItemStack().isEmpty()) {
             renderer.setBlitOffset(200);
             renderer.render(x + 8, y + 6, mouseX, mouseY, delta);
@@ -145,6 +135,18 @@ public class SlotWidget extends WidgetWithBounds {
             renderer.setBlitOffset(200);
             renderer.render(x + 8, y + 6, mouseX, mouseY, delta);
         }
+        if (drawHighlightedBackground && highlighted) {
+            GlStateManager.disableLighting();
+            GlStateManager.disableDepthTest();
+            GlStateManager.colorMask(true, true, true, false);
+            int color = darkTheme ? 0xFF5E5E5E : -2130706433;
+            blitOffset = 300;
+            fillGradient(x, y, x + 16, y + 16, color, color);
+            blitOffset = 0;
+            GlStateManager.colorMask(true, true, true, true);
+            GlStateManager.enableLighting();
+            GlStateManager.enableDepthTest();
+        }
     }
     
     public int getBlitOffset() {
@@ -160,7 +162,7 @@ public class SlotWidget extends WidgetWithBounds {
     }
     
     private List<String> getTooltip(Fluid fluid) {
-        List<String> toolTip = Lists.newArrayList(EntryListOverlay.tryGetFluidName(fluid));
+        List<String> toolTip = Lists.newArrayList(EntryListWidget.tryGetFluidName(fluid));
         toolTip.addAll(getExtraFluidToolTips(fluid));
         if (RoughlyEnoughItemsCore.getConfigManager().getConfig().shouldAppendModNames()) {
             final String modString = ClientHelper.getInstance().getFormattedModFromIdentifier(Registry.FLUID.getId(fluid));
@@ -181,7 +183,7 @@ public class SlotWidget extends WidgetWithBounds {
     }
     
     protected List<String> getTooltip(ItemStack itemStack) {
-        List<String> toolTip = Lists.newArrayList(EntryListOverlay.tryGetItemStackToolTip(itemStack, true));
+        List<String> toolTip = Lists.newArrayList(EntryListWidget.tryGetItemStackToolTip(itemStack, true));
         toolTip.addAll(getExtraItemToolTips(itemStack));
         if (RoughlyEnoughItemsCore.getConfigManager().getConfig().shouldAppendModNames()) {
             final String modString = ClientHelper.getInstance().getFormattedModFromItem(itemStack.getItem());

+ 1 - 1
src/main/java/me/shedaniel/rei/gui/widget/TabWidget.java

@@ -9,7 +9,7 @@ import com.mojang.blaze3d.platform.GlStateManager;
 import me.shedaniel.rei.api.ClientHelper;
 import me.shedaniel.rei.api.RecipeCategory;
 import me.shedaniel.rei.api.Renderer;
-import me.shedaniel.rei.client.ScreenHelper;
+import me.shedaniel.rei.impl.ScreenHelper;
 import net.minecraft.client.render.GuiLighting;
 import net.minecraft.util.Formatting;
 import net.minecraft.util.Identifier;

+ 1 - 1
src/main/java/me/shedaniel/rei/client/BaseBoundsHandlerImpl.java → src/main/java/me/shedaniel/rei/impl/BaseBoundsHandlerImpl.java

@@ -3,7 +3,7 @@
  * Licensed under the MIT License.
  */
 
-package me.shedaniel.rei.client;
+package me.shedaniel.rei.impl;
 
 import com.google.common.collect.Lists;
 import me.shedaniel.rei.RoughlyEnoughItemsCore;

+ 1 - 1
src/main/java/me/shedaniel/rei/client/ClientHelperImpl.java → src/main/java/me/shedaniel/rei/impl/ClientHelperImpl.java

@@ -3,7 +3,7 @@
  * Licensed under the MIT License.
  */
 
-package me.shedaniel.rei.client;
+package me.shedaniel.rei.impl;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Maps;

+ 1 - 1
src/main/java/me/shedaniel/rei/client/ConfigManagerImpl.java → src/main/java/me/shedaniel/rei/impl/ConfigManagerImpl.java

@@ -3,7 +3,7 @@
  * Licensed under the MIT License.
  */
 
-package me.shedaniel.rei.client;
+package me.shedaniel.rei.impl;
 
 import me.shedaniel.rei.RoughlyEnoughItemsCore;
 import me.shedaniel.rei.api.ConfigManager;

+ 13 - 1
src/main/java/me/shedaniel/rei/client/ConfigObjectImpl.java → src/main/java/me/shedaniel/rei/impl/ConfigObjectImpl.java

@@ -3,7 +3,7 @@
  * Licensed under the MIT License.
  */
 
-package me.shedaniel.rei.client;
+package me.shedaniel.rei.impl;
 
 import me.shedaniel.rei.api.ConfigObject;
 import me.shedaniel.rei.gui.config.ItemCheatingMode;
@@ -165,6 +165,13 @@ public class ConfigObjectImpl implements ConfigObject {
             .withName("registerRecipesInAnotherThread")
             .build();
     
+    private ConfigValue<Boolean> scrollingEntryListWidget = ConfigValue.builder(Boolean.class)
+            .withParent(appearance)
+            .withDefaultValue(false)
+            .withComment("Declares whether if entry list widget is scrolled.")
+            .withName("scrollingEntryListWidget")
+            .build();
+    
     //    private ConfigValue<RelativePoint> choosePageDialogPoint = ConfigValue.builder(RelativePoint.class)
     //            .withParent(technical)
     //            .withDefaultValue(new RelativePoint(.5, .5))
@@ -205,6 +212,11 @@ public class ConfigObjectImpl implements ConfigObject {
         return darkTheme.getValue().booleanValue();
     }
     
+    @Override
+    public boolean isEntryListWidgetScrolled() {
+        return scrollingEntryListWidget.getValue().booleanValue();
+    }
+    
     @Override
     public boolean shouldAppendModNames() {
         return appendModNames.getValue().booleanValue();

+ 1 - 1
src/main/java/me/shedaniel/rei/client/DisplayHelperImpl.java → src/main/java/me/shedaniel/rei/impl/DisplayHelperImpl.java

@@ -3,7 +3,7 @@
  * Licensed under the MIT License.
  */
 
-package me.shedaniel.rei.client;
+package me.shedaniel.rei.impl;
 
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;

+ 1 - 1
src/main/java/me/shedaniel/rei/client/EntryRegistryImpl.java → src/main/java/me/shedaniel/rei/impl/EntryRegistryImpl.java

@@ -3,7 +3,7 @@
  * Licensed under the MIT License.
  */
 
-package me.shedaniel.rei.client;
+package me.shedaniel.rei.impl;
 
 import com.google.common.collect.Lists;
 import me.shedaniel.rei.api.Entry;

+ 1 - 1
src/main/java/me/shedaniel/rei/client/FluidEntry.java → src/main/java/me/shedaniel/rei/impl/FluidEntry.java

@@ -1,4 +1,4 @@
-package me.shedaniel.rei.client;
+package me.shedaniel.rei.impl;
 
 import me.shedaniel.rei.api.Entry;
 import net.minecraft.fluid.Fluid;

+ 1 - 1
src/main/java/me/shedaniel/rei/client/ItemStackEntry.java → src/main/java/me/shedaniel/rei/impl/ItemStackEntry.java

@@ -1,4 +1,4 @@
-package me.shedaniel.rei.client;
+package me.shedaniel.rei.impl;
 
 import me.shedaniel.rei.api.Entry;
 import net.minecraft.fluid.Fluid;

+ 1 - 1
src/main/java/me/shedaniel/rei/client/RecipeHelperImpl.java → src/main/java/me/shedaniel/rei/impl/RecipeHelperImpl.java

@@ -3,7 +3,7 @@
  * Licensed under the MIT License.
  */
 
-package me.shedaniel.rei.client;
+package me.shedaniel.rei.impl;
 
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;

+ 1 - 1
src/main/java/me/shedaniel/rei/client/ScreenHelper.java → src/main/java/me/shedaniel/rei/impl/ScreenHelper.java

@@ -3,7 +3,7 @@
  * Licensed under the MIT License.
  */
 
-package me.shedaniel.rei.client;
+package me.shedaniel.rei.impl;
 
 import com.google.common.collect.Lists;
 import me.shedaniel.cloth.hooks.ClothClientHooks;

+ 1 - 1
src/main/java/me/shedaniel/rei/client/SearchArgument.java → src/main/java/me/shedaniel/rei/impl/SearchArgument.java

@@ -3,7 +3,7 @@
  * Licensed under the MIT License.
  */
 
-package me.shedaniel.rei.client;
+package me.shedaniel.rei.impl;
 
 import java.util.Locale;
 import java.util.function.Function;

+ 1 - 1
src/main/java/me/shedaniel/rei/client/Weather.java → src/main/java/me/shedaniel/rei/impl/Weather.java

@@ -3,7 +3,7 @@
  * Licensed under the MIT License.
  */
 
-package me.shedaniel.rei.client;
+package me.shedaniel.rei.impl;
 
 public enum Weather {
     CLEAR(0, "text.rei.weather.clear"),

+ 31 - 29
src/main/java/me/shedaniel/rei/plugin/DefaultPlugin.java

@@ -13,9 +13,9 @@ import me.shedaniel.rei.api.Entry;
 import me.shedaniel.rei.api.EntryRegistry;
 import me.shedaniel.rei.api.RecipeHelper;
 import me.shedaniel.rei.api.plugins.REIPluginV0;
-import me.shedaniel.rei.client.ScreenHelper;
 import me.shedaniel.rei.gui.RecipeViewingScreen;
 import me.shedaniel.rei.gui.VillagerRecipeViewingScreen;
+import me.shedaniel.rei.impl.ScreenHelper;
 import me.shedaniel.rei.plugin.blasting.DefaultBlastingCategory;
 import me.shedaniel.rei.plugin.blasting.DefaultBlastingDisplay;
 import me.shedaniel.rei.plugin.brewing.DefaultBrewingCategory;
@@ -45,6 +45,7 @@ import net.minecraft.client.gui.screen.ingame.*;
 import net.minecraft.client.gui.screen.recipebook.RecipeBookProvider;
 import net.minecraft.enchantment.Enchantment;
 import net.minecraft.enchantment.EnchantmentHelper;
+import net.minecraft.fluid.EmptyFluid;
 import net.minecraft.item.ItemConvertible;
 import net.minecraft.item.ItemStack;
 import net.minecraft.item.Items;
@@ -114,7 +115,8 @@ public class DefaultPlugin implements REIPluginV0 {
             }
         });
         Registry.FLUID.forEach(fluid -> {
-            entryRegistry.registerFluid(fluid);
+            if (!(fluid instanceof EmptyFluid))
+                entryRegistry.registerFluid(fluid);
         });
     }
     
@@ -258,33 +260,33 @@ public class DefaultPlugin implements REIPluginV0 {
                 return -1.0f;
             }
         });
-        displayHelper.registerBoundsHandler(new DisplayHelper.DisplayBoundsHandler<CreativeInventoryScreen>() {
-            @Override
-            public Class<?> getBaseSupportedClass() {
-                return CreativeInventoryScreen.class;
-            }
-            
-            @Override
-            public Rectangle getLeftBounds(CreativeInventoryScreen screen) {
-                return new Rectangle(2, 0, ScreenHelper.getLastContainerScreenHooks().rei_getContainerLeft() - 2, MinecraftClient.getInstance().window.getScaledHeight());
-            }
-            
-            @Override
-            public Rectangle getRightBounds(CreativeInventoryScreen screen) {
-                int startX = ScreenHelper.getLastContainerScreenHooks().rei_getContainerLeft() + ScreenHelper.getLastContainerScreenHooks().rei_getContainerWidth();
-                return new Rectangle(startX, 0, MinecraftClient.getInstance().window.getScaledWidth() - startX - 2, MinecraftClient.getInstance().window.getScaledHeight());
-            }
-            
-            @Override
-            public Rectangle getItemListArea(Rectangle rectangle) {
-                return new Rectangle(rectangle.x + 1, rectangle.y + 24, rectangle.width - 2, rectangle.height - (RoughlyEnoughItemsCore.getConfigManager().getConfig().isSideSearchField() ? 27 + 22 : 27));
-            }
-            
-            @Override
-            public float getPriority() {
-                return -0.9f;
-            }
-        });
+        //        displayHelper.registerBoundsHandler(new DisplayHelper.DisplayBoundsHandler<CreativeInventoryScreen>() {
+        //            @Override
+        //            public Class<?> getBaseSupportedClass() {
+        //                return CreativeInventoryScreen.class;
+        //            }
+        //
+        //            @Override
+        //            public Rectangle getLeftBounds(CreativeInventoryScreen screen) {
+        //                return new Rectangle(2, 0, ScreenHelper.getLastContainerScreenHooks().rei_getContainerLeft() - 2, MinecraftClient.getInstance().window.getScaledHeight());
+        //            }
+        //
+        //            @Override
+        //            public Rectangle getRightBounds(CreativeInventoryScreen screen) {
+        //                int startX = ScreenHelper.getLastContainerScreenHooks().rei_getContainerLeft() + ScreenHelper.getLastContainerScreenHooks().rei_getContainerWidth();
+        //                return new Rectangle(startX, 0, MinecraftClient.getInstance().window.getScaledWidth() - startX - 2, MinecraftClient.getInstance().window.getScaledHeight());
+        //            }
+        //
+        //            @Override
+        //            public Rectangle getItemListArea(Rectangle rectangle) {
+        //                return new Rectangle(rectangle.x + 1, rectangle.y + 24, rectangle.width - 2, rectangle.height - (RoughlyEnoughItemsCore.getConfigManager().getConfig().isSideSearchField() ? 27 + 22 : 27));
+        //            }
+        //
+        //            @Override
+        //            public float getPriority() {
+        //                return -0.9f;
+        //            }
+        //        });
     }
     
     @Override

+ 1 - 1
src/main/java/me/shedaniel/rei/plugin/DefaultPotionEffectExclusionZones.java

@@ -6,7 +6,7 @@
 package me.shedaniel.rei.plugin;
 
 import com.google.common.collect.Ordering;
-import me.shedaniel.rei.client.ScreenHelper;
+import me.shedaniel.rei.impl.ScreenHelper;
 import me.shedaniel.rei.listeners.AbstractInventoryScreenHooks;
 import me.shedaniel.rei.listeners.ContainerScreenHooks;
 import net.minecraft.client.MinecraftClient;

+ 1 - 1
src/main/java/me/shedaniel/rei/plugin/DefaultRecipeBookExclusionZones.java

@@ -6,7 +6,7 @@
 package me.shedaniel.rei.plugin;
 
 import com.google.common.collect.Lists;
-import me.shedaniel.rei.client.ScreenHelper;
+import me.shedaniel.rei.impl.ScreenHelper;
 import me.shedaniel.rei.listeners.ContainerScreenHooks;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.screen.recipebook.RecipeBookProvider;

+ 1 - 1
src/main/java/me/shedaniel/rei/plugin/autocrafting/AutoBlastingBookHandler.java

@@ -6,7 +6,7 @@
 package me.shedaniel.rei.plugin.autocrafting;
 
 import me.shedaniel.rei.api.AutoTransferHandler;
-import me.shedaniel.rei.client.ScreenHelper;
+import me.shedaniel.rei.impl.ScreenHelper;
 import me.shedaniel.rei.listeners.RecipeBookGuiHooks;
 import me.shedaniel.rei.plugin.blasting.DefaultBlastingDisplay;
 import net.minecraft.client.gui.screen.Screen;

+ 1 - 1
src/main/java/me/shedaniel/rei/plugin/autocrafting/AutoCraftingTableBookHandler.java

@@ -6,7 +6,7 @@
 package me.shedaniel.rei.plugin.autocrafting;
 
 import me.shedaniel.rei.api.AutoTransferHandler;
-import me.shedaniel.rei.client.ScreenHelper;
+import me.shedaniel.rei.impl.ScreenHelper;
 import me.shedaniel.rei.listeners.RecipeBookGuiHooks;
 import me.shedaniel.rei.plugin.crafting.DefaultCraftingDisplay;
 import net.minecraft.client.gui.screen.Screen;

+ 1 - 1
src/main/java/me/shedaniel/rei/plugin/autocrafting/AutoFurnaceBookHandler.java

@@ -6,7 +6,7 @@
 package me.shedaniel.rei.plugin.autocrafting;
 
 import me.shedaniel.rei.api.AutoTransferHandler;
-import me.shedaniel.rei.client.ScreenHelper;
+import me.shedaniel.rei.impl.ScreenHelper;
 import me.shedaniel.rei.listeners.RecipeBookGuiHooks;
 import me.shedaniel.rei.plugin.smelting.DefaultSmeltingDisplay;
 import net.minecraft.client.gui.screen.Screen;

+ 1 - 1
src/main/java/me/shedaniel/rei/plugin/autocrafting/AutoInventoryBookHandler.java

@@ -6,7 +6,7 @@
 package me.shedaniel.rei.plugin.autocrafting;
 
 import me.shedaniel.rei.api.AutoTransferHandler;
-import me.shedaniel.rei.client.ScreenHelper;
+import me.shedaniel.rei.impl.ScreenHelper;
 import me.shedaniel.rei.listeners.RecipeBookGuiHooks;
 import me.shedaniel.rei.plugin.crafting.DefaultCraftingDisplay;
 import net.minecraft.client.gui.screen.Screen;

+ 1 - 1
src/main/java/me/shedaniel/rei/plugin/autocrafting/AutoSmokerBookHandler.java

@@ -6,7 +6,7 @@
 package me.shedaniel.rei.plugin.autocrafting;
 
 import me.shedaniel.rei.api.AutoTransferHandler;
-import me.shedaniel.rei.client.ScreenHelper;
+import me.shedaniel.rei.impl.ScreenHelper;
 import me.shedaniel.rei.listeners.RecipeBookGuiHooks;
 import me.shedaniel.rei.plugin.smoking.DefaultSmokingDisplay;
 import net.minecraft.client.gui.screen.Screen;

+ 1 - 1
src/main/java/me/shedaniel/rei/plugin/campfire/DefaultCampfireCategory.java

@@ -8,7 +8,7 @@ package me.shedaniel.rei.plugin.campfire;
 import com.mojang.blaze3d.platform.GlStateManager;
 import me.shedaniel.rei.api.RecipeCategory;
 import me.shedaniel.rei.api.Renderer;
-import me.shedaniel.rei.client.ScreenHelper;
+import me.shedaniel.rei.impl.ScreenHelper;
 import me.shedaniel.rei.gui.widget.RecipeBaseWidget;
 import me.shedaniel.rei.gui.widget.SlotWidget;
 import me.shedaniel.rei.gui.widget.Widget;

+ 4 - 6
src/main/resources/fabric.mod.json

@@ -17,8 +17,8 @@
   "entrypoints": {
     "client": [
       "me.shedaniel.rei.RoughlyEnoughItemsCore",
-      "me.shedaniel.rei.client.ClientHelperImpl",
-      "me.shedaniel.rei.client.ScreenHelper"
+      "me.shedaniel.rei.impl.ClientHelperImpl",
+      "me.shedaniel.rei.impl.ScreenHelper"
     ],
     "main": [
       "me.shedaniel.rei.RoughlyEnoughItemsNetwork"
@@ -33,10 +33,8 @@
   },
   "depends": {
     "fabricloader": ">=0.4.0",
-    "cloth": "*"
-  },
-  "recommends": {
-    "cloth-config2": ">=0.1.0"
+    "cloth": "*",
+    "cloth-config2": ">=0.5.2"
   },
   "mixins": [
     "mixin.roughlyenoughitems.json",