Lua接口/客户端界面布局
来自天龙知识库
客户端界面布局 XML
352 个
.layout.xml · 13584 个控件 · 142 种控件类型 · 6005 条事件绑定一个界面是两个文件
| 文件 | 作用 |
|---|---|
<目录>/<脚本>.lua
|
界面逻辑:注册事件、改文字、调接口。所有判断与数据都写在这里。 |
<目录>/<布局>.layout.xml
|
控件层级与外观:摆在哪、多大、什么样式、点了调哪个函数。 |
哪个功能对应哪两个文件,见客户端界面索引;本页只讲 .layout.xml 里能写什么、它和 Lua 怎么接。
加载顺序
界面第一次显示时按下面顺序走一遍(实现见客户端 CEGUISystem/UIWindowMng.cpp):
- 创建界面对象,把
this注入脚本环境(this可调窗口操作里的方法)。 - 执行
<界面名>_PreLoad():此时控件还不存在,只能做准备(取配置、置标记)。 - 读取并解析
.layout.xml,挂到屏幕上并先隐藏。 - 递归注册控件:布局里每个
<Window Name="X">都成为脚本里的一个变量X。 - 执行
<界面名>_OnLoad():这时才能安全地改控件。
所以脚本里可以直接写 DressPaint_Text:SetText("") —— DressPaint_Text 不是脚本里声明的局部变量,而是加载布局时按控件名注册进来的。在 _PreLoad 里访问控件会拿到 nil。
三条接缝
| 布局里写的 | 脚本里对应的 |
|---|---|
<Window Name="DressPaint_Text">
|
同名全局变量,直接 DressPaint_Text:方法(...) 使用
|
<Event Name="Clicked" Function="DressPaint_TurnLeft(1);">
|
全局函数 function DressPaint_TurnLeft(n)(可带实参)
|
<Property Name="Text" Value="#{SZPR_XML_13}" />
|
不写脚本,取值来自 Data/Config/StrDictionary.txt 的 SZPR_XML_13
|
事件绑定实测 5158 条指向具体全局函数,其中 5095 条能在同目录的 .lua 里找到 function 同名 定义;剩下 63 条要么在别的脚本里定义,要么是引擎内建回调。
布局文件长什么样
以 DressPaint/DressPaint.layout.xml 开头几行为例(属性只留关键几条):
<?xml version="1.0" ?>
<GUILayout>
<Window Type="TLBB_MainFrame1" Name="DressPaint_Frame">
<Property Name="UnifiedPosition" Value="{{0.5,-250},{0.5,-200}" />
<Property Name="AbsoluteSize" Value="w:500 h:365" />
<Event Name="Hidden" Function="DressPaint_OnHiden();" />
<Window Type="TLBB_DragTitle" Name="DressPaint_DragTitle">
<Property Name="DragTarget" Value="DressPaint_Frame" />
<Window Type="TLBB_SimpleText" Name="DressPaint_Title">
<Property Name="Text" Value="#{SZPR_XML_13}" />
</Window>
</Window>
</Window>
</GUILayout>
要点:<Window> 可以嵌套(子控件坐标相对父控件);Type 决定控件类(决定它有哪些方法可用);Name 决定脚本里的变量名,同一界面内必须唯一。
控件类型(最常见)
共 142 种类型。括号里是布局中出现的控件个数:
| 类型 | 个数 |
|---|---|
TLBB_SimpleText
|
2136 |
TLBB_StaticImageNULL
|
1849 |
TLBB_ActionButton
|
1439 |
TLBB_ButtonCommon
|
977 |
TLBB_SimpleMulitiTextFrame
|
913 |
DefaultWindow
|
837 |
TLBB_DragTitle
|
303 |
TLBB_ButtonClose
|
301 |
TLBB_ButtonHelp
|
293 |
TLBB_Money
|
286 |
TLBB_ButtonNULL
|
285 |
TLBB_MainFrame1
|
215 |
TLBB_Frame_Lace5
|
184 |
TLBB_Frame_Lace1
|
170 |
TLBB_ButtonCheck
|
167 |
TLBB_StopWatch
|
150 |
TLBB_MenuItem
|
149 |
TLBB_MainFrameNULL
|
144 |
TLBB_SimpleTextFrame
|
140 |
TLBB_ActionButtonNULL
|
133 |
名字带 TLBB_ 前缀的是本项目的皮肤控件(外观在 Data/Interface/Schema/ 里定义);DefaultWindow 是 CEGUI 原生空容器,常用来做分组与对齐。控件上可用的方法见窗口操作。
常用属性(最常见)
共 138 个属性名:
| 属性 | 出现次数 |
|---|---|
UnifiedPosition
|
8414 |
UnifiedSize
|
7462 |
AbsoluteSize
|
5143 |
Text
|
4797 |
HorzFormatting
|
3657 |
AbsolutePosition
|
3531 |
VertFormatting
|
2724 |
TextColor
|
2452 |
RiseOnClick
|
2104 |
MouseHollow
|
2053 |
Image
|
1470 |
MouseMoveHollow
|
1449 |
Position
|
1369 |
Visible
|
1112 |
DraggingEnabled
|
886 |
MouseRButtonHollow
|
868 |
AlwaysOnTop
|
837 |
MouseLButtonHollow
|
829 |
Size
|
820 |
Empty
|
801 |
UnifiedPosition/UnifiedSize是相对父控件的比例 + 像素偏移,写作{{0.5,-250},{0.5,-200}}表示「横向 50% 再左移 250px,纵向 50% 再上移 200px」;AbsolutePosition/AbsoluteSize则是绝对坐标,窗口拉伸时不会跟着变。RiseOnClick与MouseHollow/MouseMoveHollow影响点击穿透,叠放控件时最容易出问题。- 颜色属性写
#AARRGGBB形式的十六进制。
事件(最常见)
共 41 种事件名、6005 条绑定:
| 事件 | 绑定次数 |
|---|---|
Clicked
|
3212 |
RBClicked
|
531 |
MouseLButtonDown
|
451 |
MouseButtonUp
|
260 |
MouseRClick
|
245 |
Hidden
|
201 |
MouseEnter
|
196 |
MouseLeave
|
181 |
MouseButtonDown
|
163 |
CaptureLost
|
109 |
MouseLClick
|
90 |
MouseDoubleClick
|
69 |
Hidden 是界面被隐藏时触发(用于收尾清理),Clicked / RBClicked 是左/右键点击,CaptureLost 常用于「按住拖动后松手」的收尾。
命名约定
- 框架窗口用
<界面>_Frame,标题栏<界面>_DragTitle,标题文字<界面>_Title,关闭<界面>_Close,帮助<界面>_Help。界面索引里的大多数中文名正是靠_Frame/_DragTitle/_Title这三个名字反查到的。 - 控件名一律带界面前缀(
DressPaint_Text而不是Text):注册成全局变量后,不带前缀极易和别的界面撞名。 - 布局里的可见文字不写中文,写
#{键名}并在StrDictionary.txt里给键值;直接写中文不会进字符串表,改字与多语言都会失控。
改界面时会踩的坑
- 界面目录名 ≠ 窗口名:
OpenWindow("X")用的是窗口名,而窗口名由创建界面的代码给出。改目录名不会改窗口名,两者不一致是常态(如Materalcompose/MaterialCompound.lua)。 - 一个目录可能有多套界面(如
GuildLeague下 4 个脚本各自一套),改布局前先确认改的是对的那个.layout.xml。 - 客户端脚本里的数值(成功率、花费、坐标)只决定界面怎么显示,真正的判定在服务端;想让玩法变,改的不是这里。
- 新增控件后如果脚本里取到
nil,先确认Name拼写、是否重复、以及是否在_PreLoad阶段就访问了。