From 7593f016aa7d0bb83baa57a76abb55912ada3af6 Mon Sep 17 00:00:00 2001 From: mezz Date: Thu, 3 Nov 2016 00:42:05 -0700 Subject: [PATCH] Add recipe category tabs --- gradle.properties | 2 +- src/main/java/mezz/jei/GuiEventHandler.java | 2 +- src/main/java/mezz/jei/JeiRuntime.java | 2 +- src/main/java/mezz/jei/JeiStarter.java | 2 +- src/main/java/mezz/jei/RecipeRegistry.java | 2 +- .../jei/api/recipe/BlankRecipeCategory.java | 9 + .../mezz/jei/api/recipe/IRecipeCategory.java | 14 + .../java/mezz/jei/config/JEIModConfigGui.java | 2 +- src/main/java/mezz/jei/gui/GuiHelper.java | 16 + src/main/java/mezz/jei/gui/GuiProperties.java | 1 + ....java => RecipeCategoryCraftingItems.java} | 15 +- .../gui/{ => recipes}/IRecipeGuiLogic.java | 104 +- .../recipes/IRecipeLogicStateListener.java | 5 + .../mezz/jei/gui/recipes/RecipeArrowTab.java | 52 + .../jei/gui/recipes/RecipeCategoryTab.java | 82 ++ .../{ => recipes}/RecipeClickableArea.java | 38 +- .../jei/gui/{ => recipes}/RecipeGuiLogic.java | 658 +++++++------ .../mezz/jei/gui/recipes/RecipeGuiTab.java | 48 + .../mezz/jei/gui/recipes/RecipeGuiTabs.java | 236 +++++ .../jei/gui/{ => recipes}/RecipeLayout.java | 418 ++++---- .../{ => recipes}/RecipeTransferButton.java | 107 +- .../jei/gui/{ => recipes}/RecipesGui.java | 924 +++++++++--------- .../java/mezz/jei/input/InputHandler.java | 4 +- .../ItemDescriptionRecipeCategory.java | 13 + .../vanilla/furnace/FurnaceFuelCategory.java | 14 + .../mezz/jei/transfer/RecipeTransferUtil.java | 2 +- src/main/java/mezz/jei/util/ModRegistry.java | 2 +- .../jei/textures/gui/recipeBackground.png | Bin 774 -> 0 bytes .../jei/textures/gui/recipeBackground2.png | Bin 0 -> 834 bytes .../jei/textures/gui/recipeBackgroundTall.png | Bin 294 -> 0 bytes .../textures/gui/recipeBackgroundTall2.png | Bin 0 -> 327 bytes 31 files changed, 1657 insertions(+), 1117 deletions(-) rename src/main/java/mezz/jei/gui/{RecipeCategoryCraftingItemsArea.java => RecipeCategoryCraftingItems.java} (90%) rename src/main/java/mezz/jei/gui/{ => recipes}/IRecipeGuiLogic.java (68%) create mode 100644 src/main/java/mezz/jei/gui/recipes/IRecipeLogicStateListener.java create mode 100644 src/main/java/mezz/jei/gui/recipes/RecipeArrowTab.java create mode 100644 src/main/java/mezz/jei/gui/recipes/RecipeCategoryTab.java rename src/main/java/mezz/jei/gui/{ => recipes}/RecipeClickableArea.java (92%) rename src/main/java/mezz/jei/gui/{ => recipes}/RecipeGuiLogic.java (83%) create mode 100644 src/main/java/mezz/jei/gui/recipes/RecipeGuiTab.java create mode 100644 src/main/java/mezz/jei/gui/recipes/RecipeGuiTabs.java rename src/main/java/mezz/jei/gui/{ => recipes}/RecipeLayout.java (96%) rename src/main/java/mezz/jei/gui/{ => recipes}/RecipeTransferButton.java (95%) rename src/main/java/mezz/jei/gui/{ => recipes}/RecipesGui.java (87%) delete mode 100644 src/main/resources/assets/jei/textures/gui/recipeBackground.png create mode 100644 src/main/resources/assets/jei/textures/gui/recipeBackground2.png delete mode 100644 src/main/resources/assets/jei/textures/gui/recipeBackgroundTall.png create mode 100644 src/main/resources/assets/jei/textures/gui/recipeBackgroundTall2.png diff --git a/gradle.properties b/gradle.properties index 0c7d5e8ad..dc1763705 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ mcversion=1.10.2 -forgeversion=12.18.2.2097 +forgeversion=12.18.2.2118 mcp_mappings=snapshot_20160712 curse_project_id=238222 diff --git a/src/main/java/mezz/jei/GuiEventHandler.java b/src/main/java/mezz/jei/GuiEventHandler.java index 91aa6d449..e1acea3c3 100644 --- a/src/main/java/mezz/jei/GuiEventHandler.java +++ b/src/main/java/mezz/jei/GuiEventHandler.java @@ -5,8 +5,8 @@ import mezz.jei.api.ingredients.IIngredientRegistry; import mezz.jei.config.Config; import mezz.jei.gui.ItemListOverlay; -import mezz.jei.gui.RecipesGui; import mezz.jei.gui.TooltipRenderer; +import mezz.jei.gui.recipes.RecipesGui; import mezz.jei.input.InputHandler; import mezz.jei.util.Translator; import net.minecraft.client.gui.GuiScreen; diff --git a/src/main/java/mezz/jei/JeiRuntime.java b/src/main/java/mezz/jei/JeiRuntime.java index 2fbc74e7a..907b7c2f4 100644 --- a/src/main/java/mezz/jei/JeiRuntime.java +++ b/src/main/java/mezz/jei/JeiRuntime.java @@ -2,7 +2,7 @@ import mezz.jei.api.IJeiRuntime; import mezz.jei.gui.ItemListOverlay; -import mezz.jei.gui.RecipesGui; +import mezz.jei.gui.recipes.RecipesGui; public class JeiRuntime implements IJeiRuntime { diff --git a/src/main/java/mezz/jei/JeiStarter.java b/src/main/java/mezz/jei/JeiStarter.java index fb888f660..41724835f 100644 --- a/src/main/java/mezz/jei/JeiStarter.java +++ b/src/main/java/mezz/jei/JeiStarter.java @@ -8,7 +8,7 @@ import mezz.jei.api.IModPlugin; import mezz.jei.api.gui.IAdvancedGuiHandler; import mezz.jei.gui.ItemListOverlay; -import mezz.jei.gui.RecipesGui; +import mezz.jei.gui.recipes.RecipesGui; import mezz.jei.plugins.vanilla.VanillaPlugin; import mezz.jei.util.Log; import mezz.jei.util.ModIdUtil; diff --git a/src/main/java/mezz/jei/RecipeRegistry.java b/src/main/java/mezz/jei/RecipeRegistry.java index e3682491f..56cbdcb8d 100644 --- a/src/main/java/mezz/jei/RecipeRegistry.java +++ b/src/main/java/mezz/jei/RecipeRegistry.java @@ -32,7 +32,7 @@ import mezz.jei.config.Config; import mezz.jei.config.Constants; import mezz.jei.gui.Focus; -import mezz.jei.gui.RecipeClickableArea; +import mezz.jei.gui.recipes.RecipeClickableArea; import mezz.jei.util.ErrorUtil; import mezz.jei.util.IngredientUtil; import mezz.jei.util.Ingredients; diff --git a/src/main/java/mezz/jei/api/recipe/BlankRecipeCategory.java b/src/main/java/mezz/jei/api/recipe/BlankRecipeCategory.java index fcdb7f1ba..d97d37642 100644 --- a/src/main/java/mezz/jei/api/recipe/BlankRecipeCategory.java +++ b/src/main/java/mezz/jei/api/recipe/BlankRecipeCategory.java @@ -1,5 +1,8 @@ package mezz.jei.api.recipe; +import javax.annotation.Nullable; + +import mezz.jei.api.gui.IDrawable; import mezz.jei.api.gui.IRecipeLayout; import net.minecraft.client.Minecraft; @@ -7,6 +10,12 @@ * An {@link IRecipeCategory} that does nothing, inherit from this to avoid implementing methods you don't need. */ public abstract class BlankRecipeCategory implements IRecipeCategory { + @Nullable + @Override + public IDrawable getIcon() { + return null; + } + @Override public void drawExtras(Minecraft minecraft) { diff --git a/src/main/java/mezz/jei/api/recipe/IRecipeCategory.java b/src/main/java/mezz/jei/api/recipe/IRecipeCategory.java index e7c1e6772..68b040ee9 100644 --- a/src/main/java/mezz/jei/api/recipe/IRecipeCategory.java +++ b/src/main/java/mezz/jei/api/recipe/IRecipeCategory.java @@ -1,11 +1,15 @@ package mezz.jei.api.recipe; +import javax.annotation.Nullable; + import mezz.jei.api.IGuiHelper; +import mezz.jei.api.IModRegistry; import mezz.jei.api.gui.IDrawable; import mezz.jei.api.gui.IDrawableAnimated; import mezz.jei.api.gui.IRecipeLayout; import mezz.jei.api.ingredients.IIngredients; import net.minecraft.client.Minecraft; +import net.minecraft.item.ItemStack; /** * Defines a category of recipe, (i.e. Crafting Table Recipe, Furnace Recipe). @@ -36,6 +40,16 @@ public interface IRecipeCategory { */ IDrawable getBackground(); + /** + * Optional icon for the category tab. + * If no icon is defined here, JEI will use first item registered with {@link IModRegistry#addRecipeCategoryCraftingItem(ItemStack, String...)} + * + * @return icon to draw on the category tab, max size is 16x16 pixels. + * @since 3.13.1 + */ + @Nullable + IDrawable getIcon(); + /** * Draw any extra elements that might be necessary, icons or extra slots. * diff --git a/src/main/java/mezz/jei/config/JEIModConfigGui.java b/src/main/java/mezz/jei/config/JEIModConfigGui.java index f9051791e..a01a17f50 100644 --- a/src/main/java/mezz/jei/config/JEIModConfigGui.java +++ b/src/main/java/mezz/jei/config/JEIModConfigGui.java @@ -3,7 +3,7 @@ import java.util.ArrayList; import java.util.List; -import mezz.jei.gui.RecipesGui; +import mezz.jei.gui.recipes.RecipesGui; import mezz.jei.util.Translator; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiScreen; diff --git a/src/main/java/mezz/jei/gui/GuiHelper.java b/src/main/java/mezz/jei/gui/GuiHelper.java index fa156c99a..f8455ffca 100644 --- a/src/main/java/mezz/jei/gui/GuiHelper.java +++ b/src/main/java/mezz/jei/gui/GuiHelper.java @@ -8,6 +8,7 @@ import mezz.jei.api.gui.IDrawableStatic; import mezz.jei.api.gui.ITickTimer; import mezz.jei.api.recipe.IStackHelper; +import mezz.jei.config.Constants; import mezz.jei.util.Log; import mezz.jei.util.TickTimer; import net.minecraft.util.ResourceLocation; @@ -15,11 +16,18 @@ public class GuiHelper implements IGuiHelper { private final IStackHelper stackHelper; private final IDrawableStatic slotDrawable; + private final IDrawableStatic tabSelected; + private final IDrawableStatic tabUnselected; public GuiHelper(IStackHelper stackHelper) { this.stackHelper = stackHelper; + ResourceLocation location = new ResourceLocation("minecraft", "textures/gui/container/furnace.png"); this.slotDrawable = createDrawable(location, 55, 16, 18, 18); + + ResourceLocation recipeBackgroundResource = new ResourceLocation(Constants.RESOURCE_DOMAIN, Constants.TEXTURE_RECIPE_BACKGROUND_PATH); + tabSelected = createDrawable(recipeBackgroundResource, 196, 15, 24, 24); + tabUnselected = createDrawable(recipeBackgroundResource, 220, 15, 24, 22); } @Override @@ -92,4 +100,12 @@ public ICraftingGridHelper createCraftingGridHelper(int craftInputSlot1, int cra public ITickTimer createTickTimer(int ticksPerCycle, int maxValue, boolean countDown) { return new TickTimer(ticksPerCycle, maxValue, countDown); } + + public IDrawableStatic getTabSelected() { + return tabSelected; + } + + public IDrawableStatic getTabUnselected() { + return tabUnselected; + } } diff --git a/src/main/java/mezz/jei/gui/GuiProperties.java b/src/main/java/mezz/jei/gui/GuiProperties.java index a1d368af1..42fec9bab 100644 --- a/src/main/java/mezz/jei/gui/GuiProperties.java +++ b/src/main/java/mezz/jei/gui/GuiProperties.java @@ -2,6 +2,7 @@ import javax.annotation.Nullable; +import mezz.jei.gui.recipes.RecipesGui; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.inventory.GuiContainer; diff --git a/src/main/java/mezz/jei/gui/RecipeCategoryCraftingItemsArea.java b/src/main/java/mezz/jei/gui/RecipeCategoryCraftingItems.java similarity index 90% rename from src/main/java/mezz/jei/gui/RecipeCategoryCraftingItemsArea.java rename to src/main/java/mezz/jei/gui/RecipeCategoryCraftingItems.java index 3dff82496..0756b1de2 100644 --- a/src/main/java/mezz/jei/gui/RecipeCategoryCraftingItemsArea.java +++ b/src/main/java/mezz/jei/gui/RecipeCategoryCraftingItems.java @@ -13,6 +13,7 @@ import mezz.jei.config.Constants; import mezz.jei.gui.ingredients.GuiIngredient; import mezz.jei.gui.ingredients.GuiItemStackGroup; +import mezz.jei.gui.recipes.RecipesGui; import mezz.jei.input.IClickedIngredient; import mezz.jei.input.IShowsRecipeFocuses; import net.minecraft.client.Minecraft; @@ -23,7 +24,7 @@ /** * The area drawn on left side of the {@link RecipesGui} that shows which items can craft the current recipe category. */ -public class RecipeCategoryCraftingItemsArea implements IShowsRecipeFocuses { +public class RecipeCategoryCraftingItems implements IShowsRecipeFocuses { private final IRecipeRegistry recipeRegistry; private final IDrawable topDrawable; private final IDrawable middleDrawable; @@ -33,7 +34,7 @@ public class RecipeCategoryCraftingItemsArea implements IShowsRecipeFocuses { private int left = 0; private int top = 0; - public RecipeCategoryCraftingItemsArea(IRecipeRegistry recipeRegistry) { + public RecipeCategoryCraftingItems(IRecipeRegistry recipeRegistry) { this.recipeRegistry = recipeRegistry; IFocus focus = recipeRegistry.createFocus(IFocus.Mode.NONE, null); craftingItems = new GuiItemStackGroup(focus); @@ -41,9 +42,9 @@ public RecipeCategoryCraftingItemsArea(IRecipeRegistry recipeRegistry) { ResourceLocation recipeBackgroundResource = new ResourceLocation(Constants.RESOURCE_DOMAIN, Constants.TEXTURE_RECIPE_BACKGROUND_PATH); IGuiHelper guiHelper = Internal.getHelpers().getGuiHelper(); - topDrawable = guiHelper.createDrawable(recipeBackgroundResource, 196, 65, 25, 6); - middleDrawable = guiHelper.createDrawable(recipeBackgroundResource, 196, 71, 25, 16); - bottomDrawable = guiHelper.createDrawable(recipeBackgroundResource, 196, 87, 55, 6); + topDrawable = guiHelper.createDrawable(recipeBackgroundResource, 196, 65, 26, 6); + middleDrawable = guiHelper.createDrawable(recipeBackgroundResource, 196, 71, 26, 16); + bottomDrawable = guiHelper.createDrawable(recipeBackgroundResource, 196, 87, 26, 6); } public void updateLayout(List itemStacks, GuiProperties guiProperties) { @@ -64,8 +65,8 @@ public void updateLayout(List itemStacks, GuiProperties guiProperties } } - top = guiProperties.getGuiTop() + (guiProperties.getGuiYSize() - totalHeight) / 2; // center it - left = guiProperties.getGuiLeft() + - middleDrawable.getWidth() + 3; // overlaps the recipe gui slightly + top = guiProperties.getGuiTop(); + left = guiProperties.getGuiLeft() - topDrawable.getWidth() + 4; // overlaps the recipe gui slightly ListMultimap itemStacksForSlots = ArrayListMultimap.create(); for (int i = 0; i < itemStacks.size(); i++) { diff --git a/src/main/java/mezz/jei/gui/IRecipeGuiLogic.java b/src/main/java/mezz/jei/gui/recipes/IRecipeGuiLogic.java similarity index 68% rename from src/main/java/mezz/jei/gui/IRecipeGuiLogic.java rename to src/main/java/mezz/jei/gui/recipes/IRecipeGuiLogic.java index fe6f0b4e0..e442fda2d 100644 --- a/src/main/java/mezz/jei/gui/IRecipeGuiLogic.java +++ b/src/main/java/mezz/jei/gui/recipes/IRecipeGuiLogic.java @@ -1,49 +1,55 @@ -package mezz.jei.gui; - -import javax.annotation.Nullable; -import java.util.List; - -import mezz.jei.api.recipe.IFocus; -import mezz.jei.api.recipe.IRecipeCategory; -import net.minecraft.item.ItemStack; - -public interface IRecipeGuiLogic { - - String getPageString(); - - void setRecipesPerPage(int recipesPerPage); - - boolean hasMultipleCategories(); - - boolean hasAllCategories(); - - void previousRecipeCategory(); - - void nextRecipeCategory(); - - boolean hasMultiplePages(); - - void previousPage(); - - void nextPage(); - - boolean setFocus(IFocus focus); - - @Nullable - IFocus getFocus(); - - boolean back(); - - void clearHistory(); - - boolean setCategoryFocus(); - - boolean setCategoryFocus(List recipeCategoryUids); - - @Nullable - IRecipeCategory getRecipeCategory(); - - List getRecipeCategoryCraftingItems(); - - List getRecipeWidgets(int posX, int posY, int spacingY); -} +package mezz.jei.gui.recipes; + +import javax.annotation.Nullable; +import java.util.List; + +import com.google.common.collect.ImmutableList; +import mezz.jei.api.recipe.IFocus; +import mezz.jei.api.recipe.IRecipeCategory; +import net.minecraft.item.ItemStack; + +public interface IRecipeGuiLogic { + + String getPageString(); + + void setRecipesPerPage(int recipesPerPage); + + boolean hasMultipleCategories(); + + boolean hasAllCategories(); + + void previousRecipeCategory(); + + void nextRecipeCategory(); + + void setRecipeCategory(IRecipeCategory category); + + boolean hasMultiplePages(); + + void previousPage(); + + void nextPage(); + + boolean setFocus(IFocus focus); + + IFocus getFocus(); + + boolean back(); + + void clearHistory(); + + boolean setCategoryFocus(); + + boolean setCategoryFocus(List recipeCategoryUids); + + @Nullable + IRecipeCategory getSelectedRecipeCategory(); + + ImmutableList getRecipeCategories(); + + List getRecipeCategoryCraftingItems(); + + List getRecipeCategoryCraftingItems(IRecipeCategory recipeCategory); + + List getRecipeWidgets(int posX, int posY, int spacingY); +} diff --git a/src/main/java/mezz/jei/gui/recipes/IRecipeLogicStateListener.java b/src/main/java/mezz/jei/gui/recipes/IRecipeLogicStateListener.java new file mode 100644 index 000000000..3ef68c953 --- /dev/null +++ b/src/main/java/mezz/jei/gui/recipes/IRecipeLogicStateListener.java @@ -0,0 +1,5 @@ +package mezz.jei.gui.recipes; + +public interface IRecipeLogicStateListener { + void onStateChange(); +} diff --git a/src/main/java/mezz/jei/gui/recipes/RecipeArrowTab.java b/src/main/java/mezz/jei/gui/recipes/RecipeArrowTab.java new file mode 100644 index 000000000..f4d09f45d --- /dev/null +++ b/src/main/java/mezz/jei/gui/recipes/RecipeArrowTab.java @@ -0,0 +1,52 @@ +package mezz.jei.gui.recipes; + +import javax.annotation.Nullable; + +import mezz.jei.api.recipe.IRecipeCategory; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.renderer.GlStateManager; + +public class RecipeArrowTab extends RecipeGuiTab { + private final RecipeGuiTabs recipeGuiTabs; + private final boolean next; + + public RecipeArrowTab(RecipeGuiTabs recipeGuiTabs, boolean next, int x, int y) { + super(x, y); + this.recipeGuiTabs = recipeGuiTabs; + this.next = next; + } + + @Override + public void draw(Minecraft minecraft, boolean selected, int mouseX, int mouseY) { + super.draw(minecraft, selected, mouseX, mouseY); + String arrow = next ? ">" : "<"; + FontRenderer fontRenderer = minecraft.fontRendererObj; + float textCenterX = x + (TAB_WIDTH / 2f); + float textCenterY = y + (TAB_HEIGHT / 2f) - 3; + int color = isMouseOver(mouseX, mouseY) ? 16777120 : 14737632; + fontRenderer.drawStringWithShadow(arrow, textCenterX - fontRenderer.getStringWidth(arrow) / 2f, textCenterY, color); + GlStateManager.color(1, 1, 1, 1); + } + + @Override + public boolean handleMouseClicked(int mouseX, int mouseY, int mouseButton) { + if (next) { + recipeGuiTabs.nextPage(); + } else { + recipeGuiTabs.prevPage(); + } + return true; + } + + @Override + public boolean isSelected(IRecipeCategory selectedCategory) { + return false; + } + + @Nullable + @Override + public String getTooltip() { + return null; + } +} diff --git a/src/main/java/mezz/jei/gui/recipes/RecipeCategoryTab.java b/src/main/java/mezz/jei/gui/recipes/RecipeCategoryTab.java new file mode 100644 index 000000000..a65f91d19 --- /dev/null +++ b/src/main/java/mezz/jei/gui/recipes/RecipeCategoryTab.java @@ -0,0 +1,82 @@ +package mezz.jei.gui.recipes; + +import javax.annotation.Nullable; +import java.util.List; + +import mezz.jei.api.gui.IDrawable; +import mezz.jei.api.recipe.IRecipeCategory; +import mezz.jei.plugins.vanilla.ingredients.ItemStackRenderer; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.item.ItemStack; + +public class RecipeCategoryTab extends RecipeGuiTab { + private final IRecipeGuiLogic logic; + private final IRecipeCategory category; + + public RecipeCategoryTab(IRecipeGuiLogic logic, IRecipeCategory category, int x, int y) { + super(x, y); + this.logic = logic; + this.category = category; + } + + @Override + public boolean handleMouseClicked(int mouseX, int mouseY, int mouseButton) { + logic.setRecipeCategory(category); + return true; + } + + @Override + public void draw(Minecraft minecraft, boolean selected, int mouseX, int mouseY) { + super.draw(minecraft, selected, mouseX, mouseY); + + int iconX = x + 4; + int iconY = y + 4; + + IDrawable icon = getCategoryIcon(category); + if (icon != null) { + iconX += (16 - icon.getWidth()) / 2; + iconY += (16 - icon.getHeight()) / 2; + icon.draw(minecraft, iconX, iconY); + } else { + List craftingItems = logic.getRecipeCategoryCraftingItems(category); + if (!craftingItems.isEmpty()) { + ItemStackRenderer renderer = new ItemStackRenderer(); + ItemStack ingredient = craftingItems.get(0); + GlStateManager.enableDepth(); + renderer.render(minecraft, iconX, iconY, ingredient); + GlStateManager.enableAlpha(); + GlStateManager.disableDepth(); + } else { + String text = category.getTitle().substring(0, 2); + FontRenderer fontRenderer = minecraft.fontRendererObj; + float textCenterX = x + (TAB_WIDTH / 2f); + float textCenterY = y + (TAB_HEIGHT / 2f) - 3; + int color = isMouseOver(mouseX, mouseY) ? 16777120 : 14737632; + fontRenderer.drawStringWithShadow(text, textCenterX - fontRenderer.getStringWidth(text) / 2f, textCenterY, color); + GlStateManager.color(1, 1, 1, 1); + } + } + } + + @Nullable + private static IDrawable getCategoryIcon(IRecipeCategory recipeCategory) { + try { + return recipeCategory.getIcon(); + } catch (AbstractMethodError ignored) { // old recipe categories do not implement this method + return null; + } + } + + @Override + public boolean isSelected(IRecipeCategory selectedCategory) { + return category.getUid().equals(selectedCategory.getUid()); + } + + @Nullable + @Override + public String getTooltip() { + return category.getTitle(); + } +} diff --git a/src/main/java/mezz/jei/gui/RecipeClickableArea.java b/src/main/java/mezz/jei/gui/recipes/RecipeClickableArea.java similarity index 92% rename from src/main/java/mezz/jei/gui/RecipeClickableArea.java rename to src/main/java/mezz/jei/gui/recipes/RecipeClickableArea.java index 017b26032..3b06368f2 100644 --- a/src/main/java/mezz/jei/gui/RecipeClickableArea.java +++ b/src/main/java/mezz/jei/gui/recipes/RecipeClickableArea.java @@ -1,19 +1,19 @@ -package mezz.jei.gui; - -import java.util.Arrays; -import java.util.List; - -import net.minecraftforge.fml.client.config.HoverChecker; - -public class RecipeClickableArea extends HoverChecker { - private final List recipeCategoryUids; - - public RecipeClickableArea(int top, int bottom, int left, int right, String... recipeCategoryUids) { - super(top, bottom, left, right, 0); - this.recipeCategoryUids = Arrays.asList(recipeCategoryUids); - } - - public List getRecipeCategoryUids() { - return recipeCategoryUids; - } -} +package mezz.jei.gui.recipes; + +import java.util.Arrays; +import java.util.List; + +import net.minecraftforge.fml.client.config.HoverChecker; + +public class RecipeClickableArea extends HoverChecker { + private final List recipeCategoryUids; + + public RecipeClickableArea(int top, int bottom, int left, int right, String... recipeCategoryUids) { + super(top, bottom, left, right, 0); + this.recipeCategoryUids = Arrays.asList(recipeCategoryUids); + } + + public List getRecipeCategoryUids() { + return recipeCategoryUids; + } +} diff --git a/src/main/java/mezz/jei/gui/RecipeGuiLogic.java b/src/main/java/mezz/jei/gui/recipes/RecipeGuiLogic.java similarity index 83% rename from src/main/java/mezz/jei/gui/RecipeGuiLogic.java rename to src/main/java/mezz/jei/gui/recipes/RecipeGuiLogic.java index fdf9c54c6..2034f29ae 100644 --- a/src/main/java/mezz/jei/gui/RecipeGuiLogic.java +++ b/src/main/java/mezz/jei/gui/recipes/RecipeGuiLogic.java @@ -1,314 +1,344 @@ -package mezz.jei.gui; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Stack; - -import com.google.common.collect.ImmutableList; -import mezz.jei.RecipeRegistry; -import mezz.jei.api.IModRegistry; -import mezz.jei.api.recipe.IFocus; -import mezz.jei.api.recipe.IRecipeCategory; -import mezz.jei.api.recipe.IRecipeWrapper; -import mezz.jei.util.MathUtil; -import net.minecraft.client.Minecraft; -import net.minecraft.inventory.Container; -import net.minecraft.item.ItemStack; - -public class RecipeGuiLogic implements IRecipeGuiLogic { - private static class State { - @Nonnull - public final IFocus focus; - @Nonnull - public final ImmutableList recipeCategories; - - public int recipeCategoryIndex; - public int pageIndex; - public int recipesPerPage; - - public State(IFocus focus, List recipeCategories, int recipeCategoryIndex, int pageIndex) { - this.focus = focus; - this.recipeCategories = ImmutableList.copyOf(recipeCategories); - this.recipeCategoryIndex = recipeCategoryIndex; - this.pageIndex = pageIndex; - } - } - - private final RecipeRegistry recipeRegistry; - - @Nullable - private State state = null; - private final Stack history = new Stack(); - - /** - * List of recipes for the currently selected recipeClass - */ - private List recipes = Collections.emptyList(); - - /** - * List of items that can craft recipes from the current recipe category - * - * @see IModRegistry#addRecipeCategoryCraftingItem(ItemStack, String...) - */ - private List recipeCategoryCraftingItems = Collections.emptyList(); - - public RecipeGuiLogic(RecipeRegistry recipeRegistry) { - this.recipeRegistry = recipeRegistry; - } - - @Override - public boolean setFocus(IFocus focus) { - return setFocus(focus, true); - } - - @Override - public boolean back() { - if (history.empty()) { - return false; - } - final State state = history.pop(); - setState(state); - return true; - } - - @Override - public void clearHistory() { - while (!history.empty()) { - history.pop(); - } - } - - private boolean setFocus(IFocus focus, boolean saveHistory) { - final List recipeCategories = recipeRegistry.getRecipeCategories(focus); - if (recipeCategories.isEmpty()) { - return false; - } - - final int recipeCategoryIndex = getRecipeCategoryIndex(recipeCategories); - - if (this.state != null && saveHistory) { - history.push(this.state); - } - - final State state = new State(focus, recipeCategories, recipeCategoryIndex, 0); - setState(state); - - return true; - } - - private void setState(State state) { - this.state = state; - updateRecipes(); - } - - private int getRecipeCategoryIndex(List recipeCategories) { - final Container container = Minecraft.getMinecraft().thePlayer.openContainer; - if (container == null) { - return 0; - } - - for (int i = 0; i < recipeCategories.size(); i++) { - IRecipeCategory recipeCategory = recipeCategories.get(i); - if (recipeRegistry.getRecipeTransferHandler(container, recipeCategory) != null) { - return i; - } - } - - return 0; - } - - @Override - public boolean setCategoryFocus() { - IRecipeCategory recipeCategory = getRecipeCategory(); - if (recipeCategory == null) { - return false; - } - - if (this.state != null) { - history.push(this.state); - } - - final List recipeCategories = recipeRegistry.getRecipeCategories(); - final int recipeCategoryIndex = recipeCategories.indexOf(recipeCategory); - IFocus focus = recipeRegistry.createFocus(IFocus.Mode.NONE, null); - final State state = new State(focus, recipeCategories, recipeCategoryIndex, 0); - setState(state); - - return true; - } - - @Override - public boolean setCategoryFocus(List recipeCategoryUids) { - List recipeCategories = recipeRegistry.getRecipeCategories(recipeCategoryUids); - if (recipeCategories.isEmpty()) { - return false; - } - - if (this.state != null) { - history.push(this.state); - } - - IFocus focus = recipeRegistry.createFocus(IFocus.Mode.NONE, null); - final State state = new State(focus, recipeCategories, 0, 0); - setState(state); - - return true; - } - - @Override - public IFocus getFocus() { - if (state == null) { - return null; - } - return state.focus; - } - - @Override - public List getRecipeCategoryCraftingItems() { - return recipeCategoryCraftingItems; - } - - @Override - public void setRecipesPerPage(int recipesPerPage) { - if (state == null) { - return; - } - if (state.recipesPerPage != recipesPerPage) { - int recipeIndex = state.pageIndex * state.recipesPerPage; - state.pageIndex = recipeIndex / recipesPerPage; - - state.recipesPerPage = recipesPerPage; - updateRecipes(); - } - } - - private void updateRecipes() { - if (state == null) { - return; - } - - final IRecipeCategory recipeCategory = getRecipeCategory(); - if (recipeCategory == null) { - recipes = Collections.emptyList(); - recipeCategoryCraftingItems = Collections.emptyList(); - } else { - IFocus focus = state.focus; - //noinspection unchecked - this.recipes = recipeRegistry.getRecipeWrappers(recipeCategory, focus); - - recipeCategoryCraftingItems = recipeRegistry.getCraftingItems(recipeCategory, focus); - } - } - - @Override - @Nullable - public IRecipeCategory getRecipeCategory() { - if (state == null || state.recipeCategories.size() == 0) { - return null; - } - return state.recipeCategories.get(state.recipeCategoryIndex); - } - - @Override - public List getRecipeWidgets(int posX, int posY, int spacingY) { - if (state == null) { - return Collections.emptyList(); - } - - List recipeWidgets = new ArrayList(); - - IRecipeCategory recipeCategory = getRecipeCategory(); - if (recipeCategory == null) { - return recipeWidgets; - } - - int recipeWidgetIndex = 0; - for (int recipeIndex = state.pageIndex * state.recipesPerPage; recipeIndex < recipes.size() && recipeWidgets.size() < state.recipesPerPage; recipeIndex++) { - IRecipeWrapper recipeWrapper = recipes.get(recipeIndex); - if (recipeWrapper == null) { - continue; - } - - RecipeLayout recipeWidget = new RecipeLayout(recipeWidgetIndex++, posX, posY, recipeCategory, recipeWrapper, state.focus); - recipeWidgets.add(recipeWidget); - - posY += spacingY; - } - - return recipeWidgets; - } - - @Override - public void nextRecipeCategory() { - if (state == null) { - return; - } - final int recipesTypesCount = state.recipeCategories.size(); - state.recipeCategoryIndex = (state.recipeCategoryIndex + 1) % recipesTypesCount; - state.pageIndex = 0; - updateRecipes(); - } - - @Override - public boolean hasMultiplePages() { - return state != null && recipes.size() > state.recipesPerPage; - } - - @Override - public void previousRecipeCategory() { - if (state == null) { - return; - } - final int recipesTypesCount = state.recipeCategories.size(); - state.recipeCategoryIndex = (recipesTypesCount + state.recipeCategoryIndex - 1) % recipesTypesCount; - state.pageIndex = 0; - updateRecipes(); - } - - @Override - public void nextPage() { - if (state == null) { - return; - } - int pageCount = pageCount(state.recipesPerPage); - state.pageIndex = (state.pageIndex + 1) % pageCount; - } - - @Override - public void previousPage() { - if (state == null) { - return; - } - int pageCount = pageCount(state.recipesPerPage); - state.pageIndex = (pageCount + state.pageIndex - 1) % pageCount; - } - - private int pageCount(int recipesPerPage) { - if (recipes.size() <= 1) { - return 1; - } - - return MathUtil.divideCeil(recipes.size(), recipesPerPage); - } - - @Override - public String getPageString() { - if (state == null) { - return "1/1"; - } - return (state.pageIndex + 1) + "/" + pageCount(state.recipesPerPage); - } - - @Override - public boolean hasMultipleCategories() { - return state != null && state.recipeCategories.size() > 1; - } - - @Override - public boolean hasAllCategories() { - return state != null && state.recipeCategories.size() == recipeRegistry.getRecipeCategoryCount(); - } -} +package mezz.jei.gui.recipes; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Stack; + +import com.google.common.collect.ImmutableList; +import mezz.jei.RecipeRegistry; +import mezz.jei.api.recipe.IFocus; +import mezz.jei.api.recipe.IRecipeCategory; +import mezz.jei.api.recipe.IRecipeWrapper; +import mezz.jei.util.MathUtil; +import net.minecraft.client.Minecraft; +import net.minecraft.inventory.Container; +import net.minecraft.item.ItemStack; + +public class RecipeGuiLogic implements IRecipeGuiLogic { + private static class State { + @Nonnull + public final IFocus focus; + @Nonnull + public final ImmutableList recipeCategories; + + public int recipeCategoryIndex; + public int pageIndex; + public int recipesPerPage; + + public State(IFocus focus, List recipeCategories, int recipeCategoryIndex, int pageIndex) { + this.focus = focus; + this.recipeCategories = ImmutableList.copyOf(recipeCategories); + this.recipeCategoryIndex = recipeCategoryIndex; + this.pageIndex = pageIndex; + } + } + + private final RecipeRegistry recipeRegistry; + private final IRecipeLogicStateListener stateListener; + + @Nullable + private State state = null; + private final Stack history = new Stack(); + + /** + * List of recipes for the currently selected recipeClass + */ + private List recipes = Collections.emptyList(); + + public RecipeGuiLogic(RecipeRegistry recipeRegistry, IRecipeLogicStateListener stateListener) { + this.recipeRegistry = recipeRegistry; + this.stateListener = stateListener; + } + + @Override + public boolean setFocus(IFocus focus) { + return setFocus(focus, true); + } + + @Override + public boolean back() { + if (history.empty()) { + return false; + } + final State state = history.pop(); + setState(state); + return true; + } + + @Override + public void clearHistory() { + while (!history.empty()) { + history.pop(); + } + } + + private boolean setFocus(IFocus focus, boolean saveHistory) { + final List recipeCategories = recipeRegistry.getRecipeCategories(focus); + if (recipeCategories.isEmpty()) { + return false; + } + + final int recipeCategoryIndex = getRecipeCategoryIndex(recipeCategories); + + if (this.state != null && saveHistory) { + history.push(this.state); + } + + final State state = new State(focus, recipeCategories, recipeCategoryIndex, 0); + setState(state); + + return true; + } + + private void setState(State state) { + this.state = state; + updateRecipes(); + stateListener.onStateChange(); + } + + private int getRecipeCategoryIndex(List recipeCategories) { + final Container container = Minecraft.getMinecraft().thePlayer.openContainer; + if (container == null) { + return 0; + } + + for (int i = 0; i < recipeCategories.size(); i++) { + IRecipeCategory recipeCategory = recipeCategories.get(i); + if (recipeRegistry.getRecipeTransferHandler(container, recipeCategory) != null) { + return i; + } + } + + return 0; + } + + @Override + public boolean setCategoryFocus() { + IRecipeCategory recipeCategory = getSelectedRecipeCategory(); + if (recipeCategory == null) { + return false; + } + + if (this.state != null) { + history.push(this.state); + } + + final List recipeCategories = recipeRegistry.getRecipeCategories(); + final int recipeCategoryIndex = recipeCategories.indexOf(recipeCategory); + IFocus focus = recipeRegistry.createFocus(IFocus.Mode.NONE, null); + final State state = new State(focus, recipeCategories, recipeCategoryIndex, 0); + setState(state); + + return true; + } + + @Override + public boolean setCategoryFocus(List recipeCategoryUids) { + List recipeCategories = recipeRegistry.getRecipeCategories(recipeCategoryUids); + if (recipeCategories.isEmpty()) { + return false; + } + + if (this.state != null) { + history.push(this.state); + } + + IFocus focus = recipeRegistry.createFocus(IFocus.Mode.NONE, null); + final State state = new State(focus, recipeCategories, 0, 0); + setState(state); + + return true; + } + + @Override + public IFocus getFocus() { + if (state == null) { + return null; + } + return state.focus; + } + + @Override + public List getRecipeCategoryCraftingItems() { + IRecipeCategory category = getSelectedRecipeCategory(); + if (category == null) { + return Collections.emptyList(); + } + return recipeRegistry.getCraftingItems(category, getFocus()); + } + + @Override + public List getRecipeCategoryCraftingItems(IRecipeCategory recipeCategory) { + return recipeRegistry.getCraftingItems(recipeCategory, getFocus()); + } + + @Override + public void setRecipesPerPage(int recipesPerPage) { + if (state == null) { + return; + } + if (state.recipesPerPage != recipesPerPage) { + int recipeIndex = state.pageIndex * state.recipesPerPage; + state.pageIndex = recipeIndex / recipesPerPage; + + state.recipesPerPage = recipesPerPage; + updateRecipes(); + } + } + + private void updateRecipes() { + if (state == null) { + return; + } + + final IRecipeCategory recipeCategory = getSelectedRecipeCategory(); + if (recipeCategory == null) { + recipes = Collections.emptyList(); + } else { + IFocus focus = state.focus; + //noinspection unchecked + this.recipes = recipeRegistry.getRecipeWrappers(recipeCategory, focus); + } + } + + @Override + @Nullable + public IRecipeCategory getSelectedRecipeCategory() { + if (state == null || state.recipeCategories.size() == 0) { + return null; + } + return state.recipeCategories.get(state.recipeCategoryIndex); + } + + @Override + public ImmutableList getRecipeCategories() { + if (state == null) { + return ImmutableList.of(); + } + return state.recipeCategories; + } + + @Override + public List getRecipeWidgets(int posX, int posY, int spacingY) { + if (state == null) { + return Collections.emptyList(); + } + + List recipeWidgets = new ArrayList(); + + IRecipeCategory recipeCategory = getSelectedRecipeCategory(); + if (recipeCategory == null) { + return recipeWidgets; + } + + int recipeWidgetIndex = 0; + for (int recipeIndex = state.pageIndex * state.recipesPerPage; recipeIndex < recipes.size() && recipeWidgets.size() < state.recipesPerPage; recipeIndex++) { + IRecipeWrapper recipeWrapper = recipes.get(recipeIndex); + if (recipeWrapper == null) { + continue; + } + + RecipeLayout recipeWidget = new RecipeLayout(recipeWidgetIndex++, posX, posY, recipeCategory, recipeWrapper, state.focus); + recipeWidgets.add(recipeWidget); + + posY += spacingY; + } + + return recipeWidgets; + } + + @Override + public void nextRecipeCategory() { + if (state == null) { + return; + } + final int recipesTypesCount = state.recipeCategories.size(); + state.recipeCategoryIndex = (state.recipeCategoryIndex + 1) % recipesTypesCount; + state.pageIndex = 0; + updateRecipes(); + stateListener.onStateChange(); + } + + @Override + public void setRecipeCategory(IRecipeCategory category) { + if (state == null) { + return; + } + + int index = state.recipeCategories.indexOf(category); + if (index < 0) { + return; + } + + state.recipeCategoryIndex = index; + state.pageIndex = 0; + updateRecipes(); + stateListener.onStateChange(); + } + + @Override + public boolean hasMultiplePages() { + return state != null && recipes.size() > state.recipesPerPage; + } + + @Override + public void previousRecipeCategory() { + if (state == null) { + return; + } + final int recipesTypesCount = state.recipeCategories.size(); + state.recipeCategoryIndex = (recipesTypesCount + state.recipeCategoryIndex - 1) % recipesTypesCount; + state.pageIndex = 0; + updateRecipes(); + stateListener.onStateChange(); + } + + @Override + public void nextPage() { + if (state == null) { + return; + } + int pageCount = pageCount(state.recipesPerPage); + state.pageIndex = (state.pageIndex + 1) % pageCount; + stateListener.onStateChange(); + } + + @Override + public void previousPage() { + if (state == null) { + return; + } + int pageCount = pageCount(state.recipesPerPage); + state.pageIndex = (pageCount + state.pageIndex - 1) % pageCount; + stateListener.onStateChange(); + } + + private int pageCount(int recipesPerPage) { + if (recipes.size() <= 1) { + return 1; + } + + return MathUtil.divideCeil(recipes.size(), recipesPerPage); + } + + @Override + public String getPageString() { + if (state == null) { + return "1/1"; + } + return (state.pageIndex + 1) + "/" + pageCount(state.recipesPerPage); + } + + @Override + public boolean hasMultipleCategories() { + return state != null && state.recipeCategories.size() > 1; + } + + @Override + public boolean hasAllCategories() { + return state != null && state.recipeCategories.size() == recipeRegistry.getRecipeCategoryCount(); + } +} diff --git a/src/main/java/mezz/jei/gui/recipes/RecipeGuiTab.java b/src/main/java/mezz/jei/gui/recipes/RecipeGuiTab.java new file mode 100644 index 000000000..062712972 --- /dev/null +++ b/src/main/java/mezz/jei/gui/recipes/RecipeGuiTab.java @@ -0,0 +1,48 @@ +package mezz.jei.gui.recipes; + +import javax.annotation.Nullable; + +import mezz.jei.Internal; +import mezz.jei.api.gui.IDrawable; +import mezz.jei.api.recipe.IRecipeCategory; +import mezz.jei.gui.GuiHelper; +import mezz.jei.input.IMouseHandler; +import net.minecraft.client.Minecraft; +import net.minecraftforge.fml.client.config.HoverChecker; + +public abstract class RecipeGuiTab implements IMouseHandler { + public static final int TAB_HEIGHT = 24; + public static final int TAB_WIDTH = 24; + + protected final int x; + protected final int y; + private final HoverChecker hoverChecker; + + public RecipeGuiTab(int x, int y) { + this.x = x; + this.y = y; + this.hoverChecker = new HoverChecker(y, y + TAB_HEIGHT, x, x + TAB_WIDTH, 0); + } + + @Override + public boolean isMouseOver(int mouseX, int mouseY) { + return hoverChecker.checkHover(mouseX, mouseY); + } + + @Override + public boolean handleMouseScrolled(int mouseX, int mouseY, int scrollDelta) { + return false; + } + + public abstract boolean isSelected(IRecipeCategory selectedCategory); + + public void draw(Minecraft minecraft, boolean selected, int mouseX, int mouseY) { + GuiHelper guiHelper = Internal.getHelpers().getGuiHelper(); + IDrawable tab = selected ? guiHelper.getTabSelected() : guiHelper.getTabUnselected(); + + tab.draw(minecraft, x, y); + } + + @Nullable + public abstract String getTooltip(); +} diff --git a/src/main/java/mezz/jei/gui/recipes/RecipeGuiTabs.java b/src/main/java/mezz/jei/gui/recipes/RecipeGuiTabs.java new file mode 100644 index 000000000..156070c61 --- /dev/null +++ b/src/main/java/mezz/jei/gui/recipes/RecipeGuiTabs.java @@ -0,0 +1,236 @@ +package mezz.jei.gui.recipes; + +import java.util.ArrayList; +import java.util.List; + +import com.google.common.collect.ImmutableList; +import mezz.jei.api.recipe.IRecipeCategory; +import mezz.jei.gui.GuiProperties; +import mezz.jei.gui.TooltipRenderer; +import mezz.jei.input.IMouseHandler; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GlStateManager; + +/** + * The area drawn on top of the {@link RecipesGui} that show the recipe categories. + */ +public class RecipeGuiTabs implements IMouseHandler { + private final IRecipeGuiLogic recipeGuiLogic; + + private int pageCount = 1; + private int pageNumber = 0; + private int categoriesPerPage = 1; + private int left; + private int top; + private int width; + private int height; + private List tabs = new ArrayList(); + + + public RecipeGuiTabs(IRecipeGuiLogic recipeGuiLogic) { + this.recipeGuiLogic = recipeGuiLogic; + } + + public void updateLayout(GuiProperties guiProperties) { + ImmutableList categories = recipeGuiLogic.getRecipeCategories(); + if (!categories.isEmpty()) { + int totalWidth = 0; + categoriesPerPage = 0; + + for (int i = 0; i < categories.size(); i++) { + if (totalWidth + RecipeGuiTab.TAB_WIDTH <= (guiProperties.getGuiXSize() - 4)) { + totalWidth += RecipeGuiTab.TAB_WIDTH; + categoriesPerPage++; + } else { + break; + } + } + + width = totalWidth; + height = RecipeGuiTab.TAB_HEIGHT; + left = guiProperties.getGuiLeft() + 2; + top = guiProperties.getGuiTop() - RecipeGuiTab.TAB_HEIGHT + 3; // overlaps the recipe gui slightly + + pageCount = getPageCount(categories.size(), categoriesPerPage); + + IRecipeCategory currentCategory = recipeGuiLogic.getSelectedRecipeCategory(); + int categoryIndex = categories.indexOf(currentCategory); + pageNumber = getPageNumber(categoryIndex, pageCount, categoriesPerPage); + + createTabs(); + } + } + + private static int getPageCount(int categoryCount, final int categoriesPerPage) { + int pageCount = 0; + while (categoryCount > 0) { + int availableCategories = categoriesPerPage; + if (pageCount > 0) { + availableCategories--; // back button + } + + if (categoryCount > availableCategories) { + availableCategories--; // next button + } + categoryCount -= availableCategories; + pageCount++; + } + + return pageCount; + } + + private static int getFirstCategoryIndex(final int pageNumber, final int pageCount, final int categoriesPerPage) { + int categoryIndex = 0; + + for (int i = 0; i < pageNumber; i++) { + int availableCategories = categoriesPerPage; + if (i > 0) { + availableCategories--; // back button + } + + if (i + 1 < pageCount) { + availableCategories--; // next button + } + + categoryIndex += availableCategories; + } + + return categoryIndex; + } + + private static int getPageNumber(final int categoryIndex, final int pageCount, final int categoriesPerPage) { + int currentCategoryIndex = 0; + for (int pageNumber = 0; pageNumber < pageCount; pageNumber++) { + int availableCategories = categoriesPerPage; + if (pageNumber > 0) { + availableCategories--; // back button + } + + if (pageNumber + 1 < pageCount) { + availableCategories--; // next button + } + + currentCategoryIndex += availableCategories; + if (currentCategoryIndex > categoryIndex) { + return pageNumber; + } + } + + return 0; + } + + private void createTabs() { + tabs.clear(); + + ImmutableList categories = recipeGuiLogic.getRecipeCategories(); + + boolean nextButton = false; + boolean prevButton = false; + + int categoryCount = categoriesPerPage; + if (categories.size() > categoryCount) { + if (pageNumber + 1 < pageCount) { + nextButton = true; + categoryCount--; + } + if (pageNumber > 0) { + prevButton = true; + categoryCount--; + } + } + + int tabX = this.left; + + if (prevButton) { + RecipeArrowTab tab = new RecipeArrowTab(this, false, tabX, top); + this.tabs.add(tab); + tabX += RecipeGuiTab.TAB_WIDTH; + } + + final int startIndex = getFirstCategoryIndex(pageNumber, pageCount, categoriesPerPage); + for (int i = 0; i < categoryCount; i++) { + int index = i + startIndex; + if (index >= categories.size()) { + break; + } + IRecipeCategory category = categories.get(index); + RecipeGuiTab tab = new RecipeCategoryTab(recipeGuiLogic, category, tabX, top); + this.tabs.add(tab); + tabX += RecipeGuiTab.TAB_WIDTH; + } + + if (nextButton) { + RecipeArrowTab tab = new RecipeArrowTab(this, true, tabX, top); + this.tabs.add(tab); + } + } + + public void draw(Minecraft minecraft, int mouseX, int mouseY) { + IRecipeCategory selectedCategory = recipeGuiLogic.getSelectedRecipeCategory(); + if (selectedCategory == null) { + return; + } + + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + + RecipeGuiTab hovered = null; + + GlStateManager.disableDepth(); + GlStateManager.enableAlpha(); + { + for (RecipeGuiTab tab : tabs) { + boolean selected = tab.isSelected(selectedCategory); + tab.draw(minecraft, selected, mouseX, mouseY); + if (tab.isMouseOver(mouseX, mouseY)) { + hovered = tab; + } + } + } + GlStateManager.disableAlpha(); + GlStateManager.enableDepth(); + + if (hovered != null) { + String tooltip = hovered.getTooltip(); + if (tooltip != null) { + TooltipRenderer.drawHoveringText(minecraft, tooltip, mouseX, mouseY); + } + } + } + + @Override + public boolean isMouseOver(int mouseX, int mouseY) { + return (mouseX > left && mouseX < (left + width)) && (mouseY > top && mouseY < (top + height)); + } + + @Override + public boolean handleMouseClicked(int mouseX, int mouseY, int mouseButton) { + if (mouseButton == 0) { + for (RecipeGuiTab tab : tabs) { + if (tab.isMouseOver(mouseX, mouseY)) { + tab.handleMouseClicked(mouseX, mouseY, mouseButton); + return true; + } + } + } + return false; + } + + @Override + public boolean handleMouseScrolled(int mouseX, int mouseY, int scrollDelta) { + return false; + } + + public void nextPage() { + if (pageNumber + 1 < pageCount) { + pageNumber++; + createTabs(); + } + } + + public void prevPage() { + if (pageNumber > 0) { + pageNumber--; + createTabs(); + } + } +} \ No newline at end of file diff --git a/src/main/java/mezz/jei/gui/RecipeLayout.java b/src/main/java/mezz/jei/gui/recipes/RecipeLayout.java similarity index 96% rename from src/main/java/mezz/jei/gui/RecipeLayout.java rename to src/main/java/mezz/jei/gui/recipes/RecipeLayout.java index c141f2d4b..9bdc776c9 100644 --- a/src/main/java/mezz/jei/gui/RecipeLayout.java +++ b/src/main/java/mezz/jei/gui/recipes/RecipeLayout.java @@ -1,208 +1,210 @@ -package mezz.jei.gui; - -import javax.annotation.Nullable; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import mezz.jei.api.gui.IDrawable; -import mezz.jei.api.gui.IGuiFluidStackGroup; -import mezz.jei.api.gui.IGuiIngredientGroup; -import mezz.jei.api.gui.IRecipeLayout; -import mezz.jei.api.ingredients.IIngredients; -import mezz.jei.api.recipe.IFocus; -import mezz.jei.api.recipe.IRecipeCategory; -import mezz.jei.api.recipe.IRecipeWrapper; -import mezz.jei.gui.ingredients.GuiFluidStackGroup; -import mezz.jei.gui.ingredients.GuiIngredient; -import mezz.jei.gui.ingredients.GuiIngredientGroup; -import mezz.jei.gui.ingredients.GuiItemStackGroup; -import mezz.jei.input.IClickedIngredient; -import mezz.jei.util.Ingredients; -import mezz.jei.util.Log; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.item.ItemStack; -import net.minecraftforge.fluids.FluidStack; - -public class RecipeLayout implements IRecipeLayout { - private static final int RECIPE_BUTTON_SIZE = 12; - public static final int recipeTransferButtonIndex = 100; - - private final IRecipeCategory recipeCategory; - private final GuiItemStackGroup guiItemStackGroup; - private final GuiFluidStackGroup guiFluidStackGroup; - private final Map guiIngredientGroups; - private final RecipeTransferButton recipeTransferButton; - private final IRecipeWrapper recipeWrapper; - private final IFocus focus; - - private final int posX; - private final int posY; - - public RecipeLayout(int index, int posX, int posY, IRecipeCategory recipeCategory, T recipeWrapper, IFocus focus) { - this.recipeCategory = recipeCategory; - this.focus = focus; - - ItemStack itemStackFocus = null; - FluidStack fluidStackFocus = null; - Object focusValue = focus.getValue(); - if (focusValue instanceof ItemStack) { - itemStackFocus = (ItemStack) focusValue; - } else if (focusValue instanceof FluidStack) { - fluidStackFocus = (FluidStack) focusValue; - } - this.guiItemStackGroup = new GuiItemStackGroup(new Focus(focus.getMode(), itemStackFocus)); - this.guiFluidStackGroup = new GuiFluidStackGroup(new Focus(focus.getMode(), fluidStackFocus)); - - this.guiIngredientGroups = new HashMap(); - this.guiIngredientGroups.put(ItemStack.class, this.guiItemStackGroup); - this.guiIngredientGroups.put(FluidStack.class, this.guiFluidStackGroup); - - int width = recipeCategory.getBackground().getWidth(); - int height = recipeCategory.getBackground().getHeight(); - this.recipeTransferButton = new RecipeTransferButton(recipeTransferButtonIndex + index, posX + width + 2, posY + height - RECIPE_BUTTON_SIZE, RECIPE_BUTTON_SIZE, RECIPE_BUTTON_SIZE, "+"); - this.posX = posX; - this.posY = posY; - - this.recipeWrapper = recipeWrapper; - - try { - try { - IIngredients ingredients = new Ingredients(); - recipeWrapper.getIngredients(ingredients); - recipeCategory.setRecipe(this, recipeWrapper, ingredients); - } catch (AbstractMethodError ignored) { // legacy - recipeCategory.setRecipe(this, recipeWrapper); - } - } catch (RuntimeException e) { - Log.error("Error caught from Recipe Category: {}", recipeCategory.getClass().getCanonicalName(), e); - } catch (LinkageError e) { - Log.error("Error caught from Recipe Category: {}", recipeCategory.getClass().getCanonicalName(), e); - } - } - - public void draw(Minecraft minecraft, final int mouseX, final int mouseY) { - IDrawable background = recipeCategory.getBackground(); - - GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); - GlStateManager.disableLighting(); - GlStateManager.enableAlpha(); - - final int recipeMouseX = mouseX - posX; - final int recipeMouseY = mouseY - posY; - - GlStateManager.pushMatrix(); - GlStateManager.translate(posX, posY, 0.0F); - { - background.draw(minecraft); - recipeCategory.drawExtras(minecraft); - recipeCategory.drawAnimations(minecraft); - recipeWrapper.drawAnimations(minecraft, background.getWidth(), background.getHeight()); - recipeWrapper.drawInfo(minecraft, background.getWidth(), background.getHeight(), recipeMouseX, recipeMouseY); - } - GlStateManager.popMatrix(); - - GuiIngredient hoveredIngredient = null; - for (GuiIngredientGroup guiIngredientGroup : guiIngredientGroups.values()) { - GuiIngredient hovered = guiIngredientGroup.draw(minecraft, posX, posY, mouseX, mouseY); - if (hovered != null) { - hoveredIngredient = hovered; - } - } - - recipeTransferButton.drawButton(minecraft, mouseX, mouseY); - GlStateManager.disableBlend(); - GlStateManager.disableLighting(); - - if (hoveredIngredient != null) { - hoveredIngredient.drawHovered(minecraft, posX, posY, recipeMouseX, recipeMouseY); - } else if (isMouseOver(mouseX, mouseY)) { - List tooltipStrings = recipeWrapper.getTooltipStrings(recipeMouseX, recipeMouseY); - if (tooltipStrings != null && !tooltipStrings.isEmpty()) { - TooltipRenderer.drawHoveringText(minecraft, tooltipStrings, mouseX, mouseY); - } - } - - GlStateManager.disableAlpha(); - } - - public boolean isMouseOver(int mouseX, int mouseY) { - final int recipeMouseX = mouseX - posX; - final int recipeMouseY = mouseY - posY; - final IDrawable background = recipeCategory.getBackground(); - return recipeMouseX >= 0 && recipeMouseX < background.getWidth() && recipeMouseY >= 0 && recipeMouseY < background.getHeight(); - } - - @Nullable - public IClickedIngredient getIngredientUnderMouse(int mouseX, int mouseY) { - IClickedIngredient clicked = guiItemStackGroup.getIngredientUnderMouse(posX, posY, mouseX, mouseY); - if (clicked == null) { - clicked = guiFluidStackGroup.getIngredientUnderMouse(posX, posY, mouseX, mouseY); - } - return clicked; - } - - public boolean handleClick(Minecraft minecraft, int mouseX, int mouseY, int mouseButton) { - return recipeWrapper.handleClick(minecraft, mouseX - posX, mouseY - posY, mouseButton); - } - - @Override - public GuiItemStackGroup getItemStacks() { - return guiItemStackGroup; - } - - @Override - public IGuiFluidStackGroup getFluidStacks() { - return guiFluidStackGroup; - } - - @Override - public IGuiIngredientGroup getIngredientsGroup(Class ingredientClass) { - //noinspection unchecked - GuiIngredientGroup guiIngredientGroup = guiIngredientGroups.get(ingredientClass); - if (guiIngredientGroup == null) { - T value = null; - Object focusValue = this.focus.getValue(); - if (ingredientClass.isInstance(focusValue)) { - //noinspection unchecked - value = (T) focusValue; - } - IFocus focus = new Focus(this.focus.getMode(), value); - guiIngredientGroup = new GuiIngredientGroup(ingredientClass, focus); - guiIngredientGroups.put(ingredientClass, guiIngredientGroup); - } - return guiIngredientGroup; - } - - @Override - public void setRecipeTransferButton(int posX, int posY) { - recipeTransferButton.xPosition = posX + this.posX; - recipeTransferButton.yPosition = posY + this.posY; - } - - @Override - public IFocus getFocus() { - return focus; - } - - public RecipeTransferButton getRecipeTransferButton() { - return recipeTransferButton; - } - - public IRecipeWrapper getRecipeWrapper() { - return recipeWrapper; - } - - public IRecipeCategory getRecipeCategory() { - return recipeCategory; - } - - public int getPosX() { - return posX; - } - - public int getPosY() { - return posY; - } -} +package mezz.jei.gui.recipes; + +import javax.annotation.Nullable; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import mezz.jei.api.gui.IDrawable; +import mezz.jei.api.gui.IGuiFluidStackGroup; +import mezz.jei.api.gui.IGuiIngredientGroup; +import mezz.jei.api.gui.IRecipeLayout; +import mezz.jei.api.ingredients.IIngredients; +import mezz.jei.api.recipe.IFocus; +import mezz.jei.api.recipe.IRecipeCategory; +import mezz.jei.api.recipe.IRecipeWrapper; +import mezz.jei.gui.Focus; +import mezz.jei.gui.TooltipRenderer; +import mezz.jei.gui.ingredients.GuiFluidStackGroup; +import mezz.jei.gui.ingredients.GuiIngredient; +import mezz.jei.gui.ingredients.GuiIngredientGroup; +import mezz.jei.gui.ingredients.GuiItemStackGroup; +import mezz.jei.input.IClickedIngredient; +import mezz.jei.util.Ingredients; +import mezz.jei.util.Log; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; + +public class RecipeLayout implements IRecipeLayout { + private static final int RECIPE_BUTTON_SIZE = 12; + public static final int recipeTransferButtonIndex = 100; + + private final IRecipeCategory recipeCategory; + private final GuiItemStackGroup guiItemStackGroup; + private final GuiFluidStackGroup guiFluidStackGroup; + private final Map guiIngredientGroups; + private final RecipeTransferButton recipeTransferButton; + private final IRecipeWrapper recipeWrapper; + private final IFocus focus; + + private final int posX; + private final int posY; + + public RecipeLayout(int index, int posX, int posY, IRecipeCategory recipeCategory, T recipeWrapper, IFocus focus) { + this.recipeCategory = recipeCategory; + this.focus = focus; + + ItemStack itemStackFocus = null; + FluidStack fluidStackFocus = null; + Object focusValue = focus.getValue(); + if (focusValue instanceof ItemStack) { + itemStackFocus = (ItemStack) focusValue; + } else if (focusValue instanceof FluidStack) { + fluidStackFocus = (FluidStack) focusValue; + } + this.guiItemStackGroup = new GuiItemStackGroup(new Focus(focus.getMode(), itemStackFocus)); + this.guiFluidStackGroup = new GuiFluidStackGroup(new Focus(focus.getMode(), fluidStackFocus)); + + this.guiIngredientGroups = new HashMap(); + this.guiIngredientGroups.put(ItemStack.class, this.guiItemStackGroup); + this.guiIngredientGroups.put(FluidStack.class, this.guiFluidStackGroup); + + int width = recipeCategory.getBackground().getWidth(); + int height = recipeCategory.getBackground().getHeight(); + this.recipeTransferButton = new RecipeTransferButton(recipeTransferButtonIndex + index, posX + width + 2, posY + height - RECIPE_BUTTON_SIZE, RECIPE_BUTTON_SIZE, RECIPE_BUTTON_SIZE, "+"); + this.posX = posX; + this.posY = posY; + + this.recipeWrapper = recipeWrapper; + + try { + try { + IIngredients ingredients = new Ingredients(); + recipeWrapper.getIngredients(ingredients); + recipeCategory.setRecipe(this, recipeWrapper, ingredients); + } catch (AbstractMethodError ignored) { // legacy + recipeCategory.setRecipe(this, recipeWrapper); + } + } catch (RuntimeException e) { + Log.error("Error caught from Recipe Category: {}", recipeCategory.getClass().getCanonicalName(), e); + } catch (LinkageError e) { + Log.error("Error caught from Recipe Category: {}", recipeCategory.getClass().getCanonicalName(), e); + } + } + + public void draw(Minecraft minecraft, final int mouseX, final int mouseY) { + IDrawable background = recipeCategory.getBackground(); + + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + GlStateManager.disableLighting(); + GlStateManager.enableAlpha(); + + final int recipeMouseX = mouseX - posX; + final int recipeMouseY = mouseY - posY; + + GlStateManager.pushMatrix(); + GlStateManager.translate(posX, posY, 0.0F); + { + background.draw(minecraft); + recipeCategory.drawExtras(minecraft); + recipeCategory.drawAnimations(minecraft); + recipeWrapper.drawAnimations(minecraft, background.getWidth(), background.getHeight()); + recipeWrapper.drawInfo(minecraft, background.getWidth(), background.getHeight(), recipeMouseX, recipeMouseY); + } + GlStateManager.popMatrix(); + + GuiIngredient hoveredIngredient = null; + for (GuiIngredientGroup guiIngredientGroup : guiIngredientGroups.values()) { + GuiIngredient hovered = guiIngredientGroup.draw(minecraft, posX, posY, mouseX, mouseY); + if (hovered != null) { + hoveredIngredient = hovered; + } + } + + recipeTransferButton.drawButton(minecraft, mouseX, mouseY); + GlStateManager.disableBlend(); + GlStateManager.disableLighting(); + + if (hoveredIngredient != null) { + hoveredIngredient.drawHovered(minecraft, posX, posY, recipeMouseX, recipeMouseY); + } else if (isMouseOver(mouseX, mouseY)) { + List tooltipStrings = recipeWrapper.getTooltipStrings(recipeMouseX, recipeMouseY); + if (tooltipStrings != null && !tooltipStrings.isEmpty()) { + TooltipRenderer.drawHoveringText(minecraft, tooltipStrings, mouseX, mouseY); + } + } + + GlStateManager.disableAlpha(); + } + + public boolean isMouseOver(int mouseX, int mouseY) { + final int recipeMouseX = mouseX - posX; + final int recipeMouseY = mouseY - posY; + final IDrawable background = recipeCategory.getBackground(); + return recipeMouseX >= 0 && recipeMouseX < background.getWidth() && recipeMouseY >= 0 && recipeMouseY < background.getHeight(); + } + + @Nullable + public IClickedIngredient getIngredientUnderMouse(int mouseX, int mouseY) { + IClickedIngredient clicked = guiItemStackGroup.getIngredientUnderMouse(posX, posY, mouseX, mouseY); + if (clicked == null) { + clicked = guiFluidStackGroup.getIngredientUnderMouse(posX, posY, mouseX, mouseY); + } + return clicked; + } + + public boolean handleClick(Minecraft minecraft, int mouseX, int mouseY, int mouseButton) { + return recipeWrapper.handleClick(minecraft, mouseX - posX, mouseY - posY, mouseButton); + } + + @Override + public GuiItemStackGroup getItemStacks() { + return guiItemStackGroup; + } + + @Override + public IGuiFluidStackGroup getFluidStacks() { + return guiFluidStackGroup; + } + + @Override + public IGuiIngredientGroup getIngredientsGroup(Class ingredientClass) { + //noinspection unchecked + GuiIngredientGroup guiIngredientGroup = guiIngredientGroups.get(ingredientClass); + if (guiIngredientGroup == null) { + T value = null; + Object focusValue = this.focus.getValue(); + if (ingredientClass.isInstance(focusValue)) { + //noinspection unchecked + value = (T) focusValue; + } + IFocus focus = new Focus(this.focus.getMode(), value); + guiIngredientGroup = new GuiIngredientGroup(ingredientClass, focus); + guiIngredientGroups.put(ingredientClass, guiIngredientGroup); + } + return guiIngredientGroup; + } + + @Override + public void setRecipeTransferButton(int posX, int posY) { + recipeTransferButton.xPosition = posX + this.posX; + recipeTransferButton.yPosition = posY + this.posY; + } + + @Override + public IFocus getFocus() { + return focus; + } + + public RecipeTransferButton getRecipeTransferButton() { + return recipeTransferButton; + } + + public IRecipeWrapper getRecipeWrapper() { + return recipeWrapper; + } + + public IRecipeCategory getRecipeCategory() { + return recipeCategory; + } + + public int getPosX() { + return posX; + } + + public int getPosY() { + return posY; + } +} diff --git a/src/main/java/mezz/jei/gui/RecipeTransferButton.java b/src/main/java/mezz/jei/gui/recipes/RecipeTransferButton.java similarity index 95% rename from src/main/java/mezz/jei/gui/RecipeTransferButton.java rename to src/main/java/mezz/jei/gui/recipes/RecipeTransferButton.java index b469ecd00..e59c66925 100644 --- a/src/main/java/mezz/jei/gui/RecipeTransferButton.java +++ b/src/main/java/mezz/jei/gui/recipes/RecipeTransferButton.java @@ -1,53 +1,54 @@ -package mezz.jei.gui; - -import javax.annotation.Nullable; - -import mezz.jei.api.recipe.transfer.IRecipeTransferError; -import mezz.jei.config.Constants; -import mezz.jei.transfer.RecipeTransferErrorInternal; -import mezz.jei.transfer.RecipeTransferUtil; -import net.minecraft.client.Minecraft; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.inventory.Container; -import net.minecraftforge.fml.client.config.GuiButtonExt; - -public class RecipeTransferButton extends GuiButtonExt { - private RecipeLayout recipeLayout; - @Nullable - private IRecipeTransferError recipeTransferError; - - public RecipeTransferButton(int id, int xPos, int yPos, int width, int height, String displayString) { - super(id, xPos, yPos, width, height, displayString); - } - - public void init(@Nullable Container container, RecipeLayout recipeLayout, EntityPlayer player) { - this.recipeLayout = recipeLayout; - - if (container != null) { - this.recipeTransferError = RecipeTransferUtil.getTransferRecipeError(container, recipeLayout, player); - } else { - this.recipeTransferError = RecipeTransferErrorInternal.INSTANCE; - } - - if (this.recipeTransferError == null) { - this.enabled = true; - this.visible = true; - } else { - this.enabled = false; - IRecipeTransferError.Type type = this.recipeTransferError.getType(); - this.visible = (type == IRecipeTransferError.Type.USER_FACING); - } - } - - @Override - public void drawButton(Minecraft mc, int mouseX, int mouseY) { - super.drawButton(mc, mouseX, mouseY); - if (hovered && visible) { - if (recipeTransferError != null) { - recipeTransferError.showError(mc, mouseX, mouseY, recipeLayout, recipeLayout.getPosX(), recipeLayout.getPosY()); - } else { - TooltipRenderer.drawHoveringText(mc, Constants.RECIPE_TRANSFER_TOOLTIP, mouseX, mouseY); - } - } - } -} +package mezz.jei.gui.recipes; + +import javax.annotation.Nullable; + +import mezz.jei.api.recipe.transfer.IRecipeTransferError; +import mezz.jei.config.Constants; +import mezz.jei.gui.TooltipRenderer; +import mezz.jei.transfer.RecipeTransferErrorInternal; +import mezz.jei.transfer.RecipeTransferUtil; +import net.minecraft.client.Minecraft; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.Container; +import net.minecraftforge.fml.client.config.GuiButtonExt; + +public class RecipeTransferButton extends GuiButtonExt { + private RecipeLayout recipeLayout; + @Nullable + private IRecipeTransferError recipeTransferError; + + public RecipeTransferButton(int id, int xPos, int yPos, int width, int height, String displayString) { + super(id, xPos, yPos, width, height, displayString); + } + + public void init(@Nullable Container container, RecipeLayout recipeLayout, EntityPlayer player) { + this.recipeLayout = recipeLayout; + + if (container != null) { + this.recipeTransferError = RecipeTransferUtil.getTransferRecipeError(container, recipeLayout, player); + } else { + this.recipeTransferError = RecipeTransferErrorInternal.INSTANCE; + } + + if (this.recipeTransferError == null) { + this.enabled = true; + this.visible = true; + } else { + this.enabled = false; + IRecipeTransferError.Type type = this.recipeTransferError.getType(); + this.visible = (type == IRecipeTransferError.Type.USER_FACING); + } + } + + @Override + public void drawButton(Minecraft mc, int mouseX, int mouseY) { + super.drawButton(mc, mouseX, mouseY); + if (hovered && visible) { + if (recipeTransferError != null) { + recipeTransferError.showError(mc, mouseX, mouseY, recipeLayout, recipeLayout.getPosX(), recipeLayout.getPosY()); + } else { + TooltipRenderer.drawHoveringText(mc, Constants.RECIPE_TRANSFER_TOOLTIP, mouseX, mouseY); + } + } + } +} diff --git a/src/main/java/mezz/jei/gui/RecipesGui.java b/src/main/java/mezz/jei/gui/recipes/RecipesGui.java similarity index 87% rename from src/main/java/mezz/jei/gui/RecipesGui.java rename to src/main/java/mezz/jei/gui/recipes/RecipesGui.java index 3aa561148..0f3d57ca2 100644 --- a/src/main/java/mezz/jei/gui/RecipesGui.java +++ b/src/main/java/mezz/jei/gui/recipes/RecipesGui.java @@ -1,457 +1,467 @@ -package mezz.jei.gui; - -import javax.annotation.Nullable; -import java.awt.Color; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import mezz.jei.RecipeRegistry; -import mezz.jei.api.IRecipesGui; -import mezz.jei.api.gui.IDrawable; -import mezz.jei.api.recipe.IFocus; -import mezz.jei.api.recipe.IRecipeCategory; -import mezz.jei.config.Constants; -import mezz.jei.config.KeyBindings; -import mezz.jei.gui.ingredients.GuiIngredient; -import mezz.jei.input.IClickedIngredient; -import mezz.jei.input.IShowsRecipeFocuses; -import mezz.jei.input.InputHandler; -import mezz.jei.transfer.RecipeTransferUtil; -import mezz.jei.util.Log; -import mezz.jei.util.StringUtil; -import mezz.jei.util.Translator; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiButton; -import net.minecraft.client.gui.GuiScreen; -import net.minecraft.client.gui.inventory.GuiContainer; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.inventory.Container; -import net.minecraft.item.ItemStack; -import net.minecraft.util.ResourceLocation; -import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fml.client.config.GuiButtonExt; -import net.minecraftforge.fml.client.config.HoverChecker; -import org.lwjgl.input.Mouse; - -public class RecipesGui extends GuiScreen implements IRecipesGui, IShowsRecipeFocuses { - private static final int borderPadding = 6; - private static final int innerPadding = 5; - private static final int textPadding = 5; - private static final int buttonWidth = 13; - private static final int buttonHeight = 12; - - private int titleHeight; - private int headerHeight; - - /* Internal logic for the gui, handles finding recipes */ - private final IRecipeGuiLogic logic; - - /* List of RecipeLayout to display */ - private final List recipeLayouts = new ArrayList(); - - private String pageString; - private String title; - private ResourceLocation backgroundTexture; - private final RecipeCategoryCraftingItemsArea recipeCategoryCraftingItemsArea; - - private HoverChecker titleHoverChecker; - - private GuiButton nextRecipeCategory; - private GuiButton previousRecipeCategory; - private GuiButton nextPage; - private GuiButton previousPage; - - @Nullable - private GuiScreen parentScreen; - private int xSize; - private int ySize; - private int guiLeft; - private int guiTop; - - public RecipesGui(RecipeRegistry recipeRegistry) { - this.logic = new RecipeGuiLogic(recipeRegistry); - this.recipeCategoryCraftingItemsArea = new RecipeCategoryCraftingItemsArea(recipeRegistry); - this.mc = Minecraft.getMinecraft(); - } - - public int getGuiLeft() { - return guiLeft; - } - - public int getGuiTop() { - return guiTop; - } - - public int getXSize() { - return xSize; - } - - public int getYSize() { - return ySize; - } - - @Override - public boolean doesGuiPauseGame() { - return false; - } - - @Override - public void initGui() { - super.initGui(); - - this.xSize = 176; - - ResourceLocation recipeBackgroundResource = new ResourceLocation(Constants.RESOURCE_DOMAIN, Constants.TEXTURE_RECIPE_BACKGROUND_PATH); - if (this.height > 300) { - this.ySize = 256; - this.backgroundTexture = new ResourceLocation(Constants.RESOURCE_DOMAIN, Constants.TEXTURE_RECIPE_BACKGROUND_TALL_PATH); - } else { - this.ySize = 166; - this.backgroundTexture = recipeBackgroundResource; - } - - this.guiLeft = (width - this.xSize) / 2; - this.guiTop = (height - this.ySize) / 2; - - this.titleHeight = fontRendererObj.FONT_HEIGHT + borderPadding; - this.headerHeight = titleHeight + fontRendererObj.FONT_HEIGHT + textPadding; - - final int rightButtonX = guiLeft + xSize - borderPadding - buttonWidth; - final int leftButtonX = guiLeft + borderPadding; - - int recipeClassButtonTop = guiTop + titleHeight - buttonHeight + 1; - nextRecipeCategory = new GuiButtonExt(2, rightButtonX, recipeClassButtonTop, buttonWidth, buttonHeight, ">"); - previousRecipeCategory = new GuiButtonExt(3, leftButtonX, recipeClassButtonTop, buttonWidth, buttonHeight, "<"); - - int pageButtonTop = guiTop + titleHeight + 3; - nextPage = new GuiButtonExt(4, rightButtonX, pageButtonTop, buttonWidth, buttonHeight, ">"); - previousPage = new GuiButtonExt(5, leftButtonX, pageButtonTop, buttonWidth, buttonHeight, "<"); - - addButtons(); - - updateLayout(); - } - - private void addButtons() { - this.buttonList.add(nextRecipeCategory); - this.buttonList.add(previousRecipeCategory); - this.buttonList.add(nextPage); - this.buttonList.add(previousPage); - } - - @Override - public void drawScreen(int mouseX, int mouseY, float partialTicks) { - drawGuiContainerBackgroundLayer(partialTicks, mouseX, mouseY); - - GlStateManager.disableBlend(); - - drawRect(guiLeft + borderPadding + buttonWidth, - guiTop + borderPadding - 2, - guiLeft + xSize - borderPadding - buttonWidth, - guiTop + borderPadding + 10, - 0x30000000); - drawRect(guiLeft + borderPadding + buttonWidth, - guiTop + titleHeight + textPadding - 2, - guiLeft + xSize - borderPadding - buttonWidth, - guiTop + titleHeight + textPadding + 10, - 0x30000000); - - GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); - - StringUtil.drawCenteredString(fontRendererObj, title, xSize, guiLeft, guiTop + borderPadding, Color.WHITE.getRGB(), true); - StringUtil.drawCenteredString(fontRendererObj, pageString, xSize, guiLeft, guiTop + titleHeight + textPadding, Color.WHITE.getRGB(), true); - - nextRecipeCategory.drawButton(mc, mouseX, mouseY); - previousRecipeCategory.drawButton(mc, mouseX, mouseY); - nextPage.drawButton(mc, mouseX, mouseY); - previousPage.drawButton(mc, mouseX, mouseY); - - RecipeLayout hovered = null; - for (RecipeLayout recipeWidget : recipeLayouts) { - if (recipeWidget.isMouseOver(mouseX, mouseY)) { - hovered = recipeWidget; - } else { - recipeWidget.draw(mc, mouseX, mouseY); - } - } - - GuiIngredient hoveredItemStack = recipeCategoryCraftingItemsArea.draw(mc, mouseX, mouseY); - - if (hovered != null) { - hovered.draw(mc, mouseX, mouseY); - } - if (hoveredItemStack != null) { - hoveredItemStack.drawHovered(mc, 0, 0, mouseX, mouseY); - } - - if (titleHoverChecker.checkHover(mouseX, mouseY)) { - if (!logic.hasAllCategories()) { - String showAllRecipesString = Translator.translateToLocal("jei.tooltip.show.all.recipes"); - TooltipRenderer.drawHoveringText(mc, showAllRecipesString, mouseX, mouseY); - } - } - } - - protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) { - drawDefaultBackground(); - GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); - mc.getTextureManager().bindTexture(backgroundTexture); - int x = (width - xSize) / 2; - int y = (height - ySize) / 2; - this.zLevel = 0; - drawTexturedModalRect(x, y, 0, 0, xSize, ySize); - } - - public boolean isMouseOver(int mouseX, int mouseY) { - return mc.currentScreen == this && (mouseX >= guiLeft) && (mouseY >= guiTop) && (mouseX < guiLeft + xSize) && (mouseY < guiTop + ySize); - } - - @Nullable - @Override - public IClickedIngredient getIngredientUnderMouse(int mouseX, int mouseY) { - if (isOpen()) { - IClickedIngredient clicked = recipeCategoryCraftingItemsArea.getIngredientUnderMouse(mouseX, mouseY); - if (clicked != null) { - return clicked; - } - - if (isMouseOver(mouseX, mouseY)) { - for (RecipeLayout recipeLayouts : this.recipeLayouts) { - clicked = recipeLayouts.getIngredientUnderMouse(mouseX, mouseY); - if (clicked != null) { - return clicked; - } - } - } - } - return null; - } - - @Override - public boolean canSetFocusWithMouse() { - return true; - } - - @Override - public void handleMouseInput() throws IOException { - final int x = Mouse.getEventX() * width / mc.displayWidth; - final int y = height - Mouse.getEventY() * height / mc.displayHeight - 1; - if (isMouseOver(x, y)) { - int scrollDelta = Mouse.getEventDWheel(); - if (scrollDelta < 0) { - logic.nextPage(); - updateLayout(); - return; - } else if (scrollDelta > 0) { - logic.previousPage(); - updateLayout(); - return; - } - } - super.handleMouseInput(); - } - - @Override - protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException { - if (!isMouseOver(mouseX, mouseY)) { - return; - } - - if (titleHoverChecker.checkHover(mouseX, mouseY)) { - if (logic.setCategoryFocus()) { - updateLayout(); - } - } else { - for (RecipeLayout recipeLayout : recipeLayouts) { - if (recipeLayout.handleClick(mc, mouseX, mouseY, mouseButton)) { - return; - } - } - } - - super.mouseClicked(mouseX, mouseY, mouseButton); - } - - @Override - protected void keyTyped(char typedChar, int keyCode) throws IOException { - if (InputHandler.isInventoryCloseKey(keyCode) || InputHandler.isInventoryToggleKey(keyCode)) { - close(); - } else if (KeyBindings.recipeBack.isActiveAndMatches(keyCode)) { - back(); - } - } - - public boolean isOpen() { - return mc.currentScreen == this; - } - - private void open() { - if (!isOpen()) { - parentScreen = mc.currentScreen; - } - mc.displayGuiScreen(this); - } - - public void close() { - if (isOpen()) { - if (parentScreen != null) { - mc.displayGuiScreen(parentScreen); - parentScreen = null; - } else { - mc.thePlayer.closeScreen(); - } - logic.clearHistory(); - } - } - - @Override - public void show(@Nullable IFocus focus) { - if (focus == null) { - Log.error("Null focus", new NullPointerException()); - return; - } - - if (logic.setFocus(focus)) { - open(); - } - } - - @Override - @Deprecated - public void showRecipes(@Nullable ItemStack focus) { - show(new Focus(IFocus.Mode.OUTPUT, focus)); - } - - @Override - @Deprecated - public void showRecipes(@Nullable FluidStack focus) { - show(new Focus(IFocus.Mode.OUTPUT, focus)); - } - - @Override - @Deprecated - public void showUses(@Nullable ItemStack focus) { - show(new Focus(IFocus.Mode.INPUT, focus)); - } - - @Override - @Deprecated - public void showUses(@Nullable FluidStack focus) { - show(new Focus(IFocus.Mode.INPUT, focus)); - } - - @Override - public void showCategories(@Nullable List recipeCategoryUids) { - if (recipeCategoryUids == null) { - Log.error("Null recipeCategoryUids", new NullPointerException()); - return; - } - if (recipeCategoryUids.isEmpty()) { - Log.error("Empty recipeCategoryUids", new IllegalArgumentException()); - return; - } - if (logic.setCategoryFocus(recipeCategoryUids)) { - open(); - } - } - - public void back() { - if (logic.back()) { - updateLayout(); - } - } - - @Override - protected void actionPerformed(GuiButton guibutton) { - boolean updateLayout = true; - - if (guibutton.id == nextPage.id) { - logic.nextPage(); - } else if (guibutton.id == previousPage.id) { - logic.previousPage(); - } else if (guibutton.id == nextRecipeCategory.id) { - logic.nextRecipeCategory(); - } else if (guibutton.id == previousRecipeCategory.id) { - logic.previousRecipeCategory(); - } else if (guibutton.id >= RecipeLayout.recipeTransferButtonIndex) { - int recipeIndex = guibutton.id - RecipeLayout.recipeTransferButtonIndex; - RecipeLayout recipeLayout = recipeLayouts.get(recipeIndex); - boolean maxTransfer = GuiScreen.isShiftKeyDown(); - Container container = getParentContainer(); - if (container != null && RecipeTransferUtil.transferRecipe(container, recipeLayout, mc.thePlayer, maxTransfer)) { - close(); - updateLayout = false; - } - } else { - updateLayout = false; - } - - if (updateLayout) { - updateLayout(); - } - } - - private void updateLayout() { - IRecipeCategory recipeCategory = logic.getRecipeCategory(); - if (recipeCategory == null) { - return; - } - - IDrawable recipeBackground = recipeCategory.getBackground(); - - final int recipesPerPage = Math.max(1, (ySize - headerHeight) / (recipeBackground.getHeight() + innerPadding)); - final int recipeXOffset = guiLeft + (xSize - recipeBackground.getWidth()) / 2; - final int recipeSpacing = (ySize - headerHeight - (recipesPerPage * recipeBackground.getHeight())) / (recipesPerPage + 1); - - logic.setRecipesPerPage(recipesPerPage); - - title = recipeCategory.getTitle(); - final int titleWidth = fontRendererObj.getStringWidth(title); - final int titleX = guiLeft + (xSize - titleWidth) / 2; - final int titleY = guiTop + borderPadding; - titleHoverChecker = new HoverChecker(titleY, titleY + fontRendererObj.FONT_HEIGHT, titleX, titleX + titleWidth, 0); - - int spacingY = recipeBackground.getHeight() + recipeSpacing; - - recipeLayouts.clear(); - recipeLayouts.addAll(logic.getRecipeWidgets(recipeXOffset, guiTop + headerHeight + recipeSpacing, spacingY)); - addRecipeTransferButtons(recipeLayouts); - - nextPage.enabled = previousPage.enabled = logic.hasMultiplePages(); - nextRecipeCategory.enabled = previousRecipeCategory.enabled = logic.hasMultipleCategories(); - - pageString = logic.getPageString(); - - List recipeCategoryCraftingItems = logic.getRecipeCategoryCraftingItems(); - recipeCategoryCraftingItemsArea.updateLayout(recipeCategoryCraftingItems, GuiProperties.create(this)); - } - - private void addRecipeTransferButtons(List recipeLayouts) { - buttonList.clear(); - addButtons(); - - EntityPlayer player = mc.thePlayer; - Container container = getParentContainer(); - - for (RecipeLayout recipeLayout : recipeLayouts) { - RecipeTransferButton button = recipeLayout.getRecipeTransferButton(); - button.init(container, recipeLayout, player); - buttonList.add(button); - } - } - - @Nullable - public GuiScreen getParentScreen() { - return parentScreen; - } - - @Nullable - private Container getParentContainer() { - if (parentScreen instanceof GuiContainer) { - return ((GuiContainer) parentScreen).inventorySlots; - } - return null; - } -} +package mezz.jei.gui.recipes; + +import javax.annotation.Nullable; +import java.awt.Color; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import mezz.jei.RecipeRegistry; +import mezz.jei.api.IRecipesGui; +import mezz.jei.api.gui.IDrawable; +import mezz.jei.api.recipe.IFocus; +import mezz.jei.api.recipe.IRecipeCategory; +import mezz.jei.config.Constants; +import mezz.jei.config.KeyBindings; +import mezz.jei.gui.Focus; +import mezz.jei.gui.GuiProperties; +import mezz.jei.gui.RecipeCategoryCraftingItems; +import mezz.jei.gui.TooltipRenderer; +import mezz.jei.gui.ingredients.GuiIngredient; +import mezz.jei.input.IClickedIngredient; +import mezz.jei.input.IShowsRecipeFocuses; +import mezz.jei.input.InputHandler; +import mezz.jei.transfer.RecipeTransferUtil; +import mezz.jei.util.Log; +import mezz.jei.util.StringUtil; +import mezz.jei.util.Translator; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.gui.inventory.GuiContainer; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fml.client.config.GuiButtonExt; +import net.minecraftforge.fml.client.config.HoverChecker; +import org.lwjgl.input.Mouse; + +public class RecipesGui extends GuiScreen implements IRecipesGui, IShowsRecipeFocuses, IRecipeLogicStateListener { + private static final int borderPadding = 6; + private static final int innerPadding = 5; + private static final int textPadding = 5; + private static final int buttonWidth = 13; + private static final int buttonHeight = 12; + + private int titleHeight; + private int headerHeight; + + /* Internal logic for the gui, handles finding recipes */ + private final IRecipeGuiLogic logic; + + /* List of RecipeLayout to display */ + private final List recipeLayouts = new ArrayList(); + + private String pageString; + private String title; + private ResourceLocation backgroundTexture; + private final RecipeCategoryCraftingItems recipeCategoryCraftingItems; + private final RecipeGuiTabs recipeGuiTabs; + + private HoverChecker titleHoverChecker; + + private GuiButton nextRecipeCategory; + private GuiButton previousRecipeCategory; + private GuiButton nextPage; + private GuiButton previousPage; + + @Nullable + private GuiScreen parentScreen; + private int xSize; + private int ySize; + private int guiLeft; + private int guiTop; + + private boolean init = false; + + public RecipesGui(RecipeRegistry recipeRegistry) { + this.logic = new RecipeGuiLogic(recipeRegistry, this); + this.recipeCategoryCraftingItems = new RecipeCategoryCraftingItems(recipeRegistry); + this.recipeGuiTabs = new RecipeGuiTabs(this.logic); + this.mc = Minecraft.getMinecraft(); + } + + public int getGuiLeft() { + return guiLeft; + } + + public int getGuiTop() { + return guiTop; + } + + public int getXSize() { + return xSize; + } + + public int getYSize() { + return ySize; + } + + @Override + public boolean doesGuiPauseGame() { + return false; + } + + @Override + public void initGui() { + super.initGui(); + + this.xSize = 196; + + ResourceLocation recipeBackgroundResource = new ResourceLocation(Constants.RESOURCE_DOMAIN, Constants.TEXTURE_RECIPE_BACKGROUND_PATH); + if (this.height > 300) { + this.ySize = 256; + this.backgroundTexture = new ResourceLocation(Constants.RESOURCE_DOMAIN, Constants.TEXTURE_RECIPE_BACKGROUND_TALL_PATH); + } else { + this.ySize = 166; + this.backgroundTexture = recipeBackgroundResource; + } + + this.guiLeft = (width - this.xSize) / 2; + this.guiTop = (height - this.ySize) / 2 + 8; + + this.titleHeight = fontRendererObj.FONT_HEIGHT + borderPadding; + this.headerHeight = titleHeight + fontRendererObj.FONT_HEIGHT + textPadding; + + final int rightButtonX = guiLeft + xSize - borderPadding - buttonWidth; + final int leftButtonX = guiLeft + borderPadding; + + int recipeClassButtonTop = guiTop + titleHeight - buttonHeight + 1; + nextRecipeCategory = new GuiButtonExt(2, rightButtonX, recipeClassButtonTop, buttonWidth, buttonHeight, ">"); + previousRecipeCategory = new GuiButtonExt(3, leftButtonX, recipeClassButtonTop, buttonWidth, buttonHeight, "<"); + + int pageButtonTop = guiTop + titleHeight + 3; + nextPage = new GuiButtonExt(4, rightButtonX, pageButtonTop, buttonWidth, buttonHeight, ">"); + previousPage = new GuiButtonExt(5, leftButtonX, pageButtonTop, buttonWidth, buttonHeight, "<"); + + addButtons(); + + this.init = true; + updateLayout(); + } + + private void addButtons() { + this.buttonList.add(nextRecipeCategory); + this.buttonList.add(previousRecipeCategory); + this.buttonList.add(nextPage); + this.buttonList.add(previousPage); + } + + @Override + public void drawScreen(int mouseX, int mouseY, float partialTicks) { + drawGuiContainerBackgroundLayer(partialTicks, mouseX, mouseY); + + GlStateManager.disableBlend(); + + drawRect(guiLeft + borderPadding + buttonWidth, + guiTop + borderPadding - 2, + guiLeft + xSize - borderPadding - buttonWidth, + guiTop + borderPadding + 10, + 0x30000000); + drawRect(guiLeft + borderPadding + buttonWidth, + guiTop + titleHeight + textPadding - 2, + guiLeft + xSize - borderPadding - buttonWidth, + guiTop + titleHeight + textPadding + 10, + 0x30000000); + + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + + StringUtil.drawCenteredString(fontRendererObj, title, xSize, guiLeft, guiTop + borderPadding, Color.WHITE.getRGB(), true); + StringUtil.drawCenteredString(fontRendererObj, pageString, xSize, guiLeft, guiTop + titleHeight + textPadding, Color.WHITE.getRGB(), true); + + nextRecipeCategory.drawButton(mc, mouseX, mouseY); + previousRecipeCategory.drawButton(mc, mouseX, mouseY); + nextPage.drawButton(mc, mouseX, mouseY); + previousPage.drawButton(mc, mouseX, mouseY); + + RecipeLayout hovered = null; + for (RecipeLayout recipeWidget : recipeLayouts) { + if (recipeWidget.isMouseOver(mouseX, mouseY)) { + hovered = recipeWidget; + } else { + recipeWidget.draw(mc, mouseX, mouseY); + } + } + + GuiIngredient hoveredItemStack = recipeCategoryCraftingItems.draw(mc, mouseX, mouseY); + + recipeGuiTabs.draw(mc, mouseX, mouseY); + + if (hovered != null) { + hovered.draw(mc, mouseX, mouseY); + } + if (hoveredItemStack != null) { + hoveredItemStack.drawHovered(mc, 0, 0, mouseX, mouseY); + } + + if (titleHoverChecker.checkHover(mouseX, mouseY)) { + if (!logic.hasAllCategories()) { + String showAllRecipesString = Translator.translateToLocal("jei.tooltip.show.all.recipes"); + TooltipRenderer.drawHoveringText(mc, showAllRecipesString, mouseX, mouseY); + } + } + } + + protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) { + drawDefaultBackground(); + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + mc.getTextureManager().bindTexture(backgroundTexture); + this.zLevel = 0; + drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize); + } + + public boolean isMouseOver(int mouseX, int mouseY) { + return mc.currentScreen == this && (mouseX >= guiLeft) && (mouseY >= guiTop) && (mouseX < guiLeft + xSize) && (mouseY < guiTop + ySize); + } + + @Nullable + @Override + public IClickedIngredient getIngredientUnderMouse(int mouseX, int mouseY) { + if (isOpen()) { + IClickedIngredient clicked = recipeCategoryCraftingItems.getIngredientUnderMouse(mouseX, mouseY); + if (clicked != null) { + return clicked; + } + + if (isMouseOver(mouseX, mouseY)) { + for (RecipeLayout recipeLayouts : this.recipeLayouts) { + clicked = recipeLayouts.getIngredientUnderMouse(mouseX, mouseY); + if (clicked != null) { + return clicked; + } + } + } + } + return null; + } + + @Override + public boolean canSetFocusWithMouse() { + return true; + } + + @Override + public void handleMouseInput() throws IOException { + final int x = Mouse.getEventX() * width / mc.displayWidth; + final int y = height - Mouse.getEventY() * height / mc.displayHeight - 1; + if (isMouseOver(x, y)) { + int scrollDelta = Mouse.getEventDWheel(); + if (scrollDelta < 0) { + logic.nextPage(); + return; + } else if (scrollDelta > 0) { + logic.previousPage(); + return; + } + } + super.handleMouseInput(); + } + + @Override + protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException { + if (isMouseOver(mouseX, mouseY)) { + if (titleHoverChecker.checkHover(mouseX, mouseY)) { + if (logic.setCategoryFocus()) { + return; + } + } else { + for (RecipeLayout recipeLayout : recipeLayouts) { + if (recipeLayout.handleClick(mc, mouseX, mouseY, mouseButton)) { + return; + } + } + } + } + + if (recipeGuiTabs.isMouseOver(mouseX, mouseY)) { + if (recipeGuiTabs.handleMouseClicked(mouseX, mouseY, mouseButton)) { + return; + } + } + + super.mouseClicked(mouseX, mouseY, mouseButton); + } + + @Override + protected void keyTyped(char typedChar, int keyCode) throws IOException { + if (InputHandler.isInventoryCloseKey(keyCode) || InputHandler.isInventoryToggleKey(keyCode)) { + close(); + } else if (KeyBindings.recipeBack.isActiveAndMatches(keyCode)) { + back(); + } + } + + public boolean isOpen() { + return mc.currentScreen == this; + } + + private void open() { + if (!isOpen()) { + parentScreen = mc.currentScreen; + } + mc.displayGuiScreen(this); + } + + public void close() { + if (isOpen()) { + if (parentScreen != null) { + mc.displayGuiScreen(parentScreen); + parentScreen = null; + } else { + mc.thePlayer.closeScreen(); + } + logic.clearHistory(); + } + } + + @Override + public void show(@Nullable IFocus focus) { + if (focus == null) { + Log.error("Null focus", new NullPointerException()); + return; + } + + if (logic.setFocus(focus)) { + open(); + } + } + + @Override + @Deprecated + public void showRecipes(@Nullable ItemStack focus) { + show(new Focus(IFocus.Mode.OUTPUT, focus)); + } + + @Override + @Deprecated + public void showRecipes(@Nullable FluidStack focus) { + show(new Focus(IFocus.Mode.OUTPUT, focus)); + } + + @Override + @Deprecated + public void showUses(@Nullable ItemStack focus) { + show(new Focus(IFocus.Mode.INPUT, focus)); + } + + @Override + @Deprecated + public void showUses(@Nullable FluidStack focus) { + show(new Focus(IFocus.Mode.INPUT, focus)); + } + + @Override + public void showCategories(@Nullable List recipeCategoryUids) { + if (recipeCategoryUids == null) { + Log.error("Null recipeCategoryUids", new NullPointerException()); + return; + } + if (recipeCategoryUids.isEmpty()) { + Log.error("Empty recipeCategoryUids", new IllegalArgumentException()); + return; + } + if (logic.setCategoryFocus(recipeCategoryUids)) { + open(); + } + } + + public void back() { + logic.back(); + } + + @Override + protected void actionPerformed(GuiButton guibutton) { + if (guibutton.id == nextPage.id) { + logic.nextPage(); + } else if (guibutton.id == previousPage.id) { + logic.previousPage(); + } else if (guibutton.id == nextRecipeCategory.id) { + logic.nextRecipeCategory(); + } else if (guibutton.id == previousRecipeCategory.id) { + logic.previousRecipeCategory(); + } else if (guibutton.id >= RecipeLayout.recipeTransferButtonIndex) { + int recipeIndex = guibutton.id - RecipeLayout.recipeTransferButtonIndex; + RecipeLayout recipeLayout = recipeLayouts.get(recipeIndex); + boolean maxTransfer = GuiScreen.isShiftKeyDown(); + Container container = getParentContainer(); + if (container != null && RecipeTransferUtil.transferRecipe(container, recipeLayout, mc.thePlayer, maxTransfer)) { + close(); + } + } + } + + private void updateLayout() { + if (!init) { + return; + } + IRecipeCategory recipeCategory = logic.getSelectedRecipeCategory(); + if (recipeCategory == null) { + return; + } + + IDrawable recipeBackground = recipeCategory.getBackground(); + + final int recipesPerPage = Math.max(1, (ySize - headerHeight) / (recipeBackground.getHeight() + innerPadding)); + final int recipeXOffset = guiLeft + (xSize - recipeBackground.getWidth()) / 2; + final int recipeSpacing = (ySize - headerHeight - (recipesPerPage * recipeBackground.getHeight())) / (recipesPerPage + 1); + + logic.setRecipesPerPage(recipesPerPage); + + title = recipeCategory.getTitle(); + final int titleWidth = fontRendererObj.getStringWidth(title); + final int titleX = guiLeft + (xSize - titleWidth) / 2; + final int titleY = guiTop + borderPadding; + titleHoverChecker = new HoverChecker(titleY, titleY + fontRendererObj.FONT_HEIGHT, titleX, titleX + titleWidth, 0); + + int spacingY = recipeBackground.getHeight() + recipeSpacing; + + recipeLayouts.clear(); + recipeLayouts.addAll(logic.getRecipeWidgets(recipeXOffset, guiTop + headerHeight + recipeSpacing, spacingY)); + addRecipeTransferButtons(recipeLayouts); + + nextPage.enabled = previousPage.enabled = logic.hasMultiplePages(); + nextRecipeCategory.enabled = previousRecipeCategory.enabled = logic.hasMultipleCategories(); + + pageString = logic.getPageString(); + + List recipeCategoryCraftingItems = logic.getRecipeCategoryCraftingItems(); + GuiProperties guiProperties = GuiProperties.create(this); + this.recipeCategoryCraftingItems.updateLayout(recipeCategoryCraftingItems, guiProperties); + recipeGuiTabs.updateLayout(guiProperties); + } + + private void addRecipeTransferButtons(List recipeLayouts) { + buttonList.clear(); + addButtons(); + + EntityPlayer player = mc.thePlayer; + Container container = getParentContainer(); + + for (RecipeLayout recipeLayout : recipeLayouts) { + RecipeTransferButton button = recipeLayout.getRecipeTransferButton(); + button.init(container, recipeLayout, player); + buttonList.add(button); + } + } + + @Nullable + public GuiScreen getParentScreen() { + return parentScreen; + } + + @Nullable + private Container getParentContainer() { + if (parentScreen instanceof GuiContainer) { + return ((GuiContainer) parentScreen).inventorySlots; + } + return null; + } + + @Override + public void onStateChange() { + updateLayout(); + } +} diff --git a/src/main/java/mezz/jei/input/InputHandler.java b/src/main/java/mezz/jei/input/InputHandler.java index 4025b8d34..03c9ffabe 100644 --- a/src/main/java/mezz/jei/input/InputHandler.java +++ b/src/main/java/mezz/jei/input/InputHandler.java @@ -12,8 +12,8 @@ import mezz.jei.config.KeyBindings; import mezz.jei.gui.Focus; import mezz.jei.gui.ItemListOverlay; -import mezz.jei.gui.RecipeClickableArea; -import mezz.jei.gui.RecipesGui; +import mezz.jei.gui.recipes.RecipeClickableArea; +import mezz.jei.gui.recipes.RecipesGui; import mezz.jei.util.Commands; import mezz.jei.util.MouseHelper; import net.minecraft.client.Minecraft; diff --git a/src/main/java/mezz/jei/plugins/jei/description/ItemDescriptionRecipeCategory.java b/src/main/java/mezz/jei/plugins/jei/description/ItemDescriptionRecipeCategory.java index ec868807c..eb5cd6689 100644 --- a/src/main/java/mezz/jei/plugins/jei/description/ItemDescriptionRecipeCategory.java +++ b/src/main/java/mezz/jei/plugins/jei/description/ItemDescriptionRecipeCategory.java @@ -1,5 +1,7 @@ package mezz.jei.plugins.jei.description; +import javax.annotation.Nullable; + import mezz.jei.api.IGuiHelper; import mezz.jei.api.gui.IDrawable; import mezz.jei.api.gui.IGuiItemStackGroup; @@ -7,16 +9,21 @@ import mezz.jei.api.ingredients.IIngredients; import mezz.jei.api.recipe.BlankRecipeCategory; import mezz.jei.api.recipe.VanillaRecipeCategoryUid; +import mezz.jei.config.Constants; import mezz.jei.util.Translator; +import net.minecraft.util.ResourceLocation; public class ItemDescriptionRecipeCategory extends BlankRecipeCategory { public static final int recipeWidth = 160; public static final int recipeHeight = 125; private final IDrawable background; + private final IDrawable icon; private final String localizedName; public ItemDescriptionRecipeCategory(IGuiHelper guiHelper) { background = guiHelper.createBlankDrawable(recipeWidth, recipeHeight); + ResourceLocation recipeBackgroundResource = new ResourceLocation(Constants.RESOURCE_DOMAIN, Constants.TEXTURE_RECIPE_BACKGROUND_PATH); + icon = guiHelper.createDrawable(recipeBackgroundResource, 196, 39, 16, 16); localizedName = Translator.translateToLocal("gui.jei.category.itemDescription"); } @@ -30,6 +37,12 @@ public String getTitle() { return localizedName; } + @Nullable + @Override + public IDrawable getIcon() { + return icon; + } + @Override public IDrawable getBackground() { return background; diff --git a/src/main/java/mezz/jei/plugins/vanilla/furnace/FurnaceFuelCategory.java b/src/main/java/mezz/jei/plugins/vanilla/furnace/FurnaceFuelCategory.java index 131a2c451..4ee8492ef 100644 --- a/src/main/java/mezz/jei/plugins/vanilla/furnace/FurnaceFuelCategory.java +++ b/src/main/java/mezz/jei/plugins/vanilla/furnace/FurnaceFuelCategory.java @@ -1,20 +1,28 @@ package mezz.jei.plugins.vanilla.furnace; +import javax.annotation.Nullable; + import mezz.jei.api.IGuiHelper; import mezz.jei.api.gui.IDrawable; import mezz.jei.api.gui.IGuiItemStackGroup; import mezz.jei.api.gui.IRecipeLayout; import mezz.jei.api.ingredients.IIngredients; import mezz.jei.api.recipe.VanillaRecipeCategoryUid; +import mezz.jei.config.Constants; import mezz.jei.util.Translator; +import net.minecraft.util.ResourceLocation; public class FurnaceFuelCategory extends FurnaceRecipeCategory { private final IDrawable background; + private final IDrawable flame; private final String localizedName; public FurnaceFuelCategory(IGuiHelper guiHelper) { super(guiHelper); background = guiHelper.createDrawable(backgroundLocation, 55, 38, 18, 32, 0, 0, 0, 80); + + ResourceLocation recipeBackgroundResource = new ResourceLocation(Constants.RESOURCE_DOMAIN, Constants.TEXTURE_RECIPE_BACKGROUND_PATH); + flame = guiHelper.createDrawable(recipeBackgroundResource, 215, 0, 14, 14); localizedName = Translator.translateToLocal("gui.jei.category.fuel"); } @@ -33,6 +41,12 @@ public String getTitle() { return localizedName; } + @Nullable + @Override + public IDrawable getIcon() { + return flame; + } + @Override public void setRecipe(IRecipeLayout recipeLayout, FuelRecipe recipeWrapper, IIngredients ingredients) { IGuiItemStackGroup guiItemStacks = recipeLayout.getItemStacks(); diff --git a/src/main/java/mezz/jei/transfer/RecipeTransferUtil.java b/src/main/java/mezz/jei/transfer/RecipeTransferUtil.java index 7ebf6dc20..f9ac651b7 100644 --- a/src/main/java/mezz/jei/transfer/RecipeTransferUtil.java +++ b/src/main/java/mezz/jei/transfer/RecipeTransferUtil.java @@ -7,7 +7,7 @@ import mezz.jei.RecipeRegistry; import mezz.jei.api.recipe.transfer.IRecipeTransferError; import mezz.jei.api.recipe.transfer.IRecipeTransferHandler; -import mezz.jei.gui.RecipeLayout; +import mezz.jei.gui.recipes.RecipeLayout; import mezz.jei.util.Log; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.Container; diff --git a/src/main/java/mezz/jei/util/ModRegistry.java b/src/main/java/mezz/jei/util/ModRegistry.java index 94127deef..3a59d8fad 100644 --- a/src/main/java/mezz/jei/util/ModRegistry.java +++ b/src/main/java/mezz/jei/util/ModRegistry.java @@ -22,7 +22,7 @@ import mezz.jei.api.recipe.IRecipeRegistryPlugin; import mezz.jei.api.recipe.transfer.IRecipeTransferHandler; import mezz.jei.api.recipe.transfer.IRecipeTransferRegistry; -import mezz.jei.gui.RecipeClickableArea; +import mezz.jei.gui.recipes.RecipeClickableArea; import mezz.jei.plugins.jei.description.ItemDescriptionRecipe; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.item.ItemStack; diff --git a/src/main/resources/assets/jei/textures/gui/recipeBackground.png b/src/main/resources/assets/jei/textures/gui/recipeBackground.png deleted file mode 100644 index 9e0b7b4a6bb633f6c694ec26a8173749a064cb6e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 774 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K58911MRQ8&P5Flk1;1lBd|NsBS#>V}go~u@^ zx>8tZWo1<(AmHok>+kO$5D;K*Z}08x9U2-6R1Q?x-Q9ic*fDc+^BInX;vn-%g8YIR z9G=}sV_;ya^K@|xsffFC!BB`nfrI(rZ-=IT|2LltSj4NEH_?tggO4Fzqe-liukrDw z?1mp-_fMb4Smf!F#b)v5=Gnex1qs%G^11RZ&;G`j`AA4>om+JJ+q~ThFF#rD3~T(R zrJ1_+_W}Nw4DAORKZ!V0n>OU0_)tB^p8LVSC-Pk0N)GSq>$zK)c&_@hy!iawY{7Z? zpYjiMA6O^ISZ-qc9H$_YaFY2&^wZ>%%n`p=9=N~h7~`6+j0@IwGUT#n)ZU!=i6Ke= z=p9V(mE}T~jDs{|lrM9{@+GDTUSbRlky_jg2d3!qCRi`srw`V0#juefco74Gj(zYn zod(NBuwa1K#RfTsXj@fYg;yRt2U4%CzVhoBgZ$Dd=My_#r=N?zWX&EOYH7zI@JSv@26zxyt5y)auB_>pQsL z++6PPDSScE+q)VLPx&@n(mAkV$ua8#F(f7e#=KDQ8 z8yg${|Ce92YSop(LMtn)8UcaO(9rJgZlK!#+Zb;6fD|7)c8ue&$^xJeV@Z%-FoVOh z8)*y-OnW_D978JN?p$!>I-nrpeDLP;)qDSEdb5T*?cT<0=^*zi$E-2$<-MyGx8oEX zU(d+?`SpL{R2znw7p~Q?@3^_SIhNf~f$MO^@lpX&dl#` zT-nAT@tyG!W5UZloD2rXEBtQ%3pq^&2;Cgtr##=Fu(zu*Nhol8??`4f2`#0VxG{KlYVJ}0mJR7 zGZ=2WGckSnxAe0RA45Z~M+k$a8c;XSUuJ<4$q;dmM8<6^7;;)Ic?xCTak3$q>o8B9 z$Kjf96GIAP!DSbj2HA%FhH|_I+A~U#6v3DWOjURo)*oT;*x5Vz2%|^kt^JP}me_PE zF@7kOfT^JZ-Ef}=YRaF<&d1#t7!){|SMC&fXTNqSb3oxgw$96pNilq>6}ReNYa3PBV(T4rJ@|RQ^#paQ&T1=+xiyip{h?$fP%xe$||? zhdZQiuN3QwIgDwuSS6-j`N6Uy&FK5(m;bVR0)O85zh_+->$b%QuB|>$CUT=n^hO_3 z^l2t8jRg)`+xM=MVT`Kj*!g~InA}{IpSS*VV){0&{F~#=b!xjKK~kQselF{r5}E)b Celmyv literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/jei/textures/gui/recipeBackgroundTall.png b/src/main/resources/assets/jei/textures/gui/recipeBackgroundTall.png deleted file mode 100644 index 4dd1bdc0152efac5e71a98cbee9a6de7d4e1d7a8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 294 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K58CaNs)Vi3hp+Jg1z$e7@|Ns9$CXfsb4Lx@3 zSlj!LdqE0Ig8YIR9G=}s19Fafx;TbZ#JxS|DA=GNz;IwOV+NBfmxarLe>2w<*uC36 zJ3-m4RW9@Gx&qf*fkHF>x2X?aWJ zZ<2cKf9(`o-(5=y1_lmBhBBVx6C8M+o)>XiUnhO=SIASb4m(wafdd9x&jktsU3MrS zV?nx5KgYNCDJ=UcSj~1a&f6q*Ok;JzhRr_z7`5xe;)UBZ6oEcw@O1TaS?83{1OV1I BR&@XX literal 0 HcmV?d00001