108 lines
3.0 KiB
C#
108 lines
3.0 KiB
C#
using UnityEngine;
|
||
|
||
namespace XericUI.XTable.Rendering
|
||
{
|
||
/// <summary>
|
||
/// 左上角坐标系的视图矩形。
|
||
/// Unity 的 Rect 是左下角原点(Y-up),表格数据索引是左上角原点(Y-down)。
|
||
/// 此类负责坐标转换和可见单元格范围计算。
|
||
/// </summary>
|
||
public struct XTableViewRect
|
||
{
|
||
/// <summary>左上角 X 坐标</summary>
|
||
public float X;
|
||
|
||
/// <summary>左上角 Y 坐标(从上到下递增)</summary>
|
||
public float Y;
|
||
|
||
/// <summary>视图宽度</summary>
|
||
public float Width;
|
||
|
||
/// <summary>视图高度</summary>
|
||
public float Height;
|
||
|
||
/// <summary>右边界</summary>
|
||
public float XMax => X + Width;
|
||
|
||
/// <summary>下边界</summary>
|
||
public float YMax => Y + Height;
|
||
|
||
/// <summary>
|
||
/// 从 Unity Rect(左下角原点)转换为 TableViewRect(左上角原点)
|
||
/// </summary>
|
||
/// <param name="unityRect">Unity 坐标系下的矩形</param>
|
||
/// <param name="containerHeight">容器总高度(用于 Y 轴翻转)</param>
|
||
public static XTableViewRect FromUnityRect(Rect unityRect, float containerHeight)
|
||
{
|
||
return new XTableViewRect
|
||
{
|
||
X = unityRect.xMin,
|
||
Y = containerHeight - unityRect.yMax,
|
||
Width = unityRect.width,
|
||
Height = unityRect.height
|
||
};
|
||
}
|
||
|
||
/// <summary>
|
||
/// 转换为 Unity Rect(左下角原点)
|
||
/// </summary>
|
||
public Rect ToUnityRect(float containerHeight)
|
||
{
|
||
return new Rect(X, containerHeight - Y - Height, Width, Height);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 通过行列尺寸计算可见单元格范围。
|
||
/// 累加行高/列宽直到超出视图范围。
|
||
/// </summary>
|
||
/// <param name="rowHeights">每行高度数组</param>
|
||
/// <param name="colWidths">每列宽度数组</param>
|
||
/// <param name="startRow">可见起始行(包含)</param>
|
||
/// <param name="endRow">可见结束行(不包含)</param>
|
||
/// <param name="startCol">可见起始列(包含)</param>
|
||
/// <param name="endCol">可见结束列(不包含)</param>
|
||
public void GetVisibleCellRange(
|
||
float[] rowHeights, float[] colWidths,
|
||
out int startRow, out int endRow,
|
||
out int startCol, out int endCol)
|
||
{
|
||
startRow = 0;
|
||
endRow = 0;
|
||
startCol = 0;
|
||
endCol = 0;
|
||
|
||
if (rowHeights == null || colWidths == null) return;
|
||
|
||
// 计算行范围(Y 方向,从上到下)
|
||
float accumulatedY = 0f;
|
||
for (int r = 0; r < rowHeights.Length; r++)
|
||
{
|
||
float rowBottom = accumulatedY + rowHeights[r];
|
||
if (rowBottom > Y && accumulatedY < YMax)
|
||
{
|
||
if (startRow == 0 && accumulatedY < YMax)
|
||
startRow = r;
|
||
endRow = r + 1;
|
||
}
|
||
accumulatedY = rowBottom;
|
||
if (accumulatedY > YMax) break;
|
||
}
|
||
|
||
// 计算列范围(X 方向,从左到右)
|
||
float accumulatedX = 0f;
|
||
for (int c = 0; c < colWidths.Length; c++)
|
||
{
|
||
float colRight = accumulatedX + colWidths[c];
|
||
if (colRight > X && accumulatedX < XMax)
|
||
{
|
||
if (startCol == 0 && accumulatedX < XMax)
|
||
startCol = c;
|
||
endCol = c + 1;
|
||
}
|
||
accumulatedX = colRight;
|
||
if (accumulatedX > XMax) break;
|
||
}
|
||
}
|
||
}
|
||
}
|