Merge pull request #43 from zadjii-msft/dev/crutkas/restOfCleanup

Whole lotta cleanup, calling it a night
This commit is contained in:
Clint Rutkas
2024-09-06 07:01:41 -07:00
committed by GitHub
29 changed files with 225 additions and 318 deletions

View File

@@ -2,35 +2,16 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Microsoft.Terminal.UI;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Navigation;
using Microsoft.CmdPal.Extensions;
using Windows.ApplicationModel.AppExtensions;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Microsoft.UI.Xaml.Controls;
namespace DeveloperCommandPalette;
public sealed class ActionViewModel(ICommand model)
public sealed class ActionViewModel(ICommand cmd)
{
public ICommand Command => model;
public ICommand Command => cmd;
internal readonly string Name = model.Name;
internal readonly string Icon = model.Icon.Icon;
internal bool CanInvoke => cmd is IInvokableCommand;
internal bool CanInvoke => model is IInvokableCommand;
internal IconElement IcoElement => Microsoft.Terminal.UI.IconPathConverter.IconMUX(Icon);
internal IconElement IcoElement => Microsoft.Terminal.UI.IconPathConverter.IconMUX(Command.Icon.Icon);
}

View File

@@ -8,7 +8,12 @@ namespace WindowsCommandPalette.BuiltinCommands.AllApps;
public sealed class AppCache
{
internal IList<Win32Program> Win32s = Win32Program.All();
internal IList<UWPApplication> UWPs = UWP.All();
private readonly IList<Win32Program> _win32s = Win32Program.All();
private readonly IList<UWPApplication> _uwps = UWP.All();
public IList<Win32Program> Win32s => _win32s;
public IList<UWPApplication> UWPs => _uwps;
public static readonly Lazy<AppCache> Instance = new(() => new());
}

View File

