| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- #if UNITY_2019_4_OR_NEWER
- using System;
- using System.Linq;
- using System.Collections.Generic;
- using UnityEditor;
- using UnityEngine;
- using UnityEditor.UIElements;
- using UnityEngine.UIElements;
- namespace YooAsset.Editor
- {
- //[UxmlElement]
- public partial class TreeViewer : VisualElement
- {
- private readonly ListView _listView;
- private readonly List<TreeNode> _flattenList = new List<TreeNode>(1000);
- private readonly List<TreeNode> _rootList = new List<TreeNode>(100);
- /// <summary>
- /// 制作列表元素
- /// </summary>
- public Action<VisualElement> makeItem { get; set; }
- /// <summary>
- /// 绑定列表数据
- /// </summary>
- public Action<VisualElement, object> bindItem { get; set; }
- public TreeViewer()
- {
- this.style.flexShrink = 1f;
- this.style.flexGrow = 1f;
- // 创建ListView
- _listView = new ListView();
- _listView.style.flexShrink = 1f;
- _listView.style.flexGrow = 1f;
- _listView.itemsSource = _flattenList;
- _listView.makeItem = MakeItemInternal;
- _listView.bindItem = BindItemInternal;
- this.Add(_listView);
- }
- /// <summary>
- /// 设置根节点数据
- /// </summary>
- public void SetRootItem(TreeNode rootNode)
- {
- _rootList.Add(rootNode);
- }
- /// <summary>
- /// 设置根节点数据
- /// </summary>
- public void SetRootItems(List<TreeNode> rootNodes)
- {
- _rootList.AddRange(rootNodes);
- }
- /// <summary>
- /// 清理数据
- /// </summary>
- public void ClearAll()
- {
- _rootList.Clear();
- }
- /// <summary>
- /// 重新绘制视图
- /// </summary>
- public void RebuildView()
- {
- _flattenList.Clear();
- foreach (var treeRoot in _rootList)
- {
- FlattenTree(treeRoot, 0);
- }
- _listView.Rebuild();
- }
- /// <summary>
- /// 将树形结构扁平化为列表
- /// </summary>
- private void FlattenTree(TreeNode node, int depth)
- {
- _flattenList.Add(node);
- if (node.IsExpanded)
- {
- foreach (var child in node.Children)
- {
- FlattenTree(child, depth + 1);
- }
- }
- }
- private VisualElement MakeItemInternal()
- {
- var container = new VisualElement();
- container.style.flexDirection = FlexDirection.Row;
- // 折叠按钮
- var toggle = new ToggleFoldout();
- toggle.text = string.Empty;
- toggle.name = "foldout";
- toggle.style.alignSelf = Align.Center;
- toggle.style.width = 15;
- toggle.style.height = 15;
- toggle.RegisterValueChangedCallback((ChangeEvent<bool> callback) =>
- {
- var treeNode = toggle.userData as TreeNode;
- treeNode.IsExpanded = toggle.value;
- RebuildView();
- });
- container.Add(toggle);
- // 用户自定义元素
- if (makeItem != null)
- {
- makeItem.Invoke(container);
- }
- return container;
- }
- private void BindItemInternal(VisualElement item, int index)
- {
- var treeNode = _flattenList[index];
- // 设置折叠状态
- var toggle = item.Q<ToggleFoldout>("foldout");
- toggle.SetValueWithoutNotify(treeNode.IsExpanded);
- toggle.userData = treeNode;
- toggle.style.marginLeft = treeNode.GetDepth() * 15;
- // 隐藏折叠按钮
- if (treeNode.Children.Count == 0)
- {
- toggle.style.visibility = Visibility.Hidden;
- }
- // 用户自定义元素
- if (bindItem != null)
- {
- bindItem.Invoke(item, treeNode.UserData);
- }
- }
- }
- }
- #endif
|