FuzzyPanel
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia" Version="11.0.0-preview8" />
|
||||
<PackageReference Include="PropertyChanged.SourceGenerator" Version="1.0.8">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\FileTime.App.FuzzyPanel.Abstraction\FileTime.App.FuzzyPanel.Abstraction.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
68
src/AppCommon/FileTime.App.FuzzyPanel/FuzzyPanelViewModel.cs
Normal file
68
src/AppCommon/FileTime.App.FuzzyPanel/FuzzyPanelViewModel.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
using System.ComponentModel;
|
||||
using Avalonia.Input;
|
||||
using PropertyChanged.SourceGenerator;
|
||||
|
||||
namespace FileTime.App.FuzzyPanel;
|
||||
|
||||
public abstract partial class FuzzyPanelViewModel<TItem> : IFuzzyPanelViewModel<TItem> where TItem : class
|
||||
{
|
||||
private string _searchText = String.Empty;
|
||||
|
||||
[Notify(set: Setter.Protected)] private IObservable<bool> _showWindow;
|
||||
[Notify(set: Setter.Protected)] private List<TItem> _filteredMatches;
|
||||
[Notify(set: Setter.Protected)] private TItem? _selectedItem;
|
||||
|
||||
public string SearchText
|
||||
{
|
||||
get => _searchText;
|
||||
set
|
||||
{
|
||||
if (_searchText == value) return;
|
||||
|
||||
_searchText = value;
|
||||
OnPropertyChanged(new PropertyChangedEventArgs(nameof(SearchText)));
|
||||
|
||||
UpdateFilteredMatchesInternal();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateFilteredMatchesInternal()
|
||||
{
|
||||
UpdateFilteredMatches();
|
||||
if (SelectedItem != null && FilteredMatches.Contains(SelectedItem)) return;
|
||||
|
||||
SelectedItem = FilteredMatches.Count > 0
|
||||
? FilteredMatches[0]
|
||||
: null;
|
||||
}
|
||||
|
||||
public abstract void UpdateFilteredMatches();
|
||||
|
||||
public virtual Task<bool> HandleKeyDown(KeyEventArgs keyEventArgs)
|
||||
{
|
||||
if (keyEventArgs.Key == Key.Down)
|
||||
{
|
||||
var nextItem = FilteredMatches.SkipWhile(i => i != SelectedItem).Skip(1).FirstOrDefault();
|
||||
|
||||
if (nextItem is not null)
|
||||
{
|
||||
SelectedItem = nextItem;
|
||||
}
|
||||
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
else if (keyEventArgs.Key == Key.Up)
|
||||
{
|
||||
var previousItem = FilteredMatches.TakeWhile(i => i != SelectedItem).LastOrDefault();
|
||||
|
||||
if (previousItem is not null)
|
||||
{
|
||||
SelectedItem = previousItem;
|
||||
}
|
||||
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
return Task.FromResult(false);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user