修改服务器表单¶
本页介绍如何使用JSON UI的factory机制为server_form.json中的动作表单(Action Form)和模态表单(Modal Form)添加自定义界面,同时保持与原版表单的兼容性。
适用范围
本页内容基于国际版JSON UI。中国版模组SDK提供了专有的服务器表单接口。
原理概述¶
server_form.json使用一种叫做工厂(Factory)的机制来生成表单界面:当服务端向客户端发送特定类型的表单数据时,名为server_form_factory的工厂会根据数据类型,将对应的control_ids中的控件渲染到屏幕上。其中:
long_form对应动作表单custom_form对应模态表单
通过向main_screen_content的controls数组插入一个新的工厂面板,并在control_ids中引用自定义控件,就可以在不破坏原版表单的前提下叠加自定义界面。
修改动作表单¶
第一步:插入自定义工厂¶
向main_screen_content的controls数组末尾插入一个新的工厂面板,引用自定义的long_form控件。注意:工厂面板的名称不能与原版的server_form_factory相同。
{
"main_screen_content": {
"modifications": [
{
"array_name": "controls",
"operation": "insert_back",
"value": [
{
"wiki_server_form_factory": {
"type": "panel",
"factory": {
"name": "server_form_factory",
"control_ids": {
"long_form": "@server_form.our_long_form_panel"
}
}
}
}
]
}
]
}
}
建议只插入一个工厂,将所有自定义表单逻辑集中到our_long_form_panel中统一管理,以减少维护成本。
第二步:定义自定义表单面板¶
通过#title_text绑定获取表单标题,再利用绑定表达式判断标题是否包含特定前缀,从而控制各自定义表单内容的显隐。
{
"our_long_form_panel": {
"type": "panel",
"bindings": [
{
"binding_name": "#title_text"
}
],
"controls": [
{
"our_custom_made_long_form": {
"type": "image",
"texture": "textures/items/apple",
"size": [32, 32],
"$title_needs_to_contain": "wiki_form:",
"bindings": [
{
"binding_type": "view",
"source_control_name": "our_long_form_panel",
"source_property_name": "(not ((#title_text - $title_needs_to_contain) = #title_text))",
"target_property_name": "#visible"
}
]
}
}
]
}
}
在source_property_name中,表达式((#title_text - $title_needs_to_contain) = #title_text)的含义是:从#title_text中减去前缀字符串后,若结果与原始文本相同,说明原始文本中不含该前缀。取反后,"当标题含前缀时显示"的逻辑即可成立。
第三步:避免与原版表单重叠¶
如果此时测试,会发现自定义内容与原版表单同时显示。需要向原版的long_form控件添加额外绑定,使其在自定义表单显示时隐藏自身。
{
"long_form": {
"modifications": [
{
"array_name": "bindings",
"operation": "insert_back",
"value": [
{
"binding_name": "#title_text"
},
{
"binding_type": "view",
"source_property_name": "((#title_text - 'wiki_form:') = #title_text)",
"target_property_name": "#visible"
}
]
}
]
}
}
表达式((#title_text - 'wiki_form:') = #title_text)在标题不含wiki_form:前缀时为true,即原版表单只在标题不带自定义前缀时可见。
支持多个自定义前缀
可以串联多个减法判断,例如:
这样三种前缀都会触发隐藏原版表单。修改模态表单¶
模态表单(在server_form.json内部称为custom_form)的修改方式与动作表单相同,只需额外在control_ids中添加custom_form映射,并同样对原版的custom_form控件添加隐藏绑定。
插入工厂¶
{
"main_screen_content": {
"modifications": [
{
"array_name": "controls",
"operation": "insert_back",
"value": [
{
"wiki_server_form_factory": {
"type": "panel",
"factory": {
"name": "server_form_factory",
"control_ids": {
"long_form": "@server_form.our_long_form_panel",
"custom_form": "@server_form.our_custom_form_panel"
}
}
}
}
]
}
]
}
}
定义模态表单面板¶
{
"our_custom_form_panel": {
"type": "panel",
"bindings": [
{
"binding_name": "#title_text"
}
],
"controls": [
{
"our_custom_made_custom_form": {
"type": "image",
"texture": "textures/items/apple",
"size": [32, 32],
"$title_needs_to_contain": "wiki_form:",
"bindings": [
{
"binding_type": "view",
"source_control_name": "our_custom_form_panel",
"source_property_name": "(not ((#title_text - $title_needs_to_contain) = #title_text))",
"target_property_name": "#visible"
}
]
}
}
]
}
}
隐藏原版模态表单¶
{
"custom_form": {
"modifications": [
{
"array_name": "bindings",
"operation": "insert_back",
"value": [
{
"binding_name": "#title_text"
},
{
"binding_type": "view",
"source_property_name": "((#title_text - 'wiki_form:') = #title_text)",
"target_property_name": "#visible"
}
]
}
]
}
}
注意事项¶
- 工厂面板名称不能与
server_form_factory相同,且同级工厂面板名称也不能互相重复。 - 建议每种表单类型只插入一个工厂,将所有自定义表单逻辑集中在一个主面板中。
- 标题前缀约定建议在项目内统一规范,避免不同包之间的命名冲突。
- 上述示例以图片展示效果为例,实际使用时可将
our_custom_made_long_form替换为任意自定义控件面板。