diff --git a/src/main/java/brachy/modularui/integration/jei/JeiRecipeViewerSlot.java b/src/main/java/brachy/modularui/integration/jei/JeiRecipeViewerSlot.java index cfe29f95..c1e94f22 100644 --- a/src/main/java/brachy/modularui/integration/jei/JeiRecipeViewerSlot.java +++ b/src/main/java/brachy/modularui/integration/jei/JeiRecipeViewerSlot.java @@ -1,31 +1,42 @@ package brachy.modularui.integration.jei; +import brachy.modularui.drawable.GuiTextures; import brachy.modularui.integration.recipeviewer.RecipeSlotRole; import brachy.modularui.integration.recipeviewer.RecipeViewerSlotWidget; import brachy.modularui.integration.recipeviewer.entry.EntryList; -import org.apache.commons.lang3.NotImplementedException; +import net.minecraftforge.fluids.FluidStack; + +import lombok.Getter; +import lombok.Setter; +import lombok.experimental.Accessors; import org.jetbrains.annotations.ApiStatus; @ApiStatus.Experimental public class JeiRecipeViewerSlot extends RecipeViewerSlotWidget { + @Accessors(fluent = true) + @Getter + @Setter + private RecipeSlotRole recipeSlotRole = RecipeSlotRole.RENDER_ONLY; + @Getter + private EntryList value; + @Accessors(fluent = true) + @Getter + @Setter + private float chance = 1f; public JeiRecipeViewerSlot() { - throw new NotImplementedException(); - } - - @Override - public JeiRecipeViewerSlot recipeSlotRole(RecipeSlotRole recipeSlotRole) { - return getThis(); + size(18, 18); } @Override public JeiRecipeViewerSlot value(EntryList entryList) { - return getThis(); - } - - @Override - public JeiRecipeViewerSlot chance(float chance) { + this.value = entryList; + if (this.value.getType() == FluidStack.class) { + background(GuiTextures.SLOT_FLUID); + } else { + background(GuiTextures.SLOT_ITEM); // TODO other types + } return getThis(); } } diff --git a/src/main/java/brachy/modularui/integration/jei/recipe/ModularUIRecipeCategory.java b/src/main/java/brachy/modularui/integration/jei/recipe/ModularUIRecipeCategory.java index 4a02785b..d6254610 100644 --- a/src/main/java/brachy/modularui/integration/jei/recipe/ModularUIRecipeCategory.java +++ b/src/main/java/brachy/modularui/integration/jei/recipe/ModularUIRecipeCategory.java @@ -1,8 +1,10 @@ package brachy.modularui.integration.jei.recipe; import brachy.modularui.api.widget.IWidget; +import brachy.modularui.integration.jei.JeiRecipeViewerSlot; import brachy.modularui.integration.jei.ModularUIJeiPlugin; import brachy.modularui.integration.recipeviewer.RecipeSlotRole; +import brachy.modularui.integration.recipeviewer.entry.EntryList; import brachy.modularui.integration.recipeviewer.handlers.IngredientProvider; import brachy.modularui.integration.recipeviewer.util.RecipeScreenRenderingUtil; import brachy.modularui.screen.ModularPanel; @@ -68,10 +70,10 @@ private ModularScreen getModularScreen(T recipe) { return this.modularScreenCache.getUnchecked(recipe); } - private static void addJEISlot(IRecipeLayoutBuilder builder, IngredientProvider widget, + private static void addJEISlot(IRecipeLayoutBuilder builder, EntryList entries, JeiRecipeViewerSlot widget, RecipeIngredientRole role, int index) { var type = ModularUIJeiPlugin.getRuntime().getIngredientManager() - .getIngredientTypeChecked(widget.ingredientClass()); + .getIngredientTypeChecked(entries.getType()); if (type.isEmpty()) { return; } @@ -79,7 +81,7 @@ private static void addJEISlot(IRecipeLayoutBuilder builder, IngredientProvi Area widgetArea = widget.getArea(); IRecipeSlotBuilder slotBuilder = builder.addSlot(role, widgetArea.x, widgetArea.y); - slotBuilder.addIngredients(type.get(), widget.getIngredients().getStacks()); + slotBuilder.addIngredients(type.get(), entries.getStacks()); slotBuilder.setCustomRenderer(type.get(), new IIngredientRenderer<>() { @Override @@ -111,11 +113,11 @@ public void setRecipe(IRecipeLayoutBuilder builder, T recipe, IFocusGroup focuse MutableInt i = new MutableInt(0); WidgetTree.foreachChildBFS(screen.getMainPanel(), widget -> { - if (!(widget instanceof IngredientProvider provider)) { + if (!(widget instanceof JeiRecipeViewerSlot provider)) { return true; } - RecipeIngredientRole role = mapToRole(provider.getRecipeRole()); - addJEISlot(builder, provider, role, i.getAndIncrement()); + RecipeIngredientRole role = mapToRole(provider.recipeSlotRole()); + addJEISlot(builder, provider.getValue(), provider, role, i.getAndIncrement()); return true; }, true); } diff --git a/src/main/java/brachy/modularui/integration/rei/REIStackConverter.java b/src/main/java/brachy/modularui/integration/rei/REIStackConverter.java index 42e85e34..6f387b25 100644 --- a/src/main/java/brachy/modularui/integration/rei/REIStackConverter.java +++ b/src/main/java/brachy/modularui/integration/rei/REIStackConverter.java @@ -119,6 +119,7 @@ public static Converter getForNullable(Class clazz) { return (Converter) CONVERTERS.get(clazz); } + public static Optional> getFor(Class clazz) { return Optional.ofNullable(getForNullable(clazz)); } diff --git a/src/main/java/brachy/modularui/integration/rei/ReiRecipeViewerSlot.java b/src/main/java/brachy/modularui/integration/rei/ReiRecipeViewerSlot.java index f23a6717..59bd3f01 100644 --- a/src/main/java/brachy/modularui/integration/rei/ReiRecipeViewerSlot.java +++ b/src/main/java/brachy/modularui/integration/rei/ReiRecipeViewerSlot.java @@ -1,31 +1,106 @@ package brachy.modularui.integration.rei; +import brachy.modularui.drawable.GuiTextures; import brachy.modularui.integration.recipeviewer.RecipeSlotRole; import brachy.modularui.integration.recipeviewer.RecipeViewerSlotWidget; import brachy.modularui.integration.recipeviewer.entry.EntryList; +import brachy.modularui.screen.viewport.ModularGuiContext; +import brachy.modularui.theme.WidgetThemeEntry; -import org.apache.commons.lang3.NotImplementedException; +import net.minecraftforge.fluids.FluidStack; + +import lombok.Getter; +import lombok.Setter; +import lombok.experimental.Accessors; +import me.shedaniel.math.Point; +import me.shedaniel.rei.api.client.gui.widgets.Slot; +import me.shedaniel.rei.api.client.gui.widgets.Widgets; +import me.shedaniel.rei.api.common.entry.EntryIngredient; import org.jetbrains.annotations.ApiStatus; +import java.util.function.UnaryOperator; + @ApiStatus.Experimental public class ReiRecipeViewerSlot extends RecipeViewerSlotWidget { + @ApiStatus.Internal + @Getter + private Slot slotWidget; + private int x, y; + + @Accessors(fluent = true) + @Getter + private RecipeSlotRole recipeSlotRole; + @Getter + private EntryList value; + @Accessors(fluent = true) + @Getter + @Setter + private float chance = 1f; + public ReiRecipeViewerSlot() { - throw new NotImplementedException(); + super(); + slotWidget = Widgets.createSlot(new Point()).disableBackground(); + recipeSlotRole = RecipeSlotRole.RENDER_ONLY; + + size(18, 18); } @Override public ReiRecipeViewerSlot recipeSlotRole(RecipeSlotRole recipeSlotRole) { + this.recipeSlotRole = recipeSlotRole; + rebuildReiSlot(); return getThis(); } @Override public ReiRecipeViewerSlot value(EntryList entryList) { + this.value = entryList; + rebuildReiSlot(); + if (this.value.getType() == FluidStack.class) { + background(GuiTextures.SLOT_FLUID); + } else { + background(GuiTextures.SLOT_ITEM); // TODO other types + } return getThis(); } + @SuppressWarnings("unchecked") + private void rebuildReiSlot() { + slotWidget = Widgets.createSlot(new Point()).disableBackground(); + slotWidget.entries(convertToReiEntry(this.value, chance)); + if (recipeSlotRole == RecipeSlotRole.INPUT || recipeSlotRole == RecipeSlotRole.CATALYST) { + slotWidget.markInput(); + } else if (recipeSlotRole == RecipeSlotRole.OUTPUT) { + slotWidget.markOutput(); + } else { + slotWidget.unmarkInputOrOutput(); + } + } + private static EntryIngredient convertToReiEntry(EntryList entries, float chance) { + REIStackConverter.Converter converter = REIStackConverter.getForNullable(entries.getType()); + if (converter != null){ + return converter.convertTo(entries, chance, UnaryOperator.identity()); + } + return EntryIngredient.empty(); + } + @Override - public ReiRecipeViewerSlot chance(float chance) { - return getThis(); + public void draw(ModularGuiContext context, WidgetThemeEntry widgetTheme) { + context.getGraphics().pose().pushPose(); + context.getGraphics().pose().translate(-this.x, -this.y, 0); + this.slotWidget.render(context.getGraphics(), context.getMouseX(), context.getMouseY(), context.getRenderPartialTicks()); + context.getGraphics().pose().popPose(); + } + + @Override + public Result onMousePressed(int button) { + this.slotWidget.mouseClicked(getContext().getMouseX(), getContext().getAbsMouseY(), button); + return Result.SUCCESS; + } + + @Override + public Result onKeyPressed(int keyCode, int scanCode, int modifiers) { + return this.slotWidget.keyPressed(keyCode, scanCode, modifiers) ? Result.SUCCESS : Result.ACCEPT; } } diff --git a/src/main/java/brachy/modularui/integration/rei/recipe/ModularUIREIDisplay.java b/src/main/java/brachy/modularui/integration/rei/recipe/ModularUIREIDisplay.java index e1c43a59..a93dfc9e 100644 --- a/src/main/java/brachy/modularui/integration/rei/recipe/ModularUIREIDisplay.java +++ b/src/main/java/brachy/modularui/integration/rei/recipe/ModularUIREIDisplay.java @@ -9,6 +9,7 @@ import brachy.modularui.integration.recipeviewer.handlers.fluid.EmptyFluidTank; import brachy.modularui.integration.recipeviewer.util.RecipeScreenRenderingUtil; import brachy.modularui.integration.rei.REIStackConverter; +import brachy.modularui.integration.rei.ReiRecipeViewerSlot; import brachy.modularui.screen.ModularPanel; import brachy.modularui.screen.ModularScreen; import brachy.modularui.utils.memoization.MemoizedSupplier; @@ -18,6 +19,8 @@ import brachy.modularui.widgets.slot.FluidSlot; import brachy.modularui.widgets.slot.ItemSlot; +import me.shedaniel.rei.api.client.gui.widgets.Slot; + import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.events.GuiEventListener; import net.minecraft.network.chat.Component; @@ -72,16 +75,16 @@ public ModularUIREIDisplay(ResourceLocation recipeId, Supplier widgetSu }, Duration.ofSeconds(10)); WidgetTree.foreachChildBFS(widgetSupplier.get(), widget -> { - if (!(widget instanceof IngredientProvider provider)) return true; + if (!(widget instanceof ReiRecipeViewerSlot provider)) return true; - RecipeSlotRole role = provider.getRecipeRole(); + RecipeSlotRole role = provider.recipeSlotRole(); if (role == RecipeSlotRole.RENDER_ONLY) return true; - REIStackConverter.Converter converter = REIStackConverter.getForNullable(provider.ingredientClass()); + REIStackConverter.Converter converter = REIStackConverter.getForNullable(provider.getValue().getType()); if (converter == null) return true; @SuppressWarnings({"rawtypes", "unchecked"}) - EntryIngredient ingredient = ((REIStackConverter.Converter) converter).convertTo(provider); + EntryIngredient ingredient = EntryIngredient.of(provider.getSlotWidget().getEntries()); switch (role) { case INPUT -> inputEntries.add(ingredient); @@ -102,37 +105,22 @@ public List createWidgets(Rectangle bounds) { widgets.add(new UIWrapperWidget()); WidgetTree.foreachChildBFS(this.screen.get().getMainPanel(), widget -> { - if (!(widget instanceof IngredientProvider provider)) return true; + if (!(widget instanceof ReiRecipeViewerSlot provider)) return true; - RecipeSlotRole role = provider.getRecipeRole(); + RecipeSlotRole role = provider.recipeSlotRole(); if (role == RecipeSlotRole.RENDER_ONLY) return true; - REIStackConverter.Converter converter = REIStackConverter.getForNullable(provider.ingredientClass()); + REIStackConverter.Converter converter = REIStackConverter.getForNullable(provider.getValue().getType()); if (converter == null) return true; @SuppressWarnings({"rawtypes", "unchecked"}) - EntryIngredient ingredient = ((REIStackConverter.Converter) converter).convertTo(provider); + EntryIngredient ingredient = EntryIngredient.of(provider.getSlotWidget().getEntries()); Area area = widget.getArea(); - EntryWidget entryWidget = new EntryWidget(new Rectangle(area.x(), area.y(), area.w(), area.h())); - // Clear the MUI slots and add EMI slots based on them. - if (provider instanceof ItemSlot itemSlot) { - itemSlot.slot(RecipeScreenRenderingUtil.EMPTY_ITEM_HANDLER, 0).invisible(); - } else if (provider instanceof FluidSlot fluidSlot) { - fluidSlot.syncHandler(EmptyFluidTank.INSTANCE).invisible(); - } - - entryWidget.background(false) - .entries(ingredient.castAsList()); - if (role == RecipeSlotRole.INPUT) { - entryWidget.markIsInput(); - } else if (role == RecipeSlotRole.OUTPUT) { - entryWidget.markIsOutput(); - } else { - entryWidget.unmarkInputOrOutput(); - } - if (widget instanceof ITooltip tooltip && tooltip.hasTooltip()) { - if (tooltip.tooltip().getRichText() instanceof RichText richText) { + Slot entryWidget = provider.getSlotWidget(); +/* + if (provider.hasTooltip()) { + if (provider.tooltip().getRichText() instanceof RichText richText) { var textList = richText.getAsText(); entryWidget.tooltipProcessor(text -> { textList.forEach(line -> line.map(t -> text.add((Component) t), text::add)); @@ -140,6 +128,7 @@ public List createWidgets(Rectangle bounds) { }); } } +*/ widgets.add(entryWidget); return true; }, true);