mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Implement WPF plugin settings hosting in Avalonia
- Created WpfControlHost to host WPF controls using HwndSource - Updated PluginItemViewModel to load settings via ISettingProvider - Updated PluginsSettingsPage to display settings in an expander
This commit is contained in:
parent
1209ca5194
commit
0e1af2279b
3 changed files with 120 additions and 15 deletions
|
|
@ -46,8 +46,32 @@ public partial class PluginItemViewModel : ObservableObject
|
|||
public PluginItemViewModel(PluginPair plugin)
|
||||
{
|
||||
_plugin = plugin;
|
||||
|
||||
if (plugin.Plugin is ISettingProvider settingProvider)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Create the WPF settings panel
|
||||
SettingControl = settingProvider.CreateSettingPanel();
|
||||
HasSettings = SettingControl != null;
|
||||
}
|
||||
catch (System.Exception)
|
||||
{
|
||||
// TODO: Log error using logger
|
||||
HasSettings = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
private object? _settingControl;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _hasSettings;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isExpanded;
|
||||
|
||||
public string Name => _plugin.Metadata.Name;
|
||||
public string Description => _plugin.Metadata.Description;
|
||||
public string Author => _plugin.Metadata.Author;
|
||||
|
|
|
|||
61
Flow.Launcher.Avalonia/Views/Controls/WpfControlHost.cs
Normal file
61
Flow.Launcher.Avalonia/Views/Controls/WpfControlHost.cs
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Platform;
|
||||
using System.Windows.Interop;
|
||||
using System.Windows;
|
||||
|
||||
namespace Flow.Launcher.Avalonia.Views.Controls
|
||||
{
|
||||
public class WpfControlHost : NativeControlHost
|
||||
{
|
||||
private HwndSource? _source;
|
||||
|
||||
public static readonly StyledProperty<object?> ContentProperty =
|
||||
AvaloniaProperty.Register<WpfControlHost, object?>(nameof(Content));
|
||||
|
||||
public object? Content
|
||||
{
|
||||
get => GetValue(ContentProperty);
|
||||
set => SetValue(ContentProperty, value);
|
||||
}
|
||||
|
||||
protected override IPlatformHandle CreateNativeControlCore(IPlatformHandle parent)
|
||||
{
|
||||
var parameters = new HwndSourceParameters
|
||||
{
|
||||
ParentWindow = parent.Handle,
|
||||
WindowStyle = 0x50000000, // WS_CHILD | WS_VISIBLE
|
||||
PositionX = 0,
|
||||
PositionY = 0,
|
||||
};
|
||||
|
||||
_source = new HwndSource(parameters);
|
||||
|
||||
if (Content != null)
|
||||
{
|
||||
_source.RootVisual = Content as System.Windows.Media.Visual;
|
||||
}
|
||||
|
||||
return new PlatformHandle(_source.Handle, "HwndSource");
|
||||
}
|
||||
|
||||
protected override void DestroyNativeControlCore(IPlatformHandle control)
|
||||
{
|
||||
_source?.Dispose();
|
||||
_source = null;
|
||||
base.DestroyNativeControlCore(control);
|
||||
}
|
||||
|
||||
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
|
||||
{
|
||||
base.OnPropertyChanged(change);
|
||||
|
||||
if (change.Property == ContentProperty && _source != null)
|
||||
{
|
||||
_source.RootVisual = change.NewValue as System.Windows.Media.Visual;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@
|
|||
xmlns:ui="using:FluentAvalonia.UI.Controls"
|
||||
xmlns:vm="using:Flow.Launcher.Avalonia.ViewModel.SettingPages"
|
||||
xmlns:i18n="using:Flow.Launcher.Avalonia.Resource"
|
||||
xmlns:controls="using:Flow.Launcher.Avalonia.Views.Controls"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="600"
|
||||
x:Class="Flow.Launcher.Avalonia.Views.SettingPages.PluginsSettingsPage"
|
||||
x:DataType="vm:PluginsSettingsViewModel">
|
||||
|
|
@ -23,23 +24,42 @@
|
|||
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="vm:PluginItemViewModel">
|
||||
<Grid ColumnDefinitions="Auto,*,Auto" Margin="0,5">
|
||||
<Image Grid.Column="0" Source="{Binding IconPath}" Width="32" Height="32" Margin="0,0,15,0" VerticalAlignment="Center" />
|
||||
|
||||
<StackPanel Grid.Column="1" VerticalAlignment="Center">
|
||||
<StackPanel Orientation="Horizontal" Spacing="10">
|
||||
<TextBlock Text="{Binding Name}" FontWeight="Bold" />
|
||||
<TextBlock Text="{Binding Version}" Foreground="Gray" FontSize="12" VerticalAlignment="Bottom" />
|
||||
<StackPanel Spacing="5">
|
||||
<Grid ColumnDefinitions="Auto,*,Auto" Margin="0,5">
|
||||
<Image Grid.Column="0" Source="{Binding IconPath}" Width="32" Height="32" Margin="0,0,15,0" VerticalAlignment="Center" />
|
||||
|
||||
<StackPanel Grid.Column="1" VerticalAlignment="Center">
|
||||
<StackPanel Orientation="Horizontal" Spacing="10">
|
||||
<TextBlock Text="{Binding Name}" FontWeight="Bold" />
|
||||
<TextBlock Text="{Binding Version}" Foreground="Gray" FontSize="12" VerticalAlignment="Bottom" />
|
||||
</StackPanel>
|
||||
<TextBlock Text="{Binding Description}" Foreground="Gray" FontSize="12" TextWrapping="Wrap" />
|
||||
<TextBlock Text="{Binding Author}" Foreground="LightGray" FontSize="11" />
|
||||
</StackPanel>
|
||||
<TextBlock Text="{Binding Description}" Foreground="Gray" FontSize="12" TextWrapping="Wrap" />
|
||||
<TextBlock Text="{Binding Author}" Foreground="LightGray" FontSize="11" />
|
||||
</StackPanel>
|
||||
|
||||
<ToggleSwitch Grid.Column="2"
|
||||
IsChecked="{Binding !IsDisabled}"
|
||||
VerticalAlignment="Center"
|
||||
OnContent="" OffContent="" />
|
||||
</Grid>
|
||||
<StackPanel Grid.Column="2" Orientation="Horizontal" Spacing="10" VerticalAlignment="Center">
|
||||
<ToggleButton IsChecked="{Binding IsExpanded}"
|
||||
IsVisible="{Binding HasSettings}"
|
||||
ToolTip.Tip="Settings">
|
||||
<ui:SymbolIcon Symbol="Settings" />
|
||||
</ToggleButton>
|
||||
|
||||
<ToggleSwitch IsChecked="{Binding !IsDisabled}"
|
||||
OnContent="" OffContent="" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<!-- Settings Panel -->
|
||||
<Border IsVisible="{Binding IsExpanded}"
|
||||
Background="{DynamicResource SolidBackgroundFillColorBase}"
|
||||
BorderBrush="{DynamicResource ControlElevationBorderBrush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="4"
|
||||
Padding="10"
|
||||
Margin="48,0,0,10">
|
||||
<controls:WpfControlHost Content="{Binding SettingControl}" Height="500" />
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
|
|
|
|||
Loading…
Reference in a new issue