75 lines
2.9 KiB
C#
75 lines
2.9 KiB
C#
using System;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using UnityEngine.EventSystems;
|
|
using TMPro;
|
|
|
|
namespace BaseGames.UI
|
|
{
|
|
/// <summary>
|
|
/// 通用可选择行:图标 + 标签 + 选中高亮 + 按钮,适用于菜单项、设置行、存档槽、列表项。
|
|
///
|
|
/// 配合 <see cref="PooledListView{TData,TView}"/> 作 TView,或在面板里直接布局使用。
|
|
/// 选中(手柄/键盘导航或鼠标悬停)时自动切换高亮节点。
|
|
/// </summary>
|
|
[DisallowMultipleComponent]
|
|
public class UISelectableRow : MonoBehaviour, ISelectHandler, IDeselectHandler, IPointerEnterHandler
|
|
{
|
|
[Header("引用")]
|
|
[SerializeField] private Button _button;
|
|
[SerializeField] private TMP_Text _label;
|
|
[Tooltip("行图标(可空)。")]
|
|
[SerializeField] private Image _icon;
|
|
[Tooltip("选中高亮节点(可空,选中时 SetActive(true))。")]
|
|
[SerializeField] private GameObject _selectedHighlight;
|
|
|
|
/// <summary>行被点击(或 Submit)时触发。</summary>
|
|
public event Action Clicked;
|
|
|
|
public Button Button => _button;
|
|
public Selectable Selectable => _button;
|
|
|
|
private void Awake()
|
|
{
|
|
if (_selectedHighlight != null) _selectedHighlight.SetActive(false);
|
|
if (_button != null)
|
|
_button.onClick.AddListener(() => Clicked?.Invoke());
|
|
}
|
|
|
|
// ── 数据填充 ──────────────────────────────────────────────────────────
|
|
public void SetLabel(string text)
|
|
{
|
|
if (_label != null) _label.text = text;
|
|
}
|
|
|
|
public void SetIcon(Sprite sprite)
|
|
{
|
|
if (_icon == null) return;
|
|
_icon.sprite = sprite;
|
|
_icon.enabled = sprite != null;
|
|
}
|
|
|
|
public void SetSelected(bool selected)
|
|
{
|
|
if (_selectedHighlight != null) _selectedHighlight.SetActive(selected);
|
|
}
|
|
|
|
/// <summary>把 EventSystem 焦点设到本行。</summary>
|
|
public void Focus()
|
|
{
|
|
if (_button != null && EventSystem.current != null)
|
|
EventSystem.current.SetSelectedGameObject(_button.gameObject);
|
|
}
|
|
|
|
// ── 选中反馈 ──────────────────────────────────────────────────────────
|
|
public void OnSelect(BaseEventData e) => SetSelected(true);
|
|
public void OnDeselect(BaseEventData e) => SetSelected(false);
|
|
|
|
public void OnPointerEnter(PointerEventData e)
|
|
{
|
|
if (_button != null && _button.interactable && EventSystem.current != null)
|
|
EventSystem.current.SetSelectedGameObject(_button.gameObject);
|
|
}
|
|
}
|
|
}
|