81 lines
3.5 KiB
C#
81 lines
3.5 KiB
C#
using System.Text.RegularExpressions;
|
||
|
||
namespace SLSUtilities.UI
|
||
{
|
||
/// <summary>
|
||
/// 将文本中的 [Token] 标记替换为 TMP <sprite> 富文本标签,
|
||
/// 用于在 TMP_Text 中内联显示按键图标。
|
||
/// <para>
|
||
/// Token 支持两种形式:
|
||
/// <list type="bullet">
|
||
/// <item><b>直接按键名</b>:[Q]、[LMB]、[ArrowDown] — 直接映射到 SpriteAsset 中的 sprite name</item>
|
||
/// <item><b>Input Action 名</b>:[Interact]、[MainWeaponPrimary] — 通过 <see cref="InputBindingResolver"/>
|
||
/// 解析为当前绑定的按键 glyph token(需先调用 <see cref="InputBindingResolver.Initialize"/>)</item>
|
||
/// </list>
|
||
/// 语法示例:
|
||
/// <list type="bullet">
|
||
/// <item>[Q]+[RMB] → Q 键 + 右键图标(+ 作为普通文本保留)</item>
|
||
/// <item>Hold [E] → "Hold " 为普通文本,E 键为图标</item>
|
||
/// <item>按 [Interact] 拾取 → 自动解析为当前绑定的按键图标</item>
|
||
/// </list>
|
||
/// </para>
|
||
/// </summary>
|
||
public static class InputGlyphParser
|
||
{
|
||
/// <summary>默认关联的 TMP SpriteAsset 名称。</summary>
|
||
public const string DefaultSpriteAsset = "InputGlyphs";
|
||
|
||
/// <summary>
|
||
/// 匹配 [Token] 模式。
|
||
/// \w+ 涵盖字母、数字、下划线,足以覆盖所有 Token 名(Q, LMB, ArrowDown, F12, Interact 等)。
|
||
/// </summary>
|
||
private static readonly Regex TokenPattern =
|
||
new Regex(@"\[(\w+)\]", RegexOptions.Compiled);
|
||
|
||
/// <summary>
|
||
/// 将文本中的 [Token] 标记解析为 TMP sprite 富文本标签。
|
||
/// 如果 <see cref="InputBindingResolver"/> 已初始化,Token 会先尝试解析为 Action 名对应的按键。
|
||
/// </summary>
|
||
/// <param name="rawText">
|
||
/// 原始文本,可包含 [Token] 标记。
|
||
/// 例如 "[Q]+[RMB]"、"Hold [E]"、"按 [Interact] 拾取"。
|
||
/// </param>
|
||
/// <param name="spriteAssetName">
|
||
/// 要引用的 TMP SpriteAsset 名称。
|
||
/// 传入 null 或空字符串时,生成不指定 asset 的短格式标签
|
||
/// (需在 TMP Settings 中配置默认 Sprite Asset)。
|
||
/// </param>
|
||
/// <returns>替换后的富文本字符串。输入为 null 或空时原样返回。</returns>
|
||
public static string Parse(string rawText, string spriteAssetName = DefaultSpriteAsset)
|
||
{
|
||
if (string.IsNullOrEmpty(rawText))
|
||
return rawText;
|
||
|
||
bool useResolver = InputBindingResolver.IsInitialized;
|
||
bool hasAssetName = !string.IsNullOrEmpty(spriteAssetName);
|
||
|
||
return TokenPattern.Replace(rawText, match =>
|
||
{
|
||
string token = match.Groups[1].Value;
|
||
|
||
// 通过 InputBindingResolver 解析 Action 名 → glyph token
|
||
string resolvedToken = useResolver
|
||
? InputBindingResolver.ResolveToken(token)
|
||
: token;
|
||
|
||
return hasAssetName
|
||
? $"<sprite=\"{spriteAssetName}\" name=\"{resolvedToken}\">"
|
||
: $"<sprite name=\"{resolvedToken}\">";
|
||
});
|
||
}
|
||
|
||
/// <summary>
|
||
/// 检查文本是否包含任何 [Token] 标记。
|
||
/// </summary>
|
||
public static bool ContainsGlyphs(string text)
|
||
{
|
||
return !string.IsNullOrEmpty(text) && TokenPattern.IsMatch(text);
|
||
}
|
||
}
|
||
}
|