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); }