.ui文件 c语言,UI说明文档

UI使用规范

文件命名规范json文件名 json中的namespace python文件名 三者需要一致

示例中为"myUIName"​x

myUIName.json​"namespace" : "myUIName"​myUIName.py​

JSON规范

Json是UI界面的显示内容和绑定的集合,UI是一种树状的组织结构,界面和界面中的控件都是一个UI Node节点,后续的很多方法的调用也需要这个树状结构的路径来标识。注:暂时Json只能通过手写来构筑界面,后续会开放相应的UI编辑器供开发者使用。

命名空间

命名空间是这个界面的名称,我们规定json文件名和namespace一致。xxxxxxxxxx

"namespace" : "myUIName"

Main Screen

main是这个界面名称,我们规定使用main,即一个json文件是一个界面。

controls中的内容是该界面下的树状节点,即子节点。xxxxxxxxxx

"main@common.base_screen" : {"controls" : []}变量解释main@common.base_screen表示main screen是common.base_screen的一个子类xxxxxxxxxx

my_namespace|____main|test_image|test_panel|test_label关于控件的适配问题,固定大小像素能在屏幕像素发生变化时保持形状大小不变,而百分比则能够保持与屏幕分辨率一致的比例,可能导致控件变形。

控件介绍

Label

Label 是文本框控件,用来显示文本信息,默认的字体是MC字体,如果有中文会变成中文字体格式,暂时不支持换字体,可以通过接口统一设置字体,如果需要设置后续有介绍。xxxxxxxxxx

"label" : {"anchor_from" : "top_left","anchor_to" : "top_left","auto_expand" : false,"color" : [ 1, 1, 0, 0.8],"font_size" : "large","layer" : 5,"offset" : [ "0%+0px", "0%+0px" ],"shadow" : false,"size" : [ "83.80282%+0px", "100%+0px" ],"text" : "Hello World","text_alignment" : "center","type" : "label","visible" : true},变量解释anchor_from挂接在父节点锚点的位置,取值范围["top_left", "top_middle", "top_right", "left_middle", "center", "right_middle", "bottom_left", "bottom_middle", "bottom_right"]

anchor_to自身挂接锚点的位置,取值同anchor_from

auto_expand该变量暂时无效,可删除

color字体颜色(r , g, b, a)取值范围[0 , 1]

font_size字体大小,取值["large", "normal", "small"]

layerlabel的相对父节点的层级,最终显示层级取决于父节点到该节点的layer之和

offset自身相对父节点的偏移,值为百分比+像素(1个像素等于屏幕上3个像素)

shadowMC自带的字体阴影,true为显示,false则不显示

size相对父节点的大小,取值同offset

text该Label显示的内容,可以通过后续的API在代码中设置该值

text_alignmentLabel中文字的对齐方式,取值为["left", "center", "right"]

typelabel类型

visible默认是否显示,true为显示,false为不显示

Image

Iamge是在UI中的图片控件,可以动态设置控件的图片,该种控件的特点是会保持图片的形状进行拉伸,重复的变量不再重复解释。xxxxxxxxxx

"image" : {"anchor_from" : "center","anchor_to" : "center","layer" : 1,"nineslice_size" : 0,"offset" : [ 0, 0 ],"size" : [ "20.000000%+0 px", "20.000000%+0px" ],"texture" : "textures/fish","type" : "image","uv" : [ 0, 0 ],"uv_size" : [ 16, 16 ],"visible" : true}变量解释nineslice_size九宫格切片的大小,image类型为0

texture贴图的路径,该路径从resouce_pack中的textures目录开始

type类型为image

uvuv坐标的初始值为[0, 0]

NineSliceImage

NineSliceImage是指九宫格图片空间,可以动态设置控件图片,该控件相比Image会随着拉伸改变九宫格的形状,该九宫格只显示切片后中心宫的内容。xxxxxxxxxx

