using System.Collections.ObjectModel; using System.ComponentModel; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Input; using CommunityToolkit.Mvvm.Input; using MpvNet.Windows.UI; using MpvNet.Windows.WinForms; namespace MpvNet.Windows.WPF.Controls; public partial class CommandPaletteControl : UserControl { public ICollectionView CollectionView { get; set; } public CollectionViewSource CollectionViewSource { get; } public ObservableCollection Items { get; } = new ObservableCollection(); public CommandPaletteControl() { InitializeComponent(); DataContext = this; CollectionViewSource = new CollectionViewSource() { Source = Items }; CollectionView = CollectionViewSource.View; CollectionView.Filter = new Predicate(item => Filter((CommandPaletteItem)item)); MainListView.ItemsSource = CollectionView; SearchControl.SearchTextBox.PreviewKeyDown += SearchTextBox_PreviewKeyDown; SearchControl.SearchTextBox.TextChanged += SearchTextBox_TextChanged; SearchControl.HideClearButton = true; if (Environment.OSVersion.Version < new Version(10, 0)) MainBorder.CornerRadius = new CornerRadius(0); } void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e) { CollectionView.Refresh(); SelectFirst(); } void SearchTextBox_PreviewKeyDown(object sender, KeyEventArgs e) { switch (e.Key) { case Key.Up: { int index = MainListView.SelectedIndex; index -= 1; if (index < 0) index = 0; MainListView.SelectedIndex = index; MainListView.ScrollIntoView(MainListView.SelectedItem); } break; case Key.Down: { int index = MainListView.SelectedIndex; if (++index > MainListView.Items.Count - 1) index = MainListView.Items.Count - 1; MainListView.SelectedIndex = index; MainListView.ScrollIntoView(MainListView.SelectedItem); } break; } } void MainListView_SizeChanged(object sender, SizeChangedEventArgs e) => AdjustHeight(); void MainListView_MouseUp(object sender, MouseButtonEventArgs e) => ExecuteInternal(); [RelayCommand] void Escape(object param) => MainForm.Instance?.HideCommandPalette(); [RelayCommand] void Execute() => ExecuteInternal(); void OnLoaded(object sender, RoutedEventArgs e) => Keyboard.Focus(SearchControl.SearchTextBox); public Theme Theme => Theme.Current!; bool Filter(CommandPaletteItem item) { string filter = SearchControl.SearchTextBox.Text.ToLower(); if (item.Binding != null) { // TODO: CommandItem.Alias //if (item.CommandItem.Alias.ContainsEx(filter)) // return true; if (filter.Length == 1) return item.Binding.Input.ToLower() .Replace("ctrl+", "") .Replace("shift+", "") .Replace("alt+", "") == filter.ToLower(); if (item.Binding.Command.ToLower().Contains(filter)) return true; } if (filter == "" || item.Text.ToLower().Contains(filter) || item.SecondaryText.ToLower().Contains(filter)) return true; return false; } public void SelectFirst() { if (MainListView.Items.Count > 0) { MainListView.SelectedIndex = 0; MainListView.ScrollIntoView(MainListView.SelectedItem); } } void ExecuteInternal() { if (MainListView.SelectedItem != null) { CommandPaletteItem? item = MainListView.SelectedItem as CommandPaletteItem; MainForm.Instance?.HideCommandPalette(); item?.Action?.Invoke(); //MainForm.Instance.Voodoo(); //TODO: Voodoo } } public void SetItems(IEnumerable items) { Items.Clear(); foreach (var i in items) Items.Add(i); } public void AdjustHeight() { double actualHeight = SearchControl.ActualHeight + MainListView.ActualHeight + 5 + 16; int dpi = MainForm.GetDpi(MainForm.Instance!.Handle); MainForm.Instance.CommandPaletteHost.Height = (int)(actualHeight / 96.0 * dpi); } }