修复表格中对样式的依赖与更新
This commit is contained in:
@@ -1,281 +1,280 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
using XericUI.XTable.Rendering.Component;
|
||||
|
||||
namespace XericUIEditor.XTable
|
||||
{
|
||||
/// <summary>
|
||||
/// XericUIActionTable 的 Inspector 编辑器——
|
||||
/// 折叠分组:[样式设定] [尺寸设定] [调试] [数据浏览]。
|
||||
/// 使用 EditorGUILayout.Foldout 避免与数组 PropertyField 内部的折叠冲突。
|
||||
/// </summary>
|
||||
[CustomEditor(typeof(XericUIActionTable))]
|
||||
public class XericUIActionTableEditor : Editor
|
||||
{
|
||||
private XericUIActionTable m_Table;
|
||||
/// <summary>
|
||||
/// XericUIActionTable 的 Inspector 编辑器——
|
||||
/// 折叠分组:[样式设定] [尺寸设定] [调试] [数据浏览]。
|
||||
/// 使用 EditorGUILayout.Foldout 避免与数组 PropertyField 内部的折叠冲突。
|
||||
/// </summary>
|
||||
[CustomEditor(typeof(XericUIActionTable))]
|
||||
public class XericUIActionTableEditor : Editor
|
||||
{
|
||||
private XericUIActionTable m_Table;
|
||||
|
||||
private SerializedProperty m_RowHeightsProp;
|
||||
private SerializedProperty m_ColWidthsProp;
|
||||
private SerializedProperty m_DefaultStyleNsProp;
|
||||
private SerializedProperty m_ScrollRectProp;
|
||||
private SerializedProperty m_RowHeightsProp;
|
||||
private SerializedProperty m_ColWidthsProp;
|
||||
private SerializedProperty m_DefaultStyleNsProp;
|
||||
private SerializedProperty m_ScrollRectProp;
|
||||
|
||||
// 折叠状态
|
||||
private static bool s_StyleFoldout = true;
|
||||
private static bool s_SizeFoldout = true;
|
||||
private static bool s_DebugFoldout;
|
||||
private static bool s_DataBrowseFoldout;
|
||||
// 折叠状态
|
||||
private static bool s_StyleFoldout = true;
|
||||
private static bool s_SizeFoldout = true;
|
||||
private static bool s_DebugFoldout;
|
||||
private static bool s_DataBrowseFoldout;
|
||||
|
||||
// 调试参数
|
||||
private bool m_ShowChildren;
|
||||
// 调试参数
|
||||
private bool m_ShowChildren;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
m_Table = (XericUIActionTable)target;
|
||||
private void OnEnable()
|
||||
{
|
||||
m_Table = (XericUIActionTable)target;
|
||||
|
||||
m_RowHeightsProp = serializedObject.FindProperty("m_RowHeights");
|
||||
m_ColWidthsProp = serializedObject.FindProperty("m_ColWidths");
|
||||
m_DefaultStyleNsProp = serializedObject.FindProperty("m_DefaultStyleNamespace");
|
||||
m_ScrollRectProp = serializedObject.FindProperty("m_ScrollRect");
|
||||
}
|
||||
m_RowHeightsProp = serializedObject.FindProperty("m_RowHeights");
|
||||
m_ColWidthsProp = serializedObject.FindProperty("m_ColWidths");
|
||||
m_DefaultStyleNsProp = serializedObject.FindProperty("m_DefaultStyleNamespace");
|
||||
m_ScrollRectProp = serializedObject.FindProperty("m_ScrollRect");
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
|
||||
// ===== 样式设定 =====
|
||||
s_StyleFoldout = EditorGUILayout.Foldout(s_StyleFoldout, "样式设定", true);
|
||||
if (s_StyleFoldout)
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
if (m_DefaultStyleNsProp != null)
|
||||
EditorGUILayout.PropertyField(m_DefaultStyleNsProp, new GUIContent("默认命名空间"));
|
||||
if (m_ScrollRectProp != null)
|
||||
EditorGUILayout.PropertyField(m_ScrollRectProp, new GUIContent("ScrollRect"));
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
// ===== 样式设定 =====
|
||||
s_StyleFoldout = EditorGUILayout.Foldout(s_StyleFoldout, "样式设定", true);
|
||||
if (s_StyleFoldout)
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
if (m_DefaultStyleNsProp != null)
|
||||
EditorGUILayout.PropertyField(m_DefaultStyleNsProp, new GUIContent("默认命名空间"));
|
||||
if (m_ScrollRectProp != null)
|
||||
EditorGUILayout.PropertyField(m_ScrollRectProp, new GUIContent("ScrollRect"));
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
// ===== 尺寸设定 =====
|
||||
EditorGUILayout.Space(4);
|
||||
s_SizeFoldout = EditorGUILayout.Foldout(s_SizeFoldout, "尺寸设定", true);
|
||||
if (s_SizeFoldout)
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
if (m_RowHeightsProp != null)
|
||||
EditorGUILayout.PropertyField(m_RowHeightsProp, new GUIContent("行高"), true);
|
||||
if (m_ColWidthsProp != null)
|
||||
EditorGUILayout.PropertyField(m_ColWidthsProp, new GUIContent("列宽"), true);
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
// ===== 尺寸设定 =====
|
||||
EditorGUILayout.Space(4);
|
||||
s_SizeFoldout = EditorGUILayout.Foldout(s_SizeFoldout, "尺寸设定", true);
|
||||
if (s_SizeFoldout)
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
if (m_RowHeightsProp != null)
|
||||
EditorGUILayout.PropertyField(m_RowHeightsProp, new GUIContent("行高"), true);
|
||||
if (m_ColWidthsProp != null)
|
||||
EditorGUILayout.PropertyField(m_ColWidthsProp, new GUIContent("列宽"), true);
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
// ===== 调试 =====
|
||||
EditorGUILayout.Space(4);
|
||||
s_DebugFoldout = EditorGUILayout.Foldout(s_DebugFoldout, "调试", true);
|
||||
if (s_DebugFoldout)
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
// ===== 调试 =====
|
||||
EditorGUILayout.Space(4);
|
||||
s_DebugFoldout = EditorGUILayout.Foldout(s_DebugFoldout, "调试", true);
|
||||
if (s_DebugFoldout)
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
|
||||
if (GUILayout.Button("重新生成表格", GUILayout.Height(26)))
|
||||
{
|
||||
m_Table.FullRebuild();
|
||||
m_Table.SetChildrenVisible(!m_ShowChildren);
|
||||
}
|
||||
if (GUILayout.Button("重新生成表格", GUILayout.Height(26)))
|
||||
{
|
||||
m_Table.FullRebuild();
|
||||
m_Table.SetChildrenVisible(!m_ShowChildren);
|
||||
}
|
||||
|
||||
EditorGUILayout.Space(4);
|
||||
EditorGUILayout.Space(4);
|
||||
|
||||
bool newShow = EditorGUILayout.Toggle("显示子项", m_ShowChildren);
|
||||
if (newShow != m_ShowChildren)
|
||||
{
|
||||
m_ShowChildren = newShow;
|
||||
m_Table.SetChildrenVisible(m_ShowChildren);
|
||||
}
|
||||
bool newShow = EditorGUILayout.Toggle("显示子项", m_ShowChildren);
|
||||
if (newShow != m_ShowChildren)
|
||||
{
|
||||
m_ShowChildren = newShow;
|
||||
m_Table.SetChildrenVisible(m_ShowChildren);
|
||||
}
|
||||
|
||||
if (m_ShowChildren)
|
||||
{
|
||||
EditorGUILayout.HelpBox(
|
||||
"子项已显示:所有动态生成的对象将在 Hierarchy 中可见(仍不保存到场景)。\n" +
|
||||
"用于排查表格元素堆积或渲染异常问题。",
|
||||
MessageType.Info);
|
||||
}
|
||||
if (m_ShowChildren)
|
||||
{
|
||||
EditorGUILayout.HelpBox(
|
||||
"子项已显示:所有动态生成的对象将在 Hierarchy 中可见(仍不保存到场景)。\n" +
|
||||
"用于排查表格元素堆积或渲染异常问题。",
|
||||
MessageType.Info);
|
||||
}
|
||||
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
// ===== 数据浏览 =====
|
||||
EditorGUILayout.Space(4);
|
||||
s_DataBrowseFoldout = EditorGUILayout.Foldout(s_DataBrowseFoldout, "数据浏览", true);
|
||||
if (s_DataBrowseFoldout)
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
// ===== 数据浏览 =====
|
||||
EditorGUILayout.Space(4);
|
||||
s_DataBrowseFoldout = EditorGUILayout.Foldout(s_DataBrowseFoldout, "数据浏览", true);
|
||||
if (s_DataBrowseFoldout)
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
|
||||
if (m_Table.TableData != null)
|
||||
{
|
||||
EditorGUI.BeginDisabledGroup(true);
|
||||
EditorGUILayout.IntField("块数量", m_Table.TableData.BlockCount);
|
||||
EditorGUILayout.TextField("块尺寸",
|
||||
$"{m_Table.TableData.BlockSizeX} × {m_Table.TableData.BlockSizeY}");
|
||||
EditorGUILayout.TextField("选中单元格",
|
||||
m_Table.SelectedRow >= 0 ? $"({m_Table.SelectedRow}, {m_Table.SelectedCol})" : "(未选中)");
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.HelpBox("TableData 为空——Awake() 执行后会自动创建默认实例。", MessageType.Info);
|
||||
}
|
||||
if (m_Table.TableData != null)
|
||||
{
|
||||
EditorGUI.BeginDisabledGroup(true);
|
||||
EditorGUILayout.IntField("块数量", m_Table.TableData.BlockCount);
|
||||
EditorGUILayout.TextField("块尺寸",
|
||||
$"{m_Table.TableData.BlockSizeX} × {m_Table.TableData.BlockSizeY}");
|
||||
EditorGUILayout.TextField("选中单元格",
|
||||
m_Table.SelectedRow >= 0 ? $"({m_Table.SelectedRow}, {m_Table.SelectedCol})" : "(未选中)");
|
||||
EditorGUI.EndDisabledGroup();
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.HelpBox("TableData 为空——Awake() 执行后会自动创建默认实例。", MessageType.Info);
|
||||
}
|
||||
|
||||
EditorGUILayout.Space(4);
|
||||
if (GUILayout.Button("手动刷新视图", GUILayout.Height(22)))
|
||||
EditorApplication.delayCall += () => m_Table.RefreshView();
|
||||
EditorGUILayout.Space(4);
|
||||
if (GUILayout.Button("手动刷新视图", GUILayout.Height(22)))
|
||||
EditorApplication.delayCall += () => m_Table.RefreshView();
|
||||
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
#region Hierarchy 创建菜单
|
||||
#region Hierarchy 创建菜单
|
||||
|
||||
[MenuItem("GameObject/Xeric UI/Table/Xeric UI Action Table", false, 60)]
|
||||
private static void CreateTable(MenuCommand menuCommand)
|
||||
{
|
||||
// 1. 创建表格内容节点
|
||||
GameObject contentGo = new GameObject("Content",
|
||||
typeof(RectTransform), typeof(CanvasRenderer), typeof(XericUIActionTable));
|
||||
RectTransform contentRt = contentGo.GetComponent<RectTransform>();
|
||||
contentRt.anchorMin = new Vector2(0, 1);
|
||||
contentRt.anchorMax = new Vector2(0, 1);
|
||||
contentRt.pivot = new Vector2(0, 1);
|
||||
contentRt.anchoredPosition = Vector2.zero;
|
||||
contentRt.sizeDelta = new Vector2(800, 600);
|
||||
XericUIActionTable table = contentGo.GetComponent<XericUIActionTable>();
|
||||
[MenuItem("GameObject/Xeric UI/Table/Xeric UI Action Table", false, 60)]
|
||||
private static void CreateTable(MenuCommand menuCommand)
|
||||
{
|
||||
// 1. 创建表格内容节点
|
||||
GameObject contentGo = new GameObject("Content",
|
||||
typeof(RectTransform), typeof(CanvasRenderer), typeof(XericUIActionTable));
|
||||
RectTransform contentRt = contentGo.GetComponent<RectTransform>();
|
||||
contentRt.anchorMin = new Vector2(0, 1);
|
||||
contentRt.anchorMax = new Vector2(0, 1);
|
||||
contentRt.pivot = new Vector2(0, 1);
|
||||
contentRt.anchoredPosition = Vector2.zero;
|
||||
contentRt.sizeDelta = new Vector2(800, 600);
|
||||
XericUIActionTable table = contentGo.GetComponent<XericUIActionTable>();
|
||||
|
||||
// 2. 创建 Viewport(Mask 裁剪区域)
|
||||
GameObject viewportGo = new GameObject("Viewport",
|
||||
typeof(RectTransform), typeof(Image), typeof(Mask));
|
||||
viewportGo.GetComponent<Image>().color = new Color(1, 1, 1, 0.01f);
|
||||
RectTransform vpRt = viewportGo.GetComponent<RectTransform>();
|
||||
vpRt.anchorMin = Vector2.zero;
|
||||
vpRt.anchorMax = Vector2.one;
|
||||
vpRt.sizeDelta = Vector2.zero;
|
||||
contentRt.SetParent(vpRt, false);
|
||||
// 2. 创建 Viewport(Mask 裁剪区域)
|
||||
GameObject viewportGo = new GameObject("Viewport",
|
||||
typeof(RectTransform), typeof(Image), typeof(Mask));
|
||||
viewportGo.GetComponent<Image>().color = new Color(1, 1, 1, 0.01f);
|
||||
RectTransform vpRt = viewportGo.GetComponent<RectTransform>();
|
||||
vpRt.anchorMin = Vector2.zero;
|
||||
vpRt.anchorMax = Vector2.one;
|
||||
vpRt.sizeDelta = Vector2.zero;
|
||||
contentRt.SetParent(vpRt, false);
|
||||
|
||||
// 3. 创建水平滚动条
|
||||
GameObject hScrollbarGo = new GameObject("Scrollbar Horizontal",
|
||||
typeof(RectTransform), typeof(Scrollbar), typeof(Image));
|
||||
RectTransform hBarRt = hScrollbarGo.GetComponent<RectTransform>();
|
||||
hBarRt.anchorMin = new Vector2(0, 0);
|
||||
hBarRt.anchorMax = new Vector2(1, 0);
|
||||
hBarRt.pivot = new Vector2(0.5f, 0);
|
||||
hBarRt.anchoredPosition = new Vector2(0, 4);
|
||||
hBarRt.sizeDelta = new Vector2(-16, 20);
|
||||
Image hBarImg = hScrollbarGo.GetComponent<Image>();
|
||||
hBarImg.color = new Color(0.15f, 0.15f, 0.15f, 0.5f);
|
||||
Scrollbar hBar = hScrollbarGo.GetComponent<Scrollbar>();
|
||||
hBar.direction = Scrollbar.Direction.LeftToRight;
|
||||
// 3. 创建水平滚动条
|
||||
GameObject hScrollbarGo = new GameObject("Scrollbar Horizontal",
|
||||
typeof(RectTransform), typeof(Scrollbar), typeof(Image));
|
||||
RectTransform hBarRt = hScrollbarGo.GetComponent<RectTransform>();
|
||||
hBarRt.anchorMin = new Vector2(0, 0);
|
||||
hBarRt.anchorMax = new Vector2(1, 0);
|
||||
hBarRt.pivot = new Vector2(0.5f, 0);
|
||||
hBarRt.anchoredPosition = new Vector2(0, 4);
|
||||
hBarRt.sizeDelta = new Vector2(-16, 20);
|
||||
Image hBarImg = hScrollbarGo.GetComponent<Image>();
|
||||
hBarImg.color = new Color(0.15f, 0.15f, 0.15f, 0.5f);
|
||||
Scrollbar hBar = hScrollbarGo.GetComponent<Scrollbar>();
|
||||
hBar.direction = Scrollbar.Direction.LeftToRight;
|
||||
|
||||
GameObject hSlidingGo = new GameObject("Sliding Area",
|
||||
typeof(RectTransform));
|
||||
hSlidingGo.transform.SetParent(hScrollbarGo.transform, false);
|
||||
RectTransform hSlidingRt = hSlidingGo.GetComponent<RectTransform>();
|
||||
hSlidingRt.anchorMin = Vector2.zero;
|
||||
hSlidingRt.anchorMax = Vector2.one;
|
||||
hSlidingRt.sizeDelta = new Vector2(-20, -20);
|
||||
GameObject hSlidingGo = new GameObject("Sliding Area",
|
||||
typeof(RectTransform));
|
||||
hSlidingGo.transform.SetParent(hScrollbarGo.transform, false);
|
||||
RectTransform hSlidingRt = hSlidingGo.GetComponent<RectTransform>();
|
||||
hSlidingRt.anchorMin = Vector2.zero;
|
||||
hSlidingRt.anchorMax = Vector2.one;
|
||||
hSlidingRt.sizeDelta = new Vector2(-20, -20);
|
||||
|
||||
GameObject hHandleGo = new GameObject("Handle",
|
||||
typeof(RectTransform), typeof(Image));
|
||||
hHandleGo.transform.SetParent(hSlidingGo.transform, false);
|
||||
RectTransform hHandleRt = hHandleGo.GetComponent<RectTransform>();
|
||||
hHandleRt.anchorMin = Vector2.zero;
|
||||
hHandleRt.anchorMax = Vector2.one;
|
||||
hHandleRt.sizeDelta = new Vector2(-20, -20);
|
||||
hHandleGo.GetComponent<Image>().color = new Color(0.4f, 0.4f, 0.4f, 0.8f);
|
||||
hBar.handleRect = hHandleRt;
|
||||
GameObject hHandleGo = new GameObject("Handle",
|
||||
typeof(RectTransform), typeof(Image));
|
||||
hHandleGo.transform.SetParent(hSlidingGo.transform, false);
|
||||
RectTransform hHandleRt = hHandleGo.GetComponent<RectTransform>();
|
||||
hHandleRt.anchorMin = Vector2.zero;
|
||||
hHandleRt.anchorMax = Vector2.one;
|
||||
hHandleRt.sizeDelta = new Vector2(-20, -20);
|
||||
hHandleGo.GetComponent<Image>().color = new Color(0.4f, 0.4f, 0.4f, 0.8f);
|
||||
hBar.handleRect = hHandleRt;
|
||||
|
||||
// 4. 创建垂直滚动条
|
||||
GameObject vScrollbarGo = new GameObject("Scrollbar Vertical",
|
||||
typeof(RectTransform), typeof(Scrollbar), typeof(Image));
|
||||
RectTransform vBarRt = vScrollbarGo.GetComponent<RectTransform>();
|
||||
vBarRt.anchorMin = new Vector2(1, 0);
|
||||
vBarRt.anchorMax = new Vector2(1, 1);
|
||||
vBarRt.pivot = new Vector2(1, 0.5f);
|
||||
vBarRt.anchoredPosition = new Vector2(-4, 0);
|
||||
vBarRt.sizeDelta = new Vector2(20, -16);
|
||||
Image vBarImg = vScrollbarGo.GetComponent<Image>();
|
||||
vBarImg.color = new Color(0.15f, 0.15f, 0.15f, 0.5f);
|
||||
Scrollbar vBar = vScrollbarGo.GetComponent<Scrollbar>();
|
||||
vBar.direction = Scrollbar.Direction.BottomToTop;
|
||||
// 4. 创建垂直滚动条
|
||||
GameObject vScrollbarGo = new GameObject("Scrollbar Vertical",
|
||||
typeof(RectTransform), typeof(Scrollbar), typeof(Image));
|
||||
RectTransform vBarRt = vScrollbarGo.GetComponent<RectTransform>();
|
||||
vBarRt.anchorMin = new Vector2(1, 0);
|
||||
vBarRt.anchorMax = new Vector2(1, 1);
|
||||
vBarRt.pivot = new Vector2(1, 0.5f);
|
||||
vBarRt.anchoredPosition = new Vector2(-4, 0);
|
||||
vBarRt.sizeDelta = new Vector2(20, -16);
|
||||
Image vBarImg = vScrollbarGo.GetComponent<Image>();
|
||||
vBarImg.color = new Color(0.15f, 0.15f, 0.15f, 0.5f);
|
||||
Scrollbar vBar = vScrollbarGo.GetComponent<Scrollbar>();
|
||||
vBar.direction = Scrollbar.Direction.BottomToTop;
|
||||
|
||||
GameObject vSlidingGo = new GameObject("Sliding Area",
|
||||
typeof(RectTransform));
|
||||
vSlidingGo.transform.SetParent(vScrollbarGo.transform, false);
|
||||
RectTransform vSlidingRt = vSlidingGo.GetComponent<RectTransform>();
|
||||
vSlidingRt.anchorMin = Vector2.zero;
|
||||
vSlidingRt.anchorMax = Vector2.one;
|
||||
vSlidingRt.sizeDelta = new Vector2(-20, -20);
|
||||
GameObject vSlidingGo = new GameObject("Sliding Area",
|
||||
typeof(RectTransform));
|
||||
vSlidingGo.transform.SetParent(vScrollbarGo.transform, false);
|
||||
RectTransform vSlidingRt = vSlidingGo.GetComponent<RectTransform>();
|
||||
vSlidingRt.anchorMin = Vector2.zero;
|
||||
vSlidingRt.anchorMax = Vector2.one;
|
||||
vSlidingRt.sizeDelta = new Vector2(-20, -20);
|
||||
|
||||
GameObject vHandleGo = new GameObject("Handle",
|
||||
typeof(RectTransform), typeof(Image));
|
||||
vHandleGo.transform.SetParent(vSlidingGo.transform, false);
|
||||
RectTransform vHandleRt = vHandleGo.GetComponent<RectTransform>();
|
||||
vHandleRt.anchorMin = Vector2.zero;
|
||||
vHandleRt.anchorMax = Vector2.one;
|
||||
vHandleRt.sizeDelta = new Vector2(-20, -20);
|
||||
vHandleGo.GetComponent<Image>().color = new Color(0.4f, 0.4f, 0.4f, 0.8f);
|
||||
vBar.handleRect = vHandleRt;
|
||||
GameObject vHandleGo = new GameObject("Handle",
|
||||
typeof(RectTransform), typeof(Image));
|
||||
vHandleGo.transform.SetParent(vSlidingGo.transform, false);
|
||||
RectTransform vHandleRt = vHandleGo.GetComponent<RectTransform>();
|
||||
vHandleRt.anchorMin = Vector2.zero;
|
||||
vHandleRt.anchorMax = Vector2.one;
|
||||
vHandleRt.sizeDelta = new Vector2(-20, -20);
|
||||
vHandleGo.GetComponent<Image>().color = new Color(0.4f, 0.4f, 0.4f, 0.8f);
|
||||
vBar.handleRect = vHandleRt;
|
||||
|
||||
// 5. 创建 ScrollView 根节点
|
||||
GameObject scrollGo = new GameObject("Xeric UI Action Table",
|
||||
typeof(RectTransform), typeof(ScrollRect), typeof(Image));
|
||||
RectTransform scrollRt = scrollGo.GetComponent<RectTransform>();
|
||||
scrollRt.sizeDelta = new Vector2(800, 600);
|
||||
scrollGo.GetComponent<Image>().color = new Color(0.1f, 0.1f, 0.1f, 0.3f);
|
||||
// 5. 创建 ScrollView 根节点
|
||||
GameObject scrollGo = new GameObject("Xeric UI Action Table",
|
||||
typeof(RectTransform), typeof(ScrollRect), typeof(Image));
|
||||
RectTransform scrollRt = scrollGo.GetComponent<RectTransform>();
|
||||
scrollRt.sizeDelta = new Vector2(800, 600);
|
||||
scrollGo.GetComponent<Image>().color = new Color(0.1f, 0.1f, 0.1f, 0.3f);
|
||||
|
||||
ScrollRect scrollRect = scrollGo.GetComponent<ScrollRect>();
|
||||
scrollRect.content = contentRt;
|
||||
scrollRect.viewport = vpRt;
|
||||
scrollRect.horizontalScrollbar = hBar;
|
||||
scrollRect.verticalScrollbar = vBar;
|
||||
scrollRect.horizontalScrollbarVisibility = ScrollRect.ScrollbarVisibility.AutoHide;
|
||||
scrollRect.verticalScrollbarVisibility = ScrollRect.ScrollbarVisibility.AutoHide;
|
||||
scrollRect.movementType = ScrollRect.MovementType.Clamped;
|
||||
ScrollRect scrollRect = scrollGo.GetComponent<ScrollRect>();
|
||||
scrollRect.content = contentRt;
|
||||
scrollRect.viewport = vpRt;
|
||||
scrollRect.horizontalScrollbar = hBar;
|
||||
scrollRect.verticalScrollbar = vBar;
|
||||
scrollRect.horizontalScrollbarVisibility = ScrollRect.ScrollbarVisibility.AutoHide;
|
||||
scrollRect.verticalScrollbarVisibility = ScrollRect.ScrollbarVisibility.AutoHide;
|
||||
scrollRect.movementType = ScrollRect.MovementType.Clamped;
|
||||
|
||||
// 组装层级
|
||||
vpRt.SetParent(scrollRt, false);
|
||||
hScrollbarGo.transform.SetParent(scrollRt, false);
|
||||
vScrollbarGo.transform.SetParent(scrollRt, false);
|
||||
// 组装层级
|
||||
vpRt.SetParent(scrollRt, false);
|
||||
hScrollbarGo.transform.SetParent(scrollRt, false);
|
||||
vScrollbarGo.transform.SetParent(scrollRt, false);
|
||||
|
||||
// 绑定 ScrollRect 到表格(通过 SerializedObject 正确回写)
|
||||
using (SerializedObject so = new SerializedObject(table))
|
||||
{
|
||||
SerializedProperty prop = so.FindProperty("m_ScrollRect");
|
||||
if (prop != null)
|
||||
{
|
||||
prop.objectReferenceValue = scrollRect;
|
||||
so.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
// 绑定 ScrollRect 到表格(通过 SerializedObject 正确回写)
|
||||
using (SerializedObject so = new SerializedObject(table))
|
||||
{
|
||||
SerializedProperty prop = so.FindProperty("m_ScrollRect");
|
||||
if (prop != null)
|
||||
{
|
||||
prop.objectReferenceValue = scrollRect;
|
||||
so.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
|
||||
// 挂载到 Canvas
|
||||
GameObject parent = GetOrCreateCanvas();
|
||||
scrollRt.SetParent(parent.transform, false);
|
||||
// 挂载到 Canvas
|
||||
GameObject parent = GetOrCreateCanvas();
|
||||
scrollRt.SetParent(parent.transform, false);
|
||||
|
||||
Undo.RegisterCreatedObjectUndo(scrollGo, "Create Xeric UI Action Table");
|
||||
Selection.activeGameObject = scrollGo;
|
||||
}
|
||||
Undo.RegisterCreatedObjectUndo(scrollGo, "Create Xeric UI Action Table");
|
||||
Selection.activeGameObject = scrollGo;
|
||||
}
|
||||
|
||||
private static GameObject GetOrCreateCanvas()
|
||||
{
|
||||
Canvas canvas = Object.FindObjectOfType<Canvas>();
|
||||
if (canvas != null && canvas.isRootCanvas)
|
||||
return canvas.gameObject;
|
||||
private static GameObject GetOrCreateCanvas()
|
||||
{
|
||||
Canvas canvas = Object.FindObjectOfType<Canvas>();
|
||||
if (canvas != null && canvas.isRootCanvas)
|
||||
return canvas.gameObject;
|
||||
|
||||
GameObject canvasGo = new GameObject("Canvas",
|
||||
typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster));
|
||||
canvasGo.GetComponent<Canvas>().renderMode = RenderMode.ScreenSpaceOverlay;
|
||||
return canvasGo;
|
||||
}
|
||||
GameObject canvasGo = new GameObject("Canvas",
|
||||
typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster));
|
||||
canvasGo.GetComponent<Canvas>().renderMode = RenderMode.ScreenSpaceOverlay;
|
||||
return canvasGo;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -103,12 +103,12 @@ namespace XericUI.Core.StyleSheetUI
|
||||
|
||||
public void SubscribeAll(Action<StyleValue> callback)
|
||||
{
|
||||
foreach (var f in AllFields) { if (f != null) f.OnValueChanged += callback; }
|
||||
foreach (var f in AllFields) { if (f != null) f.Member.OnValueChanged += callback; }
|
||||
}
|
||||
|
||||
public void UnsubscribeAll(Action<StyleValue> callback)
|
||||
{
|
||||
foreach (var f in AllFields) { if (f != null) f.OnValueChanged -= callback; }
|
||||
foreach (var f in AllFields) { if (f != null) f.Member.OnValueChanged -= callback; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -49,25 +49,39 @@ namespace XericUI.OverrideUI
|
||||
|
||||
if (!m_AutoRefresh) return;
|
||||
|
||||
m_ColorStyle?.Register();
|
||||
m_TextureStyle?.Register();
|
||||
m_MaterialStyle?.Register();
|
||||
m_ColorStyle.OnValueChanged += OnStyleChanged;
|
||||
m_TextureStyle.OnValueChanged += OnStyleChanged;
|
||||
m_MaterialStyle.OnValueChanged += OnStyleChanged;
|
||||
RegisterIfValid(m_ColorStyle);
|
||||
RegisterIfValid(m_TextureStyle);
|
||||
RegisterIfValid(m_MaterialStyle);
|
||||
|
||||
ApplyAllStyles();
|
||||
}
|
||||
|
||||
protected override void OnDisable()
|
||||
{
|
||||
if (m_ColorStyle != null) { m_ColorStyle.OnValueChanged -= OnStyleChanged; m_ColorStyle.Unregister(); }
|
||||
if (m_TextureStyle != null) { m_TextureStyle.OnValueChanged -= OnStyleChanged; m_TextureStyle.Unregister(); }
|
||||
if (m_MaterialStyle != null) { m_MaterialStyle.OnValueChanged -= OnStyleChanged; m_MaterialStyle.Unregister(); }
|
||||
UnregisterIfValid(m_ColorStyle);
|
||||
UnregisterIfValid(m_TextureStyle);
|
||||
UnregisterIfValid(m_MaterialStyle);
|
||||
|
||||
base.OnDisable();
|
||||
}
|
||||
|
||||
private void RegisterIfValid(StyleField field)
|
||||
{
|
||||
if (field == null) return;
|
||||
// 路径为空说明未在 Inspector 中配置,跳过注册避免空路径查询错误
|
||||
if (string.IsNullOrEmpty(field.StylePath)) return;
|
||||
field.Register();
|
||||
field.Member.OnValueChanged += OnStyleChanged;
|
||||
}
|
||||
|
||||
private void UnregisterIfValid(StyleField field)
|
||||
{
|
||||
if (field == null) return;
|
||||
if (string.IsNullOrEmpty(field.StylePath)) return;
|
||||
field.Member.OnValueChanged -= OnStyleChanged;
|
||||
field.Unregister();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 样式应用
|
||||
@@ -83,12 +97,12 @@ namespace XericUI.OverrideUI
|
||||
if (m_TextureStyle != null)
|
||||
{
|
||||
StyleValue val = m_TextureStyle.GetValue();
|
||||
Sprite sp = val?.GetValueAs<Sprite>();
|
||||
if (sp != null) { m_ResolvedSprite = sp; sprite = sp; }
|
||||
else
|
||||
if (val != null)
|
||||
{
|
||||
Texture2D tex = val?.GetValueAs<Texture2D>();
|
||||
if (tex != null)
|
||||
// 通过 Unity Object 基类获取并类型判断,抑制 Color→Object 转换的日志错误
|
||||
Object obj = SafeGetObject<Object>(val);
|
||||
if (obj is Sprite sp) { m_ResolvedSprite = sp; sprite = sp; }
|
||||
else if (obj is Texture2D tex)
|
||||
{
|
||||
m_ResolvedSprite = Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), new Vector2(0.5f, 0.5f));
|
||||
sprite = m_ResolvedSprite;
|
||||
@@ -99,8 +113,11 @@ namespace XericUI.OverrideUI
|
||||
if (m_MaterialStyle != null)
|
||||
{
|
||||
StyleValue val = m_MaterialStyle.GetValue();
|
||||
Material mat = val?.GetValueAs<Material>();
|
||||
if (mat != null) material = mat;
|
||||
if (val != null)
|
||||
{
|
||||
Object obj = SafeGetObject<Object>(val);
|
||||
if (obj is Material mat) material = mat;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,6 +129,23 @@ namespace XericUI.OverrideUI
|
||||
|
||||
#endregion
|
||||
|
||||
#region 辅助
|
||||
|
||||
/// <summary>
|
||||
/// 安全获取 UnityEngine.Object 类型值——临时关闭日志以抑制 StyleValue 内部的类型不匹配错误。
|
||||
/// </summary>
|
||||
private static T SafeGetObject<T>(StyleValue val) where T : Object
|
||||
{
|
||||
if (val == null) return null;
|
||||
var logger = Debug.unityLogger;
|
||||
bool prev = logger.logEnabled;
|
||||
logger.logEnabled = false;
|
||||
try { return val.GetValueAs<T>(); }
|
||||
finally { logger.logEnabled = prev; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 组件替换
|
||||
|
||||
#if UNITY_EDITOR
|
||||
|
||||
@@ -80,11 +80,11 @@ namespace XericUI.OverrideUI
|
||||
m_TextureState?.SubscribeAll(OnStyleChanged);
|
||||
|
||||
m_OnOverrideColor?.Register();
|
||||
m_OnOverrideColor.OnValueChanged += OnStyleChanged;
|
||||
m_OnOverrideColor.Member.OnValueChanged += OnStyleChanged;
|
||||
m_OnOverrideTexture?.Register();
|
||||
m_OnOverrideTexture.OnValueChanged += OnStyleChanged;
|
||||
m_OnOverrideTexture.Member.OnValueChanged += OnStyleChanged;
|
||||
m_CheckmarkStyle?.Register();
|
||||
m_CheckmarkStyle.OnValueChanged += OnStyleChanged;
|
||||
m_CheckmarkStyle.Member.OnValueChanged += OnStyleChanged;
|
||||
|
||||
StyleRefreshManager.Register(this);
|
||||
onValueChanged.AddListener(OnToggleValueChanged);
|
||||
@@ -101,9 +101,9 @@ namespace XericUI.OverrideUI
|
||||
m_TextureState?.UnsubscribeAll(OnStyleChanged);
|
||||
m_ColorState?.UnregisterAll();
|
||||
m_TextureState?.UnregisterAll();
|
||||
if (m_OnOverrideColor != null) { m_OnOverrideColor.OnValueChanged -= OnStyleChanged; m_OnOverrideColor.Unregister(); }
|
||||
if (m_OnOverrideTexture != null) { m_OnOverrideTexture.OnValueChanged -= OnStyleChanged; m_OnOverrideTexture.Unregister(); }
|
||||
if (m_CheckmarkStyle != null) { m_CheckmarkStyle.OnValueChanged -= OnStyleChanged; m_CheckmarkStyle.Unregister(); }
|
||||
if (m_OnOverrideColor != null) { m_OnOverrideColor.Member.OnValueChanged -= OnStyleChanged; m_OnOverrideColor.Unregister(); }
|
||||
if (m_OnOverrideTexture != null) { m_OnOverrideTexture.Member.OnValueChanged -= OnStyleChanged; m_OnOverrideTexture.Unregister(); }
|
||||
if (m_CheckmarkStyle != null) { m_CheckmarkStyle.Member.OnValueChanged -= OnStyleChanged; m_CheckmarkStyle.Unregister(); }
|
||||
|
||||
base.OnDisable();
|
||||
}
|
||||
|
||||
@@ -75,27 +75,78 @@ namespace XericUI
|
||||
|
||||
|
||||
private XericImage m_ximage;
|
||||
private bool m_ximageCached;
|
||||
|
||||
protected XericImage ximage
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_ximageCached)
|
||||
return m_ximage;
|
||||
|
||||
if (m_ximage)
|
||||
{
|
||||
m_ximageCached = true;
|
||||
return m_ximage;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if (!graphic)
|
||||
{
|
||||
m_ximageCached = true;
|
||||
return null;
|
||||
}
|
||||
#endif
|
||||
m_ximage = graphic.GetComponent<XericImage>();
|
||||
m_ximageCached = true;
|
||||
if (m_ximage)
|
||||
return m_ximage;
|
||||
#if UNITY_EDITOR
|
||||
if (!graphic)
|
||||
return null;
|
||||
#endif
|
||||
m_ximage = graphic.GetComponent<XericImage>();
|
||||
if (m_ximage)
|
||||
return m_ximage;
|
||||
Debug.Log("请替换toggle的checkmark为XericImage以支持更多的功能");
|
||||
#endif
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private bool bindXImage;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected override void OnEnable()
|
||||
{
|
||||
EnsureXericImageCheckmark();
|
||||
base.OnEnable();
|
||||
}
|
||||
|
||||
private void EnsureXericImageCheckmark()
|
||||
{
|
||||
if (graphic == null || graphic is XericImage) return;
|
||||
|
||||
var img = graphic as Image;
|
||||
if (img == null) return;
|
||||
|
||||
var go = img.gameObject;
|
||||
var sprite = img.sprite;
|
||||
var color = img.color;
|
||||
var material = img.material;
|
||||
var raycastTarget = img.raycastTarget;
|
||||
var type = img.type;
|
||||
|
||||
UnityEditor.Undo.DestroyObjectImmediate(img);
|
||||
var ximg = UnityEditor.Undo.AddComponent<XericImage>(go);
|
||||
ximg.sprite = sprite;
|
||||
ximg.color = color;
|
||||
ximg.material = material;
|
||||
ximg.raycastTarget = raycastTarget;
|
||||
ximg.type = type;
|
||||
UnityEditor.EditorUtility.SetDirty(go);
|
||||
#if dUI_TextMeshPro
|
||||
Debug.Log("已将 Toggle 的 Checkmark 自动替换为 XericImage,以支持更多功能");
|
||||
#else
|
||||
Debug.Log("已将 Toggle 的 Checkmark 自动替换为 XericImage");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
protected override void InstantClearState()
|
||||
{
|
||||
base.InstantClearState();
|
||||
|
||||
@@ -127,7 +127,7 @@ namespace XericUI.XTable.Rendering.Component
|
||||
if (m_TableData == null)
|
||||
m_TableData = new XTableData();
|
||||
|
||||
m_Assembler = new CellAssembler(rectTransform);
|
||||
m_Assembler = new CellAssembler(rectTransform, m_DefaultStyleNamespace);
|
||||
RecalculateTotalSize();
|
||||
EnsureDefaultStyleNamespace();
|
||||
CreateDefaultSampleData();
|
||||
@@ -138,6 +138,8 @@ namespace XericUI.XTable.Rendering.Component
|
||||
|
||||
if (!Application.isPlaying)
|
||||
SubscribeEditorUpdate();
|
||||
else
|
||||
m_Assembler.OnStyleChangeDetected += OnPoolStyleChanged;
|
||||
|
||||
MarkDirty(TableDirtyType.All);
|
||||
}
|
||||
@@ -160,6 +162,9 @@ namespace XericUI.XTable.Rendering.Component
|
||||
m_ScrollRect.onValueChanged.RemoveListener(OnScrollValueChanged);
|
||||
UnsubscribeEditorUpdate();
|
||||
|
||||
if (m_Assembler != null)
|
||||
m_Assembler.OnStyleChangeDetected -= OnPoolStyleChanged;
|
||||
|
||||
// 销毁所有动态生成的对象
|
||||
if (m_Assembler != null)
|
||||
m_Assembler.DestroyAll();
|
||||
@@ -548,7 +553,7 @@ namespace XericUI.XTable.Rendering.Component
|
||||
if (m_Assembler == null)
|
||||
{
|
||||
if (rectTransform != null)
|
||||
m_Assembler = new CellAssembler(rectTransform);
|
||||
m_Assembler = new CellAssembler(rectTransform, m_DefaultStyleNamespace);
|
||||
else return;
|
||||
}
|
||||
|
||||
@@ -678,7 +683,7 @@ namespace XericUI.XTable.Rendering.Component
|
||||
|
||||
m_TableData = new XTableData();
|
||||
|
||||
m_Assembler = new CellAssembler(rectTransform);
|
||||
m_Assembler = new CellAssembler(rectTransform, m_DefaultStyleNamespace);
|
||||
RecalculateTotalSize();
|
||||
CreateDefaultSampleData();
|
||||
CreateBackground();
|
||||
@@ -692,12 +697,10 @@ namespace XericUI.XTable.Rendering.Component
|
||||
|
||||
private void RenderCells(int sr, int er, int sc, int ec)
|
||||
{
|
||||
Color fgColor = GetStyleColor(m_DefaultStyleNamespace, "/cell/fg/color",
|
||||
new Color(0.05f, 0.05f, 0.05f));
|
||||
Color fgFallback = new Color(0.05f, 0.05f, 0.05f);
|
||||
Color selectionColor = new Color(0.18f, 0.42f, 0.82f, 0.25f);
|
||||
Color multiSelectColor = new Color(0.18f, 0.42f, 0.82f, 0.12f);
|
||||
Color focusColor = new Color(0.22f, 0.55f, 0.95f, 0.35f);
|
||||
int fontSize = GetStyleInt(m_DefaultStyleNamespace, "/cell/font/size", 14);
|
||||
|
||||
for (int r = sr; r < er && r < m_RowHeights.Length; r++)
|
||||
{
|
||||
@@ -708,6 +711,8 @@ namespace XericUI.XTable.Rendering.Component
|
||||
float cellW = m_ColWidths[c];
|
||||
float cellH = m_RowHeights[r];
|
||||
XTableCellData data = TableData.GetCell(r, c);
|
||||
string cellNS = (data != null && !string.IsNullOrEmpty(data.StyleNamespace))
|
||||
? data.StyleNamespace : m_DefaultStyleNamespace;
|
||||
|
||||
// 多选范围高亮(覆盖被选中范围内的所有格)
|
||||
if (IsInSelectionRange(r, c))
|
||||
@@ -742,16 +747,25 @@ namespace XericUI.XTable.Rendering.Component
|
||||
|
||||
if (data == null) continue;
|
||||
|
||||
// 文本:与 cell 同位置同尺寸,TMP 内部 Midline 对齐实现居中
|
||||
// 文本:与 cell 同位置同尺寸
|
||||
if (!string.IsNullOrEmpty(data.Text))
|
||||
{
|
||||
var txt = m_Assembler.GetText("cell_text");
|
||||
var txt = m_Assembler.GetText("cell_text", cellNS);
|
||||
txt.Rect.anchoredPosition = new Vector2(cellX + 4, cellY);
|
||||
txt.Rect.sizeDelta = new Vector2(cellW - 8, cellH);
|
||||
txt.Text.text = data.Text;
|
||||
txt.Text.color = fgColor;
|
||||
txt.Text.fontSize = fontSize;
|
||||
txt.Text.alignment = TextAlignmentOptions.Midline;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
// 编辑器模式:直接 pull 样式值(cellNS 可能是个性化命名空间)
|
||||
if (!Application.isPlaying)
|
||||
{
|
||||
txt.Text.color = GetStyleColor(cellNS, "/cell/fg/color", fgFallback);
|
||||
txt.Text.fontSize = GetStyleInt(cellNS, "/cell/font/size", 14);
|
||||
txt.Text.alignment = TextAlignmentOptions.Midline;
|
||||
}
|
||||
#endif
|
||||
// 运行时:颜色/字号/对齐由 StyleBoundElement 管理(push),
|
||||
// GetText(_, cellNS) 已通过 BindStyle 注册了对应命名空间的 StyleField
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -867,6 +881,11 @@ namespace XericUI.XTable.Rendering.Component
|
||||
|
||||
private void EnsureDefaultStyleNamespace()
|
||||
{
|
||||
// 避免在样式表尚未加载时触发 HasStyle → GetValue 的命名空间不存在错误
|
||||
var namespaces = StyleManager.GetAvailableNamespaces();
|
||||
if (namespaces == null || !namespaces.Contains(m_DefaultStyleNamespace))
|
||||
return;
|
||||
|
||||
if (!StyleManager.HasStyle(m_DefaultStyleNamespace, "/cell/bg/color"))
|
||||
{
|
||||
StyleManager.AddDynamicStyle(m_DefaultStyleNamespace, "/cell/bg/color",
|
||||
@@ -884,6 +903,9 @@ namespace XericUI.XTable.Rendering.Component
|
||||
|
||||
private void MarkDirty(TableDirtyType type) => m_DirtyFlag.Mark(type);
|
||||
|
||||
/// <summary>运行时样式变更回调:标记脏数据,下一帧重绘</summary>
|
||||
private void OnPoolStyleChanged() => MarkDirty(TableDirtyType.StyleChanged);
|
||||
|
||||
private void OnScrollValueChanged(Vector2 _) => MarkDirty(TableDirtyType.ViewChanged);
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -42,6 +42,12 @@ namespace XericUI.XTable.Rendering.Elements
|
||||
/// <summary>池根节点(所有回收对象均挂在此节点下,节点本身处于 inactive)</summary>
|
||||
public Transform PoolRoot => m_PoolRoot;
|
||||
|
||||
/// <summary>运行时的默认样式命名空间(编辑器下为 null,不绑定)</summary>
|
||||
private string m_DefaultStyleNamespace;
|
||||
|
||||
/// <summary>所有已绑定的 StyleBoundElement 回调集合(用于样式变更时通知外部)</summary>
|
||||
public event System.Action OnStyleChangeDetected;
|
||||
|
||||
private Stack<PooledImage> m_ImagePool = new Stack<PooledImage>();
|
||||
private Stack<PooledText> m_TextPool = new Stack<PooledText>();
|
||||
private List<PooledImage> m_ActiveImages = new List<PooledImage>();
|
||||
@@ -54,9 +60,10 @@ namespace XericUI.XTable.Rendering.Elements
|
||||
|
||||
#region 构造函数与析构
|
||||
|
||||
public CellAssembler(Transform parent)
|
||||
public CellAssembler(Transform parent, string defaultStyleNamespace = null)
|
||||
{
|
||||
m_Parent = parent;
|
||||
m_DefaultStyleNamespace = defaultStyleNamespace;
|
||||
|
||||
GameObject poolRoot = new GameObject("_CellPool");
|
||||
poolRoot.hideFlags = POOL_FLAGS;
|
||||
@@ -120,7 +127,7 @@ namespace XericUI.XTable.Rendering.Elements
|
||||
|
||||
#region 池操作
|
||||
|
||||
public PooledImage GetImage(string name = "cell_img")
|
||||
public PooledImage GetImage(string name = "cell_img", string styleNamespace = null)
|
||||
{
|
||||
PooledImage item;
|
||||
if (m_ImagePool.Count > 0)
|
||||
@@ -134,11 +141,12 @@ namespace XericUI.XTable.Rendering.Elements
|
||||
{
|
||||
item = CreateImage(name);
|
||||
}
|
||||
BindStyle(item.Style, styleNamespace);
|
||||
m_ActiveImages.Add(item);
|
||||
return item;
|
||||
}
|
||||
|
||||
public PooledText GetText(string name = "cell_text")
|
||||
public PooledText GetText(string name = "cell_text", string styleNamespace = null)
|
||||
{
|
||||
PooledText item;
|
||||
if (m_TextPool.Count > 0)
|
||||
@@ -152,10 +160,32 @@ namespace XericUI.XTable.Rendering.Elements
|
||||
{
|
||||
item = CreateText(name);
|
||||
}
|
||||
BindStyle(item.Style, styleNamespace);
|
||||
m_ActiveTexts.Add(item);
|
||||
return item;
|
||||
}
|
||||
|
||||
/// <summary>运行时绑定样式到池元素的 StyleBoundElement,实现被动更新(push)</summary>
|
||||
private void BindStyle(StyleBoundElement style, string cellNamespace)
|
||||
{
|
||||
if (!Application.isPlaying) return;
|
||||
|
||||
string ns = cellNamespace ?? m_DefaultStyleNamespace;
|
||||
if (string.IsNullOrEmpty(ns)) return;
|
||||
|
||||
if (style != null && style.BoundNamespace != ns)
|
||||
{
|
||||
style.OnStyleChangedCallback -= OnStyleChangedNotify;
|
||||
style.OnStyleChangedCallback += OnStyleChangedNotify;
|
||||
style.Bind(ns);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnStyleChangedNotify()
|
||||
{
|
||||
OnStyleChangeDetected?.Invoke();
|
||||
}
|
||||
|
||||
public void ReturnAll()
|
||||
{
|
||||
foreach (var img in m_ActiveImages) ReturnImage(img);
|
||||
|
||||
@@ -32,12 +32,19 @@ namespace XericUI.XTable.Rendering.Elements
|
||||
/// <summary>是否已绑定</summary>
|
||||
private bool m_IsBound;
|
||||
|
||||
/// <summary>样式变更时触发(通知表格重绘)</summary>
|
||||
public event System.Action OnStyleChangedCallback;
|
||||
|
||||
/// <summary>当前绑定的命名空间(空字符串表示未绑定)</summary>
|
||||
public string BoundNamespace => m_IsBound ? (m_StyleNamespace ?? "") : "";
|
||||
|
||||
#endregion
|
||||
|
||||
#region 公开方法
|
||||
|
||||
/// <summary>
|
||||
/// 绑定到指定命名空间并开始监听样式。
|
||||
/// 运行时注册 StyleField 实现被动更新(push);编辑器下在渲染时直接 pull。
|
||||
/// </summary>
|
||||
public void Bind(string styleNamespace)
|
||||
{
|
||||
@@ -46,6 +53,11 @@ namespace XericUI.XTable.Rendering.Elements
|
||||
|
||||
if (string.IsNullOrEmpty(styleNamespace)) return;
|
||||
|
||||
// 检查命名空间是否存在,避免 Register → GetValue 报错
|
||||
var namespaces = StyleManager.GetAvailableNamespaces();
|
||||
if (namespaces == null || !namespaces.Contains(styleNamespace))
|
||||
return;
|
||||
|
||||
// 预注册常用路径
|
||||
RegisterField("/cell/bg/color", OnStyleChanged);
|
||||
RegisterField("/cell/fg/color", OnStyleChanged);
|
||||
@@ -72,7 +84,7 @@ namespace XericUI.XTable.Rendering.Elements
|
||||
{
|
||||
if (kvp.Value != null)
|
||||
{
|
||||
kvp.Value.OnValueChanged -= OnStyleChanged;
|
||||
kvp.Value.Member.OnValueChanged -= OnStyleChanged;
|
||||
kvp.Value.Unregister();
|
||||
}
|
||||
}
|
||||
@@ -125,7 +137,7 @@ namespace XericUI.XTable.Rendering.Elements
|
||||
StylePath = path
|
||||
};
|
||||
field.Register();
|
||||
field.OnValueChanged += callback;
|
||||
field.Member.OnValueChanged += callback;
|
||||
m_Fields[path] = field;
|
||||
}
|
||||
|
||||
@@ -137,6 +149,7 @@ namespace XericUI.XTable.Rendering.Elements
|
||||
private void OnStyleChanged(StyleValue val)
|
||||
{
|
||||
RefreshAll();
|
||||
OnStyleChangedCallback?.Invoke();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -6,33 +6,33 @@
|
||||
namespace: xeric_table_default
|
||||
|
||||
// ---- 单元格背景 ----
|
||||
/cell/bg/color = (1,1,1,1):UnityEngine.Color @Desc:单元格背景颜色
|
||||
cell/bg/color = (1,1,1,1):UnityEngine.Color @Desc:单元格背景颜色
|
||||
|
||||
// ---- 单元格前景 ----
|
||||
/cell/fg/color = (0.1,0.1,0.1,1):UnityEngine.Color @Desc:单元格前景文字颜色
|
||||
cell/fg/color = (0.1,0.1,0.1,1):UnityEngine.Color @Desc:单元格前景文字颜色
|
||||
|
||||
// ---- 边框 ----
|
||||
/cell/border/top/color = (0.8,0.8,0.8,1):UnityEngine.Color @Desc:上边框颜色
|
||||
/cell/border/top/width = 1:System.Single @Desc:上边框宽度
|
||||
/cell/border/bottom/color = (0.8,0.8,0.8,1):UnityEngine.Color @Desc:下边框颜色
|
||||
/cell/border/bottom/width = 1:System.Single @Desc:下边框宽度
|
||||
/cell/border/left/color = (0.8,0.8,0.8,1):UnityEngine.Color @Desc:左边框颜色
|
||||
/cell/border/left/width = 1:System.Single @Desc:左边框宽度
|
||||
/cell/border/right/color = (0.8,0.8,0.8,1):UnityEngine.Color @Desc:右边框颜色
|
||||
/cell/border/right/width = 1:System.Single @Desc:右边框宽度
|
||||
cell/border/top/color = (0.8,0.8,0.8,1):UnityEngine.Color @Desc:上边框颜色
|
||||
cell/border/top/width = 1:System.Single @Desc:上边框宽度
|
||||
cell/border/bottom/color = (0.8,0.8,0.8,1):UnityEngine.Color @Desc:下边框颜色
|
||||
cell/border/bottom/width = 1:System.Single @Desc:下边框宽度
|
||||
cell/border/left/color = (0.8,0.8,0.8,1):UnityEngine.Color @Desc:左边框颜色
|
||||
cell/border/left/width = 1:System.Single @Desc:左边框宽度
|
||||
cell/border/right/color = (0.8,0.8,0.8,1):UnityEngine.Color @Desc:右边框颜色
|
||||
cell/border/right/width = 1:System.Single @Desc:右边框宽度
|
||||
|
||||
// ---- 选中高亮 ----
|
||||
/cell/selection/bg/color = (0.2,0.5,1,0.3):UnityEngine.Color @Desc:选中单元格高亮颜色
|
||||
cell/selection/bg/color = (0.2,0.5,1,0.3):UnityEngine.Color @Desc:选中单元格高亮颜色
|
||||
|
||||
// ---- 表头样式 ----
|
||||
/header/bg/color = (0.9,0.9,0.9,1):UnityEngine.Color @Desc:表头背景颜色
|
||||
/header/fg/color = (0,0,0,1):UnityEngine.Color @Desc:表头文字颜色
|
||||
header/bg/color = (0.9,0.9,0.9,1):UnityEngine.Color @Desc:表头背景颜色
|
||||
header/fg/color = (0,0,0,1):UnityEngine.Color @Desc:表头文字颜色
|
||||
|
||||
// ---- 字体 ----
|
||||
/cell/font/size = 14:System.Int32 @Desc:默认字体大小
|
||||
/cell/font/alignment = MiddleCenter:UnityEngine.TextAnchor @Desc:默认文本对齐
|
||||
/cell/font/richText = true:System.Boolean @Desc:是否启用富文本
|
||||
cell/font/size = 14:System.Int32 @Desc:默认字体大小
|
||||
cell/font/alignment = MiddleCenter:UnityEngine.TextAnchor @Desc:默认文本对齐
|
||||
cell/font/richText = true:System.Boolean @Desc:是否启用富文本
|
||||
|
||||
// ---- 行高 / 列宽(缺省值) ----
|
||||
/cell/default/height = 40:System.Single @Desc:默认行高
|
||||
/cell/default/width = 100:System.Single @Desc:默认列宽
|
||||
cell/default/height = 40:System.Single @Desc:默认行高
|
||||
cell/default/width = 100:System.Single @Desc:默认列宽
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
{
|
||||
"name": "Lrss3.Xericuiactionvessel.Editor.Tests",
|
||||
"references": [
|
||||
"Lrss3.Xericuiactionvessel.Editor",
|
||||
"Lrss3.Xericuiactionvessel"
|
||||
],
|
||||
"optionalUnityReferences": [
|
||||
"TestAssemblies"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": []
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 34b5b6cb85c383b418e96c1cca9770be
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"name": "Lrss3.Xericuiactionvessel.Tests",
|
||||
"references": [
|
||||
"Lrss3.Xericuiactionvessel"
|
||||
],
|
||||
"optionalUnityReferences": [
|
||||
"TestAssemblies"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": []
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 42ede1ab41660134892c4b6033a4805b
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user