220 lines
6.6 KiB
C#
220 lines
6.6 KiB
C#
using System;
|
|
using AibisDream.UI;
|
|
using AibisDream.Utility;
|
|
using TMPro;
|
|
using UnityEngine;
|
|
using UnityEngine.EventSystems;
|
|
using UnityEngine.Localization.Components;
|
|
using UnityEngine.UI;
|
|
|
|
namespace AibisDream
|
|
{
|
|
public class SelectItem : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
|
|
{
|
|
[SerializeField] private TMP_Text labelText;
|
|
[SerializeField] private LocalizeStringEvent labelLocalize;
|
|
[SerializeField] private TMP_Text showText;
|
|
[SerializeField] private LocalizeStringEvent showLocalize;
|
|
[SerializeField] private Button leftBtn;
|
|
[SerializeField] private Button rightBtn;
|
|
[SerializeField] private Image selectionBar;
|
|
[SerializeField] private float selectionBarHiddenAlpha;
|
|
[SerializeField] private float selectionBarVisibleAlpha = 1f;
|
|
[SerializeField] private Color normalTextColor = Color.white;
|
|
[SerializeField] private Color hoveredTextColor = new Color(0.02f, 0.02f, 0.04f);
|
|
[SerializeField] private ColorBlock lightRowButtonColors = new ColorBlock
|
|
{
|
|
normalColor = new Color(0.02f, 0.02f, 0.04f, 1f),
|
|
highlightedColor = new Color(0.35f, 0.35f, 0.4f, 1f),
|
|
pressedColor = new Color(0.55f, 0.55f, 0.6f, 1f),
|
|
selectedColor = new Color(0.02f, 0.02f, 0.04f, 1f),
|
|
disabledColor = new Color(0.78431374f, 0.78431374f, 0.78431374f, 0.5019608f),
|
|
colorMultiplier = 1f,
|
|
fadeDuration = 0.1f
|
|
};
|
|
|
|
private string _propName;
|
|
private UIFormOption[] _options = Array.Empty<UIFormOption>();
|
|
private int _curIdx;
|
|
private Action<string, string> _onValueChanged;
|
|
private bool _isListening;
|
|
private bool _isHovered;
|
|
private ColorBlock _darkRowButtonColors;
|
|
|
|
private void Awake()
|
|
{
|
|
if (leftBtn != null)
|
|
{
|
|
_darkRowButtonColors = leftBtn.colors;
|
|
}
|
|
|
|
SetHovered(false);
|
|
|
|
if (!_isListening)
|
|
{
|
|
leftBtn?.onClick.AddListener(LeftRoll);
|
|
rightBtn?.onClick.AddListener(RightRoll);
|
|
_isListening = leftBtn != null || rightBtn != null;
|
|
}
|
|
}
|
|
|
|
public void OnPointerEnter(PointerEventData eventData)
|
|
{
|
|
if (!_isHovered)
|
|
{
|
|
_isHovered = true;
|
|
TerminalUIAudio.NotifyHover();
|
|
}
|
|
|
|
SetHovered(true);
|
|
}
|
|
|
|
public void OnPointerExit(PointerEventData eventData)
|
|
{
|
|
_isHovered = false;
|
|
SetHovered(false);
|
|
}
|
|
|
|
private void SetHovered(bool hovered)
|
|
{
|
|
SetSelectionBarAlpha(hovered ? selectionBarVisibleAlpha : selectionBarHiddenAlpha);
|
|
|
|
var textColor = hovered ? hoveredTextColor : normalTextColor;
|
|
SetTextColor(labelText, textColor);
|
|
SetTextColor(showText, textColor);
|
|
|
|
var buttonColors = hovered ? lightRowButtonColors : _darkRowButtonColors;
|
|
ApplyButtonColors(leftBtn, buttonColors);
|
|
ApplyButtonColors(rightBtn, buttonColors);
|
|
}
|
|
|
|
private static void SetTextColor(TMP_Text text, Color color)
|
|
{
|
|
if (text != null)
|
|
{
|
|
text.color = color;
|
|
}
|
|
}
|
|
|
|
private static void ApplyButtonColors(Button button, ColorBlock colors)
|
|
{
|
|
if (button != null)
|
|
{
|
|
button.colors = colors;
|
|
}
|
|
}
|
|
|
|
private void SetSelectionBarAlpha(float alpha)
|
|
{
|
|
if (selectionBar == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var color = selectionBar.color;
|
|
color.a = alpha;
|
|
selectionBar.color = color;
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
if (!_isListening)
|
|
{
|
|
return;
|
|
}
|
|
|
|
leftBtn?.onClick.RemoveListener(LeftRoll);
|
|
rightBtn?.onClick.RemoveListener(RightRoll);
|
|
_isListening = false;
|
|
}
|
|
|
|
public void Init(string propName, string label, UIFormOption[] options, Action<string, string> onValueChanged)
|
|
{
|
|
_propName = propName;
|
|
_options = options ?? Array.Empty<UIFormOption>();
|
|
_onValueChanged = onValueChanged;
|
|
|
|
if (leftBtn == null || rightBtn == null)
|
|
{
|
|
Debug.LogError($"[SelectItem] Buttons not assigned on {name}.", this);
|
|
}
|
|
|
|
SetDisplayText(labelText, labelLocalize, label);
|
|
RefreshValue();
|
|
}
|
|
|
|
public void SetValue(string value)
|
|
{
|
|
var idx = Array.FindIndex(_options, item => item.prop == value);
|
|
if (idx < 0)
|
|
{
|
|
Debug.LogWarning($"[SelectItem] {_propName} value '{value}' not found on {name}; fallback to first option.");
|
|
idx = 0;
|
|
}
|
|
|
|
_curIdx = Mathf.Clamp(idx, 0, Mathf.Max(0, _options.Length - 1));
|
|
RefreshValue();
|
|
}
|
|
|
|
private void LeftRoll()
|
|
{
|
|
Step(1);
|
|
}
|
|
|
|
private void RightRoll()
|
|
{
|
|
Step(-1);
|
|
}
|
|
|
|
private void Step(int offset)
|
|
{
|
|
if (_options.Length == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_curIdx = CommonUtil.LoopStep(_curIdx, 0, _options.Length - 1, offset);
|
|
RefreshValue();
|
|
_onValueChanged?.Invoke(_propName, _options[_curIdx].prop);
|
|
TerminalUIAudio.NotifyClick();
|
|
}
|
|
|
|
private void RefreshValue()
|
|
{
|
|
if (_options.Length == 0)
|
|
{
|
|
SetDisplayText(showText, showLocalize, string.Empty);
|
|
return;
|
|
}
|
|
|
|
SetDisplayText(showText, showLocalize, _options[_curIdx].label);
|
|
}
|
|
|
|
private static void SetDisplayText(TMP_Text text, LocalizeStringEvent localize, string value)
|
|
{
|
|
if (localize != null && IsLocalizationKey(value))
|
|
{
|
|
localize.enabled = true;
|
|
localize.SetTable(ConstRef.UITextTable);
|
|
localize.SetEntry(value);
|
|
return;
|
|
}
|
|
|
|
if (localize != null)
|
|
{
|
|
localize.enabled = false;
|
|
}
|
|
|
|
if (text != null)
|
|
{
|
|
text.text = value;
|
|
}
|
|
}
|
|
|
|
private static bool IsLocalizationKey(string value)
|
|
{
|
|
return !string.IsNullOrEmpty(value) && value.StartsWith("setting_", StringComparison.Ordinal);
|
|
}
|
|
}
|
|
}
|