diff --git a/Editor/XTable/XTableEditorOverlay.cs b/Editor/XTable/XTableEditorOverlay.cs index f491d2d..99a378d 100644 --- a/Editor/XTable/XTableEditorOverlay.cs +++ b/Editor/XTable/XTableEditorOverlay.cs @@ -60,8 +60,8 @@ namespace XericUIEditor.XTable /// 绘制网格线 private static void DrawGridOverlay(XericUIActionTable table, RectTransform rect) { - float[] rowHeights = table.RowHeights; - float[] colWidths = table.ColWidths; + float[] rowHeights = table.ResolvedRowHeights; + float[] colWidths = table.ResolvedColWidths; if (rowHeights == null || colWidths == null) return; Vector3[] corners = new Vector3[4]; @@ -103,8 +103,8 @@ namespace XericUIEditor.XTable int selCol = table.SelectedCol; if (selRow < 0 || selCol < 0) return; - float[] rowHeights = table.RowHeights; - float[] colWidths = table.ColWidths; + float[] rowHeights = table.ResolvedRowHeights; + float[] colWidths = table.ResolvedColWidths; if (rowHeights == null || colWidths == null) return; // 计算选中单元格的世界位置 diff --git a/Editor/XTable/XericUIActionTableSceneEditor.cs b/Editor/XTable/XericUIActionTableSceneEditor.cs index 3ecaa26..0ca6448 100644 --- a/Editor/XTable/XericUIActionTableSceneEditor.cs +++ b/Editor/XTable/XericUIActionTableSceneEditor.cs @@ -42,7 +42,8 @@ namespace XericUIEditor.XTable private static int s_DragStartCol = -1; private static Rect s_TableRect; private static float s_XScale, s_YScale; - private static float[] s_RowHeights, s_ColWidths; + private static float[] s_RawRowHeights, s_RawColWidths; + private static float[] s_ResolvedRowHeights, s_ResolvedColWidths; private static XericUIActionTable s_ActiveTable; private static readonly Color s_LabelBg = new Color(0.12f, 0.12f, 0.18f, 0.9f); @@ -119,8 +120,8 @@ namespace XericUIEditor.XTable if (int.TryParse(newFocus.Substring("XTableColSizeEdit_".Length), out int idx)) { s_SizeEditTargetIndex = idx; - s_SizeEditText = s_ColWidths != null && idx < s_ColWidths.Length - ? s_ColWidths[idx].ToString("F0") + s_SizeEditText = s_RawColWidths != null && idx < s_RawColWidths.Length + ? s_RawColWidths[idx].ToString("G") : ""; } } @@ -129,8 +130,8 @@ namespace XericUIEditor.XTable if (int.TryParse(newFocus.Substring("XTableRowSizeEdit_".Length), out int idx)) { s_SizeEditTargetIndex = idx; - s_SizeEditText = s_RowHeights != null && idx < s_RowHeights.Length - ? s_RowHeights[idx].ToString("F0") + s_SizeEditText = s_RawRowHeights != null && idx < s_RawRowHeights.Length + ? s_RawRowHeights[idx].ToString("G") : ""; } } @@ -180,9 +181,12 @@ namespace XericUIEditor.XTable // 使用 Content 的 RectTransform 进行定位计算(而非表格组件所在的 ScrollRect 根节点) RectTransform tableRt = table.ContentTransform.RectTransform(); if (tableRt == null) tableRt = table.GetComponent(); - float[] rh = table.RowHeights; - float[] cw = table.ColWidths; - if (rh == null || cw == null || rh.Length == 0 || cw.Length == 0) return; + float[] rawRh = table.RowHeights; + float[] rawCw = table.ColWidths; + float[] rh = table.ResolvedRowHeights; + float[] cw = table.ResolvedColWidths; + if (rawRh == null || rawCw == null || rh == null || cw == null || + rawRh.Length == 0 || rawCw.Length == 0 || rh.Length == 0 || cw.Length == 0) return; Vector3[] corners = new Vector3[4]; tableRt.GetWorldCorners(corners); @@ -208,8 +212,10 @@ namespace XericUIEditor.XTable s_TableRect = tableRect; s_XScale = xScale; s_YScale = yScale; - s_RowHeights = rh; - s_ColWidths = cw; + s_RawRowHeights = rawRh; + s_RawColWidths = rawCw; + s_ResolvedRowHeights = rh; + s_ResolvedColWidths = cw; s_ActiveTable = table; Handles.BeginGUI(); @@ -241,7 +247,7 @@ namespace XericUIEditor.XTable DrawGridLines(rh, cw, tableRect, xScale, yScale); DrawSelectionHighlight(rh, cw, tableRect, xScale, yScale, table); DrawAddButtons(rh, cw, tableRect, xScale, yScale, table); - DrawSizeEditBubble(rh, cw, tableRect, xScale, yScale, table); + DrawSizeEditBubble(rawRh, rawCw, rh, cw, tableRect, xScale, yScale, table); DrawInputBar(table, tableRect.x, tableRect.y + tableRect.height + MARGIN); // 非导航状态不处理鼠标/键盘表格操作 @@ -671,7 +677,7 @@ namespace XericUIEditor.XTable }; } - private static void DrawSizeEditBubble(float[] rh, float[] cw, Rect tr, + private static void DrawSizeEditBubble(float[] rawRh, float[] rawCw, float[] rh, float[] cw, Rect tr, float xScale, float yScale, XericUIActionTable table) { int selRow = table.SelectedRow; @@ -686,7 +692,7 @@ namespace XericUIEditor.XTable float cx = tr.x + SumBefore(cw, selCol) * xScale; float bx = cx + 2f; float by = tr.y - ROW_H - MARGIN - BUBBLE_H - 4f; - DrawBubble(table, bx, by, cw[selCol], totalW, isColumn: true, index: selCol); + DrawBubble(table, bx, by, rawCw[selCol], totalW, isColumn: true, index: selCol); } // ── 行高气泡:左对齐行标签左侧 ── @@ -696,7 +702,7 @@ namespace XericUIEditor.XTable float rhScaled = rh[selRow] * yScale; float bx = tr.x - COL_W - MARGIN - totalW - 4f; float by = ry + (rhScaled - BUBBLE_H) / 2f; - DrawBubble(table, bx, by, rh[selRow], totalW, isColumn: false, index: selRow); + DrawBubble(table, bx, by, rawRh[selRow], totalW, isColumn: false, index: selRow); } // ── 单元格选中时同时显示 ── @@ -707,7 +713,7 @@ namespace XericUIEditor.XTable float cx = tr.x + SumBefore(cw, selCol) * xScale; float bx = cx + 2f; float by = tr.y - ROW_H - MARGIN - BUBBLE_H - 4f; - DrawBubble(table, bx, by, cw[selCol], totalW, isColumn: true, index: selCol); + DrawBubble(table, bx, by, rawCw[selCol], totalW, isColumn: true, index: selCol); } if (selRow < rh.Length) @@ -716,7 +722,7 @@ namespace XericUIEditor.XTable float rhScaled = rh[selRow] * yScale; float bx = tr.x - COL_W - MARGIN - totalW - 4f; float by = ry + (rhScaled - BUBBLE_H) / 2f; - DrawBubble(table, bx, by, rh[selRow], totalW, isColumn: false, index: selRow); + DrawBubble(table, bx, by, rawRh[selRow], totalW, isColumn: false, index: selRow); } } } @@ -1060,8 +1066,8 @@ namespace XericUIEditor.XTable { float rx = (Event.current.mousePosition.x - tr.x) / xScale; float ry = (Event.current.mousePosition.y - tr.y) / yScale; - col = IndexFromCoord(rx, s_ColWidths); - row = IndexFromCoord(ry, s_RowHeights); + col = IndexFromCoord(rx, s_ResolvedColWidths); + row = IndexFromCoord(ry, s_ResolvedRowHeights); // 点击合并覆盖的单元格时,重定向到合并源 if (row >= 0 && col >= 0 && s_ActiveTable != null) diff --git a/Runtime/XTable/Mapping/XTableCoordinateUtility.cs b/Runtime/XTable/Mapping/XTableCoordinateUtility.cs index c10e59e..770e397 100644 --- a/Runtime/XTable/Mapping/XTableCoordinateUtility.cs +++ b/Runtime/XTable/Mapping/XTableCoordinateUtility.cs @@ -75,5 +75,11 @@ namespace XericUI.XTable.Mapping int localCol = col % blockSizeX; return localRow * blockSizeX + localCol; } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float ResolveSize(float rawSize, float axisBaseSize) + { + return rawSize > 0f && rawSize <= 1f ? rawSize * axisBaseSize : rawSize; + } } } diff --git a/Runtime/XTable/Rendering/Component/XericUIActionTable.Api.cs b/Runtime/XTable/Rendering/Component/XericUIActionTable.Api.cs index 51c3092..28fee30 100644 --- a/Runtime/XTable/Rendering/Component/XericUIActionTable.Api.cs +++ b/Runtime/XTable/Rendering/Component/XericUIActionTable.Api.cs @@ -339,7 +339,7 @@ namespace XericUI.XTable.Rendering.Component => TableData.IsMergeSource(row, col, out rowSpan, out colSpan); /// - /// 在末尾追加一行,默认行高来自 Config。 + /// 在末尾追加一行,默认行高来自 Config。尺寸在 (0, 1] 时按 viewport、父级或自身高度比例解析,> 1 时为像素。 /// 行为:普通调用立即扩展行数组;CheckUpdate 内记录追加,结束时只重建一次。 /// 建议:循环追加或随后填充新行时使用 CheckUpdate。 /// @@ -367,7 +367,7 @@ namespace XericUI.XTable.Rendering.Component } /// - /// 在末尾追加一列,默认列宽来自 Config。 + /// 在末尾追加一列,默认列宽来自 Config。尺寸在 (0, 1] 时按 viewport、父级或自身宽度比例解析,> 1 时为像素。 /// 行为:普通调用立即扩展列数组;CheckUpdate 内记录追加,结束时只重建一次。 /// 建议:循环追加或随后填充新列时使用 CheckUpdate。 /// @@ -395,7 +395,7 @@ namespace XericUI.XTable.Rendering.Component } /// - /// 设置指定行的高度。 + /// 设置指定行的高度。尺寸在 (0, 1] 时按 viewport、父级或自身高度比例解析,> 1 时为像素。 /// 行为:普通调用立即更新布局;CheckUpdate 内延后,最终按命令顺序应用。 /// 建议:批量调整行高时使用 CheckUpdate。 /// @@ -420,7 +420,7 @@ namespace XericUI.XTable.Rendering.Component } /// - /// 设置指定列的宽度。 + /// 设置指定列的宽度。尺寸在 (0, 1] 时按 viewport、父级或自身宽度比例解析,> 1 时为像素。 /// 行为:普通调用立即更新布局;CheckUpdate 内延后,最终按命令顺序应用。 /// 建议:批量调整列宽时使用 CheckUpdate。 /// @@ -672,6 +672,7 @@ namespace XericUI.XTable.Rendering.Component m_Assembler = new CellAssembler(ContentTransform, m_DefaultStyleNamespace); m_PrefabPool = new PrefabPrototypePool(ContentTransform); m_ActivePrefabMap = new Dictionary<(int, int), GameObject>(); + UpdateResolvedCellSizes(); RecalculateTotalSize(); CreateDefaultSampleData(); CreateBackground(); @@ -732,6 +733,7 @@ namespace XericUI.XTable.Rendering.Component m_Assembler = new CellAssembler(ContentTransform, m_DefaultStyleNamespace); m_PrefabPool = new PrefabPrototypePool(ContentTransform); m_ActivePrefabMap = new Dictionary<(int, int), GameObject>(); + UpdateResolvedCellSizes(); RecalculateTotalSize(); // 恢复文本数据到新 TableData @@ -820,6 +822,7 @@ namespace XericUI.XTable.Rendering.Component m_PrefabPool = new PrefabPrototypePool(ContentTransform); m_ActivePrefabMap = new Dictionary<(int, int), GameObject>(); MarkDirty(TableDirtyType.All); + UpdateResolvedCellSizes(); RecalculateTotalSize(); CreateBackground(); CreateViewportRenderer(); @@ -881,6 +884,7 @@ namespace XericUI.XTable.Rendering.Component // 写回单元格文本与合并信息 data.PopulateToTable(this); + UpdateResolvedCellSizes(); RecalculateTotalSize(); RequestRefresh(TableDirtyType.DataChanged | TableDirtyType.LayoutChanged, true); SetChildrenVisible(m_ChildrenVisible); diff --git a/Runtime/XTable/Rendering/Component/XericUIActionTable.Data.cs b/Runtime/XTable/Rendering/Component/XericUIActionTable.Data.cs index 28b13af..f0e796a 100644 --- a/Runtime/XTable/Rendering/Component/XericUIActionTable.Data.cs +++ b/Runtime/XTable/Rendering/Component/XericUIActionTable.Data.cs @@ -18,9 +18,9 @@ namespace XericUI.XTable.Rendering.Component { // 计入 m_ContentOffset 以匹配单元格在 Content 中的实际渲染位置 float cellLeft = GetColLeftX(col) + m_ContentOffset; - float cellRight = cellLeft + m_ColWidths[col]; + float cellRight = cellLeft + m_ResolvedColWidths[col]; float cellTop = GetRowTopY(row) + m_ContentOffset; - float cellBottom = cellTop + m_RowHeights[row]; + float cellBottom = cellTop + m_ResolvedRowHeights[row]; return cellRight > m_VisibleRect.x && cellLeft < m_VisibleRect.xMax && cellBottom > m_VisibleRect.y && cellTop < m_VisibleRect.yMax; @@ -43,16 +43,16 @@ namespace XericUI.XTable.Rendering.Component private float GetRowTopY(int row) { float y = 0; - for (int i = 0; i < row && i < m_RowHeights.Length; i++) - y += m_RowHeights[i]; + for (int i = 0; i < row && i < m_ResolvedRowHeights.Length; i++) + y += m_ResolvedRowHeights[i]; return y; } private float GetColLeftX(int col) { float x = 0; - for (int i = 0; i < col && i < m_ColWidths.Length; i++) - x += m_ColWidths[i]; + for (int i = 0; i < col && i < m_ResolvedColWidths.Length; i++) + x += m_ResolvedColWidths[i]; return x; } @@ -83,13 +83,13 @@ namespace XericUI.XTable.Rendering.Component private void RecalculateTotalSize() { m_TotalWidth = 0; - if (m_ColWidths != null) - foreach (float w in m_ColWidths) + if (m_ResolvedColWidths != null) + foreach (float w in m_ResolvedColWidths) m_TotalWidth += w; m_TotalHeight = 0; - if (m_RowHeights != null) - foreach (float h in m_RowHeights) + if (m_ResolvedRowHeights != null) + foreach (float h in m_ResolvedRowHeights) m_TotalHeight += h; m_ContentOffset = GetCellBorderWidth(m_DefaultStyleNamespace) * 0.5f; @@ -125,9 +125,9 @@ namespace XericUI.XTable.Rendering.Component ec = 0; float accY = 0; - for (int r = 0; r < m_RowHeights.Length; r++) + for (int r = 0; r < m_ResolvedRowHeights.Length; r++) { - float rowBottom = accY + m_RowHeights[r]; + float rowBottom = accY + m_ResolvedRowHeights[r]; if (rowBottom > m_VisibleRect.y && accY < m_VisibleRect.yMax) { if (er == 0 && sr == 0) sr = r; @@ -139,9 +139,9 @@ namespace XericUI.XTable.Rendering.Component } float accX = 0; - for (int c = 0; c < m_ColWidths.Length; c++) + for (int c = 0; c < m_ResolvedColWidths.Length; c++) { - float colRight = accX + m_ColWidths[c]; + float colRight = accX + m_ResolvedColWidths[c]; if (colRight > m_VisibleRect.x && accX < m_VisibleRect.xMax) { if (ec == 0 && sc == 0) sc = c; @@ -233,7 +233,7 @@ namespace XericUI.XTable.Rendering.Component cells.Add(new XTableQuadtreeCell { Row = r, Col = c, Namespace = ResolveCellNamespace(data) }); } - m_Quadtree.Build(m_TotalWidth, m_TotalHeight, m_RowHeights, m_ColWidths, cells, Config.QuadtreeMaxCellsPerNode); + m_Quadtree.Build(m_TotalWidth, m_TotalHeight, m_ResolvedRowHeights, m_ResolvedColWidths, cells, Config.QuadtreeMaxCellsPerNode); m_QuadtreeDirty = false; } diff --git a/Runtime/XTable/Rendering/Component/XericUIActionTable.ExcelIO.cs b/Runtime/XTable/Rendering/Component/XericUIActionTable.ExcelIO.cs index b963c60..2758648 100644 --- a/Runtime/XTable/Rendering/Component/XericUIActionTable.ExcelIO.cs +++ b/Runtime/XTable/Rendering/Component/XericUIActionTable.ExcelIO.cs @@ -264,6 +264,7 @@ namespace XericUI.XTable.Rendering.Component } // 标记脏并刷新 + UpdateResolvedCellSizes(); RecalculateTotalSize(); RequestRefresh(TableDirtyType.DataChanged | TableDirtyType.LayoutChanged, true); } diff --git a/Runtime/XTable/Rendering/Component/XericUIActionTable.Freeze.cs b/Runtime/XTable/Rendering/Component/XericUIActionTable.Freeze.cs index 57e3aef..f17ebc8 100644 --- a/Runtime/XTable/Rendering/Component/XericUIActionTable.Freeze.cs +++ b/Runtime/XTable/Rendering/Component/XericUIActionTable.Freeze.cs @@ -61,8 +61,8 @@ namespace XericUI.XTable.Rendering.Component GetStyleColor = (ns, path, fallback) => GetStyleColor(ns, path, fallback), GetStyleInt = (ns, path, fallback) => GetStyleInt(ns, path, fallback), GetStyleFontAsset = (ns, path) => GetStyleFontAsset(ns, path), - GetRowHeights = () => m_RowHeights, - GetColWidths = () => m_ColWidths, + GetRowHeights = () => m_ResolvedRowHeights, + GetColWidths = () => m_ResolvedColWidths, GetTableData = () => m_TableData, GetDefaultStyleNamespace = () => m_DefaultStyleNamespace, }; diff --git a/Runtime/XTable/Rendering/Component/XericUIActionTable.RendererFilter.cs b/Runtime/XTable/Rendering/Component/XericUIActionTable.RendererFilter.cs index fc2aade..90082d8 100644 --- a/Runtime/XTable/Rendering/Component/XericUIActionTable.RendererFilter.cs +++ b/Runtime/XTable/Rendering/Component/XericUIActionTable.RendererFilter.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; +using XericLibrary.Runtime.MacroLibrary; using XericUI.XTable.Core; using XericUI.XTable.Rendering.Elements; #if UNITY_EDITOR @@ -134,16 +135,16 @@ namespace XericUI.XTable.Rendering.Component float cellX = GetCellContentX(col); float cellY = GetCellContentY(row); - float cellW = m_ColWidths[col]; - float cellH = m_RowHeights[row]; + float cellW = m_ResolvedColWidths[col]; + float cellH = m_ResolvedRowHeights[row]; // 合并源:扩展尺寸 if (TableData.IsMergeSource(row, col, out int mergeRS, out int mergeCS)) { - for (int i = 1; i < mergeCS && col + i < m_ColWidths.Length; i++) - cellW += m_ColWidths[col + i]; - for (int i = 1; i < mergeRS && row + i < m_RowHeights.Length; i++) - cellH += m_RowHeights[row + i]; + for (int i = 1; i < mergeCS && col + i < m_ResolvedColWidths.Length; i++) + cellW += m_ResolvedColWidths[col + i]; + for (int i = 1; i < mergeRS && row + i < m_ResolvedRowHeights.Length; i++) + cellH += m_ResolvedRowHeights[row + i]; } int cellId = row * m_ColWidths.Length + col; @@ -267,6 +268,7 @@ namespace XericUI.XTable.Rendering.Component if (m_RowHeights == null || m_ColWidths == null) return; if (m_RowHeights.Length == 0 || m_ColWidths.Length == 0) return; + UpdateResolvedCellSizes(); CreateBackground(); #if UNITY_EDITOR diff --git a/Runtime/XTable/Rendering/Component/XericUIActionTable.Selection.cs b/Runtime/XTable/Rendering/Component/XericUIActionTable.Selection.cs index 285733d..e48601d 100644 --- a/Runtime/XTable/Rendering/Component/XericUIActionTable.Selection.cs +++ b/Runtime/XTable/Rendering/Component/XericUIActionTable.Selection.cs @@ -70,12 +70,12 @@ namespace XericUI.XTable.Rendering.Component internal bool TryGetCellFromTablePoint(Vector2 point, bool clamp, out int row, out int col) { row = col = -1; - if (m_RowHeights == null || m_ColWidths == null || m_RowHeights.Length == 0 || m_ColWidths.Length == 0) return false; + if (m_ResolvedRowHeights == null || m_ResolvedColWidths == null || m_ResolvedRowHeights.Length == 0 || m_ResolvedColWidths.Length == 0) return false; if (clamp) { point.x = Mathf.Clamp(point.x, 0, Mathf.Max(0, m_TotalWidth - .001f)); point.y = Mathf.Clamp(point.y, 0, Mathf.Max(0, m_TotalHeight - .001f)); } else if (point.x < 0 || point.y < 0 || point.x >= m_TotalWidth || point.y >= m_TotalHeight) return false; - float cursor = 0; for (col = 0; col < m_ColWidths.Length && point.x >= (cursor += m_ColWidths[col]); col++) { } - cursor = 0; for (row = 0; row < m_RowHeights.Length && point.y >= (cursor += m_RowHeights[row]); row++) { } - if (row >= m_RowHeights.Length || col >= m_ColWidths.Length) return false; + float cursor = 0; for (col = 0; col < m_ResolvedColWidths.Length && point.x >= (cursor += m_ResolvedColWidths[col]); col++) { } + cursor = 0; for (row = 0; row < m_ResolvedRowHeights.Length && point.y >= (cursor += m_ResolvedRowHeights[row]); row++) { } + if (row >= m_ResolvedRowHeights.Length || col >= m_ResolvedColWidths.Length) return false; if (m_TableData != null && m_TableData.TryGetMergeRect(row, col, out int sr, out int sc, out _, out _)) { row = sr; col = sc; } return true; } @@ -93,7 +93,7 @@ namespace XericUI.XTable.Rendering.Component float freezeWidth = GetColLeftX(Mathf.Clamp(m_FreezeColCount, 0, m_ColWidths.Length)); float freezeHeight = GetRowTopY(Mathf.Clamp(m_FreezeRowCount, 0, m_RowHeights.Length)); if (x < freezeWidth || y < freezeHeight) return; - float width = rect.width - freezeWidth, height = rect.height - freezeHeight; + float width = Mathf.Max(0f, rect.width - freezeWidth), height = Mathf.Max(0f, rect.height - freezeHeight); float threshold = Mathf.Min(m_SelectionAutoScrollEdgeThreshold, Mathf.Min(width, height) * .5f); float sx = GetAutoScrollSpeed(x - freezeWidth, width, threshold), sy = GetAutoScrollSpeed(y - freezeHeight, height, threshold); if (Mathf.Approximately(sx, 0) && Mathf.Approximately(sy, 0)) return; @@ -106,6 +106,7 @@ namespace XericUI.XTable.Rendering.Component private float GetAutoScrollSpeed(float point, float length, float threshold) { + if (threshold <= 0f) return 0f; float direction = point < threshold ? -1f : point > length - threshold ? 1f : 0f; if (direction == 0f) return 0f; float distance = direction < 0f ? point : length - point; diff --git a/Runtime/XTable/Rendering/Component/XericUIActionTable.cs b/Runtime/XTable/Rendering/Component/XericUIActionTable.cs index 74c356a..2d6c375 100644 --- a/Runtime/XTable/Rendering/Component/XericUIActionTable.cs +++ b/Runtime/XTable/Rendering/Component/XericUIActionTable.cs @@ -108,6 +108,10 @@ namespace XericUI.XTable.Rendering.Component [System.NonSerialized] private UILineRendererV2 m_FrozenRowBorderRenderer; [System.NonSerialized] private UILineRendererV2 m_FrozenCornerBorderRenderer; + [NonSerialized] private float[] m_ResolvedRowHeights; + [NonSerialized] private float[] m_ResolvedColWidths; + [NonSerialized] private Vector2 m_LastLayoutBaseSize; + private float m_TotalWidth; private float m_TotalHeight; @@ -147,6 +151,8 @@ namespace XericUI.XTable.Rendering.Component public float[] RowHeights => m_RowHeights; public float[] ColWidths => m_ColWidths; + public float[] ResolvedRowHeights => m_ResolvedRowHeights; + public float[] ResolvedColWidths => m_ResolvedColWidths; /// 冻结行数 public int FreezeRowCount => m_FreezeRowCount; @@ -278,6 +284,7 @@ namespace XericUI.XTable.Rendering.Component m_Assembler = new CellAssembler(ContentTransform, m_DefaultStyleNamespace); m_PrefabPool = new PrefabPrototypePool(ContentTransform); m_ActivePrefabMap = new Dictionary<(int, int), GameObject>(); + UpdateResolvedCellSizes(); RecalculateTotalSize(); EnsureDefaultStyleNamespace(); CreateDefaultSampleData(); @@ -410,6 +417,51 @@ namespace XericUI.XTable.Rendering.Component [System.NonSerialized] private bool m_IsRefreshingFromScroll; + private void OnRectTransformDimensionsChange() + { + Vector2 layoutBaseSize = GetLayoutBaseSize(); + if (layoutBaseSize != m_LastLayoutBaseSize) + { + m_LastLayoutBaseSize = layoutBaseSize; + MarkDirty(TableDirtyType.LayoutChanged); + } + } + + private Vector2 GetLayoutBaseSize() + { + RectTransform baseTransform = m_ScrollRect != null && m_ScrollRect.viewport != null + ? m_ScrollRect.viewport + : transform.parent as RectTransform; + if (baseTransform == null) baseTransform = rectTransform; + + Vector2 size = baseTransform != null ? baseTransform.rect.size : Vector2.zero; + Vector2 selfSize = rectTransform != null ? rectTransform.rect.size : Vector2.zero; + return new Vector2(size.x > 0f ? size.x : (m_LastLayoutBaseSize.x > 0f ? m_LastLayoutBaseSize.x : selfSize.x), + size.y > 0f ? size.y : (m_LastLayoutBaseSize.y > 0f ? m_LastLayoutBaseSize.y : selfSize.y)); + } + + private void UpdateResolvedCellSizes() + { + Vector2 baseSize = GetLayoutBaseSize(); + m_LastLayoutBaseSize = baseSize; + if (m_RowHeights == null || m_ColWidths == null) + { + m_ResolvedRowHeights = null; + m_ResolvedColWidths = null; + return; + } + + if (m_ResolvedRowHeights == null || m_ResolvedRowHeights.Length != m_RowHeights.Length) + m_ResolvedRowHeights = new float[m_RowHeights.Length]; + if (m_ResolvedColWidths == null || m_ResolvedColWidths.Length != m_ColWidths.Length) + m_ResolvedColWidths = new float[m_ColWidths.Length]; + + for (int i = 0; i < m_RowHeights.Length; i++) + m_ResolvedRowHeights[i] = XTableCoordinateUtility.ResolveSize(m_RowHeights[i], baseSize.y); + for (int i = 0; i < m_ColWidths.Length; i++) + m_ResolvedColWidths[i] = XTableCoordinateUtility.ResolveSize(m_ColWidths[i], baseSize.x); + } + private void OnScrollValueChanged(Vector2 _) { if (IsCheckingUpdate) return;