Unknown 6 жил өмнө
parent
commit
0b11e05ed5

+ 1 - 1
gradle.properties

@@ -1,4 +1,4 @@
-mod_version=2.8.2+build.104
+mod_version=2.9-beta+build.105
 minecraft_version=1.14
 minecraft_version=1.14
 yarn_version=1.14+build.5
 yarn_version=1.14+build.5
 fabricloader_version=0.4.6+build.141
 fabricloader_version=0.4.6+build.141

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

@@ -5,6 +5,7 @@ import net.fabricmc.api.ClientModInitializer;
 import net.fabricmc.fabric.api.client.keybinding.FabricKeyBinding;
 import net.fabricmc.fabric.api.client.keybinding.FabricKeyBinding;
 import net.minecraft.item.Item;
 import net.minecraft.item.Item;
 import net.minecraft.item.ItemStack;
 import net.minecraft.item.ItemStack;
+import net.minecraft.util.Identifier;
 
 
 import java.util.List;
 import java.util.List;
 
 
@@ -33,6 +34,10 @@ public interface ClientHelper extends ClientModInitializer {
     
     
     String getFormattedModFromItem(Item item);
     String getFormattedModFromItem(Item item);
     
     
+    String getFormattedModFromIdentifier(Identifier identifier);
+    
+    String getModFromIdentifier(Identifier identifier);
+    
     FabricKeyBinding getRecipeKeyBinding();
     FabricKeyBinding getRecipeKeyBinding();
     
     
     FabricKeyBinding getUsageKeyBinding();
     FabricKeyBinding getUsageKeyBinding();

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

@@ -20,6 +20,10 @@ public interface RecipeCategory<T extends RecipeDisplay> {
     
     
     ItemStack getCategoryIcon();
     ItemStack getCategoryIcon();
     
     
+    default Renderable getIcon() {
+        return Renderable.fromItemStackSupplier(this::getCategoryIcon);
+    }
+    
     String getCategoryName();
     String getCategoryName();
     
     
     default List<Widget> setupDisplay(Supplier<T> recipeDisplaySupplier, Rectangle bounds) {
     default List<Widget> setupDisplay(Supplier<T> recipeDisplaySupplier, Rectangle bounds) {

+ 29 - 0
src/main/java/me/shedaniel/rei/api/Renderable.java

@@ -0,0 +1,29 @@
+package me.shedaniel.rei.api;
+
+import me.shedaniel.rei.gui.renderables.ItemStackRenderable;
+import net.minecraft.item.ItemStack;
+
+import java.util.function.Supplier;
+
+public interface Renderable {
+    
+    static ItemStackRenderable fromItemStackSupplier(Supplier<ItemStack> supplier) {
+        return new ItemStackRenderable() {
+            @Override
+            protected ItemStack getItemStack() {
+                return supplier.get();
+            }
+        };
+    }
+    
+    static ItemStackRenderable fromItemStack(ItemStack stack) {
+        return new ItemStackRenderable() {
+            @Override
+            protected ItemStack getItemStack() {
+                return stack;
+            }
+        };
+    }
+    
+    void render(int x, int y, double mouseX, double mouseY, float delta);
+}

+ 21 - 3
src/main/java/me/shedaniel/rei/client/ClientHelperImpl.java

@@ -10,6 +10,7 @@ import me.shedaniel.rei.api.RecipeCategory;
 import me.shedaniel.rei.api.RecipeDisplay;
 import me.shedaniel.rei.api.RecipeDisplay;
 import me.shedaniel.rei.api.RecipeHelper;
 import me.shedaniel.rei.api.RecipeHelper;
 import me.shedaniel.rei.gui.RecipeViewingScreen;
 import me.shedaniel.rei.gui.RecipeViewingScreen;
+import me.shedaniel.rei.gui.VillagerRecipeViewingScreen;
 import net.fabricmc.fabric.api.client.keybinding.FabricKeyBinding;
 import net.fabricmc.fabric.api.client.keybinding.FabricKeyBinding;
 import net.fabricmc.fabric.api.network.ClientSidePacketRegistry;
 import net.fabricmc.fabric.api.network.ClientSidePacketRegistry;
 import net.fabricmc.fabric.impl.client.keybinding.KeyBindingRegistryImpl;
 import net.fabricmc.fabric.impl.client.keybinding.KeyBindingRegistryImpl;
@@ -53,6 +54,14 @@ public class ClientHelperImpl implements ClientHelper {
         return "§9§o" + mod;
         return "§9§o" + mod;
     }
     }
     
     
+    @Override
+    public String getFormattedModFromIdentifier(Identifier identifier) {
+        String mod = getModFromIdentifier(identifier);
+        if (mod.equalsIgnoreCase(""))
+            return "";
+        return "§9§o" + mod;
+    }
+    
     @Override
     @Override
     public FabricKeyBinding getRecipeKeyBinding() {
     public FabricKeyBinding getRecipeKeyBinding() {
         return recipe;
         return recipe;
@@ -78,12 +87,14 @@ public class ClientHelperImpl implements ClientHelper {
         return nextPage;
         return nextPage;
     }
     }
     
     
+    @Override
     public String getModFromItem(Item item) {
     public String getModFromItem(Item item) {
         if (item.equals(Items.AIR))
         if (item.equals(Items.AIR))
             return "";
             return "";
         return getModFromIdentifier(Registry.ITEM.getId(item));
         return getModFromIdentifier(Registry.ITEM.getId(item));
     }
     }
     
     
+    @Override
     public String getModFromIdentifier(Identifier identifier) {
     public String getModFromIdentifier(Identifier identifier) {
         if (identifier == null)
         if (identifier == null)
             return "";
             return "";
@@ -147,7 +158,7 @@ public class ClientHelperImpl implements ClientHelper {
     public boolean executeRecipeKeyBind(ItemStack stack) {
     public boolean executeRecipeKeyBind(ItemStack stack) {
         Map<RecipeCategory, List<RecipeDisplay>> map = RecipeHelper.getInstance().getRecipesFor(stack);
         Map<RecipeCategory, List<RecipeDisplay>> map = RecipeHelper.getInstance().getRecipesFor(stack);
         if (map.keySet().size() > 0)
         if (map.keySet().size() > 0)
-            MinecraftClient.getInstance().openScreen(new RecipeViewingScreen(MinecraftClient.getInstance().window, map));
+            openRecipeViewingScreen(map);
         return map.keySet().size() > 0;
         return map.keySet().size() > 0;
     }
     }
     
     
@@ -155,7 +166,7 @@ public class ClientHelperImpl implements ClientHelper {
     public boolean executeUsageKeyBind(ItemStack stack) {
     public boolean executeUsageKeyBind(ItemStack stack) {
         Map<RecipeCategory, List<RecipeDisplay>> map = RecipeHelper.getInstance().getUsagesFor(stack);
         Map<RecipeCategory, List<RecipeDisplay>> map = RecipeHelper.getInstance().getUsagesFor(stack);
         if (map.keySet().size() > 0)
         if (map.keySet().size() > 0)
-            MinecraftClient.getInstance().openScreen(new RecipeViewingScreen(MinecraftClient.getInstance().window, map));
+            openRecipeViewingScreen(map);
         return map.keySet().size() > 0;
         return map.keySet().size() > 0;
     }
     }
     
     
@@ -174,10 +185,17 @@ public class ClientHelperImpl implements ClientHelper {
     public boolean executeViewAllRecipesKeyBind() {
     public boolean executeViewAllRecipesKeyBind() {
         Map<RecipeCategory, List<RecipeDisplay>> map = RecipeHelper.getInstance().getAllRecipes();
         Map<RecipeCategory, List<RecipeDisplay>> map = RecipeHelper.getInstance().getAllRecipes();
         if (map.keySet().size() > 0)
         if (map.keySet().size() > 0)
-            MinecraftClient.getInstance().openScreen(new RecipeViewingScreen(MinecraftClient.getInstance().window, map));
+            openRecipeViewingScreen(map);
         return map.keySet().size() > 0;
         return map.keySet().size() > 0;
     }
     }
     
     
+    public void openRecipeViewingScreen(Map<RecipeCategory, List<RecipeDisplay>> map) {
+        if (RoughlyEnoughItemsCore.getConfigManager().getConfig().screenType == RecipeScreenType.VILLAGER)
+            MinecraftClient.getInstance().openScreen(new VillagerRecipeViewingScreen(map));
+        else
+            MinecraftClient.getInstance().openScreen(new RecipeViewingScreen(map));
+    }
+    
     @Override
     @Override
     public void onInitializeClient() {
     public void onInitializeClient() {
         ClientHelperImpl.instance = (ClientHelperImpl) this;
         ClientHelperImpl.instance = (ClientHelperImpl) this;

+ 2 - 0
src/main/java/me/shedaniel/rei/client/ConfigObject.java

@@ -48,6 +48,8 @@ public class ConfigObject {
     
     
     public boolean lightGrayRecipeBorder = false;
     public boolean lightGrayRecipeBorder = false;
     
     
+    public RecipeScreenType screenType = RecipeScreenType.UNSET;
+    
     @Comment(
     @Comment(
             "The location of choose page dialog, will automatically be set to your last location so there is no need to change this.")
             "The location of choose page dialog, will automatically be set to your last location so there is no need to change this.")
     public RelativePoint choosePageDialogPoint = new RelativePoint(.5, .5);
     public RelativePoint choosePageDialogPoint = new RelativePoint(.5, .5);

+ 16 - 0
src/main/java/me/shedaniel/rei/client/RecipeScreenType.java

@@ -0,0 +1,16 @@
+package me.shedaniel.rei.client;
+
+import net.minecraft.client.resource.language.I18n;
+
+import java.util.Locale;
+
+public enum RecipeScreenType {
+    UNSET,
+    ORIGINAL,
+    VILLAGER;
+    
+    @Override
+    public String toString() {
+        return I18n.translate("text.rei.config.recipe_screen_type." + name().toLowerCase(Locale.ROOT));
+    }
+}

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

@@ -43,16 +43,15 @@ public class RecipeViewingScreen extends Screen {
     public int largestWidth, largestHeight;
     public int largestWidth, largestHeight;
     public boolean choosePageActivated;
     public boolean choosePageActivated;
     public RecipeChoosePageWidget recipeChoosePageWidget;
     public RecipeChoosePageWidget recipeChoosePageWidget;
-    private Window window;
     private Rectangle bounds;
     private Rectangle bounds;
     private RecipeCategory selectedCategory;
     private RecipeCategory selectedCategory;
     private ButtonWidget recipeBack, recipeNext, categoryBack, categoryNext;
     private ButtonWidget recipeBack, recipeNext, categoryBack, categoryNext;
     
     
-    public RecipeViewingScreen(Window window, Map<RecipeCategory, List<RecipeDisplay>> categoriesMap) {
+    public RecipeViewingScreen(Map<RecipeCategory, List<RecipeDisplay>> categoriesMap) {
         super(new StringTextComponent(""));
         super(new StringTextComponent(""));
         this.categoryPages = 0;
         this.categoryPages = 0;
-        this.window = window;
         this.widgets = Lists.newArrayList();
         this.widgets = Lists.newArrayList();
+        Window window = MinecraftClient.getInstance().window;
         this.bounds = new Rectangle(window.getScaledWidth() / 2 - guiWidth / 2, window.getScaledHeight() / 2 - guiHeight / 2, 176, 186);
         this.bounds = new Rectangle(window.getScaledWidth() / 2 - guiWidth / 2, window.getScaledHeight() / 2 - guiHeight / 2, 176, 186);
         this.categoriesMap = categoriesMap;
         this.categoriesMap = categoriesMap;
         this.categories = Lists.newArrayList();
         this.categories = Lists.newArrayList();
@@ -119,11 +118,11 @@ public class RecipeViewingScreen extends Screen {
         this.children.clear();
         this.children.clear();
         this.tabs.clear();
         this.tabs.clear();
         this.widgets.clear();
         this.widgets.clear();
-        this.largestWidth = window.getScaledWidth() - 100;
-        this.largestHeight = window.getScaledHeight() - 40;
+        this.largestWidth = width - 100;
+        this.largestHeight = height - 40;
         this.guiWidth = MathHelper.clamp(getCurrentDisplayed().stream().map(display -> selectedCategory.getDisplayWidth(display)).max(Integer::compareTo).orElse(150) + 30, 0, largestWidth);
         this.guiWidth = MathHelper.clamp(getCurrentDisplayed().stream().map(display -> selectedCategory.getDisplayWidth(display)).max(Integer::compareTo).orElse(150) + 30, 0, largestWidth);
         this.guiHeight = MathHelper.floor(MathHelper.clamp((selectedCategory.getDisplayHeight() + 7d) * (getRecipesPerPage() + 1d) + 40d, 186d, (double) largestHeight));
         this.guiHeight = MathHelper.floor(MathHelper.clamp((selectedCategory.getDisplayHeight() + 7d) * (getRecipesPerPage() + 1d) + 40d, 186d, (double) largestHeight));
-        this.bounds = new Rectangle(window.getScaledWidth() / 2 - guiWidth / 2, window.getScaledHeight() / 2 - guiHeight / 2, guiWidth, guiHeight);
+        this.bounds = new Rectangle(width / 2 - guiWidth / 2, height / 2 - guiHeight / 2, guiWidth, guiHeight);
         this.page = MathHelper.clamp(page, 0, getTotalPages(selectedCategory) - 1);
         this.page = MathHelper.clamp(page, 0, getTotalPages(selectedCategory) - 1);
         
         
         widgets.add(categoryBack = new ButtonWidget((int) bounds.getX() + 5, (int) bounds.getY() + 5, 12, 12, new TranslatableTextComponent("text.rei.left_arrow")) {
         widgets.add(categoryBack = new ButtonWidget((int) bounds.getX() + 5, (int) bounds.getY() + 5, 12, 12, new TranslatableTextComponent("text.rei.left_arrow")) {
@@ -250,7 +249,7 @@ public class RecipeViewingScreen extends Screen {
                         return false;
                         return false;
                     }
                     }
                 });
                 });
-                tab.setItem(categories.get(j).getCategoryIcon(), categories.get(j).getCategoryName(), tab.getId() + categoryPages * 6 == categories.indexOf(selectedCategory));
+                tab.setRenderable(categories.get(j), categories.get(j).getIcon(), categories.get(j).getCategoryName(), tab.getId() + categoryPages * 6 == categories.indexOf(selectedCategory));
             }
             }
         }
         }
         Optional<ButtonAreaSupplier> supplier = RecipeHelper.getInstance().getSpeedCraftButtonArea(selectedCategory);
         Optional<ButtonAreaSupplier> supplier = RecipeHelper.getInstance().getSpeedCraftButtonArea(selectedCategory);

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

@@ -0,0 +1,98 @@
+package me.shedaniel.rei.gui;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.mojang.blaze3d.platform.GlStateManager;
+import me.shedaniel.rei.api.RecipeCategory;
+import me.shedaniel.rei.api.RecipeDisplay;
+import me.shedaniel.rei.api.RecipeHelper;
+import me.shedaniel.rei.client.ScreenHelper;
+import me.shedaniel.rei.gui.widget.CategoryBaseWidget;
+import me.shedaniel.rei.gui.widget.RecipeBaseWidget;
+import me.shedaniel.rei.gui.widget.SlotBaseWidget;
+import me.shedaniel.rei.gui.widget.Widget;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.gui.Screen;
+import net.minecraft.client.render.GuiLighting;
+import net.minecraft.text.StringTextComponent;
+import net.minecraft.util.math.MathHelper;
+
+import java.awt.*;
+import java.util.List;
+import java.util.Map;
+
+public class VillagerRecipeViewingScreen extends Screen {
+    
+    private final Map<RecipeCategory, List<RecipeDisplay>> categoryMap;
+    private final List<RecipeCategory> categories;
+    private final List<Widget> widgets;
+    public Rectangle bounds, scrollListBounds;
+    private int selectedCategoryIndex, selectedRecipeIndex;
+    
+    public VillagerRecipeViewingScreen(Map<RecipeCategory, List<RecipeDisplay>> map) {
+        super(new StringTextComponent(""));
+        this.widgets = Lists.newArrayList();
+        this.categoryMap = Maps.newLinkedHashMap();
+        this.selectedCategoryIndex = 0;
+        this.selectedRecipeIndex = 0;
+        this.categories = Lists.newArrayList();
+        RecipeHelper.getInstance().getAllCategories().forEach(category -> {
+            if (map.containsKey(category)) {
+                categories.add(category);
+                categoryMap.put(category, map.get(category));
+            }
+        });
+    }
+    
+    @Override
+    protected void init() {
+        super.init();
+        this.children.clear();
+        this.widgets.clear();
+        int largestWidth = width - 100;
+        int largestHeight = height - 40;
+        RecipeCategory category = categories.get(selectedCategoryIndex);
+        RecipeDisplay display = categoryMap.get(category).get(selectedRecipeIndex);
+        int guiWidth = MathHelper.clamp(category.getDisplayWidth(display) + 30, 0, largestWidth) + 100;
+        int guiHeight = MathHelper.clamp(category.getDisplayHeight() + 40, 166, largestHeight);
+        this.bounds = new Rectangle(width / 2 - guiWidth / 2, height / 2 - guiHeight / 2, guiWidth, guiHeight);
+        this.widgets.add(new CategoryBaseWidget(bounds));
+        this.scrollListBounds = new Rectangle(bounds.x + 4, bounds.y + 17, 97, guiHeight - 17 - 7);
+        this.widgets.add(new SlotBaseWidget(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());
+        this.widgets.addAll(category.setupDisplay(() -> display, recipeBounds));
+        this.children.addAll(widgets);
+        this.children.add(ScreenHelper.getLastOverlay(true, false));
+    }
+    
+    @Override
+    public void render(int mouseX, int mouseY, float delta) {
+        this.fillGradient(0, 0, this.width, this.height, -1072689136, -804253680);
+        this.widgets.forEach(widget -> {
+            GuiLighting.disable();
+            widget.render(mouseX, mouseY, delta);
+        });
+        GuiLighting.disable();
+        ScreenHelper.getLastOverlay().render(mouseX, mouseY, delta);
+        GlStateManager.pushMatrix();
+        GlStateManager.translatef((float) bounds.x, (float) bounds.y, 0.0F);
+        GuiLighting.disable();
+        GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F);
+        String categoryName = categories.get(selectedCategoryIndex).getCategoryName();
+        font.draw(categoryName, 4 + scrollListBounds.width / 2 - font.getStringWidth(categoryName) / 2, 6, 4210752);
+        GlStateManager.popMatrix();
+        GuiLighting.disable();
+        ScreenHelper.getLastOverlay().lateRender(mouseX, mouseY, delta);
+    }
+    
+    @Override
+    public boolean keyPressed(int int_1, int int_2, int int_3) {
+        if ((int_1 == 256 || this.minecraft.options.keyInventory.matchesKey(int_1, int_2)) && this.shouldCloseOnEsc()) {
+            MinecraftClient.getInstance().openScreen(ScreenHelper.getLastContainerScreen());
+            ScreenHelper.getLastOverlay().init();
+            return true;
+        }
+        return super.keyPressed(int_1, int_2, int_3);
+    }
+    
+}

+ 33 - 0
src/main/java/me/shedaniel/rei/gui/renderables/ItemStackRenderable.java

@@ -0,0 +1,33 @@
+package me.shedaniel.rei.gui.renderables;
+
+import com.mojang.blaze3d.platform.GlStateManager;
+import me.shedaniel.rei.api.Renderable;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.gui.DrawableHelper;
+import net.minecraft.client.render.GuiLighting;
+import net.minecraft.client.render.item.ItemRenderer;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.Identifier;
+
+public abstract class ItemStackRenderable extends DrawableHelper implements Renderable {
+    
+    public static final Identifier CHEST_GUI_TEXTURE = new Identifier("roughlyenoughitems", "textures/gui/recipecontainer.png");
+    
+    @Override
+    public void render(int x, int y, double mouseX, double mouseY, float delta) {
+        int l = x - 8, i1 = y - 6;
+        GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F);
+        this.blitOffset = 100;
+        ItemRenderer itemRenderer = MinecraftClient.getInstance().getItemRenderer();
+        itemRenderer.zOffset = 100.0F;
+        GuiLighting.enableForItems();
+        itemRenderer.renderGuiItem(getItemStack(), l, i1);
+        itemRenderer.renderGuiItemOverlay(MinecraftClient.getInstance().textRenderer, getItemStack(), l, i1);
+        GlStateManager.disableLighting();
+        itemRenderer.zOffset = 0.0F;
+        this.blitOffset = 0;
+    }
+    
+    protected abstract ItemStack getItemStack();
+    
+}

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

@@ -12,9 +12,9 @@ import java.util.List;
 public class RecipeBaseWidget extends HighlightableWidget {
 public class RecipeBaseWidget extends HighlightableWidget {
     
     
     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 Color INNER_COLOR = new Color(198, 198, 198);
     
     
     private Rectangle bounds;
     private Rectangle bounds;
+    protected boolean render = true;
     
     
     public RecipeBaseWidget(Rectangle bounds) {
     public RecipeBaseWidget(Rectangle bounds) {
         this.bounds = bounds;
         this.bounds = bounds;
@@ -22,6 +22,14 @@ public class RecipeBaseWidget extends HighlightableWidget {
             throw new IllegalArgumentException("Base too small, at least 8x8!");
             throw new IllegalArgumentException("Base too small, at least 8x8!");
     }
     }
     
     
+    public boolean isRender() {
+        return render;
+    }
+    
+    public void setRender(boolean render) {
+        this.render = render;
+    }
+    
     @Override
     @Override
     public Rectangle getBounds() {
     public Rectangle getBounds() {
         return bounds;
         return bounds;
@@ -38,30 +46,36 @@ public class RecipeBaseWidget extends HighlightableWidget {
     
     
     @Override
     @Override
     public void render(int mouseX, int mouseY, float delta) {
     public void render(int mouseX, int mouseY, float delta) {
-        GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F);
-        GuiLighting.disable();
-        minecraft.getTextureManager().bindTexture(CHEST_GUI_TEXTURE);
-        int x = bounds.x, y = bounds.y, width = bounds.width, height = bounds.height;
-        int textureOffset = getTextureOffset();
-        
-        //Four Corners
-        this.blit(x, y, 106, 124 + textureOffset, 4, 4);
-        this.blit(x + width - 4, y, 252, 124 + textureOffset, 4, 4);
-        this.blit(x, y + height - 4, 106, 186 + textureOffset, 4, 4);
-        this.blit(x + width - 4, y + height - 4, 252, 186 + textureOffset, 4, 4);
-        
-        //Sides
-        for(int xx = 4; xx < width - 4; xx += 128) {
-            int thisWidth = Math.min(128, width - 4 - xx);
-            this.blit(x + xx, y, 110, 124 + textureOffset, thisWidth, 4);
-            this.blit(x + xx, y + height - 4, 110, 186 + textureOffset, thisWidth, 4);
-        }
-        for(int yy = 4; yy < height - 4; yy += 50) {
-            int thisHeight = Math.min(50, height - 4 - yy);
-            this.blit(x, y + yy, 106, 128 + textureOffset, 4, thisHeight);
-            this.blit(x + width - 4, y + yy, 252, 128 + textureOffset, 4, thisHeight);
+        if (render) {
+            GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F);
+            GuiLighting.disable();
+            minecraft.getTextureManager().bindTexture(CHEST_GUI_TEXTURE);
+            int x = bounds.x, y = bounds.y, width = bounds.width, height = bounds.height;
+            int textureOffset = getTextureOffset();
+    
+            //Four Corners
+            this.blit(x, y, 106, 124 + textureOffset, 4, 4);
+            this.blit(x + width - 4, y, 252, 124 + textureOffset, 4, 4);
+            this.blit(x, y + height - 4, 106, 186 + textureOffset, 4, 4);
+            this.blit(x + width - 4, y + height - 4, 252, 186 + textureOffset, 4, 4);
+    
+            //Sides
+            for(int xx = 4; xx < width - 4; xx += 128) {
+                int thisWidth = Math.min(128, width - 4 - xx);
+                this.blit(x + xx, y, 110, 124 + textureOffset, thisWidth, 4);
+                this.blit(x + xx, y + height - 4, 110, 186 + textureOffset, thisWidth, 4);
+            }
+            for(int yy = 4; yy < height - 4; yy += 50) {
+                int thisHeight = Math.min(50, height - 4 - yy);
+                this.blit(x, y + yy, 106, 128 + textureOffset, 4, thisHeight);
+                this.blit(x + width - 4, y + yy, 252, 128 + textureOffset, 4, thisHeight);
+            }
+            fillGradient(x + 4, y + 4, x + width - 4, y + height - 4, getInnerColor(), getInnerColor());
         }
         }
-        fillGradient(x + 4, y + 4, x + width - 4, y + height - 4, INNER_COLOR.getRGB(), INNER_COLOR.getRGB());
+    }
+    
+    protected int getInnerColor() {
+        return -3750202;
     }
     }
     
     
     protected int getTextureOffset() {
     protected int getTextureOffset() {

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

@@ -0,0 +1,21 @@
+package me.shedaniel.rei.gui.widget;
+
+import java.awt.*;
+
+public class SlotBaseWidget extends RecipeBaseWidget {
+    
+    public SlotBaseWidget(Rectangle bounds) {
+        super(bounds);
+    }
+    
+    @Override
+    public int getInnerColor() {
+        return -7631989;
+    }
+    
+    @Override
+    protected int getTextureOffset() {
+        return -66;
+    }
+    
+}

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

@@ -1,11 +1,12 @@
 package me.shedaniel.rei.gui.widget;
 package me.shedaniel.rei.gui.widget;
 
 
 import com.mojang.blaze3d.platform.GlStateManager;
 import com.mojang.blaze3d.platform.GlStateManager;
+import me.shedaniel.rei.api.ClientHelper;
+import me.shedaniel.rei.api.RecipeCategory;
+import me.shedaniel.rei.api.Renderable;
 import me.shedaniel.rei.client.ScreenHelper;
 import me.shedaniel.rei.client.ScreenHelper;
 import me.shedaniel.rei.gui.RecipeViewingScreen;
 import me.shedaniel.rei.gui.RecipeViewingScreen;
 import net.minecraft.client.render.GuiLighting;
 import net.minecraft.client.render.GuiLighting;
-import net.minecraft.client.render.item.ItemRenderer;
-import net.minecraft.item.ItemStack;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.Identifier;
 
 
 import java.awt.*;
 import java.awt.*;
@@ -17,28 +18,28 @@ public class TabWidget extends HighlightableWidget {
     public static final Identifier CHEST_GUI_TEXTURE = new Identifier("roughlyenoughitems", "textures/gui/recipecontainer.png");
     public static final Identifier CHEST_GUI_TEXTURE = new Identifier("roughlyenoughitems", "textures/gui/recipecontainer.png");
     
     
     public boolean shown = false, selected = false;
     public boolean shown = false, selected = false;
-    public ItemStack item;
+    public Renderable renderable;
     public int id;
     public int id;
     public RecipeViewingScreen recipeViewingWidget;
     public RecipeViewingScreen recipeViewingWidget;
     public String categoryName;
     public String categoryName;
     public Rectangle bounds;
     public Rectangle bounds;
-    private ItemRenderer itemRenderer;
+    public RecipeCategory category;
     
     
     public TabWidget(int id, RecipeViewingScreen recipeViewingWidget, Rectangle bounds) {
     public TabWidget(int id, RecipeViewingScreen recipeViewingWidget, Rectangle bounds) {
         this.id = id;
         this.id = id;
         this.recipeViewingWidget = recipeViewingWidget;
         this.recipeViewingWidget = recipeViewingWidget;
         this.bounds = bounds;
         this.bounds = bounds;
-        this.itemRenderer = minecraft.getItemRenderer();
     }
     }
     
     
-    public void setItem(ItemStack item, String categoryName, boolean selected) {
-        if (item == null) {
+    public void setRenderable(RecipeCategory category, Renderable renderable, String categoryName, boolean selected) {
+        if (renderable == null) {
             shown = false;
             shown = false;
-            this.item = null;
+            this.renderable = null;
         } else {
         } else {
             shown = true;
             shown = true;
-            this.item = item;
+            this.renderable = renderable;
         }
         }
+        this.category = category;
         this.selected = selected;
         this.selected = selected;
         this.categoryName = categoryName;
         this.categoryName = categoryName;
     }
     }
@@ -55,8 +56,8 @@ public class TabWidget extends HighlightableWidget {
         return shown;
         return shown;
     }
     }
     
     
-    public ItemStack getItemStack() {
-        return item;
+    public Renderable getRenderable() {
+        return renderable;
     }
     }
     
     
     @Override
     @Override
@@ -67,26 +68,21 @@ public class TabWidget extends HighlightableWidget {
     @Override
     @Override
     public void render(int mouseX, int mouseY, float delta) {
     public void render(int mouseX, int mouseY, float delta) {
         if (shown) {
         if (shown) {
-            int l = (int) this.bounds.getCenterX() - 8, i1 = (int) this.bounds.getCenterY() - 6;
             GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F);
             GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F);
             GuiLighting.disable();
             GuiLighting.disable();
             minecraft.getTextureManager().bindTexture(CHEST_GUI_TEXTURE);
             minecraft.getTextureManager().bindTexture(CHEST_GUI_TEXTURE);
             this.blit(bounds.x, bounds.y + 2, selected ? 28 : 0, 192, 28, (selected ? 30 : 27));
             this.blit(bounds.x, bounds.y + 2, selected ? 28 : 0, 192, 28, (selected ? 30 : 27));
-            this.blitOffset = 100;
-            this.itemRenderer.zOffset = 100.0F;
-            GuiLighting.enableForItems();
-            this.itemRenderer.renderGuiItem(getItemStack(), l, i1);
-            this.itemRenderer.renderGuiItemOverlay(minecraft.textRenderer, getItemStack(), l, i1);
-            GlStateManager.disableLighting();
-            this.itemRenderer.zOffset = 0.0F;
-            this.blitOffset = 0;
+            renderable.render((int) bounds.getCenterX(), (int) bounds.getCenterY(), mouseX, mouseY, delta);
             if (isHighlighted(mouseX, mouseY))
             if (isHighlighted(mouseX, mouseY))
                 drawTooltip();
                 drawTooltip();
         }
         }
     }
     }
     
     
     private void drawTooltip() {
     private void drawTooltip() {
-        ScreenHelper.getLastOverlay().addTooltip(QueuedTooltip.create(categoryName));
+        if (this.minecraft.options.advancedItemTooltips)
+            ScreenHelper.getLastOverlay().addTooltip(QueuedTooltip.create(categoryName, "§8" + category.getIdentifier().toString(), ClientHelper.getInstance().getFormattedModFromIdentifier(category.getIdentifier())));
+        else
+            ScreenHelper.getLastOverlay().addTooltip(QueuedTooltip.create(categoryName, ClientHelper.getInstance().getFormattedModFromIdentifier(category.getIdentifier())));
     }
     }
     
     
     @Override
     @Override

+ 30 - 7
src/main/java/me/shedaniel/rei/plugin/DefaultPlugin.java

@@ -5,6 +5,7 @@ import me.shedaniel.rei.RoughlyEnoughItemsCore;
 import me.shedaniel.rei.api.*;
 import me.shedaniel.rei.api.*;
 import me.shedaniel.rei.client.ScreenHelper;
 import me.shedaniel.rei.client.ScreenHelper;
 import me.shedaniel.rei.gui.RecipeViewingScreen;
 import me.shedaniel.rei.gui.RecipeViewingScreen;
+import me.shedaniel.rei.gui.VillagerRecipeViewingScreen;
 import me.shedaniel.rei.listeners.ContainerScreenHooks;
 import me.shedaniel.rei.listeners.ContainerScreenHooks;
 import me.shedaniel.rei.listeners.RecipeBookGuiHooks;
 import me.shedaniel.rei.listeners.RecipeBookGuiHooks;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.MinecraftClient;
@@ -41,13 +42,13 @@ import java.util.List;
 
 
 public class DefaultPlugin implements REIPluginEntry {
 public class DefaultPlugin implements REIPluginEntry {
     
     
-    public static final Identifier CRAFTING = new Identifier("roughlyenoughitems", "plugins/crafting");
-    public static final Identifier SMELTING = new Identifier("roughlyenoughitems", "plugins/smelting");
-    public static final Identifier SMOKING = new Identifier("roughlyenoughitems", "plugins/smoking");
-    public static final Identifier BLASTING = new Identifier("roughlyenoughitems", "plugins/blasting");
-    public static final Identifier CAMPFIRE = new Identifier("roughlyenoughitems", "plugins/campfire");
-    public static final Identifier STONE_CUTTING = new Identifier("roughlyenoughitems", "plugins/stone_cutting");
-    public static final Identifier BREWING = new Identifier("roughlyenoughitems", "plugins/brewing");
+    public static final Identifier CRAFTING = new Identifier("minecraft", "plugins/crafting");
+    public static final Identifier SMELTING = new Identifier("minecraft", "plugins/smelting");
+    public static final Identifier SMOKING = new Identifier("minecraft", "plugins/smoking");
+    public static final Identifier BLASTING = new Identifier("minecraft", "plugins/blasting");
+    public static final Identifier CAMPFIRE = new Identifier("minecraft", "plugins/campfire");
+    public static final Identifier STONE_CUTTING = new Identifier("minecraft", "plugins/stone_cutting");
+    public static final Identifier BREWING = new Identifier("minecraft", "plugins/brewing");
     public static final Identifier PLUGIN = new Identifier("roughlyenoughitems", "default_plugin");
     public static final Identifier PLUGIN = new Identifier("roughlyenoughitems", "default_plugin");
     
     
     private static final List<DefaultBrewingDisplay> BREWING_DISPLAYS = Lists.newArrayList();
     private static final List<DefaultBrewingDisplay> BREWING_DISPLAYS = Lists.newArrayList();
@@ -192,6 +193,28 @@ public class DefaultPlugin implements REIPluginEntry {
                 return -1.0f;
                 return -1.0f;
             }
             }
         });
         });
+        displayHelper.registerBoundsHandler(new DisplayHelper.DisplayBoundsHandler<VillagerRecipeViewingScreen>() {
+            @Override
+            public Class getBaseSupportedClass() {
+                return VillagerRecipeViewingScreen.class;
+            }
+            
+            @Override
+            public Rectangle getLeftBounds(VillagerRecipeViewingScreen screen) {
+                return new Rectangle(2, 0, ((VillagerRecipeViewingScreen) screen).bounds.x - 4, MinecraftClient.getInstance().window.getScaledHeight());
+            }
+            
+            @Override
+            public Rectangle getRightBounds(VillagerRecipeViewingScreen screen) {
+                int startX = ((VillagerRecipeViewingScreen) screen).bounds.x + ((VillagerRecipeViewingScreen) screen).bounds.width + 2;
+                return new Rectangle(startX, 0, MinecraftClient.getInstance().window.getScaledWidth() - startX - 2, MinecraftClient.getInstance().window.getScaledHeight());
+            }
+            
+            @Override
+            public float getPriority() {
+                return -1.0f;
+            }
+        });
         displayHelper.registerBoundsHandler(new DisplayHelper.DisplayBoundsHandler<CreativePlayerInventoryScreen>() {
         displayHelper.registerBoundsHandler(new DisplayHelper.DisplayBoundsHandler<CreativePlayerInventoryScreen>() {
             @Override
             @Override
             public Class getBaseSupportedClass() {
             public Class getBaseSupportedClass() {

+ 2 - 0
src/main/java/me/shedaniel/rei/utils/ClothScreenRegistry.java

@@ -8,6 +8,7 @@ import me.shedaniel.cloth.gui.entries.StringListEntry;
 import me.shedaniel.cloth.hooks.ScreenHooks;
 import me.shedaniel.cloth.hooks.ScreenHooks;
 import me.shedaniel.rei.RoughlyEnoughItemsCore;
 import me.shedaniel.rei.RoughlyEnoughItemsCore;
 import me.shedaniel.rei.api.ItemCheatingMode;
 import me.shedaniel.rei.api.ItemCheatingMode;
+import me.shedaniel.rei.client.RecipeScreenType;
 import me.shedaniel.rei.gui.config.ItemListOrderingConfig;
 import me.shedaniel.rei.gui.config.ItemListOrderingConfig;
 import me.shedaniel.rei.gui.credits.CreditsScreen;
 import me.shedaniel.rei.gui.credits.CreditsScreen;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.MinecraftClient;
@@ -47,6 +48,7 @@ public class ClothScreenRegistry {
             }
             }
         });
         });
         ConfigScreenBuilder.CategoryBuilder appearance = builder.addCategory("text.rei.config.appearance");
         ConfigScreenBuilder.CategoryBuilder appearance = builder.addCategory("text.rei.config.appearance");
+        appearance.addOption(new EnumListEntry<>("text.rei.config.recipe_screen_type", RecipeScreenType.class, RoughlyEnoughItemsCore.getConfigManager().getConfig().screenType, RESET, () -> RecipeScreenType.UNSET, bool -> RoughlyEnoughItemsCore.getConfigManager().getConfig().screenType = bool, EnumListEntry.DEFAULT_NAME_PROVIDER, () -> getConfigTooltip("recipe_screen_type")));
         appearance.addOption(new BooleanListEntry("text.rei.config.side_search_box", RoughlyEnoughItemsCore.getConfigManager().getConfig().sideSearchField, RESET, () -> false, bool -> RoughlyEnoughItemsCore.getConfigManager().getConfig().sideSearchField = bool, () -> getConfigTooltip("side_search_box")));
         appearance.addOption(new BooleanListEntry("text.rei.config.side_search_box", RoughlyEnoughItemsCore.getConfigManager().getConfig().sideSearchField, RESET, () -> false, bool -> RoughlyEnoughItemsCore.getConfigManager().getConfig().sideSearchField = bool, () -> getConfigTooltip("side_search_box")));
         appearance.addOption(new EnumListEntry<>("text.rei.config.list_ordering", ItemListOrderingConfig.class, ItemListOrderingConfig.from(RoughlyEnoughItemsCore.getConfigManager().getConfig().itemListOrdering, RoughlyEnoughItemsCore.getConfigManager().getConfig().isAscending), RESET, () -> ItemListOrderingConfig.REGISTRY_ASCENDING, config -> {
         appearance.addOption(new EnumListEntry<>("text.rei.config.list_ordering", ItemListOrderingConfig.class, ItemListOrderingConfig.from(RoughlyEnoughItemsCore.getConfigManager().getConfig().itemListOrdering, RoughlyEnoughItemsCore.getConfigManager().getConfig().isAscending), RESET, () -> ItemListOrderingConfig.REGISTRY_ASCENDING, config -> {
             RoughlyEnoughItemsCore.getConfigManager().getConfig().itemListOrdering = config.getOrdering();
             RoughlyEnoughItemsCore.getConfigManager().getConfig().itemListOrdering = config.getOrdering();

+ 1 - 0
src/main/resources/assets/roughlyenoughitems/lang/en_us.json

@@ -93,6 +93,7 @@
   "text.rei.config.light_gray_recipe_border": "Light Gray Recipe Border:",
   "text.rei.config.light_gray_recipe_border": "Light Gray Recipe Border:",
   "text.rei.config_api_failed": "You arrived here either if Cloth Config API failed or you don't have it installed!\nUpdate / Install the API and report to the bug tracker.",
   "text.rei.config_api_failed": "You arrived here either if Cloth Config API failed or you don't have it installed!\nUpdate / Install the API and report to the bug tracker.",
   "text.rei.back": "Back",
   "text.rei.back": "Back",
+  "text.rei.config.recipe_screen_type": "Screen Type",
 
 
   "_comment": "Config Tooltips",
   "_comment": "Config Tooltips",
   "tooltip.rei.config.side_search_box": "Declares the location of the search field:\nYes: Left / Right\nNo: Center\n \nDefaulted: No",
   "tooltip.rei.config.side_search_box": "Declares the location of the search field:\nYes: Left / Right\nNo: Center\n \nDefaulted: No",

BIN
src/main/resources/assets/roughlyenoughitems/textures/gui/recipecontainer.png


+ 1 - 1
src/main/resources/fabric.mod.json

@@ -1,7 +1,7 @@
 {
 {
   "schemaVersion": 1,
   "schemaVersion": 1,
   "id": "roughlyenoughitems",
   "id": "roughlyenoughitems",
-  "name": "RoughlyEnoughItems",
+  "name": "Roughly Enough Items",
   "description": "To allow players to view items and recipes. Version: ${version}",
   "description": "To allow players to view items and recipes. Version: ${version}",
   "version": "${version}",
   "version": "${version}",
   "authors": [
   "authors": [