From 1a52108414f3201c6d4390e5f7b626852be34e14 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Fri, 15 Apr 2022 12:39:44 +0800 Subject: [PATCH] Add container render events (#240) (cherry picked from commit 2c818cf492a05c74681fbc5f5dfacba2960ae56a) (cherry picked from commit e8ce7dbcb20896597b7f0310b1b3c4e3fe9f72ca) --- .../architectury/event/events/GuiEvent.java | 39 ++++++++++++++ .../client/MixinAbstractContainerScreen.java | 51 +++++++++++++++++++ .../main/resources/architectury.mixins.json | 1 + .../event/forge/EventHandlerImplClient.java | 10 ++++ 4 files changed, 101 insertions(+) create mode 100644 fabric/src/main/java/me/shedaniel/architectury/mixin/fabric/client/MixinAbstractContainerScreen.java diff --git a/common/src/main/java/me/shedaniel/architectury/event/events/GuiEvent.java b/common/src/main/java/me/shedaniel/architectury/event/events/GuiEvent.java index 1c1357b3..30e188f8 100644 --- a/common/src/main/java/me/shedaniel/architectury/event/events/GuiEvent.java +++ b/common/src/main/java/me/shedaniel/architectury/event/events/GuiEvent.java @@ -27,6 +27,7 @@ import net.fabricmc.api.Environment; import net.minecraft.client.gui.components.AbstractWidget; import net.minecraft.client.gui.components.events.GuiEventListener; import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.world.InteractionResult; import net.minecraft.world.InteractionResultHolder; @@ -59,6 +60,14 @@ public interface GuiEvent { * @see ScreenRenderPost#render(Screen, PoseStack, int, int, float) */ Event RENDER_POST = EventFactory.createLoop(); + /** + * @see ContainerScreenRenderBackground#render(AbstractContainerScreen, PoseStack, int, int, float) + */ + Event RENDER_CONTAINER_BACKGROUND = EventFactory.createLoop(); + /** + * @see ContainerScreenRenderForeground#render(AbstractContainerScreen, PoseStack, int, int, float) + */ + Event RENDER_CONTAINER_FOREGROUND = EventFactory.createLoop(); /** * @see SetScreen#modifyScreen(Screen) */ @@ -146,6 +155,36 @@ public interface GuiEvent { void render(Screen screen, PoseStack matrices, int mouseX, int mouseY, float delta); } + @Environment(EnvType.CLIENT) + interface ContainerScreenRenderBackground { + /** + * Invoked after a container screen's background are rendered. + * Equivalent to Forge's {@code ContainerScreenEvent.DrawBackground} event. + * + * @param screen The screen. + * @param matrices The pose stack. + * @param mouseX The scaled x-coordinate of the mouse cursor. + * @param mouseY The scaled y-coordinate of the mouse cursor. + * @param delta The current tick delta. + */ + void render(AbstractContainerScreen screen, PoseStack matrices, int mouseX, int mouseY, float delta); + } + + @Environment(EnvType.CLIENT) + interface ContainerScreenRenderForeground { + /** + * Invoked after a screen has finished rendering most of the foreground, but before any floating widgets are rendered. + * Equivalent to Forge's {@code ContainerScreenEvent.DrawForeground} event. + * + * @param screen The screen. + * @param matrices The pose stack. + * @param mouseX The scaled x-coordinate of the mouse cursor. + * @param mouseY The scaled y-coordinate of the mouse cursor. + * @param delta The current tick delta. + */ + void render(AbstractContainerScreen screen, PoseStack matrices, int mouseX, int mouseY, float delta); + } + @Environment(EnvType.CLIENT) interface SetScreen { /** diff --git a/fabric/src/main/java/me/shedaniel/architectury/mixin/fabric/client/MixinAbstractContainerScreen.java b/fabric/src/main/java/me/shedaniel/architectury/mixin/fabric/client/MixinAbstractContainerScreen.java new file mode 100644 index 00000000..a3f10bfd --- /dev/null +++ b/fabric/src/main/java/me/shedaniel/architectury/mixin/fabric/client/MixinAbstractContainerScreen.java @@ -0,0 +1,51 @@ +/* + * This file is part of architectury. + * Copyright (C) 2020, 2021, 2022 architectury + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package me.shedaniel.architectury.mixin.fabric.client; + +import com.mojang.blaze3d.vertex.PoseStack; +import me.shedaniel.architectury.event.events.GuiEvent; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.network.chat.Component; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(AbstractContainerScreen.class) +public abstract class MixinAbstractContainerScreen extends Screen { + protected MixinAbstractContainerScreen(Component component) { + super(component); + } + + @Inject(method = "render", + at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/inventory/AbstractContainerScreen;renderBg(Lcom/mojang/blaze3d/vertex/PoseStack;FII)V", + ordinal = 0, shift = At.Shift.AFTER)) + public void renderBackground(PoseStack poseStack, int mouseX, int mouseY, float delta, CallbackInfo ci) { + GuiEvent.RENDER_CONTAINER_BACKGROUND.invoker().render((AbstractContainerScreen) (Object) this, poseStack, mouseX, mouseY, delta); + } + + @Inject(method = "render", + at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/inventory/AbstractContainerScreen;renderLabels(Lcom/mojang/blaze3d/vertex/PoseStack;II)V", + ordinal = 0, shift = At.Shift.AFTER)) + public void renderForeground(PoseStack poseStack, int mouseX, int mouseY, float delta, CallbackInfo ci) { + GuiEvent.RENDER_CONTAINER_FOREGROUND.invoker().render((AbstractContainerScreen) (Object) this, poseStack, mouseX, mouseY, delta); + } +} \ No newline at end of file diff --git a/fabric/src/main/resources/architectury.mixins.json b/fabric/src/main/resources/architectury.mixins.json index e979cd9f..eb09eb2f 100644 --- a/fabric/src/main/resources/architectury.mixins.json +++ b/fabric/src/main/resources/architectury.mixins.json @@ -5,6 +5,7 @@ "compatibilityLevel": "JAVA_8", "minVersion": "0.7.11", "client": [ + "client.MixinAbstractContainerScreen", "client.MixinClientLevel", "client.MixinClientPacketListener", "client.MixinDebugScreenOverlay", diff --git a/forge/src/main/java/me/shedaniel/architectury/event/forge/EventHandlerImplClient.java b/forge/src/main/java/me/shedaniel/architectury/event/forge/EventHandlerImplClient.java index 64b52a4d..f5d5d132 100644 --- a/forge/src/main/java/me/shedaniel/architectury/event/forge/EventHandlerImplClient.java +++ b/forge/src/main/java/me/shedaniel/architectury/event/forge/EventHandlerImplClient.java @@ -151,6 +151,16 @@ public class EventHandlerImplClient { GuiEvent.RENDER_POST.invoker().render(event.getGui(), event.getMatrixStack(), event.getMouseX(), event.getMouseY(), event.getRenderPartialTicks()); } + @SubscribeEvent(priority = EventPriority.HIGH) + public static void event(GuiContainerEvent.DrawBackground event) { + GuiEvent.RENDER_CONTAINER_BACKGROUND.invoker().render(event.getGuiContainer(), event.getMatrixStack(), event.getMouseX(), event.getMouseY(), Minecraft.getInstance().getDeltaFrameTime()); + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public static void event(GuiContainerEvent.DrawForeground event) { + GuiEvent.RENDER_CONTAINER_FOREGROUND.invoker().render(event.getGuiContainer(), event.getMatrixStack(), event.getMouseX(), event.getMouseY(), Minecraft.getInstance().getDeltaFrameTime()); + } + @SubscribeEvent(priority = EventPriority.HIGH) public static void event(PlayerInteractEvent.RightClickEmpty event) { InteractionEvent.CLIENT_RIGHT_CLICK_AIR.invoker().click(event.getPlayer(), event.getHand());