using System; using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems; using TMPro; namespace BaseGames.UI { /// /// 通用可选择行:图标 + 标签 + 选中高亮 + 按钮,适用于菜单项、设置行、存档槽、列表项。 /// /// 配合 作 TView,或在面板里直接布局使用。 /// 选中(手柄/键盘导航或鼠标悬停)时自动切换高亮节点。 /// [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; /// 行被点击(或 Submit)时触发。 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); } /// 把 EventSystem 焦点设到本行。 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); } } }