Pārlūkot izejas kodu

4.0.13

Signed-off-by: shedaniel <daniel@shedaniel.me>
shedaniel 5 gadi atpakaļ
vecāks
revīzija
98199073c4
64 mainītis faili ar 500 papildinājumiem un 302 dzēšanām
  1. 2 2
      gradle.properties
  2. 11 11
      src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java
  3. 2 2
      src/main/java/me/shedaniel/rei/RoughlyEnoughItemsNetwork.java
  4. 17 11
      src/main/java/me/shedaniel/rei/api/AutoTransferHandler.java
  5. 2 1
      src/main/java/me/shedaniel/rei/api/DrawableConsumer.java
  6. 18 1
      src/main/java/me/shedaniel/rei/api/EntryStack.java
  7. 12 1
      src/main/java/me/shedaniel/rei/api/REIHelper.java
  8. 3 3
      src/main/java/me/shedaniel/rei/api/RecipeCategory.java
  9. 3 3
      src/main/java/me/shedaniel/rei/api/RecipeHelper.java
  10. 15 1
      src/main/java/me/shedaniel/rei/api/widgets/Slot.java
  11. 59 0
      src/main/java/me/shedaniel/rei/api/widgets/Tooltip.java
  12. 54 23
      src/main/java/me/shedaniel/rei/api/widgets/Widgets.java
  13. 23 25
      src/main/java/me/shedaniel/rei/gui/ContainerScreenOverlay.java
  14. 4 4
      src/main/java/me/shedaniel/rei/gui/PreRecipeViewingScreen.java
  15. 15 17
      src/main/java/me/shedaniel/rei/gui/RecipeViewingScreen.java
  16. 11 8
      src/main/java/me/shedaniel/rei/gui/VillagerRecipeViewingScreen.java
  17. 3 3
      src/main/java/me/shedaniel/rei/gui/config/entry/FilteringEntry.java
  18. 3 3
      src/main/java/me/shedaniel/rei/gui/credits/CreditsScreen.java
  19. 8 1
      src/main/java/me/shedaniel/rei/gui/entries/RecipeEntry.java
  20. 15 13
      src/main/java/me/shedaniel/rei/gui/entries/SimpleRecipeEntry.java
  21. 9 8
      src/main/java/me/shedaniel/rei/gui/widget/AutoCraftingButtonWidget.java
  22. 3 2
      src/main/java/me/shedaniel/rei/gui/widget/ButtonWidget.java
  23. 7 1
      src/main/java/me/shedaniel/rei/gui/widget/CategoryBaseWidget.java
  24. 3 2
      src/main/java/me/shedaniel/rei/gui/widget/ClickableLabelWidget.java
  25. 2 1
      src/main/java/me/shedaniel/rei/gui/widget/EntryListWidget.java
  26. 9 4
      src/main/java/me/shedaniel/rei/gui/widget/EntryWidget.java
  27. 2 1
      src/main/java/me/shedaniel/rei/gui/widget/FavoritesListWidget.java
  28. 2 1
      src/main/java/me/shedaniel/rei/gui/widget/LabelWidget.java
  29. 20 17
      src/main/java/me/shedaniel/rei/gui/widget/QueuedTooltip.java
  30. 6 0
      src/main/java/me/shedaniel/rei/gui/widget/RecipeBaseWidget.java
  31. 5 3
      src/main/java/me/shedaniel/rei/gui/widget/RecipeChoosePageWidget.java
  32. 7 0
      src/main/java/me/shedaniel/rei/gui/widget/SlotBaseWidget.java
  33. 3 2
      src/main/java/me/shedaniel/rei/gui/widget/TabWidget.java
  34. 4 0
      src/main/java/me/shedaniel/rei/gui/widget/Widget.java
  35. 2 2
      src/main/java/me/shedaniel/rei/impl/ClientHelperImpl.java
  36. 1 1
      src/main/java/me/shedaniel/rei/impl/ConfigManagerImpl.java
  37. 1 0
      src/main/java/me/shedaniel/rei/impl/DisplayHelperImpl.java
  38. 3 3
      src/main/java/me/shedaniel/rei/impl/EmptyEntryStack.java
  39. 4 3
      src/main/java/me/shedaniel/rei/impl/FluidEntryStack.java
  40. 4 3
      src/main/java/me/shedaniel/rei/impl/ItemEntryStack.java
  41. 6 6
      src/main/java/me/shedaniel/rei/impl/RecipeHelperImpl.java
  42. 3 1
      src/main/java/me/shedaniel/rei/impl/RenderingEntry.java
  43. 35 15
      src/main/java/me/shedaniel/rei/impl/ScreenHelper.java
  44. 3 2
      src/main/java/me/shedaniel/rei/impl/SearchArgument.java
  45. 2 1
      src/main/java/me/shedaniel/rei/impl/widgets/BurningFireWidget.java
  46. 3 1
      src/main/java/me/shedaniel/rei/impl/widgets/DrawableWidget.java
  47. 4 2
      src/main/java/me/shedaniel/rei/impl/widgets/FillRectangleDrawableConsumer.java
  48. 6 6
      src/main/java/me/shedaniel/rei/impl/widgets/LabelWidget.java
  49. 6 6
      src/main/java/me/shedaniel/rei/impl/widgets/PanelWidget.java
  50. 4 2
      src/main/java/me/shedaniel/rei/impl/widgets/TexturedDrawableConsumer.java
  51. 1 1
      src/main/java/me/shedaniel/rei/listeners/AbstractInventoryScreenHooks.java
  52. 2 2
      src/main/java/me/shedaniel/rei/listeners/ContainerScreenHooks.java
  53. 14 12
      src/main/java/me/shedaniel/rei/plugin/DefaultPlugin.java
  54. 2 2
      src/main/java/me/shedaniel/rei/plugin/DefaultPotionEffectExclusionZones.java
  55. 4 4
      src/main/java/me/shedaniel/rei/plugin/DefaultRecipeBookExclusionZones.java
  56. 1 1
      src/main/java/me/shedaniel/rei/plugin/DefaultServerContainerPlugin.java
  57. 2 2
      src/main/java/me/shedaniel/rei/plugin/autocrafting/DefaultCategoryHandler.java
  58. 10 10
      src/main/java/me/shedaniel/rei/plugin/autocrafting/DefaultRecipeBookHandler.java
  59. 5 13
      src/main/java/me/shedaniel/rei/plugin/beacon/DefaultBeaconBaseCategory.java
  60. 0 8
      src/main/java/me/shedaniel/rei/plugin/composting/DefaultCompostingCategory.java
  61. 4 4
      src/main/java/me/shedaniel/rei/plugin/containers/CraftingContainerInfoWrapper.java
  62. 2 2
      src/main/java/me/shedaniel/rei/plugin/crafting/DefaultCraftingCategory.java
  63. 4 4
      src/main/java/me/shedaniel/rei/plugin/fuel/DefaultFuelCategory.java
  64. 0 8
      src/main/java/me/shedaniel/rei/plugin/information/DefaultInformationCategory.java

+ 2 - 2
gradle.properties

@@ -1,6 +1,6 @@
-mod_version=4.0.12-unstable
+mod_version=4.0.13-unstable
 minecraft_version=20w11a
 minecraft_version=20w11a
-yarn_version=20w11a+build.1
+yarn_version=20w11a+build.6
 fabricloader_version=0.7.8+build.187
 fabricloader_version=0.7.8+build.187
 cloth_events_version=2.0.0-unstable.202003051905
 cloth_events_version=2.0.0-unstable.202003051905
 cloth_config_version=3.0.2-unstable.202003090708
 cloth_config_version=3.0.2-unstable.202003090708

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

@@ -40,10 +40,10 @@ import net.fabricmc.loader.api.ModContainer;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.gui.screen.Screen;
 import net.minecraft.client.gui.screen.Screen;
-import net.minecraft.client.gui.screen.ingame.CraftingTableScreen;
+import net.minecraft.client.gui.screen.ingame.CraftingScreen;
 import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen;
 import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen;
+import net.minecraft.client.gui.screen.ingame.HandledScreen;
 import net.minecraft.client.gui.screen.ingame.InventoryScreen;
 import net.minecraft.client.gui.screen.ingame.InventoryScreen;
-import net.minecraft.client.gui.screen.ingame.ScreenWithHandler;
 import net.minecraft.client.gui.screen.recipebook.RecipeBookGhostSlots;
 import net.minecraft.client.gui.screen.recipebook.RecipeBookGhostSlots;
 import net.minecraft.client.gui.screen.recipebook.RecipeBookProvider;
 import net.minecraft.client.gui.screen.recipebook.RecipeBookProvider;
 import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget;
 import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget;
@@ -54,7 +54,7 @@ import net.minecraft.item.ItemStack;
 import net.minecraft.item.Items;
 import net.minecraft.item.Items;
 import net.minecraft.recipe.Ingredient;
 import net.minecraft.recipe.Ingredient;
 import net.minecraft.recipe.RecipeManager;
 import net.minecraft.recipe.RecipeManager;
-import net.minecraft.screen.CraftingTableScreenHandler;
+import net.minecraft.screen.CraftingScreenHandler;
 import net.minecraft.screen.slot.Slot;
 import net.minecraft.screen.slot.Slot;
 import net.minecraft.text.LiteralText;
 import net.minecraft.text.LiteralText;
 import net.minecraft.util.ActionResult;
 import net.minecraft.util.ActionResult;
@@ -188,7 +188,7 @@ public class RoughlyEnoughItemsCore implements ClientModInitializer {
         });
         });
         ClientSidePacketRegistry.INSTANCE.register(RoughlyEnoughItemsNetwork.NOT_ENOUGH_ITEMS_PACKET, (packetContext, packetByteBuf) -> {
         ClientSidePacketRegistry.INSTANCE.register(RoughlyEnoughItemsNetwork.NOT_ENOUGH_ITEMS_PACKET, (packetContext, packetByteBuf) -> {
             Screen currentScreen = MinecraftClient.getInstance().currentScreen;
             Screen currentScreen = MinecraftClient.getInstance().currentScreen;
-            if (currentScreen instanceof CraftingTableScreen) {
+            if (currentScreen instanceof CraftingScreen) {
                 RecipeBookWidget recipeBookGui = ((RecipeBookProvider) currentScreen).getRecipeBookWidget();
                 RecipeBookWidget recipeBookGui = ((RecipeBookProvider) currentScreen).getRecipeBookWidget();
                 RecipeBookGhostSlots ghostSlots = ((RecipeBookGuiHooks) recipeBookGui).rei_getGhostSlots();
                 RecipeBookGhostSlots ghostSlots = ((RecipeBookGuiHooks) recipeBookGui).rei_getGhostSlots();
                 ghostSlots.reset();
                 ghostSlots.reset();
@@ -205,12 +205,12 @@ public class RoughlyEnoughItemsCore implements ClientModInitializer {
                 }
                 }
                 
                 
                 ghostSlots.addSlot(Ingredient.ofItems(Items.STONE), 381203812, 12738291);
                 ghostSlots.addSlot(Ingredient.ofItems(Items.STONE), 381203812, 12738291);
-                CraftingTableScreenHandler screenHandler = ((CraftingTableScreen) currentScreen).getScreenHandler();
+                CraftingScreenHandler screenHandler = ((CraftingScreen) currentScreen).getScreenHandler();
                 for (int i = 0; i < input.size(); i++) {
                 for (int i = 0; i < input.size(); i++) {
                     List<ItemStack> stacks = input.get(i);
                     List<ItemStack> stacks = input.get(i);
                     if (!stacks.isEmpty()) {
                     if (!stacks.isEmpty()) {
                         Slot slot = screenHandler.getSlot(i + screenHandler.getCraftingResultSlotIndex() + 1);
                         Slot slot = screenHandler.getSlot(i + screenHandler.getCraftingResultSlotIndex() + 1);
-                        ghostSlots.addSlot(Ingredient.ofStacks(stacks.toArray(new ItemStack[0])), slot.xPosition, slot.yPosition);
+                        ghostSlots.addSlot(Ingredient.ofStacks(stacks.toArray(new ItemStack[0])), slot.x, slot.y);
                     }
                     }
                 }
                 }
             }
             }
@@ -253,7 +253,7 @@ public class RoughlyEnoughItemsCore implements ClientModInitializer {
                 continue;
                 continue;
             ActionResult result = decider.shouldScreenBeOverlayed(screen);
             ActionResult result = decider.shouldScreenBeOverlayed(screen);
             if (result != ActionResult.PASS)
             if (result != ActionResult.PASS)
-                return result == ActionResult.FAIL || ScreenHelper.getLastScreenWithHandlerHooks() == null;
+                return result == ActionResult.FAIL || ScreenHelper.getLastHandledScreen() == null;
         }
         }
         return true;
         return true;
     }
     }
