Skip to content

Commit

Permalink
feat: 添加子菜单项预览功能
Browse files Browse the repository at this point in the history
  • Loading branch information
SlimeNull committed Dec 28, 2024
1 parent 4272633 commit 668c8d2
Show file tree
Hide file tree
Showing 8 changed files with 166 additions and 62 deletions.
8 changes: 8 additions & 0 deletions src/CurvaLauncher.Common/IQueryResultWithPreview.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System.Windows.Documents;

namespace CurvaLauncher;

public interface IQueryResultWithPreview
{
public FlowDocument GeneratePreview();
}
145 changes: 84 additions & 61 deletions src/CurvaLauncher/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -196,73 +196,96 @@
Content="{Binding ViewModel.CurrentImmediateResult}">
<ContentControl.Resources>
<DataTemplate DataType="{x:Type models_imr:MenuResult}">
<ListView Name="MenuResultBox" Margin="0 5 0 0" MinHeight="0"
Height="Auto"
MaxHeight="{Binding Source={StaticResource AppConfigProxy},Path=Data.LauncherResultViewHeight}"
BorderThickness="0"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ItemsSource="{Binding Items}" d:ItemsSource="{d:SampleData ItemCount=5}"
SelectedItem="{Binding SelectedItem,Mode=OneWayToSource}"
SelectedIndex="{Binding SelectedIndex}">
<behaviors:Interaction.Triggers>
<behaviors:EventTrigger EventName="SelectionChanged">
<behaviors:InvokeCommandAction Command="{Binding Source={StaticResource WindowProxy},Path=Data.ScrollToSelectedItemCommand}"
CommandParameter="{x:Reference Name=MenuResultBox}"/>
</behaviors:EventTrigger>
</behaviors:Interaction.Triggers>
<ListView.ItemTemplate>
<DataTemplate DataType="models:QueryResultModel">
<Border Padding="{DynamicResource QueryResultPaddingThickness}">
<Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="8"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid Margin="0 5 0 0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="{Binding PreviewPaneWidth}"/>
</Grid.ColumnDefinitions>

<Border Width="{DynamicResource QueryResultIconSize}"
Height="{DynamicResource QueryResultIconSize}"
CornerRadius="{DynamicResource QueryResultIconCornerRadius}">
<Border.Background>
<ImageBrush Stretch="Uniform"
ImageSource="{Binding Icon}"/>
</Border.Background>
</Border>
<ListView Name="MenuResultBox"
MinHeight="0"
Height="Auto"
MaxHeight="{Binding Source={StaticResource AppConfigProxy},Path=Data.LauncherResultViewHeight}"
BorderThickness="0"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ItemsSource="{Binding Items}" d:ItemsSource="{d:SampleData ItemCount=5}"
SelectedItem="{Binding SelectedItem,Mode=OneWayToSource}"
SelectedIndex="{Binding SelectedIndex}">
<behaviors:Interaction.Triggers>
<behaviors:EventTrigger EventName="SelectionChanged">
<behaviors:InvokeCommandAction Command="{Binding Source={StaticResource WindowProxy},Path=Data.ScrollToSelectedItemCommand}"
CommandParameter="{x:Reference Name=MenuResultBox}"/>
</behaviors:EventTrigger>
</behaviors:Interaction.Triggers>
<ListView.ItemTemplate>
<DataTemplate DataType="models:QueryResultModel">
<Border Padding="{DynamicResource QueryResultPaddingThickness}">
<Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="8"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>

<Grid Grid.Column="2">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Text="{Binding Title}"
FontSize="{DynamicResource QueryResultTitleTextSize}"
Foreground="{DynamicResource TextFillColorPrimaryBrush}"/>
<TextBlock Grid.Row="1"
TextTrimming="WordEllipsis"
Text="{Binding Description}"
FontSize="{DynamicResource QueryResultDescriptionTextSize}"
Foreground="{DynamicResource TextFillColorSecondaryBrush}"/>
<Border Width="{DynamicResource QueryResultIconSize}"
Height="{DynamicResource QueryResultIconSize}"
CornerRadius="{DynamicResource QueryResultIconCornerRadius}">
<Border.Background>
<ImageBrush Stretch="Uniform"
ImageSource="{Binding Icon}"/>
</Border.Background>
</Border>

<Grid Grid.Column="2">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Text="{Binding Title}"
FontSize="{DynamicResource QueryResultTitleTextSize}"
Foreground="{DynamicResource TextFillColorPrimaryBrush}"/>
<TextBlock Grid.Row="1"
TextTrimming="WordEllipsis"
Text="{Binding Description}"
FontSize="{DynamicResource QueryResultDescriptionTextSize}"
Foreground="{DynamicResource TextFillColorSecondaryBrush}"/>
</Grid>
</Grid>
</Grid>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}" BasedOn="{StaticResource {x:Type ListViewItem}}">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<EventSetter Event="PreviewMouseDown"
Handler="ResultBoxItemMouseDown"/>
</Style>
</ListView.ItemContainerStyle>
</ListView>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}" BasedOn="{StaticResource {x:Type ListViewItem}}">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<EventSetter Event="PreviewMouseDown"
Handler="ResultBoxItemMouseDown"/>
</Style>
</ListView.ItemContainerStyle>
</ListView>

