using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.Localization;
using UnityEngine.Localization.Settings;
using UnityEngine.UIElements;
namespace UnityEditor.Localization.UI
{
///
/// Provides a popup menu in the GameView for changing the .
///
[InitializeOnLoad]
class GameViewLanguageMenu : PopupField
{
static List s_GameViews = new List();
static List s_Locales = new List();
static GameViewLanguageMenu()
{
EditorApplication.playModeStateChanged += PlayModeStateChanged;
if (Application.isPlaying && LocalizationSettings.HasSettings && LocalizationEditorSettings.ShowLocaleMenuInGameView)
Show();
}
public GameViewLanguageMenu() :
base(GetChoices(), 0)
{
focusable = false;
labelElement.style.minWidth = 60;
labelElement.style.maxWidth = 60;
formatListItemCallback = loc => loc == null ? "None" : loc.ToString();
formatSelectedValueCallback = loc => loc == null ? "None" : loc.ToString();
}
///
/// Enabled the menu in all GameViews.
///
public static void Show()
{
if (!LocalizationSettings.HasSettings)
return;
// Don't show if we have 0 locales and are using Addressables
if (LocalizationEditorSettings.GetLocales().Count == 0 && LocalizationSettings.AvailableLocales is LocalesProvider)
return;
LocalizationSettings.SelectedLocaleChanged += OnLanguageChanged;
var initOp = LocalizationSettings.InitializationOperation;
if (initOp.IsDone)
{
AddToolbarsToGameViews();
}
else
{
initOp.Completed += (hnd) => AddToolbarsToGameViews();
}
}
///
/// Removes the menu from all GameViews.
///
public static void Hide()
{
if (LocalizationSettings.HasSettings)
LocalizationSettings.SelectedLocaleChanged -= OnLanguageChanged;
ClearViews();
}
public override void SetValueWithoutNotify(Locale newValue)
{
var choices = GetChoices();
// If the value is not contained in the known Locales(such as null) then we add a temp entry.
if (!choices.Contains(newValue))
{
choices.Insert(0, newValue);
}
base.SetValueWithoutNotify(newValue);
}
static void PlayModeStateChanged(PlayModeStateChange obj)
{
if (obj == PlayModeStateChange.EnteredPlayMode && LocalizationSettings.HasSettings && LocalizationEditorSettings.ShowLocaleMenuInGameView)
{
Show();
}
else if (s_GameViews.Count > 0)
{
Hide();
}
}
static void ClearViews()
{
foreach (var gv in s_GameViews)
{
gv.RemoveFromHierarchy();
}
s_GameViews.Clear();
}
static void AddToolbarsToGameViews()
{
Assembly assembly = typeof(EditorWindow).Assembly;
Type type = assembly.GetType("UnityEditor.GameView");
var gameViews = UnityEngine.Resources.FindObjectsOfTypeAll(type);
ClearViews();
foreach (EditorWindow gameView in gameViews)
{
var menu = new GameViewLanguageMenu();
menu.style.backgroundImage = EditorStyles.popup.normal.background;
menu.RegisterValueChangedCallback((evt) => LocalizationSettings.SelectedLocale = evt.newValue);
menu.style.alignSelf = Align.FlexEnd;
menu.style.top = 22;
gameView.rootVisualElement.Add(menu);
menu.BringToFront();
s_GameViews.Add(menu);
}
var localeOp = LocalizationSettings.SelectedLocaleAsync;
if (!localeOp.IsDone)
{
OnLanguageChanged(localeOp.Result);
}
else
{
localeOp.Completed += op => OnLanguageChanged(op.Result);
}
}
static List GetChoices()
{
s_Locales.Clear();
s_Locales.AddRange(LocalizationSettings.AvailableLocales.Locales);
return s_Locales;
}
static void OnLanguageChanged(Locale locale)
{
foreach (var gv in s_GameViews)
{
gv.SetValueWithoutNotify(locale);
}
}
}
}