树
树是列表的一种特例。组件的特殊扩展。
树属性
每级缩进:树结掉的深度每增加一级,向右缩进的像素距离。
点击文件夹展开/折叠:点击文件夹节点时是否自动展开或者折叠这个节点。
- 否:没有动作
- 单击:
- 双击:
编辑列表项目界面会出现层级选项。
树节点设计
1.名称为expanded的控制器。如果节点时文件夹节点,当节点展开时,这个控制器自动切换页面到1。反之同理。如果内置按钮负责展开和折叠,那这个按钮和控制器链接。
2.名为leaf的控制器。如果节点是文件夹节点,那么这个控制器的页面是0;如果节点是叶节点,那么这个控制器的页面是1。
3.名称为indent的对象用于设置缩进。
Popup
弹出一些组件,在用户点击空白地方时自动消失。
Popup管理
弹出和关闭Popup的API再GRoot中提供。
//弹出在当前鼠标位置
GRoot.inst.ShowPopup(aComponent);
//弹出在aButton的下方
GRoot.inst.ShowPopup(aComponent, aButton);
//弹出在自定义的位置
GRoot.inst.ShowPopup(aComponent);
aComponent.SetXY(100, 100);
//点击空白关闭
//和使用aWindow.Show显示窗口的唯一区别就是多了点击空白关闭的功能,其它用法没有任何区别。
Window aWindow;
GRoot.inst.ShowPopup(aWindow);
//获得关闭弹出框的通知
aComponent.onRemoveFromStage.Add(onPopupClosed);
PopupMenu
是FGUI提供的一个工具类,用于实现弹出菜单。菜单组件中关键组件就是一个列表,溢出处理模式应该为可见,直接显示全部item,不需要滚动。
制作好菜单后,通过一下代码生成调用。
//设置全局菜单资源
UIConfig.popupMenu = "ui://包名/菜单组件名";
//如果有设计分隔条
UIConfig.popupMenu_seperator = "ui://包名/菜单分隔条";
//如果构造函数不带参数,则表示使用UIConfig.popupMenu里定义的资源。
//也可以带一个参数,指定这个菜单使用的菜单组件资源
PopupMenu menu = new PopupMenu();
//如果要修改菜单的宽度。
menu.contentPane.width = 300;
//添加一个菜单item,并注册点击回调函数
GButton item = menu.AddItem("标题", MenuItemCallback);
item.name = "item1";
//点击回调函数,context.data是当前被点击的item
void MenuItemCallback(EventContext context)
{
GButton item = (GButton)context.data);
Debug.Log(item.name);
}
//添加分隔条
menu.AddSeperator();
//设置菜单项变灰
menu.SetItemGrayed("item1", true);
Drag&Drop
自由拖放
元件能够被拖动,设置draggable。
aObject.draggable = true;
设置一个矩形限制拖动范围,这里的坐标是世界坐标,不是本地。
aObject.dragBounds = new Rect(100,100,200,200);
开始,正在和结束拖动的事件添加
aObject.onDragStart.Add(onDragStart);
aObject.onDragMove.Add(onDragMove);
aObject.onDragEnd.Add(onDragEnd);
转换拖动
不让元件的任何地方都可拖动,就是用转换拖动。比如,FGUI窗口,点击它的标题栏,就可拖动窗口。
//设置拖动区域为可拖动,然后侦听拖动开始事件
_dragArea.draggable = true;
_dragArea.onDragStart.Add(onDragStart);
void onDragStart(EventContext context)
{
//取消掉源拖动,也就是_dragArea不会被实际拖动
context.PreventDefault();
//设置窗口处于拖动状态。context.data是手指的id。
this.StartDrag((int)context.data);
}
替身拖动
拖动只能在元件的父组件内移动,需要全屏幕移动,就用替身拖动。
先启动方式作转换:
aObject.draggable = true;
aObject.onDragStart.Add(onDragStart);
//Unity/Cry/MonoGame
void onDragStart(EventContext context)
{
//取消掉源拖动
context.PreventDefault();
//icon是这个对象的替身图片,userData可以是任意数据,底层不作解析。context.data是手指的id。
DragDropManager.inst.StartDrag(null, icon, userData, (int)context.data);
}
完成后,如果要检测拖动结束,不能再监听原来的对象:
DragDropManager.inst.dragAgent.onDragEnd.Add(onDragEnd);
DragDropManager提供拖放功能,一个组件要接收其他元件拖到它里面并释放事件:
aComponent.onDrop.Add(onDrop);
void onDrop(EventContext context)
{
//这里context.data就是StartDrag里传入的userData
Debug.Log(context.data);
}
DragDropManager用一个图片资源当替身,这个图片是用装载器显示的。这个装载器是DragDropManager.inst.dragAgent,我们可以调整其参数。
如果你要用组件作为替身,可以自定义DragDropManager。
窗口系统
编辑器中没有窗口概念,因为窗口可以设置任意组件作为它的显示内容,窗口=内容组件+窗口管理API。
设计窗口
FGUI使用约定名称将一些常见的窗口功能和我们定义的组件关联起来。窗口内容组件需要放置一个名称为frame的组件,这个组件将作为窗口的背景,或者框架。
frame组件制作方式:
- closeButton:一个按钮作为窗口的关闭按钮。
- dragArea: 一个图形作为窗口的检测拖动区,按住此区域拖动。
- contentArea:一个图形作为窗口的主要内容区域,这个区域只用于ShowModalWait。当调用其的时候,窗口会被锁定,如果有contentArea只锁这儿,如果没有那就得锁整个窗口。如果你希望窗口在modalWait状态下依然能够拖动和关闭,那么就不要让contentArea覆盖标题栏区域。
以上约定皆为可选,是否含有frame或者frame是否含有约定动能组件,都不会影响窗口的正常显示和关闭。
使用窗口
运行时可以使用以下方式创建和使用
Window win = new Window();
win.contentPane = UIPackage.CreateObject("包名", "内容组件名").asCom;
win.Show();
具体窗口动态创建机制,官方教程上详细记录了。大体就是窗口的构造函数中调用AddUISource,这个方法要一个IUISource类型的参数,其是一个接口,用户自行实现载入的逻辑。窗口第一次显示,先调用IUISource.load再调Window.onInit初始化,最后播显示动画和显示。
窗口管理
GRoot常用窗口管理API:
- BringToFront 把窗口提到所有窗口的最前面。
- CloseAllWindows 隐藏所有窗口。注意不是销毁。
- CloseAllExceptModals 隐藏所有非模态窗口。
- GetTopWindow 返回当前显示在最上面的窗口。
- hasModalWindow 当前是否有模态窗口在显示。
GRoot是2D UI的根容器。当我们通过UIPackage.CreateObject创建出顶级UI界面后,将它添加到GRoot下。例如游戏的登录界面、主界面等,这类界面的特点是在游戏的底层,且比较固定。Window的本质也是通过UIPackage.CreateObject动态创建的顶级UI界面,但它提供了常用的窗口特性,比如自动排序,显示/隐藏流程,模式窗口等。适用于游戏的对话框界面,例如人物状态、背包、商城之类。这类界面的特点是在游戏的上层,且切换频繁。
动效
引导线
勾选使用引导线之后,双击舞台上元件就可以编辑引导线。
导入导出
有一个PSD导入后直接生成UI的工具——psd2fgui,一个nodejs的应用。具体官网。
一些API
GTree
GTree继承自GList。不支持虚拟化。
GTree aTree = aComponent.GetChild("tree").asTree;
GTreeNode rootNode = aTree.rootNode;
这里rootNode时树的根节点,它是个“假”节点,不可见。
创建并添加节点:
GTreeNode aNode = new GTreeNode(true); //true表示文件夹节点,false表示叶节点
rootNode.AddChild(aNode);
渲染节点:
//直接操作节点对应组件,要节点已经再树里了才能使用,也就是已经AddChild。
GComponent obj = aNode.cell;
obj.GetChild("abc").text = "hello";
//同调函数
aTree.treeNodeRender = RenderTreeNode;
void RenderTreeNode(GTreeNode node, GComponent obj)
{
}
树节点点击,和列表相应item处理凡是一致,监听onClickItem事件,点击item对象后,通过APIGObject.treeNode获取对应GTreeNode对象。
树节点展开或者收缩回调时触发。
aTree.treeNodeWillExpand = onExpand;
void onExpand(GTreeNode node, bool expand)
{
}
Window
- Show:显示窗口。
- Hide:隐藏窗口。
- isShowing:是否显示。
- modal:设置窗口是否模态窗口,其将阻止用户点击任何模态窗口后面的内容。当其显示时,模态窗口背后自动覆盖一层灰色,且改颜色可自定义:
UIConfig.modalLayerColor = new Color(0f, 0f, 0f, 0.4f);
- ShowModalWait:锁定窗口,不允许任何操作。锁定时可显示一个提示,该组件会调整和contentArea相同大小。
UIConfig.windowModalWaiting = "ui://包名/组件名";
- CloseModalWait:取消窗口的锁定。
Transition
动效的播放再代码中启动
Transition trans = aComponent.GetTransition(“peng”);
trans.Play();
//结束时有一个回调,但需注意,如果动效里有嵌套的动效,或者有循环的内容,必须是等全部都结束后才会回调。
trans.Play(callback);
//播放动效一部分,指定时间范围 播放0.5秒到1秒之间的所有帧
trans.Play(1,0,0.5,1);
多国语言
动态加载语言包
//创建UI前载入,不支持实时切换语言文件。
string fileContent; //自行载入语言文件,这里假设已载入到此变量
FairyGUI.Utils.XML xml = new FairyGUI.Utils.XML(fileContent);
UIPackage.SetStringsSource(xml);