#if UNITY_2019_4_OR_NEWER
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
namespace YooAsset.Editor
{
///
/// Unity2022版本以上推荐官方类:MultiColumnListView组件
///
public class TableViewer : VisualElement
{
public new class UxmlFactory : UxmlFactory
{
}
private readonly Toolbar _toolbar;
private readonly ListView _listView;
private readonly List _columns = new List(10);
private List _itemsSource;
private List _sortingDatas;
// 排序相关
private string _sortingHeader;
private bool _descendingSort = true;
///
/// 数据源
///
public List itemsSource
{
get
{
return _itemsSource;
}
set
{
if (CheckItemsSource(value))
{
_itemsSource = value;
_sortingDatas = value;
}
}
}
///
/// 选中的数据列表
///
public List selectedItems
{
get
{
#if UNITY_2020_3_OR_NEWER
return _listView.selectedItems.Cast().ToList();
#else
List result = new List();
result.Add(_listView.selectedItem as ITableData);
return result;
#endif
}
}
///
/// 单元视图交互事件
///
public Action ClickTableDataEvent;
///
/// 单元视图交互事件
///
public Action ClickTableHeadEvent;
///
/// 单元视图变化事件
///
public Action SelectionChangedEvent;
public TableViewer()
{
this.style.flexShrink = 1f;
this.style.flexGrow = 1f;
// 定义标题栏
_toolbar = new Toolbar();
// 定义列表视图
_listView = new ListView();
_listView.style.flexShrink = 1f;
_listView.style.flexGrow = 1f;
_listView.makeItem = MakeListViewElement;
_listView.bindItem = BindListViewElement;
_listView.selectionType = SelectionType.Multiple;
_listView.RegisterCallback(OnClickListItem);
#if UNITY_2022_3_OR_NEWER
_listView.selectionChanged += OnSelectionChanged;
#elif UNITY_2020_1_OR_NEWER
_listView.onSelectionChange += OnSelectionChanged;
#else
_listView.onSelectionChanged += OnSelectionChanged;
#endif
this.Add(_toolbar);
this.Add(_listView);
}
///
/// 获取标题UI元素
///
public VisualElement GetHeaderElement(string elementName)
{
return _toolbar.Q(elementName);
}
///
/// 添加单元列
///
public void AddColumn(TableColumn column)
{
var toolbarBtn = new ToolbarButton();
toolbarBtn.userData = column;
toolbarBtn.name = column.ElementName;
toolbarBtn.text = column.HeaderTitle;
toolbarBtn.style.flexGrow = 0;
toolbarBtn.style.width = column.ColumnStyle.Width;
toolbarBtn.style.minWidth = column.ColumnStyle.Width;
toolbarBtn.style.maxWidth = column.ColumnStyle.Width;
toolbarBtn.clickable.clickedWithEventInfo += OnClickTableHead;
SetCellElementStyle(toolbarBtn);
_toolbar.Add(toolbarBtn);
_columns.Add(column);
// 可伸缩控制柄
if (column.ColumnStyle.Stretchable)
{
int handleWidth = 3;
int minWidth = (int)column.ColumnStyle.MinWidth.value;
int maxWidth = (int)column.ColumnStyle.MaxWidth.value;
var resizeHandle = new ResizeHandle(handleWidth, toolbarBtn, minWidth, maxWidth);
resizeHandle.ResizeChanged += (float value) =>
{
float width = Mathf.Clamp(value, column.ColumnStyle.MinWidth.value, column.ColumnStyle.MaxWidth.value);
column.ColumnStyle.Width = width;
foreach (var element in column.CellElements)
{
element.style.width = width;
element.style.minWidth = width;
element.style.maxWidth = width;
}
};
_toolbar.Add(resizeHandle);
}
// 计算索引值
column.ColumnIndex = _columns.Count - 1;
if (column.ColumnStyle.Sortable == false)
toolbarBtn.SetEnabled(false);
}
///
/// 添加单元列集合
///
public void AddColumns(IList columns)
{
foreach (var column in columns)
{
AddColumn(column);
}
}
///
/// 重建表格视图
///
public void RebuildView()
{
if (_itemsSource == null)
return;
var itemsSource = _sortingDatas.Where(row => row.Visible);
_listView.Clear();
_listView.ClearSelection();
_listView.itemsSource = itemsSource.ToList();
_listView.Rebuild();
// 刷新标题栏
RefreshToobar();
}
private void RefreshToobar()
{
// 设置为原始标题
foreach (var column in _columns)
{
var toobarButton = _toolbar.Q(column.ElementName);
toobarButton.text = column.HeaderTitle;
}
// 设置元素数量
foreach (var column in _columns)
{
if (column.ColumnStyle.Counter)
{
var toobarButton = GetHeaderElement(column.ElementName) as ToolbarButton;
toobarButton.text = $"{toobarButton.text} ({itemsSource.Count()})";
}
}
// 设置展示单位
foreach (var column in _columns)
{
if (string.IsNullOrEmpty(column.ColumnStyle.Units) == false)
{
var toobarButton = GetHeaderElement(column.ElementName) as ToolbarButton;
toobarButton.text = $"{toobarButton.text} ({column.ColumnStyle.Units})";
}
}
// 设置升降符号
if (string.IsNullOrEmpty(_sortingHeader) == false)
{
var _toobarButton = _toolbar.Q(_sortingHeader);
if (_descendingSort)
_toobarButton.text = $"{_toobarButton.text} ↓";
else
_toobarButton.text = $"{_toobarButton.text} ↑";
}
}
///
/// 清空所有数据
///
public void ClearAll(bool clearColumns, bool clearSource)
{
if (clearColumns)
{
_columns.Clear();
_toolbar.Clear();
}
if (clearSource)
{
if (_itemsSource != null)
_itemsSource.Clear();
if (_sortingDatas != null)
_sortingDatas.Clear();
_listView.Clear();
_listView.ClearSelection();
}
}
private void OnClickListItem(PointerDownEvent evt)
{
var selectData = _listView.selectedItem as ITableData;
if (selectData == null)
return;
ClickTableDataEvent?.Invoke(evt, selectData);
}
private void OnClickTableHead(EventBase eventBase)
{
if (_itemsSource == null)
return;
ToolbarButton toolbarBtn = eventBase.target as ToolbarButton;
var clickedColumn = toolbarBtn.userData as TableColumn;
if (clickedColumn == null)
return;
ClickTableHeadEvent?.Invoke(clickedColumn);
if (clickedColumn.ColumnStyle.Sortable == false)
return;
if (_sortingHeader != clickedColumn.ElementName)
{
_sortingHeader = clickedColumn.ElementName;
_descendingSort = false;
}
else
{
_descendingSort = !_descendingSort;
}
// 升降排序
if (_descendingSort)
_sortingDatas = _itemsSource.OrderByDescending(tableData => tableData.Cells[clickedColumn.ColumnIndex]).ToList();
else
_sortingDatas = _itemsSource.OrderBy(tableData => tableData.Cells[clickedColumn.ColumnIndex]).ToList();
// 刷新数据表
RebuildView();
}
private void OnSelectionChanged(IEnumerable