添加表格上的导入导出功能

This commit is contained in:
2026-06-29 22:38:26 +08:00
parent aca1c5a94e
commit cac9bb196d
5 changed files with 246 additions and 1 deletions
+29
View File
@@ -1,6 +1,8 @@
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;
using XericLibrary.Runtime.MacroLibrary;
using XericUI.XTable.Core;
using XericUI.XTable.Rendering.Component;
namespace XericUIEditor.XTable
@@ -92,6 +94,33 @@ namespace XericUIEditor.XTable
EditorGUILayout.Space(4);
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("导出到剪贴板", GUILayout.Height(26)))
{
var data = m_Table.BuildClipboardData();
MacroFile.SetClipboardObject(data, MacroFile.JsonSerializerFormatter.formatterWithZip);
Debug.Log($"[XTable] 表格数据已导出到剪贴板 ({data.Cells?.Count ?? 0} 个单元格, {data.Merges?.Count ?? 0} 个合并)");
}
if (GUILayout.Button("从剪贴板导入", GUILayout.Height(26)))
{
var data = MacroFile.GetClipboardObject<XTableClipboardData>(MacroFile.JsonSerializerFormatter.formatterWithZip);
if (data != null)
{
Undo.RecordObject(m_Table, "Import Table from Clipboard");
m_Table.ApplyClipboardData(data);
serializedObject.Update();
Repaint();
Debug.Log($"[XTable] 已从剪贴板导入表格数据 ({data.Cells?.Count ?? 0} 个单元格, {data.Merges?.Count ?? 0} 个合并)");
}
else
{
Debug.LogWarning("[XTable] 剪贴板中没有有效的表格数据");
}
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.Space(4);
bool newShow = EditorGUILayout.Toggle("显示子项", m_ShowChildren);
if (newShow != m_ShowChildren)
{
@@ -43,7 +43,7 @@ namespace XericUI.Core.StyleSheetUI
/// </summary>
public static void ForceRefreshAll()
{
#if XERIC_STYLESHEET_ENABLED
#if XericLibrary
XericLibrary.Runtime.SuperStyleSheet.StyleManager.ForceRefresh();
#endif
+177
View File
@@ -0,0 +1,177 @@
using System;
using System.Collections.Generic;
using XericUI.XTable.Mapping;
using XericUI.XTable.Rendering.Component;
namespace XericUI.XTable.Core
{
/// <summary>
/// 表格粘贴复制传输对象——将表格的尺寸、单元格文本、合并信息打包为可序列化结构,
/// 配合 MacroFile.SetClipboardObject / GetClipboardObject 实现表格内容的导入导出。
/// </summary>
[Serializable]
public class XTableClipboardData
{
[Serializable]
public struct CellEntry
{
public int Row;
public int Col;
public string Text;
public string StyleNamespace;
public CellEntry(int row, int col, string text, string styleNamespace = null)
{
Row = row;
Col = col;
Text = text;
StyleNamespace = styleNamespace;
}
}
[Serializable]
public struct MergeEntry
{
/// <summary>合并起始行(全局坐标)</summary>
public int StartRow;
/// <summary>合并起始列(全局坐标)</summary>
public int StartCol;
/// <summary>合并行数</summary>
public int RowSpan;
/// <summary>合并列数</summary>
public int ColSpan;
public MergeEntry(int startRow, int startCol, int rowSpan, int colSpan)
{
StartRow = startRow;
StartCol = startCol;
RowSpan = rowSpan;
ColSpan = colSpan;
}
}
/// <summary>行高数组</summary>
public float[] RowHeights;
/// <summary>列宽数组</summary>
public float[] ColWidths;
/// <summary>默认样式命名空间</summary>
public string DefaultStyleNamespace;
/// <summary>单元格数据列表(仅序列化有文本内容的单元格)</summary>
public List<CellEntry> Cells;
/// <summary>合并单元格描述列表</summary>
public List<MergeEntry> Merges;
public XTableClipboardData()
{
Cells = new List<CellEntry>();
Merges = new List<MergeEntry>();
}
/// <summary>
/// 从表格收集所有数据——尺寸、单元格文本、合并信息。
/// 调用方可将返回的 DTO 传给 MacroFile.SetClipboardObject 写入剪贴板。
/// </summary>
public static XTableClipboardData FromTable(XericUIActionTable table)
{
var data = new XTableClipboardData
{
RowHeights = table.RowHeights,
ColWidths = table.ColWidths,
DefaultStyleNamespace = table.DefaultStyleNamespace,
};
int rows = table.RowHeights?.Length ?? 0;
int cols = table.ColWidths?.Length ?? 0;
var tableData = table.TableData;
for (int r = 0; r < rows; r++)
{
for (int c = 0; c < cols; c++)
{
var cell = tableData.GetCell(r, c);
if (cell == null) continue;
bool hasContent = !string.IsNullOrEmpty(cell.Text)
|| !string.IsNullOrEmpty(cell.StyleNamespace);
if (!hasContent) continue;
data.Cells.Add(new CellEntry(r, c, cell.Text, cell.StyleNamespace));
}
}
// 收集合并信息(全局坐标)
if (tableData != null)
{
foreach (var kv in tableData.BlockMap)
{
var block = kv.Value;
if (block.MergeDescriptors == null || block.MergeDescriptors.Count == 0) continue;
XTableBlockMapping.ZIndexToBlockCoord(kv.Key, out int blockRow, out int blockCol);
foreach (var desc in block.MergeDescriptors)
{
if (desc.IsCrossBlock) continue;
int globalStartRow = blockRow * tableData.BlockSizeY + desc.LocalStartRow;
int globalStartCol = blockCol * tableData.BlockSizeX + desc.LocalStartCol;
data.Merges.Add(new MergeEntry(globalStartRow, globalStartCol,
desc.MergeRowSpan, desc.MergeColSpan));
}
}
}
return data;
}
/// <summary>
/// 将 DTO 中的单元格文本和合并信息写回表格数据层。
/// 尺寸与命名空间的设置由表格组件在 ApplyClipboardData 中处理。
/// </summary>
public void PopulateToTable(XericUIActionTable table)
{
var td = table.TableData;
if (td == null) return;
int rows = table.RowHeights?.Length ?? 0;
int cols = table.ColWidths?.Length ?? 0;
// 单元格文本
if (Cells != null)
{
foreach (var entry in Cells)
{
if (entry.Row < 0 || entry.Row >= rows || entry.Col < 0 || entry.Col >= cols)
continue;
var cell = td.GetOrCreateCell(entry.Row, entry.Col);
cell.Text = entry.Text;
cell.StyleNamespace = entry.StyleNamespace;
}
}
// 合并信息
if (Merges != null)
{
foreach (var merge in Merges)
{
if (merge.RowSpan > 1 || merge.ColSpan > 1)
{
int endRow = merge.StartRow + merge.RowSpan - 1;
int endCol = merge.StartCol + merge.ColSpan - 1;
if (endRow < rows && endCol < cols)
td.MergeCells(merge.StartRow, merge.StartCol, endRow, endCol);
}
}
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 31b3bc5cc85539b4db6ac19bbb4a1888
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -766,6 +766,34 @@ namespace XericUI.XTable.Rendering.Component
RefreshView();
}
/// <summary>构建剪贴板数据对象(尺寸 + 单元格文本 + 合并信息)</summary>
public XTableClipboardData BuildClipboardData()
{
return XTableClipboardData.FromTable(this);
}
/// <summary>将剪贴板数据应用到表格——覆盖尺寸、命名空间、单元格文本、合并信息并刷新</summary>
public void ApplyClipboardData(XTableClipboardData data)
{
if (data == null) return;
// 应用尺寸与默认命名空间
if (data.RowHeights != null && data.RowHeights.Length > 0)
m_RowHeights = data.RowHeights;
if (data.ColWidths != null && data.ColWidths.Length > 0)
m_ColWidths = data.ColWidths;
if (!string.IsNullOrEmpty(data.DefaultStyleNamespace))
m_DefaultStyleNamespace = data.DefaultStyleNamespace;
// 写回单元格文本与合并信息
data.PopulateToTable(this);
MarkDirty(TableDirtyType.DataChanged);
RecalculateTotalSize();
RefreshView();
SetChildrenVisible(m_ChildrenVisible);
}
#endregion
#region 单元格渲染