using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
namespace AlicizaX.EditorExtension.Editor
{
///
/// 表格视图
///
/// 数据类型
public sealed class TableView : TreeView where T : class, new()
{
///
/// 表格数据
///
private List _datas;
///
/// 当前选择的表格数据
///
private List _selectionDatas;
///
/// 根元素
///
private TableViewItem _rootItem;
///
/// 所有的元素
///
private List> _items;
///
/// 所有的元素绘制项
///
private List _drawItems;
///
/// 搜索控件
///
private SearchField _searchField;
///
/// 元素ID标记
///
private int _idSign = 0;
///
/// 当选择项改变
///
public event Action> OnSelectionChanged;
///
/// 搜索数据时的方法
///
public Func OnSearch;
///
/// 行高度
///
public float RowHeight
{
get
{
return rowHeight;
}
set
{
rowHeight = value;
}
}
///
/// 是否启用上下文右键点击
///
public bool IsEnableContextClick { get; set; } = true;
///
/// 是否允许多选
///
public bool IsCanMultiSelect { get; set; } = true;
///
/// 是否启用搜索框
///
public bool IsEnableSearch { get; set; } = false;
///
/// 表格视图
///
/// 表格视图数据
/// 表格视图的所有列
public TableView(List datas, List> columns) : base(new TreeViewState())
{
showAlternatingRowBackgrounds = true;
showBorder = true;
rowHeight = EditorGUIUtility.singleLineHeight + 4;
columns.Insert(0, GetIndexColumn());
multiColumnHeader = new MultiColumnHeader(new MultiColumnHeaderState(columns.ToArray()));
multiColumnHeader.sortingChanged += OnSortingChanged;
multiColumnHeader.visibleColumnsChanged += OnVisibleColumnsChanged;
_datas = datas;
_selectionDatas = new List();
_rootItem = new TableViewItem(-1, -1, null);
_items = new List>();
for (var i = 0; i < _datas.Count; i++)
{
_items.Add(new TableViewItem(_idSign, 0, _datas[i]));
_idSign += 1;
}
_drawItems = new List();
_searchField = new SearchField();
Reload();
}
///
/// 构造根节点
///
protected override TreeViewItem BuildRoot()
{
return _rootItem;
}
///
/// 构造所有行
///
protected override IList BuildRows(TreeViewItem root)
{
_drawItems.Clear();
if (hasSearch && OnSearch != null)
{
for (int i = 0; i < _items.Count; i++)
{
if (OnSearch(_items[i].Data, searchString))
{
_drawItems.Add(_items[i]);
}
}
}
else
{
for (int i = 0; i < _items.Count; i++)
{
_drawItems.Add(_items[i]);
}
}
return _drawItems;
}
///
/// 绘制行
///
protected override void RowGUI(RowGUIArgs args)
{
TableViewItem item = args.item as TableViewItem;
int visibleColumns = args.GetNumVisibleColumns();
for (var i = 0; i < visibleColumns; i++)
{
Rect cellRect = args.GetCellRect(i);
int index = args.GetColumn(i);
CenterRectUsingSingleLineHeight(ref cellRect);
TableColumn column = multiColumnHeader.GetColumn(index) as TableColumn;
column.DrawCell?.Invoke(cellRect, item.Data, args.row, args.selected, args.focused);
}
}
///
/// 上下文右键点击
///
protected override void ContextClicked()
{
if (!IsEnableContextClick)
return;
List selectedItems = new List();
foreach (var itemID in GetSelection())
{
TableViewItem item = _items.Find((it) => { return it.id == itemID; });
if (item != null) selectedItems.Add(item.Data);
}
GenericMenu menu = new GenericMenu();
menu.AddItem(new GUIContent("Add row"), false, () =>
{
AddData(new T());
});
if (selectedItems.Count > 0)
{
menu.AddItem(new GUIContent("Delete selected rows"), false, () =>
{
DeleteDatas(selectedItems);
});
}
menu.AddSeparator("");
menu.AddItem(new GUIContent("Clear rows"), false, () =>
{
ClearData();
});
menu.ShowAsContext();
}
///
/// 当选择项改变
///
protected override void SelectionChanged(IList selectedIds)
{
base.SelectionChanged(selectedIds);
_selectionDatas.Clear();
foreach (var itemID in selectedIds)
{
TableViewItem item = _items.Find((it) => { return it.id == itemID; });
if (item != null) _selectionDatas.Add(item.Data);
}
OnSelectionChanged?.Invoke(_selectionDatas);
}
///
/// 是否允许多选
///
protected override bool CanMultiSelect(TreeViewItem item)
{
return IsCanMultiSelect;
}
///
/// 绘制表格视图
///
/// 绘制区域
public override void OnGUI(Rect rect)
{
if (IsEnableSearch)
{
Rect sub = new Rect(rect.x, rect.y, 60, 16);
EditorGUI.LabelField(sub, "Search: ");
sub.Set(rect.x + 60, rect.y, rect.width - 60, 18);
searchString = _searchField.OnGUI(sub, searchString);
rect.y += 18;
rect.height -= 18;
base.OnGUI(rect);
}
else
{
base.OnGUI(rect);
}
}
///
/// 获取索引列
///
private TableColumn GetIndexColumn()
{
TableColumn column = new TableColumn();
column.autoResize = false;
column.headerContent = new GUIContent("Index");
column.width = 50;
column.canSort = false;
column.Compare = null;
column.DrawCell = (rect, data, rowIndex, isSelected, isFocused) =>
{
EditorGUI.LabelField(rect, rowIndex.ToString());
};
return column;
}
///
/// 当重新排序
///
private void OnSortingChanged(MultiColumnHeader columnheader)
{
bool isAscending = multiColumnHeader.IsSortedAscending(multiColumnHeader.sortedColumnIndex);
TableColumn column = multiColumnHeader.GetColumn(multiColumnHeader.sortedColumnIndex) as TableColumn;
if (column.Compare != null)
{
_items.Sort((a, b) =>
{
if (isAscending)
{
return -column.Compare(a.Data, b.Data);
}
else
{
return column.Compare(a.Data, b.Data);
}
});
Reload();
}
}
///
/// 当列激活状态改变
///
private void OnVisibleColumnsChanged(MultiColumnHeader columnheader)
{
Reload();
}
///
/// 添加数据
///
/// 数据
public void AddData(T data)
{
if (_datas.Contains(data))
return;
_datas.Add(data);
_items.Add(new TableViewItem(_idSign, 0, data));
_idSign += 1;
Reload();
}
///
/// 添加数据
///
/// 数据
public void AddDatas(List datas)
{
for (int i = 0; i < datas.Count; i++)
{
T data = datas[i];
if (_datas.Contains(data))
continue;
_datas.Add(data);
_items.Add(new TableViewItem(_idSign, 0, data));
_idSign += 1;
}
Reload();
}
///
/// 删除数据
///
/// 数据
public void DeleteData(T data)
{
if (!_datas.Contains(data))
return;
_datas.Remove(data);
TableViewItem item = _items.Find((i) => { return i.Data == data; });
if (item != null)
{
_items.Remove(item);
}
Reload();
}
///
/// 删除数据
///
/// 数据
public void DeleteDatas(List datas)
{
for (int i = 0; i < datas.Count; i++)
{
T data = datas[i];
if (!_datas.Contains(data))
continue;
_datas.Remove(data);
TableViewItem item = _items.Find((t) => { return t.Data == data; });
if (item != null)
{
_items.Remove(item);
}
}
Reload();
}
///
/// 选中数据
///
/// 数据
public void SelectData(T data)
{
if (!_datas.Contains(data))
return;
TableViewItem item = _items.Find((i) => { return i.Data == data; });
if (item != null)
{
SetSelection(new int[] { item.id });
}
}
///
/// 选中数据
///
/// 数据
/// 选中的操作
public void SelectData(T data, TreeViewSelectionOptions options)
{
if (!_datas.Contains(data))
return;
TableViewItem item = _items.Find((i) => { return i.Data == data; });
if (item != null)
{
SetSelection(new int[] { item.id }, options);
}
}
///
/// 选中数据
///
/// 数据
public void SelectDatas(List datas)
{
List ids = new List();
for (int i = 0; i < datas.Count; i++)
{
T data = datas[i];
if (!_datas.Contains(data))
continue;
TableViewItem item = _items.Find((t) => { return t.Data == data; });
if (item != null)
{
ids.Add(item.id);
}
}
if (ids.Count > 0)
{
SetSelection(ids);
}
}
///
/// 选中数据
///
/// 数据
/// 选中的操作
public void SelectDatas(List datas, TreeViewSelectionOptions options)
{
List ids = new List();
for (int i = 0; i < datas.Count; i++)
{
T data = datas[i];
if (!_datas.Contains(data))
continue;
TableViewItem item = _items.Find((t) => { return t.Data == data; });
if (item != null)
{
ids.Add(item.id);
}
}
if (ids.Count > 0)
{
SetSelection(ids, options);
}
}
///
/// 清空所有数据
///
public void ClearData()
{
_datas.Clear();
_items.Clear();
Reload();
}
}
}