uitoolkit杂记

记录一些读UIToolkit文档时的关键点,仅当备忘录。

VisualTree

由VisualElement构成的具有层级结构的数据集合。

VisualElement

一个基类,包含样式表、布局数据以及事件处理器。
内置了各种实现

  • Buttons
  • Toggles
  • Text input fields

panel

面板是视觉树的父对象,视觉树要连接到面板才能渲染。面板要么属于一个编辑器窗口,要么属于一个运行时的UIDocument。面板也处理焦点控制和为视觉树分发事件。

绘制数据

深度优先绘制

布局系统

和Web那一套一样,基于Flexbox。

UI Builder

一个可视化的编写uxml和uss文件的工具

自定义元素

实现VisualElementpublic class MyElement : VisualElement
元素都由工厂模式生成,所以需要对应的工厂类UxmlFactory<MyElement>

定义元素特征

实现VisualElement.UxmlTraits
Init中使用((MyElement)ve).status = m_Status.GetValueFromBag(bag, cc);读取数据。

加载UXML

模板加载到VisualTreeAsset
var template = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("path/to/file.uxml");
然后附加到父元素
template.CloneTree(parentElement, slots);

UQuery

基于Jquery或Linq,如
root.Query("foo").Children<Button>().ForEach(//执行操作);

事件

事件通知到每个元素
基类EventBase

分发事件

监听来自操作系统或脚本的事件,使用EventDispatcher分发到元素。首先确定分发策略,然后执行。
事件有可能由额外事件,通过队列管理。

分发行为

分为三个阶段

  • 涓滴
  • 冒泡
  • 可取消

事件传播

事件分发选择目标后,计算传播路径。

  • 从根部向目标,涓滴阶段
  • 接收事件
  • 上升到根部,冒泡阶段

事件目标

取决于事件类型,键盘则是当前获得焦点的元素。

捕获鼠标

任何时候只有一个元素具有捕获。捕获后,该元素是除了鼠标滚轮之外任何鼠标事件的目标。

焦点环和Tab顺序

默认DFS。

处理事件

注册事件回调

传播路径上除目标外可以对一个事件接受两次,涓滴和冒泡。
默认是在目标和冒泡阶段执行。如要在涓滴时执行,使用TrickleDown.TrickleDown注册回调。

// 为涓滴阶段注册回调
myElement.RegisterCallback<MouseDownEvent>(MyCallback, TrickleDown.TrickleDown);

发送自定义数据到事件回调

//将用户数据一起发送到回调
myElement.RegisterCallback<MouseDownEvent, MyType>(MyCallbackWithData, myData);
void MyCallbackWithData(MouseDownEvent evt, MyType data) { /* ...*/ }

为控件处理输入事件

捕获指针

使用CaptureEvents

使用操纵器处理事件

自定义控件

两种方式

  • 注册事件回调
  • 实现默认操作
    区别
  • 回调在实例上注册,默认操作作为一个类的虚拟函数
  • 回调传播路径上所有元素都会执行。默认操作仅对事件目标执行
override void ExecuteDefaultActionAtTarget(EventBase evt)
{
    // 调用基函数。
    base.ExecuteDefaultActionAtTarget(evt);

    if (evt.GetEventTypeId() == MouseDownEvent.TypeId())
    {
        // ...
    }
    else if (evt.GetEventTypeId() == MouseUpEvent.TypeId())
    {
        // ...
    }
    //更多事件类型
}

综合事件

事件系统使用事件池。

  1. 从事件池中获取一个事件对象
  2. 填写事件属性
  3. 包含在using中确保其返回到事件池
  4. 事件传递给element.SendEvent()

要发送来自操作系统的事件,使用UnityEngine.Event初始化事件

void SynthesizeAndSendKeyDownEvent(IPanel panel, KeyCode code,
     char character = '\0', EventModifiers modifiers = EventModifiers.None)
{
    // Create a UnityEngine.Event to hold initialization data.
    var evt = new Event() {
        type = EventType.KeyDownEvent,
        keyCode = code,
        character = character,
        modifiers = modifiers
    };

    using (KeyDownEvent keyDownEvent = KeyDownEvent.GetPooled(evt))
    {
        panel.visualTree.SendEvent(keyDownEvent);
    }
}

uitoolkit杂记
https://www.kuanmi.top/2023/01/27/uitoolkit/
作者
KuanMi
发布于
2023年1月28日
许可协议