mirror of
https://github.com/wwiinnddyy/LanMountainDesktop.git
synced 2026-08-19 15:43:23 +08:00
feat.增加了无.net10的安装包版本,实验性的修改了融合桌面设置下的组件库样式。
This commit is contained in:
@@ -10,6 +10,7 @@ namespace LanMountainDesktop.ViewModels;
|
||||
public sealed class ComponentLibraryWindowViewModel : ViewModelBase
|
||||
{
|
||||
private string _title = "Widgets";
|
||||
private ComponentLibraryItemViewModel? _selectedComponent;
|
||||
|
||||
public string Title
|
||||
{
|
||||
@@ -20,6 +21,12 @@ public sealed class ComponentLibraryWindowViewModel : ViewModelBase
|
||||
public ObservableCollection<ComponentLibraryCategoryViewModel> Categories { get; } = [];
|
||||
|
||||
public ObservableCollection<ComponentLibraryItemViewModel> Components { get; } = [];
|
||||
|
||||
public ComponentLibraryItemViewModel? SelectedComponent
|
||||
{
|
||||
get => _selectedComponent;
|
||||
set => SetProperty(ref _selectedComponent, value);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class ComponentLibraryCategoryViewModel
|
||||
@@ -51,6 +58,7 @@ public sealed class ComponentLibraryItemViewModel
|
||||
private readonly string _loadingPreviewText;
|
||||
private readonly string _previewUnavailableText;
|
||||
private string _displayName;
|
||||
private string? _description;
|
||||
private ComponentPreviewKey _previewKey;
|
||||
private ComponentPreviewImageEntry? _previewImageEntry;
|
||||
private ComponentPreviewImageState _previewState;
|
||||
@@ -61,12 +69,14 @@ public sealed class ComponentLibraryItemViewModel
|
||||
string componentId,
|
||||
string displayName,
|
||||
ComponentPreviewKey previewKey,
|
||||
string? description = null,
|
||||
string loadingPreviewText = "Loading preview...",
|
||||
string previewUnavailableText = "Preview unavailable",
|
||||
ComponentPreviewImageEntry? previewImageEntry = null)
|
||||
{
|
||||
ComponentId = componentId;
|
||||
_displayName = displayName;
|
||||
_description = description;
|
||||
_previewKey = previewKey;
|
||||
_loadingPreviewText = loadingPreviewText;
|
||||
_previewUnavailableText = previewUnavailableText;
|
||||
@@ -82,6 +92,12 @@ public sealed class ComponentLibraryItemViewModel
|
||||
set => SetProperty(ref _displayName, value);
|
||||
}
|
||||
|
||||
public string? Description
|
||||
{
|
||||
get => _description;
|
||||
set => SetProperty(ref _description, value);
|
||||
}
|
||||
|
||||
public ComponentPreviewKey PreviewKey
|
||||
{
|
||||
get => _previewKey;
|
||||
|
||||
@@ -94,6 +94,7 @@ public partial class ComponentLibraryWindow : Window
|
||||
entry.ComponentId,
|
||||
displayName,
|
||||
previewKey,
|
||||
description: null,
|
||||
_localize?.Invoke("component_library.preview.loading", "Loading preview...") ?? "Loading preview...",
|
||||
_localize?.Invoke("component_library.preview.unavailable", "Preview unavailable") ?? "Preview unavailable",
|
||||
previewEntry);
|
||||
|
||||
@@ -2,159 +2,203 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="using:LanMountainDesktop.ViewModels"
|
||||
xmlns:fi="using:FluentIcons.Avalonia"
|
||||
xmlns:converters="using:Avalonia.Data.Converters"
|
||||
x:Class="LanMountainDesktop.Views.FusedDesktopComponentLibraryControl"
|
||||
x:DataType="vm:ComponentLibraryWindowViewModel">
|
||||
|
||||
<Grid ColumnDefinitions="240,*"
|
||||
ColumnSpacing="12"
|
||||
|
||||
<UserControl.Styles>
|
||||
<!-- 分类列表项样式 -->
|
||||
<Style Selector="ListBoxItem.category-item">
|
||||
<Setter Property="Padding" Value="0"/>
|
||||
<Setter Property="Margin" Value="0,0,0,4"/>
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
</Style>
|
||||
<Style Selector="ListBoxItem.category-item:pointerover /template/ ContentPresenter#PART_ContentPresenter">
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
</Style>
|
||||
<Style Selector="ListBoxItem.category-item:selected /template/ ContentPresenter#PART_ContentPresenter">
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
</Style>
|
||||
|
||||
<!-- 分类项内容容器 - 默认状态 -->
|
||||
<Style Selector="Border.category-content">
|
||||
<Setter Property="Background" Value="{DynamicResource AdaptiveNavItemBackgroundBrush}"/>
|
||||
<Setter Property="Padding" Value="12,10"/>
|
||||
<Setter Property="CornerRadius" Value="{DynamicResource DesignCornerRadiusMd}"/>
|
||||
</Style>
|
||||
<Style Selector="ListBoxItem.category-item:selected Border.category-content">
|
||||
<Setter Property="Background" Value="{DynamicResource AdaptiveAccentBrush}"/>
|
||||
</Style>
|
||||
<Style Selector="ListBoxItem.category-item:pointerover Border.category-content">
|
||||
<Setter Property="Opacity" Value="0.9"/>
|
||||
</Style>
|
||||
|
||||
<!-- 分类项图标和文字 - 默认状态 -->
|
||||
<Style Selector="ListBoxItem.category-item fi|SymbolIcon.category-icon">
|
||||
<Setter Property="Foreground" Value="{DynamicResource AdaptiveTextPrimaryBrush}"/>
|
||||
</Style>
|
||||
<Style Selector="ListBoxItem.category-item:selected fi|SymbolIcon.category-icon">
|
||||
<Setter Property="Foreground" Value="{DynamicResource AdaptiveOnAccentBrush}"/>
|
||||
</Style>
|
||||
|
||||
<Style Selector="ListBoxItem.category-item TextBlock.category-text">
|
||||
<Setter Property="Foreground" Value="{DynamicResource AdaptiveTextPrimaryBrush}"/>
|
||||
</Style>
|
||||
<Style Selector="ListBoxItem.category-item:selected TextBlock.category-text">
|
||||
<Setter Property="Foreground" Value="{DynamicResource AdaptiveOnAccentBrush}"/>
|
||||
</Style>
|
||||
</UserControl.Styles>
|
||||
|
||||
<Grid ColumnDefinitions="280,*"
|
||||
ColumnSpacing="16"
|
||||
Margin="0">
|
||||
<!-- 分类列表 (左侧) -->
|
||||
<Border Classes="surface-translucent-panel"
|
||||
CornerRadius="{DynamicResource DesignCornerRadiusLg}"
|
||||
Padding="10">
|
||||
<Grid RowDefinitions="Auto,*">
|
||||
<TextBox x:Name="SearchBox"
|
||||
Watermark="搜索组件..."
|
||||
Margin="0,0,0,12"
|
||||
Classes="clear"
|
||||
Background="{DynamicResource AdaptiveSurfaceLowBrush}"
|
||||
CornerRadius="12"
|
||||
Padding="12,8">
|
||||
<TextBox.InnerLeftContent>
|
||||
<fi:SymbolIcon Symbol="Search" FontSize="16" Margin="10,0,0,0" Opacity="0.5" />
|
||||
</TextBox.InnerLeftContent>
|
||||
</TextBox>
|
||||
|
||||
<ListBox x:Name="CategoryListBox"
|
||||
Grid.Row="1"
|
||||
Background="Transparent"
|
||||
BorderThickness="0"
|
||||
SelectionChanged="OnCategorySelectionChanged"
|
||||
ItemsSource="{Binding Categories}">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="vm:ComponentLibraryCategoryViewModel">
|
||||
<Border Padding="10"
|
||||
Margin="0,0,0,6"
|
||||
CornerRadius="{DynamicResource DesignCornerRadiusSm}"
|
||||
Background="{DynamicResource AdaptiveNavItemBackgroundBrush}">
|
||||
<Grid ColumnDefinitions="Auto,*"
|
||||
ColumnSpacing="8">
|
||||
<fi:SymbolIcon Symbol="{Binding Icon}"
|
||||
IconVariant="Regular"
|
||||
FontSize="16" />
|
||||
<TextBlock Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
FontWeight="SemiBold"
|
||||
Foreground="{DynamicResource AdaptiveTextPrimaryBrush}"
|
||||
Text="{Binding Title}" />
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
</Grid>
|
||||
Padding="12">
|
||||
<ListBox x:Name="CategoryListBox"
|
||||
Background="Transparent"
|
||||
BorderThickness="0"
|
||||
SelectionChanged="OnCategorySelectionChanged"
|
||||
ItemsSource="{Binding Categories}">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="vm:ComponentLibraryCategoryViewModel">
|
||||
<Border Classes="category-content">
|
||||
<Grid ColumnDefinitions="Auto,*"
|
||||
ColumnSpacing="12">
|
||||
<fi:SymbolIcon Symbol="{Binding Icon}"
|
||||
IconVariant="Regular"
|
||||
FontSize="20"
|
||||
Classes="category-icon"/>
|
||||
<TextBlock Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="14"
|
||||
FontWeight="SemiBold"
|
||||
Classes="category-text"
|
||||
Text="{Binding Title}"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
</Border>
|
||||
|
||||
<!-- 组件网格 (右侧) -->
|
||||
<!-- 组件预览区 (右侧) -->
|
||||
<Border Grid.Column="1"
|
||||
Classes="surface-translucent-strong"
|
||||
CornerRadius="{DynamicResource DesignCornerRadiusLg}"
|
||||
Padding="10">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto"
|
||||
HorizontalScrollBarVisibility="Disabled">
|
||||
<ItemsControl x:Name="ComponentItemsControl"
|
||||
ItemsSource="{Binding Components}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<WrapPanel Orientation="Horizontal" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
Padding="24">
|
||||
<Panel>
|
||||
<!-- 有选中组件时的显示 -->
|
||||
<Grid RowDefinitions="Auto,*,Auto"
|
||||
IsVisible="{Binding SelectedComponent, Converter={x:Static converters:ObjectConverters.IsNotNull}}">
|
||||
<!-- 组件标题 -->
|
||||
<TextBlock Grid.Row="0"
|
||||
FontSize="28"
|
||||
FontWeight="Bold"
|
||||
Foreground="{DynamicResource AdaptiveTextPrimaryBrush}"
|
||||
Text="{Binding SelectedComponent.DisplayName}"
|
||||
Margin="0,0,0,20"/>
|
||||
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate x:DataType="vm:ComponentLibraryItemViewModel">
|
||||
<Border Width="240"
|
||||
Height="220"
|
||||
Margin="6"
|
||||
CornerRadius="{DynamicResource DesignCornerRadiusComponent}"
|
||||
Padding="10"
|
||||
Background="{DynamicResource AdaptiveSurfaceRaisedBrush}"
|
||||
BorderBrush="{DynamicResource AdaptiveButtonBorderBrush}"
|
||||
BorderThickness="1">
|
||||
<Grid RowDefinitions="*,Auto,Auto"
|
||||
RowSpacing="8">
|
||||
<!-- 预览区域 -->
|
||||
<Border CornerRadius="{DynamicResource DesignCornerRadiusSm}"
|
||||
Background="{DynamicResource AdaptiveGlassPanelBackgroundBrush}"
|
||||
BorderThickness="1"
|
||||
BorderBrush="{DynamicResource AdaptiveGlassPanelBorderBrush}"
|
||||
Padding="8">
|
||||
<Grid>
|
||||
<Image Source="{Binding PreviewBitmap}"
|
||||
Stretch="Uniform"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
RenderOptions.BitmapInterpolationMode="HighQuality"
|
||||
IsVisible="{Binding IsPreviewReady}" />
|
||||
<!-- 预览区域 -->
|
||||
<Border Grid.Row="1"
|
||||
CornerRadius="{DynamicResource DesignCornerRadiusComponent}"
|
||||
Background="{DynamicResource AdaptiveSurfaceBaseBrush}"
|
||||
BorderBrush="{DynamicResource AdaptiveGlassPanelBorderBrush}"
|
||||
BorderThickness="1"
|
||||
Padding="20"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center">
|
||||
<Grid Width="400"
|
||||
Height="300">
|
||||
<!-- 预览图片 -->
|
||||
<Image Source="{Binding SelectedComponent.PreviewBitmap}"
|
||||
Stretch="Uniform"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
RenderOptions.BitmapInterpolationMode="HighQuality"
|
||||
IsVisible="{Binding SelectedComponent.IsPreviewReady}"/>
|
||||
|
||||
<!-- 加载中状态 -->
|
||||
<Border IsVisible="{Binding IsPreviewPending}"
|
||||
Background="{DynamicResource AdaptiveSurfaceBaseBrush}">
|
||||
<StackPanel HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Spacing="8">
|
||||
<ProgressBar Width="96"
|
||||
IsIndeterminate="True" />
|
||||
<TextBlock HorizontalAlignment="Center"
|
||||
TextAlignment="Center"
|
||||
FontSize="12"
|
||||
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
|
||||
Text="{Binding PreviewStatusText}" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
<!-- 加载中状态 -->
|
||||
<Border IsVisible="{Binding SelectedComponent.IsPreviewPending}"
|
||||
Background="{DynamicResource AdaptiveSurfaceBaseBrush}">
|
||||
<StackPanel HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Spacing="12">
|
||||
<ProgressBar Width="120"
|
||||
IsIndeterminate="True"/>
|
||||
<TextBlock HorizontalAlignment="Center"
|
||||
TextAlignment="Center"
|
||||
FontSize="14"
|
||||
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
|
||||
Text="{Binding SelectedComponent.PreviewStatusText}"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- 失败状态 -->
|
||||
<Border IsVisible="{Binding IsPreviewFailed}"
|
||||
Background="{DynamicResource AdaptiveSurfaceBaseBrush}">
|
||||
<StackPanel HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Spacing="8">
|
||||
<TextBlock HorizontalAlignment="Center"
|
||||
TextAlignment="Center"
|
||||
FontWeight="SemiBold"
|
||||
Foreground="{DynamicResource AdaptiveTextPrimaryBrush}"
|
||||
Text="{Binding PreviewStatusText}" />
|
||||
<TextBlock HorizontalAlignment="Center"
|
||||
TextAlignment="Center"
|
||||
FontSize="12"
|
||||
TextWrapping="Wrap"
|
||||
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
|
||||
Text="{Binding PreviewErrorMessage}" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- 组件名称 -->
|
||||
<TextBlock Grid.Row="1"
|
||||
HorizontalAlignment="Center"
|
||||
<!-- 失败状态 -->
|
||||
<Border IsVisible="{Binding SelectedComponent.IsPreviewFailed}"
|
||||
Background="{DynamicResource AdaptiveSurfaceBaseBrush}">
|
||||
<StackPanel HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Spacing="8">
|
||||
<fi:SymbolIcon Symbol="ImageOff"
|
||||
FontSize="48"
|
||||
Opacity="0.5"
|
||||
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"/>
|
||||
<TextBlock HorizontalAlignment="Center"
|
||||
TextAlignment="Center"
|
||||
FontWeight="SemiBold"
|
||||
Foreground="{DynamicResource AdaptiveTextPrimaryBrush}"
|
||||
Text="{Binding DisplayName}" />
|
||||
|
||||
<!-- 添加按钮 -->
|
||||
<Button Grid.Row="2"
|
||||
HorizontalAlignment="Center"
|
||||
Padding="12,6"
|
||||
Tag="{Binding ComponentId}"
|
||||
Click="OnAddComponentClick">
|
||||
<TextBlock Text="添加到桌面" />
|
||||
</Button>
|
||||
</Grid>
|
||||
Text="{Binding SelectedComponent.PreviewStatusText}"/>
|
||||
<TextBlock HorizontalAlignment="Center"
|
||||
TextAlignment="Center"
|
||||
FontSize="12"
|
||||
TextWrapping="Wrap"
|
||||
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
|
||||
Text="{Binding SelectedComponent.PreviewErrorMessage}"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- 底部操作区 -->
|
||||
<Grid Grid.Row="2"
|
||||
ColumnDefinitions="*,Auto"
|
||||
Margin="0,24,0,0">
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="14"
|
||||
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
|
||||
Text="{Binding SelectedComponent.ComponentId, StringFormat='组件 ID: {0}'}"/>
|
||||
<Button Grid.Column="1"
|
||||
Classes="accent"
|
||||
Padding="20,12"
|
||||
Tag="{Binding SelectedComponent.ComponentId}"
|
||||
Click="OnAddComponentClick">
|
||||
<StackPanel Orientation="Horizontal" Spacing="8">
|
||||
<fi:SymbolIcon Symbol="Add" FontSize="16"/>
|
||||
<TextBlock Text="添加到桌面" FontWeight="SemiBold"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<Grid IsVisible="{Binding SelectedComponent, Converter={x:Static converters:ObjectConverters.IsNull}}"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center">
|
||||
<StackPanel Spacing="16" HorizontalAlignment="Center">
|
||||
<fi:SymbolIcon Symbol="Apps"
|
||||
FontSize="64"
|
||||
Opacity="0.3"
|
||||
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"/>
|
||||
<TextBlock HorizontalAlignment="Center"
|
||||
FontSize="16"
|
||||
Foreground="{DynamicResource AdaptiveTextSecondaryBrush}"
|
||||
Text="请从左侧选择一个组件"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Panel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
@@ -39,7 +39,9 @@ public partial class FusedDesktopComponentLibraryControl : UserControl
|
||||
|
||||
LoadRegistry();
|
||||
LoadCategories();
|
||||
SearchBox.KeyUp += (s, e) => FilterComponents();
|
||||
|
||||
// 为 ListBoxItem 添加 category-item 样式类
|
||||
CategoryListBox.ContainerPrepared += OnCategoryListBoxContainerPrepared;
|
||||
|
||||
// 默认选择第一个分类
|
||||
if (_viewModel.Categories.Count > 0)
|
||||
@@ -48,6 +50,14 @@ public partial class FusedDesktopComponentLibraryControl : UserControl
|
||||
}
|
||||
}
|
||||
|
||||
private void OnCategoryListBoxContainerPrepared(object? sender, ContainerPreparedEventArgs e)
|
||||
{
|
||||
if (e.Container is ListBoxItem listBoxItem)
|
||||
{
|
||||
listBoxItem.Classes.Add("category-item");
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadRegistry()
|
||||
{
|
||||
var pluginRuntimeService = (Application.Current as App)?.PluginRuntimeService;
|
||||
@@ -65,7 +75,6 @@ public partial class FusedDesktopComponentLibraryControl : UserControl
|
||||
private void LoadCategories()
|
||||
{
|
||||
_viewModel.Categories.Clear();
|
||||
_viewModel.Components.Clear();
|
||||
|
||||
// 添加"全部组件"分类
|
||||
_viewModel.Categories.Add(new ComponentLibraryCategoryViewModel(
|
||||
@@ -130,10 +139,11 @@ public partial class FusedDesktopComponentLibraryControl : UserControl
|
||||
definition.Id,
|
||||
definition.DisplayName,
|
||||
previewKey,
|
||||
description: null,
|
||||
"正在加载预览...",
|
||||
"预览不可用",
|
||||
previewEntry);
|
||||
|
||||
|
||||
if (mainWindow is not null && (previewEntry is null || previewEntry.State == ComponentPreviewImageState.Pending))
|
||||
{
|
||||
mainWindow.RequestDetachedLibraryPreview(previewKey);
|
||||
@@ -158,25 +168,49 @@ public partial class FusedDesktopComponentLibraryControl : UserControl
|
||||
|
||||
private void OnCategorySelectionChanged(object? sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
FilterComponents();
|
||||
UpdateSelectedComponent();
|
||||
}
|
||||
|
||||
private void FilterComponents()
|
||||
private void UpdateSelectedComponent()
|
||||
{
|
||||
var selectedCategory = (CategoryListBox.SelectedItem as ComponentLibraryCategoryViewModel)?.Id;
|
||||
var searchText = SearchBox.Text?.ToLower() ?? "";
|
||||
|
||||
var filtered = _allDefinitions.Where(d =>
|
||||
var selectedCategory = CategoryListBox.SelectedItem as ComponentLibraryCategoryViewModel;
|
||||
if (selectedCategory is null)
|
||||
{
|
||||
var matchesCategory = selectedCategory == "all" || string.Equals(d.Category, selectedCategory, StringComparison.OrdinalIgnoreCase);
|
||||
var matchesSearch = string.IsNullOrEmpty(searchText) || d.DisplayName.ToLower().Contains(searchText) || d.Id.ToLower().Contains(searchText);
|
||||
return matchesCategory && matchesSearch;
|
||||
});
|
||||
_viewModel.SelectedComponent = null;
|
||||
return;
|
||||
}
|
||||
|
||||
_viewModel.Components.Clear();
|
||||
foreach (var def in filtered)
|
||||
// 获取该分类下的组件列表
|
||||
IEnumerable<DesktopComponentDefinition> filtered;
|
||||
if (selectedCategory.Id == "all")
|
||||
{
|
||||
_viewModel.Components.Add(CreateComponentItem(def));
|
||||
filtered = _allDefinitions.OrderBy(d => d.DisplayName);
|
||||
}
|
||||
else
|
||||
{
|
||||
filtered = _allDefinitions
|
||||
.Where(d => string.Equals(d.Category, selectedCategory.Id, StringComparison.OrdinalIgnoreCase))
|
||||
.OrderBy(d => d.DisplayName);
|
||||
}
|
||||
|
||||
// 选择该分类下的第一个组件作为默认选中
|
||||
var firstComponent = filtered.FirstOrDefault();
|
||||
if (firstComponent is not null)
|
||||
{
|
||||
// 查找或创建对应的 ViewModel
|
||||
var existingComponent = selectedCategory.Components.FirstOrDefault(c => c.ComponentId == firstComponent.Id);
|
||||
if (existingComponent is not null)
|
||||
{
|
||||
_viewModel.SelectedComponent = existingComponent;
|
||||
}
|
||||
else
|
||||
{
|
||||
_viewModel.SelectedComponent = CreateComponentItem(firstComponent);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_viewModel.SelectedComponent = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,21 +12,21 @@
|
||||
ExtendClientAreaTitleBarHeightHint="-1"
|
||||
Background="Transparent"
|
||||
TransparencyLevelHint="Mica"
|
||||
Title="融合桌面组件库">
|
||||
|
||||
Title="添加小组件">
|
||||
|
||||
<Panel>
|
||||
<!-- 背景磨砂效果 -->
|
||||
<Border Background="{DynamicResource AdaptiveSurfaceLowBrush}"
|
||||
Opacity="0.85" />
|
||||
|
||||
<Grid RowDefinitions="Auto,*">
|
||||
|
||||
<Grid RowDefinitions="Auto,*,Auto">
|
||||
<!-- 自定义标题栏 -->
|
||||
<Border Background="Transparent"
|
||||
IsHitTestVisible="True"
|
||||
Padding="20,16">
|
||||
<Grid ColumnDefinitions="*,Auto">
|
||||
<StackPanel Spacing="6" VerticalAlignment="Center">
|
||||
<TextBlock Text="融合桌面组件库"
|
||||
<TextBlock Text="添加小组件"
|
||||
FontWeight="SemiBold"
|
||||
FontSize="20"
|
||||
Foreground="{DynamicResource AdaptiveTextPrimaryBrush}" />
|
||||
@@ -35,23 +35,35 @@
|
||||
FontSize="13"
|
||||
Foreground="{DynamicResource AdaptiveTextPrimaryBrush}" />
|
||||
</StackPanel>
|
||||
|
||||
|
||||
<Button Grid.Column="1"
|
||||
Classes="accent"
|
||||
Width="36" Height="36"
|
||||
Padding="0"
|
||||
CornerRadius="18"
|
||||
CornerRadius="{DynamicResource DesignCornerRadiusSm}"
|
||||
BorderThickness="0"
|
||||
Background="{DynamicResource AdaptiveButtonHoverBackgroundBrush}"
|
||||
Click="OnCloseClick">
|
||||
<fi:SymbolIcon Symbol="Dismiss" FontSize="18" />
|
||||
</Button>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
|
||||
<!-- 组件库控件 -->
|
||||
<controls:FusedDesktopComponentLibraryControl x:Name="LibraryControl"
|
||||
Grid.Row="1" />
|
||||
|
||||
<!-- 底部查找更多组件链接 -->
|
||||
<Border Grid.Row="2"
|
||||
Background="Transparent"
|
||||
Padding="20,12">
|
||||
<Button Classes="hyperlink"
|
||||
HorizontalAlignment="Center"
|
||||
Click="OnFindMoreComponentsClick">
|
||||
<StackPanel Orientation="Horizontal" Spacing="4">
|
||||
<fi:SymbolIcon Symbol="Globe" FontSize="14" />
|
||||
<TextBlock Text="查找更多组件" />
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Panel>
|
||||
</Window>
|
||||
|
||||
@@ -102,6 +102,26 @@ public partial class FusedDesktopComponentLibraryWindow : Window
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找更多组件链接点击处理 - 打开设置窗口的插件目录页面
|
||||
/// </summary>
|
||||
private void OnFindMoreComponentsClick(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
// 关闭当前窗口
|
||||
Close();
|
||||
|
||||
// 打开设置窗口并导航到插件目录页面
|
||||
if (Application.Current is App app && app.SettingsWindowService is { } settingsWindowService)
|
||||
{
|
||||
var mainWindow = (Application.Current?.ApplicationLifetime as IClassicDesktopStyleApplicationLifetime)?.MainWindow as MainWindow;
|
||||
var request = new SettingsWindowOpenRequest(
|
||||
Source: "FusedDesktopComponentLibrary",
|
||||
Owner: mainWindow,
|
||||
PageId: "plugin-catalog");
|
||||
settingsWindowService.Open(request);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnClosed(EventArgs e)
|
||||
{
|
||||
|
||||
@@ -20,6 +20,14 @@
|
||||
#define MyAppArch "x64"
|
||||
#endif
|
||||
|
||||
#ifndef MyAppSuffix
|
||||
#define MyAppSuffix ""
|
||||
#endif
|
||||
|
||||
#ifndef IsSelfContained
|
||||
#define IsSelfContained "true"
|
||||
#endif
|
||||
|
||||
[Setup]
|
||||
AppId={#MyAppId}
|
||||
AppName={#MyAppName}
|
||||
@@ -34,7 +42,7 @@ LanguageDetectionMethod=uilanguage
|
||||
DefaultGroupName={cm:AppShortcutName}
|
||||
UninstallDisplayIcon={app}\{#MyAppExeName}
|
||||
OutputDir={#MyOutputDir}
|
||||
OutputBaseFilename={#MyAppName}-Setup-{#MyAppVersion}-{#MyAppArch}
|
||||
OutputBaseFilename={#MyAppName}-Setup-{#MyAppVersion}-{#MyAppArch}{#MyAppSuffix}
|
||||
Compression=lzma2/ultra64
|
||||
SolidCompression=yes
|
||||
WizardStyle=modern
|
||||
@@ -93,7 +101,17 @@ chinesesimplified.UpgradeCleanupMissingUninstaller=安装程序发现了现有
|
||||
english.UpgradeCleanupFailedPrefix=Setup could not remove the existing installation automatically. Error code:
|
||||
chinesesimplified.UpgradeCleanupFailedPrefix=安装程序无法自动移除现有安装。错误代码:
|
||||
english.UpgradeCleanupFailedSuffix=Please close LanMountainDesktop, uninstall the current version manually, and then run this installer again.
|
||||
chinesesimplified.UpgradeCleanupFailedSuffix=请关闭 LanMountainDesktop,手动卸载当前版本,然后重新运行此安装程序。
|
||||
chinesesimplified.UpgradeCleanupFailedSuffix=请关闭 LanMountain Desktop,手动卸载当前版本,然后重新运行此安装程序。
|
||||
english.DotNetRuntimeMissingTitle=.NET Desktop Runtime Required
|
||||
chinesesimplified.DotNetRuntimeMissingTitle=需要 .NET Desktop Runtime
|
||||
english.DotNetRuntimeMissingMessage=This application requires .NET 10.0 Desktop Runtime to run.
|
||||
chinesesimplified.DotNetRuntimeMissingMessage=此应用程序需要 .NET 10.0 Desktop Runtime 才能运行。
|
||||
english.DotNetRuntimeMissingAction=Click "Yes" to open the official download page. Install it first, then run this installer again.
|
||||
chinesesimplified.DotNetRuntimeMissingAction=单击"是"打开官方下载页面。请先完成安装,然后重新运行此安装程序。
|
||||
english.DotNetRuntimeOpenFailedMessage=Unable to open the download page automatically.
|
||||
chinesesimplified.DotNetRuntimeOpenFailedMessage=无法自动打开下载页面。
|
||||
english.DotNetRuntimeOpenFailedAction=Please open this URL manually:
|
||||
chinesesimplified.DotNetRuntimeOpenFailedAction=请手动打开以下链接:
|
||||
|
||||
[Tasks]
|
||||
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"
|
||||
@@ -127,6 +145,7 @@ const
|
||||
UninstallRegSubkey = 'Software\Microsoft\Windows\CurrentVersion\Uninstall\{#MyAppRegistryId}_is1';
|
||||
WebView2RuntimeKeyPath = 'SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}';
|
||||
WebView2RuntimeDownloadUrl = 'https://go.microsoft.com/fwlink/p/?LinkId=2124703';
|
||||
DotNetRuntimeDownloadUrl = 'https://dotnet.microsoft.com/download/dotnet/10.0';
|
||||
UpgradeChoiceInPlace = 0;
|
||||
UpgradeChoiceRelocate = 1;
|
||||
|
||||
@@ -435,10 +454,58 @@ begin
|
||||
RegQueryStringValue(HKCU32, WebView2RuntimeKeyPath, 'pv', VersionValue);
|
||||
end;
|
||||
|
||||
function IsDotNetDesktopRuntimeInstalled(): Boolean;
|
||||
var
|
||||
RuntimePath: String;
|
||||
begin
|
||||
Result := False;
|
||||
|
||||
RuntimePath := ExpandConstant('{commonpf64}\dotnet\shared\Microsoft.WindowsDesktop.App');
|
||||
if DirExists(RuntimePath) then
|
||||
begin
|
||||
Result := True;
|
||||
exit;
|
||||
end;
|
||||
|
||||
RuntimePath := ExpandConstant('{commonpf}\dotnet\shared\Microsoft.WindowsDesktop.App');
|
||||
if DirExists(RuntimePath) then
|
||||
begin
|
||||
Result := True;
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
function InitializeSetup(): Boolean;
|
||||
var
|
||||
ErrorCode: Integer;
|
||||
IsSelfContainedBuild: Boolean;
|
||||
begin
|
||||
IsSelfContainedBuild := ('{#IsSelfContained}' = 'true');
|
||||
|
||||
if not IsSelfContainedBuild then
|
||||
begin
|
||||
if not IsDotNetDesktopRuntimeInstalled() then
|
||||
begin
|
||||
if MsgBox(
|
||||
CustomMessage('DotNetRuntimeMissingMessage') + #13#10#13#10 +
|
||||
CustomMessage('DotNetRuntimeMissingAction'),
|
||||
mbConfirmation,
|
||||
MB_YESNO) = IDYES then
|
||||
begin
|
||||
if not ShellExec('open', DotNetRuntimeDownloadUrl, '', '', SW_SHOWNORMAL, ewNoWait, ErrorCode) then
|
||||
begin
|
||||
MsgBox(
|
||||
CustomMessage('DotNetRuntimeOpenFailedMessage') + #13#10 +
|
||||
CustomMessage('DotNetRuntimeOpenFailedAction') + #13#10 + DotNetRuntimeDownloadUrl,
|
||||
mbError,
|
||||
MB_OK);
|
||||
end;
|
||||
end;
|
||||
Result := False;
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
if IsWebView2RuntimeInstalled() then
|
||||
begin
|
||||
Result := True;
|
||||
|
||||
Reference in New Issue
Block a user