change.插件sdk更新

This commit is contained in:
lincube
2026-04-12 13:52:52 +08:00
parent 4a89c2388b
commit 91ab52ce8b
7 changed files with 339 additions and 16 deletions

View File

@@ -0,0 +1,109 @@
namespace LanMountainDesktop.PluginSdk;
/// <summary>
/// 外观变更事件参数,当主题、圆角或其他外观属性变化时触发。
/// </summary>
public sealed class AppearanceChangedEvent : EventArgs
{
/// <summary>
/// 创建外观变更事件实例。
/// </summary>
/// <param name="snapshot">当前外观快照</param>
/// <param name="changedProperties">变更的属性集合</param>
public AppearanceChangedEvent(
PluginAppearanceSnapshot snapshot,
IReadOnlyCollection<AppearanceProperty> changedProperties)
{
ArgumentNullException.ThrowIfNull(snapshot);
ArgumentNullException.ThrowIfNull(changedProperties);
Snapshot = snapshot;
ChangedProperties = changedProperties;
}
/// <summary>
/// 当前外观快照。
/// </summary>
public PluginAppearanceSnapshot Snapshot { get; }
/// <summary>
/// 变更的属性集合。
/// </summary>
public IReadOnlyCollection<AppearanceProperty> ChangedProperties { get; }
/// <summary>
/// 圆角是否发生变化。
/// </summary>
public bool CornerRadiusChanged => ChangedProperties.Contains(AppearanceProperty.CornerRadius);
/// <summary>
/// 主题变体(亮色/暗色)是否发生变化。
/// </summary>
public bool ThemeVariantChanged => ChangedProperties.Contains(AppearanceProperty.ThemeVariant);
/// <summary>
/// 强调色是否发生变化。
/// </summary>
public bool AccentColorChanged => ChangedProperties.Contains(AppearanceProperty.AccentColor);
/// <summary>
/// 圆角风格是否发生变化。
/// </summary>
public bool CornerRadiusStyleChanged => ChangedProperties.Contains(AppearanceProperty.CornerRadiusStyle);
/// <summary>
/// 检查指定属性是否发生变化。
/// </summary>
/// <param name="property">要检查的属性</param>
/// <returns>如果属性发生变化则返回 true</returns>
public bool HasChanged(AppearanceProperty property)
{
return ChangedProperties.Contains(property);
}
/// <summary>
/// 检查是否有任何外观属性发生变化。
/// </summary>
public bool HasAnyChanges => ChangedProperties.Count > 0;
}
/// <summary>
/// 可变更的外观属性枚举。
/// </summary>
public enum AppearanceProperty
{
/// <summary>
/// 圆角Token值发生变化。
/// </summary>
CornerRadius,
/// <summary>
/// 主题变体(亮色/暗色)发生变化。
/// </summary>
ThemeVariant,
/// <summary>
/// 强调色发生变化。
/// </summary>
AccentColor,
/// <summary>
/// 圆角风格Sharp/Balanced/Rounded/Open发生变化。
/// </summary>
CornerRadiusStyle,
/// <summary>
/// 壁纸发生变化。
/// </summary>
Wallpaper,
/// <summary>
/// 系统材质模式发生变化。
/// </summary>
SystemMaterialMode,
/// <summary>
/// 所有外观属性(用于批量更新)。
/// </summary>
All
}

View File

@@ -1,10 +1,35 @@
namespace LanMountainDesktop.PluginSdk;
/// <summary>
/// 插件外观上下文接口,提供主题、圆角等外观资源的访问和变更通知。
/// </summary>
public interface IPluginAppearanceContext
{
/// <summary>
/// 当前外观快照。
/// </summary>
PluginAppearanceSnapshot Snapshot { get; }
/// <summary>
/// 外观变更事件。当主题、圆角或其他外观属性发生变化时触发。
/// </summary>
event EventHandler<AppearanceChangedEvent>? Changed;
/// <summary>
/// 解析带缩放的圆角半径。
/// </summary>
/// <param name="baseRadius">基础圆角半径</param>
/// <param name="minimum">最小值(可选)</param>
/// <param name="maximum">最大值(可选)</param>
/// <returns>解析后的圆角半径</returns>
double ResolveScaledCornerRadius(double baseRadius, double? minimum = null, double? maximum = null);
/// <summary>
/// 根据预设解析圆角半径。
/// </summary>
/// <param name="preset">圆角预设</param>
/// <param name="minimum">最小值(可选)</param>
/// <param name="maximum">最大值(可选)</param>
/// <returns>解析后的圆角半径</returns>
double ResolveCornerRadius(PluginCornerRadiusPreset preset, double? minimum = null, double? maximum = null);
}

