Files
XericUIActionVessel/Runtime/XTable/Rendering/XTableViewRect.cs

108 lines
3.0 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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;
}
}
}
}