Skip to content

Commit 668c8d2

Browse files
committed
feat: 添加子菜单项预览功能
1 parent 4272633 commit 668c8d2

File tree

8 files changed

+166
-62
lines changed

8 files changed

+166
-62
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
using System.Windows.Documents;
2+
3+
namespace CurvaLauncher;
4+
5+
public interface IQueryResultWithPreview
6+
{
7+
public FlowDocument GeneratePreview();
8+
}

src/CurvaLauncher/MainWindow.xaml

+84-61
Original file line numberDiff line numberDiff line change
@@ -196,73 +196,96 @@
196196
Content="{Binding ViewModel.CurrentImmediateResult}">
197197
<ContentControl.Resources>
198198
<DataTemplate DataType="{x:Type models_imr:MenuResult}">
199-
<ListView Name="MenuResultBox" Margin="0 5 0 0" MinHeight="0"
200-
Height="Auto"
201-
MaxHeight="{Binding Source={StaticResource AppConfigProxy},Path=Data.LauncherResultViewHeight}"
202-
BorderThickness="0"
203-
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
204-
ScrollViewer.VerticalScrollBarVisibility="Auto"
205-
ItemsSource="{Binding Items}" d:ItemsSource="{d:SampleData ItemCount=5}"
206-
SelectedItem="{Binding SelectedItem,Mode=OneWayToSource}"
207-
SelectedIndex="{Binding SelectedIndex}">
208-
<behaviors:Interaction.Triggers>
209-
<behaviors:EventTrigger EventName="SelectionChanged">
210-
<behaviors:InvokeCommandAction Command="{Binding Source={StaticResource WindowProxy},Path=Data.ScrollToSelectedItemCommand}"
211-
CommandParameter="{x:Reference Name=MenuResultBox}"/>
212-
</behaviors:EventTrigger>
213-
</behaviors:Interaction.Triggers>
214-
<ListView.ItemTemplate>
215-
<DataTemplate DataType="models:QueryResultModel">
216-
<Border Padding="{DynamicResource QueryResultPaddingThickness}">
217-
<Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
218-
<Grid.ColumnDefinitions>
219-
<ColumnDefinition Width="Auto"/>
220-
<ColumnDefinition Width="8"/>
221-
<ColumnDefinition/>
222-
</Grid.ColumnDefinitions>
199+
<Grid Margin="0 5 0 0">
200+
<Grid.ColumnDefinitions>
201+
<ColumnDefinition Width="1*"/>
202+
<ColumnDefinition Width="{Binding PreviewPaneWidth}"/>
203+
</Grid.ColumnDefinitions>
223204

224-
<Border Width="{DynamicResource QueryResultIconSize}"
225-
Height="{DynamicResource QueryResultIconSize}"
226-
CornerRadius="{DynamicResource QueryResultIconCornerRadius}">
227-
<Border.Background>
228-
<ImageBrush Stretch="Uniform"
229-
ImageSource="{Binding Icon}"/>
230-
</Border.Background>
231-
</Border>
205+
<ListView Name="MenuResultBox"
206+
MinHeight="0"
207+
Height="Auto"
208+
MaxHeight="{Binding Source={StaticResource AppConfigProxy},Path=Data.LauncherResultViewHeight}"
209+
BorderThickness="0"
210+
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
211+
ScrollViewer.VerticalScrollBarVisibility="Auto"
212+
ItemsSource="{Binding Items}" d:ItemsSource="{d:SampleData ItemCount=5}"
213+
SelectedItem="{Binding SelectedItem,Mode=OneWayToSource}"
214+
SelectedIndex="{Binding SelectedIndex}">
215+
<behaviors:Interaction.Triggers>
216+
<behaviors:EventTrigger EventName="SelectionChanged">
217+
<behaviors:InvokeCommandAction Command="{Binding Source={StaticResource WindowProxy},Path=Data.ScrollToSelectedItemCommand}"
218+
CommandParameter="{x:Reference Name=MenuResultBox}"/>
219+
</behaviors:EventTrigger>
220+
</behaviors:Interaction.Triggers>
221+
<ListView.ItemTemplate>
222+
<DataTemplate DataType="models:QueryResultModel">
223+
<Border Padding="{DynamicResource QueryResultPaddingThickness}">
224+
<Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
225+
<Grid.ColumnDefinitions>
226+
<ColumnDefinition Width="Auto"/>
227+
<ColumnDefinition Width="8"/>
228+
<ColumnDefinition/>
229+
</Grid.ColumnDefinitions>
232230

