From 793a57647d90f9cac4ca1e366d5d3be3ea679d43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BD=95=E5=86=A0=E5=B3=B0?= Date: Fri, 17 Jan 2025 16:23:31 +0800 Subject: [PATCH] update table view MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增单元格视图类 --- .../YooAsset/Editor/UIElements/TableView.meta | 8 + .../UIElements/TableView/ColumnStyle.cs | 45 ++++ .../UIElements/TableView/ColumnStyle.cs.meta | 11 + .../UIElements/TableView/DefaultCells.meta | 8 + .../TableView/DefaultCells/AssetPathCell.cs | 12 + .../DefaultCells/AssetPathCell.cs.meta | 11 + .../TableView/DefaultCells/ButtonCell.cs | 20 ++ .../TableView/DefaultCells/ButtonCell.cs.meta | 11 + .../DefaultCells/IntegerValueCell.cs | 39 +++ .../DefaultCells/IntegerValueCell.cs.meta | 11 + .../TableView/DefaultCells/SingleValueCell.cs | 39 +++ .../DefaultCells/SingleValueCell.cs.meta | 11 + .../TableView/DefaultCells/StringValueCell.cs | 39 +++ .../DefaultCells/StringValueCell.cs.meta | 11 + .../Editor/UIElements/TableView/ITableCell.cs | 18 ++ .../UIElements/TableView/ITableCell.cs.meta | 11 + .../Editor/UIElements/TableView/ITableData.cs | 20 ++ .../UIElements/TableView/ITableData.cs.meta | 11 + .../UIElements/TableView/SearchSystem.meta | 8 + .../SearchSystem/DefaultSearchSystem.cs | 229 ++++++++++++++++ .../SearchSystem/DefaultSearchSystem.cs.meta | 11 + .../TableView/SearchSystem/ISearchCommand.cs | 9 + .../SearchSystem/ISearchCommand.cs.meta | 11 + .../TableView/SearchSystem/SearchCompare.cs | 133 ++++++++++ .../SearchSystem/SearchCompare.cs.meta | 11 + .../TableView/SearchSystem/SearchKeyword.cs | 19 ++ .../SearchSystem/SearchKeyword.cs.meta | 11 + .../UIElements/TableView/TableColumn.cs | 50 ++++ .../UIElements/TableView/TableColumn.cs.meta | 11 + .../Editor/UIElements/TableView/TableView.cs | 245 ++++++++++++++++++ .../UIElements/TableView/TableView.cs.meta | 11 + 31 files changed, 1095 insertions(+) create mode 100644 Assets/YooAsset/Editor/UIElements/TableView.meta create mode 100644 Assets/YooAsset/Editor/UIElements/TableView/ColumnStyle.cs create mode 100644 Assets/YooAsset/Editor/UIElements/TableView/ColumnStyle.cs.meta create mode 100644 Assets/YooAsset/Editor/UIElements/TableView/DefaultCells.meta create mode 100644 Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/AssetPathCell.cs create mode 100644 Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/AssetPathCell.cs.meta create mode 100644 Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/ButtonCell.cs create mode 100644 Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/ButtonCell.cs.meta create mode 100644 Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/IntegerValueCell.cs create mode 100644 Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/IntegerValueCell.cs.meta create mode 100644 Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/SingleValueCell.cs create mode 100644 Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/SingleValueCell.cs.meta create mode 100644 Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/StringValueCell.cs create mode 100644 Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/StringValueCell.cs.meta create mode 100644 Assets/YooAsset/Editor/UIElements/TableView/ITableCell.cs create mode 100644 Assets/YooAsset/Editor/UIElements/TableView/ITableCell.cs.meta create mode 100644 Assets/YooAsset/Editor/UIElements/TableView/ITableData.cs create mode 100644 Assets/YooAsset/Editor/UIElements/TableView/ITableData.cs.meta create mode 100644 Assets/YooAsset/Editor/UIElements/TableView/SearchSystem.meta create mode 100644 Assets/YooAsset/Editor/UIElements/TableView/SearchSystem/DefaultSearchSystem.cs create mode 100644 Assets/YooAsset/Editor/UIElements/TableView/SearchSystem/DefaultSearchSystem.cs.meta create mode 100644 Assets/YooAsset/Editor/UIElements/TableView/SearchSystem/ISearchCommand.cs create mode 100644 Assets/YooAsset/Editor/UIElements/TableView/SearchSystem/ISearchCommand.cs.meta create mode 100644 Assets/YooAsset/Editor/UIElements/TableView/SearchSystem/SearchCompare.cs create mode 100644 Assets/YooAsset/Editor/UIElements/TableView/SearchSystem/SearchCompare.cs.meta create mode 100644 Assets/YooAsset/Editor/UIElements/TableView/SearchSystem/SearchKeyword.cs create mode 100644 Assets/YooAsset/Editor/UIElements/TableView/SearchSystem/SearchKeyword.cs.meta create mode 100644 Assets/YooAsset/Editor/UIElements/TableView/TableColumn.cs create mode 100644 Assets/YooAsset/Editor/UIElements/TableView/TableColumn.cs.meta create mode 100644 Assets/YooAsset/Editor/UIElements/TableView/TableView.cs create mode 100644 Assets/YooAsset/Editor/UIElements/TableView/TableView.cs.meta diff --git a/Assets/YooAsset/Editor/UIElements/TableView.meta b/Assets/YooAsset/Editor/UIElements/TableView.meta new file mode 100644 index 00000000..d28ac593 --- /dev/null +++ b/Assets/YooAsset/Editor/UIElements/TableView.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e5f8691a7e0c67d4ab790b703925cd75 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Editor/UIElements/TableView/ColumnStyle.cs b/Assets/YooAsset/Editor/UIElements/TableView/ColumnStyle.cs new file mode 100644 index 00000000..e2ed4281 --- /dev/null +++ b/Assets/YooAsset/Editor/UIElements/TableView/ColumnStyle.cs @@ -0,0 +1,45 @@ +#if UNITY_2019_4_OR_NEWER +using System; +using UnityEditor; +using UnityEngine; +using UnityEditor.UIElements; +using UnityEngine.UIElements; + +namespace YooAsset.Editor +{ + public class ColumnStyle + { + public const float MaxValue = 8388608f; + + /// + /// 单元列宽度 + /// + public Length Width = 100f; + + /// + /// 单元列最小宽度 + /// + public Length MinWidth = 30f; + + /// + /// 单元列最大宽度 + /// + public Length MaxWidth = MaxValue; + + /// + /// 可伸缩 + /// + public bool Stretchable = false; + + /// + /// 可搜索 + /// + public bool Searchable = false; + + /// + /// 可排序 + /// + public bool Sortable = false; + } +} +#endif \ No newline at end of file diff --git a/Assets/YooAsset/Editor/UIElements/TableView/ColumnStyle.cs.meta b/Assets/YooAsset/Editor/UIElements/TableView/ColumnStyle.cs.meta new file mode 100644 index 00000000..c9b12a2f --- /dev/null +++ b/Assets/YooAsset/Editor/UIElements/TableView/ColumnStyle.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6a74bbcb5d814f94fb54042ec3b6d94c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Editor/UIElements/TableView/DefaultCells.meta b/Assets/YooAsset/Editor/UIElements/TableView/DefaultCells.meta new file mode 100644 index 00000000..22a17172 --- /dev/null +++ b/Assets/YooAsset/Editor/UIElements/TableView/DefaultCells.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8b25809b75e1e7141aff3c2011845aab +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/AssetPathCell.cs b/Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/AssetPathCell.cs new file mode 100644 index 00000000..68d929be --- /dev/null +++ b/Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/AssetPathCell.cs @@ -0,0 +1,12 @@ +#if UNITY_2019_4_OR_NEWER + +namespace YooAsset.Editor +{ + public class AssetPathCell : StringValueCell + { + public AssetPathCell(string headerTitle) : base(headerTitle) + { + } + } +} +#endif \ No newline at end of file diff --git a/Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/AssetPathCell.cs.meta b/Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/AssetPathCell.cs.meta new file mode 100644 index 00000000..380a8178 --- /dev/null +++ b/Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/AssetPathCell.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ed1c077653e577846ba29aadb91f13ec +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/ButtonCell.cs b/Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/ButtonCell.cs new file mode 100644 index 00000000..79016ac2 --- /dev/null +++ b/Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/ButtonCell.cs @@ -0,0 +1,20 @@ +#if UNITY_2019_4_OR_NEWER +using System; + +namespace YooAsset.Editor +{ + public class ButtonCell : ITableCell, IComparable + { + public object CellValue { set; get; } + + public object GetDisplayObject() + { + return string.Empty; + } + public int CompareTo(object other) + { + return 1; + } + } +} +#endif \ No newline at end of file diff --git a/Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/ButtonCell.cs.meta b/Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/ButtonCell.cs.meta new file mode 100644 index 00000000..6282cb87 --- /dev/null +++ b/Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/ButtonCell.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fe6c2551d70d6934da0b6afce3f1062c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/IntegerValueCell.cs b/Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/IntegerValueCell.cs new file mode 100644 index 00000000..2dd9fd86 --- /dev/null +++ b/Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/IntegerValueCell.cs @@ -0,0 +1,39 @@ +#if UNITY_2019_4_OR_NEWER +using System; + +namespace YooAsset.Editor +{ + public class IntegerValueCell : ITableCell, IComparable + { + public object CellValue { set; get; } + public string HeaderTitle { private set; get; } + public long IntegerValue + { + get + { + return (long)CellValue; + } + } + + public IntegerValueCell(string headerTitle) + { + HeaderTitle = headerTitle; + } + public object GetDisplayObject() + { + return CellValue.ToString(); + } + public int CompareTo(object other) + { + if (other is IntegerValueCell cell) + { + return this.IntegerValue.CompareTo(cell.IntegerValue); + } + else + { + return 1; + } + } + } +} +#endif \ No newline at end of file diff --git a/Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/IntegerValueCell.cs.meta b/Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/IntegerValueCell.cs.meta new file mode 100644 index 00000000..8b47715e --- /dev/null +++ b/Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/IntegerValueCell.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: be8ecb3981efa744f89ee5d3c9e7b7ad +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/SingleValueCell.cs b/Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/SingleValueCell.cs new file mode 100644 index 00000000..94508bc6 --- /dev/null +++ b/Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/SingleValueCell.cs @@ -0,0 +1,39 @@ +#if UNITY_2019_4_OR_NEWER +using System; + +namespace YooAsset.Editor +{ + public class SingleValueCell : ITableCell, IComparable + { + public object CellValue { set; get; } + public string HeaderTitle { private set; get; } + public double SingleValue + { + get + { + return (double)CellValue; + } + } + + public SingleValueCell(string headerTitle) + { + HeaderTitle = headerTitle; + } + public object GetDisplayObject() + { + return CellValue.ToString(); + } + public int CompareTo(object other) + { + if (other is SingleValueCell cell) + { + return this.SingleValue.CompareTo(cell.SingleValue); + } + else + { + return 1; + } + } + } +} +#endif \ No newline at end of file diff --git a/Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/SingleValueCell.cs.meta b/Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/SingleValueCell.cs.meta new file mode 100644 index 00000000..d4f4d2bd --- /dev/null +++ b/Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/SingleValueCell.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ae299b7a930e03f458977750de9ca18e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/StringValueCell.cs b/Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/StringValueCell.cs new file mode 100644 index 00000000..eb6d4fbd --- /dev/null +++ b/Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/StringValueCell.cs @@ -0,0 +1,39 @@ +#if UNITY_2019_4_OR_NEWER +using System; + +namespace YooAsset.Editor +{ + public class StringValueCell : ITableCell, IComparable + { + public object CellValue { set; get; } + public string HeaderTitle { private set; get; } + public string StringValue + { + get + { + return (string)CellValue; + } + } + + public StringValueCell(string headerTitle) + { + HeaderTitle = headerTitle; + } + public object GetDisplayObject() + { + return CellValue; + } + public int CompareTo(object other) + { + if (other is StringValueCell cell) + { + return this.StringValue.CompareTo(cell.StringValue); + } + else + { + return 1; + } + } + } +} +#endif \ No newline at end of file diff --git a/Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/StringValueCell.cs.meta b/Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/StringValueCell.cs.meta new file mode 100644 index 00000000..5cf0d195 --- /dev/null +++ b/Assets/YooAsset/Editor/UIElements/TableView/DefaultCells/StringValueCell.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a04fd2585c5538547b9755673aea76df +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Editor/UIElements/TableView/ITableCell.cs b/Assets/YooAsset/Editor/UIElements/TableView/ITableCell.cs new file mode 100644 index 00000000..80a9ef2d --- /dev/null +++ b/Assets/YooAsset/Editor/UIElements/TableView/ITableCell.cs @@ -0,0 +1,18 @@ +#if UNITY_2019_4_OR_NEWER + +namespace YooAsset.Editor +{ + public interface ITableCell + { + /// + /// 单元格数值 + /// + object CellValue { set; get; } + + /// + /// 获取界面显示对象 + /// + object GetDisplayObject(); + } +} +#endif \ No newline at end of file diff --git a/Assets/YooAsset/Editor/UIElements/TableView/ITableCell.cs.meta b/Assets/YooAsset/Editor/UIElements/TableView/ITableCell.cs.meta new file mode 100644 index 00000000..ca4c26c9 --- /dev/null +++ b/Assets/YooAsset/Editor/UIElements/TableView/ITableCell.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dcfa4e21884025c4b91db2efd543e139 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Editor/UIElements/TableView/ITableData.cs b/Assets/YooAsset/Editor/UIElements/TableView/ITableData.cs new file mode 100644 index 00000000..fb48b3c7 --- /dev/null +++ b/Assets/YooAsset/Editor/UIElements/TableView/ITableData.cs @@ -0,0 +1,20 @@ +#if UNITY_2019_4_OR_NEWER +using System; +using System.Collections.Generic; + +namespace YooAsset.Editor +{ + public interface ITableData + { + /// + /// 是否可见 + /// + bool Visible { set; get; } + + /// + /// 单元格集合 + /// + IList Cells { set; get; } + } +} +#endif \ No newline at end of file diff --git a/Assets/YooAsset/Editor/UIElements/TableView/ITableData.cs.meta b/Assets/YooAsset/Editor/UIElements/TableView/ITableData.cs.meta new file mode 100644 index 00000000..6bb97bbf --- /dev/null +++ b/Assets/YooAsset/Editor/UIElements/TableView/ITableData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 26779163e1da1ca46948287a4cc10023 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Editor/UIElements/TableView/SearchSystem.meta b/Assets/YooAsset/Editor/UIElements/TableView/SearchSystem.meta new file mode 100644 index 00000000..1d431dae --- /dev/null +++ b/Assets/YooAsset/Editor/UIElements/TableView/SearchSystem.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 211ee819fabdd6d4399b79e6fcf45e5c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Editor/UIElements/TableView/SearchSystem/DefaultSearchSystem.cs b/Assets/YooAsset/Editor/UIElements/TableView/SearchSystem/DefaultSearchSystem.cs new file mode 100644 index 00000000..1f3c1148 --- /dev/null +++ b/Assets/YooAsset/Editor/UIElements/TableView/SearchSystem/DefaultSearchSystem.cs @@ -0,0 +1,229 @@ +#if UNITY_2019_4_OR_NEWER +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; +using UnityEngine; + +namespace YooAsset.Editor +{ + public static class DefaultSearchSystem + { + /// + /// 解析搜索命令 + /// + public static List ParseCommand(string commandContent) + { + if (string.IsNullOrEmpty(commandContent)) + return new List(); + + List results = new List(10); + string[] commands = Regex.Split(commandContent, @"\s+"); + foreach (var command in commands) + { + if (command.Contains("!=")) + { + var splits = command.Split(new string[] { "!=" }, StringSplitOptions.None); + if (CheckSplitsValid(command, splits) == false) + continue; + + var cmd = new SearchCompare(); + cmd.HeaderTitle = splits[0]; + cmd.CompareValue = splits[1]; + cmd.CompareOperator = "!="; + results.Add(cmd); + } + else if (command.Contains(">=")) + { + var splits = command.Split(new string[] { ">=" }, StringSplitOptions.None); + if (CheckSplitsValid(command, splits) == false) + continue; + + var cmd = new SearchCompare(); + cmd.HeaderTitle = splits[0]; + cmd.CompareValue = splits[1]; + cmd.CompareOperator = ">="; + results.Add(cmd); + } + else if (command.Contains("<=")) + { + var splits = command.Split(new string[] { "<=" }, StringSplitOptions.None); + if (CheckSplitsValid(command, splits) == false) + continue; + + var cmd = new SearchCompare(); + cmd.HeaderTitle = splits[0]; + cmd.CompareValue = splits[1]; + cmd.CompareOperator = "<="; + results.Add(cmd); + } + else if (command.Contains(">")) + { + var splits = command.Split('>'); + if (CheckSplitsValid(command, splits) == false) + continue; + + var cmd = new SearchCompare(); + cmd.HeaderTitle = splits[0]; + cmd.CompareValue = splits[1]; + cmd.CompareOperator = ">"; + results.Add(cmd); + } + else if (command.Contains("<")) + { + var splits = command.Split('<'); + if (CheckSplitsValid(command, splits) == false) + continue; + + var cmd = new SearchCompare(); + cmd.HeaderTitle = splits[0]; + cmd.CompareValue = splits[1]; + cmd.CompareOperator = "<"; + results.Add(cmd); + } + else if (command.Contains("=")) + { + var splits = command.Split('='); + if (CheckSplitsValid(command, splits) == false) + continue; + + var cmd = new SearchCompare(); + cmd.HeaderTitle = splits[0]; + cmd.CompareValue = splits[1]; + cmd.CompareOperator = "="; + results.Add(cmd); + } + else if (command.Contains(":")) + { + var splits = command.Split(':'); + if (CheckSplitsValid(command, splits) == false) + continue; + + var cmd = new SearchKeyword(); + cmd.HeaderTitle = splits[0]; + cmd.Keyword = splits[1]; + results.Add(cmd); + } + else + { + var cmd = new SearchKeyword(); + cmd.HeaderTitle = string.Empty; + cmd.Keyword = command; + results.Add(cmd); + } + } + return results; + } + private static bool CheckSplitsValid(string command, string[] splits) + { + if (splits.Length != 2) + { + Debug.LogWarning($"Invalid search command : {command}"); + return false; + } + + if (string.IsNullOrEmpty(splits[0])) + return false; + if (string.IsNullOrEmpty(splits[1])) + return false; + + return true; + } + + /// + /// 搜索匹配 + /// + public static void Search(List sourceDatas, string command) + { + var searchCmds = ParseCommand(command); + foreach (var tableData in sourceDatas) + { + tableData.Visible = Search(tableData, searchCmds); + } + } + private static bool Search(ITableData tableData, List commands) + { + if (commands.Count == 0) + return true; + + // 先匹配字符串 + var searchKeywordCmds = commands.Where(cmd => cmd is SearchKeyword).ToList(); + if (SearchKeyword(tableData, searchKeywordCmds) == false) + return false; + + // 后匹配数值 + var searchCompareCmds = commands.Where(cmd => cmd is SearchCompare).ToList(); + if (SearchCompare(tableData, searchCompareCmds) == false) + return false; + + return true; + } + private static bool SearchKeyword(ITableData tableData, List commands) + { + if (commands.Count == 0) + return true; + + // 匹配规则:任意字符串列匹配成果 + foreach (var tableCell in tableData.Cells) + { + foreach (var cmd in commands) + { + var searchKeywordCmd = cmd as SearchKeyword; + if (tableCell is StringValueCell stringValueCell) + { + if (string.IsNullOrEmpty(searchKeywordCmd.HeaderTitle) == false) + { + if (searchKeywordCmd.HeaderTitle == stringValueCell.HeaderTitle) + { + if (searchKeywordCmd.CompareTo(stringValueCell.StringValue)) + return true; + } + } + else + { + if (searchKeywordCmd.CompareTo(stringValueCell.StringValue)) + return true; + } + } + } + } + + // 匹配失败 + return false; + } + private static bool SearchCompare(ITableData tableData, List commands) + { + if (commands.Count == 0) + return true; + + // 匹配规则:任意指定数值列匹配成果 + foreach (var tableCell in tableData.Cells) + { + foreach (var cmd in commands) + { + var searchCompareCmd = cmd as SearchCompare; + if (tableCell is IntegerValueCell integerValueCell) + { + if (searchCompareCmd.HeaderTitle == integerValueCell.HeaderTitle) + { + if (searchCompareCmd.CompareTo(integerValueCell.IntegerValue)) + return true; + } + } + else if (tableCell is SingleValueCell singleValueCell) + { + if (searchCompareCmd.HeaderTitle == singleValueCell.HeaderTitle) + { + if (searchCompareCmd.CompareTo(singleValueCell.SingleValue)) + return true; + } + } + } + } + + // 匹配失败 + return false; + } + } +} +#endif \ No newline at end of file diff --git a/Assets/YooAsset/Editor/UIElements/TableView/SearchSystem/DefaultSearchSystem.cs.meta b/Assets/YooAsset/Editor/UIElements/TableView/SearchSystem/DefaultSearchSystem.cs.meta new file mode 100644 index 00000000..05c21007 --- /dev/null +++ b/Assets/YooAsset/Editor/UIElements/TableView/SearchSystem/DefaultSearchSystem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3de1e93052c2c86408ba77125da962cd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Editor/UIElements/TableView/SearchSystem/ISearchCommand.cs b/Assets/YooAsset/Editor/UIElements/TableView/SearchSystem/ISearchCommand.cs new file mode 100644 index 00000000..b3bd1945 --- /dev/null +++ b/Assets/YooAsset/Editor/UIElements/TableView/SearchSystem/ISearchCommand.cs @@ -0,0 +1,9 @@ +#if UNITY_2019_4_OR_NEWER + +namespace YooAsset.Editor +{ + public interface ISearchCommand + { + } +} +#endif \ No newline at end of file diff --git a/Assets/YooAsset/Editor/UIElements/TableView/SearchSystem/ISearchCommand.cs.meta b/Assets/YooAsset/Editor/UIElements/TableView/SearchSystem/ISearchCommand.cs.meta new file mode 100644 index 00000000..01ceb9c6 --- /dev/null +++ b/Assets/YooAsset/Editor/UIElements/TableView/SearchSystem/ISearchCommand.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4228528e243224045863d8ae14a16194 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Editor/UIElements/TableView/SearchSystem/SearchCompare.cs b/Assets/YooAsset/Editor/UIElements/TableView/SearchSystem/SearchCompare.cs new file mode 100644 index 00000000..41502957 --- /dev/null +++ b/Assets/YooAsset/Editor/UIElements/TableView/SearchSystem/SearchCompare.cs @@ -0,0 +1,133 @@ +#if UNITY_2019_4_OR_NEWER +using System; +using UnityEditor; +using UnityEngine; + +namespace YooAsset.Editor +{ + /// + /// 指定标题的比较搜索 + /// + public class SearchCompare : ISearchCommand + { + public string HeaderTitle; + public string CompareValue; + public string CompareOperator; + + /// + /// 转换的整形数值 + /// + private bool _isConvertedIntegerNum = false; + private long _convertedIntegerNumber = 0; + public long IntegerNumberValue + { + get + { + if (_isConvertedIntegerNum == false) + { + _isConvertedIntegerNum = true; + _convertedIntegerNumber = long.Parse(CompareValue.ToString()); + } + return _convertedIntegerNumber; + } + } + + /// + /// 转换的浮点数值 + /// + private bool _isConvertedSingleNum = false; + private double _convertedSingleNumber = 0; + public double SingleNumberValue + { + get + { + if (_isConvertedSingleNum == false) + { + _isConvertedSingleNum = true; + _convertedSingleNumber = double.Parse(CompareValue.ToString()); + } + return _convertedSingleNumber; + } + } + + public bool CompareTo(long value) + { + if (CompareOperator == ">") + { + if (value > SingleNumberValue) + return true; + } + else if (CompareOperator == ">=") + { + if (value >= SingleNumberValue) + return true; + } + else if (CompareOperator == "<") + { + if (value < SingleNumberValue) + return true; + } + else if (CompareOperator == "<=") + { + if (value <= SingleNumberValue) + return true; + } + else if (CompareOperator == "=") + { + if (value == SingleNumberValue) + return true; + } + else if (CompareOperator == "!=") + { + if (value != SingleNumberValue) + return true; + } + else + { + Debug.LogWarning($"Can not support operator : {CompareOperator}"); + } + + return false; + } + public bool CompareTo(double value) + { + if (CompareOperator == ">") + { + if (value > IntegerNumberValue) + return true; + } + else if (CompareOperator == ">=") + { + if (value >= IntegerNumberValue) + return true; + } + else if (CompareOperator == "<") + { + if (value < IntegerNumberValue) + return true; + } + else if (CompareOperator == "<=") + { + if (value <= IntegerNumberValue) + return true; + } + else if (CompareOperator == "=") + { + if (value == IntegerNumberValue) + return true; + } + else if (CompareOperator == "!=") + { + if (value != IntegerNumberValue) + return true; + } + else + { + Debug.LogWarning($"Can not support operator : {CompareOperator}"); + } + + return false; + } + } +} +#endif \ No newline at end of file diff --git a/Assets/YooAsset/Editor/UIElements/TableView/SearchSystem/SearchCompare.cs.meta b/Assets/YooAsset/Editor/UIElements/TableView/SearchSystem/SearchCompare.cs.meta new file mode 100644 index 00000000..38340f6e --- /dev/null +++ b/Assets/YooAsset/Editor/UIElements/TableView/SearchSystem/SearchCompare.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 345cafa16ea7ccc488c96af1a4ca33c2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Editor/UIElements/TableView/SearchSystem/SearchKeyword.cs b/Assets/YooAsset/Editor/UIElements/TableView/SearchSystem/SearchKeyword.cs new file mode 100644 index 00000000..2fefc758 --- /dev/null +++ b/Assets/YooAsset/Editor/UIElements/TableView/SearchSystem/SearchKeyword.cs @@ -0,0 +1,19 @@ +#if UNITY_2019_4_OR_NEWER + +namespace YooAsset.Editor +{ + /// + /// 搜索关键字 + /// + public class SearchKeyword : ISearchCommand + { + public string HeaderTitle; + public string Keyword; + + public bool CompareTo(string value) + { + return value.Contains(Keyword); + } + } +} +#endif \ No newline at end of file diff --git a/Assets/YooAsset/Editor/UIElements/TableView/SearchSystem/SearchKeyword.cs.meta b/Assets/YooAsset/Editor/UIElements/TableView/SearchSystem/SearchKeyword.cs.meta new file mode 100644 index 00000000..fe3f4d7f --- /dev/null +++ b/Assets/YooAsset/Editor/UIElements/TableView/SearchSystem/SearchKeyword.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3c34fa79e35e66247b64f18eafa1d230 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Editor/UIElements/TableView/TableColumn.cs b/Assets/YooAsset/Editor/UIElements/TableView/TableColumn.cs new file mode 100644 index 00000000..aada90ef --- /dev/null +++ b/Assets/YooAsset/Editor/UIElements/TableView/TableColumn.cs @@ -0,0 +1,50 @@ +#if UNITY_2019_4_OR_NEWER +using System; +using UnityEditor; +using UnityEngine; +using UnityEditor.UIElements; +using UnityEngine.UIElements; + +namespace YooAsset.Editor +{ + public class TableColumn + { + /// + /// 单元列索引值 + /// + internal int ColumnIndex; + + /// + /// UI元素名称 + /// + public string ElementName { private set; get; } + + /// + /// 标题名称 + /// + public string HeaderTitle { private set; get; } + + /// + /// 单元列样式 + /// + public ColumnStyle ColumnStyle { private set; get; } + + /// + /// 制作单元格元素 + /// + public Func MakeCell; + + /// + /// 绑定数据到单元格 + /// + public Action BindCell; + + public TableColumn(string elementName, string headerTitle, ColumnStyle columnStyle) + { + this.ElementName = elementName; + this.HeaderTitle = headerTitle; + this.ColumnStyle = columnStyle; + } + } +} +#endif \ No newline at end of file diff --git a/Assets/YooAsset/Editor/UIElements/TableView/TableColumn.cs.meta b/Assets/YooAsset/Editor/UIElements/TableView/TableColumn.cs.meta new file mode 100644 index 00000000..f7abec1e --- /dev/null +++ b/Assets/YooAsset/Editor/UIElements/TableView/TableColumn.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 034395dad363e3a4da96881de60918a3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/YooAsset/Editor/UIElements/TableView/TableView.cs b/Assets/YooAsset/Editor/UIElements/TableView/TableView.cs new file mode 100644 index 00000000..96f9bdda --- /dev/null +++ b/Assets/YooAsset/Editor/UIElements/TableView/TableView.cs @@ -0,0 +1,245 @@ +#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 TableView : VisualElement + { + private readonly Toolbar _toolbar; + private readonly ListView _listView; + + private readonly List _columns = new List(10); + private List _itemsSource; + private List _sortingDatas; + + // 排序相关 + private string _sortingHeaderElement = string.Empty; + private bool _descendingSort = true; + + /// + /// 数据源 + /// + public List itemsSource + { + get + { + return _itemsSource; + } + set + { + if (CheckItemsSource(value)) + { + _itemsSource = value; + _sortingDatas = value; + } + } + } + + /// + /// 单元视图交互事件 + /// + public Action ClickTableDataEvent; + + /// + /// 单元视图交互事件 + /// + public Action ClickTableHeadEvent; + + + public TableView() + { + _toolbar = new Toolbar(); + this.Add(_toolbar); + + _listView = new ListView(); + _listView.makeItem = MakeListViewElement; + _listView.bindItem = BindListViewElement; + _listView.RegisterCallback(OnClickListItem); + this.Add(_listView); + } + + /// + /// 添加单元列 + /// + public void AddColumn(TableColumn column) + { + var toolbarBtn = new ToolbarButton(); + toolbarBtn.userData = column; + toolbarBtn.name = column.ElementName; + toolbarBtn.text = column.HeaderTitle; + toolbarBtn.style.unityTextAlign = TextAnchor.MiddleLeft; + toolbarBtn.style.flexGrow = column.ColumnStyle.Stretchable ? 1f : 0f; + toolbarBtn.style.width = column.ColumnStyle.Width; + toolbarBtn.style.minWidth = column.ColumnStyle.MinWidth; + toolbarBtn.style.maxWidth = column.ColumnStyle.MaxWidth; + toolbarBtn.clickable.clickedWithEventInfo += OnClickTableHead; + SetCellElementStyle(toolbarBtn); + _toolbar.Add(toolbarBtn); + _columns.Add(column); + + // 计算索引值 + 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(); + } + + private bool CheckItemsSource(List itemsSource) + { + if (itemsSource == null || itemsSource.Count == 0) + { + Debug.LogWarning("Items source is null or empty !"); + return false; + } + + int cellCount = itemsSource[0].Cells.Count; + for (int i = 0; i < itemsSource.Count; i++) + { + var tableData = itemsSource[i]; + if (tableData == null) + { + Debug.LogWarning($"Items source has null instance !"); + return false; + } + if (tableData.Cells == null || tableData.Cells.Count == 0) + { + Debug.LogWarning($"Items source data has empty cells !"); + return false; + } + if (tableData.Cells.Count != cellCount) + { + Debug.LogWarning($"Items source data has inconsisten cells count ! Item index {i}"); + return false; + } + } + + return true; + } + 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 (_sortingHeaderElement != clickedColumn.ElementName) + { + _sortingHeaderElement = clickedColumn.ElementName; + _descendingSort = false; + } + else + { + _descendingSort = !_descendingSort; + } + + // 升降符号 + foreach (var column in _columns) + { + var button = _toolbar.Q(column.ElementName); + button.text = column.HeaderTitle; + } + if (_descendingSort) + toolbarBtn.text = $"{clickedColumn.HeaderTitle} ↓"; + else + toolbarBtn.text = $"{clickedColumn.HeaderTitle} ↑"; + + // 升降排序 + if (_descendingSort) + _sortingDatas = _itemsSource.OrderByDescending(tableData => tableData.Cells[clickedColumn.ColumnIndex]).ToList(); + else + _sortingDatas = _itemsSource.OrderBy(tableData => tableData.Cells[clickedColumn.ColumnIndex]).ToList(); + + // 刷新数据表 + RebuildView(); + } + private VisualElement MakeListViewElement() + { + VisualElement listViewElement = new VisualElement(); + listViewElement.style.flexDirection = FlexDirection.Row; + foreach (var colum in _columns) + { + var cellElement = colum.MakeCell.Invoke(); + cellElement.name = colum.ElementName; + SetCellElementStyle(cellElement); + listViewElement.Add(cellElement); + } + return listViewElement; + } + private void BindListViewElement(VisualElement listViewElement, int index) + { + var sourceDatas = _listView.itemsSource as List; + var tableData = sourceDatas[index]; + foreach (var colum in _columns) + { + var cellElement = listViewElement.Q(colum.ElementName); + var tableCell = tableData.Cells[colum.ColumnIndex]; + colum.BindCell.Invoke(cellElement, tableData, tableCell); + } + } + private void SetCellElementStyle(VisualElement element) + { + StyleLength defaultStyle = new StyleLength(1f); + element.style.paddingTop = defaultStyle; + element.style.paddingBottom = defaultStyle; + element.style.paddingLeft = defaultStyle; + element.style.paddingRight = defaultStyle; + element.style.marginTop = defaultStyle; + element.style.marginBottom = defaultStyle; + element.style.marginLeft = defaultStyle; + element.style.marginRight = defaultStyle; + } + } +} +#endif \ No newline at end of file diff --git a/Assets/YooAsset/Editor/UIElements/TableView/TableView.cs.meta b/Assets/YooAsset/Editor/UIElements/TableView/TableView.cs.meta new file mode 100644 index 00000000..6519b589 --- /dev/null +++ b/Assets/YooAsset/Editor/UIElements/TableView/TableView.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9c12f27850c4d104db1dc85cf532e586 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: