using System.Globalization; using System.Windows; using System.Windows.Markup; using System.Windows.Media; using Livia.Properties; using Livia.Utility.DependencyInjection; using Livia.ViewModels; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; namespace Livia.Views.Utility; public static class ViewUtility { //default language font for each language, this is needed to properly display the name of each language in settings window. public static readonly Dictionary DefaultFontFamilyDictionary = new(); public static readonly List LanguageList = []; static ViewUtility() { LanguageList.Add(new LanguageComboBoxItemViewModel("中文", "zh-CN", "Source Han Sans SC VF")); LanguageList.Add(new LanguageComboBoxItemViewModel("English", "en-US", "Source Han Sans SC VF")); LoadFonts(); //if culture is unset, set it to system default if (Settings.Default.CultureInfo == "") { string currentTag = CultureInfo.CurrentCulture.IetfLanguageTag; //special case here if (currentTag == "zh-CN") currentTag = "zh-Hans-CN"; Settings.Default.CultureInfo = currentTag; } else { CultureInfo cultureInfo = new(Settings.Default.CultureInfo); Thread.CurrentThread.CurrentCulture = cultureInfo; Thread.CurrentThread.CurrentUICulture = cultureInfo; } //this will set up proper locale for UI elements, e.g. date picker FrameworkElement.LanguageProperty.OverrideMetadata(typeof(FrameworkElement), new FrameworkPropertyMetadata(XmlLanguage.GetLanguage(Settings.Default.CultureInfo))); foreach (LanguageComboBoxItemViewModel viewModel in LanguageList.Where(viewModel => viewModel.Id == Settings.Default.Language)) { ViewSettings.Default.FontFamily = viewModel.DefaultFont; break; } } public static void LoadFonts() { ILogger logger = ActivatorUtilities.GetServiceOrCreateInstance(ServiceProviderFactory.ServiceProvider); DefaultFontFamilyDictionary.Clear(); foreach (FontFamily fontFamily in Fonts.GetFontFamilies(new Uri("pack://application:,,,/Livia;component/Resources/Fonts/"), "")) { logger.LogInformation($"Font found from resource: {fontFamily.Source}"); //check if it is a default font for some language foreach (LanguageComboBoxItemViewModel language in LanguageList.Where(language => fontFamily.FamilyNames.Select(familyName => familyName.Value).Contains(language.DefaultFont))) { logger.LogInformation($"Using {fontFamily.Source} for {language.Id}"); DefaultFontFamilyDictionary.Add(language.Id, fontFamily); } } foreach (FontFamily fontFamily in Fonts.SystemFontFamilies) { //check if it is a default font for some language foreach (LanguageComboBoxItemViewModel language in LanguageList.Where(language => fontFamily.Source == language.DefaultFont)) { if (DefaultFontFamilyDictionary.TryAdd(language.Id, fontFamily)) { logger.LogInformation($"Using {fontFamily.Source} for {language.Id}"); } } } } public static void SetDefaultFont(string language) { LanguageComboBoxItemViewModel? findResult = LanguageList.Find(viewModel => viewModel.Id == language); if (findResult == null) return; ViewSettings.Default.FontFamily = findResult.DefaultFont; } public static bool WindowExists(out T? target) where T : Window { foreach (Window window in Application.Current.Windows) { if (window is not T window1) continue; target = window1; return true; } target = null; return false; } public static T? GetDataContextFromSender(object sender) where T : class { return (sender as FrameworkElement)?.DataContext as T; } }