@@ -263,7 +263,7 @@ public class RoughlyEnoughItemsCore implements ClientModInitializer {
         long[] lastSync = {-1};
         long[] lastSync = {-1};
         ClothClientHooks.SYNC_RECIPES.register((minecraftClient, recipeManager, synchronizeRecipesS2CPacket) -> syncRecipes(lastSync));
         ClothClientHooks.SYNC_RECIPES.register((minecraftClient, recipeManager, synchronizeRecipesS2CPacket) -> syncRecipes(lastSync));
         ClothClientHooks.SCREEN_ADD_BUTTON.register((minecraftClient, screen, abstractButtonWidget) -> {
         ClothClientHooks.SCREEN_ADD_BUTTON.register((minecraftClient, screen, abstractButtonWidget) -> {
-            if (ConfigObject.getInstance().doesDisableRecipeBook() && screen instanceof ScreenWithHandler && abstractButtonWidget instanceof TexturedButtonWidget)
+            if (ConfigObject.getInstance().doesDisableRecipeBook() && screen instanceof HandledScreen && abstractButtonWidget instanceof TexturedButtonWidget)
                 if (((RecipeBookButtonWidgetHooks) abstractButtonWidget).rei_getTexture().equals(recipeButtonTex))
                 if (((RecipeBookButtonWidgetHooks) abstractButtonWidget).rei_getTexture().equals(recipeButtonTex))
                     return ActionResult.FAIL;
                     return ActionResult.FAIL;
             return ActionResult.PASS;
             return ActionResult.PASS;
@@ -273,8 +273,8 @@ public class RoughlyEnoughItemsCore implements ClientModInitializer {
                 return;
                 return;
             if (shouldReturn(screen.getClass()))
             if (shouldReturn(screen.getClass()))
                 return;
                 return;
-            if (screen instanceof ScreenWithHandler)
-                ScreenHelper.setLastScreenWithHandler((ScreenWithHandler<?>) screen);
+            if (screen instanceof HandledScreen)
+                ScreenHelper.setLastHandledScreen((HandledScreen<?>) screen);
             boolean alreadyAdded = false;
             boolean alreadyAdded = false;
             for (Element element : Lists.newArrayList(screenHooks.cloth_getChildren()))
             for (Element element : Lists.newArrayList(screenHooks.cloth_getChildren()))
                 if (ContainerScreenOverlay.class.isAssignableFrom(element.getClass()))
                 if (ContainerScreenOverlay.class.isAssignableFrom(element.getClass()))
@@ -335,7 +335,7 @@ public class RoughlyEnoughItemsCore implements ClientModInitializer {
                 return ActionResult.PASS;
                 return ActionResult.PASS;
             if (ScreenHelper.getLastOverlay().keyPressed(i, i1, i2))
             if (ScreenHelper.getLastOverlay().keyPressed(i, i1, i2))
                 return ActionResult.SUCCESS;
                 return ActionResult.SUCCESS;
-            if (screen instanceof ScreenWithHandler && ConfigObject.getInstance().doesDisableRecipeBook() && ConfigObject.getInstance().doesFixTabCloseContainer())
+            if (screen instanceof HandledScreen && ConfigObject.getInstance().doesDisableRecipeBook() && ConfigObject.getInstance().doesFixTabCloseContainer())
                 if (i == 258 && minecraftClient.options.keyInventory.matchesKey(i, i1)) {
                 if (i == 258 && minecraftClient.options.keyInventory.matchesKey(i, i1)) {
                     minecraftClient.player.closeHandledScreen();
                     minecraftClient.player.closeHandledScreen();
                     return ActionResult.SUCCESS;
                     return ActionResult.SUCCESS;

+ 2 - 2
src/main/java/me/shedaniel/rei/RoughlyEnoughItemsNetwork.java

@@ -31,7 +31,7 @@ import net.fabricmc.api.ModInitializer;
 import net.fabricmc.fabric.api.network.ServerSidePacketRegistry;
 import net.fabricmc.fabric.api.network.ServerSidePacketRegistry;
 import net.fabricmc.loader.api.FabricLoader;
 import net.fabricmc.loader.api.FabricLoader;
 import net.minecraft.item.ItemStack;
 import net.minecraft.item.ItemStack;
-import net.minecraft.screen.CraftingScreenHandler;
+import net.minecraft.screen.AbstractRecipeScreenHandler;
 import net.minecraft.screen.PlayerScreenHandler;
 import net.minecraft.screen.PlayerScreenHandler;
 import net.minecraft.screen.ScreenHandler;
 import net.minecraft.screen.ScreenHandler;
 import net.minecraft.server.network.ServerPlayerEntity;
 import net.minecraft.server.network.ServerPlayerEntity;
@@ -96,7 +96,7 @@ public class RoughlyEnoughItemsNetwork implements ModInitializer {
                 try {
                 try {
                     InputSlotCrafter.start(category, screenHandler, player, input, shift);
                     InputSlotCrafter.start(category, screenHandler, player, input, shift);
                 } catch (InputSlotCrafter.NotEnoughMaterialsException e) {
                 } catch (InputSlotCrafter.NotEnoughMaterialsException e) {
-                    if (!(screenHandler instanceof CraftingScreenHandler))
+                    if (!(screenHandler instanceof AbstractRecipeScreenHandler))
                         return;
                         return;
                     PacketByteBuf buf = new PacketByteBuf(Unpooled.buffer());
                     PacketByteBuf buf = new PacketByteBuf(Unpooled.buffer());
                     buf.writeInt(input.size());
                     buf.writeInt(input.size());

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

@@ -28,7 +28,7 @@ import it.unimi.dsi.fastutil.ints.IntList;
 import me.shedaniel.rei.gui.ContainerScreenOverlay;
 import me.shedaniel.rei.gui.ContainerScreenOverlay;
 import me.shedaniel.rei.impl.ScreenHelper;
 import me.shedaniel.rei.impl.ScreenHelper;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.MinecraftClient;
-import net.minecraft.client.gui.screen.ingame.ScreenWithHandler;
+import net.minecraft.client.gui.screen.ingame.HandledScreen;
 import net.minecraft.screen.ScreenHandler;
 import net.minecraft.screen.ScreenHandler;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.ApiStatus;
 
 
@@ -82,8 +82,8 @@ public interface AutoTransferHandler {
     }
     }
     
     
     interface Context {
     interface Context {
-        static Context create(boolean actuallyCrafting, ScreenWithHandler<?> containerScreen, RecipeDisplay recipeDisplay) {
-            return new ContextImpl(actuallyCrafting, containerScreen, () -> recipeDisplay);
+        static Context create(boolean actuallyCrafting, HandledScreen<?> handledScreen, RecipeDisplay recipeDisplay) {
+            return new ContextImpl(actuallyCrafting, handledScreen, () -> recipeDisplay);
         }
         }
         
         
         default MinecraftClient getMinecraft() {
         default MinecraftClient getMinecraft() {
@@ -92,12 +92,18 @@ public interface AutoTransferHandler {
         
         
         boolean isActuallyCrafting();
         boolean isActuallyCrafting();
         
         
-        ScreenWithHandler<?> getScreenWithHandler();
+        HandledScreen<?> getHandledScreen();
         
         
         @Deprecated
         @Deprecated
         @ApiStatus.ScheduledForRemoval
         @ApiStatus.ScheduledForRemoval
-        default ScreenWithHandler<?> getContainerScreen() {
-            return getScreenWithHandler();
+        default HandledScreen<?> getScreenWithHandler() {
+            return getHandledScreen();
+        }
+        
+        @Deprecated
+        @ApiStatus.ScheduledForRemoval
+        default HandledScreen<?> getContainerScreen() {
+            return getHandledScreen();
         }
         }
         
         
         RecipeDisplay getRecipe();
         RecipeDisplay getRecipe();
@@ -174,12 +180,12 @@ public interface AutoTransferHandler {
     @ApiStatus.Internal
     @ApiStatus.Internal
     final class ContextImpl implements Context {
     final class ContextImpl implements Context {
         boolean actuallyCrafting;
         boolean actuallyCrafting;
-        ScreenWithHandler<?> screenWithHandler;
+        HandledScreen<?> handledScreen;
         Supplier<RecipeDisplay> recipeDisplaySupplier;
         Supplier<RecipeDisplay> recipeDisplaySupplier;
         
         
-        private ContextImpl(boolean actuallyCrafting, ScreenWithHandler<?> screenWithHandler, Supplier<RecipeDisplay> recipeDisplaySupplier) {
+        private ContextImpl(boolean actuallyCrafting, HandledScreen<?> handledScreen, Supplier<RecipeDisplay> recipeDisplaySupplier) {
             this.actuallyCrafting = actuallyCrafting;
             this.actuallyCrafting = actuallyCrafting;
-            this.screenWithHandler = screenWithHandler;
+            this.handledScreen = handledScreen;
             this.recipeDisplaySupplier = recipeDisplaySupplier;
             this.recipeDisplaySupplier = recipeDisplaySupplier;
         }
         }
         
         
@@ -189,8 +195,8 @@ public interface AutoTransferHandler {
         }
         }
         
         
         @Override
         @Override
-        public ScreenWithHandler<?> getScreenWithHandler() {
-            return screenWithHandler;
+        public HandledScreen<?> getHandledScreen() {
+            return handledScreen;
         }
         }
         
         
         @Override
         @Override

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

@@ -24,10 +24,11 @@
 package me.shedaniel.rei.api;
 package me.shedaniel.rei.api;
 
 
 import net.minecraft.client.gui.DrawableHelper;
 import net.minecraft.client.gui.DrawableHelper;
+import org.jetbrains.annotations.NotNull;
 
 
 /**
 /**
  * Consumer of a {@link DrawableHelper} and information of mouse and delta.
  * Consumer of a {@link DrawableHelper} and information of mouse and delta.
  */
  */
 public interface DrawableConsumer {
 public interface DrawableConsumer {
-    void render(DrawableHelper helper, int mouseX, int mouseY, float delta);
+    void render(@NotNull DrawableHelper helper, int mouseX, int mouseY, float delta);
 }
 }

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

@@ -25,7 +25,9 @@ package me.shedaniel.rei.api;
 
 
 import com.google.gson.JsonElement;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonObject;
 import com.google.gson.JsonObject;
+import me.shedaniel.math.Point;
 import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.math.api.Rectangle;
+import me.shedaniel.rei.api.widgets.Tooltip;
 import me.shedaniel.rei.gui.widget.QueuedTooltip;
 import me.shedaniel.rei.gui.widget.QueuedTooltip;
 import me.shedaniel.rei.impl.EmptyEntryStack;
 import me.shedaniel.rei.impl.EmptyEntryStack;
 import me.shedaniel.rei.impl.FluidEntryStack;
 import me.shedaniel.rei.impl.FluidEntryStack;
@@ -229,7 +231,22 @@ public interface EntryStack {
     
     
     <T> T get(Settings<T> settings);
     <T> T get(Settings<T> settings);
     
     
-    @Nullable QueuedTooltip getTooltip(int mouseX, int mouseY);
+    /**
+     * @deprecated Use {@link #getTooltip(Point)}
+     */
+    @Nullable
+    @Deprecated
+    @ApiStatus.ScheduledForRemoval
+    default QueuedTooltip getTooltip(int mouseX, int mouseY) {
+        return null;
+    }
+    
+    @Nullable
+    default Tooltip getTooltip(Point point) {
+        QueuedTooltip tooltip = getTooltip(point.x, point.y);
+        if (tooltip == null) return null;
+        return Tooltip.create(new Point(tooltip.getX(), tooltip.getY()), tooltip.getText());
+    }
     
     
     void render(Rectangle bounds, int mouseX, int mouseY, float delta);
     void render(Rectangle bounds, int mouseX, int mouseY, float delta);
     
     

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

@@ -23,10 +23,12 @@
 
 
 package me.shedaniel.rei.api;
 package me.shedaniel.rei.api;
 
 
+import me.shedaniel.rei.api.widgets.Tooltip;
 import me.shedaniel.rei.gui.widget.QueuedTooltip;
 import me.shedaniel.rei.gui.widget.QueuedTooltip;
 import me.shedaniel.rei.gui.widget.TextFieldWidget;
 import me.shedaniel.rei.gui.widget.TextFieldWidget;
 import me.shedaniel.rei.impl.ScreenHelper;
 import me.shedaniel.rei.impl.ScreenHelper;
 import net.minecraft.item.ItemStack;
 import net.minecraft.item.ItemStack;
+import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.annotations.Nullable;
 
 
 import java.util.List;
 import java.util.List;
@@ -46,6 +48,15 @@ public interface REIHelper {
     
     
     List<ItemStack> getInventoryStacks();
     List<ItemStack> getInventoryStacks();
     
     
-    void addTooltip(@Nullable QueuedTooltip tooltip);
+    /**
+     * @deprecated Use {@link #queueTooltip(Tooltip)} or {@link Tooltip#queue()}
+     */
+    @Deprecated
+    @ApiStatus.ScheduledForRemoval
+    default void addTooltip(@Nullable QueuedTooltip tooltip) {
+        queueTooltip(tooltip);
+    }
+    
+    void queueTooltip(@Nullable Tooltip tooltip);
     
     
 }
 }

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

@@ -24,12 +24,12 @@
 package me.shedaniel.rei.api;
 package me.shedaniel.rei.api;
 
 
 import me.shedaniel.math.Rectangle;
 import me.shedaniel.math.Rectangle;
+import me.shedaniel.rei.api.widgets.Widgets;
 import me.shedaniel.rei.gui.RecipeViewingScreen;
 import me.shedaniel.rei.gui.RecipeViewingScreen;
 import me.shedaniel.rei.gui.entries.RecipeEntry;
 import me.shedaniel.rei.gui.entries.RecipeEntry;
 import me.shedaniel.rei.gui.entries.SimpleRecipeEntry;
 import me.shedaniel.rei.gui.entries.SimpleRecipeEntry;
-import me.shedaniel.rei.gui.widget.PanelWidget;
-import me.shedaniel.rei.gui.widget.RecipeBaseWidget;
 import me.shedaniel.rei.gui.widget.Widget;
 import me.shedaniel.rei.gui.widget.Widget;
+import me.shedaniel.rei.impl.widgets.PanelWidget;
 import net.minecraft.client.gui.DrawableHelper;
 import net.minecraft.client.gui.DrawableHelper;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.Identifier;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.ApiStatus;
@@ -87,7 +87,7 @@ public interface RecipeCategory<T extends RecipeDisplay> {
     @ApiStatus.ScheduledForRemoval
     @ApiStatus.ScheduledForRemoval
     @Deprecated
     @Deprecated
     default List<Widget> setupDisplay(Supplier<T> recipeDisplaySupplier, me.shedaniel.math.api.Rectangle bounds) {
     default List<Widget> setupDisplay(Supplier<T> recipeDisplaySupplier, me.shedaniel.math.api.Rectangle bounds) {
-        return Collections.singletonList(new RecipeBaseWidget(bounds));
+        return Collections.singletonList(Widgets.createCategoryBase(bounds));
     }
     }
     
     
     /**
     /**

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

@@ -25,7 +25,7 @@ package me.shedaniel.rei.api;
 
 
 import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.rei.RoughlyEnoughItemsCore;
 import me.shedaniel.rei.RoughlyEnoughItemsCore;
-import net.minecraft.client.gui.screen.ingame.ScreenWithHandler;
+import net.minecraft.client.gui.screen.ingame.HandledScreen;
 import net.minecraft.recipe.Recipe;
 import net.minecraft.recipe.Recipe;
 import net.minecraft.recipe.RecipeManager;
 import net.minecraft.recipe.RecipeManager;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.Identifier;
@@ -220,7 +220,7 @@ public interface RecipeHelper {
      */
      */
     void registerLiveRecipeGenerator(LiveRecipeGenerator<?> liveRecipeGenerator);
     void registerLiveRecipeGenerator(LiveRecipeGenerator<?> liveRecipeGenerator);
     
     
-    void registerScreenClickArea(Rectangle rectangle, Class<? extends ScreenWithHandler<?>> screenClass, Identifier... categories);
+    void registerScreenClickArea(Rectangle rectangle, Class<? extends HandledScreen<?>> screenClass, Identifier... categories);
     
     
     <T extends Recipe<?>> void registerRecipes(Identifier category, Class<T> recipeClass, Function<T, RecipeDisplay> mappingFunction);
     <T extends Recipe<?>> void registerRecipes(Identifier category, Class<T> recipeClass, Function<T, RecipeDisplay> mappingFunction);
     
     
@@ -232,7 +232,7 @@ public interface RecipeHelper {
     boolean arePluginsLoading();
     boolean arePluginsLoading();
     
     
     interface ScreenClickArea {
     interface ScreenClickArea {
-        Class<? extends ScreenWithHandler> getScreenClass();
+        Class<? extends HandledScreen> getScreenClass();
         
         
         Rectangle getRectangle();
         Rectangle getRectangle();
         
         

+ 15 - 1
src/main/java/me/shedaniel/rei/api/widgets/Slot.java

@@ -23,9 +23,11 @@
 
 
 package me.shedaniel.rei.api.widgets;
 package me.shedaniel.rei.api.widgets;
 
 
+import me.shedaniel.math.Point;
 import me.shedaniel.rei.api.EntryStack;
 import me.shedaniel.rei.api.EntryStack;
 import me.shedaniel.rei.gui.widget.QueuedTooltip;
 import me.shedaniel.rei.gui.widget.QueuedTooltip;
 import me.shedaniel.rei.gui.widget.WidgetWithBounds;
 import me.shedaniel.rei.gui.widget.WidgetWithBounds;
+import org.jetbrains.annotations.Nullable;
 
 
 import java.util.Collection;
 import java.util.Collection;
 import java.util.List;
 import java.util.List;
@@ -123,5 +125,17 @@ public abstract class Slot extends WidgetWithBounds {
     
     
     public abstract List<EntryStack> getEntries();
     public abstract List<EntryStack> getEntries();
     
     
-    public abstract QueuedTooltip getCurrentTooltip(int mouseX, int mouseY);
+    /**
+     * @deprecated use {@link #getCurrentTooltip(Point)}
+     */
+    @Nullable
+    @Deprecated
+    public QueuedTooltip getCurrentTooltip(int mouseX, int mouseY) {
+        return null;
+    }
+    
+    @Nullable
+    public Tooltip getCurrentTooltip(Point point) {
+        return getCurrentTooltip(point.x, point.y);
+    }
 }
 }

+ 59 - 0
src/main/java/me/shedaniel/rei/api/widgets/Tooltip.java

@@ -0,0 +1,59 @@
+/*
+ * This file is licensed under the MIT License, part of Roughly Enough Items.
+ * Copyright (c) 2018, 2019, 2020 shedaniel
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package me.shedaniel.rei.api.widgets;
+
+import me.shedaniel.math.Point;
+import me.shedaniel.rei.api.REIHelper;
+import me.shedaniel.rei.gui.widget.QueuedTooltip;
+
+import java.util.Collection;
+import java.util.List;
+
+public interface Tooltip {
+    static Tooltip create(Point point, Collection<String> texts) {
+        return QueuedTooltip.create(point, texts);
+    }
+    
+    static Tooltip create(Point point, String... texts) {
+        return QueuedTooltip.create(point, texts);
+    }
+    
+    static Tooltip create(Collection<String> texts) {
+        return QueuedTooltip.create(texts);
+    }
+    
+    static Tooltip create(String... texts) {
+        return QueuedTooltip.create(texts);
+    }
+    
+    int getX();
+    
+    int getY();
+    
+    List<String> getText();
+    
+    default void queue() {
+        REIHelper.getInstance().queueTooltip(this);
+    }
+}

+ 54 - 23
src/main/java/me/shedaniel/rei/api/widgets/Widgets.java

@@ -43,96 +43,127 @@ import java.util.function.Consumer;
 public final class Widgets {
 public final class Widgets {
     private Widgets() {}
     private Widgets() {}
     
     
-    public static Widget createDrawableWidget(DrawableConsumer drawable) {
+    @NotNull
+    public static Widget createDrawableWidget(@NotNull DrawableConsumer drawable) {
         return new DrawableWidget(drawable);
         return new DrawableWidget(drawable);
     }
     }
     
     
-    public static Widget createTexturedWidget(Identifier identifier, Rectangle bounds) {
+    @NotNull
+    public static Widget createTexturedWidget(@NotNull Identifier identifier, @NotNull Rectangle bounds) {
         return createTexturedWidget(identifier, bounds, 0, 0);
         return createTexturedWidget(identifier, bounds, 0, 0);
     }
     }
     
     
-    public static Widget createTexturedWidget(Identifier identifier, int x, int y, int width, int height) {
+    @NotNull
+    public static Widget createTexturedWidget(@NotNull Identifier identifier, int x, int y, int width, int height) {
         return createTexturedWidget(identifier, x, y, 0, 0, width, height);
         return createTexturedWidget(identifier, x, y, 0, 0, width, height);
     }
     }
     
     
-    public static Widget createTexturedWidget(Identifier identifier, Rectangle bounds, float u, float v) {
+    @NotNull
+    public static Widget createTexturedWidget(@NotNull Identifier identifier, @NotNull Rectangle bounds, float u, float v) {
         return createTexturedWidget(identifier, bounds, u, v, 256, 256);
         return createTexturedWidget(identifier, bounds, u, v, 256, 256);
     }
     }
     
     
-    public static Widget createTexturedWidget(Identifier identifier, int x, int y, float u, float v, int width, int height) {
+    @NotNull
+    public static Widget createTexturedWidget(@NotNull Identifier identifier, int x, int y, float u, float v, int width, int height) {
         return createTexturedWidget(identifier, x, y, u, v, width, height, 256, 256);
         return createTexturedWidget(identifier, x, y, u, v, width, height, 256, 256);
     }
     }
     
     
-    public static Widget createTexturedWidget(Identifier identifier, Rectangle bounds, float u, float v, int textureWidth, int textureHeight) {
+    @NotNull
+    public static Widget createTexturedWidget(@NotNull Identifier identifier, @NotNull Rectangle bounds, float u, float v, int textureWidth, int textureHeight) {
         return createTexturedWidget(identifier, bounds.x, bounds.y, u, v, bounds.width, bounds.height, bounds.width, bounds.height, textureWidth, textureHeight);
         return createTexturedWidget(identifier, bounds.x, bounds.y, u, v, bounds.width, bounds.height, bounds.width, bounds.height, textureWidth, textureHeight);
     }
     }
     
     
-    public static Widget createTexturedWidget(Identifier identifier, int x, int y, float u, float v, int width, int height, int textureWidth, int textureHeight) {
+    @NotNull
+    public static Widget createTexturedWidget(@NotNull Identifier identifier, int x, int y, float u, float v, int width, int height, int textureWidth, int textureHeight) {
         return createTexturedWidget(identifier, x, y, u, v, width, height, width, height, textureWidth, textureHeight);
         return createTexturedWidget(identifier, x, y, u, v, width, height, width, height, textureWidth, textureHeight);
     }
     }
     
     
-    public static Widget createTexturedWidget(Identifier identifier, Rectangle bounds, float u, float v, int uWidth, int vHeight, int textureWidth, int textureHeight) {
+    @NotNull
+    public static Widget createTexturedWidget(@NotNull Identifier identifier, @NotNull Rectangle bounds, float u, float v, int uWidth, int vHeight, int textureWidth, int textureHeight) {
         return createTexturedWidget(identifier, bounds.x, bounds.y, u, v, bounds.width, bounds.height, uWidth, vHeight, textureWidth, textureHeight);
         return createTexturedWidget(identifier, bounds.x, bounds.y, u, v, bounds.width, bounds.height, uWidth, vHeight, textureWidth, textureHeight);
     }
     }
     
     
-    public static Widget createTexturedWidget(Identifier identifier, int x, int y, float u, float v, int width, int height, int uWidth, int vHeight, int textureWidth, int textureHeight) {
+    @NotNull
+    public static Widget createTexturedWidget(@NotNull Identifier identifier, int x, int y, float u, float v, int width, int height, int uWidth, int vHeight, int textureWidth, int textureHeight) {
         return createDrawableWidget(new TexturedDrawableConsumer(identifier, x, y, width, height, u, v, uWidth, vHeight, textureWidth, textureHeight));
         return createDrawableWidget(new TexturedDrawableConsumer(identifier, x, y, width, height, u, v, uWidth, vHeight, textureWidth, textureHeight));
     }
     }
     
     
-    public static Widget createFilledRectangle(Rectangle rectangle, int color) {
+    @NotNull
+    public static Widget createFilledRectangle(@NotNull Rectangle rectangle, int color) {
         return createDrawableWidget(new FillRectangleDrawableConsumer(rectangle, color));
         return createDrawableWidget(new FillRectangleDrawableConsumer(rectangle, color));
     }
     }
     
     
-    public static Label createLabel(Point point, @NotNull String text) {
+    @NotNull
+    public static Label createLabel(@NotNull Point point, @NotNull String text) {
         return new LabelWidget(point, text);
         return new LabelWidget(point, text);
     }
     }
     
     
-    public static Label createClickableLabel(Point point, @NotNull String text, @Nullable Consumer<Label> onClick) {
+    @NotNull
+    public static Label createClickableLabel(@NotNull Point point, @NotNull String text, @Nullable Consumer<Label> onClick) {
         return new LabelWidget(point, text).clickable().onClick(onClick);
         return new LabelWidget(point, text).clickable().onClick(onClick);
     }
     }
     
     
-    public static Arrow createArrow(Point point) {
+    @NotNull
+    public static Arrow createArrow(@NotNull Point point) {
         return new ArrowWidget(new Rectangle(point, new Dimension(24, 17)));
         return new ArrowWidget(new Rectangle(point, new Dimension(24, 17)));
     }
     }
     
     
-    public static BurningFire createBurningFire(Point point) {
+    @NotNull
+    public static BurningFire createBurningFire(@NotNull Point point) {
         return new BurningFireWidget(new Rectangle(point, new Dimension(14, 14)));
         return new BurningFireWidget(new Rectangle(point, new Dimension(14, 14)));
     }
     }
     
     
-    public static Widget createSlotBackground(Point point) {
+    @NotNull
+    public static Widget createSlotBackground(@NotNull Point point) {
         return createSlotBase(new Rectangle(point.x - 1, point.y - 1, 18, 18));
         return createSlotBase(new Rectangle(point.x - 1, point.y - 1, 18, 18));
     }
     }
     
     
-    public static Widget createResultSlotBackground(Point point) {
+    @NotNull
+    public static Widget createResultSlotBackground(@NotNull Point point) {
         return createSlotBase(new Rectangle(point.x - 5, point.y - 5, 26, 26));
         return createSlotBase(new Rectangle(point.x - 5, point.y - 5, 26, 26));
     }
     }
     
     
-    public static Panel createRecipeBase(Rectangle rectangle) {
+    @NotNull
+    public static Panel createRecipeBase(@NotNull Rectangle rectangle) {
         return new PanelWidget(rectangle).yTextureOffset(ConfigObject.getInstance().getRecipeBorderType().getYOffset()).rendering(Widgets::shouldRecipeBaseRender);
         return new PanelWidget(rectangle).yTextureOffset(ConfigObject.getInstance().getRecipeBorderType().getYOffset()).rendering(Widgets::shouldRecipeBaseRender);
     }
     }
     
     
-    private static boolean shouldRecipeBaseRender(Panel panel) {
+    @NotNull
+    public static Panel createCategoryBase(@NotNull Rectangle rectangle) {
+        return new PanelWidget(rectangle).yTextureOffset(ConfigObject.getInstance().getRecipeBorderType().getYOffset()).rendering(Widgets::shouldSlotBaseRender);
+    }
+    
+    private static boolean shouldRecipeBaseRender(@NotNull Panel panel) {
         return ConfigObject.getInstance().getRecipeBorderType().isRendering() && PanelWidget.isRendering(panel);
         return ConfigObject.getInstance().getRecipeBorderType().isRendering() && PanelWidget.isRendering(panel);
     }
     }
     
     
-    public static Panel createRecipeBase(Rectangle rectangle, int color) {
+    @NotNull
+    public static Panel createRecipeBase(@NotNull Rectangle rectangle, int color) {
         return createRecipeBase(rectangle).color(color);
         return createRecipeBase(rectangle).color(color);
     }
     }
     
     
-    public static Panel createSlotBase(Rectangle rectangle) {
+    @NotNull
+    public static Panel createCategoryBase(@NotNull Rectangle rectangle, int color) {
+        return createCategoryBase(rectangle).color(color);
+    }
+    
+    @NotNull
+    public static Panel createSlotBase(@NotNull Rectangle rectangle) {
         return new PanelWidget(rectangle).yTextureOffset(-66).rendering(Widgets::shouldSlotBaseRender).innerColor(-7631989, -13619152);
         return new PanelWidget(rectangle).yTextureOffset(-66).rendering(Widgets::shouldSlotBaseRender).innerColor(-7631989, -13619152);
     }
     }
     
     
-    private static boolean shouldSlotBaseRender(Panel panel) {
+    private static boolean shouldSlotBaseRender(@NotNull Panel panel) {
         return true;
         return true;
     }
     }
     
     
-    public static Panel createSlotBase(Rectangle rectangle, int color) {
+    @NotNull
+    public static Panel createSlotBase(@NotNull Rectangle rectangle, int color) {
         return createSlotBase(rectangle).color(color);
         return createSlotBase(rectangle).color(color);
     }
     }
     
     
     @SuppressWarnings("deprecation")
     @SuppressWarnings("deprecation")
-    public static Slot createSlot(Point point) {
+    @NotNull
+    public static Slot createSlot(@NotNull Point point) {
         return EntryWidget.create(point.x, point.y);
         return EntryWidget.create(point.x, point.y);
     }
     }
     
     

+ 23 - 25
src/main/java/me/shedaniel/rei/gui/ContainerScreenOverlay.java

@@ -30,6 +30,7 @@ import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.math.impl.PointHelper;
 import me.shedaniel.math.impl.PointHelper;
 import me.shedaniel.rei.RoughlyEnoughItemsCore;
 import me.shedaniel.rei.RoughlyEnoughItemsCore;
 import me.shedaniel.rei.api.*;
 import me.shedaniel.rei.api.*;
+import me.shedaniel.rei.api.widgets.Tooltip;
 import me.shedaniel.rei.api.widgets.Widgets;
 import me.shedaniel.rei.api.widgets.Widgets;
 import me.shedaniel.rei.gui.config.SearchFieldLocation;
 import me.shedaniel.rei.gui.config.SearchFieldLocation;
 import me.shedaniel.rei.gui.widget.*;
 import me.shedaniel.rei.gui.widget.*;
@@ -40,7 +41,7 @@ import me.shedaniel.rei.utils.CollectionUtils;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.gui.screen.Screen;
 import net.minecraft.client.gui.screen.Screen;
-import net.minecraft.client.gui.screen.ingame.ScreenWithHandler;
+import net.minecraft.client.gui.screen.ingame.HandledScreen;
 import net.minecraft.client.render.Tessellator;
 import net.minecraft.client.render.Tessellator;
 import net.minecraft.client.render.VertexConsumerProvider;
 import net.minecraft.client.render.VertexConsumerProvider;
 import net.minecraft.client.resource.language.I18n;
 import net.minecraft.client.resource.language.I18n;
@@ -67,7 +68,7 @@ import java.util.*;
 public class ContainerScreenOverlay extends WidgetWithBounds {
 public class ContainerScreenOverlay extends WidgetWithBounds {
     
     
     private static final Identifier CHEST_GUI_TEXTURE = new Identifier("roughlyenoughitems", "textures/gui/recipecontainer.png");
     private static final Identifier CHEST_GUI_TEXTURE = new Identifier("roughlyenoughitems", "textures/gui/recipecontainer.png");
-    private static final List<QueuedTooltip> QUEUED_TOOLTIPS = Lists.newArrayList();
+    private static final List<Tooltip> TOOLTIPS = Lists.newArrayList();
     private static final EntryListWidget ENTRY_LIST_WIDGET = new EntryListWidget();
     private static final EntryListWidget ENTRY_LIST_WIDGET = new EntryListWidget();
     private static FavoritesListWidget favoritesListWidget = null;
     private static FavoritesListWidget favoritesListWidget = null;
     private final List<Widget> widgets = Lists.newLinkedList();
     private final List<Widget> widgets = Lists.newLinkedList();
@@ -180,7 +181,7 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
                     ClientHelper.getInstance().setCheating(!ClientHelper.getInstance().isCheating());
                     ClientHelper.getInstance().setCheating(!ClientHelper.getInstance().isCheating());
                     return;
                     return;
                 }
                 }
-                ConfigManager.getInstance().openConfigScreen(ScreenHelper.getLastScreenWithHandler());
+                ConfigManager.getInstance().openConfigScreen(ScreenHelper.getLastHandledScreen());
             }
             }
             
             
             @Override
             @Override
@@ -362,7 +363,7 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
             VillagerRecipeViewingScreen widget = (VillagerRecipeViewingScreen) MinecraftClient.getInstance().currentScreen;
             VillagerRecipeViewingScreen widget = (VillagerRecipeViewingScreen) MinecraftClient.getInstance().currentScreen;
             return new Rectangle(widget.bounds.x, window.getScaledHeight() - 22, widget.bounds.width - widthRemoved, 18);
             return new Rectangle(widget.bounds.x, window.getScaledHeight() - 22, widget.bounds.width - widthRemoved, 18);
         }
         }
-        return new Rectangle(ScreenHelper.getLastScreenWithHandlerHooks().rei_getContainerLeft(), window.getScaledHeight() - 22, ScreenHelper.getLastScreenWithHandlerHooks().rei_getContainerWidth() - widthRemoved, 18);
+        return new Rectangle(((ContainerScreenHooks) ScreenHelper.getLastHandledScreen()).rei_getContainerLeft(), window.getScaledHeight() - 22, ((ContainerScreenHooks) ScreenHelper.getLastHandledScreen()).rei_getContainerWidth() - widthRemoved, 18);
     }
     }
     
     
     private Rectangle getCraftableToggleArea() {
     private Rectangle getCraftableToggleArea() {
@@ -411,24 +412,24 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
         }
         }
         if (OverlaySearchField.isSearching) {
         if (OverlaySearchField.isSearching) {
             setZOffset(200);
             setZOffset(200);
-            if (MinecraftClient.getInstance().currentScreen instanceof ScreenWithHandler) {
+            if (MinecraftClient.getInstance().currentScreen instanceof HandledScreen) {
                 ContainerScreenHooks hooks = (ContainerScreenHooks) MinecraftClient.getInstance().currentScreen;
                 ContainerScreenHooks hooks = (ContainerScreenHooks) MinecraftClient.getInstance().currentScreen;
                 int left = hooks.rei_getContainerLeft(), top = hooks.rei_getContainerTop();
                 int left = hooks.rei_getContainerLeft(), top = hooks.rei_getContainerTop();
-                for (Slot slot : ((ScreenWithHandler<?>) MinecraftClient.getInstance().currentScreen).getScreenHandler().slots)
+                for (Slot slot : ((HandledScreen<?>) MinecraftClient.getInstance().currentScreen).getScreenHandler().slots)
                     if (!slot.hasStack() || !ENTRY_LIST_WIDGET.canLastSearchTermsBeAppliedTo(EntryStack.create(slot.getStack())))
                     if (!slot.hasStack() || !ENTRY_LIST_WIDGET.canLastSearchTermsBeAppliedTo(EntryStack.create(slot.getStack())))
-                        fillGradient(left + slot.xPosition, top + slot.yPosition, left + slot.xPosition + 16, top + slot.yPosition + 16, -601874400, -601874400);
+                        fillGradient(left + slot.x, top + slot.y, left + slot.x + 16, top + slot.y + 16, -601874400, -601874400);
             }
             }
             setZOffset(0);
             setZOffset(0);
         }
         }
         RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
         RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
         this.renderWidgets(mouseX, mouseY, delta);
         this.renderWidgets(mouseX, mouseY, delta);
-        if (MinecraftClient.getInstance().currentScreen instanceof ScreenWithHandler && ConfigObject.getInstance().areClickableRecipeArrowsEnabled()) {
+        if (MinecraftClient.getInstance().currentScreen instanceof HandledScreen && ConfigObject.getInstance().areClickableRecipeArrowsEnabled()) {
             ContainerScreenHooks hooks = (ContainerScreenHooks) MinecraftClient.getInstance().currentScreen;
             ContainerScreenHooks hooks = (ContainerScreenHooks) MinecraftClient.getInstance().currentScreen;
             for (RecipeHelper.ScreenClickArea area : RecipeHelper.getInstance().getScreenClickAreas())
             for (RecipeHelper.ScreenClickArea area : RecipeHelper.getInstance().getScreenClickAreas())
                 if (area.getScreenClass().equals(MinecraftClient.getInstance().currentScreen.getClass()))
                 if (area.getScreenClass().equals(MinecraftClient.getInstance().currentScreen.getClass()))
                     if (area.getRectangle().contains(mouseX - hooks.rei_getContainerLeft(), mouseY - hooks.rei_getContainerTop())) {
                     if (area.getRectangle().contains(mouseX - hooks.rei_getContainerLeft(), mouseY - hooks.rei_getContainerTop())) {
                         String collect = CollectionUtils.mapAndJoinToString(area.getCategories(), identifier -> RecipeHelper.getInstance().getCategory(identifier).getCategoryName(), ", ");
                         String collect = CollectionUtils.mapAndJoinToString(area.getCategories(), identifier -> RecipeHelper.getInstance().getCategory(identifier).getCategoryName(), ", ");
-                        QUEUED_TOOLTIPS.add(QueuedTooltip.create(I18n.translate("text.rei.view_recipes_for", collect)));
+                        TOOLTIPS.add(Tooltip.create(I18n.translate("text.rei.view_recipes_for", collect)));
                         break;
                         break;
                     }
                     }
         }
         }
@@ -443,18 +444,15 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
         }
         }
         Screen currentScreen = MinecraftClient.getInstance().currentScreen;
         Screen currentScreen = MinecraftClient.getInstance().currentScreen;
         if (!(currentScreen instanceof RecipeViewingScreen) || !((RecipeViewingScreen) currentScreen).choosePageActivated)
         if (!(currentScreen instanceof RecipeViewingScreen) || !((RecipeViewingScreen) currentScreen).choosePageActivated)
-            for (QueuedTooltip queuedTooltip : QUEUED_TOOLTIPS) {
-                if (queuedTooltip != null)
-                    renderTooltip(queuedTooltip);
+            for (Tooltip tooltip : TOOLTIPS) {
+                if (tooltip != null)
+                    renderTooltip(tooltip);
             }
             }
-        QUEUED_TOOLTIPS.clear();
+        TOOLTIPS.clear();
     }
     }
     
     
-    public void renderTooltip(QueuedTooltip tooltip) {
-        if (tooltip.getConsumer() == null)
-            renderTooltip(tooltip.getText(), tooltip.getX(), tooltip.getY());
-        else
-            tooltip.getConsumer().accept(tooltip);
+    public void renderTooltip(Tooltip tooltip) {
+        renderTooltip(tooltip.getText(), tooltip.getX(), tooltip.getY());
     }
     }
     
     
     public void renderTooltip(List<String> lines, int mouseX, int mouseY) {
     public void renderTooltip(List<String> lines, int mouseX, int mouseY) {
@@ -472,9 +470,9 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
         return CollectionUtils.mapAndJoinToString(list1, Object::toString, "").equals(CollectionUtils.mapAndJoinToString(list2, Object::toString, ""));
         return CollectionUtils.mapAndJoinToString(list1, Object::toString, "").equals(CollectionUtils.mapAndJoinToString(list2, Object::toString, ""));
     }
     }
     
     
-    public void addTooltip(@Nullable QueuedTooltip queuedTooltip) {
-        if (queuedTooltip != null)
-            QUEUED_TOOLTIPS.add(queuedTooltip);
+    public void addTooltip(@Nullable Tooltip tooltip) {
+        if (tooltip != null)
+            TOOLTIPS.add(tooltip);
     }
     }
     
     
     public void renderWidgets(int int_1, int int_2, float float_1) {
     public void renderWidgets(int int_1, int int_2, float float_1) {
@@ -527,9 +525,9 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
             return true;
             return true;
         }
         }
         ItemStack itemStack = null;
         ItemStack itemStack = null;
-        if (MinecraftClient.getInstance().currentScreen instanceof ScreenWithHandler)
-            if (ScreenHelper.getLastScreenWithHandlerHooks().rei_getHoveredSlot() != null && !ScreenHelper.getLastScreenWithHandlerHooks().rei_getHoveredSlot().getStack().isEmpty())
-                itemStack = ScreenHelper.getLastScreenWithHandlerHooks().rei_getHoveredSlot().getStack();
+        if (MinecraftClient.getInstance().currentScreen instanceof HandledScreen)
+            if (((ContainerScreenHooks) ScreenHelper.getLastHandledScreen()).rei_getHoveredSlot() != null && !((ContainerScreenHooks) ScreenHelper.getLastHandledScreen()).rei_getHoveredSlot().getStack().isEmpty())
+                itemStack = ((ContainerScreenHooks) ScreenHelper.getLastHandledScreen()).rei_getHoveredSlot().getStack();
         if (itemStack != null && !itemStack.isEmpty()) {
         if (itemStack != null && !itemStack.isEmpty()) {
             if (ConfigObject.getInstance().getRecipeKeybind().matchesKey(int_1, int_2))
             if (ConfigObject.getInstance().getRecipeKeybind().matchesKey(int_1, int_2))
                 return ClientHelper.getInstance().executeRecipeKeyBind(itemStack);
                 return ClientHelper.getInstance().executeRecipeKeyBind(itemStack);
@@ -569,7 +567,7 @@ public class ContainerScreenOverlay extends WidgetWithBounds {
     public boolean mouseClicked(double double_1, double double_2, int int_1) {
     public boolean mouseClicked(double double_1, double double_2, int int_1) {
         if (!ScreenHelper.isOverlayVisible())
         if (!ScreenHelper.isOverlayVisible())
             return false;
             return false;
-        if (MinecraftClient.getInstance().currentScreen instanceof ScreenWithHandler && ConfigObject.getInstance().areClickableRecipeArrowsEnabled()) {
+        if (MinecraftClient.getInstance().currentScreen instanceof HandledScreen && ConfigObject.getInstance().areClickableRecipeArrowsEnabled()) {
             ContainerScreenHooks hooks = (ContainerScreenHooks) MinecraftClient.getInstance().currentScreen;
             ContainerScreenHooks hooks = (ContainerScreenHooks) MinecraftClient.getInstance().currentScreen;
             for (RecipeHelper.ScreenClickArea area : RecipeHelper.getInstance().getScreenClickAreas())
             for (RecipeHelper.ScreenClickArea area : RecipeHelper.getInstance().getScreenClickAreas())
                 if (area.getScreenClass().equals(MinecraftClient.getInstance().currentScreen.getClass()))
                 if (area.getScreenClass().equals(MinecraftClient.getInstance().currentScreen.getClass()))

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

@@ -38,7 +38,7 @@ import me.shedaniel.rei.impl.ScreenHelper;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.gui.screen.Screen;
 import net.minecraft.client.gui.screen.Screen;
-import net.minecraft.client.gui.screen.ingame.ScreenWithHandler;
+import net.minecraft.client.gui.screen.ingame.HandledScreen;
 import net.minecraft.client.resource.language.I18n;
 import net.minecraft.client.resource.language.I18n;
 import net.minecraft.client.util.NarratorManager;
 import net.minecraft.client.util.NarratorManager;
 import net.minecraft.text.TranslatableText;
 import net.minecraft.text.TranslatableText;
@@ -169,7 +169,7 @@ public class PreRecipeViewingScreen extends Screen {
     public boolean keyPressed(int int_1, int int_2, int int_3) {
     public boolean keyPressed(int int_1, int int_2, int int_3) {
         if (int_1 == 256 || this.client.options.keyInventory.matchesKey(int_1, int_2)) {
         if (int_1 == 256 || this.client.options.keyInventory.matchesKey(int_1, int_2)) {
             MinecraftClient.getInstance().openScreen(parent);
             MinecraftClient.getInstance().openScreen(parent);
-            if (parent instanceof ScreenWithHandler)
+            if (parent instanceof HandledScreen)
                 ScreenHelper.getLastOverlay().init();
                 ScreenHelper.getLastOverlay().init();
             return true;
             return true;
         }
         }
@@ -203,10 +203,10 @@ public class PreRecipeViewingScreen extends Screen {
             if (containsMouse(double_1, double_2)) {
             if (containsMouse(double_1, double_2)) {
                 original = (v == 0);
                 original = (v == 0);
                 if (!isSet) {
                 if (!isSet) {
-                    moveFrameTo(!original ? 0 : 1, false, 0);
+                    moveFrameTo(original ? 0 : 1, false, 0);
                 }
                 }
                 isSet = true;
                 isSet = true;
-                moveFrameTo(original ? 0 : 1, true, 1000);
+                moveFrameTo(original ? 0 : 1, true, 500);
                 return true;
                 return true;
             }
             }
             return false;
             return false;

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

@@ -31,10 +31,12 @@ import me.shedaniel.math.api.Point;
 import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.math.impl.PointHelper;
 import me.shedaniel.math.impl.PointHelper;
 import me.shedaniel.rei.api.*;
 import me.shedaniel.rei.api.*;
+import me.shedaniel.rei.api.widgets.Panel;
 import me.shedaniel.rei.api.widgets.Widgets;
 import me.shedaniel.rei.api.widgets.Widgets;
 import me.shedaniel.rei.gui.widget.*;
 import me.shedaniel.rei.gui.widget.*;
 import me.shedaniel.rei.impl.ClientHelperImpl;
 import me.shedaniel.rei.impl.ClientHelperImpl;
 import me.shedaniel.rei.impl.ScreenHelper;
 import me.shedaniel.rei.impl.ScreenHelper;
+import me.shedaniel.rei.impl.widgets.PanelWidget;
 import me.shedaniel.rei.utils.CollectionUtils;
 import me.shedaniel.rei.utils.CollectionUtils;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.gui.Element;
@@ -79,7 +81,7 @@ public class RecipeViewingScreen extends Screen implements RecipeScreen {
     private int tabsPerPage = 5;
     private int tabsPerPage = 5;
     private Rectangle bounds;
     private Rectangle bounds;
     @Nullable
     @Nullable
-    private CategoryBaseWidget workingStationsBaseWidget;
+    private Panel workingStationsBaseWidget;
     private ButtonWidget recipeBack, recipeNext, categoryBack, categoryNext;
     private ButtonWidget recipeBack, recipeNext, categoryBack, categoryNext;
     private EntryStack ingredientStackToNotice = EntryStack.empty();
     private EntryStack ingredientStackToNotice = EntryStack.empty();
     private EntryStack resultStackToNotice = EntryStack.empty();
     private EntryStack resultStackToNotice = EntryStack.empty();
@@ -152,7 +154,7 @@ public class RecipeViewingScreen extends Screen implements RecipeScreen {
     }
     }
     
     
     @Nullable
     @Nullable
-    public CategoryBaseWidget getWorkingStationsBaseWidget() {
+    public Panel getWorkingStationsBaseWidget() {
         return workingStationsBaseWidget;
         return workingStationsBaseWidget;
     }
     }
     
     
@@ -184,7 +186,7 @@ public class RecipeViewingScreen extends Screen implements RecipeScreen {
             if (element.keyPressed(int_1, int_2, int_3))
             if (element.keyPressed(int_1, int_2, int_3))
                 return true;
                 return true;
         if (int_1 == 256 || this.client.options.keyInventory.matchesKey(int_1, int_2)) {
         if (int_1 == 256 || this.client.options.keyInventory.matchesKey(int_1, int_2)) {
-            MinecraftClient.getInstance().openScreen(ScreenHelper.getLastScreenWithHandler());
+            MinecraftClient.getInstance().openScreen(ScreenHelper.getLastHandledScreen());
             ScreenHelper.getLastOverlay().init();
             ScreenHelper.getLastOverlay().init();
             return true;
             return true;
         }
         }
@@ -192,7 +194,7 @@ public class RecipeViewingScreen extends Screen implements RecipeScreen {
             if (ScreenHelper.hasLastRecipeScreen())
             if (ScreenHelper.hasLastRecipeScreen())
                 client.openScreen(ScreenHelper.getLastRecipeScreen());
                 client.openScreen(ScreenHelper.getLastRecipeScreen());
             else
             else
-                client.openScreen(ScreenHelper.getLastScreenWithHandler());
+                client.openScreen(ScreenHelper.getLastHandledScreen());
             return true;
             return true;
         }
         }
         return super.keyPressed(int_1, int_2, int_3);
         return super.keyPressed(int_1, int_2, int_3);
@@ -322,8 +324,8 @@ public class RecipeViewingScreen extends Screen implements RecipeScreen {
             int innerWidth = MathHelper.ceil(workingStations.size() / ((float) hh));
             int innerWidth = MathHelper.ceil(workingStations.size() / ((float) hh));
             int xx = bounds.x - (8 + innerWidth * 16) + 6;
             int xx = bounds.x - (8 + innerWidth * 16) + 6;
             int yy = bounds.y + 16;
             int yy = bounds.y + 16;
-            preWidgets.add(workingStationsBaseWidget = new CategoryBaseWidget(new Rectangle(xx - 5, yy - 5, 15 + innerWidth * 16, 10 + actualHeight * 16)));
-            preWidgets.add(new SlotBaseWidget(new Rectangle(xx - 1, yy - 1, innerWidth * 16 + 2, actualHeight * 16 + 2)));
+            preWidgets.add(workingStationsBaseWidget = Widgets.createCategoryBase(new Rectangle(xx - 5, yy - 5, 15 + innerWidth * 16, 10 + actualHeight * 16)));
+            preWidgets.add(Widgets.createSlotBase(new Rectangle(xx - 1, yy - 1, innerWidth * 16 + 2, actualHeight * 16 + 2)));
             int index = 0;
             int index = 0;
             List<String> list = Collections.singletonList(Formatting.YELLOW.toString() + I18n.translate("text.rei.working_station"));
             List<String> list = Collections.singletonList(Formatting.YELLOW.toString() + I18n.translate("text.rei.working_station"));
             xx += (innerWidth - 1) * 16;
             xx += (innerWidth - 1) * 16;
@@ -388,17 +390,13 @@ public class RecipeViewingScreen extends Screen implements RecipeScreen {
         for (Widget widget : preWidgets) {
         for (Widget widget : preWidgets) {
             widget.render(mouseX, mouseY, delta);
             widget.render(mouseX, mouseY, delta);
         }
         }
-        if (selectedCategory != null)
-            selectedCategory.drawCategoryBackground(bounds, mouseX, mouseY, delta);
-        else {
-            PanelWidget.render(bounds, -1);
-            if (REIHelper.getInstance().isDarkThemeEnabled()) {
-                fill(bounds.x + 17, bounds.y + 5, bounds.x + bounds.width - 17, bounds.y + 17, 0xFF404040);
-                fill(bounds.x + 17, bounds.y + 19, bounds.x + bounds.width - 17, bounds.y + 30, 0xFF404040);
-            } else {
-                fill(bounds.x + 17, bounds.y + 5, bounds.x + bounds.width - 17, bounds.y + 17, 0xFF9E9E9E);
-                fill(bounds.x + 17, bounds.y + 19, bounds.x + bounds.width - 17, bounds.y + 31, 0xFF9E9E9E);
-            }
+        PanelWidget.render(bounds, -1);
+        if (REIHelper.getInstance().isDarkThemeEnabled()) {
+            fill(bounds.x + 17, bounds.y + 5, bounds.x + bounds.width - 17, bounds.y + 17, 0xFF404040);
+            fill(bounds.x + 17, bounds.y + 19, bounds.x + bounds.width - 17, bounds.y + 30, 0xFF404040);
+        } else {
+            fill(bounds.x + 17, bounds.y + 5, bounds.x + bounds.width - 17, bounds.y + 17, 0xFF9E9E9E);
+            fill(bounds.x + 17, bounds.y + 19, bounds.x + bounds.width - 17, bounds.y + 31, 0xFF9E9E9E);
         }
         }
         for (TabWidget tab : tabs) {
         for (TabWidget tab : tabs) {
             if (!tab.isSelected())
             if (!tab.isSelected())

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

@@ -33,7 +33,10 @@ import me.shedaniel.math.impl.PointHelper;
 import me.shedaniel.rei.api.*;
 import me.shedaniel.rei.api.*;
 import me.shedaniel.rei.api.widgets.Widgets;
 import me.shedaniel.rei.api.widgets.Widgets;
 import me.shedaniel.rei.gui.entries.RecipeEntry;
 import me.shedaniel.rei.gui.entries.RecipeEntry;
-import me.shedaniel.rei.gui.widget.*;
+import me.shedaniel.rei.gui.widget.AutoCraftingButtonWidget;
+import me.shedaniel.rei.gui.widget.ButtonWidget;
+import me.shedaniel.rei.gui.widget.TabWidget;
+import me.shedaniel.rei.gui.widget.Widget;
 import me.shedaniel.rei.impl.ClientHelperImpl;
 import me.shedaniel.rei.impl.ClientHelperImpl;
 import me.shedaniel.rei.impl.ScreenHelper;
 import me.shedaniel.rei.impl.ScreenHelper;
 import me.shedaniel.rei.utils.CollectionUtils;
 import me.shedaniel.rei.utils.CollectionUtils;
@@ -153,8 +156,8 @@ public class VillagerRecipeViewingScreen extends Screen implements RecipeScreen
             int h = MathHelper.ceil(workingStations.size() / ((float) ww));
             int h = MathHelper.ceil(workingStations.size() / ((float) ww));
             int xx = bounds.x + 16;
             int xx = bounds.x + 16;
             int yy = bounds.y + bounds.height + 2;
             int yy = bounds.y + bounds.height + 2;
-            widgets.add(new CategoryBaseWidget(new Rectangle(xx - 5, bounds.y + bounds.height - 5, 10 + w * 16, 12 + h * 16)));
-            widgets.add(new SlotBaseWidget(new Rectangle(xx - 1, yy - 1, 2 + w * 16, 2 + h * 16)));
+            widgets.add(Widgets.createCategoryBase(new Rectangle(xx - 5, bounds.y + bounds.height - 5, 10 + w * 16, 12 + h * 16)));
+            widgets.add(Widgets.createSlotBase(new Rectangle(xx - 1, yy - 1, 2 + w * 16, 2 + h * 16)));
             int index = 0;
             int index = 0;
             List<String> list = Collections.singletonList(Formatting.YELLOW.toString() + I18n.translate("text.rei.working_station"));
             List<String> list = Collections.singletonList(Formatting.YELLOW.toString() + I18n.translate("text.rei.working_station"));
             for (List<EntryStack> workingStation : workingStations) {
             for (List<EntryStack> workingStation : workingStations) {
@@ -169,9 +172,9 @@ public class VillagerRecipeViewingScreen extends Screen implements RecipeScreen
             }
             }
         }
         }
         
         
-        this.widgets.add(new CategoryBaseWidget(bounds));
+        this.widgets.add(Widgets.createCategoryBase(bounds));
         this.scrollListBounds = new Rectangle(bounds.x + 4, bounds.y + 17, 97 + 5, guiHeight - 17 - 7);
         this.scrollListBounds = new Rectangle(bounds.x + 4, bounds.y + 17, 97 + 5, guiHeight - 17 - 7);
-        this.widgets.add(new SlotBaseWidget(scrollListBounds));
+        this.widgets.add(Widgets.createSlotBase(scrollListBounds));
         
         
         Rectangle recipeBounds = new Rectangle(bounds.x + 100 + (guiWidth - 100) / 2 - category.getDisplayWidth(display) / 2, bounds.y + bounds.height / 2 - category.getDisplayHeight() / 2, category.getDisplayWidth(display), category.getDisplayHeight());
         Rectangle recipeBounds = new Rectangle(bounds.x + 100 + (guiWidth - 100) / 2 - category.getDisplayWidth(display) / 2, bounds.y + bounds.height / 2 - category.getDisplayHeight() / 2, category.getDisplayWidth(display), category.getDisplayHeight());
         List<Widget> setupDisplay = category.setupDisplay(display, recipeBounds);
         List<Widget> setupDisplay = category.setupDisplay(display, recipeBounds);
@@ -384,7 +387,7 @@ public class VillagerRecipeViewingScreen extends Screen implements RecipeScreen
             if (buttonWidgets.get(i).getBounds().getMaxY() > scrollListBounds.getMinY() && buttonWidgets.get(i).getBounds().getMinY() < scrollListBounds.getMaxY()) {
             if (buttonWidgets.get(i).getBounds().getMaxY() > scrollListBounds.getMinY() && buttonWidgets.get(i).getBounds().getMinY() < scrollListBounds.getMaxY()) {
                 recipeRenderers.get(i).setZ(1);
                 recipeRenderers.get(i).setZ(1);
                 recipeRenderers.get(i).render(buttonWidgets.get(i).getBounds(), mouseX, mouseY, delta);
                 recipeRenderers.get(i).render(buttonWidgets.get(i).getBounds(), mouseX, mouseY, delta);
-                REIHelper.getInstance().addTooltip(recipeRenderers.get(i).getTooltip(mouseX, mouseY));
+                recipeRenderers.get(i).getTooltip(new Point(mouseX, mouseY)).queue();
             }
             }
         }
         }
         double maxScroll = getMaxScrollPosition();
         double maxScroll = getMaxScrollPosition();
@@ -481,7 +484,7 @@ public class VillagerRecipeViewingScreen extends Screen implements RecipeScreen
             if (element.keyPressed(int_1, int_2, int_3))
             if (element.keyPressed(int_1, int_2, int_3))
                 return true;
                 return true;
         if (int_1 == 256 || this.client.options.keyInventory.matchesKey(int_1, int_2)) {
         if (int_1 == 256 || this.client.options.keyInventory.matchesKey(int_1, int_2)) {
-            MinecraftClient.getInstance().openScreen(ScreenHelper.getLastScreenWithHandler());
+            MinecraftClient.getInstance().openScreen(ScreenHelper.getLastHandledScreen());
             ScreenHelper.getLastOverlay().init();
             ScreenHelper.getLastOverlay().init();
             return true;
             return true;
         }
         }
@@ -489,7 +492,7 @@ public class VillagerRecipeViewingScreen extends Screen implements RecipeScreen
             if (ScreenHelper.hasLastRecipeScreen())
             if (ScreenHelper.hasLastRecipeScreen())
                 client.openScreen(ScreenHelper.getLastRecipeScreen());
                 client.openScreen(ScreenHelper.getLastRecipeScreen());
             else
             else
-                client.openScreen(ScreenHelper.getLastScreenWithHandler());
+                client.openScreen(ScreenHelper.getLastHandledScreen());
             return true;
             return true;
         }
         }
         return super.keyPressed(int_1, int_2, int_3);
         return super.keyPressed(int_1, int_2, int_3);

+ 3 - 3
src/main/java/me/shedaniel/rei/gui/config/entry/FilteringEntry.java

@@ -37,9 +37,9 @@ import me.shedaniel.rei.api.ConfigObject;
 import me.shedaniel.rei.api.EntryRegistry;
 import me.shedaniel.rei.api.EntryRegistry;
 import me.shedaniel.rei.api.EntryStack;
 import me.shedaniel.rei.api.EntryStack;
 import me.shedaniel.rei.api.REIHelper;
 import me.shedaniel.rei.api.REIHelper;
+import me.shedaniel.rei.api.widgets.Tooltip;
 import me.shedaniel.rei.gui.OverlaySearchField;
 import me.shedaniel.rei.gui.OverlaySearchField;
 import me.shedaniel.rei.gui.widget.EntryWidget;
 import me.shedaniel.rei.gui.widget.EntryWidget;
-import me.shedaniel.rei.gui.widget.QueuedTooltip;
 import me.shedaniel.rei.impl.ScreenHelper;
 import me.shedaniel.rei.impl.ScreenHelper;
 import me.shedaniel.rei.impl.SearchArgument;
 import me.shedaniel.rei.impl.SearchArgument;
 import me.shedaniel.rei.utils.CollectionUtils;
 import me.shedaniel.rei.utils.CollectionUtils;
@@ -73,7 +73,7 @@ public class FilteringEntry extends AbstractConfigListEntry<List<EntryStack>> {
     private Consumer<List<EntryStack>> saveConsumer;
     private Consumer<List<EntryStack>> saveConsumer;
     private List<EntryStack> defaultValue;
     private List<EntryStack> defaultValue;
     private List<EntryStack> configFiltered;
     private List<EntryStack> configFiltered;
-    private QueuedTooltip tooltip = null;
+    private Tooltip tooltip = null;
     @SuppressWarnings("rawtypes") private ClothConfigScreen.ListWidget lastList = null;
     @SuppressWarnings("rawtypes") private ClothConfigScreen.ListWidget lastList = null;
     private List<EntryStack> entryStacks = null;
     private List<EntryStack> entryStacks = null;
     private Rectangle innerBounds;
     private Rectangle innerBounds;
@@ -543,7 +543,7 @@ public class FilteringEntry extends AbstractConfigListEntry<List<EntryStack>> {
         protected void queueTooltip(int mouseX, int mouseY, float delta) {
         protected void queueTooltip(int mouseX, int mouseY, float delta) {
             if (searchField.containsMouse(mouseX, mouseY))
             if (searchField.containsMouse(mouseX, mouseY))
                 return;
                 return;
-            QueuedTooltip tooltip = getCurrentTooltip(mouseX, mouseY);
+            Tooltip tooltip = getCurrentTooltip(new Point(mouseX, mouseY));
             if (tooltip != null) {
             if (tooltip != null) {
                 FilteringEntry.this.tooltip = tooltip;
                 FilteringEntry.this.tooltip = tooltip;
             }
             }

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

@@ -30,7 +30,7 @@ import me.shedaniel.rei.impl.ScreenHelper;
 import net.fabricmc.loader.api.FabricLoader;
 import net.fabricmc.loader.api.FabricLoader;
 import net.fabricmc.loader.api.metadata.CustomValue;
 import net.fabricmc.loader.api.metadata.CustomValue;
 import net.minecraft.client.gui.screen.Screen;
 import net.minecraft.client.gui.screen.Screen;
-import net.minecraft.client.gui.screen.ingame.ScreenWithHandler;
+import net.minecraft.client.gui.screen.ingame.HandledScreen;
 import net.minecraft.client.gui.widget.AbstractPressableButtonWidget;
 import net.minecraft.client.gui.widget.AbstractPressableButtonWidget;
 import net.minecraft.client.resource.language.I18n;
 import net.minecraft.client.resource.language.I18n;
 import net.minecraft.text.LiteralText;
 import net.minecraft.text.LiteralText;
@@ -58,7 +58,7 @@ public class CreditsScreen extends Screen {
     public boolean keyPressed(int int_1, int int_2, int int_3) {
     public boolean keyPressed(int int_1, int int_2, int int_3) {
         if (int_1 == 256 && this.shouldCloseOnEsc()) {
         if (int_1 == 256 && this.shouldCloseOnEsc()) {
             this.client.openScreen(parent);
             this.client.openScreen(parent);
-            if (parent instanceof ScreenWithHandler)
+            if (parent instanceof HandledScreen)
                 ScreenHelper.getLastOverlay().init();
                 ScreenHelper.getLastOverlay().init();
             return true;
             return true;
         }
         }
@@ -112,7 +112,7 @@ public class CreditsScreen extends Screen {
             @Override
             @Override
             public void onPress() {
             public void onPress() {
                 CreditsScreen.this.client.openScreen(parent);
                 CreditsScreen.this.client.openScreen(parent);
-                if (parent instanceof ScreenWithHandler)
+                if (parent instanceof HandledScreen)
                     ScreenHelper.getLastOverlay().init();
                     ScreenHelper.getLastOverlay().init();
             }
             }
         });
         });

+ 8 - 1
src/main/java/me/shedaniel/rei/gui/entries/RecipeEntry.java

@@ -26,10 +26,17 @@ package me.shedaniel.rei.gui.entries;
 import me.shedaniel.rei.gui.widget.QueuedTooltip;
 import me.shedaniel.rei.gui.widget.QueuedTooltip;
 import me.shedaniel.rei.impl.RenderingEntry;
 import me.shedaniel.rei.impl.RenderingEntry;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Nullable;
 
 
 @ApiStatus.OverrideOnly
 @ApiStatus.OverrideOnly
 public abstract class RecipeEntry extends RenderingEntry {
 public abstract class RecipeEntry extends RenderingEntry {
-    public abstract QueuedTooltip getTooltip(int mouseX, int mouseY);
+    @Nullable
+    @Override
+    @Deprecated
+    @ApiStatus.ScheduledForRemoval
+    public QueuedTooltip getTooltip(int mouseX, int mouseY) {
+        return super.getTooltip(mouseX, mouseY);
+    }
     
     
     public abstract int getHeight();
     public abstract int getHeight();
     
     

+ 15 - 13
src/main/java/me/shedaniel/rei/gui/entries/SimpleRecipeEntry.java

@@ -24,10 +24,12 @@
 package me.shedaniel.rei.gui.entries;
 package me.shedaniel.rei.gui.entries;
 
 
 import com.google.common.collect.Lists;
 import com.google.common.collect.Lists;
+import me.shedaniel.math.Point;
 import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.rei.api.EntryStack;
 import me.shedaniel.rei.api.EntryStack;
-import me.shedaniel.rei.gui.widget.EntryWidget;
-import me.shedaniel.rei.gui.widget.QueuedTooltip;
+import me.shedaniel.rei.api.widgets.Slot;
+import me.shedaniel.rei.api.widgets.Tooltip;
+import me.shedaniel.rei.api.widgets.Widgets;
 import me.shedaniel.rei.utils.CollectionUtils;
 import me.shedaniel.rei.utils.CollectionUtils;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.Identifier;
@@ -46,8 +48,8 @@ public class SimpleRecipeEntry extends RecipeEntry {
     
     
     private static final Comparator<EntryStack> ENTRY_COMPARATOR = Comparator.comparingLong(EntryStack::hashCode);
     private static final Comparator<EntryStack> ENTRY_COMPARATOR = Comparator.comparingLong(EntryStack::hashCode);
     private static final Identifier CHEST_GUI_TEXTURE = new Identifier("roughlyenoughitems", "textures/gui/recipecontainer.png");
     private static final Identifier CHEST_GUI_TEXTURE = new Identifier("roughlyenoughitems", "textures/gui/recipecontainer.png");
-    private List<EntryWidget> inputWidgets;
-    private EntryWidget outputWidget;
+    private List<Slot> inputWidgets;
+    private Slot outputWidget;
     
     
     @ApiStatus.Internal
     @ApiStatus.Internal
     protected SimpleRecipeEntry(List<List<EntryStack>> input, List<EntryStack> output) {
     protected SimpleRecipeEntry(List<List<EntryStack>> input, List<EntryStack> output) {
@@ -67,8 +69,8 @@ public class SimpleRecipeEntry extends RecipeEntry {
                 s.setAmount(pair.getRight().get());
                 s.setAmount(pair.getRight().get());
                 return s;
                 return s;
             }).collect(Collectors.toList()));
             }).collect(Collectors.toList()));
-        this.inputWidgets = b.stream().filter(stacks -> !stacks.isEmpty()).map(stacks -> EntryWidget.create(0, 0).entries(stacks).noBackground().noHighlight().noTooltips()).collect(Collectors.toList());
-        this.outputWidget = EntryWidget.create(0, 0).entries(CollectionUtils.filter(output, stack -> !stack.isEmpty())).noBackground().noHighlight().noTooltips();
+        this.inputWidgets = b.stream().filter(stacks -> !stacks.isEmpty()).map(stacks -> Widgets.createSlot(new Point(0, 0)).entries(stacks).disableBackground().disableHighlight().disableTooltips()).collect(Collectors.toList());
+        this.outputWidget = Widgets.createSlot(new Point(0, 0)).entries(CollectionUtils.filter(output, stack -> !stack.isEmpty())).disableBackground().disableHighlight().disableTooltips();
     }
     }
     
     
     public static RecipeEntry create(Supplier<List<List<EntryStack>>> input, Supplier<List<EntryStack>> output) {
     public static RecipeEntry create(Supplier<List<List<EntryStack>>> input, Supplier<List<EntryStack>> output) {
@@ -97,7 +99,7 @@ public class SimpleRecipeEntry extends RecipeEntry {
         int xx = bounds.x + 4, yy = bounds.y + 2;
         int xx = bounds.x + 4, yy = bounds.y + 2;
         int j = 0;
         int j = 0;
         int itemsPerLine = getItemsPerLine();
         int itemsPerLine = getItemsPerLine();
-        for (EntryWidget entryWidget : inputWidgets) {
+        for (Slot entryWidget : inputWidgets) {
             entryWidget.setZ(getZ() + 50);
             entryWidget.setZ(getZ() + 50);
             entryWidget.getBounds().setLocation(xx, yy);
             entryWidget.getBounds().setLocation(xx, yy);
             entryWidget.render(mouseX, mouseY, delta);
             entryWidget.render(mouseX, mouseY, delta);
@@ -121,13 +123,13 @@ public class SimpleRecipeEntry extends RecipeEntry {
     
     
     @Nullable
     @Nullable
     @Override
     @Override
-    public QueuedTooltip getTooltip(int mouseX, int mouseY) {
-        for (EntryWidget widget : inputWidgets) {
-            if (widget.containsMouse(mouseX, mouseY))
-                return widget.getCurrentTooltip(mouseX, mouseY);
+    public Tooltip getTooltip(Point point) {
+        for (Slot widget : inputWidgets) {
+            if (widget.containsMouse(point))
+                return widget.getCurrentTooltip(point);
         }
         }
-        if (outputWidget.containsMouse(mouseX, mouseY))
-            return outputWidget.getCurrentTooltip(mouseX, mouseY);
+        if (outputWidget.containsMouse(point))
+            return outputWidget.getCurrentTooltip(point);
         return null;
         return null;
     }
     }
     
     

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

@@ -29,11 +29,12 @@ import me.shedaniel.math.api.Point;
 import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.math.impl.PointHelper;
 import me.shedaniel.math.impl.PointHelper;
 import me.shedaniel.rei.api.*;
 import me.shedaniel.rei.api.*;
+import me.shedaniel.rei.api.widgets.Tooltip;
 import me.shedaniel.rei.gui.toast.CopyRecipeIdentifierToast;
 import me.shedaniel.rei.gui.toast.CopyRecipeIdentifierToast;
 import me.shedaniel.rei.impl.ClientHelperImpl;
 import me.shedaniel.rei.impl.ClientHelperImpl;
 import me.shedaniel.rei.impl.ScreenHelper;
 import me.shedaniel.rei.impl.ScreenHelper;
 import me.shedaniel.rei.utils.CollectionUtils;
 import me.shedaniel.rei.utils.CollectionUtils;
-import net.minecraft.client.gui.screen.ingame.ScreenWithHandler;
+import net.minecraft.client.gui.screen.ingame.HandledScreen;
 import net.minecraft.client.resource.language.I18n;
 import net.minecraft.client.resource.language.I18n;
 import net.minecraft.text.LiteralText;
 import net.minecraft.text.LiteralText;
 import net.minecraft.util.Formatting;
 import net.minecraft.util.Formatting;
@@ -51,7 +52,7 @@ public class AutoCraftingButtonWidget extends ButtonWidget {
     private String extraTooltip;
     private String extraTooltip;
     private List<String> errorTooltip;
     private List<String> errorTooltip;
     private List<Widget> setupDisplay;
     private List<Widget> setupDisplay;
-    private ScreenWithHandler<?> screenWithHandler;
+    private HandledScreen<?> handledScreen;
     private boolean visible = false;
     private boolean visible = false;
     private RecipeCategory<?> category;
     private RecipeCategory<?> category;
     private Rectangle displayBounds;
     private Rectangle displayBounds;
@@ -62,14 +63,14 @@ public class AutoCraftingButtonWidget extends ButtonWidget {
         this.displaySupplier = displaySupplier;
         this.displaySupplier = displaySupplier;
         Optional<Identifier> recipe = displaySupplier.get().getRecipeLocation();
         Optional<Identifier> recipe = displaySupplier.get().getRecipeLocation();
         extraTooltip = recipe.isPresent() ? I18n.translate("text.rei.recipe_id", Formatting.GRAY.toString(), recipe.get().toString()) : "";
         extraTooltip = recipe.isPresent() ? I18n.translate("text.rei.recipe_id", Formatting.GRAY.toString(), recipe.get().toString()) : "";
-        this.screenWithHandler = ScreenHelper.getLastScreenWithHandler();
+        this.handledScreen = ScreenHelper.getLastHandledScreen();
         this.setupDisplay = setupDisplay;
         this.setupDisplay = setupDisplay;
         this.category = recipeCategory;
         this.category = recipeCategory;
     }
     }
     
     
     @Override
     @Override
     public void onPressed() {
     public void onPressed() {
-        AutoTransferHandler.Context context = AutoTransferHandler.Context.create(true, screenWithHandler, displaySupplier.get());
+        AutoTransferHandler.Context context = AutoTransferHandler.Context.create(true, handledScreen, displaySupplier.get());
         for (AutoTransferHandler autoTransferHandler : RecipeHelper.getInstance().getSortedAutoCraftingHandler())
         for (AutoTransferHandler autoTransferHandler : RecipeHelper.getInstance().getSortedAutoCraftingHandler())
             try {
             try {
                 AutoTransferHandler.Result result = autoTransferHandler.handle(context);
                 AutoTransferHandler.Result result = autoTransferHandler.handle(context);
@@ -78,7 +79,7 @@ public class AutoCraftingButtonWidget extends ButtonWidget {
             } catch (Exception e) {
             } catch (Exception e) {
                 e.printStackTrace();
                 e.printStackTrace();
             }
             }
-        minecraft.openScreen(screenWithHandler);
+        minecraft.openScreen(handledScreen);
         ScreenHelper.getLastOverlay().init();
         ScreenHelper.getLastOverlay().init();
     }
     }
     
     
@@ -89,7 +90,7 @@ public class AutoCraftingButtonWidget extends ButtonWidget {
         int color = 0;
         int color = 0;
         visible = false;
         visible = false;
         IntList redSlots = null;
         IntList redSlots = null;
-        AutoTransferHandler.Context context = AutoTransferHandler.Context.create(false, screenWithHandler, displaySupplier.get());
+        AutoTransferHandler.Context context = AutoTransferHandler.Context.create(false, handledScreen, displaySupplier.get());
         for (AutoTransferHandler autoTransferHandler : RecipeHelper.getInstance().getSortedAutoCraftingHandler()) {
         for (AutoTransferHandler autoTransferHandler : RecipeHelper.getInstance().getSortedAutoCraftingHandler()) {
             try {
             try {
                 AutoTransferHandler.Result result = autoTransferHandler.handle(context);
                 AutoTransferHandler.Result result = autoTransferHandler.handle(context);
@@ -148,9 +149,9 @@ public class AutoCraftingButtonWidget extends ButtonWidget {
         
         
         if (getTooltips().isPresent())
         if (getTooltips().isPresent())
             if (!focused && containsMouse(mouseX, mouseY))
             if (!focused && containsMouse(mouseX, mouseY))
-                REIHelper.getInstance().addTooltip(QueuedTooltip.create(getTooltips().get().split("\n")));
+                Tooltip.create(getTooltips().get().split("\n")).queue();
             else if (focused)
             else if (focused)
-                REIHelper.getInstance().addTooltip(QueuedTooltip.create(new Point(x + width / 2, y + height / 2), getTooltips().get().split("\n")));
+                Tooltip.create(new Point(x + width / 2, y + height / 2), getTooltips().get().split("\n")).queue();
     }
     }
     
     
     @Override
     @Override

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

@@ -27,6 +27,7 @@ import com.mojang.blaze3d.systems.RenderSystem;
 import me.shedaniel.math.api.Point;
 import me.shedaniel.math.api.Point;
 import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.rei.api.REIHelper;
 import me.shedaniel.rei.api.REIHelper;
+import me.shedaniel.rei.api.widgets.Tooltip;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.sound.PositionedSoundInstance;
 import net.minecraft.client.sound.PositionedSoundInstance;
 import net.minecraft.sound.SoundEvents;
 import net.minecraft.sound.SoundEvents;
@@ -154,9 +155,9 @@ public abstract class ButtonWidget extends WidgetWithBounds {
         
         
         if (getTooltips().isPresent())
         if (getTooltips().isPresent())
             if (!focused && containsMouse(mouseX, mouseY))
             if (!focused && containsMouse(mouseX, mouseY))
-                REIHelper.getInstance().addTooltip(QueuedTooltip.create(getTooltips().get().split("\n")));
+                Tooltip.create(getTooltips().get().split("\n")).queue();
             else if (focused)
             else if (focused)
-                REIHelper.getInstance().addTooltip(QueuedTooltip.create(new Point(x + width / 2, y + height / 2), getTooltips().get().split("\n")));
+                Tooltip.create(new Point(x + width / 2, y + height / 2), getTooltips().get().split("\n")).queue();
     }
     }
     
     
     public boolean isHovered(int mouseX, int mouseY) {
     public boolean isHovered(int mouseX, int mouseY) {

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

@@ -24,7 +24,14 @@
 package me.shedaniel.rei.gui.widget;
 package me.shedaniel.rei.gui.widget;
 
 
 import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.math.api.Rectangle;
+import org.jetbrains.annotations.ApiStatus;
 
 
+/**
+ * @see me.shedaniel.rei.api.widgets.Widgets#createCategoryBase(me.shedaniel.math.Rectangle)
+ * @see me.shedaniel.rei.api.widgets.Widgets#createCategoryBase(me.shedaniel.math.Rectangle, int)
+ */
+@Deprecated
+@ApiStatus.ScheduledForRemoval
 public class CategoryBaseWidget extends RecipeBaseWidget {
 public class CategoryBaseWidget extends RecipeBaseWidget {
     
     
     public CategoryBaseWidget(Rectangle bounds) {
     public CategoryBaseWidget(Rectangle bounds) {
@@ -40,5 +47,4 @@ public class CategoryBaseWidget extends RecipeBaseWidget {
     protected boolean isRendering() {
     protected boolean isRendering() {
         return true;
         return true;
     }
     }
-    
 }
 }

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

@@ -25,6 +25,7 @@ package me.shedaniel.rei.gui.widget;
 
 
 import me.shedaniel.math.Point;
 import me.shedaniel.math.Point;
 import me.shedaniel.rei.api.REIHelper;
 import me.shedaniel.rei.api.REIHelper;
+import me.shedaniel.rei.api.widgets.Tooltip;
 import me.shedaniel.rei.api.widgets.Widgets;
 import me.shedaniel.rei.api.widgets.Widgets;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.ApiStatus;
 
 
@@ -92,9 +93,9 @@ public abstract class ClickableLabelWidget extends LabelWidget {
     protected void drawTooltips(int mouseX, int mouseY) {
     protected void drawTooltips(int mouseX, int mouseY) {
         if (isClickable() && getTooltips().isPresent())
         if (isClickable() && getTooltips().isPresent())
             if (!focused && containsMouse(mouseX, mouseY))
             if (!focused && containsMouse(mouseX, mouseY))
-                REIHelper.getInstance().addTooltip(QueuedTooltip.create(getTooltips().get().split("\n")));
+                Tooltip.create(getTooltips().get().split("\n")).queue();
             else if (focused)
             else if (focused)
-                REIHelper.getInstance().addTooltip(QueuedTooltip.create(getPosition(), getTooltips().get().split("\n")));
+                Tooltip.create(getPosition(), getTooltips().get().split("\n")).queue();
     }
     }
     
     
     public int getHoveredColor() {
     public int getHoveredColor() {

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

@@ -33,6 +33,7 @@ import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.math.impl.PointHelper;
 import me.shedaniel.math.impl.PointHelper;
 import me.shedaniel.rei.RoughlyEnoughItemsCore;
 import me.shedaniel.rei.RoughlyEnoughItemsCore;
 import me.shedaniel.rei.api.*;
 import me.shedaniel.rei.api.*;
+import me.shedaniel.rei.api.widgets.Tooltip;
 import me.shedaniel.rei.api.widgets.Widgets;
 import me.shedaniel.rei.api.widgets.Widgets;
 import me.shedaniel.rei.gui.ContainerScreenOverlay;
 import me.shedaniel.rei.gui.ContainerScreenOverlay;
 import me.shedaniel.rei.gui.config.ItemListOrdering;
 import me.shedaniel.rei.gui.config.ItemListOrdering;
@@ -460,7 +461,7 @@ public class EntryListWidget extends WidgetWithBounds {
             }
             }
         }
         }
         if (containsMouse(mouseX, mouseY) && ClientHelper.getInstance().isCheating() && !minecraft.player.inventory.getCursorStack().isEmpty() && RoughlyEnoughItemsCore.hasPermissionToUsePackets())
         if (containsMouse(mouseX, mouseY) && ClientHelper.getInstance().isCheating() && !minecraft.player.inventory.getCursorStack().isEmpty() && RoughlyEnoughItemsCore.hasPermissionToUsePackets())
-            REIHelper.getInstance().addTooltip(QueuedTooltip.create(I18n.translate("text.rei.delete_items")));
+            Tooltip.create(I18n.translate("text.rei.delete_items")).queue();
     }
     }
     
     
     private int getScrollbarMinX() {
     private int getScrollbarMinX() {

+ 9 - 4
src/main/java/me/shedaniel/rei/gui/widget/EntryWidget.java

@@ -30,6 +30,7 @@ import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.math.impl.PointHelper;
 import me.shedaniel.math.impl.PointHelper;
 import me.shedaniel.rei.api.*;
 import me.shedaniel.rei.api.*;
 import me.shedaniel.rei.api.widgets.Slot;
 import me.shedaniel.rei.api.widgets.Slot;
+import me.shedaniel.rei.api.widgets.Tooltip;
 import me.shedaniel.rei.gui.ContainerScreenOverlay;
 import me.shedaniel.rei.gui.ContainerScreenOverlay;
 import me.shedaniel.rei.impl.ScreenHelper;
 import me.shedaniel.rei.impl.ScreenHelper;
 import me.shedaniel.rei.utils.CollectionUtils;
 import me.shedaniel.rei.utils.CollectionUtils;
@@ -40,6 +41,8 @@ import net.minecraft.sound.SoundEvents;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.math.MathHelper;
 import net.minecraft.util.math.MathHelper;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 
 import java.util.*;
 import java.util.*;
 
 
@@ -72,6 +75,7 @@ public class EntryWidget extends Slot {
      */
      */
     @ApiStatus.ScheduledForRemoval
     @ApiStatus.ScheduledForRemoval
     @Deprecated
     @Deprecated
+    @NotNull
     public static EntryWidget create(int x, int y) {
     public static EntryWidget create(int x, int y) {
         return create(new Point(x, y));
         return create(new Point(x, y));
     }
     }
@@ -81,6 +85,7 @@ public class EntryWidget extends Slot {
      */
      */
     @ApiStatus.ScheduledForRemoval
     @ApiStatus.ScheduledForRemoval
     @Deprecated
     @Deprecated
+    @NotNull
     public static EntryWidget create(Point point) {
     public static EntryWidget create(Point point) {
         return new EntryWidget(point);
         return new EntryWidget(point);
     }
     }
@@ -293,7 +298,7 @@ public class EntryWidget extends Slot {
     }
     }
     
     
     protected void queueTooltip(int mouseX, int mouseY, float delta) {
     protected void queueTooltip(int mouseX, int mouseY, float delta) {
-        QueuedTooltip tooltip = getCurrentTooltip(mouseX, mouseY);
+        Tooltip tooltip = getCurrentTooltip(new Point(mouseX, mouseY));
         if (tooltip != null) {
         if (tooltip != null) {
             if (interactableFavorites && ConfigObject.getInstance().doDisplayFavoritesTooltip() && !ConfigObject.getInstance().getFavoriteKeyCode().isUnknown()) {
             if (interactableFavorites && ConfigObject.getInstance().doDisplayFavoritesTooltip() && !ConfigObject.getInstance().getFavoriteKeyCode().isUnknown()) {
                 String name = ConfigObject.getInstance().getFavoriteKeyCode().getLocalizedName();
                 String name = ConfigObject.getInstance().getFavoriteKeyCode().getLocalizedName();
@@ -302,13 +307,13 @@ public class EntryWidget extends Slot {
                 else
                 else
                     tooltip.getText().addAll(Arrays.asList(I18n.translate("text.rei.favorites_tooltip", name).split("\n")));
                     tooltip.getText().addAll(Arrays.asList(I18n.translate("text.rei.favorites_tooltip", name).split("\n")));
             }
             }
-            REIHelper.getInstance().addTooltip(tooltip);
+            tooltip.queue();
         }
         }
     }
     }
     
     
     @Override
     @Override
-    public QueuedTooltip getCurrentTooltip(int mouseX, int mouseY) {
-        return getCurrentEntry().getTooltip(mouseX, mouseY);
+    public @Nullable Tooltip getCurrentTooltip(me.shedaniel.math.Point point) {
+        return getCurrentEntry().getTooltip(point);
     }
     }
     
     
     protected void drawHighlighted(int mouseX, int mouseY, float delta) {
     protected void drawHighlighted(int mouseX, int mouseY, float delta) {

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

@@ -33,6 +33,7 @@ import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.math.impl.PointHelper;
 import me.shedaniel.math.impl.PointHelper;
 import me.shedaniel.rei.RoughlyEnoughItemsCore;
 import me.shedaniel.rei.RoughlyEnoughItemsCore;
 import me.shedaniel.rei.api.*;
 import me.shedaniel.rei.api.*;
+import me.shedaniel.rei.api.widgets.Tooltip;
 import me.shedaniel.rei.gui.config.ItemListOrdering;
 import me.shedaniel.rei.gui.config.ItemListOrdering;
 import me.shedaniel.rei.impl.ScreenHelper;
 import me.shedaniel.rei.impl.ScreenHelper;
 import me.shedaniel.rei.utils.CollectionUtils;
 import me.shedaniel.rei.utils.CollectionUtils;
@@ -153,7 +154,7 @@ public class FavoritesListWidget extends WidgetWithBounds {
         ScissorsHandler.INSTANCE.removeLastScissor();
         ScissorsHandler.INSTANCE.removeLastScissor();
         renderScrollbar();
         renderScrollbar();
         if (containsMouse(mouseX, mouseY) && ClientHelper.getInstance().isCheating() && !minecraft.player.inventory.getCursorStack().isEmpty() && RoughlyEnoughItemsCore.hasPermissionToUsePackets())
         if (containsMouse(mouseX, mouseY) && ClientHelper.getInstance().isCheating() && !minecraft.player.inventory.getCursorStack().isEmpty() && RoughlyEnoughItemsCore.hasPermissionToUsePackets())
-            REIHelper.getInstance().addTooltip(QueuedTooltip.create(I18n.translate("text.rei.delete_items")));
+            Tooltip.create(I18n.translate("text.rei.delete_items")).queue();
     }
     }
     
     
     private int getScrollbarMinX() {
     private int getScrollbarMinX() {

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

@@ -26,6 +26,7 @@ package me.shedaniel.rei.gui.widget;
 import me.shedaniel.math.Point;
 import me.shedaniel.math.Point;
 import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.rei.api.REIHelper;
 import me.shedaniel.rei.api.REIHelper;
+import me.shedaniel.rei.api.widgets.Tooltip;
 import me.shedaniel.rei.api.widgets.Widgets;
 import me.shedaniel.rei.api.widgets.Widgets;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.gui.Element;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.ApiStatus;
@@ -205,6 +206,6 @@ public class LabelWidget extends WidgetWithBounds {
     protected void drawTooltips(int mouseX, int mouseY) {
     protected void drawTooltips(int mouseX, int mouseY) {
         if (getTooltips().isPresent())
         if (getTooltips().isPresent())
             if (containsMouse(mouseX, mouseY))
             if (containsMouse(mouseX, mouseY))
-                REIHelper.getInstance().addTooltip(QueuedTooltip.create(getTooltips().get().split("\n")));
+                Tooltip.create(getTooltips().get().split("\n")).queue();
     }
     }
 }
 }

+ 20 - 17
src/main/java/me/shedaniel/rei/gui/widget/QueuedTooltip.java

@@ -27,19 +27,22 @@ package me.shedaniel.rei.gui.widget;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Lists;
 import me.shedaniel.math.Point;
 import me.shedaniel.math.Point;
 import me.shedaniel.math.impl.PointHelper;
 import me.shedaniel.math.impl.PointHelper;
-import me.shedaniel.rei.api.REIHelper;
+import me.shedaniel.rei.api.widgets.Tooltip;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.ApiStatus;
 
 
+import java.util.Collection;
 import java.util.List;
 import java.util.List;
-import java.util.function.Consumer;
 
 
-public class QueuedTooltip {
+/**
+ * @see Tooltip
+ */
+@ApiStatus.Internal
+public class QueuedTooltip implements Tooltip {
     
     
     private Point location;
     private Point location;
     private List<String> text;
     private List<String> text;
-    private Consumer<QueuedTooltip> consumer = null;
     
     
-    private QueuedTooltip(Point location, List<String> text) {
+    private QueuedTooltip(Point location, Collection<String> text) {
         this.location = location;
         this.location = location;
         this.text = Lists.newArrayList(text);
         this.text = Lists.newArrayList(text);
     }
     }
@@ -56,6 +59,10 @@ public class QueuedTooltip {
         return new QueuedTooltip(location, text);
         return new QueuedTooltip(location, text);
     }
     }
     
     
+    public static QueuedTooltip create(Point location, Collection<String> text) {
+        return new QueuedTooltip(location, text);
+    }
+    
     public static QueuedTooltip create(Point location, String... text) {
     public static QueuedTooltip create(Point location, String... text) {
         return QueuedTooltip.create(location, Lists.newArrayList(text));
         return QueuedTooltip.create(location, Lists.newArrayList(text));
     }
     }
@@ -64,19 +71,12 @@ public class QueuedTooltip {
         return QueuedTooltip.create(PointHelper.ofMouse(), text);
         return QueuedTooltip.create(PointHelper.ofMouse(), text);
     }
     }
     
     
-    public static QueuedTooltip create(String... text) {
+    public static QueuedTooltip create(Collection<String> text) {
         return QueuedTooltip.create(PointHelper.ofMouse(), text);
         return QueuedTooltip.create(PointHelper.ofMouse(), text);
     }
     }
     
     
-    @ApiStatus.Internal
-    public QueuedTooltip setSpecialRenderer(Consumer<QueuedTooltip> consumer) {
-        this.consumer = consumer;
-        return this;
-    }
-    
-    @ApiStatus.Internal
-    public Consumer<QueuedTooltip> getConsumer() {
-        return consumer;
+    public static QueuedTooltip create(String... text) {
+        return QueuedTooltip.create(PointHelper.ofMouse(), text);
     }
     }
     
     
     /**
     /**
@@ -89,20 +89,23 @@ public class QueuedTooltip {
         return new me.shedaniel.math.api.Point(location);
         return new me.shedaniel.math.api.Point(location);
     }
     }
     
     
+    @Override
     public int getX() {
     public int getX() {
         return location.x;
         return location.x;
     }
     }
     
     
+    @Override
     public int getY() {
     public int getY() {
         return location.y;
         return location.y;
     }
     }
     
     
+    @Override
     public List<String> getText() {
     public List<String> getText() {
         return text;
         return text;
     }
     }
     
     
+    @Override
     public void queue() {
     public void queue() {
-        REIHelper.getInstance().addTooltip(this);
+        Tooltip.super.queue();
     }
     }
-    
 }
 }

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

@@ -27,6 +27,12 @@ import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.rei.api.ConfigObject;
 import me.shedaniel.rei.api.ConfigObject;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.ApiStatus;
 
 
+/**
+ * @see me.shedaniel.rei.api.widgets.Widgets#createRecipeBase(me.shedaniel.math.Rectangle)
+ * @see me.shedaniel.rei.api.widgets.Widgets#createRecipeBase(me.shedaniel.math.Rectangle, int)
+ */
+@Deprecated
+@ApiStatus.ScheduledForRemoval
 public class RecipeBaseWidget extends PanelWidget {
 public class RecipeBaseWidget extends PanelWidget {
     
     
     /**
     /**

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

@@ -28,6 +28,8 @@ import com.mojang.blaze3d.systems.RenderSystem;
 import me.shedaniel.math.api.Point;
 import me.shedaniel.math.api.Point;
 import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.rei.api.REIHelper;
 import me.shedaniel.rei.api.REIHelper;
+import me.shedaniel.rei.api.widgets.Panel;
+import me.shedaniel.rei.api.widgets.Widgets;
 import me.shedaniel.rei.gui.RecipeViewingScreen;
 import me.shedaniel.rei.gui.RecipeViewingScreen;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.resource.language.I18n;
 import net.minecraft.client.resource.language.I18n;
@@ -49,7 +51,7 @@ public class RecipeChoosePageWidget extends DraggableWidget {
     private List<Widget> widgets;
     private List<Widget> widgets;
     private RecipeViewingScreen recipeViewingScreen;
     private RecipeViewingScreen recipeViewingScreen;
     private TextFieldWidget textFieldWidget;
     private TextFieldWidget textFieldWidget;
-    private CategoryBaseWidget base1, base2;
+    private Panel base1, base2;
     private ButtonWidget btnDone;
     private ButtonWidget btnDone;
     
     
     public RecipeChoosePageWidget(RecipeViewingScreen recipeViewingScreen, int currentPage, int maxPage) {
     public RecipeChoosePageWidget(RecipeViewingScreen recipeViewingScreen, int currentPage, int maxPage) {
@@ -102,8 +104,8 @@ public class RecipeChoosePageWidget extends DraggableWidget {
         this.grabBounds = new Rectangle(midPoint.x - 50, midPoint.y - 20, 100, 16);
         this.grabBounds = new Rectangle(midPoint.x - 50, midPoint.y - 20, 100, 16);
         this.dragBounds = new Rectangle(midPoint.x - 50, midPoint.y - 20, 100, 70);
         this.dragBounds = new Rectangle(midPoint.x - 50, midPoint.y - 20, 100, 70);
         this.widgets = Lists.newArrayList();
         this.widgets = Lists.newArrayList();
-        this.widgets.add(base1 = new CategoryBaseWidget(new Rectangle(bounds.x + bounds.width - 50, bounds.y + bounds.height - 6, 50, 36)));
-        this.widgets.add(base2 = new CategoryBaseWidget(bounds));
+        this.widgets.add(base1 = Widgets.createCategoryBase(new Rectangle(bounds.x + bounds.width - 50, bounds.y + bounds.height - 6, 50, 36)));
+        this.widgets.add(base2 = Widgets.createCategoryBase(bounds));
         this.widgets.add(new Widget() {
         this.widgets.add(new Widget() {
             @Override
             @Override
             public List<Widget> children() {
             public List<Widget> children() {

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

@@ -27,6 +27,12 @@ import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.rei.api.REIHelper;
 import me.shedaniel.rei.api.REIHelper;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.ApiStatus;
 
 
+/**
+ * @see me.shedaniel.rei.api.widgets.Widgets#createSlotBase(me.shedaniel.math.Rectangle)
+ * @see me.shedaniel.rei.api.widgets.Widgets#createSlotBase(me.shedaniel.math.Rectangle, int)
+ */
+@ApiStatus.ScheduledForRemoval
+@Deprecated
 public class SlotBaseWidget extends RecipeBaseWidget {
 public class SlotBaseWidget extends RecipeBaseWidget {
     
     
     /**
     /**
@@ -58,3 +64,4 @@ public class SlotBaseWidget extends RecipeBaseWidget {
     }
     }
     
     
 }
 }
+

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

@@ -28,6 +28,7 @@ import me.shedaniel.rei.api.ClientHelper;
 import me.shedaniel.rei.api.EntryStack;
 import me.shedaniel.rei.api.EntryStack;
 import me.shedaniel.rei.api.REIHelper;
 import me.shedaniel.rei.api.REIHelper;
 import me.shedaniel.rei.api.RecipeCategory;
 import me.shedaniel.rei.api.RecipeCategory;
+import me.shedaniel.rei.api.widgets.Tooltip;
 import net.minecraft.util.Formatting;
 import net.minecraft.util.Formatting;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.Identifier;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.ApiStatus;
@@ -116,9 +117,9 @@ public class TabWidget extends WidgetWithBounds {
     
     
     private void drawTooltip() {
     private void drawTooltip() {
         if (this.minecraft.options.advancedItemTooltips)
         if (this.minecraft.options.advancedItemTooltips)
-            REIHelper.getInstance().addTooltip(QueuedTooltip.create(categoryName, Formatting.DARK_GRAY.toString() + category.getIdentifier().toString(), ClientHelper.getInstance().getFormattedModFromIdentifier(category.getIdentifier())));
+            Tooltip.create(categoryName, Formatting.DARK_GRAY.toString() + category.getIdentifier().toString(), ClientHelper.getInstance().getFormattedModFromIdentifier(category.getIdentifier())).queue();
         else
         else
-            REIHelper.getInstance().addTooltip(QueuedTooltip.create(categoryName, ClientHelper.getInstance().getFormattedModFromIdentifier(category.getIdentifier())));
+            Tooltip.create(categoryName, ClientHelper.getInstance().getFormattedModFromIdentifier(category.getIdentifier())).queue();
     }
     }
     
     
     @Override
     @Override

+ 4 - 0
src/main/java/me/shedaniel/rei/gui/widget/Widget.java

@@ -66,6 +66,10 @@ public abstract class Widget extends AbstractParentElement implements Drawable {
         return containsMouse(point.x, point.y);
         return containsMouse(point.x, point.y);
     }
     }
     
     
+    public final boolean containsMouse(me.shedaniel.math.Point point) {
+        return containsMouse(point.x, point.y);
+    }
+    
     @Override
     @Override
     public final boolean isMouseOver(double double_1, double double_2) {
     public final boolean isMouseOver(double double_1, double double_2) {
         return containsMouse(double_1, double_2);
         return containsMouse(double_1, double_2);

+ 2 - 2
src/main/java/me/shedaniel/rei/impl/ClientHelperImpl.java

@@ -146,7 +146,7 @@ public class ClientHelperImpl implements ClientHelper, ClientModInitializer {
     
     
     @Override
     @Override
     public void sendDeletePacket() {
     public void sendDeletePacket() {
-        if (ScreenHelper.getLastScreenWithHandler() instanceof CreativeInventoryScreen) {
+        if (ScreenHelper.getLastHandledScreen() instanceof CreativeInventoryScreen) {
             MinecraftClient.getInstance().player.inventory.setCursorStack(ItemStack.EMPTY);
             MinecraftClient.getInstance().player.inventory.setCursorStack(ItemStack.EMPTY);
             return;
             return;
         }
         }
@@ -257,7 +257,7 @@ public class ClientHelperImpl implements ClientHelper, ClientModInitializer {
             screen = new VillagerRecipeViewingScreen(map, category);
             screen = new VillagerRecipeViewingScreen(map, category);
         } else if (ConfigObject.getInstance().getRecipeScreenType() == RecipeScreenType.UNSET) {
         } else if (ConfigObject.getInstance().getRecipeScreenType() == RecipeScreenType.UNSET) {
             @Nullable Identifier finalCategory = category;
             @Nullable Identifier finalCategory = category;
-            screen = new PreRecipeViewingScreen(ScreenHelper.getLastScreenWithHandler(), RecipeScreenType.UNSET, true, original -> {
+            screen = new PreRecipeViewingScreen(ScreenHelper.getLastHandledScreen(), RecipeScreenType.UNSET, true, original -> {
                 ConfigObject.getInstance().setRecipeScreenType(original ? RecipeScreenType.ORIGINAL : RecipeScreenType.VILLAGER);
                 ConfigObject.getInstance().setRecipeScreenType(original ? RecipeScreenType.ORIGINAL : RecipeScreenType.VILLAGER);
                 ConfigManager.getInstance().saveConfig();
                 ConfigManager.getInstance().saveConfig();
                 openRecipeViewingScreen(map, finalCategory, ingredientNotice, resultNotice);
                 openRecipeViewingScreen(map, finalCategory, ingredientNotice, resultNotice);

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

@@ -117,7 +117,7 @@ public class ConfigManagerImpl implements ConfigManager {
                         Collections.singletonList(new RecipeScreenTypeEntry(220, i13n, getUnsafely(field, config, RecipeScreenType.UNSET), getUnsafely(field, defaults), type -> setUnsafely(field, config, type)))
                         Collections.singletonList(new RecipeScreenTypeEntry(220, i13n, getUnsafely(field, config, RecipeScreenType.UNSET), getUnsafely(field, defaults), type -> setUnsafely(field, config, type)))
                 , (field) -> field.getType() == RecipeScreenType.class, ConfigObjectImpl.UseSpecialRecipeTypeScreen.class);
                 , (field) -> field.getType() == RecipeScreenType.class, ConfigObjectImpl.UseSpecialRecipeTypeScreen.class);
         guiRegistry.registerAnnotationProvider((i13n, field, config, defaults, guiProvider) ->
         guiRegistry.registerAnnotationProvider((i13n, field, config, defaults, guiProvider) ->
-                        ScreenHelper.getLastScreenWithHandlerHooks() == null || MinecraftClient.getInstance().getNetworkHandler() == null || MinecraftClient.getInstance().getNetworkHandler().getRecipeManager() == null ?
+                        ScreenHelper.getLastHandledScreen() == null || MinecraftClient.getInstance().getNetworkHandler() == null || MinecraftClient.getInstance().getNetworkHandler().getRecipeManager() == null ?
                                 Collections.singletonList(new NoFilteringEntry(getUnsafely(field, config, new ArrayList<>()), getUnsafely(field, defaults), list -> setUnsafely(field, config, list)))
                                 Collections.singletonList(new NoFilteringEntry(getUnsafely(field, config, new ArrayList<>()), getUnsafely(field, defaults), list -> setUnsafely(field, config, list)))
                                 :
                                 :
                                 Collections.singletonList(new FilteringEntry(getUnsafely(field, config, new ArrayList<>()), getUnsafely(field, defaults), list -> setUnsafely(field, config, list)))
                                 Collections.singletonList(new FilteringEntry(getUnsafely(field, config, new ArrayList<>()), getUnsafely(field, defaults), list -> setUnsafely(field, config, list)))

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

@@ -110,6 +110,7 @@ public class DisplayHelperImpl implements DisplayHelper {
         screenDisplayBoundsHandlers.sort(BOUNDS_HANDLER_COMPARATOR);
         screenDisplayBoundsHandlers.sort(BOUNDS_HANDLER_COMPARATOR);
     }
     }
     
     
+    @Deprecated
     @Override
     @Override
     public BaseBoundsHandler getBaseBoundsHandler() {
     public BaseBoundsHandler getBaseBoundsHandler() {
         return baseBoundsHandler;
         return baseBoundsHandler;

+ 3 - 3
src/main/java/me/shedaniel/rei/impl/EmptyEntryStack.java

@@ -23,9 +23,10 @@
 
 
 package me.shedaniel.rei.impl;
 package me.shedaniel.rei.impl;
 
 
+import me.shedaniel.math.Point;
 import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.rei.api.EntryStack;
 import me.shedaniel.rei.api.EntryStack;
-import me.shedaniel.rei.gui.widget.QueuedTooltip;
+import me.shedaniel.rei.api.widgets.Tooltip;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.Identifier;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.annotations.Nullable;
@@ -131,8 +132,7 @@ public class EmptyEntryStack implements EntryStack {
     }
     }
     
     
     @Override
     @Override
-    @Nullable
-    public QueuedTooltip getTooltip(int mouseX, int mouseY) {
+    public @Nullable Tooltip getTooltip(Point point) {
         return null;
         return null;
     }
     }
     
     

+ 4 - 3
src/main/java/me/shedaniel/rei/impl/FluidEntryStack.java

@@ -24,11 +24,12 @@
 package me.shedaniel.rei.impl;
 package me.shedaniel.rei.impl;
 
 
 import com.google.common.collect.Lists;
 import com.google.common.collect.Lists;
+import me.shedaniel.math.Point;
 import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.rei.api.ClientHelper;
 import me.shedaniel.rei.api.ClientHelper;
 import me.shedaniel.rei.api.ConfigObject;
 import me.shedaniel.rei.api.ConfigObject;
 import me.shedaniel.rei.api.EntryStack;
 import me.shedaniel.rei.api.EntryStack;
-import me.shedaniel.rei.gui.widget.QueuedTooltip;
+import me.shedaniel.rei.api.widgets.Tooltip;
 import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandler;
 import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandler;
 import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandlerRegistry;
 import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandlerRegistry;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.MinecraftClient;
@@ -178,7 +179,7 @@ public class FluidEntryStack extends AbstractEntryStack {
     
     
     @Nullable
     @Nullable
     @Override
     @Override
-    public QueuedTooltip getTooltip(int mouseX, int mouseY) {
+    public Tooltip getTooltip(Point point) {
         if (!get(Settings.TOOLTIP_ENABLED).get() || isEmpty())
         if (!get(Settings.TOOLTIP_ENABLED).get() || isEmpty())
             return null;
             return null;
         List<String> toolTip = Lists.newArrayList(SearchArgument.tryGetEntryStackName(this));
         List<String> toolTip = Lists.newArrayList(SearchArgument.tryGetEntryStackName(this));
@@ -199,7 +200,7 @@ public class FluidEntryStack extends AbstractEntryStack {
             if (!alreadyHasMod)
             if (!alreadyHasMod)
                 toolTip.add(modString);
                 toolTip.add(modString);
         }
         }
-        return QueuedTooltip.create(toolTip);
+        return Tooltip.create(toolTip);
     }
     }
     
     
     @SuppressWarnings("deprecation")
     @SuppressWarnings("deprecation")

+ 4 - 3
src/main/java/me/shedaniel/rei/impl/ItemEntryStack.java

@@ -25,9 +25,10 @@ package me.shedaniel.rei.impl;
 
 
 import com.google.common.collect.Lists;
 import com.google.common.collect.Lists;
 import com.mojang.blaze3d.platform.GlStateManager;
 import com.mojang.blaze3d.platform.GlStateManager;
+import me.shedaniel.math.Point;
 import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.rei.api.*;
 import me.shedaniel.rei.api.*;
-import me.shedaniel.rei.gui.widget.QueuedTooltip;
+import me.shedaniel.rei.api.widgets.Tooltip;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.render.OverlayTexture;
 import net.minecraft.client.render.OverlayTexture;
 import net.minecraft.client.render.VertexConsumerProvider;
 import net.minecraft.client.render.VertexConsumerProvider;
@@ -215,7 +216,7 @@ public class ItemEntryStack extends AbstractEntryStack implements OptimalEntrySt
     
     
     @Nullable
     @Nullable
     @Override
     @Override
-    public QueuedTooltip getTooltip(int mouseX, int mouseY) {
+    public Tooltip getTooltip(Point point) {
         if (isEmpty() || !get(Settings.TOOLTIP_ENABLED).get())
         if (isEmpty() || !get(Settings.TOOLTIP_ENABLED).get())
             return null;
             return null;
         List<String> toolTip = Lists.newArrayList(SearchArgument.tryGetItemStackToolTip(getItemStack(), true));
         List<String> toolTip = Lists.newArrayList(SearchArgument.tryGetItemStackToolTip(getItemStack(), true));
@@ -231,7 +232,7 @@ public class ItemEntryStack extends AbstractEntryStack implements OptimalEntrySt
             if (!alreadyHasMod)
             if (!alreadyHasMod)
                 toolTip.add(modString);
                 toolTip.add(modString);
         }
         }
-        return QueuedTooltip.create(toolTip);
+        return Tooltip.create(toolTip);
     }
     }
     
     
     @Override
     @Override

+ 6 - 6
src/main/java/me/shedaniel/rei/impl/RecipeHelperImpl.java

@@ -31,7 +31,7 @@ import me.shedaniel.rei.RoughlyEnoughItemsCore;
 import me.shedaniel.rei.api.*;
 import me.shedaniel.rei.api.*;
 import me.shedaniel.rei.api.plugins.REIPluginV0;
 import me.shedaniel.rei.api.plugins.REIPluginV0;
 import me.shedaniel.rei.utils.CollectionUtils;
 import me.shedaniel.rei.utils.CollectionUtils;
-import net.minecraft.client.gui.screen.ingame.ScreenWithHandler;
+import net.minecraft.client.gui.screen.ingame.HandledScreen;
 import net.minecraft.recipe.Recipe;
 import net.minecraft.recipe.Recipe;
 import net.minecraft.recipe.RecipeManager;
 import net.minecraft.recipe.RecipeManager;
 import net.minecraft.util.ActionResult;
 import net.minecraft.util.ActionResult;
@@ -355,7 +355,7 @@ public class RecipeHelperImpl implements RecipeHelper {
             
             
             @Override
             @Override
             public ActionResult shouldScreenBeOverlayed(Class<?> screen) {
             public ActionResult shouldScreenBeOverlayed(Class<?> screen) {
-                return ScreenWithHandler.class.isAssignableFrom(screen) ? ActionResult.SUCCESS : ActionResult.PASS;
+                return HandledScreen.class.isAssignableFrom(screen) ? ActionResult.SUCCESS : ActionResult.PASS;
             }
             }
             
             
             @Override
             @Override
@@ -461,7 +461,7 @@ public class RecipeHelperImpl implements RecipeHelper {
     }
     }
     
     
     @Override
     @Override
-    public void registerScreenClickArea(Rectangle rectangle, Class<? extends ScreenWithHandler<?>> screenClass, Identifier... categories) {
+    public void registerScreenClickArea(Rectangle rectangle, Class<? extends HandledScreen<?>> screenClass, Identifier... categories) {
         this.screenClickAreas.add(new ScreenClickAreaImpl(screenClass, rectangle, categories));
         this.screenClickAreas.add(new ScreenClickAreaImpl(screenClass, rectangle, categories));
     }
     }
     
     
@@ -493,17 +493,17 @@ public class RecipeHelperImpl implements RecipeHelper {
     }
     }
     
     
     private static class ScreenClickAreaImpl implements ScreenClickArea {
     private static class ScreenClickAreaImpl implements ScreenClickArea {
-        Class<? extends ScreenWithHandler<?>> screenClass;
+        Class<? extends HandledScreen<?>> screenClass;
         Rectangle rectangle;
         Rectangle rectangle;
         Identifier[] categories;
         Identifier[] categories;
         
         
-        private ScreenClickAreaImpl(Class<? extends ScreenWithHandler<?>> screenClass, Rectangle rectangle, Identifier[] categories) {
+        private ScreenClickAreaImpl(Class<? extends HandledScreen<?>> screenClass, Rectangle rectangle, Identifier[] categories) {
             this.screenClass = screenClass;
             this.screenClass = screenClass;
             this.rectangle = rectangle;
             this.rectangle = rectangle;
             this.categories = categories;
             this.categories = categories;
         }
         }
         
         
-        public Class<? extends ScreenWithHandler<?>> getScreenClass() {
+        public Class<? extends HandledScreen<?>> getScreenClass() {
             return screenClass;
             return screenClass;
         }
         }
         
         

+ 3 - 1
src/main/java/me/shedaniel/rei/impl/RenderingEntry.java

@@ -131,7 +131,9 @@ public abstract class RenderingEntry extends DrawableHelper implements EntryStac
     
     
     @Nullable
     @Nullable
     @Override
     @Override
+    @Deprecated
+    @ApiStatus.ScheduledForRemoval
     public QueuedTooltip getTooltip(int mouseX, int mouseY) {
     public QueuedTooltip getTooltip(int mouseX, int mouseY) {
-        return null;
+        return EntryStack.super.getTooltip(mouseX, mouseY);
     }
     }
 }
 }

+ 35 - 15
src/main/java/me/shedaniel/rei/impl/ScreenHelper.java

@@ -30,17 +30,17 @@ import me.shedaniel.cloth.hooks.ClothClientHooks;
 import me.shedaniel.rei.api.ConfigManager;
 import me.shedaniel.rei.api.ConfigManager;
 import me.shedaniel.rei.api.ConfigObject;
 import me.shedaniel.rei.api.ConfigObject;
 import me.shedaniel.rei.api.REIHelper;
 import me.shedaniel.rei.api.REIHelper;
+import me.shedaniel.rei.api.widgets.Tooltip;
 import me.shedaniel.rei.gui.ContainerScreenOverlay;
 import me.shedaniel.rei.gui.ContainerScreenOverlay;
 import me.shedaniel.rei.gui.OverlaySearchField;
 import me.shedaniel.rei.gui.OverlaySearchField;
 import me.shedaniel.rei.gui.RecipeScreen;
 import me.shedaniel.rei.gui.RecipeScreen;
-import me.shedaniel.rei.gui.widget.QueuedTooltip;
 import me.shedaniel.rei.gui.widget.TextFieldWidget;
 import me.shedaniel.rei.gui.widget.TextFieldWidget;
 import me.shedaniel.rei.listeners.ContainerScreenHooks;
 import me.shedaniel.rei.listeners.ContainerScreenHooks;
 import net.fabricmc.api.ClientModInitializer;
 import net.fabricmc.api.ClientModInitializer;
 import net.fabricmc.fabric.api.event.client.ClientTickCallback;
 import net.fabricmc.fabric.api.event.client.ClientTickCallback;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.screen.Screen;
 import net.minecraft.client.gui.screen.Screen;
-import net.minecraft.client.gui.screen.ingame.ScreenWithHandler;
+import net.minecraft.client.gui.screen.ingame.HandledScreen;
 import net.minecraft.client.util.Window;
 import net.minecraft.client.util.Window;
 import net.minecraft.item.ItemStack;
 import net.minecraft.item.ItemStack;
 import net.minecraft.util.ActionResult;
 import net.minecraft.util.ActionResult;
@@ -59,7 +59,7 @@ public class ScreenHelper implements ClientModInitializer, REIHelper {
     @ApiStatus.Internal
     @ApiStatus.Internal
     public static List<ItemStack> inventoryStacks = Lists.newArrayList();
     public static List<ItemStack> inventoryStacks = Lists.newArrayList();
     private static ContainerScreenOverlay overlay;
     private static ContainerScreenOverlay overlay;
-    private static ScreenWithHandler<?> lastScreenWithHandler = null;
+    private static HandledScreen<?> lastHandledScreen = null;
     private static LinkedHashSet<RecipeScreen> lastRecipeScreen = Sets.newLinkedHashSetWithExpectedSize(5);
     private static LinkedHashSet<RecipeScreen> lastRecipeScreen = Sets.newLinkedHashSetWithExpectedSize(5);
     private static ScreenHelper instance;
     private static ScreenHelper instance;
     
     
@@ -73,7 +73,7 @@ public class ScreenHelper implements ClientModInitializer, REIHelper {
     }
     }
     
     
     @Override
     @Override
-    public void addTooltip(@Nullable QueuedTooltip tooltip) {
+    public void queueTooltip(@Nullable Tooltip tooltip) {
         if (overlay != null && tooltip != null) {
         if (overlay != null && tooltip != null) {
             overlay.addTooltip(tooltip);
             overlay.addTooltip(tooltip);
         }
         }
@@ -148,32 +148,52 @@ public class ScreenHelper implements ClientModInitializer, REIHelper {
     
     
     @Deprecated
     @Deprecated
     @ApiStatus.ScheduledForRemoval
     @ApiStatus.ScheduledForRemoval
-    public static ScreenWithHandler<?> getLastContainerScreen() {
-        return getLastScreenWithHandler();
+    public static HandledScreen<?> getLastContainerScreen() {
+        return getLastHandledScreen();
     }
     }
     
     
-    public static ScreenWithHandler<?> getLastScreenWithHandler() {
-        return lastScreenWithHandler;
+    @Deprecated
+    @ApiStatus.ScheduledForRemoval
+    public static HandledScreen<?> getLastScreenWithHandler() {
+        return getLastHandledScreen();
+    }
+    
+    public static HandledScreen<?> getLastHandledScreen() {
+        return lastHandledScreen;
+    }
+    
+    @Deprecated
+    @ApiStatus.ScheduledForRemoval
+    public static void setLastContainerScreen(HandledScreen<?> lastScreenWithHandler) {
+        setLastHandledScreen(lastScreenWithHandler);
     }
     }
     
     
     @Deprecated
     @Deprecated
     @ApiStatus.ScheduledForRemoval
     @ApiStatus.ScheduledForRemoval
-    public static void setLastContainerScreen(ScreenWithHandler<?> lastScreenWithHandler) {
-        setLastScreenWithHandler(lastScreenWithHandler);
+    public static void setLastScreenWithHandler(HandledScreen<?> lastScreenWithHandler) {
+        setLastHandledScreen(lastScreenWithHandler);
     }
     }
     
     
-    public static void setLastScreenWithHandler(ScreenWithHandler<?> lastScreenWithHandler) {
-        ScreenHelper.lastScreenWithHandler = lastScreenWithHandler;
+    public static void setLastHandledScreen(HandledScreen<?> lastScreenWithHandler) {
+        ScreenHelper.lastHandledScreen = lastScreenWithHandler;
     }
     }
     
     
+    /**
+     * @deprecated Please create your own mixin hooks
+     */
     @Deprecated
     @Deprecated
     @ApiStatus.ScheduledForRemoval
     @ApiStatus.ScheduledForRemoval
     public static ContainerScreenHooks getLastContainerScreenHooks() {
     public static ContainerScreenHooks getLastContainerScreenHooks() {
         return getLastScreenWithHandlerHooks();
         return getLastScreenWithHandlerHooks();
     }
     }
     
     
+    /**
+     * @deprecated Please create your own mixin hooks
+     */
+    @Deprecated
+    @ApiStatus.ScheduledForRemoval
     public static ContainerScreenHooks getLastScreenWithHandlerHooks() {
     public static ContainerScreenHooks getLastScreenWithHandlerHooks() {
-        return (ContainerScreenHooks) lastScreenWithHandler;
+        return (ContainerScreenHooks) lastHandledScreen;
     }
     }
     
     
     public static void drawHoveringWidget(int x, int y, TriConsumer<Integer, Integer, Float> consumer, int width, int height, float delta) {
     public static void drawHoveringWidget(int x, int y, TriConsumer<Integer, Integer, Float> consumer, int width, int height, float delta) {
@@ -210,8 +230,8 @@ public class ScreenHelper implements ClientModInitializer, REIHelper {
     @Override
     @Override
     public void onInitializeClient() {
     public void onInitializeClient() {
         ClothClientHooks.SCREEN_INIT_PRE.register((client, screen, screenHooks) -> {
         ClothClientHooks.SCREEN_INIT_PRE.register((client, screen, screenHooks) -> {
-            if (lastScreenWithHandler != screen && screen instanceof ScreenWithHandler)
-                lastScreenWithHandler = (ScreenWithHandler<?>) screen;
+            if (lastHandledScreen != screen && screen instanceof HandledScreen)
+                lastHandledScreen = (HandledScreen<?>) screen;
             return ActionResult.PASS;
             return ActionResult.PASS;
         });
         });
         ClientTickCallback.EVENT.register(minecraftClient -> {
         ClientTickCallback.EVENT.register(minecraftClient -> {

+ 3 - 2
src/main/java/me/shedaniel/rei/impl/SearchArgument.java

@@ -24,9 +24,10 @@
 package me.shedaniel.rei.impl;
 package me.shedaniel.rei.impl;
 
 
 import com.google.common.collect.Lists;
 import com.google.common.collect.Lists;
+import me.shedaniel.math.Point;
 import me.shedaniel.rei.api.ClientHelper;
 import me.shedaniel.rei.api.ClientHelper;
 import me.shedaniel.rei.api.EntryStack;
 import me.shedaniel.rei.api.EntryStack;
-import me.shedaniel.rei.gui.widget.QueuedTooltip;
+import me.shedaniel.rei.api.widgets.Tooltip;
 import me.shedaniel.rei.utils.CollectionUtils;
 import me.shedaniel.rei.utils.CollectionUtils;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.item.TooltipContext;
 import net.minecraft.client.item.TooltipContext;
@@ -198,7 +199,7 @@ public class SearchArgument {
     }
     }
     
     
     public static String tryGetEntryStackTooltip(EntryStack stack) {
     public static String tryGetEntryStackTooltip(EntryStack stack) {
-        QueuedTooltip tooltip = stack.getTooltip(0, 0);
+        Tooltip tooltip = stack.getTooltip(new Point());
         if (tooltip != null)
         if (tooltip != null)
             return CollectionUtils.joinToString(tooltip.getText(), "\n");
             return CollectionUtils.joinToString(tooltip.getText(), "\n");
         return "";
         return "";

+ 2 - 1
src/main/java/me/shedaniel/rei/impl/widgets/BurningFireWidget.java

@@ -57,7 +57,8 @@ public class BurningFireWidget extends BurningFire {
     }
     }
     
     
     @Override
     @Override
-    public @NotNull Rectangle getBounds() {
+    @NotNull
+    public Rectangle getBounds() {
         return bounds;
         return bounds;
     }
     }
     
     

+ 3 - 1
src/main/java/me/shedaniel/rei/impl/widgets/DrawableWidget.java

@@ -26,14 +26,16 @@ package me.shedaniel.rei.impl.widgets;
 import me.shedaniel.rei.api.DrawableConsumer;
 import me.shedaniel.rei.api.DrawableConsumer;
 import me.shedaniel.rei.gui.widget.Widget;
 import me.shedaniel.rei.gui.widget.Widget;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.gui.Element;
+import org.jetbrains.annotations.NotNull;
 
 
 import java.util.Collections;
 import java.util.Collections;
 import java.util.List;
 import java.util.List;
 
 
 public final class DrawableWidget extends Widget {
 public final class DrawableWidget extends Widget {
+    @NotNull
     private DrawableConsumer drawable;
     private DrawableConsumer drawable;
     
     
-    public DrawableWidget(DrawableConsumer drawable) {
+    public DrawableWidget(@NotNull DrawableConsumer drawable) {
         this.drawable = drawable;
         this.drawable = drawable;
     }
     }
     
     

+ 4 - 2
src/main/java/me/shedaniel/rei/impl/widgets/FillRectangleDrawableConsumer.java

@@ -30,18 +30,20 @@ import net.minecraft.client.gui.DrawableHelper;
 import net.minecraft.client.render.BufferBuilder;
 import net.minecraft.client.render.BufferBuilder;
 import net.minecraft.client.render.Tessellator;
 import net.minecraft.client.render.Tessellator;
 import net.minecraft.client.render.VertexFormats;
 import net.minecraft.client.render.VertexFormats;
+import org.jetbrains.annotations.NotNull;
 
 
 public class FillRectangleDrawableConsumer implements DrawableConsumer {
 public class FillRectangleDrawableConsumer implements DrawableConsumer {
+    @NotNull
     private Rectangle rectangle;
     private Rectangle rectangle;
     private int color;
     private int color;
     
     
-    public FillRectangleDrawableConsumer(Rectangle rectangle, int color) {
+    public FillRectangleDrawableConsumer(@NotNull Rectangle rectangle, int color) {
         this.rectangle = rectangle;
         this.rectangle = rectangle;
         this.color = color;
         this.color = color;
     }
     }
     
     
     @Override
     @Override
-    public void render(DrawableHelper helper, int mouseX, int mouseY, float delta) {
+    public void render(@NotNull DrawableHelper helper, int mouseX, int mouseY, float delta) {
         float a = (color >> 24 & 255) / 255.0F;
         float a = (color >> 24 & 255) / 255.0F;
         float r = (color >> 16 & 255) / 255.0F;
         float r = (color >> 16 & 255) / 255.0F;
         float g = (color >> 8 & 255) / 255.0F;
         float g = (color >> 8 & 255) / 255.0F;

+ 6 - 6
src/main/java/me/shedaniel/rei/impl/widgets/LabelWidget.java

@@ -27,8 +27,8 @@ import me.shedaniel.math.Point;
 import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.rei.api.REIHelper;
 import me.shedaniel.rei.api.REIHelper;
 import me.shedaniel.rei.api.widgets.Label;
 import me.shedaniel.rei.api.widgets.Label;
+import me.shedaniel.rei.api.widgets.Tooltip;
 import me.shedaniel.rei.api.widgets.Widgets;
 import me.shedaniel.rei.api.widgets.Widgets;
-import me.shedaniel.rei.gui.widget.QueuedTooltip;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.gui.Element;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.annotations.Nullable;
@@ -48,14 +48,14 @@ public final class LabelWidget extends Label {
     private boolean focusable = true;
     private boolean focusable = true;
     private int color = REIHelper.getInstance().isDarkThemeEnabled() ? 0xFFBBBBBB : -1;
     private int color = REIHelper.getInstance().isDarkThemeEnabled() ? 0xFFBBBBBB : -1;
     private int hoveredColor = REIHelper.getInstance().isDarkThemeEnabled() ? -1 : 0xFF66FFCC;
     private int hoveredColor = REIHelper.getInstance().isDarkThemeEnabled() ? -1 : 0xFF66FFCC;
-    private Point point;
+    @NotNull private Point point;
     @Nullable private Function<Label, @Nullable String> tooltip;
     @Nullable private Function<Label, @Nullable String> tooltip;
     @Nullable private Consumer<Label> onClick;
     @Nullable private Consumer<Label> onClick;
     @Nullable private Consumer<Label> onRender;
     @Nullable private Consumer<Label> onRender;
     @NotNull private String text;
     @NotNull private String text;
     
     
-    public LabelWidget(Point point, @NotNull String text) {
-        this.point = point;
+    public LabelWidget(@NotNull Point point, @NotNull String text) {
+        Objects.requireNonNull(this.point = point);
         Objects.requireNonNull(this.text = text);
         Objects.requireNonNull(this.text = text);
     }
     }
     
     
@@ -219,9 +219,9 @@ public final class LabelWidget extends Label {
             String tooltip = getTooltip();
             String tooltip = getTooltip();
             if (tooltip != null) {
             if (tooltip != null) {
                 if (!focused && containsMouse(mouseX, mouseY))
                 if (!focused && containsMouse(mouseX, mouseY))
-                    QueuedTooltip.create(tooltip.split("\n")).queue();
+                    Tooltip.create(tooltip.split("\n")).queue();
                 else if (focused)
                 else if (focused)
-                    QueuedTooltip.create(point, tooltip.split("\n")).queue();
+                    Tooltip.create(point, tooltip.split("\n")).queue();
             }
             }
         }
         }
     }
     }

+ 6 - 6
src/main/java/me/shedaniel/rei/impl/widgets/PanelWidget.java

@@ -44,7 +44,7 @@ public final class PanelWidget extends Panel {
     private static final Identifier CHEST_GUI_TEXTURE_DARK = new Identifier("roughlyenoughitems", "textures/gui/recipecontainer_dark.png");
     private static final Identifier CHEST_GUI_TEXTURE_DARK = new Identifier("roughlyenoughitems", "textures/gui/recipecontainer_dark.png");
     
     
     private static final PanelWidget TEMP = new PanelWidget(new Rectangle());
     private static final PanelWidget TEMP = new PanelWidget(new Rectangle());
-    private Rectangle bounds;
+    private me.shedaniel.math.api.Rectangle bounds;
     private int color = -1;
     private int color = -1;
     private int innerColor = REIHelper.getInstance().isDarkThemeEnabled() ? -13750738 : -3750202;
     private int innerColor = REIHelper.getInstance().isDarkThemeEnabled() ? -13750738 : -3750202;
     private int xTextureOffset = 0;
     private int xTextureOffset = 0;
@@ -56,12 +56,12 @@ public final class PanelWidget extends Panel {
         return ConfigObject.getInstance().getRecipeScreenType() != RecipeScreenType.VILLAGER;
         return ConfigObject.getInstance().getRecipeScreenType() != RecipeScreenType.VILLAGER;
     }
     }
     
     
-    public PanelWidget(Rectangle bounds) {
-        this.bounds = bounds;
+    public PanelWidget(@NotNull Rectangle bounds) {
+        this.bounds = new me.shedaniel.math.api.Rectangle(bounds);
     }
     }
     
     
-    public static void render(Rectangle bounds, int color) {
-        TEMP.bounds = bounds;
+    public static void render(@NotNull Rectangle bounds, int color) {
+        TEMP.bounds.setBounds(bounds);
         TEMP.color = color;
         TEMP.color = color;
         TEMP.render(0, 0, 0);
         TEMP.render(0, 0, 0);
     }
     }
@@ -118,7 +118,7 @@ public final class PanelWidget extends Panel {
     
     
     @Override
     @Override
     public me.shedaniel.math.api.Rectangle getBounds() {
     public me.shedaniel.math.api.Rectangle getBounds() {
-        return new me.shedaniel.math.api.Rectangle(bounds);
+        return bounds;
     }
     }
     
     
     @Override
     @Override

+ 4 - 2
src/main/java/me/shedaniel/rei/impl/widgets/TexturedDrawableConsumer.java

@@ -30,15 +30,17 @@ import net.minecraft.client.render.BufferBuilder;
 import net.minecraft.client.render.Tessellator;
 import net.minecraft.client.render.Tessellator;
 import net.minecraft.client.render.VertexFormats;
 import net.minecraft.client.render.VertexFormats;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.Identifier;
+import org.jetbrains.annotations.NotNull;
 import org.lwjgl.opengl.GL11;
 import org.lwjgl.opengl.GL11;
 
 
 public class TexturedDrawableConsumer implements DrawableConsumer {
 public class TexturedDrawableConsumer implements DrawableConsumer {
     
     
+    @NotNull
     private Identifier identifier;
     private Identifier identifier;
     private int x, y, width, height, uWidth, vHeight, textureWidth, textureHeight;
     private int x, y, width, height, uWidth, vHeight, textureWidth, textureHeight;
     private float u, v;
     private float u, v;
     
     
-    public TexturedDrawableConsumer(Identifier identifier, int x, int y, int width, int height, float u, float v, int uWidth, int vHeight, int textureWidth, int textureHeight) {
+    public TexturedDrawableConsumer(@NotNull Identifier identifier, int x, int y, int width, int height, float u, float v, int uWidth, int vHeight, int textureWidth, int textureHeight) {
         this.identifier = identifier;
         this.identifier = identifier;
         this.x = x;
         this.x = x;
         this.y = y;
         this.y = y;
@@ -53,7 +55,7 @@ public class TexturedDrawableConsumer implements DrawableConsumer {
     }
     }
     
     
     @Override
     @Override
-    public void render(DrawableHelper helper, int mouseX, int mouseY, float delta) {
+    public void render(@NotNull DrawableHelper helper, int mouseX, int mouseY, float delta) {
         MinecraftClient.getInstance().getTextureManager().bindTexture(identifier);
         MinecraftClient.getInstance().getTextureManager().bindTexture(identifier);
         innerBlit(x, x + width, y, y + height, helper.getZOffset(), uWidth, vHeight, u, v, textureWidth, textureHeight);
         innerBlit(x, x + width, y, y + height, helper.getZOffset(), uWidth, vHeight, u, v, textureWidth, textureHeight);
     }
     }

+ 1 - 1
src/main/java/me/shedaniel/rei/listeners/AbstractInventoryScreenHooks.java

@@ -31,6 +31,6 @@ import org.spongepowered.asm.mixin.gen.Accessor;
 @ApiStatus.Internal
 @ApiStatus.Internal
 @Mixin(AbstractInventoryScreen.class)
 @Mixin(AbstractInventoryScreen.class)
 public interface AbstractInventoryScreenHooks {
 public interface AbstractInventoryScreenHooks {
-    @Accessor("offsetGuiForEffects")
+    @Accessor("drawStatusEffects")
     boolean rei_doesOffsetGuiForEffects();
     boolean rei_doesOffsetGuiForEffects();
 }
 }

+ 2 - 2
src/main/java/me/shedaniel/rei/listeners/ContainerScreenHooks.java

@@ -23,14 +23,14 @@
 
 
 package me.shedaniel.rei.listeners;
 package me.shedaniel.rei.listeners;
 
 
-import net.minecraft.client.gui.screen.ingame.ScreenWithHandler;
+import net.minecraft.client.gui.screen.ingame.HandledScreen;
 import net.minecraft.screen.slot.Slot;
 import net.minecraft.screen.slot.Slot;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.ApiStatus;
 import org.spongepowered.asm.mixin.Mixin;
 import org.spongepowered.asm.mixin.Mixin;
 import org.spongepowered.asm.mixin.gen.Accessor;
 import org.spongepowered.asm.mixin.gen.Accessor;
 
 
 @ApiStatus.Internal
 @ApiStatus.Internal
-@Mixin(ScreenWithHandler.class)
+@Mixin(HandledScreen.class)
 public interface ContainerScreenHooks {
 public interface ContainerScreenHooks {
     
     
     @Accessor("x")
     @Accessor("x")

+ 14 - 12
src/main/java/me/shedaniel/rei/plugin/DefaultPlugin.java

@@ -26,17 +26,19 @@ package me.shedaniel.rei.plugin;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Maps;
 import it.unimi.dsi.fastutil.objects.Object2FloatMap;
 import it.unimi.dsi.fastutil.objects.Object2FloatMap;
+import me.shedaniel.math.Point;
 import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.rei.RoughlyEnoughItemsCore;
 import me.shedaniel.rei.RoughlyEnoughItemsCore;
 import me.shedaniel.rei.api.*;
 import me.shedaniel.rei.api.*;
 import me.shedaniel.rei.api.plugins.REIPluginV0;
 import me.shedaniel.rei.api.plugins.REIPluginV0;
+import me.shedaniel.rei.api.widgets.Panel;
+import me.shedaniel.rei.api.widgets.Tooltip;
 import me.shedaniel.rei.gui.RecipeViewingScreen;
 import me.shedaniel.rei.gui.RecipeViewingScreen;
 import me.shedaniel.rei.gui.VillagerRecipeViewingScreen;
 import me.shedaniel.rei.gui.VillagerRecipeViewingScreen;
-import me.shedaniel.rei.gui.widget.CategoryBaseWidget;
-import me.shedaniel.rei.gui.widget.QueuedTooltip;
 import me.shedaniel.rei.impl.ClientHelperImpl;
 import me.shedaniel.rei.impl.ClientHelperImpl;
 import me.shedaniel.rei.impl.RenderingEntry;
 import me.shedaniel.rei.impl.RenderingEntry;
 import me.shedaniel.rei.impl.ScreenHelper;
 import me.shedaniel.rei.impl.ScreenHelper;
+import me.shedaniel.rei.listeners.ContainerScreenHooks;
 import me.shedaniel.rei.plugin.beacon.DefaultBeaconBaseCategory;
 import me.shedaniel.rei.plugin.beacon.DefaultBeaconBaseCategory;
 import me.shedaniel.rei.plugin.beacon.DefaultBeaconBaseDisplay;
 import me.shedaniel.rei.plugin.beacon.DefaultBeaconBaseDisplay;
 import me.shedaniel.rei.plugin.blasting.DefaultBlastingDisplay;
 import me.shedaniel.rei.plugin.blasting.DefaultBlastingDisplay;
@@ -173,8 +175,8 @@ public class DefaultPlugin implements REIPluginV0 {
             }
             }
             
             
             @Override
             @Override
-            public @Nullable QueuedTooltip getTooltip(int mouseX, int mouseY) {
-                return QueuedTooltip.create("Kibby");
+            public @Nullable Tooltip getTooltip(Point point) {
+                return Tooltip.create("Kibby");
             }
             }
         });
         });
     }
     }
@@ -289,7 +291,7 @@ public class DefaultPlugin implements REIPluginV0 {
         baseBoundsHandler.registerExclusionZones(AbstractInventoryScreen.class, new DefaultPotionEffectExclusionZones());
         baseBoundsHandler.registerExclusionZones(AbstractInventoryScreen.class, new DefaultPotionEffectExclusionZones());
         baseBoundsHandler.registerExclusionZones(RecipeBookProvider.class, new DefaultRecipeBookExclusionZones());
         baseBoundsHandler.registerExclusionZones(RecipeBookProvider.class, new DefaultRecipeBookExclusionZones());
         baseBoundsHandler.registerExclusionZones(RecipeViewingScreen.class, () -> {
         baseBoundsHandler.registerExclusionZones(RecipeViewingScreen.class, () -> {
-            CategoryBaseWidget widget = ((RecipeViewingScreen) MinecraftClient.getInstance().currentScreen).getWorkingStationsBaseWidget();
+            Panel widget = ((RecipeViewingScreen) MinecraftClient.getInstance().currentScreen).getWorkingStationsBaseWidget();
             if (widget == null)
             if (widget == null)
                 return Collections.emptyList();
                 return Collections.emptyList();
             return Collections.singletonList(widget.getBounds().clone());
             return Collections.singletonList(widget.getBounds().clone());
@@ -310,20 +312,20 @@ public class DefaultPlugin implements REIPluginV0 {
 //                return 10f;
 //                return 10f;
 //            }
 //            }
 //        });
 //        });
-        displayHelper.registerHandler(new DisplayHelper.DisplayBoundsHandler<ScreenWithHandler<?>>() {
+        displayHelper.registerHandler(new DisplayHelper.DisplayBoundsHandler<HandledScreen<?>>() {
             @Override
             @Override
             public Class<?> getBaseSupportedClass() {
             public Class<?> getBaseSupportedClass() {
-                return ScreenWithHandler.class;
+                return HandledScreen.class;
             }
             }
             
             
             @Override
             @Override
-            public Rectangle getLeftBounds(ScreenWithHandler<?> screen) {
-                return new Rectangle(2, 0, ScreenHelper.getLastScreenWithHandlerHooks().rei_getContainerLeft() - 4, MinecraftClient.getInstance().getWindow().getScaledHeight());
+            public Rectangle getLeftBounds(HandledScreen<?> screen) {
+                return new Rectangle(2, 0, ((ContainerScreenHooks) ScreenHelper.getLastHandledScreen()).rei_getContainerLeft() - 4, MinecraftClient.getInstance().getWindow().getScaledHeight());
             }
             }
             
             
             @Override
             @Override
-            public Rectangle getRightBounds(ScreenWithHandler<?> screen) {
-                int startX = ScreenHelper.getLastScreenWithHandlerHooks().rei_getContainerLeft() + ScreenHelper.getLastScreenWithHandlerHooks().rei_getContainerWidth() + 2;
+            public Rectangle getRightBounds(HandledScreen<?> screen) {
+                int startX = ((ContainerScreenHooks) ScreenHelper.getLastHandledScreen()).rei_getContainerLeft() + ((ContainerScreenHooks) ScreenHelper.getLastHandledScreen()).rei_getContainerWidth() + 2;
                 return new Rectangle(startX, 0, MinecraftClient.getInstance().getWindow().getScaledWidth() - startX - 2, MinecraftClient.getInstance().getWindow().getScaledHeight());
                 return new Rectangle(startX, 0, MinecraftClient.getInstance().getWindow().getScaledWidth() - startX - 2, MinecraftClient.getInstance().getWindow().getScaledHeight());
             }
             }
             
             
@@ -396,7 +398,7 @@ public class DefaultPlugin implements REIPluginV0 {
         recipeHelper.removeAutoCraftButton(COMPOSTING);
         recipeHelper.removeAutoCraftButton(COMPOSTING);
         recipeHelper.removeAutoCraftButton(BEACON);
         recipeHelper.removeAutoCraftButton(BEACON);
         recipeHelper.removeAutoCraftButton(INFO);
         recipeHelper.removeAutoCraftButton(INFO);
-        recipeHelper.registerScreenClickArea(new Rectangle(88, 32, 28, 23), CraftingTableScreen.class, CRAFTING);
+        recipeHelper.registerScreenClickArea(new Rectangle(88, 32, 28, 23), CraftingScreen.class, CRAFTING);
         recipeHelper.registerScreenClickArea(new Rectangle(137, 29, 10, 13), InventoryScreen.class, CRAFTING);
         recipeHelper.registerScreenClickArea(new Rectangle(137, 29, 10, 13), InventoryScreen.class, CRAFTING);
         recipeHelper.registerScreenClickArea(new Rectangle(97, 16, 14, 30), BrewingStandScreen.class, BREWING);
         recipeHelper.registerScreenClickArea(new Rectangle(97, 16, 14, 30), BrewingStandScreen.class, BREWING);
         recipeHelper.registerScreenClickArea(new Rectangle(78, 32, 28, 23), FurnaceScreen.class, SMELTING);
         recipeHelper.registerScreenClickArea(new Rectangle(78, 32, 28, 23), FurnaceScreen.class, SMELTING);

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

@@ -41,12 +41,12 @@ import java.util.function.Supplier;
 public class DefaultPotionEffectExclusionZones implements Supplier<List<Rectangle>> {
 public class DefaultPotionEffectExclusionZones implements Supplier<List<Rectangle>> {
     @Override
     @Override
     public List<Rectangle> get() {
     public List<Rectangle> get() {
-        if (!(ScreenHelper.getLastScreenWithHandler() instanceof AbstractInventoryScreen) || !((AbstractInventoryScreenHooks) ScreenHelper.getLastScreenWithHandler()).rei_doesOffsetGuiForEffects())
+        if (!(ScreenHelper.getLastHandledScreen() instanceof AbstractInventoryScreen) || !((AbstractInventoryScreenHooks) ScreenHelper.getLastHandledScreen()).rei_doesOffsetGuiForEffects())
             return Collections.emptyList();
             return Collections.emptyList();
         Collection<StatusEffectInstance> activePotionEffects = MinecraftClient.getInstance().player.getStatusEffects();
         Collection<StatusEffectInstance> activePotionEffects = MinecraftClient.getInstance().player.getStatusEffects();
         if (activePotionEffects.isEmpty())
         if (activePotionEffects.isEmpty())
             return Collections.emptyList();
             return Collections.emptyList();
-        ContainerScreenHooks hooks = ScreenHelper.getLastScreenWithHandlerHooks();
+        ContainerScreenHooks hooks = ((ContainerScreenHooks) ScreenHelper.getLastHandledScreen());
         List<Rectangle> list = new ArrayList<>();
         List<Rectangle> list = new ArrayList<>();
         int x = hooks.rei_getContainerLeft() - 124;
         int x = hooks.rei_getContainerLeft() - 124;
         int y = hooks.rei_getContainerTop();
         int y = hooks.rei_getContainerTop();

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

@@ -30,7 +30,7 @@ import me.shedaniel.rei.listeners.ContainerScreenHooks;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.screen.recipebook.RecipeBookProvider;
 import net.minecraft.client.gui.screen.recipebook.RecipeBookProvider;
 import net.minecraft.client.recipebook.ClientRecipeBook;
 import net.minecraft.client.recipebook.ClientRecipeBook;
-import net.minecraft.screen.CraftingScreenHandler;
+import net.minecraft.screen.AbstractRecipeScreenHandler;
 
 
 import java.util.Collections;
 import java.util.Collections;
 import java.util.List;
 import java.util.List;
@@ -40,11 +40,11 @@ public class DefaultRecipeBookExclusionZones implements Supplier<List<Rectangle>
     
     
     @Override
     @Override
     public List<Rectangle> get() {
     public List<Rectangle> get() {
-        if (!MinecraftClient.getInstance().player.getRecipeBook().isGuiOpen() || !(MinecraftClient.getInstance().currentScreen instanceof RecipeBookProvider) || !(ScreenHelper.getLastScreenWithHandler().getScreenHandler() instanceof CraftingScreenHandler))
+        if (!MinecraftClient.getInstance().player.getRecipeBook().isGuiOpen() || !(MinecraftClient.getInstance().currentScreen instanceof RecipeBookProvider) || !(ScreenHelper.getLastHandledScreen().getScreenHandler() instanceof AbstractRecipeScreenHandler))
             return Collections.emptyList();
             return Collections.emptyList();
-        ContainerScreenHooks screenHooks = ScreenHelper.getLastScreenWithHandlerHooks();
+        ContainerScreenHooks screenHooks = ((ContainerScreenHooks) ScreenHelper.getLastHandledScreen());
         List<Rectangle> l = Lists.newArrayList(new Rectangle(screenHooks.rei_getContainerLeft() - 4 - 145, screenHooks.rei_getContainerTop(), 4 + 145 + 30, screenHooks.rei_getContainerHeight()));
         List<Rectangle> l = Lists.newArrayList(new Rectangle(screenHooks.rei_getContainerLeft() - 4 - 145, screenHooks.rei_getContainerTop(), 4 + 145 + 30, screenHooks.rei_getContainerHeight()));
-        int size = ClientRecipeBook.getGroups((CraftingScreenHandler<?>) ScreenHelper.getLastScreenWithHandler().getScreenHandler()).size();
+        int size = ClientRecipeBook.getGroups((AbstractRecipeScreenHandler<?>) ScreenHelper.getLastHandledScreen().getScreenHandler()).size();
         if (size > 0)
         if (size > 0)
             l.add(new Rectangle(screenHooks.rei_getContainerLeft() - 4 - 145 - 30, screenHooks.rei_getContainerTop(), 30, size * 27));
             l.add(new Rectangle(screenHooks.rei_getContainerLeft() - 4 - 145 - 30, screenHooks.rei_getContainerTop(), 30, size * 27));
         return l;
         return l;

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

@@ -31,7 +31,7 @@ import net.minecraft.util.Identifier;
 public class DefaultServerContainerPlugin implements Runnable {
 public class DefaultServerContainerPlugin implements Runnable {
     @Override
     @Override
     public void run() {
     public void run() {
-        ContainerInfoHandler.registerScreenWithHandlerInfo(new Identifier("minecraft", "plugins/crafting"), CraftingContainerInfoWrapper.create(CraftingTableScreenHandler.class));
+        ContainerInfoHandler.registerScreenWithHandlerInfo(new Identifier("minecraft", "plugins/crafting"), CraftingContainerInfoWrapper.create(CraftingScreenHandler.class));
         ContainerInfoHandler.registerScreenWithHandlerInfo(new Identifier("minecraft", "plugins/crafting"), CraftingContainerInfoWrapper.create(PlayerScreenHandler.class));
         ContainerInfoHandler.registerScreenWithHandlerInfo(new Identifier("minecraft", "plugins/crafting"), CraftingContainerInfoWrapper.create(PlayerScreenHandler.class));
         ContainerInfoHandler.registerScreenWithHandlerInfo(new Identifier("minecraft", "plugins/smelting"), CraftingContainerInfoWrapper.create(FurnaceScreenHandler.class));
         ContainerInfoHandler.registerScreenWithHandlerInfo(new Identifier("minecraft", "plugins/smelting"), CraftingContainerInfoWrapper.create(FurnaceScreenHandler.class));
         ContainerInfoHandler.registerScreenWithHandlerInfo(new Identifier("minecraft", "plugins/smoking"), CraftingContainerInfoWrapper.create(SmokerScreenHandler.class));
         ContainerInfoHandler.registerScreenWithHandlerInfo(new Identifier("minecraft", "plugins/smoking"), CraftingContainerInfoWrapper.create(SmokerScreenHandler.class));

+ 2 - 2
src/main/java/me/shedaniel/rei/plugin/autocrafting/DefaultCategoryHandler.java

@@ -36,7 +36,7 @@ import me.shedaniel.rei.server.ContainerInfoHandler;
 import net.fabricmc.fabric.api.network.ClientSidePacketRegistry;
 import net.fabricmc.fabric.api.network.ClientSidePacketRegistry;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.screen.Screen;
 import net.minecraft.client.gui.screen.Screen;
-import net.minecraft.client.gui.screen.ingame.ScreenWithHandler;
+import net.minecraft.client.gui.screen.ingame.HandledScreen;
 import net.minecraft.client.gui.screen.recipebook.RecipeBookProvider;
 import net.minecraft.client.gui.screen.recipebook.RecipeBookProvider;
 import net.minecraft.client.resource.language.I18n;
 import net.minecraft.client.resource.language.I18n;
 import net.minecraft.item.ItemStack;
 import net.minecraft.item.ItemStack;
@@ -57,7 +57,7 @@ public class DefaultCategoryHandler implements AutoTransferHandler {
         if (!(context.getRecipe() instanceof TransferRecipeDisplay))
         if (!(context.getRecipe() instanceof TransferRecipeDisplay))
             return Result.createNotApplicable();
             return Result.createNotApplicable();
         TransferRecipeDisplay recipe = (TransferRecipeDisplay) context.getRecipe();
         TransferRecipeDisplay recipe = (TransferRecipeDisplay) context.getRecipe();
-        ScreenWithHandler<?> screenWithHandler = context.getScreenWithHandler();
+        HandledScreen<?> screenWithHandler = context.getHandledScreen();
         ScreenHandler screenHandler = context.getScreenHandler();
         ScreenHandler screenHandler = context.getScreenHandler();
         ContainerInfo<ScreenHandler> containerInfo = (ContainerInfo<ScreenHandler>) ContainerInfoHandler.getContainerInfo(recipe.getRecipeCategory(), screenHandler.getClass());
         ContainerInfo<ScreenHandler> containerInfo = (ContainerInfo<ScreenHandler>) ContainerInfoHandler.getContainerInfo(recipe.getRecipeCategory(), screenHandler.getClass());
         if (containerInfo == null)
         if (containerInfo == null)

+ 10 - 10
src/main/java/me/shedaniel/rei/plugin/autocrafting/DefaultRecipeBookHandler.java

@@ -34,8 +34,8 @@ import net.minecraft.client.gui.screen.Screen;
 import net.minecraft.client.gui.screen.recipebook.RecipeBookProvider;
 import net.minecraft.client.gui.screen.recipebook.RecipeBookProvider;
 import net.minecraft.client.resource.language.I18n;
 import net.minecraft.client.resource.language.I18n;
 import net.minecraft.recipe.Recipe;
 import net.minecraft.recipe.Recipe;
+import net.minecraft.screen.AbstractRecipeScreenHandler;
 import net.minecraft.screen.CraftingScreenHandler;
 import net.minecraft.screen.CraftingScreenHandler;
-import net.minecraft.screen.CraftingTableScreenHandler;
 import net.minecraft.screen.PlayerScreenHandler;
 import net.minecraft.screen.PlayerScreenHandler;
 
 
 public class DefaultRecipeBookHandler implements AutoTransferHandler {
 public class DefaultRecipeBookHandler implements AutoTransferHandler {
@@ -44,14 +44,14 @@ public class DefaultRecipeBookHandler implements AutoTransferHandler {
         if (context.getRecipe() instanceof TransferRecipeDisplay && DefaultCategoryHandler.canUseMovePackets())
         if (context.getRecipe() instanceof TransferRecipeDisplay && DefaultCategoryHandler.canUseMovePackets())
             return Result.createNotApplicable();
             return Result.createNotApplicable();
         RecipeDisplay display = context.getRecipe();
         RecipeDisplay display = context.getRecipe();
-        if (!(context.getScreenHandler() instanceof CraftingScreenHandler))
+        if (!(context.getScreenHandler() instanceof AbstractRecipeScreenHandler))
             return Result.createNotApplicable();
             return Result.createNotApplicable();
-        CraftingScreenHandler<?> container = (CraftingScreenHandler<?>) context.getScreenHandler();
+        AbstractRecipeScreenHandler<?> container = (AbstractRecipeScreenHandler<?>) context.getScreenHandler();
         if (display instanceof DefaultCraftingDisplay) {
         if (display instanceof DefaultCraftingDisplay) {
             DefaultCraftingDisplay craftingDisplay = (DefaultCraftingDisplay) display;
             DefaultCraftingDisplay craftingDisplay = (DefaultCraftingDisplay) display;
             if (craftingDisplay.getOptionalRecipe().isPresent()) {
             if (craftingDisplay.getOptionalRecipe().isPresent()) {
                 int h = -1, w = -1;
                 int h = -1, w = -1;
-                if (container instanceof CraftingTableScreenHandler) {
+                if (container instanceof CraftingScreenHandler) {
                     h = 3;
                     h = 3;
                     w = 3;
                     w = 3;
                 } else if (container instanceof PlayerScreenHandler) {
                 } else if (container instanceof PlayerScreenHandler) {
@@ -67,9 +67,9 @@ public class DefaultRecipeBookHandler implements AutoTransferHandler {
                     return Result.createFailed(I18n.translate("error.rei.recipe.not.unlocked"));
                     return Result.createFailed(I18n.translate("error.rei.recipe.not.unlocked"));
                 if (!context.isActuallyCrafting())
                 if (!context.isActuallyCrafting())
                     return Result.createSuccessful();
                     return Result.createSuccessful();
-                context.getMinecraft().openScreen(context.getScreenWithHandler());
-                if (context.getScreenWithHandler() instanceof RecipeBookProvider)
-                    ((RecipeBookGuiHooks) ((RecipeBookProvider) context.getScreenWithHandler()).getRecipeBookWidget()).rei_getGhostSlots().reset();
+                context.getMinecraft().openScreen(context.getHandledScreen());
+                if (context.getHandledScreen() instanceof RecipeBookProvider)
+                    ((RecipeBookGuiHooks) ((RecipeBookProvider) context.getHandledScreen()).getRecipeBookWidget()).rei_getGhostSlots().reset();
                 context.getMinecraft().interactionManager.clickRecipe(container.syncId, recipe, Screen.hasShiftDown());
                 context.getMinecraft().interactionManager.clickRecipe(container.syncId, recipe, Screen.hasShiftDown());
                 ScreenHelper.getLastOverlay().init();
                 ScreenHelper.getLastOverlay().init();
             }
             }
@@ -81,9 +81,9 @@ public class DefaultRecipeBookHandler implements AutoTransferHandler {
                     return Result.createFailed(I18n.translate("error.rei.recipe.not.unlocked"));
                     return Result.createFailed(I18n.translate("error.rei.recipe.not.unlocked"));
                 if (!context.isActuallyCrafting())
                 if (!context.isActuallyCrafting())
                     return Result.createSuccessful();
                     return Result.createSuccessful();
-                context.getMinecraft().openScreen(context.getScreenWithHandler());
-                if (context.getScreenWithHandler() instanceof RecipeBookProvider)
-                    ((RecipeBookGuiHooks) ((RecipeBookProvider) context.getScreenWithHandler()).getRecipeBookWidget()).rei_getGhostSlots().reset();
+                context.getMinecraft().openScreen(context.getHandledScreen());
+                if (context.getHandledScreen() instanceof RecipeBookProvider)
+                    ((RecipeBookGuiHooks) ((RecipeBookProvider) context.getHandledScreen()).getRecipeBookWidget()).rei_getGhostSlots().reset();
                 context.getMinecraft().interactionManager.clickRecipe(container.syncId, recipe, Screen.hasShiftDown());
                 context.getMinecraft().interactionManager.clickRecipe(container.syncId, recipe, Screen.hasShiftDown());
                 ScreenHelper.getLastOverlay().init();
                 ScreenHelper.getLastOverlay().init();
             }
             }

+ 5 - 13
src/main/java/me/shedaniel/rei/plugin/beacon/DefaultBeaconBaseCategory.java

@@ -33,10 +33,9 @@ import me.shedaniel.math.Rectangle;
 import me.shedaniel.math.impl.PointHelper;
 import me.shedaniel.math.impl.PointHelper;
 import me.shedaniel.rei.api.EntryStack;
 import me.shedaniel.rei.api.EntryStack;
 import me.shedaniel.rei.api.RecipeCategory;
 import me.shedaniel.rei.api.RecipeCategory;
+import me.shedaniel.rei.api.widgets.Slot;
 import me.shedaniel.rei.api.widgets.Widgets;
 import me.shedaniel.rei.api.widgets.Widgets;
 import me.shedaniel.rei.gui.entries.RecipeEntry;
 import me.shedaniel.rei.gui.entries.RecipeEntry;
-import me.shedaniel.rei.gui.widget.EntryWidget;
-import me.shedaniel.rei.gui.widget.QueuedTooltip;
 import me.shedaniel.rei.gui.widget.Widget;
 import me.shedaniel.rei.gui.widget.Widget;
 import me.shedaniel.rei.gui.widget.WidgetWithBounds;
 import me.shedaniel.rei.gui.widget.WidgetWithBounds;
 import me.shedaniel.rei.plugin.DefaultPlugin;
 import me.shedaniel.rei.plugin.DefaultPlugin;
@@ -50,7 +49,6 @@ import net.minecraft.client.render.VertexFormats;
 import net.minecraft.client.resource.language.I18n;
 import net.minecraft.client.resource.language.I18n;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.math.MathHelper;
 import net.minecraft.util.math.MathHelper;
-import org.jetbrains.annotations.Nullable;
 
 
 import java.util.List;
 import java.util.List;
 
 
@@ -79,12 +77,6 @@ public class DefaultBeaconBaseCategory implements RecipeCategory<DefaultBeaconBa
                 return 10 + MinecraftClient.getInstance().textRenderer.fontHeight;
                 return 10 + MinecraftClient.getInstance().textRenderer.fontHeight;
             }
             }
             
             
-            @Nullable
-            @Override
-            public QueuedTooltip getTooltip(int mouseX, int mouseY) {
-                return null;
-            }
-            
             @Override
             @Override
             public void render(me.shedaniel.math.api.Rectangle rectangle, int mouseX, int mouseY, float delta) {
             public void render(me.shedaniel.math.api.Rectangle rectangle, int mouseX, int mouseY, float delta) {
                 MinecraftClient.getInstance().textRenderer.draw(name, rectangle.x + 5, rectangle.y + 6, -1);
                 MinecraftClient.getInstance().textRenderer.draw(name, rectangle.x + 5, rectangle.y + 6, -1);
@@ -98,7 +90,7 @@ public class DefaultBeaconBaseCategory implements RecipeCategory<DefaultBeaconBa
         widgets.add(Widgets.createSlot(new Point(bounds.getCenterX() - 8, bounds.y + 3)).entry(getLogo()));
         widgets.add(Widgets.createSlot(new Point(bounds.getCenterX() - 8, bounds.y + 3)).entry(getLogo()));
         Rectangle rectangle = new Rectangle(bounds.getCenterX() - (bounds.width / 2) - 1, bounds.y + 23, bounds.width + 2, bounds.height - 28);
         Rectangle rectangle = new Rectangle(bounds.getCenterX() - (bounds.width / 2) - 1, bounds.y + 23, bounds.width + 2, bounds.height - 28);
         widgets.add(Widgets.createSlotBase(rectangle));
         widgets.add(Widgets.createSlotBase(rectangle));
-        widgets.add(new ScrollableSlotsWidget(rectangle, CollectionUtils.map(display.getEntries(), t -> EntryWidget.create(0, 0).noBackground().entry(t))));
+        widgets.add(new ScrollableSlotsWidget(rectangle, CollectionUtils.map(display.getEntries(), t -> Widgets.createSlot(new Point(0, 0)).disableBackground().entry(t))));
         return widgets;
         return widgets;
     }
     }
     
     
@@ -114,13 +106,13 @@ public class DefaultBeaconBaseCategory implements RecipeCategory<DefaultBeaconBa
     
     
     private static class ScrollableSlotsWidget extends WidgetWithBounds {
     private static class ScrollableSlotsWidget extends WidgetWithBounds {
         private me.shedaniel.math.api.Rectangle bounds;
         private me.shedaniel.math.api.Rectangle bounds;
-        private List<EntryWidget> widgets;
+        private List<Slot> widgets;
         private double target;
         private double target;
         private double scroll;
         private double scroll;
         private long start;
         private long start;
         private long duration;
         private long duration;
         
         
-        public ScrollableSlotsWidget(Rectangle bounds, List<EntryWidget> widgets) {
+        public ScrollableSlotsWidget(Rectangle bounds, List<Slot> widgets) {
             this.bounds = new me.shedaniel.math.api.Rectangle(bounds);
             this.bounds = new me.shedaniel.math.api.Rectangle(bounds);
             this.widgets = Lists.newArrayList(widgets);
             this.widgets = Lists.newArrayList(widgets);
         }
         }
@@ -183,7 +175,7 @@ public class DefaultBeaconBaseCategory implements RecipeCategory<DefaultBeaconBa
                     int index = y * 8 + x;
                     int index = y * 8 + x;
                     if (widgets.size() <= index)
                     if (widgets.size() <= index)
                         break;
                         break;
-                    EntryWidget widget = widgets.get(index);
+                    Slot widget = widgets.get(index);
                     widget.getBounds().setLocation(bounds.x + 1 + x * 18, (int) (bounds.y + 1 + y * 18 - scroll));
                     widget.getBounds().setLocation(bounds.x + 1 + x * 18, (int) (bounds.y + 1 + y * 18 - scroll));
                     widget.render(mouseX, mouseY, delta);
                     widget.render(mouseX, mouseY, delta);
                 }
                 }

+ 0 - 8
src/main/java/me/shedaniel/rei/plugin/composting/DefaultCompostingCategory.java

@@ -31,7 +31,6 @@ import me.shedaniel.rei.api.REIHelper;
 import me.shedaniel.rei.api.RecipeCategory;
 import me.shedaniel.rei.api.RecipeCategory;
 import me.shedaniel.rei.api.widgets.Widgets;
 import me.shedaniel.rei.api.widgets.Widgets;
 import me.shedaniel.rei.gui.entries.RecipeEntry;
 import me.shedaniel.rei.gui.entries.RecipeEntry;
-import me.shedaniel.rei.gui.widget.QueuedTooltip;
 import me.shedaniel.rei.gui.widget.Widget;
 import me.shedaniel.rei.gui.widget.Widget;
 import me.shedaniel.rei.plugin.DefaultPlugin;
 import me.shedaniel.rei.plugin.DefaultPlugin;
 import net.minecraft.block.Blocks;
 import net.minecraft.block.Blocks;
@@ -40,7 +39,6 @@ import net.minecraft.client.resource.language.I18n;
 import net.minecraft.item.ItemConvertible;
 import net.minecraft.item.ItemConvertible;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.math.MathHelper;
 import net.minecraft.util.math.MathHelper;
-import org.jetbrains.annotations.Nullable;
 
 
 import java.util.Collections;
 import java.util.Collections;
 import java.util.LinkedList;
 import java.util.LinkedList;
@@ -72,12 +70,6 @@ public class DefaultCompostingCategory implements RecipeCategory<DefaultComposti
                 return 10 + MinecraftClient.getInstance().textRenderer.fontHeight;
                 return 10 + MinecraftClient.getInstance().textRenderer.fontHeight;
             }
             }
             
             
-            @Nullable
-            @Override
-            public QueuedTooltip getTooltip(int mouseX, int mouseY) {
-                return null;
-            }
-            
             @Override
             @Override
             public void render(me.shedaniel.math.api.Rectangle rectangle, int mouseX, int mouseY, float delta) {
             public void render(me.shedaniel.math.api.Rectangle rectangle, int mouseX, int mouseY, float delta) {
                 MinecraftClient.getInstance().textRenderer.draw(I18n.translate("text.rei.composting.page", recipe.getPage() + 1), rectangle.x + 5, rectangle.y + 6, -1);
                 MinecraftClient.getInstance().textRenderer.draw(I18n.translate("text.rei.composting.page", recipe.getPage() + 1), rectangle.x + 5, rectangle.y + 6, -1);

+ 4 - 4
src/main/java/me/shedaniel/rei/plugin/containers/CraftingContainerInfoWrapper.java

@@ -26,17 +26,17 @@ package me.shedaniel.rei.plugin.containers;
 import me.shedaniel.rei.server.ContainerInfo;
 import me.shedaniel.rei.server.ContainerInfo;
 import me.shedaniel.rei.server.RecipeFinder;
 import me.shedaniel.rei.server.RecipeFinder;
 import net.minecraft.item.ItemStack;
 import net.minecraft.item.ItemStack;
-import net.minecraft.screen.CraftingScreenHandler;
+import net.minecraft.screen.AbstractRecipeScreenHandler;
 import net.minecraft.screen.ScreenHandler;
 import net.minecraft.screen.ScreenHandler;
 
 
-public class CraftingContainerInfoWrapper<T extends CraftingScreenHandler<?>> implements ContainerInfo<T> {
-    private Class<? extends CraftingScreenHandler<?>> containerClass;
+public class CraftingContainerInfoWrapper<T extends AbstractRecipeScreenHandler<?>> implements ContainerInfo<T> {
+    private Class<? extends AbstractRecipeScreenHandler<?>> containerClass;
     
     
     public CraftingContainerInfoWrapper(Class<T> containerClass) {
     public CraftingContainerInfoWrapper(Class<T> containerClass) {
         this.containerClass = containerClass;
         this.containerClass = containerClass;
     }
     }
     
     
-    public static <R extends CraftingScreenHandler<?>> ContainerInfo<R> create(Class<R> containerClass) {
+    public static <R extends AbstractRecipeScreenHandler<?>> ContainerInfo<R> create(Class<R> containerClass) {
         return new CraftingContainerInfoWrapper<>(containerClass);
         return new CraftingContainerInfoWrapper<>(containerClass);
     }
     }
     
     

+ 2 - 2
src/main/java/me/shedaniel/rei/plugin/crafting/DefaultCraftingCategory.java

@@ -95,12 +95,12 @@ public class DefaultCraftingCategory implements TransferRecipeCategory<DefaultCr
     
     
     @Override
     @Override
     public void renderRedSlots(List<Widget> widgets, me.shedaniel.math.api.Rectangle bounds, DefaultCraftingDisplay display, IntList redSlots) {
     public void renderRedSlots(List<Widget> widgets, me.shedaniel.math.api.Rectangle bounds, DefaultCraftingDisplay display, IntList redSlots) {
-        ContainerInfo<ScreenHandler> info = (ContainerInfo<ScreenHandler>) ContainerInfoHandler.getContainerInfo(getIdentifier(), ScreenHelper.getLastScreenWithHandler().getScreenHandler().getClass());
+        ContainerInfo<ScreenHandler> info = (ContainerInfo<ScreenHandler>) ContainerInfoHandler.getContainerInfo(getIdentifier(), ScreenHelper.getLastHandledScreen().getScreenHandler().getClass());
         if (info == null)
         if (info == null)
             return;
             return;
         RenderSystem.translatef(0, 0, 400);
         RenderSystem.translatef(0, 0, 400);
         Point startPoint = new Point(bounds.getCenterX() - 58, bounds.getCenterY() - 27);
         Point startPoint = new Point(bounds.getCenterX() - 58, bounds.getCenterY() - 27);
-        int width = info.getCraftingWidth(ScreenHelper.getLastScreenWithHandler().getScreenHandler());
+        int width = info.getCraftingWidth(ScreenHelper.getLastHandledScreen().getScreenHandler());
         for (Integer slot : redSlots) {
         for (Integer slot : redSlots) {
             int i = slot;
             int i = slot;
             int x = i % width;
             int x = i % width;

+ 4 - 4
src/main/java/me/shedaniel/rei/plugin/fuel/DefaultFuelCategory.java

@@ -28,9 +28,9 @@ import me.shedaniel.math.Point;
 import me.shedaniel.rei.api.EntryStack;
 import me.shedaniel.rei.api.EntryStack;
 import me.shedaniel.rei.api.RecipeCategory;
 import me.shedaniel.rei.api.RecipeCategory;
 import me.shedaniel.rei.api.widgets.Slot;
 import me.shedaniel.rei.api.widgets.Slot;
+import me.shedaniel.rei.api.widgets.Tooltip;
 import me.shedaniel.rei.api.widgets.Widgets;
 import me.shedaniel.rei.api.widgets.Widgets;
 import me.shedaniel.rei.gui.entries.RecipeEntry;
 import me.shedaniel.rei.gui.entries.RecipeEntry;
-import me.shedaniel.rei.gui.widget.QueuedTooltip;
 import me.shedaniel.rei.gui.widget.Widget;
 import me.shedaniel.rei.gui.widget.Widget;
 import me.shedaniel.rei.plugin.DefaultPlugin;
 import me.shedaniel.rei.plugin.DefaultPlugin;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.MinecraftClient;
@@ -91,9 +91,9 @@ public class DefaultFuelCategory implements RecipeCategory<DefaultFuelDisplay> {
             
             
             @Nullable
             @Nullable
             @Override
             @Override
-            public QueuedTooltip getTooltip(int mouseX, int mouseY) {
-                if (slot.containsMouse(mouseX, mouseY))
-                    return slot.getCurrentTooltip(mouseX, mouseY);
+            public Tooltip getTooltip(Point point) {
+                if (slot.containsMouse(point))
+                    return slot.getCurrentTooltip(point);
                 return null;
                 return null;
             }
             }
             
             

+ 0 - 8
src/main/java/me/shedaniel/rei/plugin/information/DefaultInformationCategory.java

@@ -36,7 +36,6 @@ import me.shedaniel.rei.api.REIHelper;
 import me.shedaniel.rei.api.RecipeCategory;
 import me.shedaniel.rei.api.RecipeCategory;
 import me.shedaniel.rei.api.widgets.Widgets;
 import me.shedaniel.rei.api.widgets.Widgets;
 import me.shedaniel.rei.gui.entries.RecipeEntry;
 import me.shedaniel.rei.gui.entries.RecipeEntry;
-import me.shedaniel.rei.gui.widget.QueuedTooltip;
 import me.shedaniel.rei.gui.widget.Widget;
 import me.shedaniel.rei.gui.widget.Widget;
 import me.shedaniel.rei.gui.widget.WidgetWithBounds;
 import me.shedaniel.rei.gui.widget.WidgetWithBounds;
 import me.shedaniel.rei.impl.RenderingEntry;
 import me.shedaniel.rei.impl.RenderingEntry;
@@ -53,7 +52,6 @@ import net.minecraft.client.util.math.Matrix4f;
 import net.minecraft.text.Text;
 import net.minecraft.text.Text;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.math.MathHelper;
 import net.minecraft.util.math.MathHelper;
-import org.jetbrains.annotations.Nullable;
 
 
 import java.util.Collections;
 import java.util.Collections;
 import java.util.List;
 import java.util.List;
@@ -90,12 +88,6 @@ public class DefaultInformationCategory implements RecipeCategory<DefaultInforma
                 return 10 + MinecraftClient.getInstance().textRenderer.fontHeight;
                 return 10 + MinecraftClient.getInstance().textRenderer.fontHeight;
             }
             }
             
             
-            @Nullable
-            @Override
-            public QueuedTooltip getTooltip(int mouseX, int mouseY) {
-                return null;
-            }
-            
             @Override
             @Override
             public void render(me.shedaniel.math.api.Rectangle rectangle, int mouseX, int mouseY, float delta) {
             public void render(me.shedaniel.math.api.Rectangle rectangle, int mouseX, int mouseY, float delta) {
                 MinecraftClient.getInstance().textRenderer.draw(name.asFormattedString(), rectangle.x + 5, rectangle.y + 6, -1);
                 MinecraftClient.getInstance().textRenderer.draw(name.asFormattedString(), rectangle.x + 5, rectangle.y + 6, -1);