mirror of
https://github.com/wwiinnddyy/LanMountainDesktop.git
synced 2026-06-20 23:54:26 +08:00
change.插件设置支持View
This commit is contained in:
@@ -28,6 +28,35 @@ public static class PluginServiceCollectionExtensions
|
||||
return services;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a plugin settings section with a custom AXAML view.
|
||||
/// The host application will display <typeparamref name="TView"/> directly
|
||||
/// in the settings window, allowing the plugin to use any Fluent Avalonia controls
|
||||
/// and custom layouts — just like built-in settings pages.
|
||||
/// </summary>
|
||||
/// <typeparam name="TView">A <see cref="SettingsPageBase"/> subclass that defines the settings UI using AXAML.</typeparam>
|
||||
public static IServiceCollection AddPluginSettingsSection<TView>(
|
||||
this IServiceCollection services,
|
||||
string id,
|
||||
string titleLocalizationKey,
|
||||
string? descriptionLocalizationKey = null,
|
||||
string iconKey = "PuzzlePiece",
|
||||
int sortOrder = 0)
|
||||
where TView : SettingsPageBase
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(services);
|
||||
|
||||
var builder = new PluginSettingsSectionBuilder(
|
||||
id,
|
||||
titleLocalizationKey,
|
||||
descriptionLocalizationKey,
|
||||
iconKey,
|
||||
sortOrder);
|
||||
builder.SetCustomView<TView>();
|
||||
services.AddSingleton(builder.Build());
|
||||
return services;
|
||||
}
|
||||
|
||||
public static IServiceCollection AddPluginDesktopComponent<TControl>(
|
||||
this IServiceCollection services,
|
||||
PluginDesktopComponentOptions options)
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Avalonia.Controls;
|
||||
|
||||
namespace LanMountainDesktop.PluginSdk;
|
||||
|
||||
public sealed class PluginSettingsSectionBuilder
|
||||
{
|
||||
private readonly List<SettingsOptionDefinition> _options = [];
|
||||
private Type? _customViewType;
|
||||
|
||||
internal PluginSettingsSectionBuilder(
|
||||
string id,
|
||||
@@ -30,8 +33,46 @@ public sealed class PluginSettingsSectionBuilder
|
||||
|
||||
public int SortOrder { get; }
|
||||
|
||||
public Type? CustomViewType => _customViewType;
|
||||
|
||||
public IReadOnlyList<SettingsOptionDefinition> Options => _options;
|
||||
|
||||
/// <summary>
|
||||
/// Sets a custom AXAML view for this settings section.
|
||||
/// The view type must be a subclass of <see cref="SettingsPageBase"/>.
|
||||
/// When a custom view is provided, the host application will use it directly
|
||||
/// instead of generating a page from the declared options, allowing the plugin
|
||||
/// to use any Fluent Avalonia controls and custom layouts.
|
||||
/// </summary>
|
||||
/// <typeparam name="TView">A <see cref="SettingsPageBase"/> subclass that defines the settings UI.</typeparam>
|
||||
public PluginSettingsSectionBuilder SetCustomView<TView>() where TView : SettingsPageBase
|
||||
{
|
||||
_customViewType = typeof(TView);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a custom AXAML view for this settings section.
|
||||
/// The view type must be a subclass of <see cref="SettingsPageBase"/>.
|
||||
/// When a custom view is provided, the host application will use it directly
|
||||
/// instead of generating a page from the declared options.
|
||||
/// </summary>
|
||||
/// <param name="viewType">A <see cref="SettingsPageBase"/> subclass type that defines the settings UI.</param>
|
||||
public PluginSettingsSectionBuilder SetCustomView(Type viewType)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(viewType);
|
||||
|
||||
if (!typeof(SettingsPageBase).IsAssignableFrom(viewType))
|
||||
{
|
||||
throw new ArgumentException(
|
||||
$"Custom view type must be a subclass of {nameof(SettingsPageBase)}.",
|
||||
nameof(viewType));
|
||||
}
|
||||
|
||||
_customViewType = viewType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PluginSettingsSectionBuilder AddOption(SettingsOptionDefinition option)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(option);
|
||||
@@ -142,6 +183,7 @@ public sealed class PluginSettingsSectionBuilder
|
||||
_options.ToArray(),
|
||||
DescriptionLocalizationKey,
|
||||
IconKey,
|
||||
SortOrder);
|
||||
SortOrder,
|
||||
_customViewType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace LanMountainDesktop.PluginSdk;
|
||||
@@ -10,7 +11,8 @@ public sealed class PluginSettingsSectionRegistration
|
||||
IReadOnlyList<SettingsOptionDefinition> options,
|
||||
string? descriptionLocalizationKey = null,
|
||||
string iconKey = "PuzzlePiece",
|
||||
int sortOrder = 0)
|
||||
int sortOrder = 0,
|
||||
Type? customViewType = null)
|
||||
{
|
||||
ArgumentException.ThrowIfNullOrWhiteSpace(id);
|
||||
ArgumentException.ThrowIfNullOrWhiteSpace(titleLocalizationKey);
|
||||
@@ -24,6 +26,15 @@ public sealed class PluginSettingsSectionRegistration
|
||||
IconKey = iconKey.Trim();
|
||||
SortOrder = sortOrder;
|
||||
Options = options ?? [];
|
||||
|
||||
if (customViewType is not null && !typeof(SettingsPageBase).IsAssignableFrom(customViewType))
|
||||
{
|
||||
throw new ArgumentException(
|
||||
$"Custom view type must be a subclass of {nameof(SettingsPageBase)}.",
|
||||
nameof(customViewType));
|
||||
}
|
||||
|
||||
CustomViewType = customViewType;
|
||||
}
|
||||
|
||||
public string Id { get; }
|
||||
@@ -37,4 +48,11 @@ public sealed class PluginSettingsSectionRegistration
|
||||
public int SortOrder { get; }
|
||||
|
||||
public IReadOnlyList<SettingsOptionDefinition> Options { get; }
|
||||
|
||||
/// <summary>
|
||||
/// When set, the host application will instantiate this <see cref="SettingsPageBase"/> subclass
|
||||
/// instead of generating a page from <see cref="Options"/>.
|
||||
/// This allows plugins to provide fully custom AXAML views with any Fluent Avalonia controls.
|
||||
/// </summary>
|
||||
public Type? CustomViewType { get; }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user