界面与面板(ModularScreen / ModularPanel / ModularContainer)

基本信息

属性 值
包路径 com.cleanroommc.modularui.screen
文件数 17(另有 viewport/ 7)
界面基类 ModularScreen
面板基类 ModularPanel
容器基类 ModularContainer

ModularUI2 的界面是三层结构:原版 GuiScreen → ModularScreen → ModularPanel, 而 ModularContainer(服务端 Container)负责物品同步。

功能

三层结构

层 类 文件:行 职责
原版 net.minecraft.client.gui.GuiScreen —— 底层,由 Mixin 补丁(core/mixins/early/minecraft/GuiScreenMixin.java)接入
界面 ModularScreen screen/ModularScreen.java:58 持有 ModularPanel、处理输入分发
面板 ModularPanel screen/ModularPanel.java:63(extends ParentWidget<ModularPanel> implements IViewport, IDragResizeable) 真正构建控件树的地方,被其他 mod 继承
容器 ModularContainer screen/ModularContainer.java:38(extends net.minecraft.inventory.Container) 服务端 Container,每 tick 调 onUpdate()

关键点:ModularPanel 本身就是一个 ParentWidget<ModularPanel>—— 面板既是界面根,也是布局容器。ModularPanel 内还有 enum State(:961)表示面板状态。 ModularPanel 直接依赖 NEA 动画(screen/ModularPanel.java:35 导入 com.cleanroommc.neverenoughanimations.NEAConfig),物品移动动画由 screen/NEAAnimationHandler.java:30 驱动。

辅助类(screen/)

类 文件:行 继承 / 实现 用途
PanelManager screen/PanelManager.java:24 内含 enum State(:479) 面板栈管理(主面板 + 副面板)
SecondaryPanel screen/SecondaryPanel.java:15 implements IPanelHandler,内含 IPanelBuilder(:103) 叠加在主面板之上的副面板
DraggablePanelWrapper screen/DraggablePanelWrapper.java:11 implements IDraggable 可拖动窗口
GuiScreenWrapper screen/GuiScreenWrapper.java:12 extends GuiScreen implements IMuiScreen 包装原版 GuiScreen 以嵌入 MUI2 面板
GuiContainerWrapper screen/GuiContainerWrapper.java:12 extends GuiContainer implements IMuiScreen 同上,针对 GuiContainer
IClickableGuiContainer screen/IClickableGuiContainer.java:5 接口 可点击的原版容器
ClientScreenHandler screen/ClientScreenHandler.java:79 — 客户端事件总线处理器(ClientProxy.java:66-69 注册)
RichTooltip screen/RichTooltip.java:35 implements IRichTextBuilder<RichTooltip>,内含 enum Pos(:444) 富提示气泡(见 提示气泡)
RichTooltipEvent screen/RichTooltipEvent.java:14 extends Event 提示气泡事件
OpenScreenEvent screen/OpenScreenEvent.java:13 extends Event 打开界面事件
UISettings screen/UISettings.java:21 内含 GuiCreator(:137) 界面通用设置
RecipeViewerSettingsImpl screen/RecipeViewerSettingsImpl.java:26 implements RecipeViewerSettings 配方查看器设置实现
NEAAnimationHandler screen/NEAAnimationHandler.java:30 — NEA 物品动画

与原版 GUI 的互操作

仓库自带的 test/TestEventHandler.java 演示了如何用 GuiContainerAccessor (Mixin 生成的访问器)把原版 GuiContainer 的尺寸转成 MUI2 面板坐标:

// TestEventHandler.java:166-167
return ModularPanel.defaultPanel("watermark_overlay",
        ((GuiContainerAccessor) gui).getXSize(), ((GuiContainerAccessor) gui).getYSize())
        .pos(((GuiContainerAccessor) gui).getGuiLeft(), ((GuiContainerAccessor) gui).getGuiTop())
// TestEventHandler.java:175-178(onResize 内重复一次)
getMainPanel().pos(((GuiContainerAccessor) gui).getGuiLeft(), ((GuiContainerAccessor) gui).getGuiTop())
        .size(((GuiContainerAccessor) gui).getXSize(), ((GuiContainerAccessor) gui).getYSize());

服务端每 tick 更新

CommonProxy.onTick(CommonProxy.java:68-73)监听 TickEvent.PlayerTickEvent, 若 event.player.openContainer instanceof ModularContainer container 则调 container.onUpdate()。这是服务端向客户端推送同步的时机。

交互

触发 行为
打开界面 OpenGuiPacket → 客户端建 ModularScreen + ModularPanel
服务端每玩家 tick ModularContainer.onUpdate()
重开界面 ReopenGuiPacket(不重建 Container,只重建面板)
关闭 / 关闭全部 CloseGuiPacket / CloseAllGuiPacket
玩家登出 ModularNetwork.SERVER.onPlayerLeave(player)(CommonProxy.java:78)
客户端世界卸载 ModularNetwork.CLIENT.onPlayerLeave(player)(ClientProxy.java:199)

相关条目