收紧各组件权限
This commit is contained in:
@@ -8,18 +8,24 @@ namespace XericUI.ReflectionUIGenerator
|
||||
/// <summary>
|
||||
/// Dropdown 值组件 — 处理 string / int / enum 类型的下拉选择交互
|
||||
/// 预设选项来源:元数据的 PresetOptions 或 enum 类型的枚举名
|
||||
///
|
||||
/// 选项动态创建:OnPoolGet 时根据元数据 PresetOptions 构建选项列表,
|
||||
/// BindToAccessor 时通过 AddOptions() 填充到 Dropdown 组件。
|
||||
/// </summary>
|
||||
[AddComponentMenu("Xeric Library/UI Action Vessel/Values/XUIAvrgMDDropdownValue")]
|
||||
public class XUIAvrgMDDropdownValue : XUIAvrgMDValue
|
||||
{
|
||||
[SerializeField]
|
||||
[Tooltip("关联的 Dropdown 组件(未设置则自动查找)")]
|
||||
[SerializeField, Tooltip("关联的 Dropdown 组件(未设置则自动查找)")]
|
||||
#if dUI_TextMeshPro
|
||||
private TMPro.TMP_Dropdown _dropdown;
|
||||
#else
|
||||
private Dropdown _dropdown;
|
||||
#endif
|
||||
|
||||
[Header("选项动态创建")]
|
||||
[SerializeField, Tooltip("选项项预制体 Transform(可选,用于自定义选项创建逻辑)")]
|
||||
private Transform _optionItemPrefab;
|
||||
|
||||
private List<string> _options;
|
||||
|
||||
private void Awake()
|
||||
@@ -37,16 +43,55 @@ namespace XericUI.ReflectionUIGenerator
|
||||
{
|
||||
base.OnPoolGet(metaData);
|
||||
_options = BuildOptions(metaData?.ValueType);
|
||||
|
||||
// 动态创建选项对象(子类可覆写)
|
||||
CreateOptionItems();
|
||||
}
|
||||
|
||||
public override void OnPoolRelease()
|
||||
{
|
||||
if (_dropdown != null)
|
||||
_dropdown.onValueChanged.RemoveAllListeners();
|
||||
|
||||
DestroyOptionItems();
|
||||
_options = null;
|
||||
base.OnPoolRelease();
|
||||
}
|
||||
|
||||
// ============ 动态选项创建 ============
|
||||
|
||||
/// <summary>
|
||||
/// 根据预设选项动态创建选项子对象
|
||||
/// 子类可覆写以实现自定义选项创建(如图标、颜色等)
|
||||
/// </summary>
|
||||
protected virtual void CreateOptionItems()
|
||||
{
|
||||
if (_optionItemPrefab == null || _options == null) return;
|
||||
|
||||
for (int i = 0; i < _options.Count; i++)
|
||||
{
|
||||
var item = Instantiate(_optionItemPrefab, _optionItemPrefab.parent);
|
||||
item.name = $"Option_{i}_{_options[i]}";
|
||||
item.gameObject.SetActive(true);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 销毁动态创建的选项子对象
|
||||
/// </summary>
|
||||
protected virtual void DestroyOptionItems()
|
||||
{
|
||||
if (_optionItemPrefab == null) return;
|
||||
|
||||
var parent = _optionItemPrefab.parent;
|
||||
for (int i = parent.childCount - 1; i >= 0; i--)
|
||||
{
|
||||
var child = parent.GetChild(i);
|
||||
if (child != _optionItemPrefab)
|
||||
Destroy(child.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
// ============ 核心绑定 ============
|
||||
|
||||
public override void BindToAccessor(
|
||||
|
||||
@@ -1,19 +1,27 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XericUI.ReflectionUIGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// Label 只读值组件 — 纯文本展示,无交互控件
|
||||
/// 拥有自己的 _valueDisplayText 用于显示值
|
||||
/// </summary>
|
||||
[AddComponentMenu("Xeric Library/UI Action Vessel/Values/XUIAvrgMDLabelValue")]
|
||||
public class XUIAvrgMDLabelValue : XUIAvrgMDValue
|
||||
{
|
||||
[SerializeField, Tooltip("值显示文本 — 显示当前字段的值")]
|
||||
#if dUI_TextMeshPro
|
||||
[SerializeField, Tooltip("关联的 TMP_Text 组件(标签文本 + 值文本共用一个 Text 时使用)")]
|
||||
private TMPro.TMP_Text _tmpText;
|
||||
private TMPro.TMP_Text _valueDisplayText;
|
||||
#else
|
||||
private UnityEngine.UI.Text _valueDisplayText;
|
||||
#endif
|
||||
|
||||
public override void OnPoolRelease()
|
||||
{
|
||||
if (_valueDisplayText != null) _valueDisplayText.text = "";
|
||||
base.OnPoolRelease();
|
||||
}
|
||||
|
||||
public override void BindToAccessor(
|
||||
IAvrgValueAccessor accessor,
|
||||
AvrgMvvmBinding binding,
|
||||
@@ -33,5 +41,35 @@ namespace XericUI.ReflectionUIGenerator
|
||||
var initialValue = accessor.GetValue();
|
||||
UpdateValueDisplay(initialValue, ValidationState.Normal);
|
||||
}
|
||||
|
||||
protected override void UpdateValueDisplay(object value, ValidationState state)
|
||||
{
|
||||
if (_valueDisplayText != null)
|
||||
{
|
||||
_valueDisplayText.text = CurrentAccessor?.FormatDisplay(value) ?? value?.ToString() ?? "";
|
||||
|
||||
_valueDisplayText.color = state == ValidationState.Invalid
|
||||
? Color.red
|
||||
: state == ValidationState.Warning
|
||||
? new Color(1f, 0.92f, 0.016f)
|
||||
: Color.white;
|
||||
}
|
||||
|
||||
base.UpdateValueDisplay(value, state);
|
||||
}
|
||||
|
||||
protected override void OnValidationStateChanged(ValidationState state)
|
||||
{
|
||||
base.OnValidationStateChanged(state);
|
||||
|
||||
if (_valueDisplayText != null)
|
||||
{
|
||||
_valueDisplayText.color = state == ValidationState.Invalid
|
||||
? Color.red
|
||||
: state == ValidationState.Warning
|
||||
? new Color(1f, 0.92f, 0.016f)
|
||||
: Color.white;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,17 +15,33 @@ namespace XericUI.ReflectionUIGenerator
|
||||
private Slider _slider;
|
||||
|
||||
[Header("Slider 专属插槽")]
|
||||
[SerializeField, Tooltip("值显示文本 — 显示当前 Slider 数值")]
|
||||
#if dUI_TextMeshPro
|
||||
private TMPro.TMP_Text _valueDisplayText;
|
||||
#else
|
||||
private UnityEngine.UI.Text _valueDisplayText;
|
||||
#endif
|
||||
|
||||
[SerializeField, Tooltip("最小值文本 — 显示 Slider 下限")]
|
||||
#if dUI_TextMeshPro
|
||||
private TMPro.TMP_Text _minValueText;
|
||||
#else
|
||||
private UnityEngine.UI.Text _minValueText;
|
||||
#endif
|
||||
|
||||
[SerializeField, Tooltip("最大值文本 — 显示 Slider 上限")]
|
||||
#if dUI_TextMeshPro
|
||||
private TMPro.TMP_Text _maxValueText;
|
||||
#else
|
||||
private UnityEngine.UI.Text _maxValueText;
|
||||
#endif
|
||||
|
||||
[SerializeField, Tooltip("增加按钮(点击按步进值 +)")]
|
||||
private Button _incrementButton;
|
||||
|
||||
[SerializeField, Tooltip("减少按钮(点击按步进值 -)")]
|
||||
private Button _decrementButton;
|
||||
|
||||
#if dUI_TextMeshPro
|
||||
[SerializeField, Tooltip("值显示标签(可选,未设置则不更新)")]
|
||||
private TMPro.TMP_Text _valueLabel;
|
||||
#endif
|
||||
|
||||
private const float DefaultStep = 0.1f;
|
||||
|
||||
private void Awake()
|
||||
@@ -51,7 +67,6 @@ namespace XericUI.ReflectionUIGenerator
|
||||
|
||||
public override void OnPoolRelease()
|
||||
{
|
||||
// 清除按钮监听
|
||||
if (_incrementButton != null)
|
||||
_incrementButton.onClick.RemoveAllListeners();
|
||||
if (_decrementButton != null)
|
||||
@@ -59,6 +74,11 @@ namespace XericUI.ReflectionUIGenerator
|
||||
if (_slider != null)
|
||||
_slider.onValueChanged.RemoveAllListeners();
|
||||
|
||||
// 重置子类文本
|
||||
if (_valueDisplayText != null) _valueDisplayText.text = "";
|
||||
if (_minValueText != null) _minValueText.text = "";
|
||||
if (_maxValueText != null) _maxValueText.text = "";
|
||||
|
||||
base.OnPoolRelease();
|
||||
}
|
||||
|
||||
@@ -74,6 +94,9 @@ namespace XericUI.ReflectionUIGenerator
|
||||
|
||||
if (binding == null || accessor == null || _slider == null) return;
|
||||
|
||||
// 初始化上下限文本
|
||||
ApplyRangeTexts();
|
||||
|
||||
// 增减按钮
|
||||
if (_incrementButton != null)
|
||||
_incrementButton.onClick.AddListener(OnIncrementClicked);
|
||||
@@ -87,10 +110,7 @@ namespace XericUI.ReflectionUIGenerator
|
||||
binding.WriteFromUI(convertedVal);
|
||||
scheduler?.MarkUIDirty(binding);
|
||||
|
||||
#if dUI_TextMeshPro
|
||||
if (_valueLabel != null)
|
||||
_valueLabel.text = accessor.FormatDisplay(convertedVal);
|
||||
#endif
|
||||
RefreshValueText(convertedVal);
|
||||
});
|
||||
|
||||
// 数据 → UI(带验证状态)
|
||||
@@ -99,12 +119,9 @@ namespace XericUI.ReflectionUIGenerator
|
||||
float sliderVal = Convert.ToSingle(value);
|
||||
_slider.SetValueWithoutNotify(sliderVal);
|
||||
|
||||
#if dUI_TextMeshPro
|
||||
if (_valueLabel != null)
|
||||
_valueLabel.text = accessor.FormatDisplay(value);
|
||||
#endif
|
||||
RefreshValueText(value);
|
||||
ApplyValueTextColor(state);
|
||||
|
||||
// 委托基类处理标签合成 + 值文本
|
||||
base.UpdateValueDisplay(value, state);
|
||||
};
|
||||
|
||||
@@ -114,16 +131,45 @@ namespace XericUI.ReflectionUIGenerator
|
||||
// 首次同步
|
||||
var initialValue = accessor.GetValue();
|
||||
if (initialValue != null)
|
||||
{
|
||||
_slider.SetValueWithoutNotify(Convert.ToSingle(initialValue));
|
||||
#if dUI_TextMeshPro
|
||||
if (_valueLabel != null)
|
||||
_valueLabel.text = accessor.FormatDisplay(initialValue);
|
||||
#endif
|
||||
}
|
||||
|
||||
RefreshValueText(initialValue);
|
||||
UpdateValueDisplay(initialValue ?? 0f, ValidationState.Normal);
|
||||
}
|
||||
|
||||
// ============ 值显示 ============
|
||||
|
||||
protected override void UpdateValueDisplay(object value, ValidationState state)
|
||||
{
|
||||
ApplyValueTextColor(state);
|
||||
base.UpdateValueDisplay(value, state);
|
||||
}
|
||||
|
||||
private void RefreshValueText(object value)
|
||||
{
|
||||
if (_valueDisplayText == null || CurrentAccessor == null) return;
|
||||
_valueDisplayText.text = CurrentAccessor.FormatDisplay(value);
|
||||
}
|
||||
|
||||
private void ApplyValueTextColor(ValidationState state)
|
||||
{
|
||||
if (_valueDisplayText == null) return;
|
||||
|
||||
_valueDisplayText.color = state == ValidationState.Invalid
|
||||
? Color.red
|
||||
: state == ValidationState.Warning
|
||||
? new Color(1f, 0.92f, 0.016f)
|
||||
: Color.white;
|
||||
}
|
||||
|
||||
private void ApplyRangeTexts()
|
||||
{
|
||||
if (_minValueText != null)
|
||||
_minValueText.text = CurrentAccessor?.FormatDisplay(_slider.minValue) ?? _slider.minValue.ToString();
|
||||
if (_maxValueText != null)
|
||||
_maxValueText.text = CurrentAccessor?.FormatDisplay(_slider.maxValue) ?? _slider.maxValue.ToString();
|
||||
}
|
||||
|
||||
// ============ 步进值 ============
|
||||
|
||||
private float GetStepValue()
|
||||
@@ -169,6 +215,8 @@ namespace XericUI.ReflectionUIGenerator
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
ApplyValueTextColor(state);
|
||||
}
|
||||
|
||||
private static object ConvertValueForAccessor(float val, Type targetType)
|
||||
|
||||
@@ -8,26 +8,125 @@ namespace XericUI.ReflectionUIGenerator
|
||||
/// <summary>
|
||||
/// ToggleGroup 值组件 — 处理 string / int / enum 类型的单选组交互
|
||||
/// 适用于标记了 [XuiavrgFieldToggleGroupValue] 的字段
|
||||
///
|
||||
/// 选项动态创建:OnPoolGet 时根据元数据 PresetOptions 数量,
|
||||
/// 从 _toggleItemPrefab 实例化 Toggle 子对象。
|
||||
/// </summary>
|
||||
[AddComponentMenu("Xeric Library/UI Action Vessel/Values/XUIAvrgMDToggleGroupValue")]
|
||||
public class XUIAvrgMDToggleGroupValue : XUIAvrgMDValue
|
||||
{
|
||||
[SerializeField]
|
||||
[Tooltip("关联的 ToggleGroup 组件(未设置则自动查找)")]
|
||||
[SerializeField, Tooltip("关联的 ToggleGroup 组件(未设置则自动查找)")]
|
||||
private ToggleGroup _toggleGroup;
|
||||
|
||||
[Header("选项动态创建")]
|
||||
[SerializeField, Tooltip("Toggle 项预制体 — 在 OnPoolGet 时按预设选项数量实例化")]
|
||||
private Transform _toggleItemPrefab;
|
||||
|
||||
[SerializeField, Tooltip("选项容器 Transform — 动态创建的 Toggle 挂载到此节点下")]
|
||||
private Transform _optionsContainer;
|
||||
|
||||
private List<Toggle> _toggles = new List<Toggle>();
|
||||
private List<string> _optionLabels = new List<string>();
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (_toggleGroup == null) _toggleGroup = GetComponent<ToggleGroup>();
|
||||
if (_toggleGroup != null)
|
||||
}
|
||||
|
||||
// ============ 对象池生命周期 ============
|
||||
|
||||
public override void OnPoolGet(AvrgMemberMetaData metaData)
|
||||
{
|
||||
base.OnPoolGet(metaData);
|
||||
|
||||
// 构建选项列表
|
||||
BuildOptions(metaData?.ValueType);
|
||||
|
||||
// 动态创建 Toggle 项
|
||||
CreateToggleItems();
|
||||
}
|
||||
|
||||
public override void OnPoolRelease()
|
||||
{
|
||||
// 清理动态创建的 Toggle
|
||||
foreach (var toggle in _toggles)
|
||||
{
|
||||
_toggles = _toggleGroup.GetComponentsInChildren<Toggle>(true).ToList();
|
||||
if (toggle != null)
|
||||
toggle.onValueChanged.RemoveAllListeners();
|
||||
}
|
||||
DestroyToggleItems();
|
||||
|
||||
_toggles.Clear();
|
||||
_optionLabels.Clear();
|
||||
|
||||
base.OnPoolRelease();
|
||||
}
|
||||
|
||||
// ============ 动态 Toggle 创建 ============
|
||||
|
||||
/// <summary>
|
||||
/// 根据 _optionLabels 数量,从 _toggleItemPrefab 实例化 Toggle 子对象
|
||||
/// </summary>
|
||||
private void CreateToggleItems()
|
||||
{
|
||||
var parent = _optionsContainer != null ? _optionsContainer : transform;
|
||||
if (_toggleItemPrefab == null || _optionLabels.Count == 0) return;
|
||||
|
||||
for (int i = 0; i < _optionLabels.Count; i++)
|
||||
{
|
||||
var item = Instantiate(_toggleItemPrefab, parent);
|
||||
item.name = $"Toggle_{i}_{_optionLabels[i]}";
|
||||
item.gameObject.SetActive(true);
|
||||
|
||||
var toggle = item.GetComponent<Toggle>();
|
||||
if (toggle != null)
|
||||
{
|
||||
toggle.group = _toggleGroup;
|
||||
_toggles.Add(toggle);
|
||||
|
||||
// 设置标签文本
|
||||
var label = item.GetComponentInChildren<Text>(true);
|
||||
if (label != null)
|
||||
label.text = _optionLabels[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 销毁动态创建的所有 Toggle 子对象
|
||||
/// </summary>
|
||||
private void DestroyToggleItems()
|
||||
{
|
||||
var parent = _optionsContainer != null ? _optionsContainer : transform;
|
||||
|
||||
foreach (var toggle in _toggles)
|
||||
{
|
||||
if (toggle != null)
|
||||
Destroy(toggle.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
private void BuildOptions(System.Type valueType)
|
||||
{
|
||||
_optionLabels.Clear();
|
||||
|
||||
// 1. 从元数据 PresetOptions
|
||||
if (BoundMetaData?.PresetOptions != null && BoundMetaData.PresetOptions.Count > 0)
|
||||
{
|
||||
_optionLabels.AddRange(BoundMetaData.PresetOptions);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. enum 类型
|
||||
if (valueType != null && valueType.IsEnum)
|
||||
{
|
||||
_optionLabels.AddRange(System.Enum.GetNames(valueType));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// ============ 核心绑定 ============
|
||||
|
||||
public override void BindToAccessor(
|
||||
IAvrgValueAccessor accessor,
|
||||
AvrgMvvmBinding binding,
|
||||
@@ -36,10 +135,14 @@ namespace XericUI.ReflectionUIGenerator
|
||||
CurrentAccessor = accessor;
|
||||
CurrentBinding = binding;
|
||||
|
||||
if (binding == null || accessor == null || _toggleGroup == null) return;
|
||||
if (binding == null || accessor == null || _toggleGroup == null || _toggles.Count == 0) return;
|
||||
|
||||
// 构建选项
|
||||
BuildOptions(accessor.ValueType);
|
||||
// 只读模式下禁用所有 Toggle
|
||||
if (accessor.IsReadOnly)
|
||||
{
|
||||
foreach (var t in _toggles)
|
||||
t.interactable = false;
|
||||
}
|
||||
|
||||
// 为每个 Toggle 注册事件
|
||||
for (int i = 0; i < _toggles.Count && i < _optionLabels.Count; i++)
|
||||
@@ -88,25 +191,6 @@ namespace XericUI.ReflectionUIGenerator
|
||||
}
|
||||
}
|
||||
|
||||
private void BuildOptions(System.Type valueType)
|
||||
{
|
||||
_optionLabels.Clear();
|
||||
|
||||
// 1. 从元数据 PresetOptions
|
||||
if (BoundMetaData?.PresetOptions != null && BoundMetaData.PresetOptions.Count > 0)
|
||||
{
|
||||
_optionLabels.AddRange(BoundMetaData.PresetOptions);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. enum 类型
|
||||
if (valueType != null && valueType.IsEnum)
|
||||
{
|
||||
_optionLabels.AddRange(System.Enum.GetNames(valueType));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private static object ConvertOptionToValue(string option, System.Type targetType)
|
||||
{
|
||||
if (targetType == typeof(string)) return option;
|
||||
|
||||
@@ -13,7 +13,8 @@ namespace XericUI.ReflectionUIGenerator
|
||||
/// 3. 通过 virtual BindToAccessor() 让子类自行管理 UI 交互事件
|
||||
/// 4. 对象池生命周期:OnPoolGet(meta) 初始化、OnPoolRelease() 重置
|
||||
/// 5. 定义绑定槽(BindingSlots),供拆分属性子绑定匹配
|
||||
/// 6. 通过 UpdateValueDisplay() 合成标签文本(名称 + 只读 + 警告标记)
|
||||
/// 6. 基类统一管理标签文本(名称 + 只读 + 警告标记)和单位可见性
|
||||
/// 值显示由各子类自行实现
|
||||
/// </summary>
|
||||
[AddComponentMenu("Xeric Library/UI Action Vessel/XUIAvrgMDValue")]
|
||||
public class XUIAvrgMDValue : MonoBehaviour
|
||||
@@ -49,7 +50,7 @@ namespace XericUI.ReflectionUIGenerator
|
||||
|
||||
// ============ UI 文本插槽 ============
|
||||
|
||||
[Header("UI 文本插槽")]
|
||||
[Header("UI 基类插槽")]
|
||||
[SerializeField, Tooltip("字段标签文本 — 显示 \"名称 (只读) ⚠警告\",为 null 则不显示标签")]
|
||||
#if dUI_TextMeshPro
|
||||
protected TMPro.TMP_Text _fieldLabelText;
|
||||
@@ -57,13 +58,6 @@ namespace XericUI.ReflectionUIGenerator
|
||||
protected UnityEngine.UI.Text _fieldLabelText;
|
||||
#endif
|
||||
|
||||
[SerializeField, Tooltip("值显示文本 — 可为 null(Slider/Color/Texture 子类不依赖文本)")]
|
||||
#if dUI_TextMeshPro
|
||||
protected TMPro.TMP_Text _valueDisplayText;
|
||||
#else
|
||||
protected UnityEngine.UI.Text _valueDisplayText;
|
||||
#endif
|
||||
|
||||
[SerializeField, Tooltip("单位文本 — 可为 null")]
|
||||
#if dUI_TextMeshPro
|
||||
protected TMPro.TMP_Text _unitText;
|
||||
@@ -71,6 +65,9 @@ namespace XericUI.ReflectionUIGenerator
|
||||
protected UnityEngine.UI.Text _unitText;
|
||||
#endif
|
||||
|
||||
[SerializeField, Tooltip("单位容器 Transform — 单位文本为空时 SetActive(false) 隐藏")]
|
||||
protected Transform _unitTransform;
|
||||
|
||||
// ============ 公共属性 ============
|
||||
|
||||
/// <summary>绑定的元数据引用</summary>
|
||||
@@ -102,7 +99,8 @@ namespace XericUI.ReflectionUIGenerator
|
||||
BoundMetaData = metaData;
|
||||
CurrentValidationState = ValidationState.Normal;
|
||||
|
||||
// 子类覆写点
|
||||
// 单位可见性:无单位文本则隐藏单位节点
|
||||
ApplyUnitVisibility();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -118,8 +116,10 @@ namespace XericUI.ReflectionUIGenerator
|
||||
|
||||
// 重置 UI 文本
|
||||
if (_fieldLabelText != null) _fieldLabelText.text = "";
|
||||
if (_valueDisplayText != null) _valueDisplayText.text = "";
|
||||
if (_unitText != null) _unitText.text = "";
|
||||
|
||||
// 重置单位可见性
|
||||
if (_unitTransform != null) _unitTransform.gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
// ============ 核心绑定接口 ============
|
||||
@@ -155,34 +155,17 @@ namespace XericUI.ReflectionUIGenerator
|
||||
|
||||
/// <summary>
|
||||
/// 根据值和验证状态更新 UI 显示
|
||||
/// 子类可覆写以处理专属组件更新(Slider.value, Image.color 等)
|
||||
/// 基类负责合成标签文本、值文本颜色、单位文本
|
||||
/// 子类必须覆写以处理专属组件更新(Slider.value, Image.color 等),
|
||||
/// 并在覆写中调用 base.UpdateValueDisplay(value, state) 以刷新标签。
|
||||
/// </summary>
|
||||
protected virtual void UpdateValueDisplay(object value, ValidationState state)
|
||||
{
|
||||
// 1. 字段标签合成
|
||||
if (_fieldLabelText != null)
|
||||
{
|
||||
string label = BuildLabel(state);
|
||||
_fieldLabelText.text = label;
|
||||
}
|
||||
_fieldLabelText.text = BuildLabel(state);
|
||||
|
||||
// 2. 值显示
|
||||
if (_valueDisplayText != null)
|
||||
{
|
||||
string display = CurrentAccessor?.FormatDisplay(value) ?? value?.ToString() ?? "";
|
||||
_valueDisplayText.text = display;
|
||||
|
||||
_valueDisplayText.color = state == ValidationState.Invalid
|
||||
? Color.red
|
||||
: state == ValidationState.Warning
|
||||
? new Color(1f, 0.92f, 0.016f) // yellow
|
||||
: Color.white;
|
||||
}
|
||||
|
||||
// 3. 单位文本
|
||||
if (_unitText != null)
|
||||
_unitText.text = BoundMetaData?.UnitLabelName ?? "";
|
||||
// 2. 单位文本 + 可见性
|
||||
ApplyUnitText();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -211,6 +194,32 @@ namespace XericUI.ReflectionUIGenerator
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新单位文本并控制可见性
|
||||
/// </summary>
|
||||
protected void ApplyUnitText()
|
||||
{
|
||||
string unit = BoundMetaData?.UnitLabelName;
|
||||
bool hasUnit = !string.IsNullOrEmpty(unit);
|
||||
|
||||
if (_unitText != null)
|
||||
_unitText.text = hasUnit ? unit : "";
|
||||
|
||||
if (_unitTransform != null)
|
||||
_unitTransform.gameObject.SetActive(hasUnit);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 仅刷新单位可见性(不更新文本内容)
|
||||
/// </summary>
|
||||
protected void ApplyUnitVisibility()
|
||||
{
|
||||
if (_unitTransform == null) return;
|
||||
|
||||
string unit = BoundMetaData?.UnitLabelName;
|
||||
_unitTransform.gameObject.SetActive(!string.IsNullOrEmpty(unit));
|
||||
}
|
||||
|
||||
// ============ 验证状态回调 ============
|
||||
|
||||
/// <summary>
|
||||
@@ -224,16 +233,6 @@ namespace XericUI.ReflectionUIGenerator
|
||||
// 刷新标签文本(警告/无效标记在标签上)
|
||||
if (_fieldLabelText != null)
|
||||
_fieldLabelText.text = BuildLabel(state);
|
||||
|
||||
// 值文本颜色
|
||||
if (_valueDisplayText != null)
|
||||
{
|
||||
_valueDisplayText.color = state == ValidationState.Invalid
|
||||
? Color.red
|
||||
: state == ValidationState.Warning
|
||||
? new Color(1f, 0.92f, 0.016f)
|
||||
: Color.white;
|
||||
}
|
||||
}
|
||||
|
||||
// ============ 元数据广播 ============
|
||||
|
||||
Reference in New Issue
Block a user