From 2c818cf492a05c74681fbc5f5dfacba2960ae56a Mon Sep 17 00:00:00 2001 From: shedaniel Date: Fri, 15 Apr 2022 12:39:44 +0800 Subject: [PATCH] [ci skip] Add container render events (#240) --- .../event/events/client/ClientGuiEvent.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/dev/architectury/mixin/fabric/client/MixinAbstractContainerScreen.java diff --git a/common/src/main/java/dev/architectury/event/events/client/ClientGuiEvent.java b/common/src/main/java/dev/architectury/event/events/client/ClientGuiEvent.java index 43198961..201af93a 100644 --- a/common/src/main/java/dev/architectury/event/events/client/ClientGuiEvent.java +++ b/common/src/main/java/dev/architectury/event/events/client/ClientGuiEvent.java @@ -28,6 +28,7 @@ import dev.architectury.hooks.client.screen.ScreenAccess; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import java.util.List; @@ -58,6 +59,14 @@ public interface ClientGuiEvent { * @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.createEventResult(); + /** + * @see ContainerScreenRenderForeground#render(AbstractContainerScreen, PoseStack, int, int, float) + */ + Event RENDER_CONTAINER_FOREGROUND = EventFactory.createLoop(); /** * @see SetScreen#modifyScreen(Screen) */ @@ -145,6 +154,36 @@ public interface ClientGuiEvent { 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/dev/architectury/mixin/fabric/client/MixinAbstractContainerScreen.java b/fabric/src/main/java/dev/architectury/mixin/fabric/client/MixinAbstractContainerScreen.java new file mode 100644 index 00000000..1b07b20a --- /dev/null +++ b/fabric/src/main/java/dev/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 dev.architectury.mixin.fabric.client; + +import com.mojang.blaze3d.vertex.PoseStack; +import dev.architectury.event.events.client.ClientGuiEvent; +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) { + ClientGuiEvent.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) { + ClientGuiEvent.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 f036e515..79cb1f92 100644 --- a/fabric/src/main/resources/architectury.mixins.json +++ b/fabric/src/main/resources/architectury.mixins.json @@ -5,6 +5,7 @@ "compatibilityLevel": "JAVA_16", "minVersion": "0.7.11", "client": [ + "client.MixinAbstractContainerScreen", "client.MixinClientLevel", "client.MixinClientPacketListener", "client.MixinDebugScreenOverlay", diff --git a/forge/src/main/java/dev/architectury/event/forge/EventHandlerImplClient.java b/forge/src/main/java/dev/architectury/event/forge/EventHandlerImplClient.java index f45685ba..84b55af5 100644 --- a/forge/src/main/java/dev/architectury/event/forge/EventHandlerImplClient.java +++ b/forge/src/main/java/dev/architectury/event/forge/EventHandlerImplClient.java @@ -150,6 +150,16 @@ public class EventHandlerImplClient { ClientGuiEvent.RENDER_POST.invoker().render(event.getScreen(), event.getPoseStack(), event.getMouseX(), event.getMouseY(), event.getPartialTicks()); } + @SubscribeEvent(priority = EventPriority.HIGH) + public static void event(ContainerScreenEvent.DrawBackground event) { + ClientGuiEvent.RENDER_CONTAINER_BACKGROUND.invoker().render(event.getContainerScreen(), event.getPoseStack(), event.getMouseX(), event.getMouseY(), Minecraft.getInstance().getDeltaFrameTime()); + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public static void event(ContainerScreenEvent.DrawForeground event) { + ClientGuiEvent.RENDER_CONTAINER_FOREGROUND.invoker().render(event.getContainerScreen(), event.getPoseStack(), 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());