settings_re7

This commit is contained in:
lincube
2026-03-14 16:38:56 +08:00
parent 8d4f00efcb
commit 91f9f3d6fb
14 changed files with 370 additions and 60 deletions

View File

@@ -13,7 +13,7 @@
<TextBlock x:Name="TextElement" <TextBlock x:Name="TextElement"
Foreground="{DynamicResource AdaptiveTextPrimaryBrush}" Foreground="{DynamicResource AdaptiveTextPrimaryBrush}"
FontSize="14" FontSize="14"
FontWeight="Medium" FontWeight="SemiBold"
VerticalAlignment="Center" /> VerticalAlignment="Center" />
</StackPanel> </StackPanel>
</UserControl> </UserControl>

View File

@@ -32,9 +32,14 @@
"settings.wallpaper.title": "壁纸", "settings.wallpaper.title": "壁纸",
"settings.wallpaper.description": "选择图片或视频后可立即设为应用窗口壁纸。", "settings.wallpaper.description": "选择图片或视频后可立即设为应用窗口壁纸。",
"settings.wallpaper.current_label": "当前壁纸", "settings.wallpaper.current_label": "当前壁纸",
"settings.wallpaper.type_label": "壁纸类型",
"settings.wallpaper.type.image": "图片",
"settings.wallpaper.type.video": "视频",
"settings.wallpaper.type.solid_color": "纯色",
"settings.wallpaper.color_label": "壁纸颜色",
"settings.wallpaper.placement_label": "显示方式", "settings.wallpaper.placement_label": "显示方式",
"settings.wallpaper.placement_desc": "调整图像在桌面上的填充方式。", "settings.wallpaper.placement_desc": "调整图像在桌面上的填充方式。",
"settings.wallpaper.pick_button": "浏览文件", "settings.wallpaper.pick_button": "选择文件",
"settings.wallpaper.clear_button": "恢复纯色", "settings.wallpaper.clear_button": "恢复纯色",
"settings.wallpaper.no_selection": "未选择壁纸。", "settings.wallpaper.no_selection": "未选择壁纸。",
"settings.wallpaper.storage_unavailable": "存储提供器不可用。", "settings.wallpaper.storage_unavailable": "存储提供器不可用。",
@@ -245,8 +250,8 @@
"settings.status_bar.clock_format_label": "时钟格式", "settings.status_bar.clock_format_label": "时钟格式",
"settings.status_bar.clock_format.hm": "时:分", "settings.status_bar.clock_format.hm": "时:分",
"settings.status_bar.clock_format.hms": "时:分:秒", "settings.status_bar.clock_format.hms": "时:分:秒",
"settings.components.title": "组件", "settings.components.title": "网格",
"settings.components.description": "调整桌面网格与组件摆放密度。", "settings.components.description": "调整桌面网格与布局。",
"settings.components.grid_header": "网格布局", "settings.components.grid_header": "网格布局",
"settings.update.title": "更新", "settings.update.title": "更新",
"settings.update.current_version_label": "当前版本", "settings.update.current_version_label": "当前版本",

View File

@@ -18,6 +18,10 @@ public sealed class AppSettingsSnapshot
public string? WallpaperPath { get; set; } public string? WallpaperPath { get; set; }
public string WallpaperType { get; set; } = "Image";
public string? WallpaperColor { get; set; }
public string WallpaperPlacement { get; set; } = "Fill"; public string WallpaperPlacement { get; set; } = "Fill";
public int SettingsTabIndex { get; set; } = 0; public int SettingsTabIndex { get; set; } = 0;

View File