233-
<Grid Grid.Column="2">
234-
<Grid.RowDefinitions>
235-
<RowDefinition/>
236-
<RowDefinition/>
237-
</Grid.RowDefinitions>
238-
<TextBlock Text="{Binding Title}"
239-
FontSize="{DynamicResource QueryResultTitleTextSize}"
240-
Foreground="{DynamicResource TextFillColorPrimaryBrush}"/>
241-
<TextBlock Grid.Row="1"
242-
TextTrimming="WordEllipsis"
243-
Text="{Binding Description}"
244-
FontSize="{DynamicResource QueryResultDescriptionTextSize}"
245-
Foreground="{DynamicResource TextFillColorSecondaryBrush}"/>
231+
<Border Width="{DynamicResource QueryResultIconSize}"
232+
Height="{DynamicResource QueryResultIconSize}"
233+
CornerRadius="{DynamicResource QueryResultIconCornerRadius}">
234+
<Border.Background>
235+
<ImageBrush Stretch="Uniform"
236+
ImageSource="{Binding Icon}"/>
237+
</Border.Background>
238+
</Border>
239+
240+
<Grid Grid.Column="2">
241+
<Grid.RowDefinitions>
242+
<RowDefinition/>
243+
<RowDefinition/>
244+
</Grid.RowDefinitions>
245+
<TextBlock Text="{Binding Title}"
246+
FontSize="{DynamicResource QueryResultTitleTextSize}"
247+
Foreground="{DynamicResource TextFillColorPrimaryBrush}"/>
248+
<TextBlock Grid.Row="1"
249+
TextTrimming="WordEllipsis"
250+
Text="{Binding Description}"
251+
FontSize="{DynamicResource QueryResultDescriptionTextSize}"
252+
Foreground="{DynamicResource TextFillColorSecondaryBrush}"/>
253+
</Grid>
246254
</Grid>
247-
</Grid>
248-
</Border>
249-
</DataTemplate>
250-
</ListView.ItemTemplate>
251-
<ListView.ItemContainerStyle>
252-
<Style TargetType="{x:Type ListViewItem}" BasedOn="{StaticResource {x:Type ListViewItem}}">
253-
<Setter Property="BorderThickness" Value="0" />
254-
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
255-
<EventSetter Event="PreviewMouseDown"
256-
Handler="ResultBoxItemMouseDown"/>
257-
</Style>
258-
</ListView.ItemContainerStyle>
259-
</ListView>
255+
</Border>
256+
</DataTemplate>
257+
</ListView.ItemTemplate>
258+
<ListView.ItemContainerStyle>
259+
<Style TargetType="{x:Type ListViewItem}" BasedOn="{StaticResource {x:Type ListViewItem}}">
260+
<Setter Property="BorderThickness" Value="0" />
261+
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
262+
<EventSetter Event="PreviewMouseDown"
263+
Handler="ResultBoxItemMouseDown"/>
264+
</Style>
265+
</ListView.ItemContainerStyle>
266+
</ListView>
267+
268+
<Grid Grid.Column="1">
269+
<GridSplitter VerticalAlignment="Stretch"
270+
HorizontalAlignment="Left"
271+
Background="Transparent"
272+
Width="3"/>
273+
<Rectangle VerticalAlignment="Stretch"
274+
HorizontalAlignment="Left"
275+
Fill="#80777777"
276+
Width="1"
277+
Margin="1 0"/>
278+
<Border Margin="3 0 0 0">
279+
<FlowDocumentScrollViewer Document="{Binding SelectedItem.Preview}"/>
280+
</Border>
281+
</Grid>
282+
</Grid>
283+
260284
</DataTemplate>
261285
<DataTemplate DataType="{x:Type models_imr:DocumentResult}">
262286
<FlowDocumentScrollViewer Document="{Binding Document}"
263-
MinHeight="{Binding Source={StaticResource AppConfigProxy},Path=Data.LauncherResultViewHeight}">
264-
265-
</FlowDocumentScrollViewer>
287+
FontFamily="Microsoft Yahei"
288+
MinHeight="{Binding Source={StaticResource AppConfigProxy},Path=Data.LauncherResultViewHeight}"/>
266289
</DataTemplate>
267290
</ContentControl.Resources>
268291
</ContentControl>

src/CurvaLauncher/Models/ImmediateResults/MenuResult.cs

+16
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Collections.Generic;
22
using System.Linq;
3+
using System.Windows;
34
using CommunityToolkit.Mvvm.ComponentModel;
45

