Files
Cielonos/Packages/dev.yarnspinner.unity/Editor/Editors/LanguagePopup.cs
SoulliesOfficial 8186f54e90 新场景,剧情
2026-06-02 12:55:39 -04:00

146 lines
4.5 KiB
C#

/*
Yarn Spinner is licensed to you under the terms found in the file LICENSE.md.
*/
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;
#nullable enable
namespace Yarn.Unity.Editor
{
public class LanguageField : BaseField<string>
{
PopupField<string?> m_Popup;
TextField m_TextField;
Dictionary<string, Culture> KnownCultures = new Dictionary<string, Culture>();
CultureInfo? DefaultCulture;
public LanguageField() : this(null, false) { }
public LanguageField(string? label, bool onlyNeutralCultures = false) : base(label, new Label() { })
{
var container = new VisualElement();
container.style.flexDirection = FlexDirection.Column;
container.style.flexGrow = 1;
Add(container);
// This is the input element instantiated for the base constructor.
KnownCultures = Cultures.GetCultures().Where(c => !onlyNeutralCultures || c.IsNeutralCulture).ToDictionary(kv => kv.Name);
DefaultCulture = System.Globalization.CultureInfo.CurrentCulture;
if (onlyNeutralCultures && DefaultCulture.IsNeutralCulture == false)
{
DefaultCulture = DefaultCulture.Parent;
}
var cultureChoices = KnownCultures.Keys.Prepend(null).ToList();
static string FormatCulture(string? cultureName)
{
if (cultureName == null)
{
return "Custom";
}
else
{
return Cultures.TryGetCulture(cultureName, out var culture)
? $"{culture.DisplayName} ({culture.Name})"
: cultureName;
}
}
m_Popup = new PopupField<string?>(null, cultureChoices, DefaultCulture.Name, FormatCulture, FormatCulture);
m_Popup.style.flexGrow = 1;
m_Popup.RegisterValueChangedCallback(OnPopupValueChanged);
container.Add(m_Popup);
m_TextField = new TextField();
m_TextField.style.flexGrow = 1;
m_TextField.RegisterValueChangedCallback(OnTextFieldValueChanged);
container.Add(m_TextField);
m_Popup.style.marginRight = 0;
m_TextField.style.marginRight = 0;
this.style.flexGrow = 1;
//m_Input.RegisterValueChangedCallback(OnValueChanged);
//m_Input2.RegisterValueChangedCallback(OnValueChanged);
}
public override string value
{
get => base.value; set
{
Debug.Log($"Language value changed from {base.value} to {value}");
base.value = value;
}
}
void OnTextFieldValueChanged(ChangeEvent<string> evt)
{
this.value = evt.newValue;
}
void OnPopupValueChanged(ChangeEvent<string?> evt)
{
if (evt.newValue != null)
{
this.value = evt.newValue;
m_TextField.style.display = DisplayStyle.None;
}
else
{
// The popup has changed to the 'custom' value; show the text field
m_TextField.style.display = DisplayStyle.Flex;
}
}
public override void SetValueWithoutNotify(string newValue)
{
m_TextField.value = newValue;
if (m_TextField.focusController?.focusedElement == m_TextField)
{
// The text field has focus; do not change its visibility
}
else
{
m_TextField.style.display = (!KnownCultures.ContainsKey(newValue) || m_Popup.value == null) ? DisplayStyle.Flex : DisplayStyle.None;
}
if (KnownCultures.ContainsKey(newValue))
{
m_Popup.SetValueWithoutNotify(newValue);
}
else
{
m_Popup.SetValueWithoutNotify(null);
}
base.SetValueWithoutNotify(newValue);
}
}
public static class LanguagePopup
{
// TODO: Remove, not needed in Unity 2022
public static T ReplaceElement<T>(VisualElement oldElement, T newElement) where T : VisualElement
{
oldElement.parent.Insert(oldElement.parent.IndexOf(oldElement) + 1, newElement);
oldElement.RemoveFromHierarchy();
return newElement;
}
}
}