新增参数窗口按钮
新增参数窗口按钮
This commit is contained in:
parent
cf352f2a22
commit
0fca77ea9f
@ -933,16 +933,69 @@ namespace MeowmentDebugTool
|
||||
}
|
||||
else
|
||||
{
|
||||
Dictionary<string, List<Action<string>>> linkedFieldCallbacks = new Dictionary<string, List<Action<string>>>();
|
||||
List<KeyValuePair<string, string>> initialLinkedValues = new List<KeyValuePair<string, string>>();
|
||||
|
||||
foreach (ParameterInfo parameter in parameters)
|
||||
{
|
||||
Func<InputDialogValueResult> reader = CreateInputDialogField(parameter);
|
||||
if (reader == null)
|
||||
{
|
||||
Debug.LogWarning($"[MeowmentDebugTool] 暂不支持参数类型: {parameter.ParameterType.Name}");
|
||||
return;
|
||||
}
|
||||
DebugInputParameterAttribute paramAttr = parameter.GetCustomAttribute<DebugInputParameterAttribute>();
|
||||
|
||||
readers.Add(reader);
|
||||
if (paramAttr != null && paramAttr.ReadOnly)
|
||||
{
|
||||
string readOnlyLabel = !string.IsNullOrEmpty(paramAttr.Label) ? paramAttr.Label : parameter.Name;
|
||||
Func<string, string> displayProvider = ResolveDisplayValueProvider(parameter.Member.DeclaringType, paramAttr.DisplayValueProvider);
|
||||
|
||||
Func<InputDialogValueResult> readOnlyReader;
|
||||
Action<string> readOnlyUpdater;
|
||||
CreateReadOnlyDisplayField(readOnlyLabel, string.Empty, out readOnlyReader, out readOnlyUpdater);
|
||||
|
||||
if (!string.IsNullOrEmpty(paramAttr.LinkedTo))
|
||||
{
|
||||
string linkedTo = paramAttr.LinkedTo;
|
||||
if (!linkedFieldCallbacks.ContainsKey(linkedTo))
|
||||
linkedFieldCallbacks[linkedTo] = new List<Action<string>>();
|
||||
|
||||
linkedFieldCallbacks[linkedTo].Add(selectedValue =>
|
||||
{
|
||||
string displayValue = displayProvider != null ? displayProvider(selectedValue) : selectedValue;
|
||||
readOnlyUpdater(displayValue);
|
||||
});
|
||||
}
|
||||
|
||||
readers.Add(readOnlyReader);
|
||||
}
|
||||
else
|
||||
{
|
||||
string paramName = parameter.Name;
|
||||
Action<string> onSelectionChanged = selectedValue =>
|
||||
{
|
||||
if (linkedFieldCallbacks.TryGetValue(paramName, out List<Action<string>> callbacks))
|
||||
foreach (Action<string> cb in callbacks)
|
||||
cb(selectedValue);
|
||||
};
|
||||
|
||||
Func<InputDialogValueResult> reader = CreateInputDialogField(parameter, onSelectionChanged);
|
||||
if (reader == null)
|
||||
{
|
||||
Debug.LogWarning($"[MeowmentDebugTool] 暂不支持参数类型: {parameter.ParameterType.Name}");
|
||||
return;
|
||||
}
|
||||
|
||||
readers.Add(reader);
|
||||
|
||||
object defaultVal = GetParameterDefaultValue(parameter, paramAttr, out bool hasDefault);
|
||||
if (hasDefault && defaultVal != null)
|
||||
{
|
||||
initialLinkedValues.Add(new KeyValuePair<string, string>(paramName, defaultVal.ToString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<string, string> kvp in initialLinkedValues)
|
||||
{
|
||||
if (linkedFieldCallbacks.TryGetValue(kvp.Key, out List<Action<string>> callbacks))
|
||||
foreach (Action<string> cb in callbacks)
|
||||
cb(kvp.Value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1020,16 +1073,72 @@ namespace MeowmentDebugTool
|
||||
List<RuntimeDebugInputParameterDefinition> parameters = definition.Parameters ?? new List<RuntimeDebugInputParameterDefinition>();
|
||||
List<Func<InputDialogValueResult>> readers = new List<Func<InputDialogValueResult>>();
|
||||
|
||||
Dictionary<string, List<Action<string>>> linkedFieldCallbacks = new Dictionary<string, List<Action<string>>>();
|
||||
List<KeyValuePair<string, string>> initialLinkedValues = new List<KeyValuePair<string, string>>();
|
||||
|
||||
foreach (RuntimeDebugInputParameterDefinition parameter in parameters)
|
||||
{
|
||||
Func<InputDialogValueResult> reader = CreateRuntimeInputDialogField(parameter);
|
||||
if (reader == null)
|
||||
if (parameter != null && parameter.ReadOnly)
|
||||
{
|
||||
Debug.LogWarning($"[MeowmentDebugTool] 暂不支持运行时输入参数类型: {parameter?.ParameterType?.Name}");
|
||||
return;
|
||||
}
|
||||
string readOnlyLabel = string.IsNullOrEmpty(parameter.Label)
|
||||
? (string.IsNullOrEmpty(parameter.Key) ? "display" : parameter.Key)
|
||||
: parameter.Label;
|
||||
Func<string, string> displayProvider = parameter.DisplayValueProvider;
|
||||
|
||||
readers.Add(reader);
|
||||
Func<InputDialogValueResult> readOnlyReader;
|
||||
Action<string> readOnlyUpdater;
|
||||
CreateReadOnlyDisplayField(readOnlyLabel, string.Empty, out readOnlyReader, out readOnlyUpdater);
|
||||
|
||||
if (!string.IsNullOrEmpty(parameter.LinkedTo))
|
||||
{
|
||||
string linkedTo = parameter.LinkedTo;
|
||||
if (!linkedFieldCallbacks.ContainsKey(linkedTo))
|
||||
linkedFieldCallbacks[linkedTo] = new List<Action<string>>();
|
||||
|
||||
linkedFieldCallbacks[linkedTo].Add(selectedValue =>
|
||||
{
|
||||
string displayValue = displayProvider != null ? displayProvider(selectedValue) : selectedValue;
|
||||
readOnlyUpdater(displayValue);
|
||||
});
|
||||
}
|
||||
|
||||
readers.Add(readOnlyReader);
|
||||
}
|
||||
else
|
||||
{
|
||||
string paramKey = parameter != null && !string.IsNullOrEmpty(parameter.Key) ? parameter.Key : $"param{readers.Count}";
|
||||
Action<string> onSelectionChanged = selectedValue =>
|
||||
{
|
||||
if (linkedFieldCallbacks.TryGetValue(paramKey, out List<Action<string>> callbacks))
|
||||
foreach (Action<string> cb in callbacks)
|
||||
cb(selectedValue);
|
||||
};
|
||||
|
||||
Func<InputDialogValueResult> reader = CreateRuntimeInputDialogField(parameter, onSelectionChanged);
|
||||
if (reader == null)
|
||||
{
|
||||
Debug.LogWarning($"[MeowmentDebugTool] 暂不支持运行时输入参数类型: {parameter?.ParameterType?.Name}");
|
||||
return;
|
||||
}
|
||||
|
||||
readers.Add(reader);
|
||||
|
||||
if (parameter != null)
|
||||
{
|
||||
object defaultVal = GetRuntimeParameterDefaultValue(parameter, out bool hasDefault);
|
||||
if (hasDefault && defaultVal != null)
|
||||
{
|
||||
initialLinkedValues.Add(new KeyValuePair<string, string>(paramKey, defaultVal.ToString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<string, string> kvp in initialLinkedValues)
|
||||
{
|
||||
if (linkedFieldCallbacks.TryGetValue(kvp.Key, out List<Action<string>> callbacks))
|
||||
foreach (Action<string> cb in callbacks)
|
||||
cb(kvp.Value);
|
||||
}
|
||||
|
||||
inputDialogConfirmBtn.onClick.RemoveAllListeners();
|
||||
@ -1096,7 +1205,7 @@ namespace MeowmentDebugTool
|
||||
inputDialogGeneratedObjects.Clear();
|
||||
}
|
||||
|
||||
private Func<InputDialogValueResult> CreateInputDialogField(ParameterInfo parameter)
|
||||
private Func<InputDialogValueResult> CreateInputDialogField(ParameterInfo parameter, Action<string> onSelectionChanged = null)
|
||||
{
|
||||
Type parameterType = parameter.ParameterType;
|
||||
DebugInputParameterAttribute parameterAttribute = parameter.GetCustomAttribute<DebugInputParameterAttribute>();
|
||||
@ -1120,7 +1229,7 @@ namespace MeowmentDebugTool
|
||||
return () => CreateInputError(label, $"{label} 当前没有可选项");
|
||||
}
|
||||
|
||||
return CreateDynamicOptionField(fieldRoot.transform, parameterType, label, parameterAttribute, dynamicOptions, defaultValue, hasDefaultValue);
|
||||
return CreateDynamicOptionField(fieldRoot.transform, parameterType, label, parameterAttribute, dynamicOptions, defaultValue, hasDefaultValue, onSelectionChanged);
|
||||
}
|
||||
|
||||
if (parameterType == typeof(string))
|
||||
@ -1172,7 +1281,7 @@ namespace MeowmentDebugTool
|
||||
return CreateFlagsEnumField(fieldRoot.transform, parameterType, label, parameterAttribute, defaultValue, hasDefaultValue);
|
||||
}
|
||||
|
||||
return CreateEnumField(fieldRoot.transform, parameterType, label, parameterAttribute, defaultValue, hasDefaultValue);
|
||||
return CreateEnumField(fieldRoot.transform, parameterType, label, parameterAttribute, defaultValue, hasDefaultValue, onSelectionChanged);
|
||||
}
|
||||
|
||||
GameObject unsupported = CreateDialogHint(fieldRoot.transform, $"暂不支持类型: {parameterType.Name}");
|
||||
@ -1180,7 +1289,7 @@ namespace MeowmentDebugTool
|
||||
return null;
|
||||
}
|
||||
|
||||
private Func<InputDialogValueResult> CreateRuntimeInputDialogField(RuntimeDebugInputParameterDefinition parameterDefinition)
|
||||
private Func<InputDialogValueResult> CreateRuntimeInputDialogField(RuntimeDebugInputParameterDefinition parameterDefinition, Action<string> onSelectionChanged = null)
|
||||
{
|
||||
if (parameterDefinition == null || parameterDefinition.ParameterType == null)
|
||||
{
|
||||
@ -1208,7 +1317,7 @@ namespace MeowmentDebugTool
|
||||
return () => CreateInputError(label, $"{label} 当前没有可选项");
|
||||
}
|
||||
|
||||
return CreateDynamicOptionField(fieldRoot.transform, parameterType, label, parameterDefinition.Required, dynamicOptions, defaultValue, hasDefaultValue);
|
||||
return CreateDynamicOptionField(fieldRoot.transform, parameterType, label, parameterDefinition.Required, dynamicOptions, defaultValue, hasDefaultValue, onSelectionChanged);
|
||||
}
|
||||
|
||||
if (parameterType == typeof(string))
|
||||
@ -1260,7 +1369,7 @@ namespace MeowmentDebugTool
|
||||
return CreateFlagsEnumField(fieldRoot.transform, parameterType, label, parameterDefinition.Required, defaultValue, hasDefaultValue);
|
||||
}
|
||||
|
||||
return CreateEnumField(fieldRoot.transform, parameterType, label, parameterDefinition.Required, defaultValue, hasDefaultValue);
|
||||
return CreateEnumField(fieldRoot.transform, parameterType, label, parameterDefinition.Required, defaultValue, hasDefaultValue, onSelectionChanged);
|
||||
}
|
||||
|
||||
GameObject unsupported = CreateDialogHint(fieldRoot.transform, $"暂不支持类型: {parameterType.Name}");
|
||||
@ -1500,7 +1609,7 @@ namespace MeowmentDebugTool
|
||||
}
|
||||
|
||||
private Func<InputDialogValueResult> CreateDynamicOptionField(Transform parent, Type parameterType, string label,
|
||||
DebugInputParameterAttribute parameterAttribute, List<InputDialogDynamicOption> options, object defaultValue, bool hasDefaultValue)
|
||||
DebugInputParameterAttribute parameterAttribute, List<InputDialogDynamicOption> options, object defaultValue, bool hasDefaultValue, Action<string> onSelectionChanged = null)
|
||||
{
|
||||
GameObject optionContainer = new GameObject("DynamicOptions");
|
||||
optionContainer.transform.SetParent(parent, false);
|
||||
@ -1530,6 +1639,7 @@ namespace MeowmentDebugTool
|
||||
{
|
||||
selectedIndex = currentIndex;
|
||||
UpdateEnumOptionButtonStyles(buttons, selectedIndex);
|
||||
onSelectionChanged?.Invoke(currentOption.Value?.ToString() ?? string.Empty);
|
||||
});
|
||||
buttons.Add(optionButton);
|
||||
}
|
||||
@ -1558,7 +1668,7 @@ namespace MeowmentDebugTool
|
||||
}
|
||||
|
||||
private Func<InputDialogValueResult> CreateDynamicOptionField(Transform parent, Type parameterType, string label,
|
||||
bool required, List<InputDialogDynamicOption> options, object defaultValue, bool hasDefaultValue)
|
||||
bool required, List<InputDialogDynamicOption> options, object defaultValue, bool hasDefaultValue, Action<string> onSelectionChanged = null)
|
||||
{
|
||||
GameObject optionContainer = new GameObject("DynamicOptions");
|
||||
optionContainer.transform.SetParent(parent, false);
|
||||
@ -1588,6 +1698,7 @@ namespace MeowmentDebugTool
|
||||
{
|
||||
selectedIndex = currentIndex;
|
||||
UpdateEnumOptionButtonStyles(buttons, selectedIndex);
|
||||
onSelectionChanged?.Invoke(currentOption.Value?.ToString() ?? string.Empty);
|
||||
});
|
||||
buttons.Add(optionButton);
|
||||
}
|
||||
@ -1631,7 +1742,7 @@ namespace MeowmentDebugTool
|
||||
}
|
||||
|
||||
private Func<InputDialogValueResult> CreateEnumField(Transform parent, Type enumType, string label,
|
||||
DebugInputParameterAttribute parameterAttribute, object defaultValue, bool hasDefaultValue)
|
||||
DebugInputParameterAttribute parameterAttribute, object defaultValue, bool hasDefaultValue, Action<string> onSelectionChanged = null)
|
||||
{
|
||||
GameObject optionContainer = new GameObject("Options");
|
||||
optionContainer.transform.SetParent(parent, false);
|
||||
@ -1658,6 +1769,7 @@ namespace MeowmentDebugTool
|
||||
{
|
||||
selectedIndex = currentIndex;
|
||||
UpdateEnumOptionButtonStyles(buttons, selectedIndex);
|
||||
onSelectionChanged?.Invoke(optionValue.ToString());
|
||||
});
|
||||
buttons.Add(optionButton);
|
||||
}
|
||||
@ -1685,7 +1797,7 @@ namespace MeowmentDebugTool
|
||||
}
|
||||
|
||||
private Func<InputDialogValueResult> CreateEnumField(Transform parent, Type enumType, string label,
|
||||
bool required, object defaultValue, bool hasDefaultValue)
|
||||
bool required, object defaultValue, bool hasDefaultValue, Action<string> onSelectionChanged = null)
|
||||
{
|
||||
GameObject optionContainer = new GameObject("Options");
|
||||
optionContainer.transform.SetParent(parent, false);
|
||||
@ -1712,6 +1824,7 @@ namespace MeowmentDebugTool
|
||||
{
|
||||
selectedIndex = currentIndex;
|
||||
UpdateEnumOptionButtonStyles(buttons, selectedIndex);
|
||||
onSelectionChanged?.Invoke(optionValue.ToString());
|
||||
});
|
||||
buttons.Add(optionButton);
|
||||
}
|
||||
@ -2004,6 +2117,76 @@ namespace MeowmentDebugTool
|
||||
};
|
||||
}
|
||||
|
||||
private void CreateReadOnlyDisplayField(string label, string initialValue, out Func<InputDialogValueResult> reader, out Action<string> updater)
|
||||
{
|
||||
GameObject fieldRoot = CreateInputFieldRoot(label, false);
|
||||
inputDialogGeneratedObjects.Add(fieldRoot);
|
||||
|
||||
GameObject displayObj = new GameObject("ReadOnlyDisplay");
|
||||
displayObj.transform.SetParent(fieldRoot.transform, false);
|
||||
|
||||
Image displayBg = displayObj.AddComponent<Image>();
|
||||
displayBg.color = new Color(0.14f, 0.14f, 0.14f, 1f);
|
||||
|
||||
LayoutElement layoutEl = displayObj.AddComponent<LayoutElement>();
|
||||
layoutEl.preferredHeight = 64f;
|
||||
layoutEl.flexibleWidth = 1f;
|
||||
|
||||
GameObject textContainer = new GameObject("TextContainer");
|
||||
textContainer.transform.SetParent(displayObj.transform, false);
|
||||
RectTransform containerRect = textContainer.AddComponent<RectTransform>();
|
||||
containerRect.anchorMin = Vector2.zero;
|
||||
containerRect.anchorMax = Vector2.one;
|
||||
containerRect.offsetMin = new Vector2(20, 0);
|
||||
containerRect.offsetMax = new Vector2(-20, 0);
|
||||
|
||||
TextMeshProUGUI displayText = textContainer.AddComponent<TextMeshProUGUI>();
|
||||
displayText.text = string.IsNullOrEmpty(initialValue) ? "—" : initialValue;
|
||||
displayText.fontSize = 28;
|
||||
displayText.color = new Color(1f, 1f, 1f, 0.6f);
|
||||
displayText.alignment = TextAlignmentOptions.MidlineLeft;
|
||||
ApplySavedFont(displayText);
|
||||
|
||||
string currentValue = initialValue ?? string.Empty;
|
||||
|
||||
reader = () => new InputDialogValueResult { Success = true, Value = currentValue };
|
||||
|
||||
updater = value =>
|
||||
{
|
||||
currentValue = value ?? string.Empty;
|
||||
displayText.text = string.IsNullOrEmpty(value) ? "—" : value;
|
||||
};
|
||||
}
|
||||
|
||||
private Func<string, string> ResolveDisplayValueProvider(Type declaringType, string methodName)
|
||||
{
|
||||
if (declaringType == null || string.IsNullOrEmpty(methodName))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
MethodInfo method = declaringType.GetMethod(
|
||||
methodName,
|
||||
BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic,
|
||||
null,
|
||||
new Type[] { typeof(string) },
|
||||
null);
|
||||
|
||||
if (method == null)
|
||||
{
|
||||
Debug.LogWarning($"[MeowmentDebugTool] 未找到显示值提供方法: {declaringType.Name}.{methodName}(string)");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (method.ReturnType != typeof(string))
|
||||
{
|
||||
Debug.LogWarning($"[MeowmentDebugTool] 显示值提供方法 {methodName} 必须返回 string");
|
||||
return null;
|
||||
}
|
||||
|
||||
return selectedValue => method.Invoke(null, new object[] { selectedValue }) as string ?? string.Empty;
|
||||
}
|
||||
|
||||
private GameObject CreateInputFieldRoot(string label, bool required)
|
||||
{
|
||||
GameObject fieldRoot = new GameObject($"Field_{label}");
|
||||
@ -2634,6 +2817,9 @@ public class DebugInputParameterAttribute : Attribute
|
||||
public bool Required { get; set; }
|
||||
public float Min { get; set; } = float.NaN;
|
||||
public float Max { get; set; } = float.NaN;
|
||||
public bool ReadOnly { get; set; }
|
||||
public string LinkedTo { get; set; }
|
||||
public string DisplayValueProvider { get; set; }
|
||||
|
||||
public DebugInputParameterAttribute(string label = "")
|
||||
{
|
||||
@ -2642,6 +2828,8 @@ public class DebugInputParameterAttribute : Attribute
|
||||
DefaultValue = string.Empty;
|
||||
OptionsProvider = string.Empty;
|
||||
Required = false;
|
||||
LinkedTo = string.Empty;
|
||||
DisplayValueProvider = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2694,6 +2882,9 @@ public class RuntimeDebugInputParameterDefinition
|
||||
public float Min { get; set; } = float.NaN;
|
||||
public float Max { get; set; } = float.NaN;
|
||||
public Func<IEnumerable> OptionsProvider { get; set; }
|
||||
public bool ReadOnly { get; set; }
|
||||
public string LinkedTo { get; set; }
|
||||
public Func<string, string> DisplayValueProvider { get; set; }
|
||||
|
||||
public RuntimeDebugInputParameterDefinition(string key, Type parameterType, string label = "")
|
||||
{
|
||||
@ -2703,6 +2894,7 @@ public class RuntimeDebugInputParameterDefinition
|
||||
Placeholder = string.Empty;
|
||||
DefaultValue = string.Empty;
|
||||
Required = false;
|
||||
LinkedTo = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "com.bywaystudios.meowmentdebugtool",
|
||||
"displayName": "MeowmentDebugTool",
|
||||
"version": "0.5.2",
|
||||
"version": "0.5.3",
|
||||
"description": "\u8c03\u8bd5\u5de5\u5177\uff0c\u96c6\u6210\u4e86\u5ba2\u6237\u7aef\u6d4b\u8bd5\u65f6\u7684\u5e38\u7528\u529f\u80fd\uff0c\u652f\u6301\u6269\u5c55\u81ea\u5b9a\u4e49\u6309\u94ae\uff0c\u65b9\u4fbf\u5f00\u53d1\u8005\u8c03\u8bd5\u548c\u6d4b\u8bd5\u3002",
|
||||
"samples": [
|
||||
{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user