@@ -15,7 +15,7 @@ public enum WallpaperMediaType
} }
public sealed record GridSettingsState(int ShortSideCells, string SpacingPreset, int EdgeInsetPercent); public sealed record GridSettingsState(int ShortSideCells, string SpacingPreset, int EdgeInsetPercent);
public sealed record WallpaperSettingsState(string? WallpaperPath, string Placement); public sealed record WallpaperSettingsState(string? WallpaperPath, string Type, string? Color, string Placement);
public sealed record ThemeAppearanceSettingsState(bool IsNightMode, string? ThemeColor, bool UseSystemChrome); public sealed record ThemeAppearanceSettingsState(bool IsNightMode, string? ThemeColor, bool UseSystemChrome);
public sealed record StatusBarSettingsState( public sealed record StatusBarSettingsState(
IReadOnlyList<string> TopStatusComponentIds, IReadOnlyList<string> TopStatusComponentIds,

View File

@@ -91,13 +91,19 @@ internal sealed class WallpaperSettingsService : IWallpaperSettingsService
public WallpaperSettingsState Get() public WallpaperSettingsState Get()
{ {
var snapshot = _settingsService.Load(); var snapshot = _settingsService.Load();
return new WallpaperSettingsState(snapshot.WallpaperPath, snapshot.WallpaperPlacement); return new WallpaperSettingsState(
snapshot.WallpaperPath,
snapshot.WallpaperType ?? "Image",
snapshot.WallpaperColor,
snapshot.WallpaperPlacement);
} }
public void Save(WallpaperSettingsState state) public void Save(WallpaperSettingsState state)
{ {
var snapshot = _settingsService.Load(); var snapshot = _settingsService.Load();
snapshot.WallpaperPath = state.WallpaperPath; snapshot.WallpaperPath = state.WallpaperPath;
snapshot.WallpaperType = state.Type;
snapshot.WallpaperColor = state.Color;
snapshot.WallpaperPlacement = string.IsNullOrWhiteSpace(state.Placement) snapshot.WallpaperPlacement = string.IsNullOrWhiteSpace(state.Placement)
? "Fill" ? "Fill"
: state.Placement.Trim(); : state.Placement.Trim();
@@ -107,6 +113,8 @@ internal sealed class WallpaperSettingsService : IWallpaperSettingsService
changedKeys: changedKeys:
[ [
nameof(AppSettingsSnapshot.WallpaperPath), nameof(AppSettingsSnapshot.WallpaperPath),
nameof(AppSettingsSnapshot.WallpaperType),
nameof(AppSettingsSnapshot.WallpaperColor),
nameof(AppSettingsSnapshot.WallpaperPlacement) nameof(AppSettingsSnapshot.WallpaperPlacement)
]); ]);
} }

View File

@@ -412,6 +412,19 @@ public sealed partial class AppearanceSettingsPageViewModel : ViewModelBase
[ObservableProperty] [ObservableProperty]
private string _themeColor = string.Empty; private string _themeColor = string.Empty;
[ObservableProperty]
private Color _themeColorPickerValue;
partial void OnThemeColorPickerValueChanged(Color value)
{
if (_isInitializing)
{
return;
}
ThemeColor = value.ToString();
}
[ObservableProperty] [ObservableProperty]
private bool _useSystemChrome; private bool _useSystemChrome;
@@ -474,6 +487,14 @@ public sealed partial class AppearanceSettingsPageViewModel : ViewModelBase
var theme = _settingsFacade.Theme.Get(); var theme = _settingsFacade.Theme.Get();
IsNightMode = theme.IsNightMode; IsNightMode = theme.IsNightMode;
ThemeColor = theme.ThemeColor ?? string.Empty; ThemeColor = theme.ThemeColor ?? string.Empty;
if (Color.TryParse(ThemeColor, out var color))
{
ThemeColorPickerValue = color;
}
else
{
ThemeColorPickerValue = Color.Parse("#FF3B82F6");
}
UseSystemChrome = theme.UseSystemChrome; UseSystemChrome = theme.UseSystemChrome;
var wallpaper = _settingsFacade.Wallpaper.Get(); var wallpaper = _settingsFacade.Wallpaper.Get();
@@ -588,8 +609,11 @@ public sealed partial class AppearanceSettingsPageViewModel : ViewModelBase
private void SaveWallpaper() private void SaveWallpaper()
{ {
var current = _settingsFacade.Wallpaper.Get();
_settingsFacade.Wallpaper.Save(new WallpaperSettingsState( _settingsFacade.Wallpaper.Save(new WallpaperSettingsState(
string.IsNullOrWhiteSpace(WallpaperPath) ? null : WallpaperPath, string.IsNullOrWhiteSpace(WallpaperPath) ? null : WallpaperPath,
current.Type,
current.Color,
SelectedWallpaperPlacement.Value)); SelectedWallpaperPlacement.Value));
} }

View File

