173 lines
5.5 KiB
C#
173 lines
5.5 KiB
C#
#if UNITY_EDITOR
|
|
|
|
using UnityEditor;
|
|
|
|
using UnityEngine;
|
|
using XericLibrary.Runtime.MacroLibrary;
|
|
using XericUI.XTable.Rendering.Component;
|
|
|
|
namespace XericUIEditor.XTable
|
|
{
|
|
/// <summary>
|
|
/// 场景视图表格编辑覆盖工具——选中表格组件后,在世界编辑器视口中显示网格线和编辑辅助 UI。
|
|
/// 包含合并工具、拖拽引用工具、单元格坐标提示等。
|
|
/// </summary>
|
|
public static class XTableEditorOverlay
|
|
{
|
|
/// <summary>是否启用覆盖层(可通过菜单开关)</summary>
|
|
private static bool s_Enabled = true;
|
|
|
|
internal const string MENU_PATH = "XericLibrary/UI/Table/Table Editor Override Layer";
|
|
|
|
[MenuItem(MENU_PATH, false, 200)]
|
|
private static void ToggleOverlay()
|
|
{
|
|
s_Enabled = !s_Enabled;
|
|
Menu.SetChecked(MENU_PATH, s_Enabled);
|
|
SceneView.RepaintAll();
|
|
}
|
|
|
|
[MenuItem(MENU_PATH, true)]
|
|
private static bool ToggleOverlayValidate()
|
|
{
|
|
Menu.SetChecked(MENU_PATH, s_Enabled);
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 在 Scene View 中绘制表格编辑辅助线。
|
|
/// 调用时机:挂到 SceneView.duringSceneGui 事件上。
|
|
/// 示例:SceneView.duringSceneGui += OnSceneGUI;
|
|
/// </summary>
|
|
public static void OnSceneGUI(SceneView sceneView)
|
|
{
|
|
if (!s_Enabled) return;
|
|
|
|
// 获取当前选中的表格组件
|
|
GameObject selected = Selection.activeGameObject;
|
|
if (selected == null) return;
|
|
|
|
var table = selected.GetComponent<XericUIActionTable>();
|
|
if (table == null) return;
|
|
|
|
var rect = table.RectTransform();
|
|
if (rect == null) return;
|
|
|
|
DrawGridOverlay(table, rect);
|
|
DrawCellInfo(table, rect, sceneView);
|
|
}
|
|
|
|
/// <summary>绘制网格线</summary>
|
|
private static void DrawGridOverlay(XericUIActionTable table, RectTransform rect)
|
|
{
|
|
float[] rowHeights = table.ResolvedRowHeights;
|
|
float[] colWidths = table.ResolvedColWidths;
|
|
if (rowHeights == null || colWidths == null) return;
|
|
|
|
Vector3[] corners = new Vector3[4];
|
|
rect.GetWorldCorners(corners);
|
|
|
|
Vector3 topLeft = corners[1];
|
|
float totalWidth = rect.rect.width;
|
|
float totalHeight = rect.rect.height;
|
|
|
|
Handles.color = new Color(0.5f, 0.5f, 0.5f, 0.3f);
|
|
|
|
// 绘制行分割线
|
|
float accumulatedY = 0f;
|
|
for (int r = 0; r < rowHeights.Length && accumulatedY < totalHeight; r++)
|
|
{
|
|
float y = topLeft.y - accumulatedY - rowHeights[r];
|
|
Vector3 start = new Vector3(topLeft.x, y, topLeft.z);
|
|
Vector3 end = new Vector3(topLeft.x + Mathf.Min(totalWidth, 500f), y, topLeft.z);
|
|
Handles.DrawLine(start, end);
|
|
accumulatedY += rowHeights[r];
|
|
}
|
|
|
|
// 绘制列分割线
|
|
float accumulatedX = 0f;
|
|
for (int c = 0; c < colWidths.Length && accumulatedX < totalWidth; c++)
|
|
{
|
|
float x = topLeft.x + accumulatedX + colWidths[c];
|
|
Vector3 start = new Vector3(x, topLeft.y, topLeft.z);
|
|
Vector3 end = new Vector3(x, topLeft.y - Mathf.Min(totalHeight, 500f), topLeft.z);
|
|
Handles.DrawLine(start, end);
|
|
accumulatedX += colWidths[c];
|
|
}
|
|
}
|
|
|
|
/// <summary>绘制单元格坐标提示</summary>
|
|
private static void DrawCellInfo(XericUIActionTable table, RectTransform rect, SceneView sceneView)
|
|
{
|
|
int selRow = table.SelectedRow;
|
|
int selCol = table.SelectedCol;
|
|
if (selRow < 0 || selCol < 0) return;
|
|
|
|
float[] rowHeights = table.ResolvedRowHeights;
|
|
float[] colWidths = table.ResolvedColWidths;
|
|
if (rowHeights == null || colWidths == null) return;
|
|
|
|
// 计算选中单元格的世界位置
|
|
float cellX = 0f;
|
|
for (int c = 0; c < selCol && c < colWidths.Length; c++)
|
|
cellX += colWidths[c];
|
|
|
|
float cellY = 0f;
|
|
for (int r = 0; r < selRow && r < rowHeights.Length; r++)
|
|
cellY += rowHeights[r];
|
|
|
|
Vector3[] corners = new Vector3[4];
|
|
rect.GetWorldCorners(corners);
|
|
Vector3 topLeft = corners[1];
|
|
|
|
Vector3 cellCenter = new Vector3(
|
|
topLeft.x + cellX + (selCol < colWidths.Length ? colWidths[selCol] * 0.5f : 0),
|
|
topLeft.y - cellY - (selRow < rowHeights.Length ? rowHeights[selRow] * 0.5f : 0),
|
|
topLeft.z);
|
|
|
|
// 绘制选中高亮框
|
|
Handles.color = new Color(0.2f, 0.6f, 1f, 0.5f);
|
|
float cellW = selCol < colWidths.Length ? colWidths[selCol] : 50f;
|
|
float cellH = selRow < rowHeights.Length ? rowHeights[selRow] : 30f;
|
|
Vector3 cellTL = new Vector3(cellCenter.x - cellW * 0.5f, cellCenter.y + cellH * 0.5f, cellCenter.z);
|
|
Vector3 cellTR = new Vector3(cellCenter.x + cellW * 0.5f, cellCenter.y + cellH * 0.5f, cellCenter.z);
|
|
Vector3 cellBR = new Vector3(cellCenter.x + cellW * 0.5f, cellCenter.y - cellH * 0.5f, cellCenter.z);
|
|
Vector3 cellBL = new Vector3(cellCenter.x - cellW * 0.5f, cellCenter.y - cellH * 0.5f, cellCenter.z);
|
|
Handles.DrawSolidRectangleWithOutline(
|
|
new Vector3[] { cellTL, cellTR, cellBR, cellBL },
|
|
new Color(0.2f, 0.6f, 1f, 0.2f),
|
|
new Color(0.2f, 0.6f, 1f, 0.8f));
|
|
|
|
// 显示单元格坐标标签
|
|
Handles.Label(cellCenter + Vector3.up * 10f,
|
|
$"({selRow}, {selCol})",
|
|
new GUIStyle(EditorStyles.label)
|
|
{
|
|
normal = { textColor = Color.white },
|
|
fontStyle = FontStyle.Bold
|
|
});
|
|
|
|
// 工具栏按钮(在 Scene View 顶部绘制)
|
|
Handles.BeginGUI();
|
|
GUILayout.BeginArea(new Rect(10, 10, 200, 80));
|
|
GUILayout.BeginVertical("表格编辑工具", GUI.skin.window);
|
|
|
|
if (GUILayout.Button("合并选区"))
|
|
{
|
|
Debug.Log($"[XTable] 合并起始于 ({selRow}, {selCol})");
|
|
}
|
|
|
|
if (GUILayout.Button("取消合并"))
|
|
{
|
|
Debug.Log($"[XTable] 取消合并 ({selRow}, {selCol})");
|
|
}
|
|
|
|
GUILayout.EndVertical();
|
|
GUILayout.EndArea();
|
|
Handles.EndGUI();
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif
|