2026-08-11 23:03:55 +08:00
namespace LanMountainDesktop.AirAppSdk ;
2026-03-09 12:27:33 +08:00
2026-08-11 23:03:55 +08:00
public sealed class AirAppComponentContext
2026-03-09 12:27:33 +08:00
{
2026-08-11 23:03:55 +08:00
public AirAppComponentContext (
AirAppManifest manifest ,
2026-03-09 12:27:33 +08:00
string pluginDirectory ,
string dataDirectory ,
IServiceProvider services ,
IReadOnlyDictionary < string , object? > properties ,
string componentId ,
string? placementId ,
2026-03-13 09:10:00 +08:00
double cellSize ,
2026-08-11 23:03:55 +08:00
IAirAppAppearanceContext appearance ,
IAirAppSettingsService ? pluginSettings = null )
2026-03-09 12:27:33 +08:00
{
ArgumentNullException . ThrowIfNull ( manifest ) ;
ArgumentException . ThrowIfNullOrWhiteSpace ( pluginDirectory ) ;
ArgumentException . ThrowIfNullOrWhiteSpace ( dataDirectory ) ;
ArgumentException . ThrowIfNullOrWhiteSpace ( componentId ) ;
ArgumentNullException . ThrowIfNull ( services ) ;
ArgumentNullException . ThrowIfNull ( properties ) ;
2026-03-20 22:37:37 +08:00
ArgumentNullException . ThrowIfNull ( appearance ) ;
2026-03-09 12:27:33 +08:00
Manifest = manifest ;
2026-08-11 23:03:55 +08:00
AirAppDirectory = pluginDirectory ;
2026-03-09 12:27:33 +08:00
DataDirectory = dataDirectory ;
Services = services ;
Properties = properties ;
ComponentId = componentId . Trim ( ) ;
PlacementId = string . IsNullOrWhiteSpace ( placementId ) ? null : placementId . Trim ( ) ;
CellSize = Math . Max ( 1 , cellSize ) ;
2026-03-20 22:37:37 +08:00
Appearance = appearance ;
2026-08-11 23:03:55 +08:00
AirAppSettings = pluginSettings ;
2026-03-09 12:27:33 +08:00
}
2026-08-11 23:03:55 +08:00
public AirAppManifest Manifest { get ; }
2026-03-09 12:27:33 +08:00
2026-08-11 23:03:55 +08:00
public string AirAppDirectory { get ; }
2026-03-09 12:27:33 +08:00
public string DataDirectory { get ; }
public IServiceProvider Services { get ; }
public IReadOnlyDictionary < string , object? > Properties { get ; }
public string ComponentId { get ; }
public string? PlacementId { get ; }
public double CellSize { get ; }
2026-08-11 23:03:55 +08:00
public IAirAppAppearanceContext Appearance { get ; }
2026-03-20 22:37:37 +08:00
2026-08-11 23:03:55 +08:00
public AirAppCornerRadiusTokens CornerRadiusTokens = > Appearance . Snapshot . CornerRadiusTokens ;
2026-03-20 00:41:14 +08:00
2026-08-11 23:03:55 +08:00
public IAirAppSettingsService ? AirAppSettings { get ; }
/// <summary>
/// 由宿主注入的窗口打开处理器。组件通过 <see cref="OpenWindowAsync"/> 打开本 AirApp 的窗口轻应用。
/// </summary>
public Func < string , Task > ? OpenWindowHandler { get ; set ; }
2026-03-13 09:10:00 +08:00
2026-03-20 00:41:14 +08:00
public double ResolveScaledCornerRadius ( double baseRadius , double? minimum = null , double? maximum = null )
{
2026-03-20 22:37:37 +08:00
return Appearance . ResolveScaledCornerRadius ( baseRadius , minimum , maximum ) ;
}
2026-08-11 23:03:55 +08:00
public double ResolveCornerRadius ( AirAppCornerRadiusPreset preset , double? minimum = null , double? maximum = null )
2026-03-20 22:37:37 +08:00
{
return Appearance . ResolveCornerRadius ( preset , minimum , maximum ) ;
2026-03-20 00:41:14 +08:00
}
2026-08-11 23:03:55 +08:00
/// <summary>
/// 打开本 AirApp 声明的一个窗口轻应用。
/// </summary>
/// <param name="windowId">窗口标识(与 <c>AddAirAppWindow</c> 注册的 id 一致)。</param>
public Task OpenWindowAsync ( string windowId )
{
ArgumentException . ThrowIfNullOrWhiteSpace ( windowId ) ;
var handler = OpenWindowHandler ;
if ( handler is null )
{
throw new NotSupportedException (
$"AirApp '{Manifest.Id}' component '{ComponentId}' requested to open window '{windowId}', but the host does not support window opening for this component." ) ;
}
return handler ( windowId ) ;
}
2026-03-09 12:27:33 +08:00
public T ? GetService < T > ( )
{
return ( T ? ) Services . GetService ( typeof ( T ) ) ;
}
public bool TryGetProperty < T > ( string key , out T ? value )
{
ArgumentException . ThrowIfNullOrWhiteSpace ( key ) ;
if ( Properties . TryGetValue ( key , out var rawValue ) & & rawValue is T typedValue )
{
value = typedValue ;
return true ;
}
value = default ;
return false ;
}
}