56
namespace CurvaLauncher.Models.ImmediateResults
@@ -10,8 +11,23 @@ public partial class MenuResult : ImmediateResult
1011
private int _selectedIndex;
1112

1213
[ObservableProperty]
14+
[NotifyPropertyChangedFor(nameof(PreviewPaneWidth))]
1315
private QueryResultModel? _selectedItem;
1416

17+
public GridLength PreviewPaneWidth
18+
{
19+
get
20+
{
21+
if (SelectedItem is null ||
22+
!SelectedItem.HasPreview)
23+
{
24+
return new GridLength(0);
25+
}
26+
27+
return new GridLength(2, GridUnitType.Star);
28+
}
29+
}
30+
1531
public IReadOnlyList<QueryResultModel> Items { get; }
1632

1733
public MenuResult(PluginInstance pluginInstance, IReadOnlyList<IQueryResult> items)

src/CurvaLauncher/Models/QueryResultModel.cs

+8
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Threading;
44
using System.Threading.Tasks;
55
using System.Windows;
6+
using System.Windows.Documents;
67
using System.Windows.Media;
78
using System.Windows.Media.Imaging;
89
using CommunityToolkit.Mvvm.ComponentModel;
@@ -26,6 +27,11 @@ public QueryResultModel(PluginInstance pluginInstance, IQueryResult rawQueryResu
2627
_rawQueryResult = rawQueryResult;
2728
_icon = rawQueryResult.Icon;
2829

30+
if (rawQueryResult is IQueryResultWithPreview queryResultWithPreview)
31+
{
32+
Preview = queryResultWithPreview.GeneratePreview();
33+
}
34+
2935
SetupFallbackIcon(() => pluginInstance.Plugin.Icon);
3036
}
3137

@@ -34,7 +40,9 @@ public QueryResultModel(PluginInstance pluginInstance, IQueryResult rawQueryResu
3440
public float Weight => _pluginInstance.Weight * _rawQueryResult.Weight;
3541
public string Title => _rawQueryResult.Title;
3642
public string Description => _rawQueryResult.Description;
43+
public bool HasPreview => Preview is not null;
3744
public ImageSource? Icon => _icon;
45+
public FlowDocument? Preview { get; }
3846

3947
private void SetupFallbackIcon(Func<ImageSource> iconFactory)
4048
{

src/Plugins/CurvaLauncher.Plugins.Test/TestMenuQueryResult.cs

+12-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Windows.Media;
1+
using System.Windows.Documents;
2+
using System.Windows.Media;
23

34
namespace CurvaLauncher.Plugins.Test
45
{
@@ -16,6 +17,16 @@ public IEnumerable<IQueryResult> GetMenuItems()
1617
{
1718
yield return new TestQueryResult("Show test message box", string.Empty, 1);
1819
yield return new TestDocumentQueryResult();
20+
yield return new TestQueryResultWithPreview("Show test message box", string.Empty, 1, new System.Windows.Documents.FlowDocument()
21+
{
22+
Blocks =
23+
{
24+
new Paragraph(new Run("QWQ"))
25+
{
26+
FontSize = 22,
27+
}
28+
}
29+
});
1930
}
2031
}
2132
}

src/Plugins/CurvaLauncher.Plugins.Test/TestQueryResult.cs

+1
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,5 @@ public async Task InvokeAsync(CancellationToken cancellationToken)
2727
MessageBox.Show(Description, Title);
2828
}
2929
}
30+
3031
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
using System.Windows;
2+
using System.Windows.Documents;
3+
using System.Windows.Media;
4+
5+
namespace CurvaLauncher.Plugins.Test
6+
{
7+
public class TestQueryResultWithPreview : IAsyncActionQueryResult, IQueryResultWithPreview
8+
{
9+
private readonly FlowDocument _preview;
10+
11+
public TestQueryResultWithPreview(string title, string description, float weight, FlowDocument preview)
12+
{
13+
Title = title;
14+
Description = description;
15+
Weight = weight;
16+
this._preview = preview;
17+
}
18+
19+
public float Weight { get; }
20+
21+
public string Title { get; }
22+
23+
public string Description { get; }
24+
25+
public ImageSource? Icon => null;
26+
27+
public FlowDocument GeneratePreview() => _preview;
28+
29+
public async Task InvokeAsync(CancellationToken cancellationToken)
30+
{
31+
await Task.Delay(2000, cancellationToken);
32+
33+
MessageBox.Show(Description, Title);
34+
}
35+
}
36+
37+
}

0 commit comments

Comments
 (0)