From 5917c0361bb8c3a83e16617d7afd250afa3294a8 Mon Sep 17 00:00:00 2001
From: LiRuoChen <571244399@qq.com>
Date: Wed, 29 Jul 2026 11:32:53 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=BE=B9=E6=A1=86=E6=B8=B2?=
=?UTF-8?q?=E6=9F=93=E4=B8=8E=E5=90=88=E5=B9=B6=E5=8D=95=E5=85=83=E6=A0=BC?=
=?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../XTable/XericUIActionTableSceneEditor.cs | 7 -
Runtime/XTable/Core/XTableData.cs | 51 +++++++
Runtime/XTable/Core/XTableSelectionHandle.cs | 11 ++
.../Component/XTableSelectionOverlay.cs | 23 ++-
.../Component/XericUIActionTable.Api.cs | 82 +++++------
.../Component/XericUIActionTable.Border.cs | 17 ++-
.../Component/XericUIActionTable.Selection.cs | 133 +++++++-----------
7 files changed, 185 insertions(+), 139 deletions(-)
diff --git a/Editor/XTable/XericUIActionTableSceneEditor.cs b/Editor/XTable/XericUIActionTableSceneEditor.cs
index 233d7cf..3ecaa26 100644
--- a/Editor/XTable/XericUIActionTableSceneEditor.cs
+++ b/Editor/XTable/XericUIActionTableSceneEditor.cs
@@ -545,13 +545,6 @@ namespace XericUIEditor.XTable
int minC = Mathf.Min(table.SelectStartCol, table.SelectEndCol);
int maxC = Mathf.Max(table.SelectStartCol, table.SelectEndCol);
- // 扩展多选区域以包含合并源的全部跨度
- if (table.IsMergeSource(minR, minC, out int msRS, out int msCS))
- {
- maxR = Mathf.Max(maxR, minR + msRS - 1);
- maxC = Mathf.Max(maxC, minC + msCS - 1);
- }
-
minR = Mathf.Clamp(minR, 0, rh.Length - 1);
maxR = Mathf.Clamp(maxR, 0, rh.Length - 1);
minC = Mathf.Clamp(minC, 0, cw.Length - 1);
diff --git a/Runtime/XTable/Core/XTableData.cs b/Runtime/XTable/Core/XTableData.cs
index 4db4294..ea8f5a6 100644
--- a/Runtime/XTable/Core/XTableData.cs
+++ b/Runtime/XTable/Core/XTableData.cs
@@ -400,6 +400,47 @@ namespace XericUI.XTable.Core
return block.GetMergeRedirect(localRow, localCol) != null;
}
+ /// 获取任意合并区域单元格所属的完整合并矩形。
+ public bool TryGetMergeRect(int row, int col, out int sourceRow, out int sourceCol,
+ out int rowSpan, out int colSpan)
+ {
+ sourceRow = row;
+ sourceCol = col;
+ rowSpan = 1;
+ colSpan = 1;
+ XTableCoordinateUtility.CellToBlockCoordinate(row, col, BlockSizeX, BlockSizeY,
+ out int blockRow, out int blockCol, out int localRow, out int localCol);
+ ulong blockIndex = XTableBlockMapping.BlockCoordToZIndex(blockRow, blockCol);
+ if (!BlockMap.TryGetValue(blockIndex, out XTableBlock block)) return false;
+
+ XTableMergeDescriptor descriptor = block.GetMergeRedirect(localRow, localCol);
+ if (descriptor == null)
+ {
+ foreach (var pair in BlockMap)
+ {
+ foreach (var candidate in pair.Value.MergeDescriptors)
+ {
+ ulong sourceBlock = candidate.IsCrossBlock ? candidate.SourceBlockIndex : pair.Key;
+ if (sourceBlock == blockIndex && candidate.SourceLocalRow == localRow && candidate.SourceLocalCol == localCol)
+ {
+ descriptor = candidate;
+ break;
+ }
+ }
+ if (descriptor != null) break;
+ }
+ }
+ if (descriptor == null) return false;
+
+ ulong sourceIndex = descriptor.IsCrossBlock ? descriptor.SourceBlockIndex : blockIndex;
+ XTableBlockMapping.ZIndexToBlockCoord(sourceIndex, out int sourceBlockRow, out int sourceBlockCol);
+ sourceRow = sourceBlockRow * BlockSizeY + descriptor.SourceLocalRow;
+ sourceCol = sourceBlockCol * BlockSizeX + descriptor.SourceLocalCol;
+ rowSpan = descriptor.MergeRowSpan;
+ colSpan = descriptor.MergeColSpan;
+ return true;
+ }
+
/// 判断指定单元格是否为合并源(锚点),并返回合并跨度
public bool IsMergeSource(int row, int col, out int rowSpan, out int colSpan)
{
@@ -446,6 +487,16 @@ namespace XericUI.XTable.Core
public IReadOnlyList BorderRanges => m_BorderRanges;
+ /// 对矩形四条外边写入显式样式范围;空样式恢复隐式默认值。
+ public void SetBorderRect(int rowStart, int rowEnd, int colStart, int colEnd, string ns)
+ {
+ if (rowStart >= rowEnd || colStart >= colEnd) return;
+ SetBorderRange(XTableBorderAxis.Horizontal, rowStart, colStart, colEnd - colStart, ns);
+ SetBorderRange(XTableBorderAxis.Horizontal, rowEnd, colStart, colEnd - colStart, ns);
+ SetBorderRange(XTableBorderAxis.Vertical, colStart, rowStart, rowEnd - rowStart, ns);
+ SetBorderRange(XTableBorderAxis.Vertical, colEnd, rowStart, rowEnd - rowStart, ns);
+ }
+
public string GetBorderRightNs(int row, int col) =>
row < 0 || col < 0 ? GetOuterBorderNs(row, col) : GetBorderNamespace(XTableBorderAxis.Vertical, col + 1, row);
public string GetBorderBottomNs(int row, int col) =>
diff --git a/Runtime/XTable/Core/XTableSelectionHandle.cs b/Runtime/XTable/Core/XTableSelectionHandle.cs
index 711cf19..ff435fe 100644
--- a/Runtime/XTable/Core/XTableSelectionHandle.cs
+++ b/Runtime/XTable/Core/XTableSelectionHandle.cs
@@ -80,6 +80,17 @@ namespace XericUI.XTable.Core
NotifyChanged();
}
+ /// 一次性设置选区端点;仅在值变化时通知。
+ public void SetEndpoints(int startRow, int startCol, int endRow, int endCol)
+ {
+ if (StartRow == startRow && StartCol == startCol && EndRow == endRow && EndCol == endCol) return;
+ StartRow = startRow;
+ StartCol = startCol;
+ EndRow = endRow;
+ EndCol = endCol;
+ NotifyChanged();
+ }
+
///
/// 扩展多选范围到目标格(保持原有锚点)
///
diff --git a/Runtime/XTable/Rendering/Component/XTableSelectionOverlay.cs b/Runtime/XTable/Rendering/Component/XTableSelectionOverlay.cs
index 96b335b..5891f4d 100644
--- a/Runtime/XTable/Rendering/Component/XTableSelectionOverlay.cs
+++ b/Runtime/XTable/Rendering/Component/XTableSelectionOverlay.cs
@@ -1,6 +1,7 @@
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
+using UnityEngine.Networking;
using XericLibrary.Runtime.MacroLibrary;
namespace XericUI.XTable.Rendering.Component
@@ -17,9 +18,23 @@ namespace XericUI.XTable.Rendering.Component
private int m_ColEnd;
private bool m_Dragging;
+ #region debug-point selection-overlay-config
+ private void DebugReport(string point, string details)
+ {
+ if (!Application.isPlaying) return;
+ string body = $"{{\"sessionId\":\"selection-playmode-input\",\"point\":\"{point}\",\"details\":\"{details}\"}}";
+ var request = new UnityWebRequest("http://127.0.0.1:7777/event", "POST");
+ request.uploadHandler = new UploadHandlerRaw(System.Text.Encoding.UTF8.GetBytes(body));
+ request.downloadHandler = new DownloadHandlerBuffer();
+ request.SetRequestHeader("Content-Type", "application/json");
+ request.SendWebRequest();
+ }
+ #endregion
+
public void Configure(XericUIActionTable table, int rowStart, int rowEnd, int colStart, int colEnd)
{
m_Table = table;
+ DebugReport("overlay-config", $"region={rowStart},{rowEnd},{colStart},{colEnd};active={gameObject.activeInHierarchy}");
m_RowStart = rowStart;
m_RowEnd = rowEnd;
m_ColStart = colStart;
@@ -63,9 +78,14 @@ namespace XericUI.XTable.Rendering.Component
m_Fill.gameObject.SetActive(true);
}
+ #region debug-point selection-overlay-input
public void OnPointerDown(PointerEventData eventData)
{
- if (m_Table == null || !m_Table.TryGetCellFromScreenPoint(transform.RectTransform(), eventData.position, eventData.pressEventCamera, true, out int row, out int col))
+ int row = -1;
+ int col = -1;
+ bool hit = m_Table != null && m_Table.TryGetCellFromScreenPoint(transform.RectTransform(), eventData.position, eventData.pressEventCamera, true, out row, out col);
+ DebugReport("pointer-down", $"hit={hit};position={eventData.position};rect={transform.RectTransform().rect}");
+ if (!hit)
return;
m_Dragging = true;
m_Table.BeginSelection(row, col);
@@ -86,6 +106,7 @@ namespace XericUI.XTable.Rendering.Component
}
public void OnEndDrag(PointerEventData eventData) => EndDrag();
+ #endregion
private void OnDisable() => EndDrag();
private void OnDestroy() => EndDrag();
diff --git a/Runtime/XTable/Rendering/Component/XericUIActionTable.Api.cs b/Runtime/XTable/Rendering/Component/XericUIActionTable.Api.cs
index 2d2e808..8d8b5ff 100644
--- a/Runtime/XTable/Rendering/Component/XericUIActionTable.Api.cs
+++ b/Runtime/XTable/Rendering/Component/XericUIActionTable.Api.cs
@@ -64,57 +64,46 @@ namespace XericUI.XTable.Rendering.Component
return data;
}
- /// 设置单元格的样式命名空间,同时写入边框缓存(谁最后设置归谁)
+ /// 设置单元格或合并矩形的样式,并覆写其四条外边范围。
public XTableCellData SetCellStyle(int row, int col, string styleNamespace, string stylePath)
{
- var data = TableData.GetOrCreateCell(row, col);
- if (data.CellStyle == null)
- data.CellStyle = new XericLibrary.Runtime.SuperStyleSheet.StyleMember();
- data.CellStyle.CurrentNamespace = styleNamespace ?? "";
- data.CellStyle.StylePath = stylePath ?? "";
+ ResolveStyleRect(row, col, out int rowStart, out int rowEnd, out int colStart, out int colEnd);
+ XTableCellData result = null;
+ for (int r = rowStart; r < rowEnd; r++)
+ for (int c = colStart; c < colEnd; c++)
+ {
+ var data = TableData.GetOrCreateCell(r, c);
+ data.CellStyle ??= new XericLibrary.Runtime.SuperStyleSheet.StyleMember();
+ data.CellStyle.CurrentNamespace = styleNamespace ?? "";
+ data.CellStyle.StylePath = stylePath ?? "";
+ data.StyleNamespace = styleNamespace ?? "";
+ result ??= data;
+ }
+ TableData.SetBorderRect(rowStart, rowEnd, colStart, colEnd, styleNamespace);
MarkDirty(TableDirtyType.StyleChanged);
- return data;
+ return result;
}
/// 设置单元格的样式命名空间(兼容旧版,等同于 StyleNamespace 字段)
public void SetCellStyleNamespace(int row, int col, string styleNamespace)
{
- if (TableData.IsMergeSource(row, col, out int rowSpan, out int colSpan))
- {
- for (int r = row; r < row + rowSpan && r < m_RowHeights.Length; r++)
- for (int c = col; c < col + colSpan && c < m_ColWidths.Length; c++)
- TableData.GetOrCreateCell(r, c).StyleNamespace = styleNamespace ?? string.Empty;
-
- ApplyCellStyleBorders(row, col, rowSpan, colSpan, styleNamespace);
- }
- else
- {
- ApplyCellStyleToCell(row, col, styleNamespace);
- }
-
+ ResolveStyleRect(row, col, out int rowStart, out int rowEnd, out int colStart, out int colEnd);
+ for (int r = rowStart; r < rowEnd; r++)
+ for (int c = colStart; c < colEnd; c++)
+ TableData.GetOrCreateCell(r, c).StyleNamespace = styleNamespace ?? string.Empty;
+ TableData.SetBorderRect(rowStart, rowEnd, colStart, colEnd, styleNamespace);
MarkDirty(TableDirtyType.StyleChanged);
}
- /// 设置单元格样式并写入其可见右侧、底部边框范围。
- private void ApplyCellStyleToCell(int row, int col, string ns)
+ private void ResolveStyleRect(int row, int col, out int rowStart, out int rowEnd, out int colStart, out int colEnd)
{
- var data = TableData.GetOrCreateCell(row, col);
- data.StyleNamespace = ns ?? string.Empty;
-
- int rowSpan = 1;
- int colSpan = 1;
- if (TableData.IsMergeSource(row, col, out int mergedRows, out int mergedCols))
+ rowStart = row; colStart = col; rowEnd = row + 1; colEnd = col + 1;
+ if (TableData.TryGetMergeRect(row, col, out int sourceRow, out int sourceCol, out int rowSpan, out int colSpan))
{
- rowSpan = mergedRows;
- colSpan = mergedCols;
+ rowStart = sourceRow; colStart = sourceCol;
+ rowEnd = Mathf.Min(sourceRow + rowSpan, m_RowHeights.Length);
+ colEnd = Mathf.Min(sourceCol + colSpan, m_ColWidths.Length);
}
- ApplyCellStyleBorders(row, col, rowSpan, colSpan, ns);
- }
-
- private void ApplyCellStyleBorders(int row, int col, int rowSpan, int colSpan, string ns)
- {
- TableData.SetBorderRange(XTableBorderAxis.Vertical, col + colSpan, row, rowSpan, ns);
- TableData.SetBorderRange(XTableBorderAxis.Horizontal, row + rowSpan, col, colSpan, ns);
}
/// 清除文本内容
@@ -151,9 +140,16 @@ namespace XericUI.XTable.Rendering.Component
/// 清除单元格样式覆盖
public void ClearCellStyle(int row, int col)
{
- var data = TableData.GetCell(row, col);
- if (data == null) return;
- data.CellStyle = null;
+ ResolveStyleRect(row, col, out int rowStart, out int rowEnd, out int colStart, out int colEnd);
+ for (int r = rowStart; r < rowEnd; r++)
+ for (int c = colStart; c < colEnd; c++)
+ {
+ var data = TableData.GetCell(r, c);
+ if (data == null) continue;
+ data.CellStyle = null;
+ data.StyleNamespace = string.Empty;
+ }
+ TableData.SetBorderRect(rowStart, rowEnd, colStart, colEnd, null);
MarkDirty(TableDirtyType.StyleChanged);
}
@@ -360,15 +356,13 @@ namespace XericUI.XTable.Rendering.Component
/// 单选一个单元格
public void SelectCell(int row, int col)
{
- SelectionHandle.Select(row, col);
- MarkDirty(TableDirtyType.SelectionChanged);
+ NormalizeAndSelect(row, col, row, col);
}
/// 多选一个范围
public void SelectCell(int startRow, int startCol, int endRow, int endCol)
{
- SelectionHandle.Select(startRow, startCol, endRow, endCol);
- MarkDirty(TableDirtyType.SelectionChanged);
+ NormalizeAndSelect(startRow, startCol, endRow, endCol);
}
/// 清除选择
diff --git a/Runtime/XTable/Rendering/Component/XericUIActionTable.Border.cs b/Runtime/XTable/Rendering/Component/XericUIActionTable.Border.cs
index fdbca16..83bd588 100644
--- a/Runtime/XTable/Rendering/Component/XericUIActionTable.Border.cs
+++ b/Runtime/XTable/Rendering/Component/XericUIActionTable.Border.cs
@@ -198,15 +198,22 @@ namespace XericUI.XTable.Rendering.Component
private bool IsMergedInteriorBoundary(XTableBorderAxis axis, int fixedIndex, int index)
{
if (m_TableData == null) return false;
+ int rowA, colA, rowB, colB;
if (axis == XTableBorderAxis.Horizontal)
{
if (fixedIndex <= 0 || fixedIndex >= m_RowHeights.Length) return false;
- return m_TableData.IsCellMerged(fixedIndex - 1, index)
- || m_TableData.IsCellMerged(fixedIndex, index);
+ rowA = fixedIndex - 1; colA = index;
+ rowB = fixedIndex; colB = index;
}
- if (fixedIndex <= 0 || fixedIndex >= m_ColWidths.Length) return false;
- return m_TableData.IsCellMerged(index, fixedIndex - 1)
- || m_TableData.IsCellMerged(index, fixedIndex);
+ else
+ {
+ if (fixedIndex <= 0 || fixedIndex >= m_ColWidths.Length) return false;
+ rowA = index; colA = fixedIndex - 1;
+ rowB = index; colB = fixedIndex;
+ }
+ return m_TableData.TryGetMergeRect(rowA, colA, out int sourceRowA, out int sourceColA, out _, out _)
+ && m_TableData.TryGetMergeRect(rowB, colB, out int sourceRowB, out int sourceColB, out _, out _)
+ && sourceRowA == sourceRowB && sourceColA == sourceColB;
}
}
}
diff --git a/Runtime/XTable/Rendering/Component/XericUIActionTable.Selection.cs b/Runtime/XTable/Rendering/Component/XericUIActionTable.Selection.cs
index 6f64a72..afdcb29 100644
--- a/Runtime/XTable/Rendering/Component/XericUIActionTable.Selection.cs
+++ b/Runtime/XTable/Rendering/Component/XericUIActionTable.Selection.cs
@@ -11,7 +11,7 @@ namespace XericUI.XTable.Rendering.Component
internal void BeginSelection(int row, int col)
{
m_SelectionDragActive = true;
- SelectionHandle.Select(row, col);
+ SetNormalizedSelection(row, col, row, col);
OnCellSelected?.Invoke(row, col);
}
@@ -21,111 +21,80 @@ namespace XericUI.XTable.Rendering.Component
m_LastSelectionPointer = screenPoint;
m_SelectionPointerCamera = eventCamera;
if (TryGetCellFromScreenPoint(source, screenPoint, eventCamera, true, out int row, out int col))
- SelectionHandle.ExtendTo(row, col);
+ SetNormalizedSelection(SelectionHandle.StartRow, SelectionHandle.StartCol, row, col);
}
- internal void EndSelection()
+ internal void NormalizeAndSelect(int startRow, int startCol, int endRow, int endCol) =>
+ SetNormalizedSelection(startRow, startCol, endRow, endCol);
+
+ private void SetNormalizedSelection(int startRow, int startCol, int endRow, int endCol)
{
- m_SelectionDragActive = false;
- m_SelectionPointerCamera = null;
+ int minRow = Mathf.Min(startRow, endRow), maxRow = Mathf.Max(startRow, endRow);
+ int minCol = Mathf.Min(startCol, endCol), maxCol = Mathf.Max(startCol, endCol);
+ bool changed;
+ do
+ {
+ changed = false;
+ for (int r = minRow; r <= maxRow; r++)
+ for (int c = minCol; c <= maxCol; c++)
+ if (m_TableData != null && m_TableData.TryGetMergeRect(r, c, out int sr, out int sc, out int rs, out int cs))
+ {
+ int er = sr + rs - 1, ec = sc + cs - 1;
+ int nr = Mathf.Min(minRow, sr), nxr = Mathf.Max(maxRow, er);
+ int nc = Mathf.Min(minCol, sc), nxc = Mathf.Max(maxCol, ec);
+ changed |= nr != minRow || nxr != maxRow || nc != minCol || nxc != maxCol;
+ minRow = nr; maxRow = nxr; minCol = nc; maxCol = nxc;
+ }
+ } while (changed);
+ int normalizedEndRow = endRow >= startRow ? maxRow : minRow;
+ int normalizedEndCol = endCol >= startCol ? maxCol : minCol;
+ SelectionHandle.SetEndpoints(startRow, startCol, normalizedEndRow, normalizedEndCol);
}
- internal bool TryGetCellFromScreenPoint(RectTransform source, Vector2 screenPoint, Camera eventCamera,
- bool clamp, out int row, out int col)
+ internal void EndSelection() { m_SelectionDragActive = false; m_SelectionPointerCamera = null; }
+
+ internal bool TryGetCellFromScreenPoint(RectTransform source, Vector2 screenPoint, Camera eventCamera, bool clamp, out int row, out int col)
{
- row = -1;
- col = -1;
- if (source == null || ContentTransform is not RectTransform contentRt) return false;
- if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(source, screenPoint, eventCamera, out Vector2 sourceLocal))
- return false;
- Vector3 world = source.TransformPoint(sourceLocal);
- Vector3 contentLocal = contentRt.InverseTransformPoint(world);
- Vector2 point = new(
- contentLocal.x - contentRt.rect.xMin - m_ContentOffset,
- contentRt.rect.yMax - contentLocal.y - m_ContentOffset);
- return TryGetCellFromTablePoint(point, clamp, out row, out col);
+ row = col = -1;
+ if (source == null || ContentTransform is not RectTransform contentRt || !RectTransformUtility.ScreenPointToLocalPointInRectangle(source, screenPoint, eventCamera, out Vector2 sourceLocal)) return false;
+ Vector3 contentLocal = contentRt.InverseTransformPoint(source.TransformPoint(sourceLocal));
+ return TryGetCellFromTablePoint(new Vector2(contentLocal.x - contentRt.rect.xMin - m_ContentOffset, contentRt.rect.yMax - contentLocal.y - m_ContentOffset), clamp, out row, out col);
}
internal bool TryGetCellFromTablePoint(Vector2 point, bool clamp, out int row, out int col)
{
- row = -1;
- col = -1;
- if (m_RowHeights == null || m_ColWidths == null || m_RowHeights.Length == 0 || m_ColWidths.Length == 0)
- return false;
- if (clamp)
- {
- point.x = Mathf.Clamp(point.x, 0f, Mathf.Max(0f, m_TotalWidth - .001f));
- point.y = Mathf.Clamp(point.y, 0f, Mathf.Max(0f, m_TotalHeight - .001f));
- }
- else if (point.x < 0f || point.x >= m_TotalWidth || point.y < 0f || point.y >= m_TotalHeight)
- return false;
-
- float cursor = 0f;
- for (col = 0; col < m_ColWidths.Length; col++)
- {
- cursor += m_ColWidths[col];
- if (point.x < cursor) break;
- }
- cursor = 0f;
- for (row = 0; row < m_RowHeights.Length; row++)
- {
- cursor += m_RowHeights[row];
- if (point.y < cursor) break;
- }
+ row = col = -1;
+ if (m_RowHeights == null || m_ColWidths == null || m_RowHeights.Length == 0 || m_ColWidths.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;
- NormalizeMergeSource(ref row, ref col);
+ if (m_TableData != null && m_TableData.TryGetMergeRect(row, col, out int sr, out int sc, out _, out _)) { row = sr; col = sc; }
return true;
}
- internal Rect GetTableRect(int rowStart, int rowEnd, int colStart, int colEnd)
- {
- return new Rect(GetColLeftX(colStart), GetRowTopY(rowStart),
- GetColLeftX(colEnd) - GetColLeftX(colStart), GetRowTopY(rowEnd) - GetRowTopY(rowStart));
- }
-
- private void NormalizeMergeSource(ref int row, ref int col)
- {
- if (m_TableData == null || !m_TableData.IsCellMerged(row, col)) return;
- for (int r = 0; r <= row; r++)
- for (int c = 0; c <= col; c++)
- if (m_TableData.IsMergeSource(r, c, out int rowSpan, out int colSpan)
- && row < r + rowSpan && col < c + colSpan)
- {
- row = r;
- col = c;
- return;
- }
- }
+ internal Rect GetTableRect(int rowStart, int rowEnd, int colStart, int colEnd) => new(GetColLeftX(colStart), GetRowTopY(rowStart), GetColLeftX(colEnd) - GetColLeftX(colStart), GetRowTopY(rowEnd) - GetRowTopY(rowStart));
private void UpdateSelectionAutoScroll()
{
- if (!m_SelectionDragActive || !m_EnableSelectionAutoScroll || m_ScrollRect?.viewport == null || m_ScrollRect.content == null)
- return;
+ if (!m_SelectionDragActive || !m_EnableSelectionAutoScroll || m_ScrollRect?.viewport == null || m_ScrollRect.content == null) return;
RectTransform viewport = m_ScrollRect.viewport;
- if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(viewport, m_LastSelectionPointer, m_SelectionPointerCamera, out Vector2 local))
- return;
+ if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(viewport, m_LastSelectionPointer, m_SelectionPointerCamera, out Vector2 local)) return;
Rect rect = viewport.rect;
if (!rect.Contains(local)) return;
- float x = local.x - rect.xMin;
- float y = rect.yMax - local.y;
+ float x = local.x - rect.xMin, y = rect.yMax - local.y;
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;
- float height = rect.height - freezeHeight;
- float px = x - freezeWidth;
- float py = y - freezeHeight;
+ float width = rect.width - freezeWidth, height = rect.height - freezeHeight;
float threshold = Mathf.Min(m_SelectionAutoScrollEdgeThreshold, Mathf.Min(width, height) * .5f);
- float sx = GetAutoScrollSpeed(px, width, threshold);
- float sy = GetAutoScrollSpeed(py, height, threshold);
- if (Mathf.Approximately(sx, 0f) && Mathf.Approximately(sy, 0f)) return;
-
- var content = m_ScrollRect.content;
- Vector2 position = content.anchoredPosition;
- position.x = Mathf.Clamp(position.x + sx * Time.unscaledDeltaTime, 0f, Mathf.Max(0f, m_TotalWidth - width));
- position.y = Mathf.Clamp(position.y + sy * Time.unscaledDeltaTime, 0f, Mathf.Max(0f, m_TotalHeight - height));
- content.anchoredPosition = position;
+ float sx = GetAutoScrollSpeed(x - freezeWidth, width, threshold), sy = GetAutoScrollSpeed(y - freezeHeight, height, threshold);
+ if (Mathf.Approximately(sx, 0) && Mathf.Approximately(sy, 0)) return;
+ Vector2 position = m_ScrollRect.content.anchoredPosition;
+ position.x = Mathf.Clamp(position.x + sx * Time.unscaledDeltaTime, 0, Mathf.Max(0, m_TotalWidth - width));
+ position.y = Mathf.Clamp(position.y + sy * Time.unscaledDeltaTime, 0, Mathf.Max(0, m_TotalHeight - height));
+ m_ScrollRect.content.anchoredPosition = position;
UpdateSelectionDrag(viewport, m_LastSelectionPointer, m_SelectionPointerCamera);
}