"nine_slice_iamge" : {"anchor_from" : "center","anchor_to" : "center","is_new_nine_slice" : true,"layer" : 1,"nine_slice_bottom" : 0,"nine_slice_left" : 0,"nine_slice_right" : 0,"nine_slice_top" : 0,"offset" : [ 0, 0 ],"size" : [ "20.000000%+0 px", "30.000000%+0px" ],"texture" : "textures/items/fish","type" : "image","visible" : true,}变量解释is_new_nine_slice设置为true标记该图片为NineSliceImage类型图片

nine_slice_bottom切片距离下边的距离,默认值为0

nine_slice_left切片距离左边的距离,默认值为0

nine_slice_right切片距离右边的距离,默认值为0

nine_slice_top切片距离上边的距离,默认值为0

Image Button

ImageButton 是指可以动态设置贴图的按钮,同时含有NineSliceImage和Label。按钮有三种状态,分别为default/hover/pressed,可以分别对应不同的贴图。注 $符号表示定义变量

controls表示控制的子节点,xxxxxxxxxx

"button@common.button" : {"$default_color" : [ 1, 1, 1 ],"$default_texture" : "textures/common/button/btn01","$hover_texture" : "textures/common/button/btn02","$pressed_texture" : "textures/common/button/btn03","$labelText" : "hello","$label_font_size" : "large","$nine_slice_bottom" : 0,"$nine_slice_left" : 0,"$nine_slice_right" : 0,"$nine_slice_top" : 0,"$text_offset" : [ 0, 0 ],"anchor_from" : "center","anchor_to" : "center","is_handle_button_move_event": true,"button_mappings": [],"controls" : [{"default" : {"is_new_nine_slice" : true,"layer" : 2,"nine_slice_bottom" : "$nine_slice_bottom","nine_slice_left" : "$nine_slice_left","nine_slice_right" : "$nine_slice_right","nine_slice_top" : "$nine_slice_top","texture" : "$default_texture","type" : "image"}},{"hover" : {"is_new_nine_slice" : true,"layer" : 2,"nine_slice_bottom" : "$nine_slice_bottom","nine_slice_left" : "$nine_slice_left","nine_slice_right" : "$nine_slice_right","nine_slice_top" : "$nine_slice_top","texture" : "$hover_texture","type" : "image"}},{"pressed" : {"is_new_nine_slice" : true,"layer" : 2,"nine_slice_bottom" : "$nine_slice_bottom","nine_slice_left" : "$nine_slice_left","nine_slice_right" : "$nine_slice_right","nine_slice_top" : "$nine_slice_top","texture" : "$pressed_texture","type" : "image"}},{"button_label" : {"color" : "$default_color","font_size" : "$label_font_size","layer" : 3,"max_size" : [ "100%", "100%" ],"offset" : "$text_offset","shadow" : false,"text" : "$labelText","type" : "label"}}],"layer" : 1,"offset" : [ 0, 0 ],"size" : [ "15.000000%+0 px", "10.000000%+0px" ],"visible" : true}变量解释default表示按钮默认状态下的显示的图片内容

hover表示按钮处于悬浮状态下的图片内容

pressed表示按钮处于按下状态下的图片内容

button@common.button表示该节点是一个common.button的子类

Panel

panel为面板控件,主要是用来将控件进行分类和管理,类似文件夹。xxxxxxxxxx

"panel" : {"anchor_from" : "center","anchor_to" : "center","layer" : 0,"offset" : [ 0, 0 ],"size" : [ "50.000000%+0 px", "50.000000%+0px" ],"type" : "panel","visible" : true}变量解释type类型为panel

TextEditBox

TextEditBox是输入框控件,用来输入文字信息,可以获取输入内容,设置输入框内容,触发输入中和输入完成事件,设置最大输入值等。下面的示例展示了一个搜索框的信息。xxxxxxxxxx

