mirror of
https://github.com/wwiinnddyy/LanMountainDesktop.git
synced 2026-06-22 09:14:25 +08:00
feat.文档更新
This commit is contained in:
182
docs/archive/PLUGIN_SDK_V4_MIGRATION.md
Normal file
182
docs/archive/PLUGIN_SDK_V4_MIGRATION.md
Normal file
@@ -0,0 +1,182 @@
|
||||
# Plugin SDK v4 Migration Guide
|
||||
|
||||
This guide describes the breaking changes introduced by Plugin SDK `4.0.0`.
|
||||
|
||||
## Version Baseline
|
||||
|
||||
- Host plugin SDK baseline: `4.0.0`
|
||||
- Plugins targeting `3.x` are rejected by default
|
||||
- Manifest file remains `plugin.json`
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
1. `AddPluginDesktopComponent` now uses options-first registration.
|
||||
2. `PluginDesktopComponentOptions` is now the canonical component registration shape and must include `ComponentId`.
|
||||
3. Appearance and radius access are provided through strongly typed APIs:
|
||||
- `IPluginAppearanceContext`
|
||||
- `PluginAppearanceSnapshot`
|
||||
- `PluginCornerRadiusTokens`
|
||||
- `PluginCornerRadiusPreset`
|
||||
4. `PluginDesktopComponentContext` now exposes `Appearance` as the primary appearance access point.
|
||||
|
||||
## New Component Registration Pattern
|
||||
|
||||
```csharp
|
||||
services.AddPluginDesktopComponent<MyWidget>(new PluginDesktopComponentOptions
|
||||
{
|
||||
ComponentId = "YourPlugin.Widget",
|
||||
DisplayName = "My Widget",
|
||||
IconKey = "PuzzlePiece",
|
||||
Category = "Plugins",
|
||||
MinWidthCells = 4,
|
||||
MinHeightCells = 3,
|
||||
CornerRadiusPreset = PluginCornerRadiusPreset.Default
|
||||
});
|
||||
```
|
||||
|
||||
## Appearance Usage Pattern
|
||||
|
||||
```csharp
|
||||
public MyWidget(PluginDesktopComponentContext context)
|
||||
{
|
||||
var mdRadius = context.Appearance.ResolveCornerRadius(PluginCornerRadiusPreset.Md);
|
||||
var adaptiveRadius = context.Appearance.ResolveScaledCornerRadius(12, 8, 20);
|
||||
}
|
||||
```
|
||||
|
||||
## Corner Radius System
|
||||
|
||||
Plugin widgets must follow the host's corner radius settings to maintain visual consistency with built-in components.
|
||||
|
||||
### Why Plugins Cannot Use XAML Resources
|
||||
|
||||
Plugins run in a separate `AssemblyLoadContext` and cannot directly access the host's resource dictionary. Therefore, `{DynamicResource DesignCornerRadiusComponent}` is not available in plugin XAML. Instead, plugins must resolve corner radius values in code through `PluginDesktopComponentContext`.
|
||||
|
||||
### Available Corner Radius Presets
|
||||
|
||||
| Preset | Default Value | Usage |
|
||||
|--------|---------------|-------|
|
||||
| `Micro` | 6px | Tiny elements |
|
||||
| `Xs` | 12px | Small elements and icon containers |
|
||||
| `Sm` | 14px | Small colored blocks |
|
||||
| `Md` | 20px | Common buttons/cards |
|
||||
| `Lg` | 28px | Normal glass panels |
|
||||
| `Xl` | 32px | Emphasized containers |
|
||||
| `Island` | 36px | Large containers |
|
||||
| `Component` | 18px | **Desktop widget standard radius** |
|
||||
| `Default` | (adaptive) | Adaptive based on cell size |
|
||||
|
||||
### Corner Radius API Reference
|
||||
|
||||
```csharp
|
||||
public class MyWidget : Border
|
||||
{
|
||||
public MyWidget(PluginDesktopComponentContext context)
|
||||
{
|
||||
// Method 1: Use preset tokens (recommended for consistency)
|
||||
CornerRadius = context.ResolveCornerRadius(PluginCornerRadiusPreset.Component);
|
||||
|
||||
// Method 2: Use preset with fallback (extension method)
|
||||
CornerRadius = context.Appearance.Snapshot.ResolveCornerRadius(
|
||||
PluginCornerRadiusPreset.Md,
|
||||
fallback: new CornerRadius(8));
|
||||
|
||||
// Method 3: Custom radius with global scale applied
|
||||
CornerRadius = context.ResolveScaledCornerRadius(baseRadius: 16, minimum: 8, maximum: 24);
|
||||
|
||||
// Method 4: Access tokens directly
|
||||
var tokens = context.CornerRadiusTokens;
|
||||
CornerRadius = tokens.ToCornerRadius(PluginCornerRadiusPreset.Md);
|
||||
|
||||
// Method 5: Get raw token value (double)
|
||||
double componentRadius = context.CornerRadiusTokens.Component;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Best Practices
|
||||
|
||||
1. **Always use `PluginCornerRadiusPreset.Component` for the widget root container** - This ensures consistency with built-in widgets.
|
||||
|
||||
2. **Apply corner radius in code, not XAML** - Since plugins cannot access host resources, set `CornerRadius` in the constructor or code-behind.
|
||||
|
||||
3. **Re-apply radius on size changes** - For adaptive layouts, subscribe to `SizeChanged` and recalculate:
|
||||
|
||||
```csharp
|
||||
public MyWidget(PluginDesktopComponentContext context)
|
||||
{
|
||||
_context = context;
|
||||
ApplyCornerRadius();
|
||||
SizeChanged += (_, _) => ApplyCornerRadius();
|
||||
}
|
||||
|
||||
private void ApplyCornerRadius()
|
||||
{
|
||||
var basis = Math.Min(Bounds.Width, Bounds.Height);
|
||||
CornerRadius = _context.ResolveCornerRadius(
|
||||
PluginCornerRadiusPreset.Component,
|
||||
minimum: Math.Clamp(basis * 0.08, 8, 16),
|
||||
maximum: Math.Clamp(basis * 0.15, 16, 28));
|
||||
}
|
||||
```
|
||||
|
||||
4. **Inner elements can use smaller presets** - For cards or buttons inside your widget:
|
||||
|
||||
```csharp
|
||||
var innerCard = new Border
|
||||
{
|
||||
CornerRadius = _context.ResolveCornerRadius(PluginCornerRadiusPreset.Md)
|
||||
};
|
||||
```
|
||||
|
||||
## Manifest Update
|
||||
|
||||
Update plugin manifests to API `4.x`:
|
||||
|
||||
```json
|
||||
{
|
||||
"apiVersion": "4.0.0"
|
||||
}
|
||||
```
|
||||
|
||||
## Validation Checklist
|
||||
|
||||
- `plugin.json` declares `apiVersion` `4.0.0` (or compatible `4.x`)
|
||||
- component registration migrated to options model
|
||||
- runtime appearance access uses `IPluginAppearanceContext`
|
||||
- plugin package rebuilt and republished as `.laapp`
|
||||
|
||||
## Process Isolation Additions
|
||||
|
||||
SDK `4.x` now also reserves manifest and API surface for process isolation without breaking existing plugins.
|
||||
|
||||
### Manifest
|
||||
|
||||
`plugin.json` can declare the desired runtime mode:
|
||||
|
||||
```json
|
||||
{
|
||||
"runtime": {
|
||||
"mode": "in-proc"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Supported values:
|
||||
|
||||
- `in-proc`
|
||||
- `isolated-background`
|
||||
- `isolated-window`
|
||||
|
||||
If `runtime` is omitted, the host normalizes it to `in-proc` for backward compatibility.
|
||||
|
||||
### Worker Entry
|
||||
|
||||
Plugins that opt into isolated execution can prepare a worker-side entry by implementing:
|
||||
|
||||
- `IPluginWorker`
|
||||
- `PluginWorkerBase`
|
||||
- `IPluginWorkerContext`
|
||||
- `[PluginWorkerEntrance]`
|
||||
|
||||
The first phase only targets `isolated-background`: background services, timers, network calls, and risky native integrations move into the worker process, while UI remains a host-side shell driven over IPC.
|
||||
Reference in New Issue
Block a user