界面与面板(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) |
相关条目
- 视口与绘制上下文 -
ModularGuiContext与坐标变换栈 - 提示气泡 -
RichTooltip的定位与渲染 - GUI 工厂 - 界面如何被打开
- Mixin 与底层补丁 -
GuiScreen/GuiContainer的接入点