浏览代码

Add container render events (#240)

(cherry picked from commit 2c818cf492a05c74681fbc5f5dfacba2960ae56a)

(cherry picked from commit e8ce7dbcb20896597b7f0310b1b3c4e3fe9f72ca)
shedaniel 3 年之前
父节点
当前提交
1a52108414

+ 39 - 0
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<ScreenRenderPost> RENDER_POST = EventFactory.createLoop();
+    /**
+     * @see ContainerScreenRenderBackground#render(AbstractContainerScreen, PoseStack, int, int, float)
+     */
+    Event<ContainerScreenRenderBackground> RENDER_CONTAINER_BACKGROUND = EventFactory.createLoop();
+    /**
+     * @see ContainerScreenRenderForeground#render(AbstractContainerScreen, PoseStack, int, int, float)
+     */
+    Event<ContainerScreenRenderForeground> 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 {
         /**

+ 51 - 0
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);
+    }
+}

+ 1 - 0
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",

+ 10 - 0
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());