"search_panel": {"type": "panel","anchor_from" : "top_left","anchor_to" : "top_left","offset" : [ "7.21832%+0px", "50%+0px" ],"size" : [ "83.80282%+0px", "10.31250%+0px" ],"$text_edit_clipping_panel_size": [ "100% - 23px", "100%" ],"$text_edit_box_label_anchor_point": "left_middle","controls": [{"search_text_box@common.text_edit_box": {"max_length": 3,"$text_box_name": "%test_screen.TextBox","$text_edit_box_enabled_binding_type": "none","$text_edit_box_content_binding_name": "#test_screen.ReturnTextString","$place_holder_text": "#test_screen.ReturnHolderContent","$text_edit_box_placeholder_content_binding_name": "#test_screen.ReturnHolderContent","$enabled": true}},{"clear_button@common.close_button": {"anchor_from": "right_middle","anchor_to": "right_middle","visible": true,"layer": 2,"focus_enabled": true,"$close_button_offset": [ -2, 0 ],"button_mappings": [{"from_button_id": "button.menu_select","to_button_id": "%test_screen.ClearButtonClick","mapping_type": "pressed"},{"from_button_id": "button.menu_ok","to_button_id": "%test_screen.ClearButtonClick","mapping_type": "focused"}]}},{"test_label@test_screen.test_label" : {}}]}变量解释search_text_box@common.text_edit_box继承于基础的text_edit_box输入框

max_length初始最大输入长度,后续可代码设置

"$text_box_name": "%test_screen.TextBox"获取输入到的信息,监听了BF_EditChanged和BF_EditFinished的函数Textbox,会在输入框内容修改和输入完成时调到该函数,可参考下面的注

"$text_edit_box_content_binding_name": "#test_screen.ReturnTextString"输入框显示ReturnTextString中返回的内容,这与上面形成了一个双向绑定,可参考下面的注

"$place_holder_text": "#test_screen.ReturnHolderContent"输入框初始化没有输入时的提示语,函数ReturnHolderContent返回我们想要显示的内容,可参考下面的注

"to_button_id": "%test_screen.ClearButtonClick"清除按钮的逻辑,清除输入框中的内容,可参考下面的注注1xxxxxxxxxx

class TestScreen(ScreenNode):def __init__(self, namespace, name, param):ScreenNode.__init__(self, namespace, name, param)self.text = ""self.holder = str("请输入姓名")@ViewBinder.binding(ViewBinder.BF_EditChanged | ViewBinder.BF_EditFinished)def TextBox(self, args):print "SearchTextBox ", argsself.text = args["Text"]return ViewRequest.Refresh​@ViewBinder.binding(ViewBinder.BF_InteractButtonClick)def ClearButtonClick(self, args):self.text = ""return ViewRequest.Refresh​@ViewBinder.binding(ViewBinder.BF_BindString)def ReturnTextString(self):return self.text​@ViewBinder.binding(ViewBinder.BF_BindString)def ReturnHolderContent(self):return self.holder注2

max_length 可以通过接口SetEditTextMaxLength,接口详细调用可见下文。

注意:输入框不允许在inputmode为0的情况下使用。

创建带输入框的UI时inputmode必须要为1,如:

clientApi.CreateUI("testMod", "testUI", {"inputMode":1})

PaperDoll

该控件可以用于在ui上显示骨骼模型xxxxxxxxxx

"paper_doll0" : {"anchor_from" : "center","anchor_to" : "center","bindings" : [{"binding_type": "view","source_control_name": "paper_doll0_skin_viewer_panel","source_property_name": "#gesture_delta_source","target_property_name": "#gesture_delta_source"},{"binding_type" : "view","source_control_name" : "paper_doll0_skin_viewer_panel","source_property_name" : "#gesture_mouse_delta_x","target_property_name" : "#gesture_mouse_delta_x"}],"controls" : [{"paper_doll0_skin_viewer_panel" : {"anchor_from" : "bottom_middle","anchor_to" : "bottom_middle","button_mappings" : [{"button_up_right_of_first_refusal" : true,"from_button_id" : "button.menu_select","mapping_type" : "pressed","to_button_id" : "button.turn_doll"}],"gesture_tracking_button" : "button.turn_doll","layer" : 3,"offset" : [ 0, 0 ],"size" : [ "100%+0px", "100%+0px" ],"type" : "input_panel","visible" : true}}],"property_bag":{"#skin_rotation": true,"#custom_rot_y": 90},"layer" : 1,"offset" : [ "0.00000%+0px", "1.66667%+0px" ],"renderer" : "paper_doll_renderer","rotation" : "gesture_x","modelname": "xuenv","animation": "idle","modelsize": 1.0,"size" : [ "19.37500%+0px", "50.27777%+0px" ],"type" : "custom","visible" : true}变量解释modelname要显示的骨骼模型的名称,可通过API中的SetUiModel接口动态修改

