mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-12 08:17:35 +00:00
Implement GUI Stacking feature. (#8130)
You can now use `mc.pushGuiLayer` and `mc.popGuiLayer` to manage the layers. mc.setScreen behaves such that if called with a non-null screen it replaces the entire stack, and if called with null it closes the entire stack.
This commit is contained in:
1 parent
fd544dd414
commit
9944a8252a
7 files changed
+258
-2
No files matched your search
@@ -23,6 +23,7 @@ import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.*;
|
||||
import net.minecraft.client.gui.chat.NarratorChatListener;
|
||||
import net.minecraft.client.gui.screens.multiplayer.JoinMultiplayerScreen;
|
||||
import net.minecraft.client.model.geom.ModelLayerLocation;
|
||||
import net.minecraft.client.model.geom.builders.LayerDefinition;
|
||||
@@ -127,7 +128,16 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.Buffer;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -150,6 +160,55 @@ public class ForgeHooksClient
|
||||
|
||||
//private static final ResourceLocation ITEM_GLINT = new ResourceLocation("textures/misc/enchanted_item_glint.png");
|
||||
|
||||
/**
|
||||
* Contains the *extra* GUI layers.
|
||||
* The current top layer stays in Minecraft#currentScreen, and the rest serve as a background for it.
|
||||
*/
|
||||
private static final Stack<Screen> guiLayers = new Stack<>();
|
||||
|
||||
public static void clearGuiLayers(Minecraft minecraft)
|
||||
{
|
||||
while(guiLayers.size() > 0)
|
||||
popGuiLayerInternal(minecraft);
|
||||
}
|
||||
|
||||
private static void popGuiLayerInternal(Minecraft minecraft)
|
||||
{
|
||||
if (minecraft.screen != null)
|
||||
minecraft.screen.removed();
|
||||
minecraft.screen = guiLayers.pop();
|
||||
}
|
||||
|
||||
public static void pushGuiLayer(Minecraft minecraft, Screen screen)
|
||||
{
|
||||
if (minecraft.screen != null)
|
||||
guiLayers.push(minecraft.screen);
|
||||
minecraft.screen = Objects.requireNonNull(screen);
|
||||
screen.init(minecraft, minecraft.getWindow().getGuiScaledWidth(), minecraft.getWindow().getGuiScaledHeight());
|
||||
NarratorChatListener.INSTANCE.sayNow(screen.getNarrationMessage());
|
||||
}
|
||||
|
||||
public static void popGuiLayer(Minecraft minecraft)
|
||||
{
|
||||
if (guiLayers.size() == 0)
|
||||
{
|
||||
minecraft.setScreen(null);
|
||||
return;
|
||||
}
|
||||
|
||||
popGuiLayerInternal(minecraft);
|
||||
if (minecraft.screen != null)
|
||||
NarratorChatListener.INSTANCE.sayNow(minecraft.screen.getNarrationMessage());
|
||||
}
|
||||
|
||||
public static float getGuiFarPlane()
|
||||
{
|
||||
// 1000 units for the overlay background,
|
||||
// and 2000 units for each layered Screen,
|
||||
|
||||
return 1000.0F + 2000.0F * (1 + guiLayers.size());
|
||||
}
|
||||
|
||||
public static String getArmorTexture(Entity entity, ItemStack armor, String _default, EquipmentSlot slot, String type)
|
||||
{
|
||||
String result = armor.getItem().getArmorTexture(armor, entity, slot, type);
|
||||
@@ -310,6 +369,18 @@ public class ForgeHooksClient
|
||||
}
|
||||
|
||||
public static void drawScreen(Screen screen, PoseStack mStack, int mouseX, int mouseY, float partialTicks)
|
||||
{
|
||||
mStack.pushPose();
|
||||
guiLayers.forEach(layer -> {
|
||||
// Prevent the background layers from thinking the mouse is over their controls and showing them as highlighted.
|
||||
drawScreenInternal(layer, mStack, Integer.MAX_VALUE, Integer.MAX_VALUE, partialTicks);
|
||||
mStack.translate(0,0,2000);
|
||||
});
|
||||
drawScreenInternal(screen, mStack, mouseX, mouseY, partialTicks);
|
||||
mStack.popPose();
|
||||
}
|
||||
|
||||
private static void drawScreenInternal(Screen screen, PoseStack mStack, int mouseX, int mouseY, float partialTicks)
|
||||
{
|
||||
if (!MinecraftForge.EVENT_BUS.post(new GuiScreenEvent.DrawScreenEvent.Pre(screen, mStack, mouseX, mouseY, partialTicks)))
|
||||
screen.render(mStack, mouseX, mouseY, partialTicks);
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016-2021.
|
||||
*
|
||||
* This library 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 version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library 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 library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.client.extensions;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraftforge.client.ForgeHooksClient;
|
||||
|
||||
public interface IForgeMinecraft
|
||||
{
|
||||
private Minecraft self() { return (Minecraft)this; }
|
||||
|
||||
default void pushGuiLayer(Screen screen)
|
||||
{
|
||||
ForgeHooksClient.pushGuiLayer(self(), screen);
|
||||
}
|
||||
|
||||
default void popGuiLayer()
|
||||
{
|
||||
ForgeHooksClient.popGuiLayer(self());
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user