- Add VCP commands for brightness (10), contrast (12), input source (60) - Fix UTF-16 encoding for monitor data parsing - Add system tray app with monitor controls - Add localization for en, es, fr, de, zh, ja, pt, it, hi - Update to .NET 9.0 - Add LICENSE and README 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
152 lines
5.0 KiB
C#
152 lines
5.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.Linq;
|
|
using System.Windows;
|
|
|
|
namespace CMM.Language
|
|
{
|
|
public class CulturesHelper
|
|
{
|
|
private bool _isFoundInstalledCultures = false;
|
|
|
|
const string LanguageFolder = "/Language;component";
|
|
const string ResourceLocalPath = "pack://application:,," + LanguageFolder;
|
|
const string LanguageFileName = "StringResources";
|
|
|
|
public List<CultureInfo> SupportedCultures { get; private set; } = new List<CultureInfo>();
|
|
|
|
public CulturesHelper() => Init();
|
|
|
|
private void Init()
|
|
{
|
|
if (!_isFoundInstalledCultures)
|
|
{
|
|
var cultureInfo = new CultureInfo("");
|
|
|
|
var Languages = GetAllLanguageResource();
|
|
|
|
GetAllLanguageResource().ForEach(file =>
|
|
{
|
|
try
|
|
{
|
|
string cultureName = file.Substring(file.IndexOf(".") + 1).Replace(".xaml", "");
|
|
|
|
cultureInfo = CultureInfo.GetCultureInfo(cultureName);
|
|
|
|
if (cultureInfo != null)
|
|
{
|
|
SupportedCultures.Add(cultureInfo);
|
|
}
|
|
}
|
|
catch (ArgumentException) { }
|
|
});
|
|
|
|
_isFoundInstalledCultures = true;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 增加Language的XMAL檔
|
|
/// </summary>
|
|
private static List<string> GetAllLanguageResource()
|
|
{
|
|
var Languages = new List<string>();
|
|
string uriPath = ResourceLocalPath + "/" + LanguageFileName;
|
|
|
|
Languages.Add(uriPath + ".en.xaml");
|
|
Languages.Add(uriPath + ".es.xaml");
|
|
Languages.Add(uriPath + ".fr.xaml");
|
|
Languages.Add(uriPath + ".de.xaml");
|
|
Languages.Add(uriPath + ".zh.xaml");
|
|
Languages.Add(uriPath + ".ja.xaml");
|
|
Languages.Add(uriPath + ".pt.xaml");
|
|
Languages.Add(uriPath + ".it.xaml");
|
|
Languages.Add(uriPath + ".hi.xaml");
|
|
|
|
return Languages;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Auto-detect and apply system language
|
|
/// </summary>
|
|
public void ApplySystemLanguage()
|
|
{
|
|
var systemCulture = CultureInfo.CurrentUICulture;
|
|
var matchedCulture = FindBestMatchingCulture(systemCulture);
|
|
ChangeCulture(matchedCulture);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Find the best matching supported culture for the given culture
|
|
/// </summary>
|
|
private CultureInfo FindBestMatchingCulture(CultureInfo culture)
|
|
{
|
|
// Try exact match first
|
|
var exactMatch = SupportedCultures.FirstOrDefault(c =>
|
|
c.Name.Equals(culture.Name, StringComparison.OrdinalIgnoreCase));
|
|
if (exactMatch != null) return exactMatch;
|
|
|
|
// Try matching by two-letter ISO language name
|
|
var languageMatch = SupportedCultures.FirstOrDefault(c =>
|
|
c.TwoLetterISOLanguageName.Equals(culture.TwoLetterISOLanguageName, StringComparison.OrdinalIgnoreCase));
|
|
if (languageMatch != null) return languageMatch;
|
|
|
|
// Default to English
|
|
return SupportedCultures.FirstOrDefault(c => c.Name == "en") ?? SupportedCultures.First();
|
|
}
|
|
|
|
public void ChangeCulture(string cultureName)
|
|
{
|
|
var cultureInfo = CultureInfo.GetCultureInfo(cultureName);
|
|
|
|
if (cultureInfo != null)
|
|
{
|
|
ChangeCulture(cultureInfo);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 切換語系
|
|
/// </summary>
|
|
public void ChangeCulture(CultureInfo culture)
|
|
{
|
|
if (SupportedCultures.Contains(culture))
|
|
{
|
|
var existsRD = Application.Current.Resources.MergedDictionaries
|
|
.Where(x => x.Source.OriginalString.StartsWith(ResourceLocalPath, StringComparison.CurrentCultureIgnoreCase) ||
|
|
x.Source.OriginalString.StartsWith(LanguageFolder, StringComparison.CurrentCultureIgnoreCase))
|
|
.FirstOrDefault();
|
|
|
|
if (existsRD == null) return;
|
|
|
|
var resourceFile = $"{ResourceLocalPath}/{LanguageFileName}.{culture.Name}.xaml";
|
|
var res = new ResourceDictionary()
|
|
{
|
|
Source = new Uri(resourceFile, UriKind.Absolute)
|
|
};
|
|
|
|
Application.Current.Resources.MergedDictionaries.Remove(existsRD);
|
|
Application.Current.Resources.MergedDictionaries.Add(res);
|
|
}
|
|
}
|
|
}
|
|
|
|
public static class Lang
|
|
{
|
|
public static string Find(string key)
|
|
{
|
|
if (Application.Current == null) return null;
|
|
|
|
try
|
|
{
|
|
return (string)Application.Current.FindResource(key);
|
|
}
|
|
catch
|
|
{
|
|
return string.Empty;
|
|
}
|
|
}
|
|
}
|
|
}
|