<Grid Grid.Column="1">
<GridSplitter VerticalAlignment="Stretch"
HorizontalAlignment="Left"
Background="Transparent"
Width="3"/>
<Rectangle VerticalAlignment="Stretch"
HorizontalAlignment="Left"
Fill="#80777777"
Width="1"
Margin="1 0"/>
<Border Margin="3 0 0 0">
<FlowDocumentScrollViewer Document="{Binding SelectedItem.Preview}"/>
</Border>
</Grid>
</Grid>

</DataTemplate>
<DataTemplate DataType="{x:Type models_imr:DocumentResult}">
<FlowDocumentScrollViewer Document="{Binding Document}"
MinHeight="{Binding Source={StaticResource AppConfigProxy},Path=Data.LauncherResultViewHeight}">

</FlowDocumentScrollViewer>
FontFamily="Microsoft Yahei"
MinHeight="{Binding Source={StaticResource AppConfigProxy},Path=Data.LauncherResultViewHeight}"/>
</DataTemplate>
</ContentControl.Resources>
</ContentControl>
Expand Down
16 changes: 16 additions & 0 deletions src/CurvaLauncher/Models/ImmediateResults/MenuResult.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using CommunityToolkit.Mvvm.ComponentModel;

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

[ObservableProperty]
[NotifyPropertyChangedFor(nameof(PreviewPaneWidth))]
private QueryResultModel? _selectedItem;

public GridLength PreviewPaneWidth
{
get
{
if (SelectedItem is null ||
!SelectedItem.HasPreview)
{
return new GridLength(0);
}

return new GridLength(2, GridUnitType.Star);
}
}

public IReadOnlyList<QueryResultModel> Items { get; }

public MenuResult(PluginInstance pluginInstance, IReadOnlyList<IQueryResult> items)
Expand Down
File renamed without changes.
8 changes: 8 additions & 0 deletions src/CurvaLauncher/Models/QueryResultModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using CommunityToolkit.Mvvm.ComponentModel;
Expand All @@ -26,6 +27,11 @@ public QueryResultModel(PluginInstance pluginInstance, IQueryResult rawQueryResu
_rawQueryResult = rawQueryResult;
_icon = rawQueryResult.Icon;

if (rawQueryResult is IQueryResultWithPreview queryResultWithPreview)
{
Preview = queryResultWithPreview.GeneratePreview();
}

SetupFallbackIcon(() => pluginInstance.Plugin.Icon);
}

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

private void SetupFallbackIcon(Func<ImageSource> iconFactory)
{
Expand Down
13 changes: 12 additions & 1 deletion src/Plugins/CurvaLauncher.Plugins.Test/TestMenuQueryResult.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Windows.Media;
using System.Windows.Documents;
using System.Windows.Media;

namespace CurvaLauncher.Plugins.Test
{
Expand All @@ -16,6 +17,16 @@ public IEnumerable<IQueryResult> GetMenuItems()
{
yield return new TestQueryResult("Show test message box", string.Empty, 1);
yield return new TestDocumentQueryResult();
yield return new TestQueryResultWithPreview("Show test message box", string.Empty, 1, new System.Windows.Documents.FlowDocument()
{
Blocks =
{
new Paragraph(new Run("QWQ"))
{
FontSize = 22,
}
}
});
}
}
}
1 change: 1 addition & 0 deletions src/Plugins/CurvaLauncher.Plugins.Test/TestQueryResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ public async Task InvokeAsync(CancellationToken cancellationToken)
MessageBox.Show(Description, Title);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;

namespace CurvaLauncher.Plugins.Test
{
public class TestQueryResultWithPreview : IAsyncActionQueryResult, IQueryResultWithPreview
{
private readonly FlowDocument _preview;

public TestQueryResultWithPreview(string title, string description, float weight, FlowDocument preview)
{
Title = title;
Description = description;
Weight = weight;
this._preview = preview;
}

public float Weight { get; }

public string Title { get; }

public string Description { get; }

public ImageSource? Icon => null;

public FlowDocument GeneratePreview() => _preview;

public async Task InvokeAsync(CancellationToken cancellationToken)
{
await Task.Delay(2000, cancellationToken);

MessageBox.Show(Description, Title);
}
}

}

0 comments on commit 668c8d2

Please sign in to comment.