@@ -13,17 +13,28 @@ internal sealed class AppListItem : ListItem
public AppListItem(AppItem app)
: base(new AppAction(app))
{
this._app = app;
this.Title = app.Name;
this.Subtitle = app.Subtitle;
this.Details = new Details() { Title = this.Title, HeroImage = this.Command.Icon, Body = "### App" };
this.Tags = [new Tag() { Text = "App" }];
_app = app;
Title = app.Name;
Subtitle = app.Subtitle;
Tags = [new Tag() { Text = "App" }];
Details = new Details()
{
Title = this.Title,
HeroImage = Command?.Icon ?? new(string.Empty),
Body = "### App",
};
if (string.IsNullOrEmpty(app.UserModelId))
{
// Win32 exe or other non UWP app
MoreCommands = [
new CommandContextItem(new OpenPathAction(app.DirPath) { Name = "Open location", Icon = new("\ue838") })
new CommandContextItem(
new OpenPathAction(app.DirPath)
{
Name = "Open location",
Icon = new("\ue838"),
})
];
}
else

View File

@@ -2,31 +2,15 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Microsoft.Terminal.UI;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Navigation;
using Microsoft.CmdPal.Extensions;
using Windows.ApplicationModel.AppExtensions;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Microsoft.UI.Xaml.Controls;
namespace DeveloperCommandPalette;
public sealed class ContextItemViewModel : INotifyPropertyChanged
{
internal ICommand Command;
public ICommand Command { get; set; }
internal string Name => Command.Name;
@@ -38,9 +22,9 @@ public sealed class ContextItemViewModel : INotifyPropertyChanged
internal IconElement IcoElement => Microsoft.Terminal.UI.IconPathConverter.IconMUX(Icon.Icon);
public ContextItemViewModel(ICommand action)
public ContextItemViewModel(ICommand cmd)
{
this.Command = action;
this.Command = cmd;
this.Command.PropChanged += Action_PropertyChanged;
}

View File

@@ -6,10 +6,10 @@ using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using CmdPal.Models;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml;
using Microsoft.CmdPal.Extensions;
using Microsoft.CmdPal.Extensions.Helpers;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml;
using WindowsCommandPalette.Views;
namespace DeveloperCommandPalette;
@@ -29,7 +29,7 @@ public sealed class FilteredListSection : ISection, INotifyCollectionChanged
public ObservableCollection<MainListItem> TopLevelItems { get; set; }
// Apps, from the apps built in command.
private IEnumerable<IListItem> AllApps => _mainViewModel.apps.GetItems().First().Items;
private IEnumerable<IListItem> AllApps => _mainViewModel.Apps.GetItems().First().Items;
// Results from the last searched text
private IEnumerable<IListItem>? lastSearchResults;

View File

@@ -5,9 +5,9 @@
using System.ComponentModel;
using System.Runtime.InteropServices;
using CmdPal.Models;
using Microsoft.CmdPal.Extensions;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml.Controls;
using Microsoft.CmdPal.Extensions;
using WindowsCommandPalette.Views;
namespace DeveloperCommandPalette;

View File

@@ -4,49 +4,50 @@
using Microsoft.CmdPal.Extensions;
using Microsoft.CmdPal.Extensions.Helpers;
using Windows.Foundation;
namespace DeveloperCommandPalette;
public sealed class MainListItem : ListItem
{
private readonly IListItem _listItem;
public IListItem Item => _listItem;
public IListItem Item { get; set; }
internal MainListItem(IListItem listItem)
: base(listItem.Command)
{
_listItem = listItem;
Item = listItem;
Title = _listItem.Title ?? _listItem.Command.Name;
Subtitle = _listItem.Subtitle;
MoreCommands = _listItem.MoreCommands;
FallbackHandler = _listItem.FallbackHandler;
Tags = _listItem.Tags;
Title = Item.Title ?? Item.Command.Name;
Subtitle = Item.Subtitle;
MoreCommands = Item.MoreCommands;
FallbackHandler = Item.FallbackHandler;
Tags = Item.Tags;
Command.PropChanged += Action_PropertyChanged;
_listItem.PropChanged += Action_PropertyChanged;
if (Command != null)
{
Command.PropChanged += Action_PropertyChanged;
}
Item.PropChanged += Action_PropertyChanged;
}
private void Action_PropertyChanged(object sender, Microsoft.CmdPal.Extensions.PropChangedEventArgs args)
private void Action_PropertyChanged(object sender, PropChangedEventArgs args)
{
if (args.PropertyName == "Name")
{
this.Title = !string.IsNullOrEmpty(this._listItem.Title) ? this._listItem.Title : Command.Name;
Title = !string.IsNullOrEmpty(Item.Title) ? Item.Title : Command?.Name ?? string.Empty;
OnPropertyChanged(nameof(Title));
}
else if (args.PropertyName == nameof(Title))
{
this.Title = this._listItem.Title;
Title = Item.Title;
}
else if (args.PropertyName == nameof(Subtitle))
{
this.Subtitle = this._listItem.Subtitle;
Subtitle = Item.Subtitle;
}
else if (args.PropertyName == nameof(MoreCommands))
{
this.MoreCommands = this._listItem.MoreCommands;
MoreCommands = Item.MoreCommands;
}
OnPropertyChanged(args.PropertyName);

View File

@@ -68,7 +68,7 @@ public sealed class MainListPage : DynamicListPage
// Eh, it's fine to be unsafe here, we're probably tossing MainListItem
if (!_mainViewModel.Recent.Contains(listItem))
{
_mainSection._Items.Add(new MainListItem(listItem.Unsafe));
_mainSection.TopLevelItems.Add(new MainListItem(listItem.Unsafe));
}
_filteredSection.TopLevelItems.Add(new MainListItem(listItem.Unsafe));
@@ -81,11 +81,11 @@ public sealed class MainListPage : DynamicListPage
{
if (item is ExtensionObject<IListItem> listItem)
{
foreach (var mainListItem in _mainSection._Items)
foreach (var mainListItem in _mainSection.TopLevelItems)
{
if (mainListItem.Item == listItem)
{
_mainSection._Items.Remove(mainListItem);
_mainSection.TopLevelItems.Remove(mainListItem);
break;
}
}

View File

@@ -4,12 +4,8 @@
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using CmdPal.Models;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml;
using Microsoft.CmdPal.Extensions;
using Microsoft.CmdPal.Extensions.Helpers;
using Microsoft.UI.Dispatching;
using WindowsCommandPalette.Views;
namespace DeveloperCommandPalette;
@@ -25,7 +21,7 @@ public sealed class MainListSection : ISection, INotifyCollectionChanged
private readonly DispatcherQueue _dispatcherQueue = DispatcherQueue.GetForCurrentThread();
// Top-level list items, from builtin commands and extensions
internal ObservableCollection<MainListItem> _Items { get; set; }
public ObservableCollection<MainListItem> TopLevelItems { get; set; }
// Things we should enumerate over, depending on the search query.
// This is either
@@ -33,8 +29,7 @@ public sealed class MainListSection : ISection, INotifyCollectionChanged
// * OR one of:
// * Just the top-level actions (if there's no query)
// * OR the top-level actions AND the apps (if there's a query)
private IEnumerable<IListItem> itemsToEnumerate =>
_Items.Where(i => i != null && (!_mainViewModel.IsRecentCommand(i)));
private IEnumerable<IListItem> TopLevelItemsToEnumerate => TopLevelItems.Where(i => i != null && (!_mainViewModel.IsRecentCommand(i)));
// Watch out future me!
//
@@ -45,18 +40,18 @@ public sealed class MainListSection : ISection, INotifyCollectionChanged
//
// instead run the query once when the action query changes, and store the
// results.
public IListItem[] Items => itemsToEnumerate.ToArray();
public IListItem[] Items => TopLevelItemsToEnumerate.ToArray();
public MainListSection(MainViewModel viewModel)
{
this._mainViewModel = viewModel;
_Items = new(_mainViewModel.TopLevelCommands.Select(w => w.Unsafe).Where(li => li != null).Select(li => new MainListItem(li!)));
_Items.CollectionChanged += Bubble_CollectionChanged;
TopLevelItems = new(_mainViewModel.TopLevelCommands.Select(w => w.Unsafe).Where(li => li != null).Select(li => new MainListItem(li!)));
TopLevelItems.CollectionChanged += Bubble_CollectionChanged;
}
internal void UpdateQuery(string query)
{
var fallbacks = _Items.Select(i => i?.FallbackHandler).Where(fb => fb != null).Select(fb => fb!);
var fallbacks = TopLevelItems.Select(i => i?.FallbackHandler).Where(fb => fb != null).Select(fb => fb!);
foreach (var fb in fallbacks)
{
fb.UpdateQuery(query);
@@ -73,6 +68,6 @@ public sealed class MainListSection : ISection, INotifyCollectionChanged
internal void Reset()
{
_Items.Clear();
TopLevelItems.Clear();
}
}

View File

@@ -27,20 +27,24 @@ namespace DeveloperCommandPalette;
/// </summary>
public sealed partial class MainWindow : Window
{
private readonly AppWindow m_AppWindow;
private readonly AppWindow _appWindow;
private MainViewModel _mainViewModel { get; init; }
private readonly MainViewModel _mainViewModel;
private readonly HWND hwnd;
private const uint DOT_KEY = 0xBE;
private const uint WM_HOTKEY = 0x0312;
private WNDPROC? origPrc;
private WNDPROC? hotKeyPrc;
private Windows.Win32.Foundation.LRESULT HotKeyPrc(Windows.Win32.Foundation.HWND hwnd,
uint uMsg,
Windows.Win32.Foundation.WPARAM wParam,
Windows.Win32.Foundation.LPARAM lParam)
#pragma warning disable SA1310 // Field names should not contain underscore
private const uint DOT_KEY = 0xBE;
private const uint WM_HOTKEY = 0x0312;
#pragma warning restore SA1310 // Field names should not contain underscore
private LRESULT HotKeyPrc(
HWND hwnd,
uint uMsg,
WPARAM wParam,
LPARAM lParam)
{
if (uMsg == WM_HOTKEY)
{
@@ -71,8 +75,8 @@ public sealed partial class MainWindow : Window
public MainWindow()
{
this.InitializeComponent();
this._mainViewModel = MainPage.ViewModel;
InitializeComponent();
_mainViewModel = MainPage.ViewModel;
hwnd = new Windows.Win32.Foundation.HWND(WinRT.Interop.WindowNative.GetWindowHandle(this).ToInt32());
@@ -80,7 +84,7 @@ public sealed partial class MainWindow : Window
// Assumes "this" is a XAML Window. In projects that don't use
// WinUI 3 1.3 or later, use interop APIs to get the AppWindow.
m_AppWindow = this.AppWindow;
_appWindow = AppWindow;
Activated += MainWindow_Activated;
AppTitleBar.SizeChanged += AppTitleBar_SizeChanged;
@@ -88,10 +92,10 @@ public sealed partial class MainWindow : Window
ExtendsContentIntoTitleBar = true;
// Hide our titlebar. We'll make the sides draggable later
m_AppWindow.TitleBar.PreferredHeightOption = TitleBarHeightOption.Collapsed;
_appWindow.TitleBar.PreferredHeightOption = TitleBarHeightOption.Collapsed;
AppTitleTextBlock.Text = AppInfo.Current.DisplayInfo.DisplayName;
m_AppWindow.Title = AppTitleTextBlock.Text;
_appWindow.Title = AppTitleTextBlock.Text;
Application.Current.GetService<ILocalSettingsService>().SaveSettingAsync("ThisIsAVeryBizarreString", true);
@@ -101,7 +105,7 @@ public sealed partial class MainWindow : Window
_mainViewModel.QuitRequested += (s, e) =>
{
this.Close();
Close();
// Application.Current.Exit();
};
@@ -120,8 +124,8 @@ public sealed partial class MainWindow : Window
private void PositionCentered()
{
m_AppWindow.Resize(new SizeInt32 { Width = 860, Height = 512 });
DisplayArea displayArea = DisplayArea.GetFromWindowId(m_AppWindow.Id, DisplayAreaFallback.Nearest);
_appWindow.Resize(new SizeInt32 { Width = 860, Height = 512 });
DisplayArea displayArea = DisplayArea.GetFromWindowId(_appWindow.Id, DisplayAreaFallback.Nearest);
if (displayArea is not null)
{
var centeredPosition = AppWindow.Position;
@@ -134,7 +138,7 @@ public sealed partial class MainWindow : Window
private void PositionForStartMenu()
{
m_AppWindow.Resize(new Windows.Graphics.SizeInt32(768, 768));
_appWindow.Resize(new Windows.Graphics.SizeInt32(768, 768));
// now put the window in the right place
//
@@ -168,22 +172,22 @@ public sealed partial class MainWindow : Window
// react appropriately
}
Microsoft.UI.Windowing.DisplayArea displayArea = Microsoft.UI.Windowing.DisplayArea.GetFromWindowId(m_AppWindow.Id, Microsoft.UI.Windowing.DisplayAreaFallback.Nearest);
Microsoft.UI.Windowing.DisplayArea displayArea = Microsoft.UI.Windowing.DisplayArea.GetFromWindowId(_appWindow.Id, Microsoft.UI.Windowing.DisplayAreaFallback.Nearest);
if (displayArea is not null)
{
var centeredPosition = m_AppWindow.Position;
var centeredPosition = _appWindow.Position;
if (onLeft)
{
centeredPosition.X = 16;
centeredPosition.Y = displayArea.WorkArea.Height - m_AppWindow.Size.Height - 16;
centeredPosition.Y = displayArea.WorkArea.Height - _appWindow.Size.Height - 16;
}
else
{
centeredPosition.X = (displayArea.WorkArea.Width - m_AppWindow.Size.Width) / 2;
centeredPosition.Y = displayArea.WorkArea.Height - m_AppWindow.Size.Height - 16;
centeredPosition.X = (displayArea.WorkArea.Width - _appWindow.Size.Width) / 2;
centeredPosition.Y = displayArea.WorkArea.Height - _appWindow.Size.Height - 16;
}
m_AppWindow.Move(centeredPosition);
_appWindow.Move(centeredPosition);
}
}
@@ -215,8 +219,8 @@ public sealed partial class MainWindow : Window
// Specify the interactive regions of the title bar.
var scaleAdjustment = AppTitleBar.XamlRoot.RasterizationScale;
RightPaddingColumn.Width = new GridLength(m_AppWindow.TitleBar.RightInset / scaleAdjustment);
LeftPaddingColumn.Width = new GridLength(m_AppWindow.TitleBar.LeftInset / scaleAdjustment);
RightPaddingColumn.Width = new GridLength(_appWindow.TitleBar.RightInset / scaleAdjustment);
LeftPaddingColumn.Width = new GridLength(_appWindow.TitleBar.LeftInset / scaleAdjustment);
//// Get the rectangle around the content
GeneralTransform transform = MainPage.TransformToVisual(null);
@@ -317,7 +321,7 @@ public sealed partial class MainWindow : Window
return modifierString + keyString;
}
private static (VirtualKey key, VirtualKeyModifiers modifiers) StringToKeybinding(string keybinding)
private static (VirtualKey Key, VirtualKeyModifiers Modifiers) StringToKeybinding(string keybinding)
{
var parts = keybinding.Split('+');
var modifiers = VirtualKeyModifiers.None;
@@ -351,9 +355,10 @@ public sealed partial class MainWindow : Window
return (key, modifiers);
}
private static (uint vk, Windows.Win32.UI.Input.KeyboardAndMouse.HOT_KEY_MODIFIERS mod) UwpToWin32(VirtualKey key, VirtualKeyModifiers modifiers)
private static (uint Vk, Windows.Win32.UI.Input.KeyboardAndMouse.HOT_KEY_MODIFIERS Mod) UwpToWin32(VirtualKey key, VirtualKeyModifiers modifiers)
{
Windows.Win32.UI.Input.KeyboardAndMouse.HOT_KEY_MODIFIERS mod = new();
Windows.Win32.UI.Input.KeyboardAndMouse.HOT_KEY_MODIFIERS mod = default;
if (modifiers.HasFlag(VirtualKeyModifiers.Control))
{
mod |= Windows.Win32.UI.Input.KeyboardAndMouse.HOT_KEY_MODIFIERS.MOD_CONTROL;

View File

@@ -9,11 +9,9 @@ namespace DeveloperCommandPalette;
public class PageViewModel
{
private bool nested;
public bool Nested { get; set; }
public bool Nested { get => nested; set => nested = value; }
protected IPage pageAction { get; }
public IPage PageAction { get; }
// public IPage PageAction { get => pageAction; set => pageAction = value; }
public ActionViewModel Command { get; }
@@ -26,8 +24,8 @@ public class PageViewModel
protected PageViewModel(IPage page)
{
this.pageAction = page;
this.Command = new(page);
PageAction = page;
Command = new(page);
}
public void DoAction(ActionViewModel action)

View File

@@ -4,12 +4,9 @@
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using CmdPal.Models;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml;
using Microsoft.CmdPal.Extensions;
using Microsoft.CmdPal.Extensions.Helpers;
using Microsoft.UI.Dispatching;
using WindowsCommandPalette.Views;
namespace DeveloperCommandPalette;
@@ -21,26 +18,27 @@ public sealed class RecentsListSection : ListSection, INotifyCollectionChanged
private readonly DispatcherQueue _dispatcherQueue = DispatcherQueue.GetForCurrentThread();
private readonly MainViewModel _mainViewModel;
internal ObservableCollection<MainListItem> _Items { get; set; } = [];
private readonly ObservableCollection<MainListItem> _items = [];
private bool loadedApps;
public RecentsListSection(MainViewModel viewModel)
{
this.Title = "Recent";
this._mainViewModel = viewModel;
Title = "Recent";
_mainViewModel = viewModel;
var recent = _mainViewModel.RecentActions;
Reset();
_Items.CollectionChanged += Bubble_CollectionChanged;
_items.CollectionChanged += Bubble_CollectionChanged;
_mainViewModel.AppsReady += _mainViewModel_AppsReady;
_mainViewModel.AppsReady += MainViewModel_AppsReady;
}
private void _mainViewModel_AppsReady(object sender, object? args)
private void MainViewModel_AppsReady(object sender, object? args)
{
loadedApps = true;
_mainViewModel.AppsReady -= _mainViewModel_AppsReady;
_mainViewModel.AppsReady -= MainViewModel_AppsReady;
AddApps();
}
@@ -52,11 +50,11 @@ public sealed class RecentsListSection : ListSection, INotifyCollectionChanged
});
}
public override IListItem[] Items => _Items.ToArray();
public override IListItem[] Items => _items.ToArray();
internal void Reset()
{
_Items.Clear();
_items.Clear();
if (loadedApps)
{
AddApps();
@@ -68,7 +66,7 @@ public sealed class RecentsListSection : ListSection, INotifyCollectionChanged
var apps = _mainViewModel.Recent;
foreach (var app in apps)
{
_Items.Add(new MainListItem(app.Unsafe)); // we know these are all local
_items.Add(new MainListItem(app.Unsafe)); // we know these are all local
}
}
}

View File

@@ -6,8 +6,8 @@ using CmdPal.Models;
using Microsoft.CmdPal.Common.Contracts;
using Microsoft.CmdPal.Common.Extensions;
using Microsoft.CmdPal.Common.Services;
using Microsoft.UI.Xaml;
using Microsoft.CmdPal.Extensions;
using Microsoft.UI.Xaml;
using Windows.ApplicationModel;
using Windows.ApplicationModel.AppExtensions;
using Windows.Foundation.Collections;
@@ -168,8 +168,9 @@ public class ExtensionService : IExtensionService, IDisposable
var extensions = await GetInstalledAppExtensionsAsync();
foreach (var extension in extensions)
{
var (CmdPalProvider, classIds) = await GetCmdPalExtensionPropertiesAsync(extension);
if (CmdPalProvider == null || classIds.Count == 0)
var (cmdPalProvider, classIds) = await GetCmdPalExtensionPropertiesAsync(extension);
if (cmdPalProvider == null || classIds.Count == 0)
{
continue;
}
@@ -178,7 +179,7 @@ public class ExtensionService : IExtensionService, IDisposable
{
var extensionWrapper = new ExtensionWrapper(extension, classId);
var supportedInterfaces = GetSubPropertySet(CmdPalProvider, "SupportedInterfaces");
var supportedInterfaces = GetSubPropertySet(cmdPalProvider, "SupportedInterfaces");
if (supportedInterfaces is not null)
{
foreach (var supportedInterface in supportedInterfaces)

View File

@@ -3,9 +3,9 @@
// See the LICENSE file in the project root for more information.
using System.ComponentModel;
using Microsoft.CmdPal.Extensions;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
using Microsoft.CmdPal.Extensions;
using Windows.UI;
namespace DeveloperCommandPalette;

View File

@@ -2,27 +2,13 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Collections.ObjectModel;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.WindowsRuntime;
using CmdPal.Models;
using DeveloperCommandPalette;
using Microsoft.CmdPal.Common.Extensions;
using Microsoft.CmdPal.Common.Services;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media.Animation;
using Microsoft.CmdPal.Extensions;
using Microsoft.CmdPal.Extensions.Helpers;
using Windows.Foundation;
using Windows.Win32;
using WindowsCommandPalette.BuiltinCommands;
using WindowsCommandPalette.BuiltinCommands.AllApps;
namespace WindowsCommandPalette.Views;
internal sealed class ActionsProviderWrapper
public sealed class ActionsProviderWrapper
{
public bool IsExtension => extensionWrapper != null;

View File

@@ -2,8 +2,8 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Microsoft.UI.Xaml.Controls;
using Microsoft.CmdPal.Extensions;
using Microsoft.UI.Xaml.Controls;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.

View File

@@ -2,30 +2,16 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Runtime.InteropServices;
using DeveloperCommandPalette;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Input;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Navigation;
using Microsoft.CmdPal.Extensions;
using Microsoft.CmdPal.Extensions.Helpers;
namespace WindowsCommandPalette.Views;
public sealed class ErrorListItem : Microsoft.CmdPal.Extensions.Helpers.ListItem
public sealed class ErrorListItem : ListItem
{
public ErrorListItem(Exception ex)
: base(new NoOpAction())
{
this.Title = "Error in extension:";
this.Subtitle = ex.Message;
Title = "Error in extension:";
Subtitle = ex.Message;
}
}

View File

@@ -14,8 +14,9 @@ namespace WindowsCommandPalette.Views;
public sealed partial class FormPage : Page
{
private readonly AdaptiveCardRenderer Renderer = new();
private FormPageViewModel? ViewModel;
private readonly AdaptiveCardRenderer _renderer = new();
public FormPageViewModel? ViewModel { get; set; }
public FormPage()
{
@@ -26,12 +27,12 @@ public sealed partial class FormPage : Page
// yep it's this dumb
var foreground = settings.GetColorValue(UIColorType.Foreground);
var lightTheme = foreground.R < 128;
Renderer.HostConfig = AdaptiveHostConfig.FromJsonString(lightTheme ? LightHostConfig : DarkHostConfig).HostConfig;
_renderer.HostConfig = AdaptiveHostConfig.FromJsonString(lightTheme ? LightHostConfig : DarkHostConfig).HostConfig;
}
private void AddCardElement(FormViewModel form)
{
form.RenderToXaml(Renderer);
form.RenderToXaml(_renderer);
}
protected override void OnNavigatedTo(NavigationEventArgs e)

View File

@@ -2,28 +2,15 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using AdaptiveCards.ObjectModel.WinUI3;
using AdaptiveCards.Rendering.WinUI3;
using AdaptiveCards.Templating;
using DeveloperCommandPalette;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Navigation;
using Microsoft.CmdPal.Extensions;
using Microsoft.CmdPal.Extensions.Helpers;
using Windows.Foundation;
using Windows.System;
using Windows.UI.ViewManagement;
namespace WindowsCommandPalette.Views;
public sealed class FormPageViewModel : PageViewModel
{
internal IFormPage Page => (IFormPage)this.pageAction;
internal IFormPage Page => (IFormPage)this.PageAction;
internal ObservableCollection<FormViewModel> Forms = new();

View File

@@ -7,62 +7,63 @@ using AdaptiveCards.ObjectModel.WinUI3;
using AdaptiveCards.Rendering.WinUI3;
using AdaptiveCards.Templating;
using DeveloperCommandPalette;
using Microsoft.UI.Xaml;
using Microsoft.CmdPal.Extensions;
using Microsoft.UI.Xaml;
using Windows.Foundation;
using Windows.System;
namespace WindowsCommandPalette.Views;
public sealed class FormViewModel : System.ComponentModel.INotifyPropertyChanged
public sealed class FormViewModel : INotifyPropertyChanged
{
internal readonly IForm form;
internal AdaptiveCardParseResult? card;
internal RenderedAdaptiveCard? RenderedAdaptiveCard;
internal string TemplateJson = "{}";
internal string DataJson = "{}";
private readonly IForm _form;
private AdaptiveCardParseResult? _card;
private RenderedAdaptiveCard? _renderedAdaptiveCard;
private string _templateJson = "{}";
private string _dataJson = "{}";
public event TypedEventHandler<object, SubmitFormArgs>? RequestSubmitForm;
public event PropertyChangedEventHandler? PropertyChanged;
public bool ShouldDisplay => RenderedAdaptiveCard?.FrameworkElement != null;
public bool ShouldDisplay => _renderedAdaptiveCard?.FrameworkElement != null;
public FrameworkElement? RenderedChildElement => RenderedAdaptiveCard?.FrameworkElement;
public FrameworkElement? RenderedChildElement => _renderedAdaptiveCard?.FrameworkElement;
public FormViewModel(IForm form)
{
this.form = form;
this._form = form;
}
internal void InitialRender()
{
// var t = new Task<bool>(() => {
this.TemplateJson = this.form.TemplateJson();
this._templateJson = this._form.TemplateJson();
try
{
this.DataJson = this.form.DataJson();
this._dataJson = this._form.DataJson();
}
catch (Exception)
{
this.DataJson = "{}";
this._dataJson = "{}";
}
// return true;
// });
// t.Start();
// await t;
AdaptiveCardTemplate template = new(TemplateJson);
var cardJson = template.Expand(DataJson);
this.card = AdaptiveCard.FromJsonString(cardJson);
AdaptiveCardTemplate template = new(_templateJson);
var cardJson = template.Expand(_dataJson);
this._card = AdaptiveCard.FromJsonString(cardJson);
}
internal void RenderToXaml(AdaptiveCardRenderer renderer)
{
if (this.card != null)
if (this._card != null)
{
RenderedAdaptiveCard = renderer.RenderAdaptiveCard(card.AdaptiveCard);
RenderedAdaptiveCard.Action += RenderedAdaptiveCard_Action;
_renderedAdaptiveCard = renderer.RenderAdaptiveCard(_card.AdaptiveCard);
_renderedAdaptiveCard.Action += RenderedAdaptiveCard_Action;
var handlers = this.PropertyChanged;
handlers?.Invoke(this, new PropertyChangedEventArgs(nameof(ShouldDisplay)));
@@ -86,7 +87,7 @@ public sealed class FormViewModel : System.ComponentModel.INotifyPropertyChanged
// Process them as desired
var handlers = RequestSubmitForm;
handlers?.Invoke(this, new() { FormData = inputs, Form = form });
handlers?.Invoke(this, new() { FormData = inputs, Form = _form });
}
}
}

View File

@@ -4,6 +4,7 @@
using System.ComponentModel;
using DeveloperCommandPalette;
using Microsoft.CmdPal.Extensions.Helpers;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Input;
using Microsoft.UI.Xaml;
@@ -11,7 +12,6 @@ using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Navigation;
using Microsoft.CmdPal.Extensions.Helpers;
namespace WindowsCommandPalette.Views;
@@ -255,20 +255,16 @@ public sealed partial class ListPage : Page, INotifyPropertyChanged
}
e.Handled = true;
}
else if (ctrlPressed && e.Key == Windows.System.VirtualKey.K) // ctrl+k
} // ctrl+k
else if (ctrlPressed && e.Key == Windows.System.VirtualKey.K && ActionsDropdown.Items.Count > 0)
{
// Open the more actions flyout and focus the first item
if (ActionsDropdown.Items.Count > 0)
FlyoutShowOptions options = new FlyoutShowOptions
{
FlyoutShowOptions options = new FlyoutShowOptions
{
ShowMode = FlyoutShowMode.Standard,
};
MoreCommandsButton.Flyout.ShowAt(MoreCommandsButton, options);
ActionsDropdown.SelectedIndex = 0;
ActionsDropdown.Focus(FocusState.Programmatic);
}
ShowMode = FlyoutShowMode.Standard,
};
MoreCommandsButton.Flyout.ShowAt(MoreCommandsButton, options);
ActionsDropdown.SelectedIndex = 0;
ActionsDropdown.Focus(FocusState.Programmatic);
}
}

View File

@@ -5,9 +5,9 @@
using System.Collections.ObjectModel;
using System.Runtime.InteropServices;
using DeveloperCommandPalette;
using Microsoft.UI.Dispatching;
using Microsoft.CmdPal.Extensions;
using Microsoft.CmdPal.Extensions.Helpers;
using Microsoft.UI.Dispatching;
namespace WindowsCommandPalette.Views;
@@ -16,14 +16,14 @@ public sealed class ListPageViewModel : PageViewModel
internal readonly ObservableCollection<SectionInfoList> Items = [];
internal readonly ObservableCollection<SectionInfoList> FilteredItems = [];
internal IListPage Page => (IListPage)this.pageAction;
internal IListPage Page => (IListPage)this.PageAction;
private bool isDynamic => Page is IDynamicListPage;
private bool IsDynamic => Page is IDynamicListPage;
private IDynamicListPage? dynamicPage => Page as IDynamicListPage;
private IDynamicListPage? IsDynamicPage => Page as IDynamicListPage;
private readonly DispatcherQueue _dispatcherQueue = DispatcherQueue.GetForCurrentThread();
internal string Query = string.Empty;
private string _query = string.Empty;
public ListPageViewModel(IListPage page)
: base(page)
@@ -42,8 +42,8 @@ public sealed class ListPageViewModel : PageViewModel
{
try
{
return dynamicPage != null ?
dynamicPage.GetItems(Query) :
return IsDynamicPage != null ?
IsDynamicPage.GetItems(_query) :
this.Page.GetItems();
}
catch (Exception ex)
@@ -98,13 +98,13 @@ public sealed class ListPageViewModel : PageViewModel
internal async Task<Collection<SectionInfoList>> GetFilteredItems(string query)
{
if (query == Query)
if (query == _query)
{
return FilteredItems;
}
Query = query;
if (isDynamic)
_query = query;
if (IsDynamic)
{
await UpdateListItems();
return FilteredItems;
@@ -125,7 +125,7 @@ public sealed class ListPageViewModel : PageViewModel
Items
.SelectMany(section => section)
.Select(vm => vm.ListItem.Unsafe),
Query).Select(li => new ListItemViewModel(li));
_query).Select(li => new ListItemViewModel(li));
var newSection = new SectionInfoList(null, allFilteredItems);
return [newSection];

View File

@@ -6,11 +6,11 @@ using System.Runtime.InteropServices;
using DeveloperCommandPalette;
using Microsoft.CmdPal.Common.Extensions;
using Microsoft.CmdPal.Common.Services;
using Microsoft.CmdPal.Extensions;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media.Animation;
using Microsoft.CmdPal.Extensions;
namespace WindowsCommandPalette.Views;
@@ -89,10 +89,11 @@ public sealed partial class MainPage : Page
{
// Load commands from builtins
// TODO! I don't understand async enough to get why this has to be ConfigureAwait(false)
foreach (var provider in ViewModel._builtInCommands)
foreach (var provider in ViewModel.BuiltInCommands)
{
var wrapper = new ActionsProviderWrapper(provider);
ViewModel.CommandsProviders.Add(wrapper);
ViewModel.ActionsProvider.Add(wrapper);
await LoadTopLevelCommandsFromProvider(wrapper).ConfigureAwait(false);
}
}
@@ -138,7 +139,7 @@ public sealed partial class MainPage : Page
private void TryAllowForeground(ICommand action)
{
foreach (var provider in ViewModel.CommandsProviders)
foreach (var provider in ViewModel.ActionsProvider)
{
if (!provider.IsExtension)
{
@@ -271,7 +272,7 @@ public sealed partial class MainPage : Page
{
await extension.StartExtensionAsync();
var wrapper = new ActionsProviderWrapper(extension);
ViewModel.CommandsProviders.Add(wrapper);
ViewModel.ActionsProvider.Add(wrapper);
await LoadTopLevelCommandsFromProvider(wrapper);
}
catch (Exception ex)

View File

@@ -7,40 +7,37 @@ using System.Runtime.InteropServices;
using System.Runtime.InteropServices.WindowsRuntime;
using CmdPal.Models;
using DeveloperCommandPalette;
using Microsoft.CmdPal.Common.Extensions;
using Microsoft.CmdPal.Common.Services;
using Microsoft.CmdPal.Ext.Bookmarks;
using Microsoft.CmdPal.Ext.Calc;
using Microsoft.CmdPal.Ext.Settings;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media.Animation;
using Microsoft.CmdPal.Extensions;
using Microsoft.CmdPal.Extensions.Helpers;
using Windows.Foundation;
using Windows.Win32;
using WindowsCommandPalette.BuiltinCommands;
using WindowsCommandPalette.BuiltinCommands.AllApps;
namespace WindowsCommandPalette.Views;
public sealed class MainViewModel
public sealed class MainViewModel : IDisposable
{
internal readonly AllAppsPage apps = new();
internal readonly QuitActionProvider quitActionProvider = new();
internal readonly ReloadExtensionsActionProvider reloadActionProvider = new();
private readonly QuitActionProvider _quitActionProvider = new();
private readonly ReloadExtensionsActionProvider _reloadActionProvider = new();
public event TypedEventHandler<object, object?>? QuitRequested { add => quitActionProvider.QuitRequested += value; remove => quitActionProvider.QuitRequested -= value; }
public AllAppsPage Apps { get; set; } = new();
internal readonly ObservableCollection<ActionsProviderWrapper> CommandsProviders = new();
internal readonly ObservableCollection<ExtensionObject<IListItem>> TopLevelCommands = [];
public event TypedEventHandler<object, object?>? QuitRequested { add => _quitActionProvider.QuitRequested += value; remove => _quitActionProvider.QuitRequested -= value; }
internal readonly List<ICommandProvider> _builtInCommands = [];
public ObservableCollection<ActionsProviderWrapper> ActionsProvider { get; set; } = [];
internal bool Loaded;
internal bool LoadingExtensions;
internal bool LoadedApps;
public ObservableCollection<ExtensionObject<IListItem>> TopLevelCommands { get; set; } = [];
public List<ICommandProvider> BuiltInCommands { get; set; } = [];
public bool Loaded { get; set; }
public bool LoadingExtensions { get; set; }
public bool LoadedApps { get; set; }
public event TypedEventHandler<object, object?>? HideRequested;
@@ -50,18 +47,19 @@ public sealed class MainViewModel
internal MainViewModel()
{
_builtInCommands.Add(new BookmarksActionProvider());
_builtInCommands.Add(new CalculatorActionProvider());
_builtInCommands.Add(new SettingsActionProvider());
_builtInCommands.Add(quitActionProvider);
_builtInCommands.Add(reloadActionProvider);
BuiltInCommands.Add(new BookmarksActionProvider());
BuiltInCommands.Add(new CalculatorActionProvider());
BuiltInCommands.Add(new SettingsActionProvider());
BuiltInCommands.Add(_quitActionProvider);
BuiltInCommands.Add(_reloadActionProvider);
ResetTopLevel();
// On a background thread, warm up the app cache since we want it more often than not
new Task(() =>
{
var _ = AppCache.Instance.Value;
_ = AppCache.Instance.Value;
LoadedApps = true;
AppsReady?.Invoke(this, null);
}).Start();
@@ -70,7 +68,7 @@ public sealed class MainViewModel
public void ResetTopLevel()
{
TopLevelCommands.Clear();
TopLevelCommands.Add(new(new ListItem(apps)));
TopLevelCommands.Add(new(new ListItem(Apps)));
}
internal void RequestHide()
@@ -111,7 +109,7 @@ public sealed class MainViewModel
return false;
}).Select(i => i!);
public IEnumerable<IListItem> AppItems => LoadedApps ? apps.GetItems().First().Items : [];
public IEnumerable<IListItem> AppItems => LoadedApps ? Apps.GetItems().First().Items : [];
public IEnumerable<ExtensionObject<IListItem>> Everything => TopLevelCommands
.Concat(AppItems.Select(i => new ExtensionObject<IListItem>(i)))
@@ -183,4 +181,10 @@ public sealed class MainViewModel
}
}
}
public void Dispose()
{
_quitActionProvider.Dispose();
_reloadActionProvider.Dispose();
}
}

View File

@@ -4,19 +4,19 @@
using System.ComponentModel;
using DeveloperCommandPalette;
using Microsoft.CmdPal.Extensions;
using Microsoft.UI.Input;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Navigation;
using Microsoft.CmdPal.Extensions;
namespace WindowsCommandPalette.Views;
public sealed partial class MarkdownPage : Page, INotifyPropertyChanged
{
private MarkdownPageViewModel? ViewModel;
public MarkdownPageViewModel? ViewModel { get; set; }
#pragma warning disable CS0067
public event PropertyChangedEventHandler? PropertyChanged;

View File

@@ -9,29 +9,31 @@ namespace WindowsCommandPalette.Views;
public sealed class MarkdownPageViewModel : PageViewModel
{
internal IMarkdownPage Page => (IMarkdownPage)this.pageAction;
public IMarkdownPage Page => (IMarkdownPage)PageAction;
internal string[] MarkdownContent = [string.Empty];
public string[] MarkdownContent { get; set; } = [string.Empty];
internal string Title => Page.Title;
public string Title => Page.Title;
private IEnumerable<ICommandContextItem> contextActions => Page.Commands.Where(i => i is ICommandContextItem).Select(i => (ICommandContextItem)i);
private IEnumerable<ICommandContextItem> GetCommandContextItems()
{
return Page.Commands.Where(i => i is ICommandContextItem).Select(i => (ICommandContextItem)i);
}
internal bool HasMoreCommands => contextActions.Any();
public bool HasMoreCommands => GetCommandContextItems().Any();
internal IList<ContextItemViewModel> ContextActions => contextActions.Select(a => new ContextItemViewModel(a)).ToList();
public IList<ContextItemViewModel> ContextActions => GetCommandContextItems().Select(a => new ContextItemViewModel(a)).ToList();
public MarkdownPageViewModel(IMarkdownPage page)
: base(page)
{
}
internal async Task InitialRender(MarkdownPage markdownPage)
public async Task InitialRender(MarkdownPage markdownPage)
{
var t = new Task<string[]>(() => {
return this.Page.Bodies();
});
var t = new Task<string[]>(Page.Bodies);
t.Start();
this.MarkdownContent = await t;
MarkdownContent = await t;
}
}

View File

@@ -2,19 +2,6 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Runtime.InteropServices;
using DeveloperCommandPalette;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Input;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Navigation;
using Microsoft.CmdPal.Extensions;
using Microsoft.CmdPal.Extensions.Helpers;

View File

@@ -4,19 +4,9 @@
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Runtime.InteropServices;
using DeveloperCommandPalette;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Input;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Navigation;
using Microsoft.CmdPal.Extensions;
using Microsoft.CmdPal.Extensions.Helpers;
using Microsoft.UI.Dispatching;
namespace WindowsCommandPalette.Views;

View File

@@ -2,21 +2,8 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Runtime.InteropServices;
using DeveloperCommandPalette;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Input;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Navigation;
using Microsoft.CmdPal.Extensions;
using Microsoft.CmdPal.Extensions.Helpers;
namespace WindowsCommandPalette.Views;