using System.ComponentModel; using System.Windows.Data; using System.Windows.Media; using CommunityToolkit.Mvvm.ComponentModel; using CursorLang.Models; using CursorLang.Services; namespace CursorLang.ViewModels; /// Вариант выбора в списке: значение и его подпись на текущем языке. public sealed record EnumOption(T Value, string Display); /// /// Окно настроек. Значения правятся прямо в , /// поэтому подсказка подхватывает их сразу, без кнопки «Применить». /// public sealed partial class SettingsViewModel : ObservableObject, IDisposable { private static readonly Color[] Palette = [ Color.FromRgb(0x20, 0x20, 0x20), Color.FromRgb(0x00, 0x00, 0x00), Color.FromRgb(0x1E, 0x3A, 0x8A), Color.FromRgb(0x0F, 0x76, 0x6E), Color.FromRgb(0x7C, 0x2D, 0x12), Color.FromRgb(0x86, 0x19, 0x8F), Color.FromRgb(0xB9, 0x1C, 0x1C), Color.FromRgb(0xF5, 0xF5, 0xF5), ]; public SettingsViewModel(AppSettings settings, ILocalizationService localization) { Settings = settings; Localization = localization; // Язык интерфейса — такая же настройка, как остальные, и хранится там же Localization.CurrentLanguage = settings.Language; Settings.PropertyChanged += OnSettingsChanged; Localization.PropertyChanged += OnLocalizationChanged; BuildLocalizedOptions(); } public AppSettings Settings { get; } public ILocalizationService Localization { get; } public IReadOnlyList BackgroundPalette { get; } = Palette; public IReadOnlyList> PlacementModes { get; private set; } = []; public IReadOnlyList> CursorCorners { get; private set; } = []; public IReadOnlyList> ScreenPositions { get; private set; } = []; public void Dispose() { Settings.PropertyChanged -= OnSettingsChanged; Localization.PropertyChanged -= OnLocalizationChanged; } private void OnSettingsChanged(object? sender, PropertyChangedEventArgs e) { if (e.PropertyName == nameof(AppSettings.Language)) { Localization.CurrentLanguage = Settings.Language; } } // Подписи вариантов приходят из ресурсов, поэтому при смене языка // списки нужно собрать заново — привязки сами перечитают их private void OnLocalizationChanged(object? sender, PropertyChangedEventArgs e) { if (e.PropertyName == Binding.IndexerName) { BuildLocalizedOptions(); } } private void BuildLocalizedOptions() { PlacementModes = BuildOptions(nameof(PopupPlacementMode)); CursorCorners = BuildOptions(nameof(CursorCorner)); ScreenPositions = BuildOptions(nameof(ScreenPosition)); OnPropertyChanged(nameof(PlacementModes)); OnPropertyChanged(nameof(CursorCorners)); OnPropertyChanged(nameof(ScreenPositions)); } private EnumOption[] BuildOptions(string resourcePrefix) where T : struct, Enum => [.. Enum.GetValues().Select(value => new EnumOption(value, Localization[$"{resourcePrefix}_{value}"]))]; }