Merge remote-tracking branch 'gitea/thr_dev/dev2'
# Conflicts: # Runtime/XTable/Rendering/Component/XericUIActionTable.cs
This commit is contained in:
@@ -1,53 +1,84 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using XericLibrary.Runtime.SuperStyleSheet;
|
||||
|
||||
namespace XericUI.XTable.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// 单元格数据模型——仅保存数据内容,不保存自身尺寸。
|
||||
/// 尺寸由渲染阶段的行列标题(行高/列宽)决定。
|
||||
/// 样式通过 StyleNamespace 字符串引用 StyleManager 中的命名空间。
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class XTableCellData
|
||||
{
|
||||
/// <summary>文本内容</summary>
|
||||
public string Text;
|
||||
/// <summary>单元格内容类型——决定渲染时使用哪种内容</summary>
|
||||
public enum CellContentType
|
||||
{
|
||||
/// <summary>文本内容</summary>
|
||||
Text,
|
||||
/// <summary>图片纹理</summary>
|
||||
Image,
|
||||
/// <summary>预制体实例</summary>
|
||||
Prefab,
|
||||
}
|
||||
|
||||
/// <summary>图片纹理</summary>
|
||||
public Texture2D Image;
|
||||
/// <summary>
|
||||
/// 单元格数据模型——仅保存数据内容,不保存自身尺寸。
|
||||
/// 尺寸由渲染阶段的行列标题(行高/列宽)决定。
|
||||
/// 样式通过 StyleNamespace 字符串引用 StyleManager 中的命名空间。
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class XTableCellData
|
||||
{
|
||||
/// <summary>内容类型——决定渲染时使用 Text / Image / Prefab 中的哪一个</summary>
|
||||
public CellContentType ContentType;
|
||||
|
||||
/// <summary>预制体对象(用于嵌入复杂 UI 元素)</summary>
|
||||
public GameObject Prefab;
|
||||
/// <summary>文本内容(ContentType == Text 时生效)</summary>
|
||||
public string Text;
|
||||
|
||||
/// <summary>
|
||||
/// 样式命名空间——对应 StyleManager 中的命名空间。
|
||||
/// 为空或 "xeric_table_default" 时使用默认表格样式。
|
||||
/// 渲染时从此命名空间读取 /cell/bg/color、/cell/font/size 等路径。
|
||||
/// </summary>
|
||||
public string StyleNamespace;
|
||||
/// <summary>图片纹理(ContentType == Image 时生效)</summary>
|
||||
public Texture2D Image;
|
||||
|
||||
/// <summary>预制体实例从对象池取出时回调——外部可在此初始化实例内容</summary>
|
||||
[NonSerialized] public System.Action<GameObject> OnPrefabAcquire;
|
||||
/// <summary>预制体对象(ContentType == Prefab 时生效,用于嵌入复杂 UI 元素)</summary>
|
||||
public GameObject Prefab;
|
||||
|
||||
/// <summary>预制体实例归还对象池前回调——外部可在此清理引用</summary>
|
||||
[NonSerialized] public System.Action<GameObject> OnPrefabRelease;
|
||||
/// <summary>
|
||||
/// 样式命名空间——对应 StyleManager 中的命名空间。
|
||||
/// 为空或 "xeric_table_default" 时使用默认表格样式。
|
||||
/// 渲染时从此命名空间读取 /cell/bg/color、/cell/font/size 等路径。
|
||||
/// </summary>
|
||||
public string StyleNamespace;
|
||||
|
||||
public XTableCellData()
|
||||
{ }
|
||||
/// <summary>
|
||||
/// 单元格级别样式覆盖——通过命名空间 + 路径引用样式表中的值。
|
||||
/// 渲染时优先使用此样式路径派生颜色/尺寸(如 {StylePath}/bg/color),未设置时回退到 StyleNamespace。
|
||||
/// </summary>
|
||||
public StyleMember CellStyle;
|
||||
|
||||
public XTableCellData(string text) => Text = text;
|
||||
/// <summary>预制体实例从对象池取出时回调——外部可在此初始化实例内容</summary>
|
||||
[NonSerialized] public System.Action<GameObject> OnPrefabAcquire;
|
||||
|
||||
public XTableCellData(string text, string styleNamespace = null) : this(text) =>
|
||||
StyleNamespace = styleNamespace;
|
||||
/// <summary>预制体实例归还对象池前回调——外部可在此清理引用</summary>
|
||||
[NonSerialized] public System.Action<GameObject> OnPrefabRelease;
|
||||
|
||||
public XTableCellData(string text, Texture2D image, string styleNamespace = null) :
|
||||
this(text, styleNamespace) => Image = image;
|
||||
public XTableCellData()
|
||||
{ }
|
||||
|
||||
public void ClearEvent()
|
||||
{
|
||||
OnPrefabAcquire = null;
|
||||
OnPrefabRelease = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
public XTableCellData(string text) => Text = text;
|
||||
|
||||
public XTableCellData(string text, string styleNamespace = null) : this(text) =>
|
||||
StyleNamespace = styleNamespace;
|
||||
|
||||
public XTableCellData(string text, Texture2D image, string styleNamespace = null) :
|
||||
this(text, styleNamespace) => Image = image;
|
||||
|
||||
/// <summary>获取该单元格渲染时使用的样式命名空间(CellStyle 优先,否则 fallback 到 StyleNamespace)</summary>
|
||||
public string GetEffectiveStyleNamespace(string fallbackNamespace)
|
||||
{
|
||||
if (CellStyle != null && !string.IsNullOrEmpty(CellStyle.CurrentNamespace))
|
||||
return CellStyle.CurrentNamespace;
|
||||
if (!string.IsNullOrEmpty(StyleNamespace))
|
||||
return StyleNamespace;
|
||||
return fallbackNamespace;
|
||||
}
|
||||
|
||||
public void ClearEvent()
|
||||
{
|
||||
OnPrefabAcquire = null;
|
||||
OnPrefabRelease = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace XericUI.XTable.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// 表格系统全局配置资源——统一管理布局、样式回退值、运行时颜色等参数。
|
||||
/// 表格组件在 Awake 时自动加载 Resources 中的 "XTableDefaultConfig",
|
||||
/// 或由外部脚本在初始化阶段显式赋值。
|
||||
/// </summary>
|
||||
[CreateAssetMenu(fileName = "XTableConfig", menuName = "Xeric Library/Table/Table Config", order = 100)]
|
||||
public class XTableConfig : ScriptableObject
|
||||
{
|
||||
#region 布局
|
||||
|
||||
[Header("布局")]
|
||||
[Tooltip("新增行时的默认行高(像素)")]
|
||||
public float DefaultRowHeight = 40f;
|
||||
|
||||
[Tooltip("新增列时的默认列宽(像素)")]
|
||||
public float DefaultColumnWidth = 100f;
|
||||
|
||||
[Tooltip("单元格内容水平内边距(左右各此值)")]
|
||||
public float CellHorizontalPadding = 4f;
|
||||
|
||||
#endregion
|
||||
|
||||
#region 四叉树
|
||||
|
||||
[Header("四叉树")]
|
||||
[Tooltip("单节点最大单元格数,超过此值强制空间分裂以提升可见性裁剪效率")]
|
||||
public int QuadtreeMaxCellsPerNode = 64;
|
||||
|
||||
#endregion
|
||||
|
||||
#region 对象池
|
||||
|
||||
[Header("对象池")]
|
||||
[Tooltip("通用对象池初始容量")]
|
||||
public int PoolInitialCapacity = 64;
|
||||
|
||||
#endregion
|
||||
|
||||
#region 样式回退值
|
||||
|
||||
[Header("样式回退值(当 StyleManager 中查不到时使用)")]
|
||||
[Tooltip("默认样式命名空间")]
|
||||
public string DefaultStyleNamespace = "xeric_table_default";
|
||||
|
||||
[Tooltip("单元格背景色")]
|
||||
public Color BgColor = new Color(0.18f, 0.18f, 0.18f, 1f);
|
||||
|
||||
[Tooltip("单元格前景色(文字颜色)")]
|
||||
public Color FgColor = new Color(0.05f, 0.05f, 0.05f);
|
||||
|
||||
[Tooltip("编辑器选中色")]
|
||||
public Color SelectionColor = new Color(0.2f, 0.5f, 1f, 0.3f);
|
||||
|
||||
[Tooltip("边框颜色")]
|
||||
public Color BorderColor = new Color(0.35f, 0.35f, 0.35f, 0.5f);
|
||||
|
||||
[Tooltip("边框宽度")]
|
||||
public float BorderWidth = 1f;
|
||||
|
||||
[Tooltip("字体大小")]
|
||||
public int FontSize = 14;
|
||||
|
||||
#endregion
|
||||
|
||||
#region 运行时颜色
|
||||
|
||||
[Header("运行时选中/边框颜色")]
|
||||
[Tooltip("运行时单选高亮")]
|
||||
public Color RuntimeSelectionColor = new Color(0.18f, 0.42f, 0.82f, 0.25f);
|
||||
|
||||
[Tooltip("运行时多选高亮")]
|
||||
public Color RuntimeMultiSelectColor = new Color(0.18f, 0.42f, 0.82f, 0.12f);
|
||||
|
||||
[Tooltip("运行时焦点高亮(当前选中格)")]
|
||||
public Color RuntimeFocusColor = new Color(0.22f, 0.55f, 0.95f, 0.35f);
|
||||
|
||||
[Tooltip("运行时边框色")]
|
||||
public Color RuntimeBorderColor = new Color(0.35f, 0.35f, 0.35f, 0.5f);
|
||||
|
||||
[Tooltip("运行时边框宽度")]
|
||||
public float RuntimeBorderWidth = 1f;
|
||||
|
||||
#endregion
|
||||
|
||||
#region 编辑器多选颜色因子
|
||||
|
||||
[Header("编辑器多选/焦点颜色因子(基于 SelectionColor 计算)")]
|
||||
[Tooltip("多选透明因子")]
|
||||
[Range(0, 1)] public float MultiSelectAlphaFactor = 0.4f;
|
||||
|
||||
[Tooltip("焦点色 R 增量")]
|
||||
[Range(0, 0.5f)] public float FocusRAdd = 0.04f;
|
||||
|
||||
[Tooltip("焦点色 G 增量")]
|
||||
[Range(0, 0.5f)] public float FocusGAdd = 0.13f;
|
||||
|
||||
[Tooltip("焦点色 B 增量")]
|
||||
[Range(0, 0.5f)] public float FocusBAdd = 0.13f;
|
||||
|
||||
[Tooltip("焦点色 Alpha 倍数")]
|
||||
[Range(0.1f, 3f)] public float FocusAlphaMul = 1.4f;
|
||||
|
||||
#endregion
|
||||
|
||||
#region 资源路径
|
||||
|
||||
/// <summary>Resources 目录下的默认配置文件名(不含扩展名)</summary>
|
||||
public const string DEFAULT_RESOURCE_PATH = "XTableDefaultConfig";
|
||||
|
||||
/// <summary>从 Resources 加载默认配置,若失败则返回 ScriptableObject.CreateInstance 的默认值</summary>
|
||||
public static XTableConfig LoadOrDefault()
|
||||
{
|
||||
var cfg = Resources.Load<XTableConfig>(DEFAULT_RESOURCE_PATH);
|
||||
if (cfg != null) return cfg;
|
||||
return CreateInstance<XTableConfig>();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 94d64cced79c6ef41af29f7473ff5105
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -65,12 +65,17 @@ namespace XericUI.XTable.Core
|
||||
private Node m_Root;
|
||||
private float[] m_RowHeights;
|
||||
private float[] m_ColWidths;
|
||||
private int m_MaxCellsPerNode;
|
||||
|
||||
/// <summary>四叉树是否已构建完成</summary>
|
||||
public bool IsBuilt { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region 常量
|
||||
|
||||
#endregion
|
||||
|
||||
#region 构建
|
||||
|
||||
/// <summary>
|
||||
@@ -83,7 +88,7 @@ namespace XericUI.XTable.Core
|
||||
/// <param name="cells">所有有数据的单元格元数据列表</param>
|
||||
public void Build(float totalWidth, float totalHeight,
|
||||
float[] rowHeights, float[] colWidths,
|
||||
List<XTableQuadtreeCell> cells)
|
||||
List<XTableQuadtreeCell> cells, int maxCellsPerNode = 64)
|
||||
{
|
||||
if (rowHeights == null || colWidths == null || cells == null)
|
||||
{
|
||||
@@ -93,6 +98,7 @@ namespace XericUI.XTable.Core
|
||||
|
||||
m_RowHeights = rowHeights;
|
||||
m_ColWidths = colWidths;
|
||||
m_MaxCellsPerNode = maxCellsPerNode;
|
||||
m_Root = new Node { Region = new Rect(0, 0, totalWidth, totalHeight) };
|
||||
|
||||
int maxRow = rowHeights.Length - 1;
|
||||
@@ -109,10 +115,10 @@ namespace XericUI.XTable.Core
|
||||
/// <summary>强制重建(外部入口,通常由表格组件在数据/布局变更后调用)</summary>
|
||||
public void ForceRebuild(float totalWidth, float totalHeight,
|
||||
float[] rowHeights, float[] colWidths,
|
||||
List<XTableQuadtreeCell> cells)
|
||||
List<XTableQuadtreeCell> cells, int maxCellsPerNode = 64)
|
||||
{
|
||||
Clear();
|
||||
Build(totalWidth, totalHeight, rowHeights, colWidths, cells);
|
||||
Build(totalWidth, totalHeight, rowHeights, colWidths, cells, maxCellsPerNode);
|
||||
}
|
||||
|
||||
private void BuildNode(Node node, List<XTableQuadtreeCell> allCells,
|
||||
@@ -149,11 +155,20 @@ namespace XericUI.XTable.Core
|
||||
|
||||
if (allSame)
|
||||
{
|
||||
node.UniformNamespace = firstNs;
|
||||
node.Cells = new List<(int, int)>(cellsInRange.Count);
|
||||
for (int i = 0; i < cellsInRange.Count; i++)
|
||||
node.Cells.Add((cellsInRange[i].Row, cellsInRange[i].Col));
|
||||
return;
|
||||
// 命名空间统一,但若空间跨度过大则继续分裂以便按块跳过不可见区域
|
||||
if (cellsInRange.Count > m_MaxCellsPerNode &&
|
||||
(minRow < maxRow || minCol < maxCol))
|
||||
{
|
||||
// 继续执行分裂逻辑(不要 return)
|
||||
}
|
||||
else
|
||||
{
|
||||
node.UniformNamespace = firstNs;
|
||||
node.Cells = new List<(int, int)>(cellsInRange.Count);
|
||||
for (int i = 0; i < cellsInRange.Count; i++)
|
||||
node.Cells.Add((cellsInRange[i].Row, cellsInRange[i].Col));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 无法继续分裂(单行单列),强制标记为均匀
|
||||
|
||||
Reference in New Issue
Block a user