animation骨骼模型播放的动作

modelsize骨骼模型的显示缩放

rotation模型的旋转控制,有以下取值:

auto或none: 模型根据#skin_rotation的取值是否自动旋转

custom_y: 模型根据#custom_rot_y的取值旋转固定角度

gesture_x: 模型可由用户拖动绕y轴任意旋转

bindings若rotation为gesture_x,需要有示例中的绑定,其中source_control_name与子controls的控件名对应

controls若rotation为gesture_x,需要有示例中的input_panel子控件,其中控件名,size,offset可自行调整,该子控件的size与offset决定模型拖动的响应区域

property_bag#skin_rotation:当rotation为auto或者none时生效,该属性为true,则模型自动缓慢旋转,为false时,模型正面朝屏幕

#custom_rot_y:当rotation为custom_y时生效,模型绕y轴旋转该值的角度

ScrollView

该控件是可以滑动的窗口,需要有其他控件附属。xxxxxxxxxx

"first_scroll_panel@common.scrolling_panel" : {"$scroll_bar_right_padding_size" : [ 0, 3 ],"$scroll_box_mouse_image_control" : "common-classic.button_state_default","$scroll_size" : [ 0, "100.000000%+0px" ],"$scroll_view_name" : "scroll_view","$scrolling_content" : "test_screen.first_stack_grid","$scrolling_pane_offset" : [ -3, 0 ],"$scrolling_pane_size" : [ "100.000000%+0 px", "100.000000%+0px" ],"$show_background" : false,"anchor_from" : "right_middle","anchor_to" : "right_middle","layer" : 2,"offset" : [ "-9.500000%+0 px", "3.000000%+0px" ],"size" : [ "37.67606%+0px", "66.87500%+0px" ],"visible" : true},变量解释scroll_bar_right_padding_size滑动列表右侧填充的大小

scroll_box_mouse_image_controlcommon-classic.button_state_default为默认的状态

scrolling_content这里保存了该滑动窗口的内容

show_background是否显示背景

StackGrid

该控件可以依附在滚动条中,用来实现背包等功能。xxxxxxxxxx

"first_stack_grid" : {"anchor_from" : "center","anchor_to" : "center","bindings" : [{"binding_condition" : "always","binding_name" : "#first_stack_grid.item_count","binding_name_override" : "#StackGridItemsCount"}],"collection_name" : "hugo_first_scroll","controls" : [{"first_stack@test_screen.first_stack" : {}}],"item_count" : 8,"layer" : 0,"orientation" : "vertical","property_bag" : {"#first_stack_grid.item_count" : 8},"size" : [ "100%", "default" ],"type" : "stack_grid","visible" : true},变量解释"binding_name" : "#first_stack_grid.item_count"这里的binding_name属于在Python中使用的绑定变量

"binding_name_override" : "#StackGridItemsCount"这里的binding_name_override属于在引擎中的绑定变量,值不可改变

"collection_name" : "hugo_first_scroll"定义了集合变量的名称

item_count给定了默认的行数为8行

orientationvertical垂直地排列

Grid

Grid组件类似于上面的StackGrid组件,属于网格型的排列。xxxxxxxxxx

"grid0" : {"anchor_from" : "center","anchor_to" : "center","bindings" : [{"binding_condition" : "always","binding_name" : "#grid0.grid_dimension_binding","binding_name_override" : "#GridItemsCount"}],"collection_name" : "hugo_grid","grid_dimension_binding" : "#grid0.grid_dimension_binding","grid_dimensions" : [ 2, 2 ],"grid_item_template" : "test_screen.item_content0","layer" : 1,"offset" : [ "0%+0px", "0%+0px" ],"size" : [ "35.73944%+0px", "33.75000%+0px" ],"type" : "grid","visible" : true},变量解释"binding_name" : "#grid0.grid_dimension_binding"绑定脚本层的函数的名称

