версия 2.0.8: выбор шрифта интерфейса в Настройках
- Настройки: выпадающий список «Шрифт» со всеми системными шрифтами (+ «По умолчанию»), с превью каждого шрифта в себе самом - шрифт применяется ко всему приложению (ресурс AppFontFamily + стиль Window), сохраняется и восстанавливается при старте Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
4e341f76c3
commit
c808d62188
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#define MyAppName "Электронная Фармация"
|
#define MyAppName "Электронная Фармация"
|
||||||
#define MyAppBrand "ЭльФиСА"
|
#define MyAppBrand "ЭльФиСА"
|
||||||
#define MyAppVersion "2.0.7"
|
#define MyAppVersion "2.0.8"
|
||||||
#define MyAppPublisher "PharmData"
|
#define MyAppPublisher "PharmData"
|
||||||
#define MyAppURL "https://cdn.24pharmdata.ru"
|
#define MyAppURL "https://cdn.24pharmdata.ru"
|
||||||
#define MyAppSupportURL "https://24pharmdata.ru"
|
#define MyAppSupportURL "https://24pharmdata.ru"
|
||||||
|
|||||||
@ -41,11 +41,18 @@
|
|||||||
<SolidColorBrush x:Key="SidebarActive" Color="#0A4A44"/>
|
<SolidColorBrush x:Key="SidebarActive" Color="#0A4A44"/>
|
||||||
<SolidColorBrush x:Key="SidebarText" Color="#D5F5F0"/>
|
<SolidColorBrush x:Key="SidebarText" Color="#D5F5F0"/>
|
||||||
<SolidColorBrush x:Key="OnAccent" Color="#FFFFFF"/>
|
<SolidColorBrush x:Key="OnAccent" Color="#FFFFFF"/>
|
||||||
|
|
||||||
|
<!-- Шрифт интерфейса. Меняется из Настроек: Resources["AppFontFamily"] = FontFamily. -->
|
||||||
|
<FontFamily x:Key="AppFontFamily">Segoe UI</FontFamily>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
</Application.Resources>
|
</Application.Resources>
|
||||||
|
|
||||||
<Application.Styles>
|
<Application.Styles>
|
||||||
<FluentTheme />
|
<FluentTheme />
|
||||||
|
<!-- Единый шрифт для всех окон (дочерние контролы наследуют). -->
|
||||||
|
<Style Selector="Window">
|
||||||
|
<Setter Property="FontFamily" Value="{DynamicResource AppFontFamily}"/>
|
||||||
|
</Style>
|
||||||
<StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml"/>
|
<StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml"/>
|
||||||
<StyleInclude Source="/Styles/Elfisa.axaml"/>
|
<StyleInclude Source="/Styles/Elfisa.axaml"/>
|
||||||
</Application.Styles>
|
</Application.Styles>
|
||||||
|
|||||||
@ -4,6 +4,7 @@ using Avalonia.Data.Core;
|
|||||||
using Avalonia.Data.Core.Plugins;
|
using Avalonia.Data.Core.Plugins;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Avalonia.Markup.Xaml;
|
using Avalonia.Markup.Xaml;
|
||||||
|
using Avalonia.Media;
|
||||||
using Elfisa.Avalonia.ViewModels;
|
using Elfisa.Avalonia.ViewModels;
|
||||||
using Elfisa.Avalonia.Views;
|
using Elfisa.Avalonia.Views;
|
||||||
|
|
||||||
@ -11,17 +12,30 @@ namespace Elfisa.Avalonia;
|
|||||||
|
|
||||||
public partial class App : Application
|
public partial class App : Application
|
||||||
{
|
{
|
||||||
|
/// <summary>Дефолтный шрифт интерфейса (когда «По умолчанию»).</summary>
|
||||||
|
public const string DefaultFont = "Segoe UI";
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
AvaloniaXamlLoader.Load(this);
|
AvaloniaXamlLoader.Load(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Применяет шрифт ко всему приложению (ресурс наследуется всеми окнами).</summary>
|
||||||
|
public static void ApplyFont(string? name)
|
||||||
|
{
|
||||||
|
var family = string.IsNullOrWhiteSpace(name) ? DefaultFont : name!;
|
||||||
|
if (Current is { } app)
|
||||||
|
app.Resources["AppFontFamily"] = new FontFamily(family);
|
||||||
|
}
|
||||||
|
|
||||||
public override void OnFrameworkInitializationCompleted()
|
public override void OnFrameworkInitializationCompleted()
|
||||||
{
|
{
|
||||||
RequestedThemeVariant = Elfisa.Core.SettingsStore.Current.Theme == "Dark"
|
RequestedThemeVariant = Elfisa.Core.SettingsStore.Current.Theme == "Dark"
|
||||||
? global::Avalonia.Styling.ThemeVariant.Dark
|
? global::Avalonia.Styling.ThemeVariant.Dark
|
||||||
: global::Avalonia.Styling.ThemeVariant.Light;
|
: global::Avalonia.Styling.ThemeVariant.Light;
|
||||||
|
|
||||||
|
ApplyFont(Elfisa.Core.SettingsStore.Current.FontFamily);
|
||||||
|
|
||||||
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||||
{
|
{
|
||||||
desktop.MainWindow = new MainWindow
|
desktop.MainWindow = new MainWindow
|
||||||
|
|||||||
@ -5,9 +5,9 @@
|
|||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||||
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
|
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
|
||||||
<Version>2.0.7</Version>
|
<Version>2.0.8</Version>
|
||||||
<AssemblyVersion>2.0.7.0</AssemblyVersion>
|
<AssemblyVersion>2.0.8.0</AssemblyVersion>
|
||||||
<FileVersion>2.0.7.0</FileVersion>
|
<FileVersion>2.0.8.0</FileVersion>
|
||||||
<Product>ЭльФиСА — Электронная Фармация</Product>
|
<Product>ЭльФиСА — Электронная Фармация</Product>
|
||||||
<Company>PharmData</Company>
|
<Company>PharmData</Company>
|
||||||
<!-- Кросс-платформенная публикация задаётся флагами CLI (RID + self-contained). -->
|
<!-- Кросс-платформенная публикация задаётся флагами CLI (RID + self-contained). -->
|
||||||
|
|||||||
@ -2,6 +2,7 @@ using System;
|
|||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Avalonia.Media;
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using Elfisa.Core;
|
using Elfisa.Core;
|
||||||
|
|
||||||
@ -11,10 +12,17 @@ public partial class SettingsViewModel : ViewModelBase
|
|||||||
{
|
{
|
||||||
private readonly ApiClient _api = new();
|
private readonly ApiClient _api = new();
|
||||||
|
|
||||||
|
/// <summary>Пункт «По умолчанию» в списке шрифтов.</summary>
|
||||||
|
public const string DefaultFontLabel = "По умолчанию";
|
||||||
|
|
||||||
[ObservableProperty] private string _apiBaseUrl = "";
|
[ObservableProperty] private string _apiBaseUrl = "";
|
||||||
public string[] Themes { get; } = { "Светлая", "Тёмная" };
|
public string[] Themes { get; } = { "Светлая", "Тёмная" };
|
||||||
[ObservableProperty] private int _themeIndex;
|
[ObservableProperty] private int _themeIndex;
|
||||||
|
|
||||||
|
/// <summary>Все системные шрифты + «По умолчанию» первым.</summary>
|
||||||
|
public ObservableCollection<string> Fonts { get; } = new();
|
||||||
|
[ObservableProperty] private string _selectedFont = DefaultFontLabel;
|
||||||
|
|
||||||
public ObservableCollection<BuyerLocationDto> Locations { get; } = new();
|
public ObservableCollection<BuyerLocationDto> Locations { get; } = new();
|
||||||
[ObservableProperty] private BuyerLocationDto? _selectedLocation;
|
[ObservableProperty] private BuyerLocationDto? _selectedLocation;
|
||||||
|
|
||||||
@ -23,6 +31,20 @@ public partial class SettingsViewModel : ViewModelBase
|
|||||||
_api.SetToken(Session.Current.Token);
|
_api.SetToken(Session.Current.Token);
|
||||||
ApiBaseUrl = SettingsStore.Current.ApiBaseUrl ?? AppConfig.DefaultApiBaseUrl;
|
ApiBaseUrl = SettingsStore.Current.ApiBaseUrl ?? AppConfig.DefaultApiBaseUrl;
|
||||||
ThemeIndex = SettingsStore.Current.Theme == "Dark" ? 1 : 0;
|
ThemeIndex = SettingsStore.Current.Theme == "Dark" ? 1 : 0;
|
||||||
|
|
||||||
|
Fonts.Add(DefaultFontLabel);
|
||||||
|
foreach (var f in FontManager.Current.SystemFonts
|
||||||
|
.Select(x => x.Name)
|
||||||
|
.Where(n => !string.IsNullOrWhiteSpace(n))
|
||||||
|
.Distinct()
|
||||||
|
.OrderBy(n => n, StringComparer.CurrentCultureIgnoreCase))
|
||||||
|
Fonts.Add(f);
|
||||||
|
|
||||||
|
var saved = SettingsStore.Current.FontFamily;
|
||||||
|
SelectedFont = !string.IsNullOrWhiteSpace(saved) && Fonts.Contains(saved!)
|
||||||
|
? saved!
|
||||||
|
: DefaultFontLabel;
|
||||||
|
|
||||||
if (Session.Current.IsAuthenticated) _ = LoadLocationsAsync();
|
if (Session.Current.IsAuthenticated) _ = LoadLocationsAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
xmlns:vm="using:Elfisa.Avalonia.ViewModels"
|
xmlns:vm="using:Elfisa.Avalonia.ViewModels"
|
||||||
x:Class="Elfisa.Avalonia.Views.SettingsWindow"
|
x:Class="Elfisa.Avalonia.Views.SettingsWindow"
|
||||||
x:DataType="vm:SettingsViewModel"
|
x:DataType="vm:SettingsViewModel"
|
||||||
Width="460" Height="440" CanResize="False"
|
Width="460" Height="520" CanResize="False"
|
||||||
WindowStartupLocation="CenterOwner"
|
WindowStartupLocation="CenterOwner"
|
||||||
Background="{DynamicResource Bg}"
|
Background="{DynamicResource Bg}"
|
||||||
Title="Настройки">
|
Title="Настройки">
|
||||||
@ -21,6 +21,18 @@
|
|||||||
<ComboBox ItemsSource="{Binding Themes}" SelectedIndex="{Binding ThemeIndex}" HorizontalAlignment="Stretch"/>
|
<ComboBox ItemsSource="{Binding Themes}" SelectedIndex="{Binding ThemeIndex}" HorizontalAlignment="Stretch"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
|
<StackPanel Spacing="6">
|
||||||
|
<TextBlock Text="Шрифт" Classes="label"/>
|
||||||
|
<ComboBox ItemsSource="{Binding Fonts}" SelectedItem="{Binding SelectedFont}"
|
||||||
|
HorizontalAlignment="Stretch" MaxDropDownHeight="360">
|
||||||
|
<ComboBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<TextBlock Text="{Binding}" FontFamily="{Binding}"/>
|
||||||
|
</DataTemplate>
|
||||||
|
</ComboBox.ItemTemplate>
|
||||||
|
</ComboBox>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
<StackPanel Spacing="6">
|
<StackPanel Spacing="6">
|
||||||
<TextBlock Text="Грузополучатель по умолчанию" Classes="label"/>
|
<TextBlock Text="Грузополучатель по умолчанию" Classes="label"/>
|
||||||
<ComboBox ItemsSource="{Binding Locations}" SelectedItem="{Binding SelectedLocation}" HorizontalAlignment="Stretch"/>
|
<ComboBox ItemsSource="{Binding Locations}" SelectedItem="{Binding SelectedLocation}" HorizontalAlignment="Stretch"/>
|
||||||
|
|||||||
@ -42,11 +42,14 @@ public partial class SettingsWindow : Window
|
|||||||
{
|
{
|
||||||
SettingsStore.Current.ApiBaseUrl = string.IsNullOrWhiteSpace(vm.ApiBaseUrl) ? null : vm.ApiBaseUrl.Trim().TrimEnd('/');
|
SettingsStore.Current.ApiBaseUrl = string.IsNullOrWhiteSpace(vm.ApiBaseUrl) ? null : vm.ApiBaseUrl.Trim().TrimEnd('/');
|
||||||
SettingsStore.Current.Theme = vm.ThemeIndex == 1 ? "Dark" : "Light";
|
SettingsStore.Current.Theme = vm.ThemeIndex == 1 ? "Dark" : "Light";
|
||||||
|
var font = vm.SelectedFont == SettingsViewModel.DefaultFontLabel ? null : vm.SelectedFont;
|
||||||
|
SettingsStore.Current.FontFamily = font;
|
||||||
SettingsStore.Current.DefaultLocationId = vm.SelectedLocation?.BuyerLocationId;
|
SettingsStore.Current.DefaultLocationId = vm.SelectedLocation?.BuyerLocationId;
|
||||||
SettingsStore.Save();
|
SettingsStore.Save();
|
||||||
|
|
||||||
if (Application.Current is { } app)
|
if (Application.Current is { } app)
|
||||||
app.RequestedThemeVariant = vm.ThemeIndex == 1 ? ThemeVariant.Dark : ThemeVariant.Light;
|
app.RequestedThemeVariant = vm.ThemeIndex == 1 ? ThemeVariant.Dark : ThemeVariant.Light;
|
||||||
|
App.ApplyFont(font); // применяем сразу ко всем окнам
|
||||||
}
|
}
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@ public sealed class AppSettings
|
|||||||
{
|
{
|
||||||
public string? ApiBaseUrl { get; set; }
|
public string? ApiBaseUrl { get; set; }
|
||||||
public string Theme { get; set; } = "Light"; // Light | Dark
|
public string Theme { get; set; } = "Light"; // Light | Dark
|
||||||
|
public string? FontFamily { get; set; } // шрифт интерфейса (null = по умолчанию)
|
||||||
public string? DefaultLocationId { get; set; }
|
public string? DefaultLocationId { get; set; }
|
||||||
public string? Token { get; set; } // сохранённая сессия
|
public string? Token { get; set; } // сохранённая сессия
|
||||||
public string? Role { get; set; }
|
public string? Role { get; set; }
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user