修复运行时框选绘制覆盖层太多的问题,修复事件层太靠上导致预制体收不到事件的问题
This commit is contained in:
@@ -27,6 +27,7 @@ namespace XericUI.XTable.Rendering.Component
|
|||||||
public Dictionary<(int, int), GameObject> ActivePrefabMap;
|
public Dictionary<(int, int), GameObject> ActivePrefabMap;
|
||||||
public float CellPadding;
|
public float CellPadding;
|
||||||
public XTableConfig Config;
|
public XTableConfig Config;
|
||||||
|
public XericUIActionTable SelectionTable;
|
||||||
|
|
||||||
public int StartRow;
|
public int StartRow;
|
||||||
public int StartCol;
|
public int StartCol;
|
||||||
@@ -62,12 +63,13 @@ namespace XericUI.XTable.Rendering.Component
|
|||||||
{
|
{
|
||||||
if (m_BackgroundGo == null)
|
if (m_BackgroundGo == null)
|
||||||
{
|
{
|
||||||
m_BackgroundGo = new GameObject("_TableBackground", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image));
|
m_BackgroundGo = new GameObject("_TableBackground", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(XTableSelectionInput));
|
||||||
m_BackgroundGo.hideFlags = HideFlags.DontSave | HideFlags.HideInHierarchy;
|
m_BackgroundGo.hideFlags = HideFlags.DontSave | HideFlags.HideInHierarchy;
|
||||||
m_BackgroundGo.transform.SetParent(m_Parent, false);
|
m_BackgroundGo.transform.SetParent(m_Parent, false);
|
||||||
m_BackgroundGo.transform.SetAsFirstSibling();
|
m_BackgroundGo.transform.SetAsFirstSibling();
|
||||||
var image = m_BackgroundGo.GetComponent<Image>();
|
var image = m_BackgroundGo.GetComponent<Image>();
|
||||||
image.raycastTarget = false;
|
image.raycastTarget = true;
|
||||||
|
m_BackgroundGo.GetComponent<XTableSelectionInput>().Configure(SelectionTable);
|
||||||
image.color = GetStyleColor?.Invoke(styleNamespace, XericUIActionTable.STYLE_CELL_BG_COLOR,
|
image.color = GetStyleColor?.Invoke(styleNamespace, XericUIActionTable.STYLE_CELL_BG_COLOR,
|
||||||
XericUIActionTable.BG_COLOR_FALLBACK) ?? XericUIActionTable.BG_COLOR_FALLBACK;
|
XericUIActionTable.BG_COLOR_FALLBACK) ?? XericUIActionTable.BG_COLOR_FALLBACK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.EventSystems;
|
||||||
|
|
||||||
|
namespace XericUI.XTable.Rendering.Component
|
||||||
|
{
|
||||||
|
[RequireComponent(typeof(RectTransform))]
|
||||||
|
internal sealed class XTableSelectionInput : MonoBehaviour, IPointerDownHandler, IDragHandler, IPointerUpHandler, IEndDragHandler
|
||||||
|
{
|
||||||
|
private XericUIActionTable m_Table;
|
||||||
|
private bool m_Dragging;
|
||||||
|
|
||||||
|
internal void Configure(XericUIActionTable table) => m_Table = table;
|
||||||
|
|
||||||
|
public void OnPointerDown(PointerEventData eventData)
|
||||||
|
{
|
||||||
|
if (m_Table == null || !m_Table.TryGetCellFromScreenPoint((RectTransform)transform, eventData.position,
|
||||||
|
eventData.pressEventCamera, true, out int row, out int col)) return;
|
||||||
|
m_Dragging = true;
|
||||||
|
m_Table.BeginSelection(row, col);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnDrag(PointerEventData eventData)
|
||||||
|
{
|
||||||
|
if (!m_Dragging || m_Table == null) return;
|
||||||
|
m_Table.UpdateSelectionDrag((RectTransform)transform, eventData.position, eventData.pressEventCamera);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnPointerUp(PointerEventData eventData) => EndSelection();
|
||||||
|
public void OnEndDrag(PointerEventData eventData) => EndSelection();
|
||||||
|
private void OnDisable() => EndSelection();
|
||||||
|
|
||||||
|
private void EndSelection()
|
||||||
|
{
|
||||||
|
if (!m_Dragging) return;
|
||||||
|
m_Dragging = false;
|
||||||
|
m_Table?.EndSelection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7ec3998ca9451274896072bf17af699b
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -1,14 +1,12 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.EventSystems;
|
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
using XericLibrary.Runtime.MacroLibrary;
|
using XericLibrary.Runtime.MacroLibrary;
|
||||||
|
|
||||||
namespace XericUI.XTable.Rendering.Component
|
namespace XericUI.XTable.Rendering.Component
|
||||||
{
|
{
|
||||||
/// <summary>单个渲染层的固定框选输入与视觉覆盖层。</summary>
|
/// <summary>单个渲染层的固定选区视觉覆盖层。</summary>
|
||||||
[RequireComponent(typeof(RectTransform), typeof(Image))]
|
[RequireComponent(typeof(RectTransform), typeof(Image))]
|
||||||
public sealed class XTableSelectionOverlay : MonoBehaviour, IPointerDownHandler, IDragHandler, IPointerUpHandler, IEndDragHandler
|
public sealed class XTableSelectionOverlay : MonoBehaviour
|
||||||
{
|
{
|
||||||
private XericUIActionTable m_Table;
|
private XericUIActionTable m_Table;
|
||||||
private Image m_Fill;
|
private Image m_Fill;
|
||||||
@@ -16,15 +14,6 @@ namespace XericUI.XTable.Rendering.Component
|
|||||||
private int m_RowEnd;
|
private int m_RowEnd;
|
||||||
private int m_ColStart;
|
private int m_ColStart;
|
||||||
private int m_ColEnd;
|
private int m_ColEnd;
|
||||||
private bool m_Dragging;
|
|
||||||
|
|
||||||
#region debug-point selection-overlay-config
|
|
||||||
private void DebugReport(string point, string details)
|
|
||||||
{
|
|
||||||
if (Application.isPlaying)
|
|
||||||
Debug.Log($"[XTableSelection] {point} object={name}; {details}", this);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
public void Configure(XericUIActionTable table, int rowStart, int rowEnd, int colStart, int colEnd)
|
public void Configure(XericUIActionTable table, int rowStart, int rowEnd, int colStart, int colEnd)
|
||||||
{
|
{
|
||||||
@@ -42,7 +31,6 @@ namespace XericUI.XTable.Rendering.Component
|
|||||||
rt.sizeDelta = region.size;
|
rt.sizeDelta = region.size;
|
||||||
EnsureVisuals();
|
EnsureVisuals();
|
||||||
RefreshVisual();
|
RefreshVisual();
|
||||||
DebugReport("overlay-config", $"region={m_RowStart},{m_RowEnd},{m_ColStart},{m_ColEnd};rect={rt.rect};position={rt.anchoredPosition};parent={transform.parent?.name};sibling={transform.GetSiblingIndex()}");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RefreshVisual()
|
public void RefreshVisual()
|
||||||
@@ -73,88 +61,33 @@ namespace XericUI.XTable.Rendering.Component
|
|||||||
m_Fill.gameObject.SetActive(true);
|
m_Fill.gameObject.SetActive(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region debug-point selection-overlay-input
|
|
||||||
public void OnPointerDown(PointerEventData eventData)
|
|
||||||
{
|
|
||||||
int row = -1;
|
|
||||||
int col = -1;
|
|
||||||
bool hit = TryGetCellFromOverlayPoint(eventData.position, eventData.pressEventCamera, out row, out col);
|
|
||||||
DebugReport("pointer-down", $"hit={hit};row={row};col={col};position={eventData.position};rect={transform.RectTransform().rect};dragHandler={eventData.pointerDrag?.name};pressHandler={eventData.pointerPress?.name}");
|
|
||||||
if (!hit)
|
|
||||||
return;
|
|
||||||
m_Dragging = true;
|
|
||||||
m_Table.BeginSelection(row, col);
|
|
||||||
eventData.Use();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnDrag(PointerEventData eventData)
|
|
||||||
{
|
|
||||||
if (!m_Dragging || m_Table == null)
|
|
||||||
{
|
|
||||||
DebugReport("drag-ignored", $"dragging={m_Dragging};table={m_Table != null};dragHandler={eventData.pointerDrag?.name}");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
bool hit = TryGetCellFromOverlayPoint(eventData.position, eventData.pressEventCamera, out int row, out int col);
|
|
||||||
DebugReport("drag", $"hit={hit};row={row};col={col};position={eventData.position};dragHandler={eventData.pointerDrag?.name}");
|
|
||||||
if (hit)
|
|
||||||
m_Table.UpdateSelectionDragToCell(row, col);
|
|
||||||
eventData.Use();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnPointerUp(PointerEventData eventData)
|
|
||||||
{
|
|
||||||
EndDrag();
|
|
||||||
eventData.Use();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnEndDrag(PointerEventData eventData) => EndDrag();
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
private void Update()
|
|
||||||
{
|
|
||||||
if (!Application.isPlaying || !Input.GetMouseButtonDown(0) || EventSystem.current == null) return;
|
|
||||||
var data = new PointerEventData(EventSystem.current) { position = Input.mousePosition };
|
|
||||||
var results = new List<RaycastResult>();
|
|
||||||
EventSystem.current.RaycastAll(data, results);
|
|
||||||
string hits = string.Empty;
|
|
||||||
for (int i = 0; i < results.Count && i < 5; i++)
|
|
||||||
hits += $"{i}:{results[i].gameObject.name}/{results[i].module.GetType().Name} ";
|
|
||||||
DebugReport("raycast", $"mouse={Input.mousePosition};hits={hits}");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnDisable() => EndDrag();
|
|
||||||
private void OnDestroy() => EndDrag();
|
|
||||||
|
|
||||||
private void EndDrag()
|
|
||||||
{
|
|
||||||
if (!m_Dragging) return;
|
|
||||||
m_Dragging = false;
|
|
||||||
m_Table?.EndSelection();
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool TryGetCellFromOverlayPoint(Vector2 screenPoint, Camera eventCamera, out int row, out int col)
|
|
||||||
{
|
|
||||||
row = col = -1;
|
|
||||||
if (m_Table == null || !RectTransformUtility.ScreenPointToLocalPointInRectangle(transform.RectTransform(), screenPoint, eventCamera, out Vector2 local))
|
|
||||||
return false;
|
|
||||||
Rect region = m_Table.GetTableRect(m_RowStart, m_RowEnd, m_ColStart, m_ColEnd);
|
|
||||||
return m_Table.TryGetCellFromTablePoint(new Vector2(region.x + local.x, region.y - local.y), true, out row, out col);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void EnsureVisuals()
|
private void EnsureVisuals()
|
||||||
{
|
{
|
||||||
var input = GetComponent<Image>();
|
var input = GetComponent<Image>();
|
||||||
input.color = Color.clear;
|
input.color = Color.clear;
|
||||||
input.raycastTarget = true;
|
input.raycastTarget = false;
|
||||||
|
for (int i = transform.childCount - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
Transform child = transform.GetChild(i);
|
||||||
|
if (child.name != "_SelectionRect") continue;
|
||||||
|
Image image = child.GetComponent<Image>();
|
||||||
|
if (m_Fill == null && image != null)
|
||||||
|
{
|
||||||
|
m_Fill = image;
|
||||||
|
m_Fill.raycastTarget = false;
|
||||||
|
var outline = child.GetComponent<Outline>();
|
||||||
|
if (outline != null) Destroy(outline);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (Application.isPlaying) Destroy(child.gameObject);
|
||||||
|
else DestroyImmediate(child.gameObject);
|
||||||
|
}
|
||||||
if (m_Fill != null) return;
|
if (m_Fill != null) return;
|
||||||
var go = new GameObject("_SelectionRect", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Outline));
|
var go = new GameObject("_SelectionRect", typeof(RectTransform), typeof(CanvasRenderer), typeof(Image));
|
||||||
go.hideFlags = HideFlags.DontSave | HideFlags.HideInHierarchy;
|
go.hideFlags = HideFlags.DontSave | HideFlags.HideInHierarchy;
|
||||||
go.transform.SetParent(transform, false);
|
go.transform.SetParent(transform, false);
|
||||||
m_Fill = go.GetComponent<Image>();
|
m_Fill = go.GetComponent<Image>();
|
||||||
m_Fill.raycastTarget = false;
|
m_Fill.raycastTarget = false;
|
||||||
var outline = go.GetComponent<Outline>();
|
|
||||||
outline.effectColor = new Color(0.2f, 0.55f, 1f, 1f);
|
|
||||||
outline.effectDistance = new Vector2(1f, -1f);
|
|
||||||
var rt = m_Fill.rectTransform;
|
var rt = m_Fill.rectTransform;
|
||||||
rt.anchorMin = new Vector2(0, 1);
|
rt.anchorMin = new Vector2(0, 1);
|
||||||
rt.anchorMax = new Vector2(0, 1);
|
rt.anchorMax = new Vector2(0, 1);
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ namespace XericUI.XTable.Rendering.Component
|
|||||||
PrefabPool = m_PrefabPool,
|
PrefabPool = m_PrefabPool,
|
||||||
CellPadding = CellPadding,
|
CellPadding = CellPadding,
|
||||||
Config = Config,
|
Config = Config,
|
||||||
|
SelectionTable = this,
|
||||||
GetStyleColor = (ns, path, fallback) => GetStyleColor(ns, path, fallback),
|
GetStyleColor = (ns, path, fallback) => GetStyleColor(ns, path, fallback),
|
||||||
GetStyleInt = (ns, path, fallback) => GetStyleInt(ns, path, fallback),
|
GetStyleInt = (ns, path, fallback) => GetStyleInt(ns, path, fallback),
|
||||||
GetStyleFontAsset = (ns, path) => GetStyleFontAsset(ns, path),
|
GetStyleFontAsset = (ns, path) => GetStyleFontAsset(ns, path),
|
||||||
|
|||||||
@@ -405,7 +405,7 @@ namespace XericUI.XTable.Rendering.Component
|
|||||||
if (m_BackgroundRenderer != null) return;
|
if (m_BackgroundRenderer != null) return;
|
||||||
|
|
||||||
var backgroundGo = new GameObject("_TableBackground",
|
var backgroundGo = new GameObject("_TableBackground",
|
||||||
typeof(RectTransform), typeof(CanvasRenderer), typeof(XTableBackgroundRenderer));
|
typeof(RectTransform), typeof(CanvasRenderer), typeof(XTableBackgroundRenderer), typeof(XTableSelectionInput));
|
||||||
backgroundGo.hideFlags = HideFlags.DontSave | HideFlags.HideInHierarchy;
|
backgroundGo.hideFlags = HideFlags.DontSave | HideFlags.HideInHierarchy;
|
||||||
backgroundGo.transform.SetParent(ContentTransform, false);
|
backgroundGo.transform.SetParent(ContentTransform, false);
|
||||||
backgroundGo.transform.SetAsFirstSibling();
|
backgroundGo.transform.SetAsFirstSibling();
|
||||||
@@ -418,7 +418,8 @@ namespace XericUI.XTable.Rendering.Component
|
|||||||
backgroundRt.sizeDelta = new Vector2(m_TotalWidth, m_TotalHeight);
|
backgroundRt.sizeDelta = new Vector2(m_TotalWidth, m_TotalHeight);
|
||||||
|
|
||||||
m_BackgroundRenderer = backgroundGo.GetComponent<XTableBackgroundRenderer>();
|
m_BackgroundRenderer = backgroundGo.GetComponent<XTableBackgroundRenderer>();
|
||||||
m_BackgroundRenderer.raycastTarget = false;
|
m_BackgroundRenderer.raycastTarget = true;
|
||||||
|
backgroundGo.GetComponent<XTableSelectionInput>().Configure(this);
|
||||||
UpdateBackground();
|
UpdateBackground();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user