"binding_name_override" : "#GridItemsCount"引擎中绑定的名称

"grid_dimension_binding" : "#grid0.grid_dimension_binding",绑定函数的名称

"grid_dimensions" : [ 2, 2 ],初始值大小2X2

Python规范

必要的属性xxxxxxxxxx

import client.extraClientApi as clientApiViewBinder = clientApi.GetViewBinderCls()ViewRequest = clientApi.GetViewViewRequestCls()ScreenNode = clientApi.GetScreenNodeCls()变量解释extraClientApi我们开发的Client端Api接口文件

ViewBinder用于绑定回调函数的类型和响应的方法

ViewRequest用于返回绑定函数的返回值

ScreenNodeUI的基类,用于继承基类的方法和UI管理

UI界面初始化xxxxxxxxxx

class TestScreen(ScreenNode):def __init__(self, namespace, name, param):ScreenNode.__init__(self, namespace, name, param)

ScreenNode是我们的UI节点基类,必须继承。xxxxxxxxxx

# Bind Typeclass ViewBinder(object):ButtonFilter = 0x10000000BF_ButtonClickUp=0 | ButtonFilterBF_ButtonClickDown=1 | ButtonFilterBF_ButtonClick= 2 | ButtonFilterBF_ButtonClickCancel= 3BF_InteractButtonClick = 4BindFilter = 0x01000000BF_BindBool= 5 | BindFilterBF_BindInt= 6 | BindFilterBF_BindFloat= 7 | BindFilterBF_BindString= 8 | BindFilterBF_BindGridSize = 9 | BindFilterBF_BindColor= 10 | BindFilterEditFilter = 0x00100000BF_EditChanged= 11 | EditFilterBF_EditFinished= 12 | EditFilter# Return Typeclass ViewRequest(object):Nothing = 0Refresh = 1 << 0PointerHeldEventsRequest = 1 << 1PointerHeldEventsCancel = 1 << 2Exit = 1 << 3​

UI绑定和返回

UI的绑定分为binding单个绑定和binding_collection集合绑定,适合集合容器。绑定类型绑定方式解释BF_ButtonClickUpbinding绑定按钮的Up事件

BF_ButtonClickDownbinding绑定按钮的Down事件

BF_ButtonClickbinding同时绑定Up和Down事件

BF_ButtonClickCancelbinding绑定按钮的Cancel事件(按钮down其他up)

BF_InteractButtonClickbinding绑定游戏原生的按钮点击事件

BF_BindBoolbinding|binding_collection绑定Bool变量

BF_BindIntbinding|binding_collection绑定Int变量

BF_BindFloatbinding|binding_collection绑定Float变量

BF_BindStringbinding|binding_collection绑定String变量

BF_BindGridSizebinding绑定GridSize变量

BF_BindColorbinding|binding_collection绑定颜色变量

BF_EditChangedbinding绑定输入框输入改变事件

BF_EditFinishedbinding绑定输入框输入完成事件

binding(bind_flag, binding_name = None)

bind_flag为上文中绑定类型,binding_name为绑定名称。

binding_name为脚本绑定变量,binding_name_override为引擎变量,json格式如下xxxxxxxxxx

"bindings" : [{"binding_condition" : "always","binding_name" : "#scoreboard_grid.item_count","binding_name_override" : "#StackGridItemsCount"}]

对应的Python代码如下xxxxxxxxxx

@ViewBinder.binding(ViewBinder.BF_BindInt, "#scoreboard_grid.item_count")def OnStarkGridResize(self):return len(self.scoreBoardList)

binding_collection(bind_flag, collection_name, binding_name = None)

bind_flag为上文中的绑定类型,collection_name为集合名称,binding_name为绑定的变量名称。

集合的json如下:xxxxxxxxxx

"collection_name" : "scoreboard_stackgrid"

在集合的子控件中,binding_collection_name为集合名,binding_condition为绑定条件,binding_name为绑定名称,binding_type为collection绑定,property_bag设置他的初始值,text为它的绑定值。xxxxxxxxxx

"label_score_board" : {"bindings" : [{"binding_collection_name" : "scoreboard_stackgrid","binding_condition" : "always","binding_name" : "#label_score_board.text","binding_type" : "collection"}],"offset" : [ "0%+0 px", "0%+0px" ],"property_bag" : {"#label_score_board.text" : "666666666666"},"text" : "#label_score_board.text","text_alignment" : "left","type" : "label","visible" : true},

对应的Python代码如下,其中index表示在集合中的哪一元素。xxxxxxxxxx

@ViewBinder.binding_collection(ViewBinder.BF_BindString, "scoreboard_stackgrid", "#label_score_board.text")def OnRefreshScoreBoardLabel(self, index):return self.scoreBoardList[index] if len(self.scoreBoardList) > index else ""

调用规范

参数命名规范

@Mod.Binding(name = myModName, version = myModVersion)参数类型解释myModNamestrMod名称

myModVersionstrMod版本

假设设置Mod名称为"myModName",示例:xxxxxxxxxx

@Mod.Binding(name = "myModName", version = "0.1")class MyModClass(object):def __init__(self):pass

注册UI界面

RegisterUI(myModName, key, clsPath, uiDef)参数类型解释myModNamestr用来标识Mod名称,尽量个性化不与其他人重复

keystr用来标识界面名称

clsPathstr用来标识python中ui类的路径

uiDefstr用来标识json ui的命名空间和界面名

该函数用来,示例:xxxxxxxxxx

import client.extraClientApi as clientApiclientApi.RegisterUI("myModName", "myUIName", "myScripts.modClient.ui.myUIName.MyUIClass", "myUIName.main")

创建UI界面

CreateUI(myModName, key, paramDict=None)参数类型解释myModNamestr用来标识Mod名称

keystr用来标识界面名称

paramDictdict参数字典 参数Key为( isHud) ,值为(0 / 1) ,意为是否为HUD界面的UI。一般情况下,射击按钮不屏蔽游戏, 原生的操作的界面应该isHud为1;商城界面等不适游戏内操作的界面isHud应该为0,默认值为1。xxxxxxxxxx

import client.extraClientApi as clientApiclientApi.CreateUI("myModName", "myUIName", {"isHud" : 1})

获取UI界面

GetUI(myModName, key)参数类型解释myModNamestr用来标识Mod名称

keystr用来标识界面名称

获取UI结点,该结点就是python类的实例,示例:xxxxxxxxxx

import client.extraClientApi as clientApiuiNode = clientApi.GetUI("myModName", "myUIName")

删除UI界面

uiNode.SetRemove()xxxxxxxxxx

import client.extraClientApi as clientApiuiNode = clientApi.GetUI("myModName", "myUIName")uiNode.SetRemove()xxxxxxxxxx

从上面获取的UI结点删除界面,会调用node的Destroy()方法。注意 单个json界面内的layer值应小于1000

生命周期函数

生命周期函数会被自动在以下情况下调用,重写函数可以完成一些逻辑。函数作用CreateUI创建成功时调用

OnActiveUI重新回到栈顶时调用

OnDeactive栈顶UI有其他UI入栈时调用

DestroyUI销毁时调用

下面是一些示例:xxxxxxxxxx

def Create(self):print "================ fpsui create "clientApi.HideHudGUI(False)comp = clientApi.CreateComponent(clientApi.GetLevelId(), "Minecraft", "operation")comp.all = TrueclientApi.NeedsUpdate(comp)​def OnActive(self):print "================ fpsui OnActive "clientApi.HideHudGUI(False)comp = clientApi.CreateComponent(clientApi.GetLevelId(), "Minecraft", "operation")comp.all = TrueclientApi.NeedsUpdate(comp)​def OnDeactive(self):print "================ fpsui OnDeactive "clientApi.HideHudGUI(True)comp = clientApi.CreateComponent(clientApi.GetLevelId(), "Minecraft", "operation")comp.all = FalseclientApi.NeedsUpdate(comp)​def Destroy(self):print "================ fpsui Destroy "clientApi.HideHudGUI(False)comp = clientApi.CreateComponent(clientApi.GetLevelId(), "Minecraft", "operation")comp.all = TrueclientApi.NeedsUpdate(comp)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值