Files
zeling_v2/Assets/_Game/Scripts/UI/Controls/UISelectableRow.cs
2026-06-06 09:00:11 +08:00

75 lines
2.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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);
}
}
}