2025-07-08 10:46:31 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Text.RegularExpressions;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
using UnityEngine.UI;
|
|
|
|
|
using TMPro;
|
|
|
|
|
|
|
|
|
|
namespace Superlazy.UI
|
|
|
|
|
{
|
|
|
|
|
[RequireComponent(typeof(TextMeshProUGUI), typeof(TMP_InputField))]
|
|
|
|
|
public class SLUIInputField : SLUIComponent
|
|
|
|
|
{
|
|
|
|
|
public string bindingValue;
|
|
|
|
|
public bool useChangeValue;
|
|
|
|
|
public string changeCommand;
|
|
|
|
|
public bool isNumber;
|
|
|
|
|
public SLValueComparison comparison;
|
|
|
|
|
|
|
|
|
|
[NonSerialized]
|
|
|
|
|
public TMP_InputField inputField;
|
|
|
|
|
|
|
|
|
|
private readonly string regex = @"(?:\uD83D(?:[\uDC76\uDC66\uDC67](?:\uD83C[\uDFFB-\uDFFF])?|\uDC68(?:(?:\uD83C(?:[\uDFFB-\uDFFF](?:\u200D(?:\u2695\uFE0F?|\uD83C[\uDF93\uDFEB\uDF3E\uDF73\uDFED\uDFA4\uDFA8]|\u2696\uFE0F?|\uD83D[\uDD27\uDCBC\uDD2C\uDCBB\uDE80\uDE92]|\u2708\uFE0F?|\uD83E[\uDDB0-\uDDB3]))?)|\u200D(?:\u2695\uFE0F?|\uD83C[\uDF93\uDFEB\uDF3E\uDF73\uDFED\uDFA4\uDFA8]|\u2696\uFE0F?|\uD83D(?:\uDC69\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|\uDC68\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?|[\uDD27\uDCBC\uDD2C\uDCBB\uDE80\uDE92])|\u2708\uFE0F?|\uD83E[\uDDB0-\uDDB3]|\u2764(?:\uFE0F\u200D\uD83D(?:\uDC8B\u200D\uD83D\uDC68|\uDC68)|\u200D\uD83D(?:\uDC8B\u200D\uD83D\uDC68|\uDC68)))))?|\uDC69(?:(?:\uD83C(?:[\uDFFB-\uDFFF](?:\u200D(?:\u2695\uFE0F?|\uD83C[\uDF93\uDFEB\uDF3E\uDF73\uDFED\uDFA4\uDFA8]|\u2696\uFE0F?|\uD83D[\uDD27\uDCBC\uDD2C\uDCBB\uDE80\uDE92]|\u2708\uFE0F?|\uD83E[\uDDB0-\uDDB3]))?)|\u200D(?:\u2695\uFE0F?|\uD83C[\uDF93\uDFEB\uDF3E\uDF73\uDFED\uDFA4\uDFA8]|\u2696\uFE0F?|\uD83D(?:\uDC69\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?|[\uDD27\uDCBC\uDD2C\uDCBB\uDE80\uDE92])|\u2708\uFE0F?|\uD83E[\uDDB0-\uDDB3]|\u2764(?:\uFE0F\u200D\uD83D(?:\uDC8B\u200D\uD83D[\uDC68\uDC69]|[\uDC68\uDC69])|\u200D\uD83D(?:\uDC8B\u200D\uD83D[\uDC68\uDC69]|[\uDC68\uDC69])))))?|[\uDC74\uDC75](?:\uD83C[\uDFFB-\uDFFF])?|\uDC6E(?:(?:\uD83C(?:[\uDFFB-\uDFFF](?:\u200D(?:[\u2642\u2640]\uFE0F?))?)|\u200D(?:[\u2642\u2640]\uFE0F?)))?|\uDD75(?:(?:\uFE0F(?:\u200D(?:[\u2642\u2640]\uFE0F?))?|\uD83C(?:[\uDFFB-\uDFFF](?:\u200D(?:[\u2642\u2640]\uFE0F?))?)|\u200D(?:[\u2642\u2640]\uFE0F?)))?|[\uDC82\uDC77](?:(?:\uD83C(?:[\uDFFB-\uDFFF](?:\u200D(?:[\u2642\u2640]\uFE0F?))?)|\u200D(?:[\u2642\u2640]\uFE0F?)))?|\uDC78(?:\uD83C[\uDFFB-\uDFFF])?|\uDC73(?:(?:\uD83C(?:[\uDFFB-\uDFFF](?:\u200D(?:[\u2642\u2640]\uFE0F?))?)|\u200D(?:[\u2642\u2640]\uFE0F?)))?|\uDC72(?:\uD83C[\uDFFB-\uDFFF])?|\uDC71(?:(?:\uD83C(?:[\uDFFB-\uDFFF](?:\u200D(?:[\u2642\u2640]\uFE0F?))?)|\u200D(?:[\u2642\u2640]\uFE0F?)))?|[\uDC70\uDC7C](?:\uD83C[\uDFFB-\uDFFF])?|[\uDE4D\uDE4E\uDE45\uDE46\uDC81\uDE4B\uDE47\uDC86\uDC87\uDEB6](?:(?:\uD83C(?:[\uDFFB-\uDFFF](?:\u200D(?:[\u2642\u2640]\uFE0F?))?)|\u200D(?:[\u2642\u2640]\uFE0F?)))?|[\uDC83\uDD7A](?:\uD83C[\uDFFB-\uDFFF])?|\uDC6F(?:\u200D(?:[\u2642\u2640]\uFE0F?))?|[\uDEC0\uDECC](?:\uD83C[\uDFFB-\uDFFF])?|\uDD74(?:(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F))?|\uDDE3\uFE0F?|[\uDEA3\uDEB4\uDEB5](?:(?:\uD83C(?:[\uDFFB-\uDFFF](?:\u200D(?:[\u2642\u2640]\uFE0F?))?)|\u200D(?:[\u2642\u2640]\uFE0F?)))?|[\uDCAA\uDC48\uDC49\uDC46\uDD95\uDC47\uDD96](?:\uD83C[\uDFFB-\uDFFF])?|\uDD90(?:(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F))?|[\uDC4C-\uDC4E\uDC4A\uDC4B\uDC4F\uDC50\uDE4C\uDE4F\uDC85\uDC42\uDC43](?:\uD83C[\uDFFB-\uDFFF])?|\uDC41(?:(?:\uFE0F(?:\u200D\uD83D\uDDE8\uFE0F?)?|\u200D\uD83D\uDDE8\uFE0F?))?|[\uDDE8\uDDEF\uDD73\uDD76\uDECD\uDC3F\uDD4A\uDD77\uDD78\uDDFA\uDEE3\uDEE4\uDEE2\uDEF3\uDEE5\uDEE9\uDEF0\uDECE\uDD70\uDD79\uDDBC\uDDA5\uDDA8\uDDB1\uDDB2\uDCFD\uDD6F\uDDDE\uDDF3\uDD8B\uDD8A\uDD8C\uDD8D\uDDC2\uDDD2\uDDD3\uDD87\uDDC3\uDDC4\uDDD1\uDDDD\uDEE0\uDDE1\uDEE1\uDDDC\uDECF\uDECB\uDD49]\uFE0F?|[\uDE00-\uDE06\uDE09-\uDE0B\uDE0E\uDE0D\uDE18\uDE17\uDE19\uDE1A\uDE42\uDE10\uDE11\uDE36\uDE44\uDE0F\uDE23\uDE25\uDE2E\uDE2F\uDE2A\uDE2B\uDE34\uDE0C\uDE1B-\uDE1D\uDE12-\uDE15\uDE43\uDE32\uDE41\uDE16\uDE1E\uDE1F\uDE24\uDE22\uDE2D\uDE26-\uDE29\uDE2C\uDE30\uDE31\uDE33\uDE35\uDE21\uDE20\uDE37\uDE07\uDE08\uDC7F\uDC79\uDC7A\uDC80\uDC7B\uDC7D\uDC7E\uDCA9\uDE3A\uDE38\uDE39\uDE3B-\uDE3D\uDE40\uDE3F\uDE3E\uDE48-\uDE4A\uDC64\uDC65\uDC6B-\uDC6D\uDC8F\uDC91\uDC6A\uDC63\uDC40\uDC45\uDC44\uDC8B\uDC98\uDC93-\uDC97\uDC99-\uDC9C\uDDA4\uDC9D-\uDC9F\uDC8C\uDCA4\uDCA2\uDCA3\uDCA5\uDCA6\uDCA8\uDCAB-\uDCAD\uDC53-\uDC62\uDC51\uDC52\uDCFF\uDC84\uDC8D\uDC8E\uDC35\uDC12\uDC36\uDC15\uDC29\uDC3A\uDC31\uDC08\uDC2F\uDC05\uDC06\uDC34\uDC0E\uDC2E\uDC02-\uDC04\uDC37\uDC16\uDC1
|
|
|
|
|
|
|
|
|
|
protected override void Validate()
|
|
|
|
|
{
|
|
|
|
|
inputField = GetComponent<TMP_InputField>();
|
|
|
|
|
inputField.textComponent = GetComponent<TextMeshProUGUI>();
|
|
|
|
|
inputField.textComponent.richText = false;
|
|
|
|
|
inputField.textViewport = transform.parent.GetComponent<RectTransform>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void Init()
|
|
|
|
|
{
|
|
|
|
|
// TODO: 폰트처리 관련 체크 필요
|
|
|
|
|
inputField.onValidateInput = (t, i, c) =>
|
|
|
|
|
{
|
|
|
|
|
return Regex.IsMatch(c.ToString(), regex) /*|| inputField.textComponent.font.HasCharacter(c) == false*/ ? '\0' : c;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (bindingValue != string.Empty)
|
|
|
|
|
{
|
|
|
|
|
inputField.onEndEdit.AddListener(
|
|
|
|
|
(val) =>
|
|
|
|
|
{
|
|
|
|
|
if (bindParent.Active == false) return;
|
|
|
|
|
val = Regex.Replace(val, regex, "");
|
|
|
|
|
inputField.text = val;
|
|
|
|
|
SLGame.SessionGet(bindParent.BindPath).Set(bindingValue, val);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
inputField.onEndEdit.AddListener(
|
|
|
|
|
(val) =>
|
|
|
|
|
{
|
|
|
|
|
if (bindParent.Active == false) return;
|
|
|
|
|
val = Regex.Replace(val, regex, "");
|
|
|
|
|
inputField.text = val;
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (string.IsNullOrEmpty(changeCommand) == false)
|
|
|
|
|
{
|
|
|
|
|
inputField.onValueChanged.AddListener(
|
|
|
|
|
(val) =>
|
|
|
|
|
{
|
|
|
|
|
if (bindParent.Active == false) return;
|
|
|
|
|
val = Regex.Replace(val, regex, "");
|
|
|
|
|
inputField.text = val;
|
|
|
|
|
if (isNumber)
|
|
|
|
|
{
|
|
|
|
|
if (int.TryParse(val, out var intNum))
|
|
|
|
|
{
|
|
|
|
|
SLGame.SessionGet(bindParent.BindPath).Set(bindingValue, intNum);
|
|
|
|
|
}
|
|
|
|
|
else if (double.TryParse(val, out var doubleNum))
|
|
|
|
|
{
|
|
|
|
|
SLGame.SessionGet(bindParent.BindPath).Set(bindingValue, doubleNum);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SLGame.SessionGet(bindParent.BindPath).Set(bindingValue, val);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SLGame.SessionGet(bindParent.BindPath).Set(bindingValue, val);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SLGame.Command(changeCommand, SLGame.SessionGet(bindParent.BindPath));
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
else if (bindingValue != string.Empty)
|
|
|
|
|
{
|
|
|
|
|
inputField.onValueChanged.AddListener(
|
|
|
|
|
(val) =>
|
|
|
|
|
{
|
|
|
|
|
if (bindParent.Active == false) return;
|
|
|
|
|
val = Regex.Replace(val, regex, "");
|
|
|
|
|
inputField.text = val;
|
|
|
|
|
if (isNumber)
|
|
|
|
|
{
|
|
|
|
|
if (int.TryParse(val, out var intNum))
|
|
|
|
|
{
|
|
|
|
|
SLGame.SessionGet(bindParent.BindPath).Set(bindingValue, intNum);
|
|
|
|
|
}
|
|
|
|
|
else if (double.TryParse(val, out var doubleNum))
|
|
|
|
|
{
|
|
|
|
|
SLGame.SessionGet(bindParent.BindPath).Set(bindingValue, doubleNum);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SLGame.SessionGet(bindParent.BindPath).Set(bindingValue, val);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SLGame.SessionGet(bindParent.BindPath).Set(bindingValue, val);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
inputField.onValueChanged.AddListener(
|
|
|
|
|
(val) =>
|
|
|
|
|
{
|
|
|
|
|
if (bindParent.Active == false) return;
|
|
|
|
|
val = Regex.Replace(val, regex, "");
|
|
|
|
|
inputField.text = val;
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void Enable()
|
|
|
|
|
{
|
|
|
|
|
if (bindingValue != string.Empty)
|
|
|
|
|
{
|
|
|
|
|
SLGame.AddNotify(bindParent.BindPath.CombinePath(bindingValue), OnChangeBindingValue);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (comparison.useCheckValue) comparison.OnEnable(bindParent.BindPath, OnChange);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void Disable()
|
|
|
|
|
{
|
|
|
|
|
if (bindingValue != string.Empty)
|
|
|
|
|
{
|
|
|
|
|
SLGame.RemoveNotify(bindParent.BindPath.CombinePath(bindingValue), OnChangeBindingValue);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (comparison.useCheckValue) comparison.OnDisable();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void OnChangeBindingValue()
|
|
|
|
|
{
|
|
|
|
|
if (bindParent.Active == false) return;
|
|
|
|
|
|
|
|
|
|
inputField.text = SLGame.SessionGet(bindParent.BindPath).Get(bindingValue);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void OnChange()
|
|
|
|
|
{
|
|
|
|
|
if (bindParent.Active == false) return;
|
|
|
|
|
|
|
|
|
|
var result = true;
|
|
|
|
|
if (comparison.useCheckValue)
|
|
|
|
|
{
|
|
|
|
|
result = comparison.Result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inputField.interactable = result;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|