livia-test/Livia/Views/Utility/ViewUtility.cs
2025-03-28 14:31:53 +08:00

106 lines
4.1 KiB
C#

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<string, FontFamily> DefaultFontFamilyDictionary = new();
public static readonly List<LanguageComboBoxItemViewModel> 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<ILogger>(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<T>(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<T>(object sender) where T : class
{
return (sender as FrameworkElement)?.DataContext as T;
}
}