@@ -1,7 +1,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Avalonia.Media;
using Avalonia.Media.Imaging;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using LanMountainDesktop.Services; using LanMountainDesktop.Services;
using LanMountainDesktop.Services.Settings; using LanMountainDesktop.Services.Settings;
@@ -19,6 +24,8 @@ public sealed partial class WallpaperSettingsPageViewModel : ViewModelBase
_settingsFacade = settingsFacade; _settingsFacade = settingsFacade;
_languageCode = _localizationService.NormalizeLanguageCode(_settingsFacade.Region.Get().LanguageCode); _languageCode = _localizationService.NormalizeLanguageCode(_settingsFacade.Region.Get().LanguageCode);
WallpaperPlacements = CreateWallpaperPlacements(); WallpaperPlacements = CreateWallpaperPlacements();
WallpaperTypes = CreateWallpaperTypes();
PresetColors = CreatePresetColors();
RefreshLocalizedText(); RefreshLocalizedText();
_isInitializing = true; _isInitializing = true;
@@ -27,41 +34,90 @@ public sealed partial class WallpaperSettingsPageViewModel : ViewModelBase
} }
public IReadOnlyList<SelectionOption> WallpaperPlacements { get; } public IReadOnlyList<SelectionOption> WallpaperPlacements { get; }
public IReadOnlyList<SelectionOption> WallpaperTypes { get; }
public IReadOnlyList<string> PresetColors { get; }
[CommunityToolkit.Mvvm.ComponentModel.ObservableProperty] [ObservableProperty]
private string _wallpaperPath = string.Empty; private string _wallpaperPath = string.Empty;
[CommunityToolkit.Mvvm.ComponentModel.ObservableProperty] [ObservableProperty]
private SelectionOption _selectedWallpaperPlacement = new("Fill", "Fill"); private SelectionOption _selectedWallpaperType = null!;
[CommunityToolkit.Mvvm.ComponentModel.ObservableProperty] [ObservableProperty]
private string? _selectedColor;
[ObservableProperty]
private SelectionOption _selectedWallpaperPlacement = null!;
[ObservableProperty]
private string _wallpaperHeader = string.Empty; private string _wallpaperHeader = string.Empty;
[CommunityToolkit.Mvvm.ComponentModel.ObservableProperty] [ObservableProperty]
private string _wallpaperTypeLabel = string.Empty;
[ObservableProperty]
private string _wallpaperPathLabel = string.Empty; private string _wallpaperPathLabel = string.Empty;
[CommunityToolkit.Mvvm.ComponentModel.ObservableProperty] [ObservableProperty]
private string _wallpaperColorLabel = string.Empty;
[ObservableProperty]
private string _wallpaperPlacementLabel = string.Empty; private string _wallpaperPlacementLabel = string.Empty;
[CommunityToolkit.Mvvm.ComponentModel.ObservableProperty] [ObservableProperty]
private string _wallpaperPlacementDescription = string.Empty; private string _wallpaperPlacementDescription = string.Empty;
[CommunityToolkit.Mvvm.ComponentModel.ObservableProperty] [ObservableProperty]
private string _importWallpaperButtonText = string.Empty; private string _importWallpaperButtonText = string.Empty;
[CommunityToolkit.Mvvm.ComponentModel.ObservableProperty] [ObservableProperty]
private string _filePickerTitle = string.Empty; private string _filePickerTitle = string.Empty;
[ObservableProperty]
private bool _isImageOrVideo;
[ObservableProperty]
private bool _isSolidColor;
[ObservableProperty]
private Bitmap? _previewImage;
public void Load() public void Load()
{ {
var wallpaper = _settingsFacade.Wallpaper.Get(); var wallpaper = _settingsFacade.Wallpaper.Get();
WallpaperPath = wallpaper.WallpaperPath ?? string.Empty; WallpaperPath = wallpaper.WallpaperPath ?? string.Empty;
SelectedWallpaperType = WallpaperTypes.FirstOrDefault(t => t.Value == wallpaper.Type) ?? WallpaperTypes[0];
SelectedColor = wallpaper.Color ?? PresetColors[0];
var wallpaperPlacement = string.IsNullOrWhiteSpace(wallpaper.Placement) var wallpaperPlacement = string.IsNullOrWhiteSpace(wallpaper.Placement)
? "Fill" ? "Fill"
: wallpaper.Placement; : wallpaper.Placement;
SelectedWallpaperPlacement = WallpaperPlacements.FirstOrDefault(option => SelectedWallpaperPlacement = WallpaperPlacements.FirstOrDefault(option =>
string.Equals(option.Value, wallpaperPlacement, StringComparison.OrdinalIgnoreCase)) string.Equals(option.Value, wallpaperPlacement, StringComparison.OrdinalIgnoreCase))
?? WallpaperPlacements[0]; ?? WallpaperPlacements[0];
UpdateVisibility();
UpdatePreviewImage(WallpaperPath);
}
partial void OnSelectedWallpaperTypeChanged(SelectionOption value)
{
UpdateVisibility();
if (_isInitializing) return;
SaveWallpaper();
}
private void UpdateVisibility()
{
IsImageOrVideo = SelectedWallpaperType?.Value is "Image" or "Video";
IsSolidColor = SelectedWallpaperType?.Value == "SolidColor";
}
partial void OnSelectedColorChanged(string? value)
{
if (_isInitializing) return;
SaveWallpaper();
} }
public async Task ImportWallpaperAsync(string sourcePath) public async Task ImportWallpaperAsync(string sourcePath)
@@ -75,28 +131,48 @@ public sealed partial class WallpaperSettingsPageViewModel : ViewModelBase
partial void OnWallpaperPathChanged(string value) partial void OnWallpaperPathChanged(string value)
{ {
if (_isInitializing) UpdatePreviewImage(value);
if (_isInitializing) return;
SaveWallpaper();
}
private void UpdatePreviewImage(string path)
{
if (string.IsNullOrWhiteSpace(path) || !System.IO.File.Exists(path))
{ {
PreviewImage = null;
return; return;
} }
SaveWallpaper(); try
{
using var stream = System.IO.File.OpenRead(path);
PreviewImage = new Bitmap(stream);
}
catch
{
PreviewImage = null;
}
} }
partial void OnSelectedWallpaperPlacementChanged(SelectionOption value) partial void OnSelectedWallpaperPlacementChanged(SelectionOption value)
{ {
if (_isInitializing || value is null) if (_isInitializing || value is null) return;
{
return;
}
SaveWallpaper(); SaveWallpaper();
} }
[RelayCommand]
private void SelectColor(string color)
{
SelectedColor = color;
}
private void SaveWallpaper() private void SaveWallpaper()
{ {
_settingsFacade.Wallpaper.Save(new WallpaperSettingsState( _settingsFacade.Wallpaper.Save(new WallpaperSettingsState(
string.IsNullOrWhiteSpace(WallpaperPath) ? null : WallpaperPath, string.IsNullOrWhiteSpace(WallpaperPath) ? null : WallpaperPath,
SelectedWallpaperType.Value,
SelectedColor,
SelectedWallpaperPlacement.Value)); SelectedWallpaperPlacement.Value));
} }
@@ -112,10 +188,32 @@ public sealed partial class WallpaperSettingsPageViewModel : ViewModelBase
]; ];
} }
private IReadOnlyList<SelectionOption> CreateWallpaperTypes()
{
return
[
new SelectionOption("Image", L("settings.wallpaper.type.image", "Image")),
new SelectionOption("Video", L("settings.wallpaper.type.video", "Video")),
new SelectionOption("SolidColor", L("settings.wallpaper.type.solid_color", "Solid Color"))
];
}
private IReadOnlyList<string> CreatePresetColors()
{
return
[
"#D8A7B1", "#B6C9BB", "#A2B5BB", "#E6E2D3",
"#B5A397", "#C5C1C0", "#D4BE8D", "#C08261",
"#8E9775", "#9FBAD3", "#E5BAA2", "#4E596F"
];
}
private void RefreshLocalizedText() private void RefreshLocalizedText()
{ {
WallpaperHeader = L("settings.wallpaper.title", "Wallpaper"); WallpaperHeader = L("settings.wallpaper.title", "Wallpaper");
WallpaperTypeLabel = L("settings.wallpaper.type_label", "Wallpaper Type");
WallpaperPathLabel = L("settings.wallpaper.current_label", "Current Wallpaper"); WallpaperPathLabel = L("settings.wallpaper.current_label", "Current Wallpaper");
WallpaperColorLabel = L("settings.wallpaper.color_label", "Wallpaper Color");
WallpaperPlacementLabel = L("settings.wallpaper.placement_label", "Placement"); WallpaperPlacementLabel = L("settings.wallpaper.placement_label", "Placement");
WallpaperPlacementDescription = L("settings.wallpaper.placement_desc", "Adjust how the image fills the desktop."); WallpaperPlacementDescription = L("settings.wallpaper.placement_desc", "Adjust how the image fills the desktop.");
ImportWallpaperButtonText = L("settings.wallpaper.pick_button", "Import Wallpaper"); ImportWallpaperButtonText = L("settings.wallpaper.pick_button", "Import Wallpaper");

View File

@@ -15,6 +15,8 @@ using LanMountainDesktop.PluginSdk;
using LanMountainDesktop.Services; using LanMountainDesktop.Services;
using LanMountainDesktop.Theme; using LanMountainDesktop.Theme;
using LanMountainDesktop.Views.Components; using LanMountainDesktop.Views.Components;
using LibVLCSharp.Shared;
using LibVLCSharp.Avalonia;
namespace LanMountainDesktop.Views; namespace LanMountainDesktop.Views;
@@ -218,13 +220,24 @@ public partial class MainWindow
_defaultDesktopBackground = GetThemeBrush("AdaptiveSurfaceBaseBrush"); _defaultDesktopBackground = GetThemeBrush("AdaptiveSurfaceBaseBrush");
} }
private void TryRestoreWallpaper(string? savedWallpaperPath) private void TryRestoreWallpaper(string? savedWallpaperPath, string? type = null, string? color = null)
{ {
_wallpaperPath = string.IsNullOrWhiteSpace(savedWallpaperPath) ? null : savedWallpaperPath; _wallpaperPath = string.IsNullOrWhiteSpace(savedWallpaperPath) ? null : savedWallpaperPath;
_wallpaperType = type ?? "Image";
if (TryParseColor(color, out var parsedColor))
{
_wallpaperSolidColor = parsedColor;
}
_wallpaperBitmap?.Dispose(); _wallpaperBitmap?.Dispose();
_wallpaperBitmap = null; _wallpaperBitmap = null;
if (_wallpaperType == "SolidColor")
{
_wallpaperMediaType = WallpaperMediaType.SolidColor;
return;
}
if (string.IsNullOrWhiteSpace(_wallpaperPath) || !File.Exists(_wallpaperPath)) if (string.IsNullOrWhiteSpace(_wallpaperPath) || !File.Exists(_wallpaperPath))
{ {
_wallpaperMediaType = WallpaperMediaType.None; _wallpaperMediaType = WallpaperMediaType.None;
@@ -232,7 +245,7 @@ public partial class MainWindow
} }
var extension = Path.GetExtension(_wallpaperPath); var extension = Path.GetExtension(_wallpaperPath);
if (SupportedVideoExtensions.Contains(extension)) if (SupportedVideoExtensions.Contains(extension) || _wallpaperType == "Video")
{ {
_wallpaperMediaType = WallpaperMediaType.Video; _wallpaperMediaType = WallpaperMediaType.Video;
_wallpaperVideoPath = _wallpaperPath; _wallpaperVideoPath = _wallpaperPath;
@@ -263,6 +276,12 @@ public partial class MainWindow
private void ApplyWallpaperBrush() private void ApplyWallpaperBrush()
{ {
if (_wallpaperMediaType == WallpaperMediaType.SolidColor && _wallpaperSolidColor.HasValue)
{
DesktopWallpaperLayer.Background = new SolidColorBrush(_wallpaperSolidColor.Value);
return;
}
if (_wallpaperMediaType == WallpaperMediaType.Image && _wallpaperBitmap is not null) if (_wallpaperMediaType == WallpaperMediaType.Image && _wallpaperBitmap is not null)
{ {
DesktopWallpaperLayer.Background = new ImageBrush(_wallpaperBitmap) DesktopWallpaperLayer.Background = new ImageBrush(_wallpaperBitmap)
@@ -277,16 +296,65 @@ public partial class MainWindow
private void UpdateWallpaperDisplay() private void UpdateWallpaperDisplay()
{ {
if (_wallpaperMediaType == WallpaperMediaType.Video)
{
if (!string.IsNullOrWhiteSpace(_wallpaperVideoPath))
{
StartVideoWallpaper(_wallpaperVideoPath);
}
}
else
{
StopVideoWallpaper();
}
ApplyWallpaperBrush(); ApplyWallpaperBrush();
} }
private void StartVideoWallpaper(string videoPath)
{
if (string.IsNullOrWhiteSpace(videoPath) || !File.Exists(videoPath))
{
return;
}
try
{
_libVlc ??= new LibVLC();
_videoWallpaperPlayer ??= new MediaPlayer(_libVlc);
if (_videoWallpaperMedia?.Mrl != videoPath)
{
_videoWallpaperMedia?.Dispose();
_videoWallpaperMedia = new Media(_libVlc, new Uri(videoPath));
_videoWallpaperPlayer.Media = _videoWallpaperMedia;
}
if (DesktopVideoWallpaperView is { } videoView)
{
videoView.MediaPlayer = _videoWallpaperPlayer;
videoView.IsVisible = true;
}
if (!_videoWallpaperPlayer.IsPlaying)
{
_videoWallpaperPlayer.Play();
}
}
catch
{
}
}
private void StopVideoWallpaper() private void StopVideoWallpaper()
{ {
_wallpaperVideoPath = null; if (DesktopVideoWallpaperView is { } videoView)
if (_wallpaperMediaType == WallpaperMediaType.Video)
{ {
_wallpaperMediaType = WallpaperMediaType.None; videoView.IsVisible = false;
} }
_videoWallpaperPlayer?.Stop();
_wallpaperVideoPath = null;
} }
private double CalculateCurrentBackgroundLuminance() private double CalculateCurrentBackgroundLuminance()
@@ -398,7 +466,7 @@ public partial class MainWindow
InitializeDesktopSurfaceState(layoutSnapshot); InitializeDesktopSurfaceState(layoutSnapshot);
InitializeLauncherVisibilitySettings(launcherSnapshot); InitializeLauncherVisibilitySettings(launcherSnapshot);
InitializeDesktopComponentPlacements(layoutSnapshot); InitializeDesktopComponentPlacements(layoutSnapshot);
TryRestoreWallpaper(snapshot.WallpaperPath); TryRestoreWallpaper(snapshot.WallpaperPath, snapshot.WallpaperType, snapshot.WallpaperColor);
if (TryParseColor(snapshot.ThemeColor, out var savedThemeColor)) if (TryParseColor(snapshot.ThemeColor, out var savedThemeColor))
{ {
_selectedThemeColor = savedThemeColor; _selectedThemeColor = savedThemeColor;
@@ -428,6 +496,8 @@ public partial class MainWindow
IsNightMode = _isNightMode, IsNightMode = _isNightMode,
ThemeColor = _selectedThemeColor.ToString(), ThemeColor = _selectedThemeColor.ToString(),
WallpaperPath = _wallpaperPath, WallpaperPath = _wallpaperPath,
WallpaperType = _wallpaperType,
WallpaperColor = _wallpaperSolidColor?.ToString(),
LanguageCode = _languageCode, LanguageCode = _languageCode,
TimeZoneId = _timeZoneService.CurrentTimeZone.Id, TimeZoneId = _timeZoneService.CurrentTimeZone.Id,
WeatherLocationMode = _weatherLocationMode.ToString(), WeatherLocationMode = _weatherLocationMode.ToString(),

View File

@@ -47,6 +47,12 @@
VerticalAlignment="Stretch" VerticalAlignment="Stretch"
Background="{DynamicResource AdaptiveSurfaceBaseBrush}" /> Background="{DynamicResource AdaptiveSurfaceBaseBrush}" />
<vlc:VideoView x:Name="DesktopVideoWallpaperView"
IsVisible="False"
IsHitTestVisible="False"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" />
<Image x:Name="DesktopVideoWallpaperImage" <Image x:Name="DesktopVideoWallpaperImage"
IsVisible="False" IsVisible="False"
IsHitTestVisible="False" IsHitTestVisible="False"

View File

@@ -45,7 +45,8 @@ public partial class MainWindow : Window, ISettingsWindowAnchorProvider
{ {
None, None,
Image, Image,
Video Video,
SolidColor
} }
private enum WeatherLocationMode private enum WeatherLocationMode
@@ -119,6 +120,8 @@ public partial class MainWindow : Window, ISettingsWindowAnchorProvider
private Bitmap? _wallpaperBitmap; private Bitmap? _wallpaperBitmap;
private WallpaperMediaType _wallpaperMediaType; private WallpaperMediaType _wallpaperMediaType;
private string? _wallpaperVideoPath; private string? _wallpaperVideoPath;
private string _wallpaperType = "Image";
private Color? _wallpaperSolidColor;
private LibVLC? _libVlc; private LibVLC? _libVlc;
private MediaPlayer? _videoWallpaperPlayer; private MediaPlayer? _videoWallpaperPlayer;
private Media? _videoWallpaperMedia; private Media? _videoWallpaperMedia;
@@ -277,7 +280,7 @@ public partial class MainWindow : Window, ISettingsWindowAnchorProvider
InitializeDesktopComponentPlacements(desktopLayoutSnapshot); InitializeDesktopComponentPlacements(desktopLayoutSnapshot);
InitializeSettingsIcons(); InitializeSettingsIcons();
TryRestoreWallpaper(snapshot.WallpaperPath); TryRestoreWallpaper(snapshot.WallpaperPath, snapshot.WallpaperType, snapshot.WallpaperColor);
ApplyWallpaperBrush(); ApplyWallpaperBrush();
UpdateWallpaperDisplay(); UpdateWallpaperDisplay();

View File

@@ -36,9 +36,7 @@
<fi:SymbolIconSource Symbol="Color" /> <fi:SymbolIconSource Symbol="Color" />
</ui:SettingsExpander.IconSource> </ui:SettingsExpander.IconSource>
<ui:SettingsExpander.Footer> <ui:SettingsExpander.Footer>
<TextBox Watermark="#AABBCC" <ColorPicker Color="{Binding ThemeColorPickerValue}" />
Width="180"
Text="{Binding ThemeColor}" />
</ui:SettingsExpander.Footer> </ui:SettingsExpander.Footer>
</ui:SettingsExpander> </ui:SettingsExpander>

View File

@@ -20,25 +20,37 @@
<fi:SymbolIconSource Symbol="GridDots" /> <fi:SymbolIconSource Symbol="GridDots" />
</ui:SettingsExpander.IconSource> </ui:SettingsExpander.IconSource>
<ui:SettingsExpanderItem> <ui:SettingsExpanderItem>
<Grid ColumnDefinitions="Auto,*"> <Grid ColumnDefinitions="Auto,*,Auto" ColumnSpacing="16">
<TextBlock Text="{Binding ShortSideCellsLabel}" <TextBlock Text="{Binding ShortSideCellsLabel}"
VerticalAlignment="Center" /> VerticalAlignment="Center" />
<NumericUpDown Grid.Column="1" <Slider Grid.Column="1"
Width="120" Minimum="6"
Minimum="6" Maximum="96"
Maximum="96" IsSnapToTickEnabled="True"
Value="{Binding ShortSideCells}" /> TickFrequency="1"
Value="{Binding ShortSideCells}" />
<TextBlock Grid.Column="2"
Width="32"
Text="{Binding ShortSideCells}"
VerticalAlignment="Center"
HorizontalAlignment="Right" />
</Grid> </Grid>
</ui:SettingsExpanderItem> </ui:SettingsExpanderItem>
<ui:SettingsExpanderItem> <ui:SettingsExpanderItem>
<Grid ColumnDefinitions="Auto,*"> <Grid ColumnDefinitions="Auto,*,Auto" ColumnSpacing="16">
<TextBlock Text="{Binding EdgeInsetPercentLabel}" <TextBlock Text="{Binding EdgeInsetPercentLabel}"
VerticalAlignment="Center" /> VerticalAlignment="Center" />
<NumericUpDown Grid.Column="1" <Slider Grid.Column="1"
Width="120" Minimum="0"
Minimum="0" Maximum="30"
Maximum="30" IsSnapToTickEnabled="True"
Value="{Binding EdgeInsetPercent}" /> TickFrequency="1"
Value="{Binding EdgeInsetPercent}" />
<TextBlock Grid.Column="2"
Width="32"
Text="{Binding EdgeInsetPercent, StringFormat='{}{0}%'}"
VerticalAlignment="Center"
HorizontalAlignment="Right" />
</Grid> </Grid>
</ui:SettingsExpanderItem> </ui:SettingsExpanderItem>
<ui:SettingsExpanderItem> <ui:SettingsExpanderItem>

View File

@@ -9,34 +9,116 @@
<ScrollViewer VerticalScrollBarVisibility="Auto"> <ScrollViewer VerticalScrollBarVisibility="Auto">
<StackPanel Classes="settings-page-container"> <StackPanel Classes="settings-page-container">
<!-- 预览与颜色选择区域 -->
<Grid ColumnDefinitions="*,*" ColumnSpacing="32" Margin="0,0,0,32">
<!-- 左侧:模拟屏幕预览 (占一半宽度) -->
<Border Grid.Column="0" VerticalAlignment="Top">
<Viewbox Stretch="Uniform">
<Border Width="1600" Height="900"
Background="#080808"
BorderBrush="#1A1A1A"
BorderThickness="24"
CornerRadius="48"
BoxShadow="0 12 32 #50000000">
<Panel Background="{DynamicResource AdaptiveSurfaceBaseBrush}" Margin="2">
<!-- 图片/视频预览 -->
<Image Source="{Binding PreviewImage}"
IsVisible="{Binding IsImageOrVideo}"
Stretch="UniformToFill" />
<!-- 纯色预览 -->
<Border Background="{Binding SelectedColor}"
IsVisible="{Binding IsSolidColor}" />
</Panel>
</Border>
</Viewbox>
</Border>
<!-- 右侧:颜色选择网格 -->
<StackPanel Grid.Column="1" VerticalAlignment="Center" Spacing="12" IsVisible="{Binding IsSolidColor}">
<TextBlock Text="{Binding WallpaperColorLabel}"
FontSize="14"
FontWeight="SemiBold"
Opacity="0.8" />
<ItemsControl ItemsSource="{Binding PresetColors}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="4" Rows="3" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Width="48" Height="48" Margin="4" Padding="0"
Background="{Binding}"
BorderThickness="0"
CornerRadius="6"
Command="{Binding $parent[UserControl].((vm:WallpaperSettingsPageViewModel)DataContext).SelectColorCommand}"
CommandParameter="{Binding}"
ToolTip.Tip="{Binding}">
<!-- 简单的悬停与选中效果由 Button 默认样式提供,
由于使用了低饱和度颜色,背景色本身就很柔和 -->
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Grid>
<Separator Classes="settings-separator" Margin="0,0,0,24" />
<!-- 基本设置项 -->
<controls:IconText Icon="Image" <controls:IconText Icon="Image"
Text="{Binding WallpaperHeader}" Text="{Binding WallpaperHeader}"
Margin="0,0,0,4" /> Margin="0,0,0,8" />
<ui:SettingsExpander Header="{Binding WallpaperPathLabel}"> <!-- 壁纸类型 -->
<ui:SettingsExpander Header="{Binding WallpaperTypeLabel}">
<ui:SettingsExpander.IconSource> <ui:SettingsExpander.IconSource>
<fi:SymbolIconSource Symbol="Image" /> <fi:SymbolIconSource Symbol="Layer" />
</ui:SettingsExpander.IconSource> </ui:SettingsExpander.IconSource>
<ui:SettingsExpander.Footer> <ui:SettingsExpander.Footer>
<Grid ColumnDefinitions="220,Auto" <ComboBox Width="200"
ColumnSpacing="8"> ItemsSource="{Binding WallpaperTypes}"
<TextBox IsReadOnly="True" SelectedItem="{Binding SelectedWallpaperType}">
Grid.Column="0" <ComboBox.ItemTemplate>
Text="{Binding WallpaperPath}" /> <DataTemplate x:DataType="vm:SelectionOption">
<Button Grid.Column="1" <TextBlock Text="{Binding Label}" />
Click="OnBrowseWallpaperClick" </DataTemplate>
Content="{Binding ImportWallpaperButtonText}" /> </ComboBox.ItemTemplate>
</Grid> </ComboBox>
</ui:SettingsExpander.Footer> </ui:SettingsExpander.Footer>
</ui:SettingsExpander> </ui:SettingsExpander>
<!-- 图片/视频文件选择 -->
<ui:SettingsExpander Header="{Binding WallpaperPathLabel}"
IsVisible="{Binding IsImageOrVideo}"
Margin="0,4,0,0">
<ui:SettingsExpander.IconSource>
<fi:SymbolIconSource Symbol="FolderOpen" />
</ui:SettingsExpander.IconSource>
<ui:SettingsExpander.Footer>
<StackPanel Orientation="Horizontal" Spacing="8">
<TextBox IsReadOnly="True"
Width="300"
Text="{Binding WallpaperPath}"
VerticalAlignment="Center" />
<Button Click="OnBrowseWallpaperClick"
Classes="accent"
Content="{Binding ImportWallpaperButtonText}"
VerticalAlignment="Center" />
</StackPanel>
</ui:SettingsExpander.Footer>
</ui:SettingsExpander>
<!-- 填充方式 -->
<ui:SettingsExpander Header="{Binding WallpaperPlacementLabel}" <ui:SettingsExpander Header="{Binding WallpaperPlacementLabel}"
Description="{Binding WallpaperPlacementDescription}"> Description="{Binding WallpaperPlacementDescription}"
IsVisible="{Binding IsImageOrVideo}"
Margin="0,4,0,0">
<ui:SettingsExpander.IconSource> <ui:SettingsExpander.IconSource>
<fi:SymbolIconSource Symbol="Maximize" /> <fi:SymbolIconSource Symbol="Maximize" />
</ui:SettingsExpander.IconSource> </ui:SettingsExpander.IconSource>
<ui:SettingsExpander.Footer> <ui:SettingsExpander.Footer>
<ComboBox Width="180" <ComboBox Width="200"
ItemsSource="{Binding WallpaperPlacements}" ItemsSource="{Binding WallpaperPlacements}"
SelectedItem="{Binding SelectedWallpaperPlacement}"> SelectedItem="{Binding SelectedWallpaperPlacement}">
<ComboBox.ItemTemplate> <ComboBox.ItemTemplate>

View File

@@ -29,7 +29,7 @@
<Style Selector="TextBlock.page-title-text"> <Style Selector="TextBlock.page-title-text">
<Setter Property="FontSize" Value="28" /> <Setter Property="FontSize" Value="28" />
<Setter Property="FontWeight" Value="Normal" /> <Setter Property="FontWeight" Value="SemiBold" />
</Style> </Style>
<Style Selector="TextBlock.page-title-text:narrow"> <Style Selector="TextBlock.page-title-text:narrow">