mirror of
https://github.com/wwiinnddyy/LanMountainDesktop.git
synced 2026-06-22 00:54:26 +08:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
915739ff7b |
8
Directory.Build.props
Normal file
8
Directory.Build.props
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<Project>
|
||||||
|
<PropertyGroup>
|
||||||
|
<Version>1.0.0</Version>
|
||||||
|
<TargetFramework Condition="'$(TargetFramework)' == ''">net10.0</TargetFramework>
|
||||||
|
<Nullable Condition="'$(Nullable)' == ''">enable</Nullable>
|
||||||
|
<ImplicitUsings Condition="'$(ImplicitUsings)' == ''">enable</ImplicitUsings>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using LanMountainDesktop.Settings.Core;
|
||||||
|
using LanMountainDesktop.Shared.Contracts;
|
||||||
|
|
||||||
|
namespace LanMountainDesktop.Appearance;
|
||||||
|
|
||||||
|
public static class AppearanceCornerRadiusTokenFactory
|
||||||
|
{
|
||||||
|
public static AppearanceCornerRadiusTokens Create(double scale)
|
||||||
|
{
|
||||||
|
var normalizedScale = GlobalAppearanceSettings.NormalizeCornerRadiusScale(scale);
|
||||||
|
return new AppearanceCornerRadiusTokens(
|
||||||
|
Radius(6, normalizedScale),
|
||||||
|
Radius(10, normalizedScale),
|
||||||
|
Radius(14, normalizedScale),
|
||||||
|
Radius(18, normalizedScale),
|
||||||
|
Radius(24, normalizedScale),
|
||||||
|
Radius(30, normalizedScale),
|
||||||
|
Radius(36, normalizedScale));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static CornerRadius Radius(double value, double scale)
|
||||||
|
{
|
||||||
|
var scaled = Math.Round(value * scale * 2, MidpointRounding.AwayFromZero) / 2d;
|
||||||
|
return new CornerRadius(scaled);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\LanMountainDesktop.PluginSdk\LanMountainDesktop.PluginSdk.csproj" />
|
||||||
|
<ProjectReference Include="..\LanMountainDesktop.Shared.Contracts\LanMountainDesktop.Shared.Contracts.csproj" />
|
||||||
|
<ProjectReference Include="..\LanMountainDesktop.Settings.Core\LanMountainDesktop.Settings.Core.csproj" />
|
||||||
|
<ProjectReference Include="..\LanMountainDesktop.Host.Abstractions\LanMountainDesktop.Host.Abstractions.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\LanMountainDesktop.PluginSdk\LanMountainDesktop.PluginSdk.csproj" />
|
||||||
|
<ProjectReference Include="..\LanMountainDesktop.Shared.Contracts\LanMountainDesktop.Shared.Contracts.csproj" />
|
||||||
|
<ProjectReference Include="..\LanMountainDesktop.Settings.Core\LanMountainDesktop.Settings.Core.csproj" />
|
||||||
|
<ProjectReference Include="..\LanMountainDesktop.Appearance\LanMountainDesktop.Appearance.csproj" />
|
||||||
|
<ProjectReference Include="..\LanMountainDesktop.Host.Abstractions\LanMountainDesktop.Host.Abstractions.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
27
LanMountainDesktop.DesktopHost/DesktopBootstrap.cs
Normal file
27
LanMountainDesktop.DesktopHost/DesktopBootstrap.cs
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
using System;
|
||||||
|
using Avalonia;
|
||||||
|
|
||||||
|
namespace LanMountainDesktop.DesktopHost;
|
||||||
|
|
||||||
|
public static class DesktopBootstrap
|
||||||
|
{
|
||||||
|
public static void InitializeStartupServices(Action initializeDeviceId, Action initializeCrashReporting, Action initializeUserBehaviorAnalytics, Action scheduleStartupCleanup)
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(initializeDeviceId);
|
||||||
|
ArgumentNullException.ThrowIfNull(initializeCrashReporting);
|
||||||
|
ArgumentNullException.ThrowIfNull(initializeUserBehaviorAnalytics);
|
||||||
|
ArgumentNullException.ThrowIfNull(scheduleStartupCleanup);
|
||||||
|
|
||||||
|
initializeDeviceId();
|
||||||
|
initializeCrashReporting();
|
||||||
|
initializeUserBehaviorAnalytics();
|
||||||
|
scheduleStartupCleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void InitializeApplication(Application application, Action initializeShell)
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(application);
|
||||||
|
ArgumentNullException.ThrowIfNull(initializeShell);
|
||||||
|
initializeShell();
|
||||||
|
}
|
||||||
|
}
|
||||||
55
LanMountainDesktop.DesktopHost/DesktopShellHost.cs
Normal file
55
LanMountainDesktop.DesktopHost/DesktopShellHost.cs
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
using System;
|
||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Controls.ApplicationLifetimes;
|
||||||
|
using LanMountainDesktop.Host.Abstractions;
|
||||||
|
|
||||||
|
namespace LanMountainDesktop.DesktopHost;
|
||||||
|
|
||||||
|
public sealed class DesktopShellHost : IDesktopShellHost
|
||||||
|
{
|
||||||
|
private readonly Action _initializePluginRuntime;
|
||||||
|
private readonly Action _initializeTrayIcon;
|
||||||
|
private readonly Action<IClassicDesktopStyleApplicationLifetime> _createAndAssignMainWindow;
|
||||||
|
private readonly Action _performExitCleanup;
|
||||||
|
private readonly Action _startActivationListener;
|
||||||
|
private readonly Action _startWeatherRefresh;
|
||||||
|
|
||||||
|
public DesktopShellHost(
|
||||||
|
Action initializePluginRuntime,
|
||||||
|
Action initializeTrayIcon,
|
||||||
|
Action<IClassicDesktopStyleApplicationLifetime> createAndAssignMainWindow,
|
||||||
|
Action performExitCleanup,
|
||||||
|
Action startActivationListener,
|
||||||
|
Action startWeatherRefresh)
|
||||||
|
{
|
||||||
|
_initializePluginRuntime = initializePluginRuntime;
|
||||||
|
_initializeTrayIcon = initializeTrayIcon;
|
||||||
|
_createAndAssignMainWindow = createAndAssignMainWindow;
|
||||||
|
_performExitCleanup = performExitCleanup;
|
||||||
|
_startActivationListener = startActivationListener;
|
||||||
|
_startWeatherRefresh = startWeatherRefresh;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Initialize()
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("An application instance is required to initialize the desktop shell.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Initialize(Application application)
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(application);
|
||||||
|
|
||||||
|
_initializePluginRuntime();
|
||||||
|
_initializeTrayIcon();
|
||||||
|
|
||||||
|
if (application.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||||
|
{
|
||||||
|
desktop.Exit += (_, _) => _performExitCleanup();
|
||||||
|
_createAndAssignMainWindow(desktop);
|
||||||
|
_startActivationListener();
|
||||||
|
}
|
||||||
|
|
||||||
|
_startWeatherRefresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
15
LanMountainDesktop.DesktopHost/DesktopStartupCoordinator.cs
Normal file
15
LanMountainDesktop.DesktopHost/DesktopStartupCoordinator.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace LanMountainDesktop.DesktopHost;
|
||||||
|
|
||||||
|
public sealed class DesktopStartupCoordinator
|
||||||
|
{
|
||||||
|
private readonly Action _restoreWorkspaceState;
|
||||||
|
|
||||||
|
public DesktopStartupCoordinator(Action restoreWorkspaceState)
|
||||||
|
{
|
||||||
|
_restoreWorkspaceState = restoreWorkspaceState ?? throw new ArgumentNullException(nameof(restoreWorkspaceState));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Restore() => _restoreWorkspaceState();
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Avalonia" Version="11.3.12" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\LanMountainDesktop.PluginSdk\LanMountainDesktop.PluginSdk.csproj" />
|
||||||
|
<ProjectReference Include="..\LanMountainDesktop.Shared.Contracts\LanMountainDesktop.Shared.Contracts.csproj" />
|
||||||
|
<ProjectReference Include="..\LanMountainDesktop.Settings.Core\LanMountainDesktop.Settings.Core.csproj" />
|
||||||
|
<ProjectReference Include="..\LanMountainDesktop.Appearance\LanMountainDesktop.Appearance.csproj" />
|
||||||
|
<ProjectReference Include="..\LanMountainDesktop.DesktopComponents.Runtime\LanMountainDesktop.DesktopComponents.Runtime.csproj" />
|
||||||
|
<ProjectReference Include="..\LanMountainDesktop.Host.Abstractions\LanMountainDesktop.Host.Abstractions.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
18
LanMountainDesktop.DesktopHost/SettingsWindowHost.cs
Normal file
18
LanMountainDesktop.DesktopHost/SettingsWindowHost.cs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace LanMountainDesktop.DesktopHost;
|
||||||
|
|
||||||
|
public sealed class SettingsWindowHost
|
||||||
|
{
|
||||||
|
private readonly Action<string, string?> _openSettingsWindow;
|
||||||
|
|
||||||
|
public SettingsWindowHost(Action<string, string?> openSettingsWindow)
|
||||||
|
{
|
||||||
|
_openSettingsWindow = openSettingsWindow ?? throw new ArgumentNullException(nameof(openSettingsWindow));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Open(string source, string? pageId = null)
|
||||||
|
{
|
||||||
|
_openSettingsWindow(source, pageId);
|
||||||
|
}
|
||||||
|
}
|
||||||
19
LanMountainDesktop.DesktopHost/ShutdownCoordinator.cs
Normal file
19
LanMountainDesktop.DesktopHost/ShutdownCoordinator.cs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace LanMountainDesktop.DesktopHost;
|
||||||
|
|
||||||
|
public sealed class ShutdownCoordinator
|
||||||
|
{
|
||||||
|
private readonly Action<bool, string> _prepareForShutdown;
|
||||||
|
private readonly Action<string> _resetShutdownIntent;
|
||||||
|
|
||||||
|
public ShutdownCoordinator(Action<bool, string> prepareForShutdown, Action<string> resetShutdownIntent)
|
||||||
|
{
|
||||||
|
_prepareForShutdown = prepareForShutdown ?? throw new ArgumentNullException(nameof(prepareForShutdown));
|
||||||
|
_resetShutdownIntent = resetShutdownIntent ?? throw new ArgumentNullException(nameof(resetShutdownIntent));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Prepare(bool isRestart, string source) => _prepareForShutdown(isRestart, source);
|
||||||
|
|
||||||
|
public void Reset(string source) => _resetShutdownIntent(source);
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
using LanMountainDesktop.PluginSdk;
|
||||||
|
using LanMountainDesktop.Shared.Contracts;
|
||||||
|
|
||||||
|
namespace LanMountainDesktop.Host.Abstractions;
|
||||||
|
|
||||||
|
public sealed record ComponentChromeContext(
|
||||||
|
string ComponentId,
|
||||||
|
string? PlacementId,
|
||||||
|
double CellSize,
|
||||||
|
double GlobalCornerRadiusScale,
|
||||||
|
AppearanceCornerRadiusTokens CornerRadiusTokens,
|
||||||
|
SettingsScope Scope = SettingsScope.App);
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
namespace LanMountainDesktop.Host.Abstractions;
|
||||||
|
|
||||||
|
public interface IDesktopShellHost
|
||||||
|
{
|
||||||
|
void Initialize();
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\LanMountainDesktop.PluginSdk\LanMountainDesktop.PluginSdk.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
<PackageReference Include="Avalonia" Version="11.3.12" />
|
<PackageReference Include="Avalonia" Version="11.3.12" />
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.0" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="10.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="10.0.0" />
|
||||||
|
<ProjectReference Include="..\LanMountainDesktop.Shared.Contracts\LanMountainDesktop.Shared.Contracts.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
using LanMountainDesktop.Shared.Contracts;
|
||||||
|
|
||||||
namespace LanMountainDesktop.PluginSdk;
|
namespace LanMountainDesktop.PluginSdk;
|
||||||
|
|
||||||
public sealed class PluginDesktopComponentContext
|
public sealed class PluginDesktopComponentContext
|
||||||
@@ -11,6 +13,8 @@ public sealed class PluginDesktopComponentContext
|
|||||||
string componentId,
|
string componentId,
|
||||||
string? placementId,
|
string? placementId,
|
||||||
double cellSize,
|
double cellSize,
|
||||||
|
double globalCornerRadiusScale,
|
||||||
|
AppearanceCornerRadiusTokens cornerRadiusTokens,
|
||||||
IPluginSettingsService? pluginSettings = null)
|
IPluginSettingsService? pluginSettings = null)
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(manifest);
|
ArgumentNullException.ThrowIfNull(manifest);
|
||||||
@@ -19,6 +23,7 @@ public sealed class PluginDesktopComponentContext
|
|||||||
ArgumentException.ThrowIfNullOrWhiteSpace(componentId);
|
ArgumentException.ThrowIfNullOrWhiteSpace(componentId);
|
||||||
ArgumentNullException.ThrowIfNull(services);
|
ArgumentNullException.ThrowIfNull(services);
|
||||||
ArgumentNullException.ThrowIfNull(properties);
|
ArgumentNullException.ThrowIfNull(properties);
|
||||||
|
ArgumentNullException.ThrowIfNull(cornerRadiusTokens);
|
||||||
|
|
||||||
Manifest = manifest;
|
Manifest = manifest;
|
||||||
PluginDirectory = pluginDirectory;
|
PluginDirectory = pluginDirectory;
|
||||||
@@ -28,6 +33,8 @@ public sealed class PluginDesktopComponentContext
|
|||||||
ComponentId = componentId.Trim();
|
ComponentId = componentId.Trim();
|
||||||
PlacementId = string.IsNullOrWhiteSpace(placementId) ? null : placementId.Trim();
|
PlacementId = string.IsNullOrWhiteSpace(placementId) ? null : placementId.Trim();
|
||||||
CellSize = Math.Max(1, cellSize);
|
CellSize = Math.Max(1, cellSize);
|
||||||
|
GlobalCornerRadiusScale = Math.Max(0.1d, globalCornerRadiusScale);
|
||||||
|
CornerRadiusTokens = cornerRadiusTokens;
|
||||||
PluginSettings = pluginSettings;
|
PluginSettings = pluginSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,8 +54,22 @@ public sealed class PluginDesktopComponentContext
|
|||||||
|
|
||||||
public double CellSize { get; }
|
public double CellSize { get; }
|
||||||
|
|
||||||
|
public double GlobalCornerRadiusScale { get; }
|
||||||
|
|
||||||
|
public AppearanceCornerRadiusTokens CornerRadiusTokens { get; }
|
||||||
|
|
||||||
public IPluginSettingsService? PluginSettings { get; }
|
public IPluginSettingsService? PluginSettings { get; }
|
||||||
|
|
||||||
|
public double ResolveScaledCornerRadius(double baseRadius, double? minimum = null, double? maximum = null)
|
||||||
|
{
|
||||||
|
var scaled = Math.Max(0d, baseRadius) * GlobalCornerRadiusScale;
|
||||||
|
var scaledMin = minimum.HasValue ? minimum.Value * GlobalCornerRadiusScale : scaled;
|
||||||
|
var scaledMax = maximum.HasValue ? maximum.Value * GlobalCornerRadiusScale : scaled;
|
||||||
|
return minimum.HasValue || maximum.HasValue
|
||||||
|
? Math.Clamp(scaled, scaledMin, scaledMax)
|
||||||
|
: scaled;
|
||||||
|
}
|
||||||
|
|
||||||
public T? GetService<T>()
|
public T? GetService<T>()
|
||||||
{
|
{
|
||||||
return (T?)Services.GetService(typeof(T));
|
return (T?)Services.GetService(typeof(T));
|
||||||
|
|||||||
20
LanMountainDesktop.Settings.Core/GlobalAppearanceSettings.cs
Normal file
20
LanMountainDesktop.Settings.Core/GlobalAppearanceSettings.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
namespace LanMountainDesktop.Settings.Core;
|
||||||
|
|
||||||
|
public static class GlobalAppearanceSettings
|
||||||
|
{
|
||||||
|
public const double DefaultCornerRadiusScale = 1.0;
|
||||||
|
public const double MinimumCornerRadiusScale = 0.70;
|
||||||
|
public const double MaximumCornerRadiusScale = 1.40;
|
||||||
|
public const double CornerRadiusScaleStep = 0.05;
|
||||||
|
|
||||||
|
public static double NormalizeCornerRadiusScale(double value)
|
||||||
|
{
|
||||||
|
if (double.IsNaN(value) || double.IsInfinity(value))
|
||||||
|
{
|
||||||
|
return DefaultCornerRadiusScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
var clamped = Math.Clamp(value, MinimumCornerRadiusScale, MaximumCornerRadiusScale);
|
||||||
|
return Math.Round(clamped / CornerRadiusScaleStep, MidpointRounding.AwayFromZero) * CornerRadiusScaleStep;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\LanMountainDesktop.PluginSdk\LanMountainDesktop.PluginSdk.csproj" />
|
||||||
|
<ProjectReference Include="..\LanMountainDesktop.Shared.Contracts\LanMountainDesktop.Shared.Contracts.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
using Avalonia;
|
||||||
|
|
||||||
|
namespace LanMountainDesktop.Shared.Contracts;
|
||||||
|
|
||||||
|
public sealed record AppearanceCornerRadiusTokens(
|
||||||
|
CornerRadius Micro,
|
||||||
|
CornerRadius Xs,
|
||||||
|
CornerRadius Sm,
|
||||||
|
CornerRadius Md,
|
||||||
|
CornerRadius Lg,
|
||||||
|
CornerRadius Xl,
|
||||||
|
CornerRadius Island);
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Avalonia" Version="11.3.12" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
@@ -1,5 +1,11 @@
|
|||||||
<Solution>
|
<Solution>
|
||||||
<Project Path="LanAirApp/tools/LanMountainDesktop.PluginPackager/LanMountainDesktop.PluginPackager.csproj" />
|
<Project Path="LanAirApp/tools/LanMountainDesktop.PluginPackager/LanMountainDesktop.PluginPackager.csproj" />
|
||||||
|
<Project Path="LanMountainDesktop.Host.Abstractions/LanMountainDesktop.Host.Abstractions.csproj" />
|
||||||
|
<Project Path="LanMountainDesktop.Shared.Contracts/LanMountainDesktop.Shared.Contracts.csproj" />
|
||||||
|
<Project Path="LanMountainDesktop.Settings.Core/LanMountainDesktop.Settings.Core.csproj" />
|
||||||
|
<Project Path="LanMountainDesktop.Appearance/LanMountainDesktop.Appearance.csproj" />
|
||||||
|
<Project Path="LanMountainDesktop.DesktopComponents.Runtime/LanMountainDesktop.DesktopComponents.Runtime.csproj" />
|
||||||
|
<Project Path="LanMountainDesktop.DesktopHost/LanMountainDesktop.DesktopHost.csproj" />
|
||||||
<Project Path="LanMountainDesktop.PluginSdk/LanMountainDesktop.PluginSdk.csproj" />
|
<Project Path="LanMountainDesktop.PluginSdk/LanMountainDesktop.PluginSdk.csproj" />
|
||||||
<Project Path="LanMountainDesktop.PluginsInstallHelper/LanMountainDesktop.PluginsInstallHelper.csproj" />
|
<Project Path="LanMountainDesktop.PluginsInstallHelper/LanMountainDesktop.PluginsInstallHelper.csproj" />
|
||||||
<Project Path="LanMountainDesktop/LanMountainDesktop.csproj" />
|
<Project Path="LanMountainDesktop/LanMountainDesktop.csproj" />
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ using Avalonia.Styling;
|
|||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
using AvaloniaWebView;
|
using AvaloniaWebView;
|
||||||
using LanMountainDesktop.ComponentSystem;
|
using LanMountainDesktop.ComponentSystem;
|
||||||
|
using LanMountainDesktop.DesktopHost;
|
||||||
using LanMountainDesktop.Models;
|
using LanMountainDesktop.Models;
|
||||||
using LanMountainDesktop.PluginSdk;
|
using LanMountainDesktop.PluginSdk;
|
||||||
using LanMountainDesktop.Services;
|
using LanMountainDesktop.Services;
|
||||||
@@ -61,6 +62,7 @@ public partial class App : Application
|
|||||||
private MainWindow? _mainWindow;
|
private MainWindow? _mainWindow;
|
||||||
private bool _mainWindowClosed;
|
private bool _mainWindowClosed;
|
||||||
private bool _uiUnhandledExceptionHooked;
|
private bool _uiUnhandledExceptionHooked;
|
||||||
|
private DesktopShellHost? _desktopShellHost;
|
||||||
|
|
||||||
internal static SingleInstanceService? CurrentSingleInstanceService { get; set; }
|
internal static SingleInstanceService? CurrentSingleInstanceService { get; set; }
|
||||||
internal static (UserBehaviorAnalyticsService?, CrashReportService?) AnalyticsServices { get; set; }
|
internal static (UserBehaviorAnalyticsService?, CrashReportService?) AnalyticsServices { get; set; }
|
||||||
@@ -116,28 +118,32 @@ public partial class App : Application
|
|||||||
AppLogger.Info("App", "Framework initialization completed.");
|
AppLogger.Info("App", "Framework initialization completed.");
|
||||||
RegisterUiUnhandledExceptionGuard();
|
RegisterUiUnhandledExceptionGuard();
|
||||||
LinuxDesktopEntryInstaller.EnsureInstalled();
|
LinuxDesktopEntryInstaller.EnsureInstalled();
|
||||||
InitializePluginRuntime();
|
DesktopBootstrap.InitializeApplication(this, InitializeDesktopShell);
|
||||||
InitializeTrayIcon();
|
|
||||||
|
|
||||||
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
base.OnFrameworkInitializationCompleted();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeDesktopShell()
|
||||||
|
{
|
||||||
|
_desktopShellHost ??= new DesktopShellHost(
|
||||||
|
InitializePluginRuntime,
|
||||||
|
InitializeTrayIcon,
|
||||||
|
desktop =>
|
||||||
{
|
{
|
||||||
// Avoid duplicate validations from both Avalonia and the CommunityToolkit.
|
// Avoid duplicate validations from both Avalonia and the CommunityToolkit.
|
||||||
// More info: https://docs.avaloniaui.net/docs/guides/development-guides/data-validation#manage-validationplugins
|
// More info: https://docs.avaloniaui.net/docs/guides/development-guides/data-validation#manage-validationplugins
|
||||||
DisableAvaloniaDataAnnotationValidation();
|
DisableAvaloniaDataAnnotationValidation();
|
||||||
desktop.ShutdownMode = Avalonia.Controls.ShutdownMode.OnExplicitShutdown;
|
desktop.ShutdownMode = Avalonia.Controls.ShutdownMode.OnExplicitShutdown;
|
||||||
desktop.Exit += (_, _) =>
|
CreateAndAssignMainWindow(desktop, "FrameworkInitialization");
|
||||||
|
},
|
||||||
|
() =>
|
||||||
{
|
{
|
||||||
AppLogger.Info("App", "Desktop lifetime exit triggered.");
|
AppLogger.Info("App", "Desktop lifetime exit triggered.");
|
||||||
PerformExitCleanup();
|
PerformExitCleanup();
|
||||||
};
|
},
|
||||||
|
() => CurrentSingleInstanceService?.StartActivationListener(ActivateMainWindow),
|
||||||
CreateAndAssignMainWindow(desktop, "FrameworkInitialization");
|
StartWeatherLocationRefreshIfNeeded);
|
||||||
CurrentSingleInstanceService?.StartActivationListener(ActivateMainWindow);
|
_desktopShellHost.Initialize(this);
|
||||||
}
|
|
||||||
|
|
||||||
StartWeatherLocationRefreshIfNeeded();
|
|
||||||
|
|
||||||
base.OnFrameworkInitializationCompleted();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnTrayExitClick(object? sender, EventArgs e)
|
private void OnTrayExitClick(object? sender, EventArgs e)
|
||||||
@@ -493,6 +499,7 @@ public partial class App : Application
|
|||||||
refreshAll ||
|
refreshAll ||
|
||||||
changedKeys.Contains(nameof(AppSettingsSnapshot.IsNightMode), StringComparer.OrdinalIgnoreCase) ||
|
changedKeys.Contains(nameof(AppSettingsSnapshot.IsNightMode), StringComparer.OrdinalIgnoreCase) ||
|
||||||
changedKeys.Contains(nameof(AppSettingsSnapshot.UseSystemChrome), StringComparer.OrdinalIgnoreCase) ||
|
changedKeys.Contains(nameof(AppSettingsSnapshot.UseSystemChrome), StringComparer.OrdinalIgnoreCase) ||
|
||||||
|
changedKeys.Contains(nameof(AppSettingsSnapshot.GlobalCornerRadiusScale), StringComparer.OrdinalIgnoreCase) ||
|
||||||
(string.Equals(liveAppearance.ThemeColorMode, ThemeAppearanceValues.ColorModeSeedMonet, StringComparison.OrdinalIgnoreCase) &&
|
(string.Equals(liveAppearance.ThemeColorMode, ThemeAppearanceValues.ColorModeSeedMonet, StringComparison.OrdinalIgnoreCase) &&
|
||||||
changedKeys.Contains(nameof(AppSettingsSnapshot.ThemeColor), StringComparer.OrdinalIgnoreCase)) ||
|
changedKeys.Contains(nameof(AppSettingsSnapshot.ThemeColor), StringComparer.OrdinalIgnoreCase)) ||
|
||||||
(string.Equals(liveAppearance.ThemeColorMode, ThemeAppearanceValues.ColorModeWallpaperMonet, StringComparison.OrdinalIgnoreCase) &&
|
(string.Equals(liveAppearance.ThemeColorMode, ThemeAppearanceValues.ColorModeWallpaperMonet, StringComparison.OrdinalIgnoreCase) &&
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using LanMountainDesktop.Host.Abstractions;
|
||||||
using LanMountainDesktop.PluginSdk;
|
using LanMountainDesktop.PluginSdk;
|
||||||
using LanMountainDesktop.Services;
|
using LanMountainDesktop.Services;
|
||||||
using LanMountainDesktop.Services.Settings;
|
using LanMountainDesktop.Services.Settings;
|
||||||
@@ -10,5 +11,6 @@ public sealed record DesktopComponentRuntimeContext(
|
|||||||
ISettingsFacadeService SettingsFacade,
|
ISettingsFacadeService SettingsFacade,
|
||||||
ISettingsService SettingsService,
|
ISettingsService SettingsService,
|
||||||
IAppearanceThemeService AppearanceTheme,
|
IAppearanceThemeService AppearanceTheme,
|
||||||
|
ComponentChromeContext Chrome,
|
||||||
IComponentSettingsAccessor ComponentSettingsAccessor,
|
IComponentSettingsAccessor ComponentSettingsAccessor,
|
||||||
IComponentInstanceSettingsStore ComponentSettingsStore);
|
IComponentInstanceSettingsStore ComponentSettingsStore);
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
using LanMountainDesktop.Host.Abstractions;
|
||||||
|
|
||||||
|
namespace LanMountainDesktop.ComponentSystem;
|
||||||
|
|
||||||
|
public interface IComponentChromeContextAware
|
||||||
|
{
|
||||||
|
void SetComponentChromeContext(ComponentChromeContext context);
|
||||||
|
}
|
||||||
@@ -29,6 +29,12 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\LanMountainDesktop.Host.Abstractions\LanMountainDesktop.Host.Abstractions.csproj" />
|
||||||
|
<ProjectReference Include="..\LanMountainDesktop.Shared.Contracts\LanMountainDesktop.Shared.Contracts.csproj" />
|
||||||
|
<ProjectReference Include="..\LanMountainDesktop.Settings.Core\LanMountainDesktop.Settings.Core.csproj" />
|
||||||
|
<ProjectReference Include="..\LanMountainDesktop.Appearance\LanMountainDesktop.Appearance.csproj" />
|
||||||
|
<ProjectReference Include="..\LanMountainDesktop.DesktopComponents.Runtime\LanMountainDesktop.DesktopComponents.Runtime.csproj" />
|
||||||
|
<ProjectReference Include="..\LanMountainDesktop.DesktopHost\LanMountainDesktop.DesktopHost.csproj" />
|
||||||
<ProjectReference Include="..\LanMountainDesktop.PluginSdk\LanMountainDesktop.PluginSdk.csproj" />
|
<ProjectReference Include="..\LanMountainDesktop.PluginSdk\LanMountainDesktop.PluginSdk.csproj" />
|
||||||
<ProjectReference Include="..\LanMountainDesktop.PluginsInstallHelper\LanMountainDesktop.PluginsInstallHelper.csproj" ReferenceOutputAssembly="false" />
|
<ProjectReference Include="..\LanMountainDesktop.PluginsInstallHelper\LanMountainDesktop.PluginsInstallHelper.csproj" ReferenceOutputAssembly="false" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
"settings.nav.group_system": "System",
|
"settings.nav.group_system": "System",
|
||||||
"settings.nav.group_extensions": "Extensions",
|
"settings.nav.group_extensions": "Extensions",
|
||||||
"settings.nav.wallpaper": "Wallpaper",
|
"settings.nav.wallpaper": "Wallpaper",
|
||||||
"settings.nav.grid": "Grid",
|
"settings.nav.grid": "Components",
|
||||||
"settings.nav.color": "Color",
|
"settings.nav.color": "Color",
|
||||||
"settings.nav.status_bar": "Status Bar",
|
"settings.nav.status_bar": "Status Bar",
|
||||||
"settings.nav.weather": "Weather",
|
"settings.nav.weather": "Weather",
|
||||||
@@ -303,8 +303,17 @@
|
|||||||
"settings.status_bar.clock_format.hm": "Hour:Minute",
|
"settings.status_bar.clock_format.hm": "Hour:Minute",
|
||||||
"settings.status_bar.clock_format.hms": "Hour:Minute:Second",
|
"settings.status_bar.clock_format.hms": "Hour:Minute:Second",
|
||||||
"settings.components.title": "Components",
|
"settings.components.title": "Components",
|
||||||
"settings.components.description": "Adjust desktop grid density and widget placement.",
|
"settings.components.description": "Adjust component layout and corner design.",
|
||||||
"settings.components.grid_header": "Grid Layout",
|
"settings.components.grid_header": "Grid Settings",
|
||||||
|
"settings.components.header": "Grid Settings",
|
||||||
|
"settings.components.short_side_label": "Short Side Cells",
|
||||||
|
"settings.components.edge_inset_label": "Screen Inset",
|
||||||
|
"settings.components.spacing_label": "Component Spacing",
|
||||||
|
"settings.components.spacing_compact": "Compact",
|
||||||
|
"settings.components.spacing_relaxed": "Relaxed",
|
||||||
|
"settings.components.corner_radius.header": "Corner Design",
|
||||||
|
"settings.components.corner_radius.label": "Component Corner Radius",
|
||||||
|
"settings.components.corner_radius.description": "Adjust the shared corner radius used by component containers, and expand the internal safe area with it.",
|
||||||
"settings.update.title": "Update",
|
"settings.update.title": "Update",
|
||||||
"settings.update.current_version_label": "Current Version",
|
"settings.update.current_version_label": "Current Version",
|
||||||
"settings.update.latest_version_label": "Latest Release",
|
"settings.update.latest_version_label": "Latest Release",
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
"settings.nav.group_system": "系统",
|
"settings.nav.group_system": "系统",
|
||||||
"settings.nav.group_extensions": "扩展",
|
"settings.nav.group_extensions": "扩展",
|
||||||
"settings.nav.wallpaper": "壁纸",
|
"settings.nav.wallpaper": "壁纸",
|
||||||
"settings.nav.grid": "网格",
|
"settings.nav.grid": "组件",
|
||||||
"settings.nav.color": "颜色",
|
"settings.nav.color": "颜色",
|
||||||
"settings.nav.status_bar": "状态栏",
|
"settings.nav.status_bar": "状态栏",
|
||||||
"settings.nav.weather": "天气",
|
"settings.nav.weather": "天气",
|
||||||
@@ -301,9 +301,18 @@
|
|||||||
"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.components.header": "网格设置",
|
||||||
|
"settings.components.short_side_label": "短边格数",
|
||||||
|
"settings.components.edge_inset_label": "屏幕边距",
|
||||||
|
"settings.components.spacing_label": "组件间距",
|
||||||
|
"settings.components.spacing_compact": "紧凑",
|
||||||
|
"settings.components.spacing_relaxed": "宽松",
|
||||||
|
"settings.components.corner_radius.header": "圆角设计",
|
||||||
|
"settings.components.corner_radius.label": "组件圆角",
|
||||||
|
"settings.components.corner_radius.description": "统一调整组件容器圆角,并随圆角增大同步扩展内部安全区。",
|
||||||
"settings.update.title": "更新",
|
"settings.update.title": "更新",
|
||||||
"settings.update.current_version_label": "当前版本",
|
"settings.update.current_version_label": "当前版本",
|
||||||
"settings.update.latest_version_label": "最新发布",
|
"settings.update.latest_version_label": "最新发布",
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using LanMountainDesktop.Settings.Core;
|
||||||
|
|
||||||
namespace LanMountainDesktop.Models;
|
namespace LanMountainDesktop.Models;
|
||||||
|
|
||||||
@@ -16,6 +17,8 @@ public sealed class AppSettingsSnapshot
|
|||||||
|
|
||||||
public bool UseSystemChrome { get; set; }
|
public bool UseSystemChrome { get; set; }
|
||||||
|
|
||||||
|
public double GlobalCornerRadiusScale { get; set; } = GlobalAppearanceSettings.DefaultCornerRadiusScale;
|
||||||
|
|
||||||
public string ThemeColorMode { get; set; } = "default_neutral";
|
public string ThemeColorMode { get; set; } = "default_neutral";
|
||||||
|
|
||||||
public string SystemMaterialMode { get; set; } = "none";
|
public string SystemMaterialMode { get; set; } = "none";
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using System.Threading;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.WebView.Desktop;
|
using Avalonia.WebView.Desktop;
|
||||||
|
using LanMountainDesktop.DesktopHost;
|
||||||
using LanMountainDesktop.Models;
|
using LanMountainDesktop.Models;
|
||||||
using LanMountainDesktop.Services;
|
using LanMountainDesktop.Services;
|
||||||
using LanMountainDesktop.Services.Settings;
|
using LanMountainDesktop.Services.Settings;
|
||||||
@@ -20,9 +21,11 @@ sealed class Program
|
|||||||
{
|
{
|
||||||
AppLogger.Initialize();
|
AppLogger.Initialize();
|
||||||
RegisterGlobalExceptionLogging();
|
RegisterGlobalExceptionLogging();
|
||||||
InitializeDeviceId();
|
DesktopBootstrap.InitializeStartupServices(
|
||||||
InitializeCrashReporting();
|
InitializeDeviceId,
|
||||||
InitializeUserBehaviorAnalytics();
|
InitializeCrashReporting,
|
||||||
|
InitializeUserBehaviorAnalytics,
|
||||||
|
ScheduleWhiteboardNoteStartupCleanup);
|
||||||
var restartParentProcessId = AppRestartService.TryGetRestartParentProcessId(args);
|
var restartParentProcessId = AppRestartService.TryGetRestartParentProcessId(args);
|
||||||
|
|
||||||
using var singleInstance = AcquireSingleInstance(restartParentProcessId);
|
using var singleInstance = AcquireSingleInstance(restartParentProcessId);
|
||||||
@@ -43,7 +46,6 @@ sealed class Program
|
|||||||
|
|
||||||
var diagnostics = StartupDiagnosticsService.Run(args);
|
var diagnostics = StartupDiagnosticsService.Run(args);
|
||||||
StartupDiagnosticsService.ShowLegacyExecutableWarningIfNeeded(diagnostics);
|
StartupDiagnosticsService.ShowLegacyExecutableWarningIfNeeded(diagnostics);
|
||||||
ScheduleWhiteboardNoteStartupCleanup();
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,9 +11,12 @@ using Avalonia.Media;
|
|||||||
using Avalonia.Styling;
|
using Avalonia.Styling;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
using Avalonia.Media.Imaging;
|
using Avalonia.Media.Imaging;
|
||||||
|
using LanMountainDesktop.Appearance;
|
||||||
using LanMountainDesktop.Models;
|
using LanMountainDesktop.Models;
|
||||||
using LanMountainDesktop.PluginSdk;
|
using LanMountainDesktop.PluginSdk;
|
||||||
using LanMountainDesktop.Services.Settings;
|
using LanMountainDesktop.Services.Settings;
|
||||||
|
using LanMountainDesktop.Settings.Core;
|
||||||
|
using LanMountainDesktop.Shared.Contracts;
|
||||||
using LanMountainDesktop.Theme;
|
using LanMountainDesktop.Theme;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
|
|
||||||
@@ -41,6 +44,8 @@ public sealed record AppearanceThemeSnapshot(
|
|||||||
string ThemeColorMode,
|
string ThemeColorMode,
|
||||||
string? UserThemeColor,
|
string? UserThemeColor,
|
||||||
string? SelectedWallpaperSeed,
|
string? SelectedWallpaperSeed,
|
||||||
|
double GlobalCornerRadiusScale,
|
||||||
|
AppearanceCornerRadiusTokens CornerRadiusTokens,
|
||||||
string ResolvedSeedSource,
|
string ResolvedSeedSource,
|
||||||
MonetPalette MonetPalette,
|
MonetPalette MonetPalette,
|
||||||
Color AccentColor,
|
Color AccentColor,
|
||||||
@@ -464,6 +469,13 @@ internal sealed class AppearanceThemeService : IAppearanceThemeService, IDisposa
|
|||||||
var context = CreateThemeContext(snapshot);
|
var context = CreateThemeContext(snapshot);
|
||||||
ThemeColorSystemService.ApplyThemeResources(resources, context);
|
ThemeColorSystemService.ApplyThemeResources(resources, context);
|
||||||
GlassEffectService.ApplyGlassResources(resources, context);
|
GlassEffectService.ApplyGlassResources(resources, context);
|
||||||
|
resources["DesignCornerRadiusMicro"] = snapshot.CornerRadiusTokens.Micro;
|
||||||
|
resources["DesignCornerRadiusXs"] = snapshot.CornerRadiusTokens.Xs;
|
||||||
|
resources["DesignCornerRadiusSm"] = snapshot.CornerRadiusTokens.Sm;
|
||||||
|
resources["DesignCornerRadiusMd"] = snapshot.CornerRadiusTokens.Md;
|
||||||
|
resources["DesignCornerRadiusLg"] = snapshot.CornerRadiusTokens.Lg;
|
||||||
|
resources["DesignCornerRadiusXl"] = snapshot.CornerRadiusTokens.Xl;
|
||||||
|
resources["DesignCornerRadiusIsland"] = snapshot.CornerRadiusTokens.Island;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AppearanceMaterialSurface GetMaterialSurface(MaterialSurfaceRole role)
|
public AppearanceMaterialSurface GetMaterialSurface(MaterialSurfaceRole role)
|
||||||
@@ -538,6 +550,7 @@ internal sealed class AppearanceThemeService : IAppearanceThemeService, IDisposa
|
|||||||
if (!refreshAll &&
|
if (!refreshAll &&
|
||||||
!changedKeys.Contains(nameof(AppSettingsSnapshot.IsNightMode), StringComparer.OrdinalIgnoreCase) &&
|
!changedKeys.Contains(nameof(AppSettingsSnapshot.IsNightMode), StringComparer.OrdinalIgnoreCase) &&
|
||||||
!changedKeys.Contains(nameof(AppSettingsSnapshot.UseSystemChrome), StringComparer.OrdinalIgnoreCase) &&
|
!changedKeys.Contains(nameof(AppSettingsSnapshot.UseSystemChrome), StringComparer.OrdinalIgnoreCase) &&
|
||||||
|
!changedKeys.Contains(nameof(AppSettingsSnapshot.GlobalCornerRadiusScale), StringComparer.OrdinalIgnoreCase) &&
|
||||||
!(respondsToThemeColor &&
|
!(respondsToThemeColor &&
|
||||||
changedKeys.Contains(nameof(AppSettingsSnapshot.ThemeColor), StringComparer.OrdinalIgnoreCase)) &&
|
changedKeys.Contains(nameof(AppSettingsSnapshot.ThemeColor), StringComparer.OrdinalIgnoreCase)) &&
|
||||||
!(respondsToWallpaper &&
|
!(respondsToWallpaper &&
|
||||||
@@ -559,6 +572,8 @@ internal sealed class AppearanceThemeService : IAppearanceThemeService, IDisposa
|
|||||||
bool queueWallpaperPaletteBuild)
|
bool queueWallpaperPaletteBuild)
|
||||||
{
|
{
|
||||||
var availableModes = _windowMaterialService.GetAvailableModes();
|
var availableModes = _windowMaterialService.GetAvailableModes();
|
||||||
|
var globalCornerRadiusScale = GlobalAppearanceSettings.NormalizeCornerRadiusScale(themeState.GlobalCornerRadiusScale);
|
||||||
|
var cornerRadiusTokens = AppearanceCornerRadiusTokenFactory.Create(globalCornerRadiusScale);
|
||||||
MonetPalette palette;
|
MonetPalette palette;
|
||||||
IReadOnlyList<Color> wallpaperSeedCandidates;
|
IReadOnlyList<Color> wallpaperSeedCandidates;
|
||||||
Color effectiveSeedColor;
|
Color effectiveSeedColor;
|
||||||
@@ -598,6 +613,8 @@ internal sealed class AppearanceThemeService : IAppearanceThemeService, IDisposa
|
|||||||
themeColorMode,
|
themeColorMode,
|
||||||
themeState.ThemeColor,
|
themeState.ThemeColor,
|
||||||
selectedWallpaperSeed,
|
selectedWallpaperSeed,
|
||||||
|
globalCornerRadiusScale,
|
||||||
|
cornerRadiusTokens,
|
||||||
resolvedSeedSource,
|
resolvedSeedSource,
|
||||||
palette,
|
palette,
|
||||||
ResolveAccentColor(themeColorMode, themeState.ThemeColor, palette),
|
ResolveAccentColor(themeColorMode, themeState.ThemeColor, palette),
|
||||||
|
|||||||
@@ -122,6 +122,7 @@ public static class DesktopComponentRegistryFactory
|
|||||||
var pluginSettings = new PluginScopedSettingsService(
|
var pluginSettings = new PluginScopedSettingsService(
|
||||||
contribution.Plugin.Manifest.Id,
|
contribution.Plugin.Manifest.Id,
|
||||||
settingsService);
|
settingsService);
|
||||||
|
var appearanceSnapshot = HostAppearanceThemeProvider.GetOrCreate().GetCurrent();
|
||||||
var pluginContext = new PluginDesktopComponentContext(
|
var pluginContext = new PluginDesktopComponentContext(
|
||||||
contribution.Plugin.Manifest,
|
contribution.Plugin.Manifest,
|
||||||
contribution.Plugin.Context.PluginDirectory,
|
contribution.Plugin.Context.PluginDirectory,
|
||||||
@@ -131,6 +132,8 @@ public static class DesktopComponentRegistryFactory
|
|||||||
contribution.Registration.ComponentId,
|
contribution.Registration.ComponentId,
|
||||||
context.PlacementId,
|
context.PlacementId,
|
||||||
context.CellSize,
|
context.CellSize,
|
||||||
|
appearanceSnapshot.GlobalCornerRadiusScale,
|
||||||
|
appearanceSnapshot.CornerRadiusTokens,
|
||||||
pluginSettings);
|
pluginSettings);
|
||||||
|
|
||||||
return contribution.Registration.ControlFactory(contribution.Plugin.Services, pluginContext);
|
return contribution.Registration.ControlFactory(contribution.Plugin.Services, pluginContext);
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ public sealed record ComponentLibraryCategoryEntry(
|
|||||||
|
|
||||||
public sealed record ComponentLibraryCreateContext(
|
public sealed record ComponentLibraryCreateContext(
|
||||||
double CellSize,
|
double CellSize,
|
||||||
|
double GlobalCornerRadiusScale,
|
||||||
TimeZoneService TimeZoneService,
|
TimeZoneService TimeZoneService,
|
||||||
IWeatherInfoService WeatherInfoService,
|
IWeatherInfoService WeatherInfoService,
|
||||||
IRecommendationInfoService RecommendationInfoService,
|
IRecommendationInfoService RecommendationInfoService,
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ internal sealed class SettingsCatalogService : ISettingsCatalog
|
|||||||
[
|
[
|
||||||
new SettingsSectionDefinition("general", SettingsCategories.General, SettingsScope.App, "settings.general.title", iconKey: "Settings", sortOrder: 0),
|
new SettingsSectionDefinition("general", SettingsCategories.General, SettingsScope.App, "settings.general.title", iconKey: "Settings", sortOrder: 0),
|
||||||
new SettingsSectionDefinition("appearance", SettingsCategories.Appearance, SettingsScope.App, "settings.appearance.title", iconKey: "DesignIdeas", sortOrder: 10),
|
new SettingsSectionDefinition("appearance", SettingsCategories.Appearance, SettingsScope.App, "settings.appearance.title", iconKey: "DesignIdeas", sortOrder: 10),
|
||||||
new SettingsSectionDefinition("components", SettingsCategories.Components, SettingsScope.ComponentInstance, "settings.components.title", iconKey: "GridDots", sortOrder: 20),
|
new SettingsSectionDefinition("components", SettingsCategories.Components, SettingsScope.ComponentInstance, "settings.components.title", iconKey: "Apps", sortOrder: 20),
|
||||||
new SettingsSectionDefinition("plugins", SettingsCategories.Plugins, SettingsScope.Plugin, "settings.plugins.title", iconKey: "PuzzlePiece", sortOrder: 30),
|
new SettingsSectionDefinition("plugins", SettingsCategories.Plugins, SettingsScope.Plugin, "settings.plugins.title", iconKey: "PuzzlePiece", sortOrder: 30),
|
||||||
new SettingsSectionDefinition("about", SettingsCategories.About, SettingsScope.App, "settings.about.title", iconKey: "Info", sortOrder: 40)
|
new SettingsSectionDefinition("about", SettingsCategories.About, SettingsScope.App, "settings.about.title", iconKey: "Info", sortOrder: 40)
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using System.Threading.Tasks;
|
|||||||
using LanMountainDesktop.Models;
|
using LanMountainDesktop.Models;
|
||||||
using LanMountainDesktop.PluginSdk;
|
using LanMountainDesktop.PluginSdk;
|
||||||
using LanMountainDesktop.Services;
|
using LanMountainDesktop.Services;
|
||||||
|
using LanMountainDesktop.Settings.Core;
|
||||||
|
|
||||||
namespace LanMountainDesktop.Services.Settings;
|
namespace LanMountainDesktop.Services.Settings;
|
||||||
|
|
||||||
@@ -20,6 +21,7 @@ public sealed record ThemeAppearanceSettingsState(
|
|||||||
bool IsNightMode,
|
bool IsNightMode,
|
||||||
string? ThemeColor,
|
string? ThemeColor,
|
||||||
bool UseSystemChrome,
|
bool UseSystemChrome,
|
||||||
|
double GlobalCornerRadiusScale = GlobalAppearanceSettings.DefaultCornerRadiusScale,
|
||||||
string ThemeColorMode = ThemeAppearanceValues.ColorModeDefaultNeutral,
|
string ThemeColorMode = ThemeAppearanceValues.ColorModeDefaultNeutral,
|
||||||
string SystemMaterialMode = ThemeAppearanceValues.MaterialNone,
|
string SystemMaterialMode = ThemeAppearanceValues.MaterialNone,
|
||||||
string? SelectedWallpaperSeed = null);
|
string? SelectedWallpaperSeed = null);
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ using Avalonia.Media.Imaging;
|
|||||||
using LanMountainDesktop.Models;
|
using LanMountainDesktop.Models;
|
||||||
using LanMountainDesktop.PluginSdk;
|
using LanMountainDesktop.PluginSdk;
|
||||||
using LanMountainDesktop.Services;
|
using LanMountainDesktop.Services;
|
||||||
|
using LanMountainDesktop.Settings.Core;
|
||||||
using LanMountainDesktop.Services.PluginMarket;
|
using LanMountainDesktop.Services.PluginMarket;
|
||||||
|
|
||||||
namespace LanMountainDesktop.Services.Settings;
|
namespace LanMountainDesktop.Services.Settings;
|
||||||
@@ -242,6 +243,7 @@ internal sealed class ThemeAppearanceService : IThemeAppearanceService
|
|||||||
snapshot.IsNightMode ?? false,
|
snapshot.IsNightMode ?? false,
|
||||||
snapshot.ThemeColor,
|
snapshot.ThemeColor,
|
||||||
snapshot.UseSystemChrome,
|
snapshot.UseSystemChrome,
|
||||||
|
GlobalAppearanceSettings.NormalizeCornerRadiusScale(snapshot.GlobalCornerRadiusScale),
|
||||||
ThemeAppearanceValues.NormalizeThemeColorMode(snapshot.ThemeColorMode, snapshot.ThemeColor),
|
ThemeAppearanceValues.NormalizeThemeColorMode(snapshot.ThemeColorMode, snapshot.ThemeColor),
|
||||||
ThemeAppearanceValues.NormalizeSystemMaterialMode(snapshot.SystemMaterialMode),
|
ThemeAppearanceValues.NormalizeSystemMaterialMode(snapshot.SystemMaterialMode),
|
||||||
snapshot.SelectedWallpaperSeed);
|
snapshot.SelectedWallpaperSeed);
|
||||||
@@ -252,6 +254,7 @@ internal sealed class ThemeAppearanceService : IThemeAppearanceService
|
|||||||
var snapshot = _settingsService.Load();
|
var snapshot = _settingsService.Load();
|
||||||
var changedKeys = new List<string>();
|
var changedKeys = new List<string>();
|
||||||
var normalizedThemeColor = string.IsNullOrWhiteSpace(state.ThemeColor) ? null : state.ThemeColor;
|
var normalizedThemeColor = string.IsNullOrWhiteSpace(state.ThemeColor) ? null : state.ThemeColor;
|
||||||
|
var normalizedCornerRadiusScale = GlobalAppearanceSettings.NormalizeCornerRadiusScale(state.GlobalCornerRadiusScale);
|
||||||
var normalizedThemeColorMode = ThemeAppearanceValues.NormalizeThemeColorMode(state.ThemeColorMode, state.ThemeColor);
|
var normalizedThemeColorMode = ThemeAppearanceValues.NormalizeThemeColorMode(state.ThemeColorMode, state.ThemeColor);
|
||||||
var normalizedSystemMaterialMode = ThemeAppearanceValues.NormalizeSystemMaterialMode(state.SystemMaterialMode);
|
var normalizedSystemMaterialMode = ThemeAppearanceValues.NormalizeSystemMaterialMode(state.SystemMaterialMode);
|
||||||
var normalizedSelectedWallpaperSeed = string.IsNullOrWhiteSpace(state.SelectedWallpaperSeed)
|
var normalizedSelectedWallpaperSeed = string.IsNullOrWhiteSpace(state.SelectedWallpaperSeed)
|
||||||
@@ -276,6 +279,12 @@ internal sealed class ThemeAppearanceService : IThemeAppearanceService
|
|||||||
changedKeys.Add(nameof(AppSettingsSnapshot.UseSystemChrome));
|
changedKeys.Add(nameof(AppSettingsSnapshot.UseSystemChrome));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Math.Abs(GlobalAppearanceSettings.NormalizeCornerRadiusScale(snapshot.GlobalCornerRadiusScale) - normalizedCornerRadiusScale) > 0.0001d)
|
||||||
|
{
|
||||||
|
snapshot.GlobalCornerRadiusScale = normalizedCornerRadiusScale;
|
||||||
|
changedKeys.Add(nameof(AppSettingsSnapshot.GlobalCornerRadiusScale));
|
||||||
|
}
|
||||||
|
|
||||||
if (!string.Equals(snapshot.ThemeColorMode, normalizedThemeColorMode, StringComparison.OrdinalIgnoreCase))
|
if (!string.Equals(snapshot.ThemeColorMode, normalizedThemeColorMode, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
snapshot.ThemeColorMode = normalizedThemeColorMode;
|
snapshot.ThemeColorMode = normalizedThemeColorMode;
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
<Setter Property="Background" Value="{DynamicResource EditorSelectFieldBackgroundBrush}" />
|
<Setter Property="Background" Value="{DynamicResource EditorSelectFieldBackgroundBrush}" />
|
||||||
<Setter Property="BorderBrush" Value="{DynamicResource EditorSelectOutlineBrush}" />
|
<Setter Property="BorderBrush" Value="{DynamicResource EditorSelectOutlineBrush}" />
|
||||||
<Setter Property="BorderThickness" Value="1" />
|
<Setter Property="BorderThickness" Value="1" />
|
||||||
<Setter Property="CornerRadius" Value="18" />
|
<Setter Property="CornerRadius" Value="{DynamicResource DesignCornerRadiusMd}" />
|
||||||
<Setter Property="Padding" Value="16,14,12,14" />
|
<Setter Property="Padding" Value="16,14,12,14" />
|
||||||
<Setter Property="MinHeight" Value="56" />
|
<Setter Property="MinHeight" Value="56" />
|
||||||
<Setter Property="FontSize" Value="14" />
|
<Setter Property="FontSize" Value="14" />
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
<Setter Property="Background" Value="{DynamicResource EditorSelectFieldBackgroundBrush}" />
|
<Setter Property="Background" Value="{DynamicResource EditorSelectFieldBackgroundBrush}" />
|
||||||
<Setter Property="BorderBrush" Value="{DynamicResource EditorSelectOutlineBrush}" />
|
<Setter Property="BorderBrush" Value="{DynamicResource EditorSelectOutlineBrush}" />
|
||||||
<Setter Property="BorderThickness" Value="1" />
|
<Setter Property="BorderThickness" Value="1" />
|
||||||
<Setter Property="CornerRadius" Value="18" />
|
<Setter Property="CornerRadius" Value="{DynamicResource DesignCornerRadiusMd}" />
|
||||||
<Setter Property="Padding" Value="16,14,12,14" />
|
<Setter Property="Padding" Value="16,14,12,14" />
|
||||||
<Setter Property="MinHeight" Value="56" />
|
<Setter Property="MinHeight" Value="56" />
|
||||||
<Setter Property="Foreground" Value="{DynamicResource ComponentEditorPrimaryTextBrush}" />
|
<Setter Property="Foreground" Value="{DynamicResource ComponentEditorPrimaryTextBrush}" />
|
||||||
@@ -61,7 +61,7 @@
|
|||||||
<Setter Property="Background" Value="Transparent" />
|
<Setter Property="Background" Value="Transparent" />
|
||||||
<Setter Property="Padding" Value="16,12" />
|
<Setter Property="Padding" Value="16,12" />
|
||||||
<Setter Property="Margin" Value="6,4" />
|
<Setter Property="Margin" Value="6,4" />
|
||||||
<Setter Property="CornerRadius" Value="14" />
|
<Setter Property="CornerRadius" Value="{DynamicResource DesignCornerRadiusSm}" />
|
||||||
<Setter Property="MinHeight" Value="44" />
|
<Setter Property="MinHeight" Value="44" />
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
@@ -100,7 +100,7 @@
|
|||||||
<Setter Property="Background" Value="{DynamicResource EditorSurfaceContainerHighBrush}" />
|
<Setter Property="Background" Value="{DynamicResource EditorSurfaceContainerHighBrush}" />
|
||||||
<Setter Property="BorderBrush" Value="{DynamicResource EditorSelectOutlineBrush}" />
|
<Setter Property="BorderBrush" Value="{DynamicResource EditorSelectOutlineBrush}" />
|
||||||
<Setter Property="BorderThickness" Value="1" />
|
<Setter Property="BorderThickness" Value="1" />
|
||||||
<Setter Property="CornerRadius" Value="20" />
|
<Setter Property="CornerRadius" Value="{DynamicResource DesignCornerRadiusLg}" />
|
||||||
<Setter Property="Padding" Value="4" />
|
<Setter Property="Padding" Value="4" />
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@
|
|||||||
<Setter Property="Background" Value="Transparent" />
|
<Setter Property="Background" Value="Transparent" />
|
||||||
<Setter Property="BorderBrush" Value="Transparent" />
|
<Setter Property="BorderBrush" Value="Transparent" />
|
||||||
<Setter Property="BorderThickness" Value="0" />
|
<Setter Property="BorderThickness" Value="0" />
|
||||||
<Setter Property="CornerRadius" Value="16" />
|
<Setter Property="CornerRadius" Value="{DynamicResource DesignCornerRadiusSm}" />
|
||||||
<Setter Property="Padding" Value="18,12" />
|
<Setter Property="Padding" Value="18,12" />
|
||||||
<Setter Property="MinHeight" Value="48" />
|
<Setter Property="MinHeight" Value="48" />
|
||||||
<Setter Property="FontSize" Value="14" />
|
<Setter Property="FontSize" Value="14" />
|
||||||
@@ -139,14 +139,14 @@
|
|||||||
<Setter Property="Background" Value="{DynamicResource ComponentEditorHeroBackgroundBrush}" />
|
<Setter Property="Background" Value="{DynamicResource ComponentEditorHeroBackgroundBrush}" />
|
||||||
<Setter Property="BorderBrush" Value="{DynamicResource ComponentEditorCardBorderBrush}" />
|
<Setter Property="BorderBrush" Value="{DynamicResource ComponentEditorCardBorderBrush}" />
|
||||||
<Setter Property="BorderThickness" Value="1" />
|
<Setter Property="BorderThickness" Value="1" />
|
||||||
<Setter Property="CornerRadius" Value="28" />
|
<Setter Property="CornerRadius" Value="{DynamicResource DesignCornerRadiusXl}" />
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
<Style Selector="Border.component-editor-card">
|
<Style Selector="Border.component-editor-card">
|
||||||
<Setter Property="Background" Value="{DynamicResource ComponentEditorCardBackgroundBrush}" />
|
<Setter Property="Background" Value="{DynamicResource ComponentEditorCardBackgroundBrush}" />
|
||||||
<Setter Property="BorderBrush" Value="{DynamicResource ComponentEditorCardBorderBrush}" />
|
<Setter Property="BorderBrush" Value="{DynamicResource ComponentEditorCardBorderBrush}" />
|
||||||
<Setter Property="BorderThickness" Value="1" />
|
<Setter Property="BorderThickness" Value="1" />
|
||||||
<Setter Property="CornerRadius" Value="24" />
|
<Setter Property="CornerRadius" Value="{DynamicResource DesignCornerRadiusLg}" />
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
<Style Selector="TextBlock.component-editor-headline">
|
<Style Selector="TextBlock.component-editor-headline">
|
||||||
|
|||||||
@@ -4,11 +4,13 @@
|
|||||||
|
|
||||||
<Styles.Resources>
|
<Styles.Resources>
|
||||||
<!-- Unified corner radius tokens used across settings and widget panels -->
|
<!-- Unified corner radius tokens used across settings and widget panels -->
|
||||||
|
<CornerRadius x:Key="DesignCornerRadiusMicro">6</CornerRadius>
|
||||||
<CornerRadius x:Key="DesignCornerRadiusXl">32</CornerRadius>
|
<CornerRadius x:Key="DesignCornerRadiusXl">32</CornerRadius>
|
||||||
<CornerRadius x:Key="DesignCornerRadiusLg">28</CornerRadius>
|
<CornerRadius x:Key="DesignCornerRadiusLg">28</CornerRadius>
|
||||||
<CornerRadius x:Key="DesignCornerRadiusMd">20</CornerRadius>
|
<CornerRadius x:Key="DesignCornerRadiusMd">20</CornerRadius>
|
||||||
<CornerRadius x:Key="DesignCornerRadiusSm">14</CornerRadius>
|
<CornerRadius x:Key="DesignCornerRadiusSm">14</CornerRadius>
|
||||||
<CornerRadius x:Key="DesignCornerRadiusXs">12</CornerRadius>
|
<CornerRadius x:Key="DesignCornerRadiusXs">12</CornerRadius>
|
||||||
|
<CornerRadius x:Key="DesignCornerRadiusIsland">36</CornerRadius>
|
||||||
</Styles.Resources>
|
</Styles.Resources>
|
||||||
|
|
||||||
<Style Selector="TextBlock">
|
<Style Selector="TextBlock">
|
||||||
@@ -19,7 +21,7 @@
|
|||||||
<Setter Property="Background" Value="{DynamicResource AdaptiveButtonBackgroundBrush}" />
|
<Setter Property="Background" Value="{DynamicResource AdaptiveButtonBackgroundBrush}" />
|
||||||
<Setter Property="BorderThickness" Value="1" />
|
<Setter Property="BorderThickness" Value="1" />
|
||||||
<Setter Property="BorderBrush" Value="{DynamicResource AdaptiveButtonBorderBrush}" />
|
<Setter Property="BorderBrush" Value="{DynamicResource AdaptiveButtonBorderBrush}" />
|
||||||
<Setter Property="CornerRadius" Value="20" />
|
<Setter Property="CornerRadius" Value="{DynamicResource DesignCornerRadiusMd}" />
|
||||||
<Setter Property="Foreground" Value="{DynamicResource AdaptiveTextPrimaryBrush}" />
|
<Setter Property="Foreground" Value="{DynamicResource AdaptiveTextPrimaryBrush}" />
|
||||||
<Setter Property="FontSize" Value="14" />
|
<Setter Property="FontSize" Value="14" />
|
||||||
<Setter Property="Padding" Value="16,10" />
|
<Setter Property="Padding" Value="16,10" />
|
||||||
@@ -155,7 +157,7 @@
|
|||||||
|
|
||||||
<Style Selector="Button.swatch-button">
|
<Style Selector="Button.swatch-button">
|
||||||
<Setter Property="BorderThickness" Value="0" />
|
<Setter Property="BorderThickness" Value="0" />
|
||||||
<Setter Property="CornerRadius" Value="16" />
|
<Setter Property="CornerRadius" Value="{DynamicResource DesignCornerRadiusXs}" />
|
||||||
<Setter Property="Opacity" Value="0.88" />
|
<Setter Property="Opacity" Value="0.88" />
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
@@ -175,7 +177,7 @@
|
|||||||
<Setter Property="Background" Value="{DynamicResource AdaptiveGlassPanelBackgroundBrush}" />
|
<Setter Property="Background" Value="{DynamicResource AdaptiveGlassPanelBackgroundBrush}" />
|
||||||
<Setter Property="BorderBrush" Value="{DynamicResource AdaptiveGlassPanelBorderBrush}" />
|
<Setter Property="BorderBrush" Value="{DynamicResource AdaptiveGlassPanelBorderBrush}" />
|
||||||
<Setter Property="BorderThickness" Value="1.2" />
|
<Setter Property="BorderThickness" Value="1.2" />
|
||||||
<Setter Property="CornerRadius" Value="28" />
|
<Setter Property="CornerRadius" Value="{DynamicResource DesignCornerRadiusLg}" />
|
||||||
<Setter Property="Opacity" Value="{DynamicResource AdaptiveGlassPanelOpacity}" />
|
<Setter Property="Opacity" Value="{DynamicResource AdaptiveGlassPanelOpacity}" />
|
||||||
<Setter Property="BoxShadow" Value="0 4 12 #1A000000" />
|
<Setter Property="BoxShadow" Value="0 4 12 #1A000000" />
|
||||||
</Style>
|
</Style>
|
||||||
@@ -184,7 +186,7 @@
|
|||||||
<Setter Property="Background" Value="{DynamicResource AdaptiveGlassStrongBackgroundBrush}" />
|
<Setter Property="Background" Value="{DynamicResource AdaptiveGlassStrongBackgroundBrush}" />
|
||||||
<Setter Property="BorderBrush" Value="{DynamicResource AdaptiveGlassStrongBorderBrush}" />
|
<Setter Property="BorderBrush" Value="{DynamicResource AdaptiveGlassStrongBorderBrush}" />
|
||||||
<Setter Property="BorderThickness" Value="1.5" />
|
<Setter Property="BorderThickness" Value="1.5" />
|
||||||
<Setter Property="CornerRadius" Value="32" />
|
<Setter Property="CornerRadius" Value="{DynamicResource DesignCornerRadiusXl}" />
|
||||||
<Setter Property="Opacity" Value="{DynamicResource AdaptiveGlassStrongOpacity}" />
|
<Setter Property="Opacity" Value="{DynamicResource AdaptiveGlassStrongOpacity}" />
|
||||||
<Setter Property="BoxShadow" Value="0 8 24 #26000000" />
|
<Setter Property="BoxShadow" Value="0 8 24 #26000000" />
|
||||||
</Style>
|
</Style>
|
||||||
@@ -193,7 +195,7 @@
|
|||||||
<Setter Property="Background" Value="{DynamicResource AdaptiveDockGlassBackgroundBrush}" />
|
<Setter Property="Background" Value="{DynamicResource AdaptiveDockGlassBackgroundBrush}" />
|
||||||
<Setter Property="BorderBrush" Value="{DynamicResource AdaptiveDockGlassBorderBrush}" />
|
<Setter Property="BorderBrush" Value="{DynamicResource AdaptiveDockGlassBorderBrush}" />
|
||||||
<Setter Property="BorderThickness" Value="1.5" />
|
<Setter Property="BorderThickness" Value="1.5" />
|
||||||
<Setter Property="CornerRadius" Value="36" />
|
<Setter Property="CornerRadius" Value="{DynamicResource DesignCornerRadiusIsland}" />
|
||||||
<Setter Property="Opacity" Value="{DynamicResource AdaptiveGlassStrongOpacity}" />
|
<Setter Property="Opacity" Value="{DynamicResource AdaptiveGlassStrongOpacity}" />
|
||||||
<Setter Property="BoxShadow" Value="0 12 32 #33000000" />
|
<Setter Property="BoxShadow" Value="0 12 32 #33000000" />
|
||||||
<Setter Property="Transitions">
|
<Setter Property="Transitions">
|
||||||
@@ -206,7 +208,7 @@
|
|||||||
<Style Selector="Border.surface-solid-strong">
|
<Style Selector="Border.surface-solid-strong">
|
||||||
<Setter Property="Background" Value="{DynamicResource AdaptiveGlassStrongBackgroundBrush}" />
|
<Setter Property="Background" Value="{DynamicResource AdaptiveGlassStrongBackgroundBrush}" />
|
||||||
<Setter Property="BorderThickness" Value="0" />
|
<Setter Property="BorderThickness" Value="0" />
|
||||||
<Setter Property="CornerRadius" Value="36" />
|
<Setter Property="CornerRadius" Value="{DynamicResource DesignCornerRadiusIsland}" />
|
||||||
<Setter Property="Opacity" Value="{DynamicResource AdaptiveGlassStrongOpacity}" />
|
<Setter Property="Opacity" Value="{DynamicResource AdaptiveGlassStrongOpacity}" />
|
||||||
<Setter Property="BoxShadow" Value="0 8 22 #2A000000" />
|
<Setter Property="BoxShadow" Value="0 8 22 #2A000000" />
|
||||||
</Style>
|
</Style>
|
||||||
|
|||||||
@@ -48,21 +48,21 @@
|
|||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
<Style Selector="Border.settings-section-card">
|
<Style Selector="Border.settings-section-card">
|
||||||
<Setter Property="CornerRadius" Value="18" />
|
<Setter Property="CornerRadius" Value="{DynamicResource DesignCornerRadiusLg}" />
|
||||||
<Setter Property="Padding" Value="20" />
|
<Setter Property="Padding" Value="20" />
|
||||||
<Setter Property="Margin" Value="0,0,0,14" />
|
<Setter Property="Margin" Value="0,0,0,14" />
|
||||||
<Setter Property="BoxShadow" Value="0 2 8 #12000000" />
|
<Setter Property="BoxShadow" Value="0 2 8 #12000000" />
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
<Style Selector="Border.settings-option-card">
|
<Style Selector="Border.settings-option-card">
|
||||||
<Setter Property="CornerRadius" Value="14" />
|
<Setter Property="CornerRadius" Value="{DynamicResource DesignCornerRadiusSm}" />
|
||||||
<Setter Property="Padding" Value="16" />
|
<Setter Property="Padding" Value="16" />
|
||||||
<Setter Property="Margin" Value="0,0,0,12" />
|
<Setter Property="Margin" Value="0,0,0,12" />
|
||||||
<Setter Property="BoxShadow" Value="0 1 4 #0F000000" />
|
<Setter Property="BoxShadow" Value="0 1 4 #0F000000" />
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
<Style Selector="Border.settings-list-item">
|
<Style Selector="Border.settings-list-item">
|
||||||
<Setter Property="CornerRadius" Value="14" />
|
<Setter Property="CornerRadius" Value="{DynamicResource DesignCornerRadiusSm}" />
|
||||||
<Setter Property="Padding" Value="16" />
|
<Setter Property="Padding" Value="16" />
|
||||||
<Setter Property="Margin" Value="0,0,0,10" />
|
<Setter Property="Margin" Value="0,0,0,10" />
|
||||||
<Setter Property="BoxShadow" Value="0 1 4 #0F000000" />
|
<Setter Property="BoxShadow" Value="0 1 4 #0F000000" />
|
||||||
@@ -77,7 +77,7 @@
|
|||||||
<Setter Property="Background" Value="{DynamicResource AdaptiveButtonBackgroundBrush}" />
|
<Setter Property="Background" Value="{DynamicResource AdaptiveButtonBackgroundBrush}" />
|
||||||
<Setter Property="BorderBrush" Value="{DynamicResource AdaptiveButtonBorderBrush}" />
|
<Setter Property="BorderBrush" Value="{DynamicResource AdaptiveButtonBorderBrush}" />
|
||||||
<Setter Property="BorderThickness" Value="1" />
|
<Setter Property="BorderThickness" Value="1" />
|
||||||
<Setter Property="CornerRadius" Value="12" />
|
<Setter Property="CornerRadius" Value="{DynamicResource DesignCornerRadiusXs}" />
|
||||||
<Setter Property="HorizontalAlignment" Value="Left" />
|
<Setter Property="HorizontalAlignment" Value="Left" />
|
||||||
<Setter Property="VerticalAlignment" Value="Top" />
|
<Setter Property="VerticalAlignment" Value="Top" />
|
||||||
</Style>
|
</Style>
|
||||||
@@ -201,7 +201,7 @@
|
|||||||
<Setter Property="Background" Value="{DynamicResource AdaptiveSurfaceRaisedBrush}" />
|
<Setter Property="Background" Value="{DynamicResource AdaptiveSurfaceRaisedBrush}" />
|
||||||
<Setter Property="BorderBrush" Value="{DynamicResource AdaptiveGlassPanelBorderBrush}" />
|
<Setter Property="BorderBrush" Value="{DynamicResource AdaptiveGlassPanelBorderBrush}" />
|
||||||
<Setter Property="BorderThickness" Value="1" />
|
<Setter Property="BorderThickness" Value="1" />
|
||||||
<Setter Property="CornerRadius" Value="12" />
|
<Setter Property="CornerRadius" Value="{DynamicResource DesignCornerRadiusXs}" />
|
||||||
<Setter Property="Padding" Value="14,12" />
|
<Setter Property="Padding" Value="14,12" />
|
||||||
<Setter Property="Margin" Value="0,0,0,8" />
|
<Setter Property="Margin" Value="0,0,0,8" />
|
||||||
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||||
@@ -229,7 +229,7 @@
|
|||||||
<Setter Property="Background" Value="{DynamicResource AdaptiveAccentBrush}" />
|
<Setter Property="Background" Value="{DynamicResource AdaptiveAccentBrush}" />
|
||||||
<Setter Property="Foreground" Value="{DynamicResource AdaptiveOnAccentBrush}" />
|
<Setter Property="Foreground" Value="{DynamicResource AdaptiveOnAccentBrush}" />
|
||||||
<Setter Property="BorderThickness" Value="0" />
|
<Setter Property="BorderThickness" Value="0" />
|
||||||
<Setter Property="CornerRadius" Value="10" />
|
<Setter Property="CornerRadius" Value="{DynamicResource DesignCornerRadiusXs}" />
|
||||||
<Setter Property="Padding" Value="16,10" />
|
<Setter Property="Padding" Value="16,10" />
|
||||||
<Setter Property="MinHeight" Value="36" />
|
<Setter Property="MinHeight" Value="36" />
|
||||||
</Style>
|
</Style>
|
||||||
@@ -254,7 +254,7 @@
|
|||||||
<Setter Property="Width" Value="36" />
|
<Setter Property="Width" Value="36" />
|
||||||
<Setter Property="Height" Value="36" />
|
<Setter Property="Height" Value="36" />
|
||||||
<Setter Property="Padding" Value="0" />
|
<Setter Property="Padding" Value="0" />
|
||||||
<Setter Property="CornerRadius" Value="10" />
|
<Setter Property="CornerRadius" Value="{DynamicResource DesignCornerRadiusXs}" />
|
||||||
<Setter Property="MinHeight" Value="36" />
|
<Setter Property="MinHeight" Value="36" />
|
||||||
<Setter Property="Background" Value="{DynamicResource AdaptiveButtonBackgroundBrush}" />
|
<Setter Property="Background" Value="{DynamicResource AdaptiveButtonBackgroundBrush}" />
|
||||||
<Setter Property="BorderBrush" Value="{DynamicResource AdaptiveButtonBorderBrush}" />
|
<Setter Property="BorderBrush" Value="{DynamicResource AdaptiveButtonBorderBrush}" />
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ using LanMountainDesktop.Models;
|
|||||||
using LanMountainDesktop.PluginSdk;
|
using LanMountainDesktop.PluginSdk;
|
||||||
using LanMountainDesktop.Services;
|
using LanMountainDesktop.Services;
|
||||||
using LanMountainDesktop.Services.Settings;
|
using LanMountainDesktop.Services.Settings;
|
||||||
|
using LanMountainDesktop.Settings.Core;
|
||||||
|
|
||||||
namespace LanMountainDesktop.ViewModels;
|
namespace LanMountainDesktop.ViewModels;
|
||||||
|
|
||||||
@@ -481,6 +482,9 @@ public sealed partial class AppearanceSettingsPageViewModel : ViewModelBase
|
|||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _useSystemChrome;
|
private bool _useSystemChrome;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private double _globalCornerRadiusScale = GlobalAppearanceSettings.DefaultCornerRadiusScale;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private SelectionOption _selectedThemeColorMode = new(ThemeAppearanceValues.ColorModeSeedMonet, "User theme color Monet");
|
private SelectionOption _selectedThemeColorMode = new(ThemeAppearanceValues.ColorModeSeedMonet, "User theme color Monet");
|
||||||
|
|
||||||
@@ -547,6 +551,12 @@ public sealed partial class AppearanceSettingsPageViewModel : ViewModelBase
|
|||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _systemMaterialLabel = string.Empty;
|
private string _systemMaterialLabel = string.Empty;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private string _globalCornerRadiusLabel = string.Empty;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private string _globalCornerRadiusDescription = string.Empty;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _themeHeader = string.Empty;
|
private string _themeHeader = string.Empty;
|
||||||
|
|
||||||
@@ -668,6 +678,32 @@ public sealed partial class AppearanceSettingsPageViewModel : ViewModelBase
|
|||||||
PersistCurrentState(restartRequired: false);
|
PersistCurrentState(restartRequired: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
partial void OnGlobalCornerRadiusScaleChanged(double value)
|
||||||
|
{
|
||||||
|
if (_isInitializing)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var normalized = GlobalAppearanceSettings.NormalizeCornerRadiusScale(value);
|
||||||
|
if (Math.Abs(normalized - value) > 0.0001d)
|
||||||
|
{
|
||||||
|
_isInitializing = true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
GlobalCornerRadiusScale = normalized;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_isInitializing = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PersistCurrentState(restartRequired: false);
|
||||||
|
}
|
||||||
|
|
||||||
partial void OnSelectedThemeColorModeChanged(SelectionOption value)
|
partial void OnSelectedThemeColorModeChanged(SelectionOption value)
|
||||||
{
|
{
|
||||||
if (_isInitializing || value is null)
|
if (_isInitializing || value is null)
|
||||||
@@ -732,6 +768,8 @@ public sealed partial class AppearanceSettingsPageViewModel : ViewModelBase
|
|||||||
ThemeColorLabel = L("settings.color.theme_color_label", "Theme Accent Color");
|
ThemeColorLabel = L("settings.color.theme_color_label", "Theme Accent Color");
|
||||||
ThemeColorModeLabel = L("settings.appearance.theme_color_mode_label", "Theme color source");
|
ThemeColorModeLabel = L("settings.appearance.theme_color_mode_label", "Theme color source");
|
||||||
SystemMaterialLabel = L("settings.appearance.system_material_label", "System material");
|
SystemMaterialLabel = L("settings.appearance.system_material_label", "System material");
|
||||||
|
GlobalCornerRadiusLabel = L("settings.appearance.corner_radius.label", "Global corner radius");
|
||||||
|
GlobalCornerRadiusDescription = L("settings.appearance.corner_radius.description", "Adjust the shared radius scale used by cards, panels, and component containers.");
|
||||||
ThemeSourceNeutralText = L("settings.appearance.theme_color_mode.neutral", "Default neutral");
|
ThemeSourceNeutralText = L("settings.appearance.theme_color_mode.neutral", "Default neutral");
|
||||||
ThemeSourceUserColorText = L("settings.appearance.theme_color_mode.user", "User theme color Monet");
|
ThemeSourceUserColorText = L("settings.appearance.theme_color_mode.user", "User theme color Monet");
|
||||||
ThemeSourceWallpaperText = L("settings.appearance.theme_color_mode.wallpaper", "Wallpaper Monet");
|
ThemeSourceWallpaperText = L("settings.appearance.theme_color_mode.wallpaper", "Wallpaper Monet");
|
||||||
@@ -776,6 +814,7 @@ public sealed partial class AppearanceSettingsPageViewModel : ViewModelBase
|
|||||||
IsNightMode = theme.IsNightMode;
|
IsNightMode = theme.IsNightMode;
|
||||||
ThemeColor = theme.ThemeColor ?? string.Empty;
|
ThemeColor = theme.ThemeColor ?? string.Empty;
|
||||||
UseSystemChrome = theme.UseSystemChrome;
|
UseSystemChrome = theme.UseSystemChrome;
|
||||||
|
GlobalCornerRadiusScale = GlobalAppearanceSettings.NormalizeCornerRadiusScale(theme.GlobalCornerRadiusScale);
|
||||||
_selectedWallpaperSeed = theme.SelectedWallpaperSeed;
|
_selectedWallpaperSeed = theme.SelectedWallpaperSeed;
|
||||||
SyncCustomSeedPickerWithSavedThemeColor();
|
SyncCustomSeedPickerWithSavedThemeColor();
|
||||||
|
|
||||||
@@ -825,6 +864,7 @@ public sealed partial class AppearanceSettingsPageViewModel : ViewModelBase
|
|||||||
IsNightMode,
|
IsNightMode,
|
||||||
themeColor,
|
themeColor,
|
||||||
UseSystemChrome,
|
UseSystemChrome,
|
||||||
|
GlobalAppearanceSettings.NormalizeCornerRadiusScale(GlobalCornerRadiusScale),
|
||||||
themeColorMode,
|
themeColorMode,
|
||||||
ThemeAppearanceValues.NormalizeSystemMaterialMode(SelectedSystemMaterialMode?.Value),
|
ThemeAppearanceValues.NormalizeSystemMaterialMode(SelectedSystemMaterialMode?.Value),
|
||||||
_selectedWallpaperSeed);
|
_selectedWallpaperSeed);
|
||||||
@@ -956,7 +996,7 @@ public sealed partial class ComponentsSettingsPageViewModel : ViewModelBase
|
|||||||
private string _pageDescription = string.Empty;
|
private string _pageDescription = string.Empty;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _gridHeader = string.Empty;
|
private string _componentsHeader = string.Empty;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _shortSideCellsLabel = string.Empty;
|
private string _shortSideCellsLabel = string.Empty;
|
||||||
@@ -967,6 +1007,18 @@ public sealed partial class ComponentsSettingsPageViewModel : ViewModelBase
|
|||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _spacingPresetLabel = string.Empty;
|
private string _spacingPresetLabel = string.Empty;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private double _globalCornerRadiusScale = GlobalAppearanceSettings.DefaultCornerRadiusScale;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private string _componentRadiusHeader = string.Empty;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private string _globalCornerRadiusLabel = string.Empty;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private string _globalCornerRadiusDescription = string.Empty;
|
||||||
|
|
||||||
public void Load()
|
public void Load()
|
||||||
{
|
{
|
||||||
var state = _settingsFacade.Grid.Get();
|
var state = _settingsFacade.Grid.Get();
|
||||||
@@ -976,6 +1028,9 @@ public sealed partial class ComponentsSettingsPageViewModel : ViewModelBase
|
|||||||
SelectedSpacingPreset = SpacingPresets.FirstOrDefault(option =>
|
SelectedSpacingPreset = SpacingPresets.FirstOrDefault(option =>
|
||||||
string.Equals(option.Value, spacingPreset, StringComparison.OrdinalIgnoreCase))
|
string.Equals(option.Value, spacingPreset, StringComparison.OrdinalIgnoreCase))
|
||||||
?? SpacingPresets[1];
|
?? SpacingPresets[1];
|
||||||
|
|
||||||
|
var theme = _settingsFacade.Theme.Get();
|
||||||
|
GlobalCornerRadiusScale = GlobalAppearanceSettings.NormalizeCornerRadiusScale(theme.GlobalCornerRadiusScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
partial void OnShortSideCellsChanged(int value)
|
partial void OnShortSideCellsChanged(int value)
|
||||||
@@ -1008,6 +1063,32 @@ public sealed partial class ComponentsSettingsPageViewModel : ViewModelBase
|
|||||||
SaveGrid();
|
SaveGrid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
partial void OnGlobalCornerRadiusScaleChanged(double value)
|
||||||
|
{
|
||||||
|
if (_isInitializing)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var normalized = GlobalAppearanceSettings.NormalizeCornerRadiusScale(value);
|
||||||
|
if (Math.Abs(normalized - value) > 0.0001d)
|
||||||
|
{
|
||||||
|
_isInitializing = true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
GlobalCornerRadiusScale = normalized;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_isInitializing = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SaveComponentCornerRadius();
|
||||||
|
}
|
||||||
|
|
||||||
private void SaveGrid()
|
private void SaveGrid()
|
||||||
{
|
{
|
||||||
_settingsFacade.Grid.Save(new GridSettingsState(
|
_settingsFacade.Grid.Save(new GridSettingsState(
|
||||||
@@ -1016,23 +1097,39 @@ public sealed partial class ComponentsSettingsPageViewModel : ViewModelBase
|
|||||||
Math.Clamp(EdgeInsetPercent, 0, 30)));
|
Math.Clamp(EdgeInsetPercent, 0, 30)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SaveComponentCornerRadius()
|
||||||
|
{
|
||||||
|
var theme = _settingsFacade.Theme.Get();
|
||||||
|
_settingsFacade.Theme.Save(new ThemeAppearanceSettingsState(
|
||||||
|
theme.IsNightMode,
|
||||||
|
theme.ThemeColor,
|
||||||
|
theme.UseSystemChrome,
|
||||||
|
GlobalAppearanceSettings.NormalizeCornerRadiusScale(GlobalCornerRadiusScale),
|
||||||
|
theme.ThemeColorMode,
|
||||||
|
theme.SystemMaterialMode,
|
||||||
|
theme.SelectedWallpaperSeed));
|
||||||
|
}
|
||||||
|
|
||||||
private IReadOnlyList<SelectionOption> CreateSpacingPresets()
|
private IReadOnlyList<SelectionOption> CreateSpacingPresets()
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
[
|
[
|
||||||
new SelectionOption("Compact", L("settings.grid.spacing_compact", "Compact")),
|
new SelectionOption("Compact", L("settings.components.spacing_compact", "Compact")),
|
||||||
new SelectionOption("Relaxed", L("settings.grid.spacing_relaxed", "Relaxed"))
|
new SelectionOption("Relaxed", L("settings.components.spacing_relaxed", "Relaxed"))
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RefreshLocalizedText()
|
private void RefreshLocalizedText()
|
||||||
{
|
{
|
||||||
PageTitle = L("settings.components.title", "Components");
|
PageTitle = L("settings.components.title", "Components");
|
||||||
PageDescription = L("settings.components.description", "Desktop grid and widget placement density.");
|
PageDescription = L("settings.components.description", "Adjust component layout and corner design.");
|
||||||
GridHeader = L("settings.components.grid_header", "Grid Layout");
|
ComponentsHeader = L("settings.components.header", "Grid Settings");
|
||||||
ShortSideCellsLabel = L("settings.grid.short_side_label", "Short Side Cells");
|
ShortSideCellsLabel = L("settings.components.short_side_label", "Short Side Cells");
|
||||||
EdgeInsetPercentLabel = L("settings.grid.edge_inset_label", "Screen Inset");
|
EdgeInsetPercentLabel = L("settings.components.edge_inset_label", "Screen Inset");
|
||||||
SpacingPresetLabel = L("settings.grid.spacing_label", "Grid Spacing");
|
SpacingPresetLabel = L("settings.components.spacing_label", "Component Spacing");
|
||||||
|
ComponentRadiusHeader = L("settings.components.corner_radius.header", "Corner Design");
|
||||||
|
GlobalCornerRadiusLabel = L("settings.components.corner_radius.label", "Component Corner Radius");
|
||||||
|
GlobalCornerRadiusDescription = L("settings.components.corner_radius.description", "Adjust the shared corner radius used by component containers, and expand the internal safe area with it.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private string L(string key, string fallback)
|
private string L(string key, string fallback)
|
||||||
|
|||||||
@@ -53,7 +53,7 @@
|
|||||||
|
|
||||||
<!-- MD3 Button Styles -->
|
<!-- MD3 Button Styles -->
|
||||||
<Style Selector="Button.component-editor-footer-button">
|
<Style Selector="Button.component-editor-footer-button">
|
||||||
<Setter Property="CornerRadius" Value="20" />
|
<Setter Property="CornerRadius" Value="{DynamicResource DesignCornerRadiusMd}" />
|
||||||
<Setter Property="Background" Value="{DynamicResource EditorPrimaryBrush}" />
|
<Setter Property="Background" Value="{DynamicResource EditorPrimaryBrush}" />
|
||||||
<Setter Property="Foreground" Value="{DynamicResource EditorOnPrimaryBrush}" />
|
<Setter Property="Foreground" Value="{DynamicResource EditorOnPrimaryBrush}" />
|
||||||
<Setter Property="Height" Value="40" />
|
<Setter Property="Height" Value="40" />
|
||||||
@@ -118,7 +118,7 @@
|
|||||||
Height="64"
|
Height="64"
|
||||||
Background="{DynamicResource EditorPrimaryBrush}"
|
Background="{DynamicResource EditorPrimaryBrush}"
|
||||||
Foreground="{DynamicResource EditorOnPrimaryBrush}"
|
Foreground="{DynamicResource EditorOnPrimaryBrush}"
|
||||||
CornerRadius="18"
|
CornerRadius="{DynamicResource DesignCornerRadiusMd}"
|
||||||
Classes="accent"
|
Classes="accent"
|
||||||
Click="OnCloseClick">
|
Click="OnCloseClick">
|
||||||
<Button.Styles>
|
<Button.Styles>
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
ColumnDefinitions="240,*"
|
ColumnDefinitions="240,*"
|
||||||
ColumnSpacing="12">
|
ColumnSpacing="12">
|
||||||
<Border Classes="surface-translucent-panel"
|
<Border Classes="surface-translucent-panel"
|
||||||
CornerRadius="24"
|
CornerRadius="{DynamicResource DesignCornerRadiusLg}"
|
||||||
Padding="10">
|
Padding="10">
|
||||||
<ListBox x:Name="CategoryListBox"
|
<ListBox x:Name="CategoryListBox"
|
||||||
Background="Transparent"
|
Background="Transparent"
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
<DataTemplate x:DataType="vm:ComponentLibraryCategoryViewModel">
|
<DataTemplate x:DataType="vm:ComponentLibraryCategoryViewModel">
|
||||||
<Border Padding="10"
|
<Border Padding="10"
|
||||||
Margin="0,0,0,6"
|
Margin="0,0,0,6"
|
||||||
CornerRadius="14"
|
CornerRadius="{DynamicResource DesignCornerRadiusSm}"
|
||||||
Background="{DynamicResource AdaptiveNavItemBackgroundBrush}">
|
Background="{DynamicResource AdaptiveNavItemBackgroundBrush}">
|
||||||
<Grid ColumnDefinitions="Auto,*"
|
<Grid ColumnDefinitions="Auto,*"
|
||||||
ColumnSpacing="8">
|
ColumnSpacing="8">
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
|
|
||||||
<Border Grid.Column="1"
|
<Border Grid.Column="1"
|
||||||
Classes="surface-translucent-strong"
|
Classes="surface-translucent-strong"
|
||||||
CornerRadius="24"
|
CornerRadius="{DynamicResource DesignCornerRadiusLg}"
|
||||||
Padding="10">
|
Padding="10">
|
||||||
<ScrollViewer VerticalScrollBarVisibility="Auto"
|
<ScrollViewer VerticalScrollBarVisibility="Auto"
|
||||||
HorizontalScrollBarVisibility="Disabled">
|
HorizontalScrollBarVisibility="Disabled">
|
||||||
@@ -87,14 +87,14 @@
|
|||||||
<Border Width="240"
|
<Border Width="240"
|
||||||
Height="220"
|
Height="220"
|
||||||
Margin="6"
|
Margin="6"
|
||||||
CornerRadius="18"
|
CornerRadius="{DynamicResource DesignCornerRadiusLg}"
|
||||||
Padding="10"
|
Padding="10"
|
||||||
Background="{DynamicResource AdaptiveSurfaceRaisedBrush}"
|
Background="{DynamicResource AdaptiveSurfaceRaisedBrush}"
|
||||||
BorderBrush="{DynamicResource AdaptiveButtonBorderBrush}"
|
BorderBrush="{DynamicResource AdaptiveButtonBorderBrush}"
|
||||||
BorderThickness="1">
|
BorderThickness="1">
|
||||||
<Grid RowDefinitions="*,Auto,Auto"
|
<Grid RowDefinitions="*,Auto,Auto"
|
||||||
RowSpacing="8">
|
RowSpacing="8">
|
||||||
<Border CornerRadius="12"
|
<Border CornerRadius="{DynamicResource DesignCornerRadiusXs}"
|
||||||
Background="{DynamicResource AdaptiveGlassPanelBackgroundBrush}"
|
Background="{DynamicResource AdaptiveGlassPanelBackgroundBrush}"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
BorderBrush="{DynamicResource AdaptiveGlassPanelBorderBrush}"
|
BorderBrush="{DynamicResource AdaptiveGlassPanelBorderBrush}"
|
||||||
|
|||||||
@@ -326,7 +326,7 @@ public partial class AnalogClockWidget : UserControl, IDesktopComponentWidget, I
|
|||||||
_currentCellSize = Math.Max(1, cellSize);
|
_currentCellSize = Math.Max(1, cellSize);
|
||||||
var scale = ResolveScale();
|
var scale = ResolveScale();
|
||||||
|
|
||||||
RootBorder.CornerRadius = new CornerRadius(Math.Clamp(42 * scale, 16, 56));
|
RootBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(42 * scale, 16, 56);
|
||||||
RootBorder.Padding = new Thickness(Math.Clamp(14 * scale, 8, 26));
|
RootBorder.Padding = new Thickness(Math.Clamp(14 * scale, 8, 26));
|
||||||
ApplyModeVisualIfNeeded();
|
ApplyModeVisualIfNeeded();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -381,12 +381,12 @@ public partial class BaiduHotSearchWidget : UserControl, IDesktopComponentWidget
|
|||||||
var totalWidth = Bounds.Width > 1 ? Bounds.Width : _currentCellSize * BaseWidthCells;
|
var totalWidth = Bounds.Width > 1 ? Bounds.Width : _currentCellSize * BaseWidthCells;
|
||||||
var totalHeight = Bounds.Height > 1 ? Bounds.Height : _currentCellSize * BaseHeightCells;
|
var totalHeight = Bounds.Height > 1 ? Bounds.Height : _currentCellSize * BaseHeightCells;
|
||||||
|
|
||||||
RootBorder.CornerRadius = new CornerRadius(Math.Clamp(34 * softScale, 16, 52));
|
RootBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(34 * softScale, 16, 52);
|
||||||
RootBorder.Padding = new Thickness(0);
|
RootBorder.Padding = new Thickness(0);
|
||||||
|
|
||||||
var horizontalPadding = Math.Clamp(16 * softScale, 8, 24);
|
var horizontalPadding = Math.Clamp(16 * softScale, 8, 24);
|
||||||
var verticalPadding = Math.Clamp(14 * softScale, 7, 20);
|
var verticalPadding = Math.Clamp(14 * softScale, 7, 20);
|
||||||
CardBorder.CornerRadius = new CornerRadius(Math.Clamp(34 * softScale, 16, 52));
|
CardBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(34 * softScale, 16, 52);
|
||||||
CardBorder.Padding = new Thickness(horizontalPadding, verticalPadding, horizontalPadding, verticalPadding);
|
CardBorder.Padding = new Thickness(horizontalPadding, verticalPadding, horizontalPadding, verticalPadding);
|
||||||
|
|
||||||
var innerWidth = Math.Max(120, totalWidth - (horizontalPadding * 2d));
|
var innerWidth = Math.Max(120, totalWidth - (horizontalPadding * 2d));
|
||||||
|
|||||||
@@ -386,12 +386,12 @@ public partial class BilibiliHotSearchWidget : UserControl, IDesktopComponentWid
|
|||||||
var totalWidth = Bounds.Width > 1 ? Bounds.Width : _currentCellSize * BaseWidthCells;
|
var totalWidth = Bounds.Width > 1 ? Bounds.Width : _currentCellSize * BaseWidthCells;
|
||||||
var totalHeight = Bounds.Height > 1 ? Bounds.Height : _currentCellSize * BaseHeightCells;
|
var totalHeight = Bounds.Height > 1 ? Bounds.Height : _currentCellSize * BaseHeightCells;
|
||||||
|
|
||||||
RootBorder.CornerRadius = new CornerRadius(Math.Clamp(34 * softScale, 16, 52));
|
RootBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(34 * softScale, 16, 52);
|
||||||
RootBorder.Padding = new Thickness(0);
|
RootBorder.Padding = new Thickness(0);
|
||||||
|
|
||||||
var horizontalPadding = Math.Clamp(16 * softScale, 8, 24);
|
var horizontalPadding = Math.Clamp(16 * softScale, 8, 24);
|
||||||
var verticalPadding = Math.Clamp(14 * softScale, 7, 20);
|
var verticalPadding = Math.Clamp(14 * softScale, 7, 20);
|
||||||
CardBorder.CornerRadius = new CornerRadius(Math.Clamp(34 * softScale, 16, 52));
|
CardBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(34 * softScale, 16, 52);
|
||||||
CardBorder.Padding = new Thickness(horizontalPadding, verticalPadding, horizontalPadding, verticalPadding);
|
CardBorder.Padding = new Thickness(horizontalPadding, verticalPadding, horizontalPadding, verticalPadding);
|
||||||
|
|
||||||
var innerWidth = Math.Max(120, totalWidth - (horizontalPadding * 2d));
|
var innerWidth = Math.Max(120, totalWidth - (horizontalPadding * 2d));
|
||||||
|
|||||||
@@ -79,11 +79,11 @@ public partial class BrowserWidget : UserControl, IDesktopComponentWidget,
|
|||||||
{
|
{
|
||||||
_currentCellSize = Math.Max(1, cellSize);
|
_currentCellSize = Math.Max(1, cellSize);
|
||||||
|
|
||||||
RootBorder.CornerRadius = new CornerRadius(Math.Clamp(_currentCellSize * 0.34, 12, 28));
|
RootBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(_currentCellSize * 0.34, 12, 28);
|
||||||
RootBorder.Padding = new Thickness(Math.Clamp(_currentCellSize * 0.20, 8, 18));
|
RootBorder.Padding = new Thickness(Math.Clamp(_currentCellSize * 0.20, 8, 18));
|
||||||
|
|
||||||
WebViewHostBorder.CornerRadius = new CornerRadius(Math.Clamp(_currentCellSize * 0.24, 10, 22));
|
WebViewHostBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(_currentCellSize * 0.24, 10, 22);
|
||||||
AddressBarBorder.CornerRadius = new CornerRadius(Math.Clamp(_currentCellSize * 0.22, 10, 20));
|
AddressBarBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(_currentCellSize * 0.22, 10, 20);
|
||||||
AddressBarBorder.Padding = new Thickness(8, 6);
|
AddressBarBorder.Padding = new Thickness(8, 6);
|
||||||
|
|
||||||
if (RootBorder.Child is Grid rootGrid)
|
if (RootBorder.Child is Grid rootGrid)
|
||||||
|
|||||||
@@ -613,18 +613,17 @@ public partial class ClassScheduleWidget : UserControl, IDesktopComponentWidget,
|
|||||||
? CreateBrush("#FF4FC3F7")
|
? CreateBrush("#FF4FC3F7")
|
||||||
: CreateBrush("#FF3250");
|
: CreateBrush("#FF3250");
|
||||||
|
|
||||||
var cornerRadius = Math.Clamp(_currentCellSize * 0.45, 24, 44);
|
RootBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(_currentCellSize * 0.45, 24, 44);
|
||||||
RootBorder.CornerRadius = new CornerRadius(cornerRadius);
|
|
||||||
RootBorder.Background = _isNightVisual
|
RootBorder.Background = _isNightVisual
|
||||||
? CreateGradientBrush("#171A21", "#0C0E14")
|
? CreateGradientBrush("#171A21", "#0C0E14")
|
||||||
: CreateGradientBrush("#F7F8FC", "#ECEFF6");
|
: CreateGradientBrush("#F7F8FC", "#ECEFF6");
|
||||||
RootBorder.BorderBrush = CreateBrush(_isNightVisual ? "#24FFFFFF" : "#15000000");
|
RootBorder.BorderBrush = CreateBrush(_isNightVisual ? "#24FFFFFF" : "#15000000");
|
||||||
|
|
||||||
var rootPadding = new Thickness(
|
var rootPadding = new Thickness(
|
||||||
Math.Clamp(16 * scale, 10, 24),
|
ComponentChromeCornerRadiusHelper.SafeValue(16 * scale, 10, 24),
|
||||||
Math.Clamp(14 * scale, 9, 20),
|
ComponentChromeCornerRadiusHelper.SafeValue(14 * scale, 9, 20),
|
||||||
Math.Clamp(16 * scale, 10, 24),
|
ComponentChromeCornerRadiusHelper.SafeValue(16 * scale, 10, 24),
|
||||||
Math.Clamp(14 * scale, 8, 20));
|
ComponentChromeCornerRadiusHelper.SafeValue(14 * scale, 8, 20));
|
||||||
RootBorder.Padding = rootPadding;
|
RootBorder.Padding = rootPadding;
|
||||||
|
|
||||||
LayoutGrid.RowSpacing = Math.Clamp(14 * scale, 6, 20);
|
LayoutGrid.RowSpacing = Math.Clamp(14 * scale, 6, 20);
|
||||||
|
|||||||
@@ -480,7 +480,7 @@ public partial class CnrDailyNewsWidget : UserControl, IDesktopComponentWidget,
|
|||||||
{
|
{
|
||||||
Width = 160,
|
Width = 160,
|
||||||
Height = 90,
|
Height = 90,
|
||||||
CornerRadius = new CornerRadius(16),
|
CornerRadius = ComponentChromeCornerRadiusHelper.Scale(16, 8, 22),
|
||||||
ClipToBounds = true,
|
ClipToBounds = true,
|
||||||
Background = new SolidColorBrush(Color.Parse("#E6E6E6")),
|
Background = new SolidColorBrush(Color.Parse("#E6E6E6")),
|
||||||
IsHitTestVisible = false
|
IsHitTestVisible = false
|
||||||
@@ -545,10 +545,10 @@ public partial class CnrDailyNewsWidget : UserControl, IDesktopComponentWidget,
|
|||||||
var scale = ResolveScale();
|
var scale = ResolveScale();
|
||||||
var totalWidth = Bounds.Width > 1 ? Bounds.Width : _currentCellSize * BaseWidthCells;
|
var totalWidth = Bounds.Width > 1 ? Bounds.Width : _currentCellSize * BaseWidthCells;
|
||||||
|
|
||||||
RootBorder.CornerRadius = new CornerRadius(Math.Clamp(34 * scale, 16, 52));
|
RootBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(34 * scale, 16, 52);
|
||||||
RootBorder.Padding = new Thickness(0);
|
RootBorder.Padding = new Thickness(0);
|
||||||
|
|
||||||
CardBorder.CornerRadius = new CornerRadius(Math.Clamp(34 * scale, 16, 52));
|
CardBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(34 * scale, 16, 52);
|
||||||
CardBorder.Padding = new Thickness(
|
CardBorder.Padding = new Thickness(
|
||||||
Math.Clamp(16 * scale, 8, 24),
|
Math.Clamp(16 * scale, 8, 24),
|
||||||
Math.Clamp(14 * scale, 7, 22),
|
Math.Clamp(14 * scale, 7, 22),
|
||||||
@@ -573,8 +573,8 @@ public partial class CnrDailyNewsWidget : UserControl, IDesktopComponentWidget,
|
|||||||
News1ImageHost.Height = imageHeight;
|
News1ImageHost.Height = imageHeight;
|
||||||
News2ImageHost.Width = imageWidth;
|
News2ImageHost.Width = imageWidth;
|
||||||
News2ImageHost.Height = imageHeight;
|
News2ImageHost.Height = imageHeight;
|
||||||
News1ImageHost.CornerRadius = new CornerRadius(Math.Clamp(16 * scale, 8, 22));
|
News1ImageHost.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(16 * scale, 8, 22);
|
||||||
News2ImageHost.CornerRadius = new CornerRadius(Math.Clamp(16 * scale, 8, 22));
|
News2ImageHost.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(16 * scale, 8, 22);
|
||||||
|
|
||||||
var columnGap = Math.Clamp(12 * scale, 6, 18);
|
var columnGap = Math.Clamp(12 * scale, 6, 18);
|
||||||
NewsItem1Grid.ColumnSpacing = columnGap;
|
NewsItem1Grid.ColumnSpacing = columnGap;
|
||||||
@@ -611,7 +611,7 @@ public partial class CnrDailyNewsWidget : UserControl, IDesktopComponentWidget,
|
|||||||
|
|
||||||
row.ImageHost.Width = imageWidth;
|
row.ImageHost.Width = imageWidth;
|
||||||
row.ImageHost.Height = imageHeight;
|
row.ImageHost.Height = imageHeight;
|
||||||
row.ImageHost.CornerRadius = new CornerRadius(Math.Clamp(16 * scale, 8, 22));
|
row.ImageHost.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(16 * scale, 8, 22);
|
||||||
|
|
||||||
row.TitleTextBlock.MaxWidth = availableTextWidth;
|
row.TitleTextBlock.MaxWidth = availableTextWidth;
|
||||||
row.TitleTextBlock.FontSize = Math.Clamp(19 * scale, 10, 25);
|
row.TitleTextBlock.FontSize = Math.Clamp(19 * scale, 10, 25);
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Media;
|
||||||
|
using LanMountainDesktop.Host.Abstractions;
|
||||||
|
using LanMountainDesktop.Services;
|
||||||
|
|
||||||
|
namespace LanMountainDesktop.Views.Components;
|
||||||
|
|
||||||
|
internal static class ComponentChromeCornerRadiusHelper
|
||||||
|
{
|
||||||
|
public static double ResolveScale(ComponentChromeContext? chromeContext = null)
|
||||||
|
{
|
||||||
|
if (chromeContext is not null)
|
||||||
|
{
|
||||||
|
return Math.Max(0.1d, chromeContext.GlobalCornerRadiusScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.Max(0.1d, HostAppearanceThemeProvider.GetOrCreate().GetCurrent().GlobalCornerRadiusScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CornerRadius Scale(double baseRadius, double min, double max, ComponentChromeContext? chromeContext = null)
|
||||||
|
{
|
||||||
|
var scale = ResolveScale(chromeContext);
|
||||||
|
return new CornerRadius(Math.Clamp(baseRadius * scale, min * scale, max * scale));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Apply(CornerRadius radius, params Border?[] chromeLayers)
|
||||||
|
{
|
||||||
|
foreach (var chromeLayer in chromeLayers)
|
||||||
|
{
|
||||||
|
if (chromeLayer is not null)
|
||||||
|
{
|
||||||
|
chromeLayer.CornerRadius = radius;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CornerRadius ResolveToken(string key, double fallback)
|
||||||
|
{
|
||||||
|
var application = Application.Current;
|
||||||
|
return application is not null &&
|
||||||
|
application.Resources.TryGetResource(key, application.ActualThemeVariant, out var resource) &&
|
||||||
|
resource is CornerRadius radius
|
||||||
|
? radius
|
||||||
|
: new CornerRadius(fallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double ScaleValue(double value, ComponentChromeContext? chromeContext = null)
|
||||||
|
{
|
||||||
|
return value * ResolveScale(chromeContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double ResolveContentSafetyScale(
|
||||||
|
ComponentChromeContext? chromeContext = null,
|
||||||
|
double responsiveness = 0.45d)
|
||||||
|
{
|
||||||
|
var scale = ResolveScale(chromeContext);
|
||||||
|
var normalizedResponsiveness = Math.Clamp(responsiveness, 0d, 1d);
|
||||||
|
return 1d + ((scale - 1d) * normalizedResponsiveness);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double SafeValue(
|
||||||
|
double baseValue,
|
||||||
|
double min,
|
||||||
|
double max,
|
||||||
|
ComponentChromeContext? chromeContext = null,
|
||||||
|
double responsiveness = 0.45d)
|
||||||
|
{
|
||||||
|
var safetyScale = ResolveContentSafetyScale(chromeContext, responsiveness);
|
||||||
|
return Math.Clamp(baseValue * safetyScale, min * safetyScale, max * safetyScale);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -101,7 +101,7 @@ public partial class DailyArtworkWidget : UserControl, IDesktopComponentWidget,
|
|||||||
_currentCellSize = Math.Max(1, cellSize);
|
_currentCellSize = Math.Max(1, cellSize);
|
||||||
var scale = ResolveScale();
|
var scale = ResolveScale();
|
||||||
|
|
||||||
RootBorder.CornerRadius = new CornerRadius(Math.Clamp(34 * scale, 16, 52));
|
RootBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(34 * scale, 16, 52);
|
||||||
|
|
||||||
InfoPanel.Padding = new Thickness(
|
InfoPanel.Padding = new Thickness(
|
||||||
Math.Clamp(18 * scale, 10, 28),
|
Math.Clamp(18 * scale, 10, 28),
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ public partial class DailyPoetryWidget : UserControl, IDesktopComponentWidget, I
|
|||||||
_currentCellSize = Math.Max(1, cellSize);
|
_currentCellSize = Math.Max(1, cellSize);
|
||||||
var scale = ResolveScale();
|
var scale = ResolveScale();
|
||||||
|
|
||||||
RootBorder.CornerRadius = new CornerRadius(Math.Clamp(34 * scale, 16, 52));
|
RootBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(34 * scale, 16, 52);
|
||||||
RootBorder.Padding = new Thickness(
|
RootBorder.Padding = new Thickness(
|
||||||
Math.Clamp(20 * scale, 10, 34),
|
Math.Clamp(20 * scale, 10, 34),
|
||||||
Math.Clamp(16 * scale, 8, 28),
|
Math.Clamp(16 * scale, 8, 28),
|
||||||
|
|||||||
@@ -328,7 +328,7 @@ public partial class DailyWord2x2Widget : UserControl, IDesktopComponentWidget,
|
|||||||
var totalWidth = Bounds.Width > 1 ? Bounds.Width : _currentCellSize * BaseWidthCells;
|
var totalWidth = Bounds.Width > 1 ? Bounds.Width : _currentCellSize * BaseWidthCells;
|
||||||
var totalHeight = Bounds.Height > 1 ? Bounds.Height : _currentCellSize * BaseHeightCells;
|
var totalHeight = Bounds.Height > 1 ? Bounds.Height : _currentCellSize * BaseHeightCells;
|
||||||
|
|
||||||
RootBorder.CornerRadius = new CornerRadius(Math.Clamp(30 * scale, 14, 40));
|
RootBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(30 * scale, 14, 40);
|
||||||
CardBorder.CornerRadius = RootBorder.CornerRadius;
|
CardBorder.CornerRadius = RootBorder.CornerRadius;
|
||||||
CardBorder.Padding = new Thickness(
|
CardBorder.Padding = new Thickness(
|
||||||
Math.Clamp(12 * scale, 8, 18),
|
Math.Clamp(12 * scale, 8, 18),
|
||||||
|
|||||||
@@ -298,10 +298,11 @@ public partial class DailyWordWidget : UserControl, IDesktopComponentWidget, IRe
|
|||||||
isFourByThree = widthRatio >= 0.9 && heightRatio >= 1.35;
|
isFourByThree = widthRatio >= 0.9 && heightRatio >= 1.35;
|
||||||
}
|
}
|
||||||
|
|
||||||
RootBorder.CornerRadius = new CornerRadius(Math.Clamp(34 * scale, 16, 52));
|
var containerRadius = ComponentChromeCornerRadiusHelper.Scale(34 * scale, 16, 52);
|
||||||
|
RootBorder.CornerRadius = containerRadius;
|
||||||
RootBorder.Padding = new Thickness(0);
|
RootBorder.Padding = new Thickness(0);
|
||||||
|
|
||||||
CardBorder.CornerRadius = new CornerRadius(Math.Clamp(34 * scale, 16, 52));
|
CardBorder.CornerRadius = containerRadius;
|
||||||
CardBorder.Padding = new Thickness(
|
CardBorder.Padding = new Thickness(
|
||||||
Math.Clamp(16 * scale, 8, 24),
|
Math.Clamp(16 * scale, 8, 24),
|
||||||
Math.Clamp(14 * scale, 7, 22),
|
Math.Clamp(14 * scale, 7, 22),
|
||||||
|
|||||||
@@ -325,7 +325,7 @@ public partial class DateWidget : UserControl, IDesktopComponentWidget, ITimeZon
|
|||||||
{
|
{
|
||||||
var scale = ResolveScale();
|
var scale = ResolveScale();
|
||||||
|
|
||||||
RootBorder.CornerRadius = new CornerRadius(Math.Clamp(28 * scale, 16, 40));
|
RootBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(28 * scale, 16, 40);
|
||||||
RootBorder.Padding = new Thickness(Math.Clamp(11 * scale, 7, 17));
|
RootBorder.Padding = new Thickness(Math.Clamp(11 * scale, 7, 17));
|
||||||
|
|
||||||
LayoutRoot.ColumnSpacing = Math.Clamp(10 * scale, 6, 16);
|
LayoutRoot.ColumnSpacing = Math.Clamp(10 * scale, 6, 16);
|
||||||
@@ -337,7 +337,7 @@ public partial class DateWidget : UserControl, IDesktopComponentWidget, ITimeZon
|
|||||||
Math.Clamp(2.4 * scale, 1, 4));
|
Math.Clamp(2.4 * scale, 1, 4));
|
||||||
CalendarGrid.Margin = new Thickness(0, 0, 0, Math.Clamp(0.8 * scale, 0, 2));
|
CalendarGrid.Margin = new Thickness(0, 0, 0, Math.Clamp(0.8 * scale, 0, 2));
|
||||||
|
|
||||||
LunarCardBorder.CornerRadius = new CornerRadius(Math.Clamp(24 * scale, 14, 34));
|
LunarCardBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(24 * scale, 14, 34);
|
||||||
LunarCardBorder.Padding = new Thickness(Math.Clamp(14 * scale, 8, 20));
|
LunarCardBorder.Padding = new Thickness(Math.Clamp(14 * scale, 8, 20));
|
||||||
RightPanelGrid.RowSpacing = Math.Clamp(7.5 * scale, 3.5, 11);
|
RightPanelGrid.RowSpacing = Math.Clamp(7.5 * scale, 3.5, 11);
|
||||||
DividerBorder.Margin = new Thickness(0, Math.Clamp(1 * scale, 0, 2), 0, Math.Clamp(1 * scale, 0, 2));
|
DividerBorder.Margin = new Thickness(0, Math.Clamp(1 * scale, 0, 2), 0, Math.Clamp(1 * scale, 0, 2));
|
||||||
|
|||||||
@@ -3,7 +3,9 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
|
using LanMountainDesktop.Appearance;
|
||||||
using LanMountainDesktop.ComponentSystem;
|
using LanMountainDesktop.ComponentSystem;
|
||||||
|
using LanMountainDesktop.Host.Abstractions;
|
||||||
using LanMountainDesktop.PluginSdk;
|
using LanMountainDesktop.PluginSdk;
|
||||||
using LanMountainDesktop.Services;
|
using LanMountainDesktop.Services;
|
||||||
using LanMountainDesktop.Services.Settings;
|
using LanMountainDesktop.Services.Settings;
|
||||||
@@ -30,7 +32,11 @@ public sealed class DesktopComponentRuntimeRegistration
|
|||||||
string? displayNameLocalizationKey,
|
string? displayNameLocalizationKey,
|
||||||
Func<Control> controlFactory,
|
Func<Control> controlFactory,
|
||||||
Func<double, double>? cornerRadiusResolver = null)
|
Func<double, double>? cornerRadiusResolver = null)
|
||||||
: this(componentId, displayNameLocalizationKey, _ => controlFactory(), cornerRadiusResolver)
|
: this(
|
||||||
|
componentId,
|
||||||
|
displayNameLocalizationKey,
|
||||||
|
_ => controlFactory(),
|
||||||
|
cornerRadiusResolver is null ? null : chromeContext => cornerRadiusResolver(chromeContext.CellSize))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,6 +45,19 @@ public sealed class DesktopComponentRuntimeRegistration
|
|||||||
string? displayNameLocalizationKey,
|
string? displayNameLocalizationKey,
|
||||||
Func<DesktopComponentControlFactoryContext, Control> controlFactory,
|
Func<DesktopComponentControlFactoryContext, Control> controlFactory,
|
||||||
Func<double, double>? cornerRadiusResolver = null)
|
Func<double, double>? cornerRadiusResolver = null)
|
||||||
|
: this(
|
||||||
|
componentId,
|
||||||
|
displayNameLocalizationKey,
|
||||||
|
controlFactory,
|
||||||
|
cornerRadiusResolver is null ? null : chromeContext => cornerRadiusResolver(chromeContext.CellSize))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public DesktopComponentRuntimeRegistration(
|
||||||
|
string componentId,
|
||||||
|
string? displayNameLocalizationKey,
|
||||||
|
Func<DesktopComponentControlFactoryContext, Control> controlFactory,
|
||||||
|
Func<ComponentChromeContext, double>? cornerRadiusResolver = null)
|
||||||
{
|
{
|
||||||
ArgumentException.ThrowIfNullOrWhiteSpace(componentId);
|
ArgumentException.ThrowIfNullOrWhiteSpace(componentId);
|
||||||
ArgumentNullException.ThrowIfNull(controlFactory);
|
ArgumentNullException.ThrowIfNull(controlFactory);
|
||||||
@@ -57,22 +76,27 @@ public sealed class DesktopComponentRuntimeRegistration
|
|||||||
|
|
||||||
public Func<DesktopComponentControlFactoryContext, Control> ControlFactory { get; }
|
public Func<DesktopComponentControlFactoryContext, Control> ControlFactory { get; }
|
||||||
|
|
||||||
public Func<double, double>? CornerRadiusResolver { get; }
|
public Func<ComponentChromeContext, double>? CornerRadiusResolver { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class DesktopComponentRuntimeDescriptor
|
public sealed class DesktopComponentRuntimeDescriptor
|
||||||
{
|
{
|
||||||
private static readonly Func<double, double> DefaultCornerRadiusResolver =
|
private static readonly Func<ComponentChromeContext, double> DefaultCornerRadiusResolver =
|
||||||
cellSize => Math.Clamp(cellSize * 0.22, 8, 18);
|
chromeContext =>
|
||||||
|
{
|
||||||
|
var scale = Math.Max(0.1d, chromeContext.GlobalCornerRadiusScale);
|
||||||
|
var baseRadius = Math.Clamp(chromeContext.CellSize * 0.22, 8, 18);
|
||||||
|
return Math.Clamp(baseRadius * scale, 8 * scale, 18 * scale);
|
||||||
|
};
|
||||||
|
|
||||||
private readonly Func<DesktopComponentControlFactoryContext, Control> _controlFactory;
|
private readonly Func<DesktopComponentControlFactoryContext, Control> _controlFactory;
|
||||||
private readonly Func<double, double> _cornerRadiusResolver;
|
private readonly Func<ComponentChromeContext, double> _cornerRadiusResolver;
|
||||||
|
|
||||||
internal DesktopComponentRuntimeDescriptor(
|
internal DesktopComponentRuntimeDescriptor(
|
||||||
DesktopComponentDefinition definition,
|
DesktopComponentDefinition definition,
|
||||||
string? displayNameLocalizationKey,
|
string? displayNameLocalizationKey,
|
||||||
Func<DesktopComponentControlFactoryContext, Control> controlFactory,
|
Func<DesktopComponentControlFactoryContext, Control> controlFactory,
|
||||||
Func<double, double>? cornerRadiusResolver)
|
Func<ComponentChromeContext, double>? cornerRadiusResolver)
|
||||||
{
|
{
|
||||||
Definition = definition;
|
Definition = definition;
|
||||||
DisplayNameLocalizationKey = displayNameLocalizationKey;
|
DisplayNameLocalizationKey = displayNameLocalizationKey;
|
||||||
@@ -97,9 +121,16 @@ public sealed class DesktopComponentRuntimeDescriptor
|
|||||||
|
|
||||||
var settingsService = settingsFacade.Settings;
|
var settingsService = settingsFacade.Settings;
|
||||||
var appearanceTheme = HostAppearanceThemeProvider.GetOrCreate();
|
var appearanceTheme = HostAppearanceThemeProvider.GetOrCreate();
|
||||||
|
var appearanceSnapshot = appearanceTheme.GetCurrent();
|
||||||
var componentAccessor = settingsService.GetComponentAccessor(Definition.Id, placementId);
|
var componentAccessor = settingsService.GetComponentAccessor(Definition.Id, placementId);
|
||||||
var componentSettingsStore = new ComponentSettingsService(settingsService);
|
var componentSettingsStore = new ComponentSettingsService(settingsService);
|
||||||
componentSettingsStore.SetScopedComponentContext(Definition.Id, placementId);
|
componentSettingsStore.SetScopedComponentContext(Definition.Id, placementId);
|
||||||
|
var chromeContext = new ComponentChromeContext(
|
||||||
|
Definition.Id,
|
||||||
|
placementId,
|
||||||
|
cellSize,
|
||||||
|
appearanceSnapshot.GlobalCornerRadiusScale,
|
||||||
|
appearanceSnapshot.CornerRadiusTokens);
|
||||||
var control = _controlFactory(new DesktopComponentControlFactoryContext(
|
var control = _controlFactory(new DesktopComponentControlFactoryContext(
|
||||||
Definition,
|
Definition,
|
||||||
cellSize,
|
cellSize,
|
||||||
@@ -118,6 +149,7 @@ public sealed class DesktopComponentRuntimeDescriptor
|
|||||||
settingsFacade,
|
settingsFacade,
|
||||||
settingsService,
|
settingsService,
|
||||||
appearanceTheme,
|
appearanceTheme,
|
||||||
|
chromeContext,
|
||||||
componentAccessor,
|
componentAccessor,
|
||||||
componentSettingsStore);
|
componentSettingsStore);
|
||||||
|
|
||||||
@@ -145,6 +177,11 @@ public sealed class DesktopComponentRuntimeDescriptor
|
|||||||
placementAwareComponent.SetComponentPlacementContext(Definition.Id, placementId);
|
placementAwareComponent.SetComponentPlacementContext(Definition.Id, placementId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (control is IComponentChromeContextAware chromeContextAwareComponent)
|
||||||
|
{
|
||||||
|
chromeContextAwareComponent.SetComponentChromeContext(chromeContext);
|
||||||
|
}
|
||||||
|
|
||||||
if (control is IDesktopComponentWidget sizedComponent)
|
if (control is IDesktopComponentWidget sizedComponent)
|
||||||
{
|
{
|
||||||
sizedComponent.ApplyCellSize(cellSize);
|
sizedComponent.ApplyCellSize(cellSize);
|
||||||
@@ -173,9 +210,22 @@ public sealed class DesktopComponentRuntimeDescriptor
|
|||||||
return control;
|
return control;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public double ResolveCornerRadius(ComponentChromeContext chromeContext)
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(chromeContext);
|
||||||
|
|
||||||
|
var resolved = _cornerRadiusResolver(chromeContext with { CellSize = Math.Max(1, chromeContext.CellSize) });
|
||||||
|
return double.IsFinite(resolved) ? Math.Max(0d, resolved) : DefaultCornerRadiusResolver(chromeContext);
|
||||||
|
}
|
||||||
|
|
||||||
public double ResolveCornerRadius(double cellSize)
|
public double ResolveCornerRadius(double cellSize)
|
||||||
{
|
{
|
||||||
return _cornerRadiusResolver(Math.Max(1, cellSize));
|
return ResolveCornerRadius(new ComponentChromeContext(
|
||||||
|
Definition.Id,
|
||||||
|
null,
|
||||||
|
Math.Max(1, cellSize),
|
||||||
|
1d,
|
||||||
|
AppearanceCornerRadiusTokenFactory.Create(1d)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ApplySettingsDependencies(
|
private static void ApplySettingsDependencies(
|
||||||
|
|||||||
@@ -80,8 +80,8 @@ public partial class ExchangeRateCalculatorWidget : UserControl, IDesktopCompone
|
|||||||
{
|
{
|
||||||
_currentCellSize = Math.Max(1, cellSize);
|
_currentCellSize = Math.Max(1, cellSize);
|
||||||
var scale = ResolveScale();
|
var scale = ResolveScale();
|
||||||
RootBorder.CornerRadius = new CornerRadius(Math.Clamp(34 * scale, 14, 48));
|
RootBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(34 * scale, 14, 48);
|
||||||
RootBorder.Padding = new Thickness(Math.Clamp(12 * scale, 6, 18));
|
RootBorder.Padding = new Thickness(ComponentChromeCornerRadiusHelper.SafeValue(12 * scale, 6, 18));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetRecommendationInfoService(IRecommendationInfoService recommendationInfoService)
|
public void SetRecommendationInfoService(IRecommendationInfoService recommendationInfoService)
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ using Avalonia.Controls;
|
|||||||
using Avalonia.Media;
|
using Avalonia.Media;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
using LanMountainDesktop.ComponentSystem;
|
using LanMountainDesktop.ComponentSystem;
|
||||||
|
using LanMountainDesktop.Host.Abstractions;
|
||||||
using LanMountainDesktop.Models;
|
using LanMountainDesktop.Models;
|
||||||
using LanMountainDesktop.PluginSdk;
|
using LanMountainDesktop.PluginSdk;
|
||||||
using LanMountainDesktop.Services;
|
using LanMountainDesktop.Services;
|
||||||
@@ -18,7 +19,7 @@ using LanMountainDesktop.Theme;
|
|||||||
|
|
||||||
namespace LanMountainDesktop.Views.Components;
|
namespace LanMountainDesktop.Views.Components;
|
||||||
|
|
||||||
public partial class ExtendedWeatherWidget : UserControl, IDesktopComponentWidget, IDesktopPageVisibilityAwareComponentWidget, ITimeZoneAwareComponentWidget, IWeatherInfoAwareComponentWidget, IComponentPlacementContextAware
|
public partial class ExtendedWeatherWidget : UserControl, IDesktopComponentWidget, IDesktopPageVisibilityAwareComponentWidget, ITimeZoneAwareComponentWidget, IWeatherInfoAwareComponentWidget, IComponentPlacementContextAware, IComponentChromeContextAware
|
||||||
{
|
{
|
||||||
private static readonly IWeatherInfoService DefaultWeatherInfoService = new XiaomiWeatherService();
|
private static readonly IWeatherInfoService DefaultWeatherInfoService = new XiaomiWeatherService();
|
||||||
private static readonly IReadOnlyList<int> SupportedAutoRefreshIntervalsMinutes = RefreshIntervalCatalog.SupportedIntervalsMinutes;
|
private static readonly IReadOnlyList<int> SupportedAutoRefreshIntervalsMinutes = RefreshIntervalCatalog.SupportedIntervalsMinutes;
|
||||||
@@ -34,6 +35,7 @@ public partial class ExtendedWeatherWidget : UserControl, IDesktopComponentWidge
|
|||||||
private TimeZoneService? _timeZoneService;
|
private TimeZoneService? _timeZoneService;
|
||||||
private CancellationTokenSource? _refreshCts;
|
private CancellationTokenSource? _refreshCts;
|
||||||
private double _currentCellSize = 48;
|
private double _currentCellSize = 48;
|
||||||
|
private ComponentChromeContext? _chromeContext;
|
||||||
private double _phase;
|
private double _phase;
|
||||||
private bool _isAttached;
|
private bool _isAttached;
|
||||||
private bool _isOnActivePage = true;
|
private bool _isOnActivePage = true;
|
||||||
@@ -122,21 +124,34 @@ public partial class ExtendedWeatherWidget : UserControl, IDesktopComponentWidge
|
|||||||
var metrics = HyperOS3WeatherTheme.ResolveMetrics(HyperOS3WeatherWidgetKind.Extended4x4);
|
var metrics = HyperOS3WeatherTheme.ResolveMetrics(HyperOS3WeatherWidgetKind.Extended4x4);
|
||||||
var width = Bounds.Width > 1 ? Bounds.Width : _currentCellSize * 4;
|
var width = Bounds.Width > 1 ? Bounds.Width : _currentCellSize * 4;
|
||||||
var height = Bounds.Height > 1 ? Bounds.Height : _currentCellSize * 4;
|
var height = Bounds.Height > 1 ? Bounds.Height : _currentCellSize * 4;
|
||||||
var radius = Math.Clamp(_currentCellSize * metrics.CornerRadiusScale, 28, 54);
|
var radius = ComponentChromeCornerRadiusHelper.Scale(
|
||||||
RootBorder.CornerRadius = new CornerRadius(radius);
|
_currentCellSize * metrics.CornerRadiusScale,
|
||||||
BackgroundImageLayer.CornerRadius = new CornerRadius(radius);
|
28,
|
||||||
BackgroundMotionLayer.CornerRadius = new CornerRadius(radius);
|
54,
|
||||||
BackgroundTintLayer.CornerRadius = new CornerRadius(radius);
|
_chromeContext);
|
||||||
BackgroundLightLayer.CornerRadius = new CornerRadius(radius);
|
ComponentChromeCornerRadiusHelper.Apply(
|
||||||
BackgroundShadeLayer.CornerRadius = new CornerRadius(radius);
|
radius,
|
||||||
|
RootBorder,
|
||||||
|
BackgroundImageLayer,
|
||||||
|
BackgroundMotionLayer,
|
||||||
|
BackgroundTintLayer,
|
||||||
|
BackgroundLightLayer,
|
||||||
|
BackgroundShadeLayer);
|
||||||
var horizontalPadding = Math.Clamp(Math.Min(width * metrics.HorizontalPaddingScale * 0.30, width * 0.11), 4, 34);
|
var horizontalPadding = Math.Clamp(Math.Min(width * metrics.HorizontalPaddingScale * 0.30, width * 0.11), 4, 34);
|
||||||
var verticalPadding = Math.Clamp(Math.Min(height * metrics.VerticalPaddingScale * 0.30, height * 0.11), 4, 34);
|
var verticalPadding = Math.Clamp(Math.Min(height * metrics.VerticalPaddingScale * 0.30, height * 0.11), 4, 34);
|
||||||
ContentPaddingBorder.Padding = new Thickness(
|
ContentPaddingBorder.Padding = new Thickness(
|
||||||
horizontalPadding,
|
ComponentChromeCornerRadiusHelper.SafeValue(horizontalPadding, 4, 34, _chromeContext),
|
||||||
verticalPadding);
|
ComponentChromeCornerRadiusHelper.SafeValue(verticalPadding, 4, 34, _chromeContext));
|
||||||
ApplyTypography(width, height);
|
ApplyTypography(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetComponentChromeContext(ComponentChromeContext context)
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(context);
|
||||||
|
_chromeContext = context;
|
||||||
|
ApplyCellSize(_currentCellSize);
|
||||||
|
}
|
||||||
|
|
||||||
public void SetTimeZoneService(TimeZoneService timeZoneService)
|
public void SetTimeZoneService(TimeZoneService timeZoneService)
|
||||||
{
|
{
|
||||||
if (_timeZoneService is not null)
|
if (_timeZoneService is not null)
|
||||||
|
|||||||
@@ -216,8 +216,8 @@ public partial class HolidayCalendarWidget : UserControl, IDesktopComponentWidge
|
|||||||
var titleNeedsTwoLines = isUltraCompact || titleUnits >= (isCompact ? 13 : 17);
|
var titleNeedsTwoLines = isUltraCompact || titleUnits >= (isCompact ? 13 : 17);
|
||||||
var dateNeedsTwoLines = isUltraCompact || dateUnits >= (isCompact ? 15 : 20);
|
var dateNeedsTwoLines = isUltraCompact || dateUnits >= (isCompact ? 15 : 20);
|
||||||
|
|
||||||
RootBorder.CornerRadius = new CornerRadius(Math.Clamp(shortSide * 0.13, 10, 46));
|
RootBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(shortSide * 0.13, 10, 46);
|
||||||
var padding = Math.Clamp(shortSide * 0.05, 4.5, 21);
|
var padding = ComponentChromeCornerRadiusHelper.SafeValue(shortSide * 0.05, 4.5, 21);
|
||||||
RootBorder.Padding = new Thickness(padding);
|
RootBorder.Padding = new Thickness(padding);
|
||||||
LayoutRoot.RowSpacing = Math.Clamp(shortSide * 0.028, 2.2, 12);
|
LayoutRoot.RowSpacing = Math.Clamp(shortSide * 0.028, 2.2, 12);
|
||||||
var rowWeights = ApplyAdaptiveRowHeights(isCompact, isUltraCompact, titleNeedsTwoLines, dateNeedsTwoLines);
|
var rowWeights = ApplyAdaptiveRowHeights(isCompact, isUltraCompact, titleNeedsTwoLines, dateNeedsTwoLines);
|
||||||
|
|||||||
@@ -12,13 +12,14 @@ using Avalonia.Media.Imaging;
|
|||||||
using Avalonia.Platform;
|
using Avalonia.Platform;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
using LanMountainDesktop.ComponentSystem;
|
using LanMountainDesktop.ComponentSystem;
|
||||||
|
using LanMountainDesktop.Host.Abstractions;
|
||||||
using LanMountainDesktop.Models;
|
using LanMountainDesktop.Models;
|
||||||
using LanMountainDesktop.Services;
|
using LanMountainDesktop.Services;
|
||||||
using LanMountainDesktop.Theme;
|
using LanMountainDesktop.Theme;
|
||||||
|
|
||||||
namespace LanMountainDesktop.Views.Components;
|
namespace LanMountainDesktop.Views.Components;
|
||||||
|
|
||||||
public partial class HourlyWeatherWidget : UserControl, IDesktopComponentWidget, IDesktopPageVisibilityAwareComponentWidget, ITimeZoneAwareComponentWidget, IWeatherInfoAwareComponentWidget, IComponentPlacementContextAware
|
public partial class HourlyWeatherWidget : UserControl, IDesktopComponentWidget, IDesktopPageVisibilityAwareComponentWidget, ITimeZoneAwareComponentWidget, IWeatherInfoAwareComponentWidget, IComponentPlacementContextAware, IComponentChromeContextAware
|
||||||
{
|
{
|
||||||
private enum WeatherVisualKind
|
private enum WeatherVisualKind
|
||||||
{
|
{
|
||||||
@@ -117,6 +118,7 @@ public partial class HourlyWeatherWidget : UserControl, IDesktopComponentWidget,
|
|||||||
private WeatherSnapshot? _latestSnapshot;
|
private WeatherSnapshot? _latestSnapshot;
|
||||||
private string _languageCode = "zh-CN";
|
private string _languageCode = "zh-CN";
|
||||||
private double _currentCellSize = 48;
|
private double _currentCellSize = 48;
|
||||||
|
private ComponentChromeContext? _chromeContext;
|
||||||
private WeatherVisualKind _activeVisualKind = WeatherVisualKind.ClearDay;
|
private WeatherVisualKind _activeVisualKind = WeatherVisualKind.ClearDay;
|
||||||
private double _animationPhase;
|
private double _animationPhase;
|
||||||
private int _activeParticleCount;
|
private int _activeParticleCount;
|
||||||
@@ -254,6 +256,13 @@ public partial class HourlyWeatherWidget : UserControl, IDesktopComponentWidget,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetComponentChromeContext(ComponentChromeContext context)
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(context);
|
||||||
|
_chromeContext = context;
|
||||||
|
ApplyCellSize(_currentCellSize);
|
||||||
|
}
|
||||||
|
|
||||||
public void ApplyCellSize(double cellSize)
|
public void ApplyCellSize(double cellSize)
|
||||||
{
|
{
|
||||||
_currentCellSize = Math.Max(1, cellSize);
|
_currentCellSize = Math.Max(1, cellSize);
|
||||||
@@ -261,17 +270,23 @@ public partial class HourlyWeatherWidget : UserControl, IDesktopComponentWidget,
|
|||||||
var scale = ResolveScale();
|
var scale = ResolveScale();
|
||||||
var hostWidth = Bounds.Width > 1 ? Bounds.Width : Math.Max(140, _currentCellSize * 4);
|
var hostWidth = Bounds.Width > 1 ? Bounds.Width : Math.Max(140, _currentCellSize * 4);
|
||||||
var hostHeight = Bounds.Height > 1 ? Bounds.Height : Math.Max(78, _currentCellSize * 2);
|
var hostHeight = Bounds.Height > 1 ? Bounds.Height : Math.Max(78, _currentCellSize * 2);
|
||||||
var cornerRadius = Math.Clamp(_currentCellSize * metrics.CornerRadiusScale, 24, 46);
|
var cornerRadius = ComponentChromeCornerRadiusHelper.Scale(
|
||||||
|
_currentCellSize * metrics.CornerRadiusScale,
|
||||||
|
24,
|
||||||
|
46,
|
||||||
|
_chromeContext);
|
||||||
|
|
||||||
RootBorder.CornerRadius = new CornerRadius(cornerRadius);
|
ComponentChromeCornerRadiusHelper.Apply(
|
||||||
BackgroundImageLayer.CornerRadius = new CornerRadius(cornerRadius);
|
cornerRadius,
|
||||||
BackgroundMotionLayer.CornerRadius = new CornerRadius(cornerRadius);
|
RootBorder,
|
||||||
BackgroundTintLayer.CornerRadius = new CornerRadius(cornerRadius);
|
BackgroundImageLayer,
|
||||||
BackgroundLightLayer.CornerRadius = new CornerRadius(cornerRadius);
|
BackgroundMotionLayer,
|
||||||
BackgroundShadeLayer.CornerRadius = new CornerRadius(cornerRadius);
|
BackgroundTintLayer,
|
||||||
|
BackgroundLightLayer,
|
||||||
|
BackgroundShadeLayer);
|
||||||
ContentPaddingBorder.Padding = new Thickness(
|
ContentPaddingBorder.Padding = new Thickness(
|
||||||
Math.Clamp(Math.Min((_currentCellSize * metrics.HorizontalPaddingScale) * scale, hostWidth * 0.034), 4, 22),
|
ComponentChromeCornerRadiusHelper.SafeValue(Math.Min((_currentCellSize * metrics.HorizontalPaddingScale) * scale, hostWidth * 0.034), 4, 22, _chromeContext),
|
||||||
Math.Clamp(Math.Min((_currentCellSize * metrics.VerticalPaddingScale) * scale, hostHeight * 0.068), 3, 18));
|
ComponentChromeCornerRadiusHelper.SafeValue(Math.Min((_currentCellSize * metrics.VerticalPaddingScale) * scale, hostHeight * 0.068), 3, 18, _chromeContext));
|
||||||
ApplyAdaptiveTypography();
|
ApplyAdaptiveTypography();
|
||||||
ResetParticles();
|
ResetParticles();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -400,8 +400,8 @@ public partial class IfengNewsWidget : UserControl, IDesktopComponentWidget, IRe
|
|||||||
var totalWidth = Bounds.Width > 1 ? Bounds.Width : _currentCellSize * BaseWidthCells;
|
var totalWidth = Bounds.Width > 1 ? Bounds.Width : _currentCellSize * BaseWidthCells;
|
||||||
var totalHeight = Bounds.Height > 1 ? Bounds.Height : _currentCellSize * BaseHeightCells;
|
var totalHeight = Bounds.Height > 1 ? Bounds.Height : _currentCellSize * BaseHeightCells;
|
||||||
|
|
||||||
RootBorder.CornerRadius = new CornerRadius(Math.Clamp(32 * softScale, 16, 46));
|
RootBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(32 * softScale, 16, 46);
|
||||||
CardBorder.CornerRadius = new CornerRadius(Math.Clamp(32 * softScale, 16, 46));
|
CardBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(32 * softScale, 16, 46);
|
||||||
|
|
||||||
var horizontalPadding = Math.Clamp(14 * softScale, 8, 20);
|
var horizontalPadding = Math.Clamp(14 * softScale, 8, 20);
|
||||||
var verticalPadding = Math.Clamp(14 * softScale, 8, 20);
|
var verticalPadding = Math.Clamp(14 * softScale, 8, 20);
|
||||||
@@ -452,7 +452,7 @@ public partial class IfengNewsWidget : UserControl, IDesktopComponentWidget, IRe
|
|||||||
|
|
||||||
visual.ImageHost.Width = imageWidth;
|
visual.ImageHost.Width = imageWidth;
|
||||||
visual.ImageHost.Height = imageHeight;
|
visual.ImageHost.Height = imageHeight;
|
||||||
visual.ImageHost.CornerRadius = new CornerRadius(Math.Clamp(imageHeight * 0.15, 8, 16));
|
visual.ImageHost.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(imageHeight * 0.15, 8, 16);
|
||||||
|
|
||||||
visual.TitleTextBlock.MaxWidth = textWidth;
|
visual.TitleTextBlock.MaxWidth = textWidth;
|
||||||
visual.TitleTextBlock.FontSize = titleFont;
|
visual.TitleTextBlock.FontSize = titleFont;
|
||||||
|
|||||||
@@ -182,8 +182,8 @@ public partial class LunarCalendarWidget : UserControl, IDesktopComponentWidget,
|
|||||||
{
|
{
|
||||||
var scale = ResolveScale();
|
var scale = ResolveScale();
|
||||||
|
|
||||||
RootBorder.CornerRadius = new CornerRadius(Math.Clamp(30 * scale, 16, 44));
|
RootBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(30 * scale, 16, 44);
|
||||||
RootBorder.Padding = new Thickness(Math.Clamp(16 * scale, 8, 24));
|
RootBorder.Padding = new Thickness(ComponentChromeCornerRadiusHelper.SafeValue(16 * scale, 8, 24));
|
||||||
LayoutRoot.RowSpacing = Math.Clamp(10 * scale, 5, 18);
|
LayoutRoot.RowSpacing = Math.Clamp(10 * scale, 5, 18);
|
||||||
DividerBorder.Margin = new Thickness(
|
DividerBorder.Margin = new Thickness(
|
||||||
Math.Clamp(8 * scale, 3, 14),
|
Math.Clamp(8 * scale, 3, 14),
|
||||||
|
|||||||
@@ -217,8 +217,8 @@ public partial class MonthCalendarWidget : UserControl, IDesktopComponentWidget,
|
|||||||
{
|
{
|
||||||
var scale = ResolveScale();
|
var scale = ResolveScale();
|
||||||
|
|
||||||
RootBorder.CornerRadius = new CornerRadius(Math.Clamp(28 * scale, 14, 40));
|
RootBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(28 * scale, 14, 40);
|
||||||
RootBorder.Padding = new Thickness(Math.Clamp(14 * scale, 8, 22));
|
RootBorder.Padding = new Thickness(ComponentChromeCornerRadiusHelper.SafeValue(14 * scale, 8, 22));
|
||||||
LayoutRoot.RowSpacing = Math.Clamp(10 * scale, 5, 16);
|
LayoutRoot.RowSpacing = Math.Clamp(10 * scale, 5, 16);
|
||||||
LayoutRoot.Width = Math.Clamp(280 * scale, 220, 420);
|
LayoutRoot.Width = Math.Clamp(280 * scale, 220, 420);
|
||||||
LayoutRoot.Height = Math.Clamp(280 * scale, 220, 420);
|
LayoutRoot.Height = Math.Clamp(280 * scale, 220, 420);
|
||||||
|
|||||||
@@ -10,13 +10,14 @@ using Avalonia.Controls;
|
|||||||
using Avalonia.Media;
|
using Avalonia.Media;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
using LanMountainDesktop.ComponentSystem;
|
using LanMountainDesktop.ComponentSystem;
|
||||||
|
using LanMountainDesktop.Host.Abstractions;
|
||||||
using LanMountainDesktop.Models;
|
using LanMountainDesktop.Models;
|
||||||
using LanMountainDesktop.Services;
|
using LanMountainDesktop.Services;
|
||||||
using LanMountainDesktop.Theme;
|
using LanMountainDesktop.Theme;
|
||||||
|
|
||||||
namespace LanMountainDesktop.Views.Components;
|
namespace LanMountainDesktop.Views.Components;
|
||||||
|
|
||||||
public partial class MultiDayWeatherWidget : UserControl, IDesktopComponentWidget, IDesktopPageVisibilityAwareComponentWidget, ITimeZoneAwareComponentWidget, IWeatherInfoAwareComponentWidget, IComponentPlacementContextAware
|
public partial class MultiDayWeatherWidget : UserControl, IDesktopComponentWidget, IDesktopPageVisibilityAwareComponentWidget, ITimeZoneAwareComponentWidget, IWeatherInfoAwareComponentWidget, IComponentPlacementContextAware, IComponentChromeContextAware
|
||||||
{
|
{
|
||||||
private enum WeatherVisualKind
|
private enum WeatherVisualKind
|
||||||
{
|
{
|
||||||
@@ -115,6 +116,7 @@ public partial class MultiDayWeatherWidget : UserControl, IDesktopComponentWidge
|
|||||||
private WeatherSnapshot? _latestSnapshot;
|
private WeatherSnapshot? _latestSnapshot;
|
||||||
private string _languageCode = "zh-CN";
|
private string _languageCode = "zh-CN";
|
||||||
private double _currentCellSize = 48;
|
private double _currentCellSize = 48;
|
||||||
|
private ComponentChromeContext? _chromeContext;
|
||||||
private WeatherVisualKind _activeVisualKind = WeatherVisualKind.ClearDay;
|
private WeatherVisualKind _activeVisualKind = WeatherVisualKind.ClearDay;
|
||||||
private double _animationPhase;
|
private double _animationPhase;
|
||||||
private int _activeParticleCount;
|
private int _activeParticleCount;
|
||||||
@@ -252,6 +254,13 @@ public partial class MultiDayWeatherWidget : UserControl, IDesktopComponentWidge
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetComponentChromeContext(ComponentChromeContext context)
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(context);
|
||||||
|
_chromeContext = context;
|
||||||
|
ApplyCellSize(_currentCellSize);
|
||||||
|
}
|
||||||
|
|
||||||
public void ApplyCellSize(double cellSize)
|
public void ApplyCellSize(double cellSize)
|
||||||
{
|
{
|
||||||
_currentCellSize = Math.Max(1, cellSize);
|
_currentCellSize = Math.Max(1, cellSize);
|
||||||
@@ -259,17 +268,23 @@ public partial class MultiDayWeatherWidget : UserControl, IDesktopComponentWidge
|
|||||||
var scale = ResolveScale();
|
var scale = ResolveScale();
|
||||||
var hostWidth = Bounds.Width > 1 ? Bounds.Width : Math.Max(140, _currentCellSize * 4);
|
var hostWidth = Bounds.Width > 1 ? Bounds.Width : Math.Max(140, _currentCellSize * 4);
|
||||||
var hostHeight = Bounds.Height > 1 ? Bounds.Height : Math.Max(78, _currentCellSize * 2);
|
var hostHeight = Bounds.Height > 1 ? Bounds.Height : Math.Max(78, _currentCellSize * 2);
|
||||||
var cornerRadius = Math.Clamp(_currentCellSize * metrics.CornerRadiusScale, 24, 46);
|
var cornerRadius = ComponentChromeCornerRadiusHelper.Scale(
|
||||||
|
_currentCellSize * metrics.CornerRadiusScale,
|
||||||
|
24,
|
||||||
|
46,
|
||||||
|
_chromeContext);
|
||||||
|
|
||||||
RootBorder.CornerRadius = new CornerRadius(cornerRadius);
|
ComponentChromeCornerRadiusHelper.Apply(
|
||||||
BackgroundImageLayer.CornerRadius = new CornerRadius(cornerRadius);
|
cornerRadius,
|
||||||
BackgroundMotionLayer.CornerRadius = new CornerRadius(cornerRadius);
|
RootBorder,
|
||||||
BackgroundTintLayer.CornerRadius = new CornerRadius(cornerRadius);
|
BackgroundImageLayer,
|
||||||
BackgroundLightLayer.CornerRadius = new CornerRadius(cornerRadius);
|
BackgroundMotionLayer,
|
||||||
BackgroundShadeLayer.CornerRadius = new CornerRadius(cornerRadius);
|
BackgroundTintLayer,
|
||||||
|
BackgroundLightLayer,
|
||||||
|
BackgroundShadeLayer);
|
||||||
ContentPaddingBorder.Padding = new Thickness(
|
ContentPaddingBorder.Padding = new Thickness(
|
||||||
Math.Clamp(Math.Min((_currentCellSize * metrics.HorizontalPaddingScale) * scale, hostWidth * 0.034), 4, 22),
|
ComponentChromeCornerRadiusHelper.SafeValue(Math.Min((_currentCellSize * metrics.HorizontalPaddingScale) * scale, hostWidth * 0.034), 4, 22, _chromeContext),
|
||||||
Math.Clamp(Math.Min((_currentCellSize * metrics.VerticalPaddingScale) * scale, hostHeight * 0.068), 3, 18));
|
ComponentChromeCornerRadiusHelper.SafeValue(Math.Min((_currentCellSize * metrics.VerticalPaddingScale) * scale, hostHeight * 0.068), 3, 18, _chromeContext));
|
||||||
ApplyAdaptiveTypography();
|
ApplyAdaptiveTypography();
|
||||||
ResetParticles();
|
ResetParticles();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,15 +63,15 @@ public partial class RecordingWidget : UserControl, IDesktopComponentWidget, IDe
|
|||||||
var chromeScale = Math.Clamp(rawScale, 0.62, 2.0);
|
var chromeScale = Math.Clamp(rawScale, 0.62, 2.0);
|
||||||
var contentScale = Math.Clamp(rawScale, 0.74, 1.0);
|
var contentScale = Math.Clamp(rawScale, 0.74, 1.0);
|
||||||
|
|
||||||
var rootRadius = Math.Clamp(34 * chromeScale, 16, 56);
|
var rootRadius = ComponentChromeCornerRadiusHelper.Scale(34 * chromeScale, 16, 56);
|
||||||
RootBorder.CornerRadius = new CornerRadius(rootRadius);
|
RootBorder.CornerRadius = rootRadius;
|
||||||
RootBorder.Padding = new Thickness(0);
|
RootBorder.Padding = new Thickness(0);
|
||||||
RecorderCardBorder.CornerRadius = new CornerRadius(rootRadius);
|
RecorderCardBorder.CornerRadius = rootRadius;
|
||||||
RecorderContentGrid.Margin = new Thickness(
|
RecorderContentGrid.Margin = new Thickness(
|
||||||
Math.Clamp(24 * contentScale, 14, 26),
|
ComponentChromeCornerRadiusHelper.SafeValue(24 * contentScale, 14, 26),
|
||||||
Math.Clamp(18 * contentScale, 10, 22),
|
ComponentChromeCornerRadiusHelper.SafeValue(18 * contentScale, 10, 22),
|
||||||
Math.Clamp(24 * contentScale, 14, 26),
|
ComponentChromeCornerRadiusHelper.SafeValue(24 * contentScale, 14, 26),
|
||||||
Math.Clamp(18 * contentScale, 10, 24));
|
ComponentChromeCornerRadiusHelper.SafeValue(18 * contentScale, 10, 24));
|
||||||
|
|
||||||
var sideButtonSize = Math.Clamp(54 * contentScale, 34, 58);
|
var sideButtonSize = Math.Clamp(54 * contentScale, 34, 58);
|
||||||
DiscardButtonBorder.Width = sideButtonSize;
|
DiscardButtonBorder.Width = sideButtonSize;
|
||||||
|
|||||||
@@ -347,13 +347,12 @@ public partial class RemovableStorageWidget : UserControl, IDesktopComponentWidg
|
|||||||
var scale = ResolveScale();
|
var scale = ResolveScale();
|
||||||
var width = Bounds.Width > 1 ? Bounds.Width : _currentCellSize * 2;
|
var width = Bounds.Width > 1 ? Bounds.Width : _currentCellSize * 2;
|
||||||
|
|
||||||
var cornerRadius = Math.Clamp(_currentCellSize * 0.44, 18, 34);
|
RootBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(_currentCellSize * 0.44, 18, 34);
|
||||||
RootBorder.CornerRadius = new CornerRadius(cornerRadius);
|
|
||||||
RootBorder.Padding = new Thickness(
|
RootBorder.Padding = new Thickness(
|
||||||
Math.Clamp(16 * scale, 10, 24),
|
ComponentChromeCornerRadiusHelper.SafeValue(16 * scale, 10, 24),
|
||||||
Math.Clamp(15 * scale, 10, 22),
|
ComponentChromeCornerRadiusHelper.SafeValue(15 * scale, 10, 22),
|
||||||
Math.Clamp(16 * scale, 10, 24),
|
ComponentChromeCornerRadiusHelper.SafeValue(16 * scale, 10, 24),
|
||||||
Math.Clamp(15 * scale, 10, 22));
|
ComponentChromeCornerRadiusHelper.SafeValue(15 * scale, 10, 22));
|
||||||
|
|
||||||
LayoutGrid.RowSpacing = Math.Clamp(10 * scale, 8, 16);
|
LayoutGrid.RowSpacing = Math.Clamp(10 * scale, 8, 16);
|
||||||
HeaderGrid.ColumnSpacing = Math.Clamp(12 * scale, 8, 16);
|
HeaderGrid.ColumnSpacing = Math.Clamp(12 * scale, 8, 16);
|
||||||
|
|||||||
@@ -602,8 +602,8 @@ public partial class Stcn24ForumWidget : UserControl, IDesktopComponentWidget, I
|
|||||||
var totalWidth = Bounds.Width > 1 ? Bounds.Width : _currentCellSize * BaseWidthCells;
|
var totalWidth = Bounds.Width > 1 ? Bounds.Width : _currentCellSize * BaseWidthCells;
|
||||||
var totalHeight = Bounds.Height > 1 ? Bounds.Height : _currentCellSize * BaseHeightCells;
|
var totalHeight = Bounds.Height > 1 ? Bounds.Height : _currentCellSize * BaseHeightCells;
|
||||||
|
|
||||||
RootBorder.CornerRadius = new CornerRadius(Math.Clamp(30 * softScale, 14, 44));
|
RootBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(30 * softScale, 14, 44);
|
||||||
CardBorder.CornerRadius = new CornerRadius(Math.Clamp(30 * softScale, 14, 44));
|
CardBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(30 * softScale, 14, 44);
|
||||||
CardBorder.Padding = new Thickness(
|
CardBorder.Padding = new Thickness(
|
||||||
Math.Clamp(12 * softScale, 8, 18),
|
Math.Clamp(12 * softScale, 8, 18),
|
||||||
Math.Clamp(12 * softScale, 8, 18),
|
Math.Clamp(12 * softScale, 8, 18),
|
||||||
@@ -628,7 +628,6 @@ public partial class Stcn24ForumWidget : UserControl, IDesktopComponentWidget, I
|
|||||||
var innerWidth = Math.Max(100, totalWidth - CardBorder.Padding.Left - CardBorder.Padding.Right);
|
var innerWidth = Math.Max(100, totalWidth - CardBorder.Padding.Left - CardBorder.Padding.Right);
|
||||||
var rowPaddingHorizontal = Math.Clamp(8 * softScale, 5, 14);
|
var rowPaddingHorizontal = Math.Clamp(8 * softScale, 5, 14);
|
||||||
var rowPaddingVertical = Math.Clamp(6 * softScale, 3, 10);
|
var rowPaddingVertical = Math.Clamp(6 * softScale, 3, 10);
|
||||||
var itemCornerRadius = Math.Clamp(10 * softScale, 6, 14);
|
|
||||||
var avatarSize = Math.Clamp(30 * softScale, 20, 40);
|
var avatarSize = Math.Clamp(30 * softScale, 20, 40);
|
||||||
var avatarFont = Math.Clamp(13 * softScale, 9, 18);
|
var avatarFont = Math.Clamp(13 * softScale, 9, 18);
|
||||||
var titleFont = Math.Clamp(14 * softScale, 10, 19);
|
var titleFont = Math.Clamp(14 * softScale, 10, 19);
|
||||||
@@ -658,7 +657,7 @@ public partial class Stcn24ForumWidget : UserControl, IDesktopComponentWidget, I
|
|||||||
|
|
||||||
foreach (var visual in _itemVisuals)
|
foreach (var visual in _itemVisuals)
|
||||||
{
|
{
|
||||||
visual.Host.CornerRadius = new CornerRadius(itemCornerRadius);
|
visual.Host.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(10 * softScale, 6, 14);
|
||||||
visual.Host.Padding = new Thickness(rowPaddingHorizontal, rowPaddingVertical);
|
visual.Host.Padding = new Thickness(rowPaddingHorizontal, rowPaddingVertical);
|
||||||
visual.RowGrid.ColumnSpacing = Math.Clamp(8 * softScale, 4, 12);
|
visual.RowGrid.ColumnSpacing = Math.Clamp(8 * softScale, 4, 12);
|
||||||
|
|
||||||
|
|||||||
@@ -229,7 +229,7 @@ public partial class StudyDeductionReasonsWidget : UserControl, IDesktopComponen
|
|||||||
_isUltraCompactMode = scale < 0.72 || (Bounds.Width > 1 && Bounds.Width < 300) || (Bounds.Height > 1 && Bounds.Height < 145);
|
_isUltraCompactMode = scale < 0.72 || (Bounds.Width > 1 && Bounds.Width < 300) || (Bounds.Height > 1 && Bounds.Height < 145);
|
||||||
|
|
||||||
var compactMultiplier = _isUltraCompactMode ? 0.76 : _isCompactMode ? 0.88 : 1.0;
|
var compactMultiplier = _isUltraCompactMode ? 0.76 : _isCompactMode ? 0.88 : 1.0;
|
||||||
RootBorder.CornerRadius = new CornerRadius(Math.Clamp(_currentCellSize * 0.46, 12, 34));
|
RootBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(_currentCellSize * 0.46, 12, 34);
|
||||||
RootBorder.Padding = new Thickness(
|
RootBorder.Padding = new Thickness(
|
||||||
Math.Clamp(12 * scale * compactMultiplier, 6, 18),
|
Math.Clamp(12 * scale * compactMultiplier, 6, 18),
|
||||||
Math.Clamp(10 * scale * compactMultiplier, 5, 16));
|
Math.Clamp(10 * scale * compactMultiplier, 5, 16));
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ public partial class StudyEnvironmentWidget : UserControl, IDesktopComponentWidg
|
|||||||
_currentCellSize = Math.Max(1, cellSize);
|
_currentCellSize = Math.Max(1, cellSize);
|
||||||
var scale = Math.Clamp(_currentCellSize / 48d, 0.82, 2.2);
|
var scale = Math.Clamp(_currentCellSize / 48d, 0.82, 2.2);
|
||||||
|
|
||||||
RootBorder.CornerRadius = new CornerRadius(Math.Clamp(_currentCellSize * 0.34, 10, 28));
|
RootBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(_currentCellSize * 0.34, 10, 28);
|
||||||
RootBorder.Padding = new Thickness(
|
RootBorder.Padding = new Thickness(
|
||||||
Math.Clamp(14 * scale, 8, 20),
|
Math.Clamp(14 * scale, 8, 20),
|
||||||
Math.Clamp(10 * scale, 6, 16));
|
Math.Clamp(10 * scale, 6, 16));
|
||||||
|
|||||||
@@ -255,7 +255,7 @@ public partial class StudyInterruptDensityWidget : UserControl, IDesktopComponen
|
|||||||
_isUltraCompactMode = scale < 0.72 || (Bounds.Width > 1 && Bounds.Width < 295) || (Bounds.Height > 1 && Bounds.Height < 130);
|
_isUltraCompactMode = scale < 0.72 || (Bounds.Width > 1 && Bounds.Width < 295) || (Bounds.Height > 1 && Bounds.Height < 130);
|
||||||
|
|
||||||
var compactMultiplier = _isUltraCompactMode ? 0.76 : _isCompactMode ? 0.88 : 1.0;
|
var compactMultiplier = _isUltraCompactMode ? 0.76 : _isCompactMode ? 0.88 : 1.0;
|
||||||
RootBorder.CornerRadius = new CornerRadius(Math.Clamp(_currentCellSize * 0.46, 12, 34));
|
RootBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(_currentCellSize * 0.46, 12, 34);
|
||||||
RootBorder.Padding = new Thickness(
|
RootBorder.Padding = new Thickness(
|
||||||
Math.Clamp(12 * scale * compactMultiplier, 6, 18),
|
Math.Clamp(12 * scale * compactMultiplier, 6, 18),
|
||||||
Math.Clamp(9 * scale * compactMultiplier, 5, 16));
|
Math.Clamp(9 * scale * compactMultiplier, 5, 16));
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ public partial class StudyNoiseCurveWidget : UserControl, IDesktopComponentWidge
|
|||||||
_currentCellSize = Math.Max(1, cellSize);
|
_currentCellSize = Math.Max(1, cellSize);
|
||||||
var scale = Math.Clamp(_currentCellSize / 48d, 0.78, 2.4);
|
var scale = Math.Clamp(_currentCellSize / 48d, 0.78, 2.4);
|
||||||
|
|
||||||
RootBorder.CornerRadius = new CornerRadius(Math.Clamp(_currentCellSize * 0.44, 14, 42));
|
RootBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(_currentCellSize * 0.44, 14, 42);
|
||||||
RootBorder.Padding = new Thickness(
|
RootBorder.Padding = new Thickness(
|
||||||
Math.Clamp(14 * scale, 8, 22),
|
Math.Clamp(14 * scale, 8, 22),
|
||||||
Math.Clamp(10 * scale, 6, 16));
|
Math.Clamp(10 * scale, 6, 16));
|
||||||
|
|||||||
@@ -323,7 +323,7 @@ public partial class StudyNoiseDistributionWidget : UserControl, IDesktopCompone
|
|||||||
_isUltraCompactMode = scale < 0.74 || (Bounds.Width > 1 && Bounds.Width < 300) || (Bounds.Height > 1 && Bounds.Height < 142);
|
_isUltraCompactMode = scale < 0.74 || (Bounds.Width > 1 && Bounds.Width < 300) || (Bounds.Height > 1 && Bounds.Height < 142);
|
||||||
|
|
||||||
var compactMultiplier = _isUltraCompactMode ? 0.76 : _isCompactMode ? 0.88 : 1.0;
|
var compactMultiplier = _isUltraCompactMode ? 0.76 : _isCompactMode ? 0.88 : 1.0;
|
||||||
RootBorder.CornerRadius = new CornerRadius(Math.Clamp(_currentCellSize * 0.44, 12, 34));
|
RootBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(_currentCellSize * 0.44, 12, 34);
|
||||||
RootBorder.Padding = new Thickness(
|
RootBorder.Padding = new Thickness(
|
||||||
Math.Clamp(12 * scale * compactMultiplier, 6, 18),
|
Math.Clamp(12 * scale * compactMultiplier, 6, 18),
|
||||||
Math.Clamp(9 * scale * compactMultiplier, 5, 16));
|
Math.Clamp(9 * scale * compactMultiplier, 5, 16));
|
||||||
|
|||||||
@@ -258,7 +258,7 @@ public partial class StudyScoreOverviewWidget : UserControl, IDesktopComponentWi
|
|||||||
|
|
||||||
var compactMultiplier = _isUltraCompactMode ? 0.76 : _isCompactMode ? 0.88 : 1.0;
|
var compactMultiplier = _isUltraCompactMode ? 0.76 : _isCompactMode ? 0.88 : 1.0;
|
||||||
var expandedMultiplier = _isExpandedMode ? 1.12 : 1.0;
|
var expandedMultiplier = _isExpandedMode ? 1.12 : 1.0;
|
||||||
RootBorder.CornerRadius = new CornerRadius(Math.Clamp(_currentCellSize * 0.50, 14, 42));
|
RootBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(_currentCellSize * 0.50, 14, 42);
|
||||||
RootBorder.Padding = new Thickness(
|
RootBorder.Padding = new Thickness(
|
||||||
Math.Clamp(16 * scale * compactMultiplier * expandedMultiplier, 8, 30),
|
Math.Clamp(16 * scale * compactMultiplier * expandedMultiplier, 8, 30),
|
||||||
Math.Clamp(14 * scale * compactMultiplier * expandedMultiplier, 6, 26));
|
Math.Clamp(14 * scale * compactMultiplier * expandedMultiplier, 6, 26));
|
||||||
@@ -305,7 +305,7 @@ public partial class StudyScoreOverviewWidget : UserControl, IDesktopComponentWi
|
|||||||
var cardPadding = new Thickness(
|
var cardPadding = new Thickness(
|
||||||
Math.Clamp(10 * scale * compactMultiplier * expandedMultiplier, 6, 20),
|
Math.Clamp(10 * scale * compactMultiplier * expandedMultiplier, 6, 20),
|
||||||
Math.Clamp(8 * scale * compactMultiplier * expandedMultiplier, 4, 16));
|
Math.Clamp(8 * scale * compactMultiplier * expandedMultiplier, 4, 16));
|
||||||
var cardCornerRadius = new CornerRadius(Math.Clamp(10 * scale, 6, 18));
|
var cardCornerRadius = ComponentChromeCornerRadiusHelper.Scale(10 * scale, 6, 18);
|
||||||
AverageCardBorder.Padding = cardPadding;
|
AverageCardBorder.Padding = cardPadding;
|
||||||
MinimumCardBorder.Padding = cardPadding;
|
MinimumCardBorder.Padding = cardPadding;
|
||||||
MaximumCardBorder.Padding = cardPadding;
|
MaximumCardBorder.Padding = cardPadding;
|
||||||
|
|||||||
@@ -268,7 +268,7 @@ public partial class StudySessionControlWidget : UserControl, IDesktopComponentW
|
|||||||
_isUltraCompactMode = scale < 0.74 || (Bounds.Width > 1 && Bounds.Width < 180) || (Bounds.Height > 1 && Bounds.Height < 76);
|
_isUltraCompactMode = scale < 0.74 || (Bounds.Width > 1 && Bounds.Width < 180) || (Bounds.Height > 1 && Bounds.Height < 76);
|
||||||
|
|
||||||
var compactMultiplier = _isUltraCompactMode ? 0.78 : _isCompactMode ? 0.90 : 1.0;
|
var compactMultiplier = _isUltraCompactMode ? 0.78 : _isCompactMode ? 0.90 : 1.0;
|
||||||
RootBorder.CornerRadius = new CornerRadius(Math.Clamp(_currentCellSize * 0.34, 10, 28));
|
RootBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(_currentCellSize * 0.34, 10, 28);
|
||||||
RootBorder.Padding = new Thickness(
|
RootBorder.Padding = new Thickness(
|
||||||
Math.Clamp(14 * scale * compactMultiplier, 7, 22),
|
Math.Clamp(14 * scale * compactMultiplier, 7, 22),
|
||||||
Math.Clamp(10 * scale * compactMultiplier, 5, 16));
|
Math.Clamp(10 * scale * compactMultiplier, 5, 16));
|
||||||
|
|||||||
@@ -237,7 +237,7 @@ public partial class StudySessionHistoryWidget : UserControl, IDesktopComponentW
|
|||||||
|
|
||||||
var rowBorder = new Border
|
var rowBorder = new Border
|
||||||
{
|
{
|
||||||
CornerRadius = new CornerRadius(Math.Clamp(_currentCellSize * 0.20, 8, 14)),
|
CornerRadius = ComponentChromeCornerRadiusHelper.Scale(_currentCellSize * 0.20, 8, 14),
|
||||||
Background = new SolidColorBrush(rowBackground),
|
Background = new SolidColorBrush(rowBackground),
|
||||||
BorderBrush = new SolidColorBrush(rowBorderColor),
|
BorderBrush = new SolidColorBrush(rowBorderColor),
|
||||||
BorderThickness = new Thickness(1),
|
BorderThickness = new Thickness(1),
|
||||||
@@ -588,7 +588,7 @@ public partial class StudySessionHistoryWidget : UserControl, IDesktopComponentW
|
|||||||
_isCompactMode = scale < 0.92 || (Bounds.Width > 1 && Bounds.Width < 320) || (Bounds.Height > 1 && Bounds.Height < 145);
|
_isCompactMode = scale < 0.92 || (Bounds.Width > 1 && Bounds.Width < 320) || (Bounds.Height > 1 && Bounds.Height < 145);
|
||||||
_isUltraCompactMode = scale < 0.78 || (Bounds.Width > 1 && Bounds.Width < 280) || (Bounds.Height > 1 && Bounds.Height < 120);
|
_isUltraCompactMode = scale < 0.78 || (Bounds.Width > 1 && Bounds.Width < 280) || (Bounds.Height > 1 && Bounds.Height < 120);
|
||||||
|
|
||||||
RootBorder.CornerRadius = new CornerRadius(Math.Clamp(_currentCellSize * 0.44, 12, 36));
|
RootBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(_currentCellSize * 0.44, 12, 36);
|
||||||
RootBorder.Padding = new Thickness(
|
RootBorder.Padding = new Thickness(
|
||||||
Math.Clamp(12 * scale, 7, 22),
|
Math.Clamp(12 * scale, 7, 22),
|
||||||
Math.Clamp(9 * scale, 5, 16));
|
Math.Clamp(9 * scale, 5, 16));
|
||||||
@@ -606,7 +606,7 @@ public partial class StudySessionHistoryWidget : UserControl, IDesktopComponentW
|
|||||||
DialogOverlayBorder.Padding = new Thickness(
|
DialogOverlayBorder.Padding = new Thickness(
|
||||||
Math.Clamp(12 * scale, 8, 20),
|
Math.Clamp(12 * scale, 8, 20),
|
||||||
Math.Clamp(10 * scale, 8, 18));
|
Math.Clamp(10 * scale, 8, 18));
|
||||||
DialogCardBorder.CornerRadius = new CornerRadius(Math.Clamp(12 * scale, 10, 18));
|
DialogCardBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(12 * scale, 10, 18);
|
||||||
DialogCardBorder.Padding = new Thickness(
|
DialogCardBorder.Padding = new Thickness(
|
||||||
Math.Clamp(12 * scale, 9, 20),
|
Math.Clamp(12 * scale, 9, 20),
|
||||||
Math.Clamp(11 * scale, 8, 18));
|
Math.Clamp(11 * scale, 8, 18));
|
||||||
|
|||||||
@@ -197,9 +197,9 @@ public partial class TimerWidget : UserControl, IDesktopComponentWidget
|
|||||||
_currentCellSize = Math.Max(1, cellSize);
|
_currentCellSize = Math.Max(1, cellSize);
|
||||||
var scale = ResolveScale();
|
var scale = ResolveScale();
|
||||||
|
|
||||||
RootBorder.CornerRadius = new CornerRadius(Math.Clamp(34 * scale, 12, 48));
|
RootBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(34 * scale, 12, 48);
|
||||||
RootBorder.Padding = new Thickness(Math.Clamp(14 * scale, 7, 22));
|
RootBorder.Padding = new Thickness(Math.Clamp(14 * scale, 7, 22));
|
||||||
TimerPanelBorder.CornerRadius = new CornerRadius(Math.Clamp(32 * scale, 12, 42));
|
TimerPanelBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(32 * scale, 12, 42);
|
||||||
|
|
||||||
PlayButtonBorder.Width = Math.Clamp(42 * scale, 28, 58);
|
PlayButtonBorder.Width = Math.Clamp(42 * scale, 28, 58);
|
||||||
PlayButtonBorder.Height = Math.Clamp(42 * scale, 28, 58);
|
PlayButtonBorder.Height = Math.Clamp(42 * scale, 28, 58);
|
||||||
|
|||||||
@@ -11,12 +11,13 @@ using Avalonia.Media;
|
|||||||
using Avalonia.Styling;
|
using Avalonia.Styling;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
using LanMountainDesktop.ComponentSystem;
|
using LanMountainDesktop.ComponentSystem;
|
||||||
|
using LanMountainDesktop.Host.Abstractions;
|
||||||
using LanMountainDesktop.Models;
|
using LanMountainDesktop.Models;
|
||||||
using LanMountainDesktop.Services;
|
using LanMountainDesktop.Services;
|
||||||
|
|
||||||
namespace LanMountainDesktop.Views.Components;
|
namespace LanMountainDesktop.Views.Components;
|
||||||
|
|
||||||
public partial class WeatherClockWidget : UserControl, IDesktopComponentWidget, ITimeZoneAwareComponentWidget, IWeatherInfoAwareComponentWidget, IComponentPlacementContextAware
|
public partial class WeatherClockWidget : UserControl, IDesktopComponentWidget, ITimeZoneAwareComponentWidget, IWeatherInfoAwareComponentWidget, IComponentPlacementContextAware, IComponentChromeContextAware
|
||||||
{
|
{
|
||||||
private sealed record WeatherClockConfig(
|
private sealed record WeatherClockConfig(
|
||||||
string LanguageCode,
|
string LanguageCode,
|
||||||
@@ -52,6 +53,7 @@ public partial class WeatherClockWidget : UserControl, IDesktopComponentWidget,
|
|||||||
private TimeZoneService? _timeZoneService;
|
private TimeZoneService? _timeZoneService;
|
||||||
private CancellationTokenSource? _refreshCts;
|
private CancellationTokenSource? _refreshCts;
|
||||||
private double _currentCellSize = 48;
|
private double _currentCellSize = 48;
|
||||||
|
private ComponentChromeContext? _chromeContext;
|
||||||
private bool _isAttached;
|
private bool _isAttached;
|
||||||
private bool _dialInitialized;
|
private bool _dialInitialized;
|
||||||
private bool _handsInitialized;
|
private bool _handsInitialized;
|
||||||
@@ -128,6 +130,13 @@ public partial class WeatherClockWidget : UserControl, IDesktopComponentWidget,
|
|||||||
RefreshFromSettings();
|
RefreshFromSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetComponentChromeContext(ComponentChromeContext context)
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(context);
|
||||||
|
_chromeContext = context;
|
||||||
|
ApplyCellSize(_currentCellSize);
|
||||||
|
}
|
||||||
|
|
||||||
public void ApplyCellSize(double cellSize)
|
public void ApplyCellSize(double cellSize)
|
||||||
{
|
{
|
||||||
_currentCellSize = Math.Max(1, cellSize);
|
_currentCellSize = Math.Max(1, cellSize);
|
||||||
@@ -142,12 +151,24 @@ public partial class WeatherClockWidget : UserControl, IDesktopComponentWidget,
|
|||||||
var compactness = Math.Clamp((176 - targetWidth) / 86d, 0, 1);
|
var compactness = Math.Clamp((176 - targetWidth) / 86d, 0, 1);
|
||||||
var ultraCompact = targetWidth < 126 || targetHeight < 46;
|
var ultraCompact = targetWidth < 126 || targetHeight < 46;
|
||||||
var compactFactor = Lerp(1, ultraCompact ? 0.64 : 0.72, compactness);
|
var compactFactor = Lerp(1, ultraCompact ? 0.64 : 0.72, compactness);
|
||||||
var cornerRadius = Math.Clamp(targetHeight * metrics.CornerRadiusScale, 15, 36);
|
var cornerRadius = ComponentChromeCornerRadiusHelper.Scale(
|
||||||
|
targetHeight * metrics.CornerRadiusScale,
|
||||||
|
15,
|
||||||
|
36,
|
||||||
|
_chromeContext);
|
||||||
|
|
||||||
var horizontalPadding = Math.Clamp(targetHeight * Lerp(0.18, 0.12, compactness), 5, 30);
|
var horizontalPadding = ComponentChromeCornerRadiusHelper.SafeValue(
|
||||||
var verticalPadding = Math.Clamp(targetHeight * Lerp(0.14, 0.10, compactness), 3, 20);
|
targetHeight * Lerp(0.18, 0.12, compactness),
|
||||||
|
5,
|
||||||
|
30,
|
||||||
|
_chromeContext);
|
||||||
|
var verticalPadding = ComponentChromeCornerRadiusHelper.SafeValue(
|
||||||
|
targetHeight * Lerp(0.14, 0.10, compactness),
|
||||||
|
3,
|
||||||
|
20,
|
||||||
|
_chromeContext);
|
||||||
|
|
||||||
RootBorder.CornerRadius = new CornerRadius(cornerRadius);
|
RootBorder.CornerRadius = cornerRadius;
|
||||||
RootBorder.Padding = new Thickness(horizontalPadding, verticalPadding, horizontalPadding, verticalPadding);
|
RootBorder.Padding = new Thickness(horizontalPadding, verticalPadding, horizontalPadding, verticalPadding);
|
||||||
|
|
||||||
var columnSpacing = Math.Clamp(targetHeight * Lerp(0.16, 0.08, compactness), 2, 22);
|
var columnSpacing = Math.Clamp(targetHeight * Lerp(0.16, 0.08, compactness), 2, 22);
|
||||||
|
|||||||
@@ -12,13 +12,14 @@ using Avalonia.Media.Imaging;
|
|||||||
using Avalonia.Platform;
|
using Avalonia.Platform;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
using LanMountainDesktop.ComponentSystem;
|
using LanMountainDesktop.ComponentSystem;
|
||||||
|
using LanMountainDesktop.Host.Abstractions;
|
||||||
using LanMountainDesktop.Models;
|
using LanMountainDesktop.Models;
|
||||||
using LanMountainDesktop.Services;
|
using LanMountainDesktop.Services;
|
||||||
using LanMountainDesktop.Theme;
|
using LanMountainDesktop.Theme;
|
||||||
|
|
||||||
namespace LanMountainDesktop.Views.Components;
|
namespace LanMountainDesktop.Views.Components;
|
||||||
|
|
||||||
public partial class WeatherWidget : UserControl, IDesktopComponentWidget, IDesktopPageVisibilityAwareComponentWidget, ITimeZoneAwareComponentWidget, IWeatherInfoAwareComponentWidget, IComponentPlacementContextAware
|
public partial class WeatherWidget : UserControl, IDesktopComponentWidget, IDesktopPageVisibilityAwareComponentWidget, ITimeZoneAwareComponentWidget, IWeatherInfoAwareComponentWidget, IComponentPlacementContextAware, IComponentChromeContextAware
|
||||||
{
|
{
|
||||||
private enum WeatherVisualKind
|
private enum WeatherVisualKind
|
||||||
{
|
{
|
||||||
@@ -111,6 +112,7 @@ public partial class WeatherWidget : UserControl, IDesktopComponentWidget, IDesk
|
|||||||
private WeatherSnapshot? _latestSnapshot;
|
private WeatherSnapshot? _latestSnapshot;
|
||||||
private string _languageCode = "zh-CN";
|
private string _languageCode = "zh-CN";
|
||||||
private double _currentCellSize = 48;
|
private double _currentCellSize = 48;
|
||||||
|
private ComponentChromeContext? _chromeContext;
|
||||||
private WeatherVisualKind _activeVisualKind = WeatherVisualKind.ClearDay;
|
private WeatherVisualKind _activeVisualKind = WeatherVisualKind.ClearDay;
|
||||||
private double _animationPhase;
|
private double _animationPhase;
|
||||||
private int _activeParticleCount;
|
private int _activeParticleCount;
|
||||||
@@ -197,6 +199,13 @@ public partial class WeatherWidget : UserControl, IDesktopComponentWidget, IDesk
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetComponentChromeContext(ComponentChromeContext context)
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(context);
|
||||||
|
_chromeContext = context;
|
||||||
|
ApplyCellSize(_currentCellSize);
|
||||||
|
}
|
||||||
|
|
||||||
public void ApplyCellSize(double cellSize)
|
public void ApplyCellSize(double cellSize)
|
||||||
{
|
{
|
||||||
_currentCellSize = Math.Max(1, cellSize);
|
_currentCellSize = Math.Max(1, cellSize);
|
||||||
@@ -204,19 +213,25 @@ public partial class WeatherWidget : UserControl, IDesktopComponentWidget, IDesk
|
|||||||
var metrics = HyperOS3WeatherTheme.ResolveMetrics(HyperOS3WeatherWidgetKind.Realtime2x2);
|
var metrics = HyperOS3WeatherTheme.ResolveMetrics(HyperOS3WeatherWidgetKind.Realtime2x2);
|
||||||
var hostWidth = Bounds.Width > 1 ? Bounds.Width : Math.Max(80, _currentCellSize * 2);
|
var hostWidth = Bounds.Width > 1 ? Bounds.Width : Math.Max(80, _currentCellSize * 2);
|
||||||
var hostHeight = Bounds.Height > 1 ? Bounds.Height : Math.Max(80, _currentCellSize * 2);
|
var hostHeight = Bounds.Height > 1 ? Bounds.Height : Math.Max(80, _currentCellSize * 2);
|
||||||
var cornerRadius = Math.Clamp(_currentCellSize * metrics.CornerRadiusScale, 26, 46);
|
var cornerRadius = ComponentChromeCornerRadiusHelper.Scale(
|
||||||
|
_currentCellSize * metrics.CornerRadiusScale,
|
||||||
|
26,
|
||||||
|
46,
|
||||||
|
_chromeContext);
|
||||||
var horizontalPadding = Math.Clamp(_currentCellSize * metrics.HorizontalPaddingScale, 10, 24);
|
var horizontalPadding = Math.Clamp(_currentCellSize * metrics.HorizontalPaddingScale, 10, 24);
|
||||||
var verticalPadding = Math.Clamp(_currentCellSize * metrics.VerticalPaddingScale, 10, 24);
|
var verticalPadding = Math.Clamp(_currentCellSize * metrics.VerticalPaddingScale, 10, 24);
|
||||||
|
|
||||||
RootBorder.CornerRadius = new CornerRadius(cornerRadius);
|
ComponentChromeCornerRadiusHelper.Apply(
|
||||||
BackgroundImageLayer.CornerRadius = new CornerRadius(cornerRadius);
|
cornerRadius,
|
||||||
BackgroundMotionLayer.CornerRadius = new CornerRadius(cornerRadius);
|
RootBorder,
|
||||||
BackgroundTintLayer.CornerRadius = new CornerRadius(cornerRadius);
|
BackgroundImageLayer,
|
||||||
BackgroundLightLayer.CornerRadius = new CornerRadius(cornerRadius);
|
BackgroundMotionLayer,
|
||||||
BackgroundShadeLayer.CornerRadius = new CornerRadius(cornerRadius);
|
BackgroundTintLayer,
|
||||||
|
BackgroundLightLayer,
|
||||||
|
BackgroundShadeLayer);
|
||||||
ContentPaddingBorder.Padding = new Thickness(
|
ContentPaddingBorder.Padding = new Thickness(
|
||||||
Math.Clamp(Math.Min(horizontalPadding * scale, hostWidth * 0.12), 3, 24),
|
ComponentChromeCornerRadiusHelper.SafeValue(Math.Min(horizontalPadding * scale, hostWidth * 0.12), 3, 24, _chromeContext),
|
||||||
Math.Clamp(Math.Min(verticalPadding * scale, hostHeight * 0.12), 3, 24));
|
ComponentChromeCornerRadiusHelper.SafeValue(Math.Min(verticalPadding * scale, hostHeight * 0.12), 3, 24, _chromeContext));
|
||||||
ApplyAdaptiveTypography();
|
ApplyAdaptiveTypography();
|
||||||
ResetParticles();
|
ResetParticles();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -117,11 +117,13 @@ public partial class WhiteboardWidget : UserControl, IDesktopComponentWidget, IC
|
|||||||
var toolbarPaddingHorizontal = Math.Clamp(buttonSize * 0.36, 6, 12);
|
var toolbarPaddingHorizontal = Math.Clamp(buttonSize * 0.36, 6, 12);
|
||||||
var toolbarPaddingVertical = Math.Clamp(buttonSize * 0.24, 4, 8);
|
var toolbarPaddingVertical = Math.Clamp(buttonSize * 0.24, 4, 8);
|
||||||
|
|
||||||
RootBorder.Padding = new Thickness(Math.Clamp(_currentCellSize * 0.14, 6, 14));
|
RootBorder.Padding = new Thickness(ComponentChromeCornerRadiusHelper.SafeValue(_currentCellSize * 0.14, 6, 14));
|
||||||
RootBorder.CornerRadius = new CornerRadius(Math.Clamp(_currentCellSize * 0.34, 12, 28));
|
RootBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(_currentCellSize * 0.34, 12, 28);
|
||||||
CanvasBorder.CornerRadius = new CornerRadius(Math.Clamp(_currentCellSize * 0.24, 10, 22));
|
CanvasBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(_currentCellSize * 0.24, 10, 22);
|
||||||
ToolbarBorder.CornerRadius = new CornerRadius(Math.Clamp(_currentCellSize * 0.22, 10, 20));
|
ToolbarBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(_currentCellSize * 0.22, 10, 20);
|
||||||
ToolbarBorder.Padding = new Thickness(toolbarPaddingHorizontal, toolbarPaddingVertical);
|
ToolbarBorder.Padding = new Thickness(
|
||||||
|
ComponentChromeCornerRadiusHelper.SafeValue(toolbarPaddingHorizontal, 6, 12),
|
||||||
|
ComponentChromeCornerRadiusHelper.SafeValue(toolbarPaddingVertical, 4, 8));
|
||||||
ToolbarButtonsPanel.Spacing = toolbarSpacing;
|
ToolbarButtonsPanel.Spacing = toolbarSpacing;
|
||||||
|
|
||||||
foreach (var button in new[] { PenButton, EraserButton, ClearButton, ExportButton })
|
foreach (var button in new[] { PenButton, EraserButton, ClearButton, ExportButton })
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ public partial class WorldClockWidget : UserControl, IDesktopComponentWidget, IT
|
|||||||
var horizontalPadding = Math.Clamp(10 * scale, 4, 26);
|
var horizontalPadding = Math.Clamp(10 * scale, 4, 26);
|
||||||
var verticalPadding = Math.Clamp(8 * scale, 3, 22);
|
var verticalPadding = Math.Clamp(8 * scale, 3, 22);
|
||||||
RootBorder.Padding = new Thickness(horizontalPadding, verticalPadding);
|
RootBorder.Padding = new Thickness(horizontalPadding, verticalPadding);
|
||||||
RootBorder.CornerRadius = new CornerRadius(Math.Clamp(24 * scale, 10, 46));
|
RootBorder.CornerRadius = ComponentChromeCornerRadiusHelper.Scale(24 * scale, 10, 46);
|
||||||
|
|
||||||
var usableWidth = Math.Max(48, totalWidth - horizontalPadding * 2);
|
var usableWidth = Math.Max(48, totalWidth - horizontalPadding * 2);
|
||||||
var usableHeight = Math.Max(28, totalHeight - verticalPadding * 2);
|
var usableHeight = Math.Max(28, totalHeight - verticalPadding * 2);
|
||||||
|
|||||||
@@ -13,11 +13,13 @@ using Avalonia.VisualTree;
|
|||||||
using FluentIcons.Avalonia;
|
using FluentIcons.Avalonia;
|
||||||
using FluentIcons.Common;
|
using FluentIcons.Common;
|
||||||
using LanMountainDesktop.ComponentSystem;
|
using LanMountainDesktop.ComponentSystem;
|
||||||
|
using LanMountainDesktop.Host.Abstractions;
|
||||||
using LanMountainDesktop.Models;
|
using LanMountainDesktop.Models;
|
||||||
using LanMountainDesktop.Services;
|
using LanMountainDesktop.Services;
|
||||||
using LanMountainDesktop.Services.Settings;
|
using LanMountainDesktop.Services.Settings;
|
||||||
using LanMountainDesktop.Theme;
|
using LanMountainDesktop.Theme;
|
||||||
using LanMountainDesktop.Views.Components;
|
using LanMountainDesktop.Views.Components;
|
||||||
|
using PathShape = Avalonia.Controls.Shapes.Path;
|
||||||
|
|
||||||
namespace LanMountainDesktop.Views;
|
namespace LanMountainDesktop.Views;
|
||||||
|
|
||||||
@@ -579,13 +581,18 @@ public partial class MainWindow
|
|||||||
{
|
{
|
||||||
var window = new ComponentLibraryWindow(
|
var window = new ComponentLibraryWindow(
|
||||||
_componentLibraryService,
|
_componentLibraryService,
|
||||||
cellSize => new ComponentLibraryCreateContext(
|
cellSize =>
|
||||||
|
{
|
||||||
|
var appearanceSnapshot = HostAppearanceThemeProvider.GetOrCreate().GetCurrent();
|
||||||
|
return new ComponentLibraryCreateContext(
|
||||||
cellSize,
|
cellSize,
|
||||||
|
appearanceSnapshot.GlobalCornerRadiusScale,
|
||||||
_timeZoneService,
|
_timeZoneService,
|
||||||
_weatherDataService,
|
_weatherDataService,
|
||||||
_recommendationInfoService,
|
_recommendationInfoService,
|
||||||
_calculatorDataService,
|
_calculatorDataService,
|
||||||
_settingsFacade),
|
_settingsFacade);
|
||||||
|
},
|
||||||
L);
|
L);
|
||||||
window.AddComponentRequested += OnDetachedComponentLibraryAddComponentRequested;
|
window.AddComponentRequested += OnDetachedComponentLibraryAddComponentRequested;
|
||||||
window.Closed += OnDetachedComponentLibraryClosed;
|
window.Closed += OnDetachedComponentLibraryClosed;
|
||||||
@@ -1258,7 +1265,7 @@ public partial class MainWindow
|
|||||||
Height = handleVisualSize,
|
Height = handleVisualSize,
|
||||||
IsHitTestVisible = false
|
IsHitTestVisible = false
|
||||||
};
|
};
|
||||||
resizeHandleVisual.Children.Add(new Path
|
resizeHandleVisual.Children.Add(new PathShape
|
||||||
{
|
{
|
||||||
Data = arcData,
|
Data = arcData,
|
||||||
Stretch = Stretch.Fill,
|
Stretch = Stretch.Fill,
|
||||||
@@ -1266,7 +1273,7 @@ public partial class MainWindow
|
|||||||
StrokeThickness = arcThickness + 3,
|
StrokeThickness = arcThickness + 3,
|
||||||
StrokeLineCap = PenLineCap.Round
|
StrokeLineCap = PenLineCap.Round
|
||||||
});
|
});
|
||||||
resizeHandleVisual.Children.Add(new Path
|
resizeHandleVisual.Children.Add(new PathShape
|
||||||
{
|
{
|
||||||
Data = arcData,
|
Data = arcData,
|
||||||
Stretch = Stretch.Fill,
|
Stretch = Stretch.Fill,
|
||||||
@@ -1513,12 +1520,20 @@ public partial class MainWindow
|
|||||||
|
|
||||||
private double GetComponentCornerRadius(string componentId)
|
private double GetComponentCornerRadius(string componentId)
|
||||||
{
|
{
|
||||||
|
var appearanceSnapshot = HostAppearanceThemeProvider.GetOrCreate().GetCurrent();
|
||||||
|
|
||||||
if (_componentRuntimeRegistry.TryGetDescriptor(componentId, out var runtimeDescriptor))
|
if (_componentRuntimeRegistry.TryGetDescriptor(componentId, out var runtimeDescriptor))
|
||||||
{
|
{
|
||||||
return runtimeDescriptor.ResolveCornerRadius(_currentDesktopCellSize);
|
return runtimeDescriptor.ResolveCornerRadius(new ComponentChromeContext(
|
||||||
|
componentId,
|
||||||
|
null,
|
||||||
|
_currentDesktopCellSize,
|
||||||
|
appearanceSnapshot.GlobalCornerRadiusScale,
|
||||||
|
appearanceSnapshot.CornerRadiusTokens));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Math.Clamp(_currentDesktopCellSize * 0.22, 8, 18);
|
var scale = Math.Max(0.1d, appearanceSnapshot.GlobalCornerRadiusScale);
|
||||||
|
return Math.Clamp(_currentDesktopCellSize * 0.22, 8, 18) * scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Thickness GetDesktopComponentVisualInset(int widthCells, int heightCells)
|
private Thickness GetDesktopComponentVisualInset(int widthCells, int heightCells)
|
||||||
@@ -1767,8 +1782,10 @@ public partial class MainWindow
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
var appearanceSnapshot = HostAppearanceThemeProvider.GetOrCreate().GetCurrent();
|
||||||
var createContext = new ComponentLibraryCreateContext(
|
var createContext = new ComponentLibraryCreateContext(
|
||||||
cellSize,
|
cellSize,
|
||||||
|
appearanceSnapshot.GlobalCornerRadiusScale,
|
||||||
_timeZoneService,
|
_timeZoneService,
|
||||||
_weatherDataService,
|
_weatherDataService,
|
||||||
_recommendationInfoService,
|
_recommendationInfoService,
|
||||||
|
|||||||
@@ -83,7 +83,7 @@
|
|||||||
Background="{Binding NeutralLightPreviewBrush}"
|
Background="{Binding NeutralLightPreviewBrush}"
|
||||||
BorderBrush="{DynamicResource AdaptiveGlassPanelBorderBrush}"
|
BorderBrush="{DynamicResource AdaptiveGlassPanelBorderBrush}"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
CornerRadius="14" />
|
CornerRadius="{DynamicResource DesignCornerRadiusSm}" />
|
||||||
<TextBlock Text="{Binding PreviewNeutralLightLabel}"
|
<TextBlock Text="{Binding PreviewNeutralLightLabel}"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
@@ -94,7 +94,7 @@
|
|||||||
Background="{Binding NeutralDarkPreviewBrush}"
|
Background="{Binding NeutralDarkPreviewBrush}"
|
||||||
BorderBrush="{DynamicResource AdaptiveGlassPanelBorderBrush}"
|
BorderBrush="{DynamicResource AdaptiveGlassPanelBorderBrush}"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
CornerRadius="14" />
|
CornerRadius="{DynamicResource DesignCornerRadiusSm}" />
|
||||||
<TextBlock Text="{Binding PreviewNeutralDarkLabel}"
|
<TextBlock Text="{Binding PreviewNeutralDarkLabel}"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
@@ -110,7 +110,7 @@
|
|||||||
Background="{Binding PrimarySwatchBrush}"
|
Background="{Binding PrimarySwatchBrush}"
|
||||||
BorderBrush="{DynamicResource AdaptiveGlassPanelBorderBrush}"
|
BorderBrush="{DynamicResource AdaptiveGlassPanelBorderBrush}"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
CornerRadius="14" />
|
CornerRadius="{DynamicResource DesignCornerRadiusSm}" />
|
||||||
<TextBlock Text="{Binding PreviewPrimaryLabel}"
|
<TextBlock Text="{Binding PreviewPrimaryLabel}"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
@@ -122,7 +122,7 @@
|
|||||||
Background="{Binding SecondarySwatchBrush}"
|
Background="{Binding SecondarySwatchBrush}"
|
||||||
BorderBrush="{DynamicResource AdaptiveGlassPanelBorderBrush}"
|
BorderBrush="{DynamicResource AdaptiveGlassPanelBorderBrush}"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
CornerRadius="14" />
|
CornerRadius="{DynamicResource DesignCornerRadiusSm}" />
|
||||||
<TextBlock Text="{Binding PreviewSecondaryLabel}"
|
<TextBlock Text="{Binding PreviewSecondaryLabel}"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
@@ -134,7 +134,7 @@
|
|||||||
Background="{Binding TertiarySwatchBrush}"
|
Background="{Binding TertiarySwatchBrush}"
|
||||||
BorderBrush="{DynamicResource AdaptiveGlassPanelBorderBrush}"
|
BorderBrush="{DynamicResource AdaptiveGlassPanelBorderBrush}"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
CornerRadius="14" />
|
CornerRadius="{DynamicResource DesignCornerRadiusSm}" />
|
||||||
<TextBlock Text="{Binding PreviewTertiaryLabel}"
|
<TextBlock Text="{Binding PreviewTertiaryLabel}"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
@@ -146,7 +146,7 @@
|
|||||||
Background="{Binding NeutralSwatchBrush}"
|
Background="{Binding NeutralSwatchBrush}"
|
||||||
BorderBrush="{DynamicResource AdaptiveGlassPanelBorderBrush}"
|
BorderBrush="{DynamicResource AdaptiveGlassPanelBorderBrush}"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
CornerRadius="14" />
|
CornerRadius="{DynamicResource DesignCornerRadiusSm}" />
|
||||||
<TextBlock Text="{Binding PreviewNeutralLabel}"
|
<TextBlock Text="{Binding PreviewNeutralLabel}"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
@@ -177,7 +177,7 @@
|
|||||||
Background="{Binding SeedSwatchBrush}"
|
Background="{Binding SeedSwatchBrush}"
|
||||||
BorderBrush="{DynamicResource AdaptiveGlassPanelBorderBrush}"
|
BorderBrush="{DynamicResource AdaptiveGlassPanelBorderBrush}"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
CornerRadius="14" />
|
CornerRadius="{DynamicResource DesignCornerRadiusSm}" />
|
||||||
<TextBlock Text="{Binding PreviewSeedLabel}"
|
<TextBlock Text="{Binding PreviewSeedLabel}"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
@@ -217,7 +217,7 @@
|
|||||||
Background="{Binding Brush}"
|
Background="{Binding Brush}"
|
||||||
BorderBrush="{DynamicResource AdaptiveGlassPanelBorderBrush}"
|
BorderBrush="{DynamicResource AdaptiveGlassPanelBorderBrush}"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
CornerRadius="12" />
|
CornerRadius="{DynamicResource DesignCornerRadiusXs}" />
|
||||||
<TextBlock Text="{Binding Label}"
|
<TextBlock Text="{Binding Label}"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
TextAlignment="Center"
|
TextAlignment="Center"
|
||||||
@@ -240,7 +240,7 @@
|
|||||||
Background="{Binding SeedSwatchBrush}"
|
Background="{Binding SeedSwatchBrush}"
|
||||||
BorderBrush="{DynamicResource AdaptiveGlassPanelBorderBrush}"
|
BorderBrush="{DynamicResource AdaptiveGlassPanelBorderBrush}"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
CornerRadius="14" />
|
CornerRadius="{DynamicResource DesignCornerRadiusSm}" />
|
||||||
<TextBlock Text="{Binding PreviewSeedLabel}"
|
<TextBlock Text="{Binding PreviewSeedLabel}"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
|
|||||||
@@ -8,16 +8,14 @@
|
|||||||
x:DataType="vm:ComponentsSettingsPageViewModel">
|
x:DataType="vm:ComponentsSettingsPageViewModel">
|
||||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||||
<StackPanel Classes="settings-page-container">
|
<StackPanel Classes="settings-page-container">
|
||||||
|
<controls:IconText Icon="Apps"
|
||||||
<!-- 网格布局设置分组 -->
|
Text="{Binding ComponentsHeader}"
|
||||||
<controls:IconText Icon="GridDots"
|
|
||||||
Text="{Binding GridHeader}"
|
|
||||||
Margin="0,0,0,4" />
|
Margin="0,0,0,4" />
|
||||||
|
|
||||||
<ui:SettingsExpander Header="{Binding GridHeader}"
|
<ui:SettingsExpander Header="{Binding ComponentsHeader}"
|
||||||
IsExpanded="True">
|
IsExpanded="True">
|
||||||
<ui:SettingsExpander.IconSource>
|
<ui:SettingsExpander.IconSource>
|
||||||
<fi:SymbolIconSource Symbol="GridDots" />
|
<fi:SymbolIconSource Symbol="Apps" />
|
||||||
</ui:SettingsExpander.IconSource>
|
</ui:SettingsExpander.IconSource>
|
||||||
<ui:SettingsExpanderItem>
|
<ui:SettingsExpanderItem>
|
||||||
<Grid ColumnDefinitions="Auto,*,Auto" ColumnSpacing="16">
|
<Grid ColumnDefinitions="Auto,*,Auto" ColumnSpacing="16">
|
||||||
@@ -71,6 +69,33 @@
|
|||||||
</ui:SettingsExpanderItem>
|
</ui:SettingsExpanderItem>
|
||||||
</ui:SettingsExpander>
|
</ui:SettingsExpander>
|
||||||
|
|
||||||
|
<controls:IconText Icon="ShapeOrganic"
|
||||||
|
Text="{Binding ComponentRadiusHeader}"
|
||||||
|
Margin="0,12,0,4" />
|
||||||
|
|
||||||
|
<ui:SettingsExpander Header="{Binding GlobalCornerRadiusLabel}"
|
||||||
|
Description="{Binding GlobalCornerRadiusDescription}">
|
||||||
|
<ui:SettingsExpander.IconSource>
|
||||||
|
<fi:SymbolIconSource Symbol="ShapeOrganic" />
|
||||||
|
</ui:SettingsExpander.IconSource>
|
||||||
|
<ui:SettingsExpanderItem>
|
||||||
|
<Grid ColumnDefinitions="Auto,*,Auto" ColumnSpacing="16">
|
||||||
|
<TextBlock Text="{Binding GlobalCornerRadiusLabel}"
|
||||||
|
VerticalAlignment="Center" />
|
||||||
|
<Slider Grid.Column="1"
|
||||||
|
Minimum="0.7"
|
||||||
|
Maximum="1.4"
|
||||||
|
IsSnapToTickEnabled="True"
|
||||||
|
TickFrequency="0.05"
|
||||||
|
Value="{Binding GlobalCornerRadiusScale}" />
|
||||||
|
<TextBlock Grid.Column="2"
|
||||||
|
Width="48"
|
||||||
|
Text="{Binding GlobalCornerRadiusScale, StringFormat={}{0:F2}x}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
HorizontalAlignment="Right" />
|
||||||
|
</Grid>
|
||||||
|
</ui:SettingsExpanderItem>
|
||||||
|
</ui:SettingsExpander>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ namespace LanMountainDesktop.Views.SettingsPages;
|
|||||||
"components",
|
"components",
|
||||||
"Components",
|
"Components",
|
||||||
SettingsPageCategory.Components,
|
SettingsPageCategory.Components,
|
||||||
IconKey = "GridDots",
|
IconKey = "Apps",
|
||||||
SortOrder = 20,
|
SortOrder = 20,
|
||||||
TitleLocalizationKey = "settings.components.title",
|
TitleLocalizationKey = "settings.components.title",
|
||||||
DescriptionLocalizationKey = "settings.components.description")]
|
DescriptionLocalizationKey = "settings.components.description")]
|
||||||
|
|||||||
@@ -515,7 +515,7 @@ internal sealed class PluginMarketEmbeddedView : UserControl, IDisposable
|
|||||||
Background = isSelected ? SelectedSurfaceBrush : SurfaceBrush,
|
Background = isSelected ? SelectedSurfaceBrush : SurfaceBrush,
|
||||||
BorderBrush = isSelected ? SelectedBorderBrush : CardBorderBrush,
|
BorderBrush = isSelected ? SelectedBorderBrush : CardBorderBrush,
|
||||||
BorderThickness = new Thickness(1),
|
BorderThickness = new Thickness(1),
|
||||||
CornerRadius = new CornerRadius(18),
|
CornerRadius = ResolveCornerRadiusResource("DesignCornerRadiusMd", 18),
|
||||||
Padding = new Thickness(14),
|
Padding = new Thickness(14),
|
||||||
Child = layoutGrid
|
Child = layoutGrid
|
||||||
};
|
};
|
||||||
@@ -597,7 +597,7 @@ internal sealed class PluginMarketEmbeddedView : UserControl, IDisposable
|
|||||||
detailPanel.Children.Add(new Border
|
detailPanel.Children.Add(new Border
|
||||||
{
|
{
|
||||||
Background = new SolidColorBrush(Color.Parse("#24FFC42B1C")),
|
Background = new SolidColorBrush(Color.Parse("#24FFC42B1C")),
|
||||||
CornerRadius = new CornerRadius(14),
|
CornerRadius = ResolveCornerRadiusResource("DesignCornerRadiusSm", 14),
|
||||||
Padding = new Thickness(12),
|
Padding = new Thickness(12),
|
||||||
Child = new TextBlock
|
Child = new TextBlock
|
||||||
{
|
{
|
||||||
@@ -617,7 +617,7 @@ internal sealed class PluginMarketEmbeddedView : UserControl, IDisposable
|
|||||||
Background = SurfaceBrush,
|
Background = SurfaceBrush,
|
||||||
BorderBrush = CardBorderBrush,
|
BorderBrush = CardBorderBrush,
|
||||||
BorderThickness = new Thickness(1),
|
BorderThickness = new Thickness(1),
|
||||||
CornerRadius = new CornerRadius(16),
|
CornerRadius = ResolveCornerRadiusResource("DesignCornerRadiusMd", 16),
|
||||||
Padding = new Thickness(16),
|
Padding = new Thickness(16),
|
||||||
Child = new TextBlock
|
Child = new TextBlock
|
||||||
{
|
{
|
||||||
@@ -1011,7 +1011,7 @@ internal sealed class PluginMarketEmbeddedView : UserControl, IDisposable
|
|||||||
return new Border
|
return new Border
|
||||||
{
|
{
|
||||||
Background = SurfaceBrush,
|
Background = SurfaceBrush,
|
||||||
CornerRadius = new CornerRadius(18),
|
CornerRadius = ResolveCornerRadiusResource("DesignCornerRadiusMd", 18),
|
||||||
Padding = new Thickness(padding)
|
Padding = new Thickness(padding)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -1021,7 +1021,7 @@ internal sealed class PluginMarketEmbeddedView : UserControl, IDisposable
|
|||||||
return new Border
|
return new Border
|
||||||
{
|
{
|
||||||
Background = SurfaceBrush,
|
Background = SurfaceBrush,
|
||||||
CornerRadius = new CornerRadius(16),
|
CornerRadius = ResolveCornerRadiusResource("DesignCornerRadiusMd", 16),
|
||||||
BorderBrush = CardBorderBrush,
|
BorderBrush = CardBorderBrush,
|
||||||
BorderThickness = new Thickness(1),
|
BorderThickness = new Thickness(1),
|
||||||
Padding = new Thickness(18),
|
Padding = new Thickness(18),
|
||||||
@@ -1124,7 +1124,7 @@ internal sealed class PluginMarketEmbeddedView : UserControl, IDisposable
|
|||||||
Background = SurfaceBrush,
|
Background = SurfaceBrush,
|
||||||
BorderBrush = CardBorderBrush,
|
BorderBrush = CardBorderBrush,
|
||||||
BorderThickness = new Thickness(1),
|
BorderThickness = new Thickness(1),
|
||||||
CornerRadius = new CornerRadius(14),
|
CornerRadius = ResolveCornerRadiusResource("DesignCornerRadiusSm", 14),
|
||||||
Padding = new Thickness(14),
|
Padding = new Thickness(14),
|
||||||
Child = new StackPanel
|
Child = new StackPanel
|
||||||
{
|
{
|
||||||
@@ -1154,7 +1154,7 @@ internal sealed class PluginMarketEmbeddedView : UserControl, IDisposable
|
|||||||
Background = SurfaceBrush,
|
Background = SurfaceBrush,
|
||||||
BorderBrush = CardBorderBrush,
|
BorderBrush = CardBorderBrush,
|
||||||
BorderThickness = new Thickness(1),
|
BorderThickness = new Thickness(1),
|
||||||
CornerRadius = new CornerRadius(14),
|
CornerRadius = ResolveCornerRadiusResource("DesignCornerRadiusSm", 14),
|
||||||
Padding = new Thickness(14),
|
Padding = new Thickness(14),
|
||||||
Child = new StackPanel
|
Child = new StackPanel
|
||||||
{
|
{
|
||||||
@@ -1257,4 +1257,11 @@ internal sealed class PluginMarketEmbeddedView : UserControl, IDisposable
|
|||||||
_ => "Install"
|
_ => "Install"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static CornerRadius ResolveCornerRadiusResource(string key, double fallback)
|
||||||
|
{
|
||||||
|
return Application.Current?.TryFindResource(key, out var resource) == true && resource is CornerRadius radius
|
||||||
|
? radius
|
||||||
|
: new CornerRadius(fallback);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user