View File

@@ -1,13 +1,22 @@
namespace LanMountainDesktop.PluginSdk;
/// <summary>
/// 插件外观上下文实现,提供主题、圆角等外观资源的访问和变更通知。
/// </summary>
public sealed class PluginAppearanceContext : IPluginAppearanceContext
{
private PluginAppearanceSnapshot _snapshot;
/// <summary>
/// 创建插件外观上下文实例。
/// </summary>
/// <param name="snapshot">初始外观快照</param>
public PluginAppearanceContext(PluginAppearanceSnapshot snapshot)
{
ArgumentNullException.ThrowIfNull(snapshot);
ArgumentNullException.ThrowIfNull(snapshot.CornerRadiusTokens);
Snapshot = snapshot with
_snapshot = snapshot with
{
ThemeVariant = string.IsNullOrWhiteSpace(snapshot.ThemeVariant)
? "Unknown"
@@ -15,8 +24,37 @@ public sealed class PluginAppearanceContext : IPluginAppearanceContext
};
}
public PluginAppearanceSnapshot Snapshot { get; }
/// <inheritdoc />
public PluginAppearanceSnapshot Snapshot => _snapshot;
/// <inheritdoc />
public event EventHandler<AppearanceChangedEvent>? Changed;
/// <summary>
/// 更新外观快照并触发变更事件。
/// 此方法由宿主调用,用于在主题、圆角等外观属性变化时通知插件。
/// </summary>
/// <param name="newSnapshot">新的外观快照</param>
/// <param name="changedProperties">变更的属性集合</param>
public void UpdateSnapshot(PluginAppearanceSnapshot newSnapshot, IReadOnlyCollection<AppearanceProperty> changedProperties)
{
ArgumentNullException.ThrowIfNull(newSnapshot);
ArgumentNullException.ThrowIfNull(changedProperties);
_snapshot = newSnapshot with
{
ThemeVariant = string.IsNullOrWhiteSpace(newSnapshot.ThemeVariant)
? "Unknown"
: newSnapshot.ThemeVariant.Trim()
};
if (changedProperties.Count > 0)
{
Changed?.Invoke(this, new AppearanceChangedEvent(_snapshot, changedProperties));
}
}
/// <inheritdoc />
public double ResolveScaledCornerRadius(double baseRadius, double? minimum = null, double? maximum = null)
{
var value = Math.Max(0d, baseRadius);
@@ -30,16 +68,17 @@ public sealed class PluginAppearanceContext : IPluginAppearanceContext
return Math.Clamp(value, clampedMin, clampedMax);
}
/// <inheritdoc />
public double ResolveCornerRadius(PluginCornerRadiusPreset preset, double? minimum = null, double? maximum = null)
{
var resolved = Math.Max(0d, Snapshot.CornerRadiusTokens.Get(preset));
var resolved = Math.Max(0d, _snapshot.CornerRadiusTokens.Get(preset));
if (!minimum.HasValue && !maximum.HasValue)
{
return resolved;
}
var clampedMin = minimum ?? resolved;
var clampedMax = maximum ?? resolved;
var clampedMin = minimum ?? 0d;
var clampedMax = maximum ?? double.MaxValue;
if (clampedMin > clampedMax)
{
(clampedMin, clampedMax) = (clampedMax, clampedMin);

View File

@@ -0,0 +1,137 @@
using Avalonia;
namespace LanMountainDesktop.PluginSdk;
/// <summary>
/// 插件外观辅助方法,提供统一的圆角和主题资源访问。
/// </summary>
public static class PluginAppearanceHelper
{
/// <summary>
/// 获取桌面组件主外壳圆角半径。
/// 这是组件最外层边框应该使用的圆角值,对应 DesignCornerRadiusComponent 资源。
/// </summary>
/// <param name="context">外观上下文</param>
/// <returns>主外壳圆角半径(像素)</returns>
public static double GetShellCornerRadius(this IPluginAppearanceContext context)
{
ArgumentNullException.ThrowIfNull(context);
return context.ResolveCornerRadius(PluginCornerRadiusPreset.Component);
}
/// <summary>
/// 获取内部卡片圆角半径。
/// 用于组件内部的次级卡片、内容区块等。
/// </summary>
/// <param name="context">外观上下文</param>
/// <returns>内部卡片圆角半径(像素)</returns>
public static double GetCardCornerRadius(this IPluginAppearanceContext context)
{
ArgumentNullException.ThrowIfNull(context);
return context.ResolveCornerRadius(PluginCornerRadiusPreset.Sm);
}
/// <summary>
/// 获取控件圆角半径。
/// 用于按钮、输入框、标签等交互控件。
/// </summary>
/// <param name="context">外观上下文</param>
/// <returns>控件圆角半径(像素)</returns>
public static double GetControlCornerRadius(this IPluginAppearanceContext context)
{
ArgumentNullException.ThrowIfNull(context);
return context.ResolveCornerRadius(PluginCornerRadiusPreset.Xs);
}
/// <summary>
/// 获取徽章/标签圆角半径。
/// 用于小徽章、标签、角标等微元素。
/// </summary>
/// <param name="context">外观上下文</param>
/// <returns>徽章圆角半径(像素)</returns>
public static double GetBadgeCornerRadius(this IPluginAppearanceContext context)
{
ArgumentNullException.ThrowIfNull(context);
return context.ResolveCornerRadius(PluginCornerRadiusPreset.Micro);
}
/// <summary>
/// 获取中等面板圆角半径。
/// 用于悬浮菜单、小提示框、子面板等。
/// </summary>
/// <param name="context">外观上下文</param>
/// <returns>中等面板圆角半径(像素)</returns>
public static double GetMediumPanelCornerRadius(this IPluginAppearanceContext context)
{
ArgumentNullException.ThrowIfNull(context);
return context.ResolveCornerRadius(PluginCornerRadiusPreset.Md);
}
/// <summary>
/// 获取大面板圆角半径。
/// 用于对话框、设置面板等大型容器(非桌面组件)。
/// </summary>
/// <param name="context">外观上下文</param>
/// <returns>大面板圆角半径(像素)</returns>
public static double GetLargePanelCornerRadius(this IPluginAppearanceContext context)
{
ArgumentNullException.ThrowIfNull(context);
return context.ResolveCornerRadius(PluginCornerRadiusPreset.Lg);
}
/// <summary>
/// 将圆角预设转换为 Avalonia CornerRadius。
/// </summary>
/// <param name="context">外观上下文</param>
/// <param name="preset">圆角预设</param>
/// <returns>Avalonia CornerRadius 结构</returns>
public static CornerRadius ToCornerRadius(this IPluginAppearanceContext context, PluginCornerRadiusPreset preset)
{
ArgumentNullException.ThrowIfNull(context);
var radius = context.ResolveCornerRadius(preset);
return new CornerRadius(radius);
}
/// <summary>
/// 获取当前主题变体(亮色/暗色)。
/// </summary>
/// <param name="context">外观上下文</param>
/// <returns>是否为暗色主题</returns>
public static bool IsDarkTheme(this IPluginAppearanceContext context)
{
ArgumentNullException.ThrowIfNull(context);
return string.Equals(context.Snapshot.ThemeVariant, "Dark", StringComparison.OrdinalIgnoreCase);
}
/// <summary>
/// 获取当前主题变体字符串。
/// </summary>
/// <param name="context">外观上下文</param>
/// <returns>主题变体字符串("Light" 或 "Dark"</returns>
public static string GetThemeVariant(this IPluginAppearanceContext context)
{
ArgumentNullException.ThrowIfNull(context);
return context.Snapshot.ThemeVariant;
}
}
/// <summary>
/// 内部元素层级,用于区分不同层级的圆角需求。
/// </summary>
public enum InnerElementLevel
{
/// <summary>
/// 内部卡片:使用 Sm token14px @ 1.0x
/// </summary>
Card,
/// <summary>
/// 交互控件:使用 Xs token12px @ 1.0x
/// </summary>
Control,
/// <summary>
/// 微元素徽章:使用 Micro token6px @ 1.0x
/// </summary>
Badge
}

View File

@@ -72,14 +72,11 @@ public sealed class PluginDesktopComponentRegistration
var resolved = CornerRadiusResolver is not null
? CornerRadiusResolver(appearance, Math.Max(1d, cellSize))
: CornerRadiusPreset == PluginCornerRadiusPreset.Default
? appearance.ResolveScaledCornerRadius(
Math.Clamp(Math.Max(1d, cellSize) * 0.22, 8, 18),
8,
18)
? appearance.ResolveCornerRadius(PluginCornerRadiusPreset.Component)
: appearance.ResolveCornerRadius(CornerRadiusPreset);
return double.IsFinite(resolved)
? Math.Max(0d, resolved)
: appearance.ResolveCornerRadius(PluginCornerRadiusPreset.Default);
: appearance.ResolveCornerRadius(PluginCornerRadiusPreset.Component);
}
}