Compare commits

...

26 Commits

Author SHA1 Message Date
Mike Griese
630e7e0ac8 Remove ManagedCommon from core.viewmodels 2025-07-11 10:19:37 -05:00
Mike Griese
1a2406671d Merge branch 'dev/migrie/40113/new-core-project' into dev/migrie/40113/extension-hosts-try-2 2025-07-11 09:23:11 -05:00
Mike Griese
b59f2875f4 Merge branch 'dev/migrie/40113/viewmodel-factory' into dev/migrie/40113/new-core-project 2025-07-11 09:22:52 -05:00
Mike Griese
129c10a0a2 Merge branch 'dev/migrie/40113/remove-mainlistpage-from-shellvm' into dev/migrie/40113/viewmodel-factory 2025-07-11 09:22:21 -05:00
Mike Griese
8d342b4b32 Merge remote-tracking branch 'origin/main' into dev/migrie/40113/remove-mainlistpage-from-shellvm 2025-07-11 09:21:50 -05:00
Mike Griese
89ac05a8cd cleanup comments 2025-07-11 09:17:55 -05:00
Mike Griese
a10a79ecc8 cleanup comments 2025-07-11 09:13:48 -05:00
Mike Griese
d7eb61d57e Move the extension FG handler to the PT RootPageService too 2025-07-11 09:04:13 -05:00
Mike Griese
555c488de5 lot of cleanup, it builds and runs 2025-07-10 15:22:36 -05:00
Mike Griese
e214cda85c A different approach to the extension host problem
I think the work to figure out the extension host was much
overcomplicated. I don't think we need all that.
2025-07-10 12:53:38 -05:00
Mike Griese
ae6172dc16 Merge branch 'dev/migrie/40113/viewmodel-factory' into dev/migrie/40113/new-core-project 2025-07-10 10:11:40 -05:00
Mike Griese
b290b9b1a2 Merge branch 'dev/migrie/40113/remove-mainlistpage-from-shellvm' into dev/migrie/40113/viewmodel-factory 2025-07-10 09:37:22 -05:00
Mike Griese
42262ee9d6 Merge remote-tracking branch 'origin/main' into dev/migrie/40113/remove-mainlistpage-from-shellvm 2025-07-10 06:45:34 -05:00
Mike Griese
c3c77f2c75 add support for content pages again 2025-07-09 13:21:17 -05:00
Mike Griese
a8d0fbf44e damn it builds and actually runs 2025-07-09 12:50:26 -05:00
Mike Griese
402e379c6f the ui.vm project builds 2025-07-09 10:27:52 -05:00
Mike Griese
8cd6622d14 the core vm project builds, unbelievable 2025-07-09 10:09:52 -05:00
Mike Griese
ddff05ec54 blind file moves 2025-07-09 10:09:35 -05:00
Mike Griese
ef6412d116 CmdPal: Add a viewmodel factory for pages
_targets #40482_
ref #40113

A smaller refactor, to be sure.

This just moves the instantiation of PageViewModel objects out of the
ShellViewModel, and into its own class.

The idea being that other page types could be added, just by extending
that factory (or implementing your own), and then also handling those
new VMs in your ShellPage.xaml.cs equivalent.
2025-07-09 09:39:33 -05:00
Mike Griese
0654830420 cleanup 2025-07-08 15:22:12 -05:00
Mike Griese
91d085fbca Remove ShellViewModel's dependency on MainListPage
targets #40479

Kinda mental that the viewmodel had this hard dependency.

So instead I added a service for providing the root page for the app.
Theoretically, you could add a different IRootPageService, and give out
a different root page.

This works and builds and runs. Needs cleanup.

ref #49113
2025-07-08 15:07:58 -05:00
Mike Griese
c1d755aea6 This needs to be handled on the UI thread, so move it to the UI 2025-07-08 15:07:11 -05:00
Mike Griese
be5ebf9322 comment 2025-07-08 13:54:19 -05:00
Mike Griese
f2c57ee33e telem too 2025-07-08 13:51:00 -05:00
Mike Griese
1e198d4acf some cleanup 2025-07-08 13:36:13 -05:00
Mike Griese
f809bd139c Refactor ShellPage logic into VM
ref #40113

Moves a lot of the "model" logic out of ShellPage.xaml.cs into
ShellViewModel. It compiles, and runs, hot dang.

Needs some cleanup.
2025-07-08 12:32:45 -05:00
123 changed files with 873 additions and 593 deletions

View File

@@ -736,6 +736,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ManagedCsWin32", "src\commo
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PowerRenameUITest", "src\modules\powerrename\PowerRenameUITest\PowerRenameUITest.csproj", "{9D3F3793-EFE3-4525-8782-238015DABA62}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Core", "Core", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Core.ViewModels", "src\modules\cmdpal\Microsoft.CmdPal.Core.ViewModels\Microsoft.CmdPal.Core.ViewModels.csproj", "{24133F7F-C1D1-DE04-EFA8-F5D5467FE027}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM64 = Debug|ARM64
@@ -2718,6 +2722,14 @@ Global
{14AFD976-B4D2-49D0-9E6C-AA93CC061B8A}.Release|ARM64.Build.0 = Release|ARM64
{14AFD976-B4D2-49D0-9E6C-AA93CC061B8A}.Release|x64.ActiveCfg = Release|x64
{14AFD976-B4D2-49D0-9E6C-AA93CC061B8A}.Release|x64.Build.0 = Release|x64
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027}.Debug|ARM64.ActiveCfg = Debug|ARM64
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027}.Debug|ARM64.Build.0 = Debug|ARM64
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027}.Debug|x64.ActiveCfg = Debug|x64
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027}.Debug|x64.Build.0 = Debug|x64
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027}.Release|ARM64.ActiveCfg = Release|ARM64
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027}.Release|ARM64.Build.0 = Release|ARM64
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027}.Release|x64.ActiveCfg = Release|x64
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027}.Release|x64.Build.0 = Release|x64
{9D3F3793-EFE3-4525-8782-238015DABA62}.Debug|ARM64.ActiveCfg = Debug|ARM64
{9D3F3793-EFE3-4525-8782-238015DABA62}.Debug|ARM64.Build.0 = Debug|ARM64
{9D3F3793-EFE3-4525-8782-238015DABA62}.Debug|x64.ActiveCfg = Debug|x64
@@ -3010,6 +3022,8 @@ Global
{43E779F3-D83C-48B1-BA8D-1912DBD76FC9} = {A2221D7E-55E7-4BEA-90D1-4F162D670BBF}
{2CF78CF7-8FEB-4BE1-9591-55FA25B48FC6} = {1AFB6476-670D-4E80-A464-657E01DFF482}
{14AFD976-B4D2-49D0-9E6C-AA93CC061B8A} = {1AFB6476-670D-4E80-A464-657E01DFF482}
{02EA681E-C7D8-13C7-8484-4AC65E1B71E8} = {3846508C-77EB-4034-A702-F8BB263C4F79}
{24133F7F-C1D1-DE04-EFA8-F5D5467FE027} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{9D3F3793-EFE3-4525-8782-238015DABA62} = {89E20BCE-EB9C-46C8-8B50-E01A82E6FDC3}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution

View File

@@ -0,0 +1,167 @@
// Copyright (c) Microsoft Corporation
// 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.Diagnostics;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
using Windows.Foundation;
namespace Microsoft.CmdPal.Core.ViewModels;
public abstract partial class AppExtensionHost : IExtensionHost
{
private static readonly GlobalLogPageContext _globalLogPageContext = new();
private static ulong _hostingHwnd;
public static ObservableCollection<LogMessageViewModel> LogMessages { get; } = [];
public ulong HostingHwnd => _hostingHwnd;
public string LanguageOverride => string.Empty;
public ObservableCollection<StatusMessageViewModel> StatusMessages { get; } = [];
public static void SetHostHwnd(ulong hostHwnd) => _hostingHwnd = hostHwnd;
public void DebugLog(string message)
{
#if DEBUG
this.ProcessLogMessage(new LogMessage(message));
#endif
}
public IAsyncAction HideStatus(IStatusMessage? message)
{
if (message == null)
{
return Task.CompletedTask.AsAsyncAction();
}
_ = Task.Run(() =>
{
ProcessHideStatusMessage(message);
});
return Task.CompletedTask.AsAsyncAction();
}
public void Log(string message)
{
this.ProcessLogMessage(new LogMessage(message));
}
public IAsyncAction LogMessage(ILogMessage? message)
{
if (message == null)
{
return Task.CompletedTask.AsAsyncAction();
}
CoreLogger.LogDebug(message.Message);
_ = Task.Run(() =>
{
ProcessLogMessage(message);
});
// We can't just make a LogMessageViewModel : ExtensionObjectViewModel
// because we don't necessarily know the page context. Butts.
return Task.CompletedTask.AsAsyncAction();
}
public void ProcessHideStatusMessage(IStatusMessage message)
{
Task.Factory.StartNew(
() =>
{
try
{
var vm = StatusMessages.Where(messageVM => messageVM.Model.Unsafe == message).FirstOrDefault();
if (vm != null)
{
StatusMessages.Remove(vm);
}
}
catch
{
}
},
CancellationToken.None,
TaskCreationOptions.None,
_globalLogPageContext.Scheduler);
}
public void ProcessLogMessage(ILogMessage message)
{
var vm = new LogMessageViewModel(message, _globalLogPageContext);
vm.SafeInitializePropertiesSynchronous();
Task.Factory.StartNew(
() =>
{
LogMessages.Add(vm);
},
CancellationToken.None,
TaskCreationOptions.None,
_globalLogPageContext.Scheduler);
}
public void ProcessStatusMessage(IStatusMessage message, StatusContext context)
{
// If this message is already in the list of messages, just bring it to the top
var oldVm = StatusMessages.Where(messageVM => messageVM.Model.Unsafe == message).FirstOrDefault();
if (oldVm != null)
{
Task.Factory.StartNew(
() =>
{
StatusMessages.Remove(oldVm);
StatusMessages.Add(oldVm);
},
CancellationToken.None,
TaskCreationOptions.None,
_globalLogPageContext.Scheduler);
return;
}
var vm = new StatusMessageViewModel(message, new(_globalLogPageContext));
vm.SafeInitializePropertiesSynchronous();
Task.Factory.StartNew(
() =>
{
StatusMessages.Add(vm);
},
CancellationToken.None,
TaskCreationOptions.None,
_globalLogPageContext.Scheduler);
}
public IAsyncAction ShowStatus(IStatusMessage? message, StatusContext context)
{
if (message == null)
{
return Task.CompletedTask.AsAsyncAction();
}
Debug.WriteLine(message.Message);
_ = Task.Run(() =>
{
ProcessStatusMessage(message, context);
});
return Task.CompletedTask.AsAsyncAction();
}
public abstract string? GetExtensionDisplayName();
}
public interface IAppHostService
{
AppExtensionHost GetDefaultHost();
AppExtensionHost GetHostForCommand(object? context, AppExtensionHost? currentHost);
}

View File

@@ -1,15 +1,15 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// 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 CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Messaging;
using Microsoft.CmdPal.UI.ViewModels.Messages;
using Microsoft.CmdPal.Core.ViewModels.Messages;
using Microsoft.CommandPalette.Extensions.Toolkit;
using Windows.System;
namespace Microsoft.CmdPal.UI.ViewModels;
namespace Microsoft.CmdPal.Core.ViewModels;
public partial class CommandBarViewModel : ObservableObject,
IRecipient<UpdateCommandBarMessage>

View File

@@ -1,13 +1,11 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using CommunityToolkit.Mvvm.Messaging;
using Microsoft.CmdPal.UI.ViewModels.Messages;
using Microsoft.CmdPal.UI.ViewModels.Models;
using Microsoft.CmdPal.Core.ViewModels.Models;
using Microsoft.CommandPalette.Extensions;
namespace Microsoft.CmdPal.UI.ViewModels;
namespace Microsoft.CmdPal.Core.ViewModels;
public partial class CommandContextItemViewModel(ICommandContextItem contextItem, WeakReference<IPageContext> context) : CommandItemViewModel(new(contextItem), context), IContextItemViewModel
{

View File

@@ -1,13 +1,13 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// 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.CmdPal.UI.ViewModels.Messages;
using Microsoft.CmdPal.UI.ViewModels.Models;
using Microsoft.CmdPal.Core.ViewModels.Messages;
using Microsoft.CmdPal.Core.ViewModels.Models;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
namespace Microsoft.CmdPal.UI.ViewModels;
namespace Microsoft.CmdPal.Core.ViewModels;
public partial class CommandItemViewModel : ExtensionObjectViewModel, ICommandBarContext
{

View File

@@ -1,11 +1,11 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// 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.CmdPal.UI.ViewModels.Models;
using Microsoft.CmdPal.Core.ViewModels.Models;
using Microsoft.CommandPalette.Extensions;
namespace Microsoft.CmdPal.UI.ViewModels;
namespace Microsoft.CmdPal.Core.ViewModels;
public partial class CommandViewModel : ExtensionObjectViewModel
{

View File

@@ -1,11 +1,11 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// 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.CmdPal.UI.ViewModels.Models;
using Microsoft.CmdPal.Core.ViewModels.Models;
using Microsoft.CommandPalette.Extensions;
namespace Microsoft.CmdPal.UI.ViewModels;
namespace Microsoft.CmdPal.Core.ViewModels;
public partial class ConfirmResultViewModel(IConfirmationArgs _args, WeakReference<IPageContext> context) :
ExtensionObjectViewModel(context)

View File

@@ -7,12 +7,12 @@ using System.Diagnostics.CodeAnalysis;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using Microsoft.CmdPal.UI.ViewModels.Messages;
using Microsoft.CmdPal.UI.ViewModels.Models;
using Microsoft.CmdPal.Core.ViewModels.Messages;
using Microsoft.CmdPal.Core.ViewModels.Models;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
namespace Microsoft.CmdPal.UI.ViewModels;
namespace Microsoft.CmdPal.Core.ViewModels;
public partial class ContentPageViewModel : PageViewModel, ICommandBarContext
{
@@ -47,7 +47,7 @@ public partial class ContentPageViewModel : PageViewModel, ICommandBarContext
// Remember - "observable" properties from the model (via PropChanged)
// cannot be marked [ObservableProperty]
public ContentPageViewModel(IContentPage model, TaskScheduler scheduler, CommandPaletteHost host)
public ContentPageViewModel(IContentPage model, TaskScheduler scheduler, AppExtensionHost host)
: base(model, scheduler, host)
{
_model = new(model);
@@ -91,16 +91,12 @@ public partial class ContentPageViewModel : PageViewModel, ICommandBarContext
});
}
public static ContentViewModel? ViewModelFromContent(IContent content, WeakReference<IPageContext> context)
public virtual ContentViewModel? ViewModelFromContent(IContent content, WeakReference<IPageContext> context)
{
ContentViewModel? viewModel = content switch
{
IFormContent form => new ContentFormViewModel(form, context),
IMarkdownContent markdown => new ContentMarkdownViewModel(markdown, context),
ITreeContent tree => new ContentTreeViewModel(tree, context),
_ => null,
};
return viewModel;
// The core ContentPageViewModel doesn't actually handle any content,
// so we just return null here.
// The real content is handled by the derived class CommandPaletteContentPageViewModel
return null;
}
public override void InitializeProperties()
@@ -115,15 +111,15 @@ public partial class ContentPageViewModel : PageViewModel, ICommandBarContext
Commands = model.Commands
.ToList()
.Select(item =>
.Select<IContextItem, IContextItemViewModel>(item =>
{
if (item is CommandContextItem contextItem)
{
return new CommandContextItemViewModel(contextItem, PageContext) as IContextItemViewModel;
return new CommandContextItemViewModel(contextItem, PageContext);
}
else
{
return new SeparatorContextItemViewModel() as IContextItemViewModel;
return new SeparatorContextItemViewModel();
}
})
.ToList();
@@ -182,7 +178,7 @@ public partial class ContentPageViewModel : PageViewModel, ICommandBarContext
}
else
{
return new SeparatorContextItemViewModel() as IContextItemViewModel;
return new SeparatorContextItemViewModel();
}
})
.ToList();

View File

@@ -1,8 +1,8 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.CmdPal.UI.ViewModels;
namespace Microsoft.CmdPal.Core.ViewModels;
public abstract partial class ContentViewModel(WeakReference<IPageContext> context) :
ExtensionObjectViewModel(context)

View File

@@ -5,13 +5,12 @@
using System.Collections.ObjectModel;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Messaging;
using Microsoft.CmdPal.UI.ViewModels.Messages;
using Microsoft.CmdPal.Core.ViewModels.Messages;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
using Microsoft.Diagnostics.Utilities;
using Windows.System;
namespace Microsoft.CmdPal.UI.ViewModels;
namespace Microsoft.CmdPal.Core.ViewModels;
public partial class ContextMenuViewModel : ObservableObject,
IRecipient<UpdateCommandBarMessage>,

View File

@@ -0,0 +1,60 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.CmdPal.Core.ViewModels;
public static class CoreLogger
{
public static void InitializeLogger(ILogger implementation)
{
_logger = implementation;
}
private static ILogger? _logger;
public static void LogError(string message, Exception ex, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
{
_logger?.LogError(message, ex, memberName, sourceFilePath, sourceLineNumber);
}
public static void LogError(string message, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
{
_logger?.LogError(message, memberName, sourceFilePath, sourceLineNumber);
}
public static void LogWarning(string message, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
{
_logger?.LogWarning(message, memberName, sourceFilePath, sourceLineNumber);
}
public static void LogInfo(string message, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
{
_logger?.LogInfo(message, memberName, sourceFilePath, sourceLineNumber);
}
public static void LogDebug(string message, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
{
_logger?.LogDebug(message, memberName, sourceFilePath, sourceLineNumber);
}
public static void LogTrace([System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
{
_logger?.LogTrace(memberName, sourceFilePath, sourceLineNumber);
}
}
public interface ILogger
{
void LogError(string message, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0);
void LogError(string message, Exception ex, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0);
void LogWarning(string message, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0);
void LogInfo(string message, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0);
void LogDebug(string message, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0);
void LogTrace([System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0);
}

View File

@@ -1,11 +1,11 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// 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.CmdPal.UI.ViewModels.Models;
using Microsoft.CmdPal.Core.ViewModels.Models;
using Microsoft.CommandPalette.Extensions;
namespace Microsoft.CmdPal.UI.ViewModels;
namespace Microsoft.CmdPal.Core.ViewModels;
public partial class DetailsCommandsViewModel(
IDetailsElement _detailsElement,

View File

@@ -1,11 +1,11 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// 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.CmdPal.UI.ViewModels.Models;
using Microsoft.CmdPal.Core.ViewModels.Models;
using Microsoft.CommandPalette.Extensions;
namespace Microsoft.CmdPal.UI.ViewModels;
namespace Microsoft.CmdPal.Core.ViewModels;
public abstract partial class DetailsDataViewModel(IPageContext context) : ExtensionObjectViewModel(context)
{

View File

@@ -1,11 +1,11 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// 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.CmdPal.UI.ViewModels.Models;
using Microsoft.CmdPal.Core.ViewModels.Models;
using Microsoft.CommandPalette.Extensions;
namespace Microsoft.CmdPal.UI.ViewModels;
namespace Microsoft.CmdPal.Core.ViewModels;
public abstract partial class DetailsElementViewModel(IDetailsElement _detailsElement, WeakReference<IPageContext> context) : ExtensionObjectViewModel(context)
{

View File

@@ -1,11 +1,11 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// 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.CmdPal.UI.ViewModels.Models;
using Microsoft.CmdPal.Core.ViewModels.Models;
using Microsoft.CommandPalette.Extensions;
namespace Microsoft.CmdPal.UI.ViewModels;
namespace Microsoft.CmdPal.Core.ViewModels;
public partial class DetailsLinkViewModel(
IDetailsElement _detailsElement,

View File

@@ -1,11 +1,11 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// 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.CmdPal.UI.ViewModels.Models;
using Microsoft.CmdPal.Core.ViewModels.Models;
using Microsoft.CommandPalette.Extensions;
namespace Microsoft.CmdPal.UI.ViewModels;
namespace Microsoft.CmdPal.Core.ViewModels;
public partial class DetailsSeparatorViewModel(
IDetailsElement _detailsElement,

View File

@@ -1,11 +1,11 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// 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.CmdPal.UI.ViewModels.Models;
using Microsoft.CmdPal.Core.ViewModels.Models;
using Microsoft.CommandPalette.Extensions;
namespace Microsoft.CmdPal.UI.ViewModels;
namespace Microsoft.CmdPal.Core.ViewModels;
public partial class DetailsTagsViewModel(
IDetailsElement _detailsElement,

View File

@@ -1,11 +1,11 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// 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.CmdPal.UI.ViewModels.Models;
using Microsoft.CmdPal.Core.ViewModels.Models;
using Microsoft.CommandPalette.Extensions;
namespace Microsoft.CmdPal.UI.ViewModels;
namespace Microsoft.CmdPal.Core.ViewModels;
public partial class DetailsViewModel(IDetails _details, WeakReference<IPageContext> context) : ExtensionObjectViewModel(context)
{

View File

@@ -1,11 +1,10 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using CommunityToolkit.Mvvm.ComponentModel;
using ManagedCommon;
namespace Microsoft.CmdPal.UI.ViewModels;
namespace Microsoft.CmdPal.Core.ViewModels;
public abstract partial class ExtensionObjectViewModel : ObservableObject
{
@@ -84,7 +83,7 @@ public abstract partial class ExtensionObjectViewModel : ObservableObject
}
catch (Exception ex)
{
Logger.LogDebug(ex.ToString());
CoreLogger.LogDebug(ex.ToString());
}
}
}

View File

@@ -2,7 +2,7 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.CmdPal.UI.ViewModels;
namespace Microsoft.CmdPal.Core.ViewModels;
public class GlobalLogPageContext : IPageContext
{

View File

@@ -8,7 +8,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Microsoft.CmdPal.UI.ViewModels;
namespace Microsoft.CmdPal.Core.ViewModels;
public interface IContextItemViewModel
{

View File

@@ -2,9 +2,7 @@
// 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.Threading.Tasks;
namespace Microsoft.CmdPal.Common.Services;
namespace Microsoft.CmdPal.Core.ViewModels;
public interface IRootPageService
{
@@ -29,9 +27,11 @@ public interface IRootPageService
Task PostLoadRootPageAsync();
/// <summary>
/// Called when a top-level command is performed. The context is the
/// Called when a command is performed. The context is the
/// sender context for the invoked command. This is typically the IListItem
/// or ICommandContextItem that was used to invoke the command.
/// </summary>
void OnPerformTopLevelCommand(object? context);
void OnPerformCommand(object? context, bool topLevel, AppExtensionHost? currentHost);
void GoHome();
}

View File

@@ -1,13 +1,13 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using CommunityToolkit.Mvvm.ComponentModel;
using Microsoft.CmdPal.UI.ViewModels.Models;
using Microsoft.CmdPal.Core.ViewModels.Models;
using Microsoft.CommandPalette.Extensions;
using Windows.Storage.Streams;
namespace Microsoft.CmdPal.UI.ViewModels;
namespace Microsoft.CmdPal.Core.ViewModels;
public partial class IconDataViewModel : ObservableObject, IIconData
{

View File

@@ -1,12 +1,12 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using CommunityToolkit.Mvvm.ComponentModel;
using Microsoft.CmdPal.UI.ViewModels.Models;
using Microsoft.CmdPal.Core.ViewModels.Models;
using Microsoft.CommandPalette.Extensions;
namespace Microsoft.CmdPal.UI.ViewModels;
namespace Microsoft.CmdPal.Core.ViewModels;
public partial class IconInfoViewModel : ObservableObject, IIconInfo
{

View File

@@ -1,13 +1,13 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// 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.Diagnostics.CodeAnalysis;
using Microsoft.CmdPal.UI.ViewModels.Models;
using Microsoft.CmdPal.Core.ViewModels.Models;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
namespace Microsoft.CmdPal.UI.ViewModels;
namespace Microsoft.CmdPal.Core.ViewModels;
public partial class ListItemViewModel(IListItem model, WeakReference<IPageContext> context)
: CommandItemViewModel(new(model), context)

View File

@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
@@ -6,13 +6,13 @@ using System.Collections.ObjectModel;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using Microsoft.CmdPal.UI.ViewModels.Messages;
using Microsoft.CmdPal.UI.ViewModels.Models;
using Microsoft.CmdPal.Core.ViewModels.Messages;
using Microsoft.CmdPal.Core.ViewModels.Models;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
using Windows.Foundation;
namespace Microsoft.CmdPal.UI.ViewModels;
namespace Microsoft.CmdPal.Core.ViewModels;
public partial class ListViewModel : PageViewModel, IDisposable
{
@@ -72,7 +72,7 @@ public partial class ListViewModel : PageViewModel, IDisposable
}
}
public ListViewModel(IListPage model, TaskScheduler scheduler, CommandPaletteHost host)
public ListViewModel(IListPage model, TaskScheduler scheduler, AppExtensionHost host)
: base(model, scheduler, host)
{
_model = new(model);
@@ -158,10 +158,7 @@ public partial class ListViewModel : PageViewModel, IDisposable
}
// Cancel any ongoing search
if (_cancellationTokenSource != null)
{
_cancellationTokenSource.Cancel();
}
_cancellationTokenSource?.Cancel();
lock (_listLock)
{

View File

@@ -1,15 +1,15 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// 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.CommandPalette.Extensions;
namespace Microsoft.CmdPal.UI.ViewModels;
namespace Microsoft.CmdPal.Core.ViewModels;
public partial class LoadingPageViewModel : PageViewModel
{
public LoadingPageViewModel(IPage? model, TaskScheduler scheduler)
: base(model, scheduler, CommandPaletteHost.Instance)
public LoadingPageViewModel(IPage? model, TaskScheduler scheduler, AppExtensionHost host)
: base(model, scheduler, host)
{
ModelIsLoading = true;
IsInitialized = false;

View File

@@ -2,10 +2,10 @@
// 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.CmdPal.UI.ViewModels.Models;
using Microsoft.CmdPal.Core.ViewModels.Models;
using Microsoft.CommandPalette.Extensions;
namespace Microsoft.CmdPal.UI.ViewModels;
namespace Microsoft.CmdPal.Core.ViewModels;
public partial class LogMessageViewModel : ExtensionObjectViewModel
{
@@ -13,8 +13,6 @@ public partial class LogMessageViewModel : ExtensionObjectViewModel
public string Message { get; private set; } = string.Empty;
public string ExtensionPfn { get; set; } = string.Empty;
public LogMessageViewModel(ILogMessage message, IPageContext context)
: base(context)
{

View File

@@ -1,8 +1,8 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
/// <summary>
/// Used to perform a list item's secondary command when the user presses ctrl+enter in the search box

View File

@@ -2,7 +2,7 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
/// <summary>
/// Used to perform a list item's command when the user presses enter in the search box

View File

@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
public record BeginInvokeMessage;

View File

@@ -1,8 +1,8 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
public record ClearSearchMessage()
{

View File

@@ -2,7 +2,7 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
/// <summary>
/// Used to announce that a context menu should close

View File

@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
public record CmdPalInvokeResultMessage(Microsoft.CommandPalette.Extensions.CommandResultKind Kind);

View File

@@ -1,8 +1,8 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
public record DismissMessage()
{

View File

@@ -1,8 +1,8 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
public record FocusSearchBoxMessage()
{

View File

@@ -1,8 +1,8 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
public record GoBackMessage(bool WithAnimation = true, bool FocusSearch = true)
{

View File

@@ -1,8 +1,8 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
// TODO! sticking these properties here feels like leaking the UI into the models
public record GoHomeMessage(bool WithAnimation = true, bool FocusSearch = true)

View File

@@ -1,11 +1,11 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// 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.CmdPal.UI.ViewModels.Models;
using Microsoft.CmdPal.Core.ViewModels.Models;
using Microsoft.CommandPalette.Extensions;
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
public record HandleCommandResultMessage(ExtensionObject<ICommandResult> Result)
{

View File

@@ -1,11 +1,11 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// 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.CmdPal.UI.ViewModels.Models;
using Microsoft.CmdPal.Core.ViewModels.Models;
using Microsoft.CommandPalette.Extensions;
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
public record HideDetailsMessage()
{

View File

@@ -1,8 +1,8 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
public record HotkeySummonMessage(string CommandId, IntPtr Hwnd)
{

View File

@@ -1,11 +1,11 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// 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.CmdPal.UI.ViewModels.Models;
using Microsoft.CmdPal.Core.ViewModels.Models;
using Microsoft.CommandPalette.Extensions;
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
public record LaunchUriMessage(Uri Uri)
{

View File

@@ -1,8 +1,8 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
public record NavigateBackMessage(bool FromBackspace = false)
{

View File

@@ -1,8 +1,8 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
/// <summary>
/// Used to navigate to the next command in the page when pressing the Down key in the SearchBox.

View File

@@ -1,8 +1,8 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
/// <summary>
/// Used to navigate to the previous command in the page when pressing the Down key in the SearchBox.

View File

@@ -1,8 +1,8 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
public record NavigateToPageMessage(PageViewModel Page, bool WithAnimation)
{

View File

@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
@@ -6,7 +6,7 @@ using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls.Primitives;
using Windows.Foundation;
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
/// <summary>
/// Used to announce the context menu should open

View File

@@ -1,10 +1,8 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// 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.CmdPal.UI.ViewModels.BuiltinCommands;
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
public record OpenSettingsMessage()
{

View File

@@ -1,11 +1,11 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// 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.CmdPal.UI.ViewModels.Models;
using Microsoft.CmdPal.Core.ViewModels.Models;
using Microsoft.CommandPalette.Extensions;
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
/// <summary>
/// Used to do a command - navigate to a page or invoke it
@@ -18,21 +18,12 @@ public record PerformCommandMessage
public bool WithAnimation { get; set; } = true;
public CommandPaletteHost? ExtensionHost { get; private set; }
public PerformCommandMessage(ExtensionObject<ICommand> command)
{
Command = command;
Context = null;
}
public PerformCommandMessage(TopLevelViewModel topLevelCommand)
{
Command = topLevelCommand.CommandViewModel.Model;
Context = null;
ExtensionHost = topLevelCommand.ExtensionHost;
}
public PerformCommandMessage(ExtensionObject<ICommand> command, ExtensionObject<IListItem> context)
{
Command = command;

View File

@@ -1,10 +1,8 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// 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.CmdPal.UI.ViewModels.BuiltinCommands;
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
/// <summary>
/// Message which closes the application. Used by <see cref="QuitCommand"/> via <see cref="BuiltInsCommandProvider"/>.

View File

@@ -1,8 +1,8 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
public record ReloadCommandsMessage()
{

View File

@@ -1,8 +1,8 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
public record SettingsWindowClosedMessage
{

View File

@@ -1,8 +1,8 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
public record ShowConfirmationMessage(Microsoft.CommandPalette.Extensions.IConfirmationArgs? Args)
{

View File

@@ -1,11 +1,11 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// 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.CmdPal.UI.ViewModels.Models;
using Microsoft.CmdPal.Core.ViewModels.Models;
using Microsoft.CommandPalette.Extensions;
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
public record ShowDetailsMessage(DetailsViewModel Details)
{

View File

@@ -1,8 +1,8 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
public record ShowToastMessage(string Message)
{

View File

@@ -1,8 +1,8 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
public record ShowWindowMessage(IntPtr Hwnd)
{

View File

@@ -1,10 +1,10 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Windows.System;
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
public record TryCommandKeybindingMessage(bool Ctrl, bool Alt, bool Shift, bool Win, VirtualKey Key)
{

View File

@@ -1,11 +1,11 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// 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.ComponentModel;
using Microsoft.CommandPalette.Extensions;
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
/// <summary>
/// Used to update the command bar at the bottom to reflect the commands for a list item

View File

@@ -1,8 +1,8 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.CmdPal.UI.ViewModels.Messages;
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
public record UpdateFallbackItemsMessage()
{

View File

@@ -0,0 +1,47 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\Common.Dotnet.CsWinRT.props" />
<Import Project="..\..\..\Common.Dotnet.AotCompatibility.props" />
<PropertyGroup>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<OutputPath>$(SolutionDir)$(Platform)\$(Configuration)\WinUI3Apps\CmdPal</OutputPath>
<!-- For MVVM Toolkit Partial Properties/AOT support -->
<LangVersion>preview</LangVersion>
<!-- Disable SA1313 for Primary Constructor fields conflict https://learn.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/instance-constructors#primary-constructors -->
<NoWarn>SA1313;</NoWarn>
</PropertyGroup>
<PropertyGroup>
<CsWinRTAotOptimizerEnabled>true</CsWinRTAotOptimizerEnabled>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CommunityToolkit.Common" />
<PackageReference Include="CommunityToolkit.Mvvm" />
<PackageReference Include="Microsoft.Windows.CsWin32">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="WyHash" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Microsoft.CmdPal.Common\Microsoft.CmdPal.Common.csproj" />
<ProjectReference Include="..\extensionsdk\Microsoft.CommandPalette.Extensions.Toolkit\Microsoft.CommandPalette.Extensions.Toolkit.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
</ItemGroup>
</Project>

View File

@@ -1,8 +1,8 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.CmdPal.UI.ViewModels.Models;
namespace Microsoft.CmdPal.Core.ViewModels.Models;
public class ExtensionObject<T>(T? value) // where T : IInspectable
{

View File

@@ -0,0 +1,4 @@
{
"$schema": "https://aka.ms/CsWin32.schema.json",
"allowMarshaling": false
}

View File

@@ -0,0 +1,19 @@
GetPhysicallyInstalledSystemMemory
GlobalMemoryStatusEx
GetSystemInfo
CoCreateInstance
SetForegroundWindow
IsIconic
RegisterHotKey
SetWindowLongPtr
CallWindowProc
ShowWindow
SetForegroundWindow
SetFocus
SetActiveWindow
MonitorFromWindow
GetMonitorInfo
SHCreateStreamOnFileEx
CoAllowSetForegroundWindow
SHCreateStreamOnFileEx
SHLoadIndirectString

View File

@@ -1,14 +1,14 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// 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 CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Microsoft.CmdPal.UI.ViewModels.Models;
using Microsoft.CmdPal.Core.ViewModels.Models;
using Microsoft.CommandPalette.Extensions;
namespace Microsoft.CmdPal.UI.ViewModels;
namespace Microsoft.CmdPal.Core.ViewModels;
public partial class PageViewModel : ExtensionObjectViewModel, IPageContext
{
@@ -43,7 +43,7 @@ public partial class PageViewModel : ExtensionObjectViewModel, IPageContext
public bool ShowSuggestion => !string.IsNullOrEmpty(TextToSuggest) && TextToSuggest != Filter;
[ObservableProperty]
public partial CommandPaletteHost ExtensionHost { get; private set; }
public partial AppExtensionHost ExtensionHost { get; private set; }
public bool HasStatusMessage => MostRecentStatusMessage != null;
@@ -69,7 +69,7 @@ public partial class PageViewModel : ExtensionObjectViewModel, IPageContext
public IconInfoViewModel Icon { get; protected set; }
public PageViewModel(IPage? model, TaskScheduler scheduler, CommandPaletteHost extensionHost)
public PageViewModel(IPage? model, TaskScheduler scheduler, AppExtensionHost extensionHost)
: base((IPageContext?)null)
{
_pageModel = new(model);
@@ -220,7 +220,7 @@ public partial class PageViewModel : ExtensionObjectViewModel, IPageContext
{
// Set the extensionHint to the Page Title (if we have one, and one not provided).
// extensionHint ??= _pageModel?.Unsafe?.Title;
extensionHint ??= ExtensionHost.Extension?.ExtensionDisplayName ?? Title;
extensionHint ??= ExtensionHost.GetExtensionDisplayName() ?? Title;
Task.Factory.StartNew(
() =>
{
@@ -249,7 +249,19 @@ public partial class PageViewModel : ExtensionObjectViewModel, IPageContext
public interface IPageContext
{
public void ShowException(Exception ex, string? extensionHint = null);
void ShowException(Exception ex, string? extensionHint = null);
public TaskScheduler Scheduler { get; }
TaskScheduler Scheduler { get; }
}
public interface IPageViewModelFactoryService
{
/// <summary>
/// Creates a new instance of the page view model for the given page type.
/// </summary>
/// <param name="page">The page for which to create the view model.</param>
/// <param name="nested">Indicates whether the page is not the top-level page.</param>
/// <param name="host">The command palette host that will host the page (for status messages)</param>
/// <returns>A new instance of the page view model.</returns>
PageViewModel? TryCreatePageViewModel(IPage page, bool nested, AppExtensionHost host);
}

View File

@@ -0,0 +1,27 @@
// Copyright (c) Microsoft Corporation
// 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.CommandPalette.Extensions;
namespace Microsoft.CmdPal.Core.ViewModels;
public class PageViewModelFactory : IPageViewModelFactoryService
{
private readonly TaskScheduler _scheduler;
public PageViewModelFactory(TaskScheduler scheduler)
{
_scheduler = scheduler;
}
public PageViewModel? TryCreatePageViewModel(IPage page, bool nested, AppExtensionHost host)
{
return page switch
{
IListPage listPage => new ListViewModel(listPage, _scheduler, host) { IsNested = nested },
IContentPage contentPage => new ContentPageViewModel(contentPage, _scheduler, host),
_ => null,
};
}
}

View File

@@ -1,11 +1,11 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// 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.CmdPal.UI.ViewModels.Models;
using Microsoft.CmdPal.Core.ViewModels.Models;
using Microsoft.CommandPalette.Extensions;
namespace Microsoft.CmdPal.UI.ViewModels;
namespace Microsoft.CmdPal.Core.ViewModels;
public partial class ProgressViewModel : ExtensionObjectViewModel
{

View File

@@ -2,10 +2,10 @@
// 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.CmdPal.UI.ViewModels.Models;
using Microsoft.CmdPal.Core.ViewModels;
using Microsoft.CommandPalette.Extensions;
namespace Microsoft.CmdPal.UI.ViewModels;
namespace Microsoft.CmdPal.Core.ViewModels;
public partial class SeparatorContextItemViewModel() : IContextItemViewModel, ISeparatorContextItem
{

View File

@@ -1,26 +1,23 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// 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.Runtime.InteropServices;
using System.Runtime.Versioning;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using ManagedCommon;
using Microsoft.CmdPal.Common.Services;
using Microsoft.CmdPal.UI.ViewModels.Messages;
using Microsoft.CmdPal.UI.ViewModels.Models;
using Microsoft.CmdPal.Core.ViewModels.Messages;
using Microsoft.CmdPal.Core.ViewModels.Models;
using Microsoft.CommandPalette.Extensions;
using WinRT;
namespace Microsoft.CmdPal.UI.ViewModels;
namespace Microsoft.CmdPal.Core.ViewModels;
public partial class ShellViewModel : ObservableObject,
IRecipient<PerformCommandMessage>
{
private readonly IRootPageService _rootPageService;
private readonly IAppHostService _appHostService;
private readonly TaskScheduler _scheduler;
private readonly IPageViewModelFactoryService _pageViewModelFactory;
private readonly Lock _invokeLock = new();
private Task? _handleInvokeTask;
@@ -51,7 +48,7 @@ public partial class ShellViewModel : ObservableObject,
}
catch (Exception ex)
{
Logger.LogError(ex.ToString());
CoreLogger.LogError(ex.ToString());
}
}
}
@@ -60,16 +57,22 @@ public partial class ShellViewModel : ObservableObject,
private IPage? _rootPage;
private IExtensionWrapper? _activeExtension;
private bool _isNested;
public bool IsNested { get => _isNested; }
public ShellViewModel(TaskScheduler scheduler, IRootPageService rootPageService)
public ShellViewModel(
TaskScheduler scheduler,
IRootPageService rootPageService,
IPageViewModelFactoryService pageViewModelFactory,
IAppHostService appHostService)
{
_pageViewModelFactory = pageViewModelFactory;
_scheduler = scheduler;
_rootPageService = rootPageService;
_currentPage = new LoadingPageViewModel(null, _scheduler);
_appHostService = appHostService;
_currentPage = new LoadingPageViewModel(null, _scheduler, appHostService.GetDefaultHost());
// Register to receive messages
WeakReferenceMessenger.Default.Register<PerformCommandMessage>(this);
@@ -135,7 +138,7 @@ public partial class ShellViewModel : ObservableObject,
// TODO: Handle failure case
if (viewModel.InitializeCommand.ExecutionTask.Exception is AggregateException ex)
{
Logger.LogError(ex.ToString());
CoreLogger.LogError(ex.ToString());
}
// TODO GH #239 switch back when using the new MD text block
@@ -171,11 +174,6 @@ public partial class ShellViewModel : ObservableObject,
}
}
public void PerformTopLevelCommand(PerformCommandMessage message)
{
_rootPageService.OnPerformTopLevelCommand(message.Context);
}
public void Receive(PerformCommandMessage message)
{
PerformCommand(message);
@@ -189,73 +187,24 @@ public partial class ShellViewModel : ObservableObject,
return;
}
if (!CurrentPage.IsNested)
{
// on the main page here
PerformTopLevelCommand(message);
}
var host = _appHostService.GetHostForCommand(message.Context, CurrentPage.ExtensionHost);
IExtensionWrapper? extension = null;
_rootPageService.OnPerformCommand(message.Context, !CurrentPage.IsNested, host);
try
{
// In the case that we're coming from a top-level command, the
// current page's host is the global instance. We only really want
// to use that as the host of last resort.
var pageHost = CurrentPage?.ExtensionHost;
if (pageHost == CommandPaletteHost.Instance)
{
pageHost = null;
}
var messageHost = message.ExtensionHost;
// Use the host from the current page if it has one, else use the
// one specified in the PerformMessage for a top-level command,
// else just use the global one.
CommandPaletteHost host;
// Top level items can come through without a Extension set on the
// message. In that case, the `Context` is actually the
// TopLevelViewModel itself, and we can use that to get at the
// extension object.
extension = pageHost?.Extension ?? messageHost?.Extension ?? null;
if (extension == null && message.Context is TopLevelViewModel topLevelViewModel)
{
extension = topLevelViewModel.ExtensionHost?.Extension;
host = pageHost ?? messageHost ?? topLevelViewModel?.ExtensionHost ?? CommandPaletteHost.Instance;
}
else
{
host = pageHost ?? messageHost ?? CommandPaletteHost.Instance;
}
if (extension != null)
{
if (messageHost != null)
{
Logger.LogDebug($"Activated top-level command from {extension.ExtensionDisplayName}");
}
else
{
Logger.LogDebug($"Activated command from {extension.ExtensionDisplayName}");
}
}
SetActiveExtension(extension);
if (command is IPage page)
{
Logger.LogDebug($"Navigating to page");
CoreLogger.LogDebug($"Navigating to page");
var isMainPage = command == _rootPage;
_isNested = !isMainPage;
// Construct our ViewModel of the appropriate type and pass it the UI Thread context.
var pageViewModel = GetViewModelForPage(page, _isNested, host);
var pageViewModel = _pageViewModelFactory.TryCreatePageViewModel(page, _isNested, host);
if (pageViewModel == null)
{
Logger.LogError($"Failed to create ViewModel for page {page.GetType().Name}");
CoreLogger.LogError($"Failed to create ViewModel for page {page.GetType().Name}");
throw new NotSupportedException();
}
@@ -269,21 +218,21 @@ public partial class ShellViewModel : ObservableObject,
}
else if (command is IInvokableCommand invokable)
{
Logger.LogDebug($"Invoking command");
CoreLogger.LogDebug($"Invoking command");
WeakReferenceMessenger.Default.Send<BeginInvokeMessage>();
StartInvoke(message, invokable);
StartInvoke(message, invokable, host);
}
}
catch (Exception ex)
{
// TODO: It would be better to do this as a page exception, rather
// than a silent log message.
CommandPaletteHost.Instance.Log(ex.Message);
host?.Log(ex.Message);
}
}
private void StartInvoke(PerformCommandMessage message, IInvokableCommand invokable)
private void StartInvoke(PerformCommandMessage message, IInvokableCommand invokable, AppExtensionHost? host)
{
// TODO GH #525 This needs more better locking.
lock (_invokeLock)
@@ -296,13 +245,13 @@ public partial class ShellViewModel : ObservableObject,
{
_handleInvokeTask = Task.Run(() =>
{
SafeHandleInvokeCommandSynchronous(message, invokable);
SafeHandleInvokeCommandSynchronous(message, invokable, host);
});
}
}
}
private void SafeHandleInvokeCommandSynchronous(PerformCommandMessage message, IInvokableCommand invokable)
private void SafeHandleInvokeCommandSynchronous(PerformCommandMessage message, IInvokableCommand invokable, AppExtensionHost? host)
{
try
{
@@ -322,7 +271,7 @@ public partial class ShellViewModel : ObservableObject,
// TODO: It would be better to do this as a page exception, rather
// than a silent log message.
CommandPaletteHost.Instance.Log(ex.Message);
host?.Log(ex.Message);
}
}
@@ -335,7 +284,7 @@ public partial class ShellViewModel : ObservableObject,
}
var kind = result.Kind;
Logger.LogDebug($"handling {kind.ToString()}");
CoreLogger.LogDebug($"handling {kind.ToString()}");
WeakReferenceMessenger.Default.Send<CmdPalInvokeResultMessage>(new(kind));
switch (kind)
@@ -397,54 +346,9 @@ public partial class ShellViewModel : ObservableObject,
}
}
private PageViewModel? GetViewModelForPage(IPage page, bool nested, CommandPaletteHost host)
{
return page switch
{
IListPage listPage => new ListViewModel(listPage, _scheduler, host)
{
IsNested = nested,
},
IContentPage contentPage => new ContentPageViewModel(contentPage, _scheduler, host),
_ => null,
};
}
public void SetActiveExtension(IExtensionWrapper? extension)
{
if (extension != _activeExtension)
{
// There's not really a CoDisallowSetForegroundWindow, so we don't
// need to handle that
_activeExtension = extension;
var extensionWinRtObject = _activeExtension?.GetExtensionObject();
if (extensionWinRtObject != null)
{
try
{
unsafe
{
var winrtObj = (IWinRTObject)extensionWinRtObject;
var intPtr = winrtObj.NativeObject.ThisPtr;
var hr = Native.CoAllowSetForegroundWindow(intPtr);
if (hr != 0)
{
Logger.LogWarning($"Error giving foreground rights: 0x{hr.Value:X8}");
}
}
}
catch (Exception ex)
{
Logger.LogError(ex.ToString());
}
}
}
}
public void GoHome(bool withAnimation = true, bool focusSearch = true)
{
SetActiveExtension(null);
_rootPageService.GoHome();
WeakReferenceMessenger.Default.Send<GoHomeMessage>(new(withAnimation, focusSearch));
}
@@ -453,20 +357,6 @@ public partial class ShellViewModel : ObservableObject,
WeakReferenceMessenger.Default.Send<GoBackMessage>(new(withAnimation, focusSearch));
}
// You may ask yourself, why aren't we using CsWin32 for this?
// The CsWin32 projected version includes some object marshalling, like so:
//
// HRESULT CoAllowSetForegroundWindow([MarshalAs(UnmanagedType.IUnknown)] object pUnk,...)
//
// And if you do it like that, then the IForegroundTransfer interface isn't marshalled correctly
internal sealed class Native
{
[DllImport("OLE32.dll", ExactSpelling = true)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
[SupportedOSPlatform("windows5.0")]
internal static extern unsafe global::Windows.Win32.Foundation.HRESULT CoAllowSetForegroundWindow(nint pUnk, [Optional] void* lpvReserved);
}
private void OnUIThread(Action action)
{
_ = Task.Factory.StartNew(

View File

@@ -1,11 +1,11 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// 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.CmdPal.UI.ViewModels.Models;
using Microsoft.CmdPal.Core.ViewModels.Models;
using Microsoft.CommandPalette.Extensions;
namespace Microsoft.CmdPal.UI.ViewModels;
namespace Microsoft.CmdPal.Core.ViewModels;
public partial class StatusMessageViewModel : ExtensionObjectViewModel
{
@@ -15,14 +15,10 @@ public partial class StatusMessageViewModel : ExtensionObjectViewModel
public MessageState State { get; private set; } = MessageState.Info;
public string ExtensionPfn { get; set; } = string.Empty;
public ProgressViewModel? Progress { get; private set; }
public bool HasProgress => Progress != null;
// public bool IsIndeterminate => Progress != null && Progress.IsIndeterminate;
// public double ProgressValue => (Progress?.ProgressPercent ?? 0) / 100.0;
public StatusMessageViewModel(IStatusMessage message, WeakReference<IPageContext> context)
: base(context)
{

View File

@@ -1,11 +1,11 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// 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.CmdPal.UI.ViewModels.Models;
using Microsoft.CmdPal.Core.ViewModels.Models;
using Microsoft.CommandPalette.Extensions;
namespace Microsoft.CmdPal.UI.ViewModels;
namespace Microsoft.CmdPal.Core.ViewModels;
public partial class TagViewModel(ITag _tag, WeakReference<IPageContext> context) : ExtensionObjectViewModel(context)
{

View File

@@ -4,9 +4,9 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Messaging;
using Microsoft.CmdPal.UI.ViewModels.Messages;
using Microsoft.CmdPal.Core.ViewModels.Messages;
namespace Microsoft.CmdPal.UI.ViewModels;
namespace Microsoft.CmdPal.Core.ViewModels;
public partial class ToastViewModel : ObservableObject
{

View File

@@ -4,7 +4,7 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Messaging;
using Microsoft.CmdPal.UI.ViewModels.Messages;
using Microsoft.CmdPal.Core.ViewModels.Messages;
namespace Microsoft.CmdPal.UI.ViewModels;
@@ -38,7 +38,8 @@ public partial class AliasManager : ObservableObject
if (topLevelCommand != null)
{
WeakReferenceMessenger.Default.Send<ClearSearchMessage>();
WeakReferenceMessenger.Default.Send<PerformCommandMessage>(new(topLevelCommand));
WeakReferenceMessenger.Default.Send<PerformCommandMessage>(topLevelCommand.GetPerformCommandMessage());
return true;
}
}

View File

@@ -0,0 +1,28 @@
// Copyright (c) Microsoft Corporation
// 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.CmdPal.Core.ViewModels;
using Microsoft.CommandPalette.Extensions;
namespace Microsoft.CmdPal.UI.ViewModels;
public partial class CommandPaletteContentPageViewModel : ContentPageViewModel
{
public CommandPaletteContentPageViewModel(IContentPage model, TaskScheduler scheduler, AppExtensionHost host)
: base(model, scheduler, host)
{
}
public override ContentViewModel? ViewModelFromContent(IContent content, WeakReference<IPageContext> context)
{
ContentViewModel? viewModel = content switch
{
IFormContent form => new ContentFormViewModel(form, context),
IMarkdownContent markdown => new ContentMarkdownViewModel(markdown, context),
ITreeContent tree => new ContentTreeViewModel(tree, context),
_ => null,
};
return viewModel;
}
}

View File

@@ -1,35 +1,19 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// 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.Diagnostics;
using ManagedCommon;
using Microsoft.CmdPal.Common.Services;
using Microsoft.CmdPal.Core.ViewModels;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
using Windows.Foundation;
namespace Microsoft.CmdPal.UI.ViewModels;
public sealed partial class CommandPaletteHost : IExtensionHost
public sealed partial class CommandPaletteHost : AppExtensionHost, IExtensionHost
{
// Static singleton, so that we can access this from anywhere
// Post MVVM - this should probably be like, a dependency injection thing.
public static CommandPaletteHost Instance { get; } = new();
private static readonly GlobalLogPageContext _globalLogPageContext = new();
private static ulong _hostingHwnd;
public ulong HostingHwnd => _hostingHwnd;
public string LanguageOverride => string.Empty;
public static ObservableCollection<LogMessageViewModel> LogMessages { get; } = [];
public ObservableCollection<StatusMessageViewModel> StatusMessages { get; } = [];
public IExtensionWrapper? Extension { get; }
private readonly ICommandProvider? _builtInProvider;
@@ -48,145 +32,8 @@ public sealed partial class CommandPaletteHost : IExtensionHost
_builtInProvider = builtInProvider;
}
public IAsyncAction ShowStatus(IStatusMessage? message, StatusContext context)
public override string? GetExtensionDisplayName()
{
if (message == null)
{
return Task.CompletedTask.AsAsyncAction();
}
Debug.WriteLine(message.Message);
_ = Task.Run(() =>
{
ProcessStatusMessage(message, context);
});
return Task.CompletedTask.AsAsyncAction();
}
public IAsyncAction HideStatus(IStatusMessage? message)
{
if (message == null)
{
return Task.CompletedTask.AsAsyncAction();
}
_ = Task.Run(() =>
{
ProcessHideStatusMessage(message);
});
return Task.CompletedTask.AsAsyncAction();
}
public IAsyncAction LogMessage(ILogMessage? message)
{
if (message == null)
{
return Task.CompletedTask.AsAsyncAction();
}
Logger.LogDebug(message.Message);
_ = Task.Run(() =>
{
ProcessLogMessage(message);
});
// We can't just make a LogMessageViewModel : ExtensionObjectViewModel
// because we don't necessarily know the page context. Butts.
return Task.CompletedTask.AsAsyncAction();
}
public void ProcessLogMessage(ILogMessage message)
{
var vm = new LogMessageViewModel(message, _globalLogPageContext);
vm.SafeInitializePropertiesSynchronous();
if (Extension != null)
{
vm.ExtensionPfn = Extension.PackageFamilyName;
}
Task.Factory.StartNew(
() =>
{
LogMessages.Add(vm);
},
CancellationToken.None,
TaskCreationOptions.None,
_globalLogPageContext.Scheduler);
}
public void ProcessStatusMessage(IStatusMessage message, StatusContext context)
{
// If this message is already in the list of messages, just bring it to the top
var oldVm = StatusMessages.Where(messageVM => messageVM.Model.Unsafe == message).FirstOrDefault();
if (oldVm != null)
{
Task.Factory.StartNew(
() =>
{
StatusMessages.Remove(oldVm);
StatusMessages.Add(oldVm);
},
CancellationToken.None,
TaskCreationOptions.None,
_globalLogPageContext.Scheduler);
return;
}
var vm = new StatusMessageViewModel(message, new(_globalLogPageContext));
vm.SafeInitializePropertiesSynchronous();
if (Extension != null)
{
vm.ExtensionPfn = Extension.PackageFamilyName;
}
Task.Factory.StartNew(
() =>
{
StatusMessages.Add(vm);
},
CancellationToken.None,
TaskCreationOptions.None,
_globalLogPageContext.Scheduler);
}
public void ProcessHideStatusMessage(IStatusMessage message)
{
Task.Factory.StartNew(
() =>
{
try
{
var vm = StatusMessages.Where(messageVM => messageVM.Model.Unsafe == message).FirstOrDefault();
if (vm != null)
{
StatusMessages.Remove(vm);
}
}
catch
{
}
},
CancellationToken.None,
TaskCreationOptions.None,
_globalLogPageContext.Scheduler);
}
public static void SetHostHwnd(ulong hostHwnd) => _hostingHwnd = hostHwnd;
public void DebugLog(string message)
{
#if DEBUG
this.ProcessLogMessage(new LogMessage(message));
#endif
}
public void Log(string message)
{
this.ProcessLogMessage(new LogMessage(message));
return Extension?.ExtensionDisplayName;
}
}

View File

@@ -0,0 +1,29 @@
// Copyright (c) Microsoft Corporation
// 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.CmdPal.Core.ViewModels;
using Microsoft.CommandPalette.Extensions;
namespace Microsoft.CmdPal.UI.ViewModels;
public class CommandPalettePageViewModelFactory
: IPageViewModelFactoryService
{
private readonly TaskScheduler _scheduler;
public CommandPalettePageViewModelFactory(TaskScheduler scheduler)
{
_scheduler = scheduler;
}
public PageViewModel? TryCreatePageViewModel(IPage page, bool nested, AppExtensionHost host)
{
return page switch
{
IListPage listPage => new ListViewModel(listPage, _scheduler, host) { IsNested = nested },
IContentPage contentPage => new CommandPaletteContentPageViewModel(contentPage, _scheduler, host),
_ => null,
};
}
}

View File

@@ -4,7 +4,8 @@
using ManagedCommon;
using Microsoft.CmdPal.Common.Services;
using Microsoft.CmdPal.UI.ViewModels.Models;
using Microsoft.CmdPal.Core.ViewModels;
using Microsoft.CmdPal.Core.ViewModels.Models;
using Microsoft.CommandPalette.Extensions;
using Microsoft.Extensions.DependencyInjection;

View File

@@ -3,10 +3,11 @@
// See the LICENSE file in the project root for more information.
using ManagedCommon;
using Microsoft.CmdPal.UI.ViewModels.Models;
using Microsoft.CmdPal.Core.ViewModels.Models;
using Microsoft.CmdPal.UI.ViewModels;
using Microsoft.CommandPalette.Extensions;
namespace Microsoft.CmdPal.UI.ViewModels;
namespace Microsoft.CmdPal.Core.ViewModels;
public partial class CommandSettingsViewModel(ICommandSettings? _unsafeSettings, CommandProviderWrapper provider, TaskScheduler mainThread)
{
@@ -43,7 +44,7 @@ public partial class CommandSettingsViewModel(ICommandSettings? _unsafeSettings,
}
catch (Exception ex)
{
Logger.LogError($"Failed to load settings page", ex: ex);
CoreLogger.LogError($"Failed to load settings page", ex: ex);
}
Initialized = true;

View File

@@ -2,7 +2,7 @@
// 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.CmdPal.UI.ViewModels.Messages;
using Microsoft.CmdPal.Core.ViewModels.Messages;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;

View File

@@ -2,15 +2,7 @@
// 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.Diagnostics.CodeAnalysis;
using System.IO.Compression;
using System.Text.Json;
using System.Text.Json.Nodes;
using Microsoft.CmdPal.Common;
using Microsoft.CmdPal.UI.ViewModels.Messages;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
using Windows.Foundation;
namespace Microsoft.CmdPal.UI.ViewModels.BuiltinCommands;

View File

@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System.Collections.Specialized;
using Microsoft.CmdPal.Core.ViewModels;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
@@ -10,7 +11,7 @@ namespace Microsoft.CmdPal.UI.ViewModels.Commands;
public partial class LogMessagesPage : ListPage
{
private readonly List<IListItem> _listItems = new();
private readonly List<IListItem> _listItems = [];
public LogMessagesPage()
{
@@ -31,7 +32,6 @@ public partial class LogMessagesPage : ListPage
var li = new ListItem(new NoOpCommand())
{
Title = logMessageViewModel.Message,
Subtitle = logMessageViewModel.ExtensionPfn,
};
_listItems.Insert(0, li);
}

View File

@@ -6,8 +6,8 @@ using System.Collections.Immutable;
using System.Collections.Specialized;
using CommunityToolkit.Mvvm.Messaging;
using ManagedCommon;
using Microsoft.CmdPal.Core.ViewModels.Messages;
using Microsoft.CmdPal.Ext.Apps;
using Microsoft.CmdPal.UI.ViewModels.Messages;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
using Microsoft.Extensions.DependencyInjection;

View File

@@ -6,7 +6,7 @@ using System.Diagnostics.CodeAnalysis;
using System.IO.Compression;
using System.Text.Json;
using System.Text.Json.Nodes;
using Microsoft.CmdPal.UI.ViewModels.Messages;
using Microsoft.CmdPal.Core.ViewModels.Messages;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
using Windows.Foundation;

View File

@@ -3,7 +3,7 @@
// See the LICENSE file in the project root for more information.
using CommunityToolkit.Mvvm.Messaging;
using Microsoft.CmdPal.UI.ViewModels.Messages;
using Microsoft.CmdPal.Core.ViewModels.Messages;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;

View File

@@ -3,7 +3,7 @@
// See the LICENSE file in the project root for more information.
using CommunityToolkit.Mvvm.Messaging;
using Microsoft.CmdPal.UI.ViewModels.Messages;
using Microsoft.CmdPal.Core.ViewModels.Messages;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;

View File

@@ -3,7 +3,7 @@
// See the LICENSE file in the project root for more information.
using CommunityToolkit.Mvvm.Messaging;
using Microsoft.CmdPal.UI.ViewModels.Messages;
using Microsoft.CmdPal.Core.ViewModels.Messages;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;

View File

@@ -7,8 +7,9 @@ using AdaptiveCards.ObjectModel.WinUI3;
using AdaptiveCards.Templating;
using CommunityToolkit.Mvvm.Messaging;
using ManagedCommon;
using Microsoft.CmdPal.UI.ViewModels.Messages;
using Microsoft.CmdPal.UI.ViewModels.Models;
using Microsoft.CmdPal.Core.ViewModels;
using Microsoft.CmdPal.Core.ViewModels.Messages;
using Microsoft.CmdPal.Core.ViewModels.Models;
using Microsoft.CommandPalette.Extensions;
using Windows.Data.Json;

View File

@@ -2,7 +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.CmdPal.UI.ViewModels.Models;
using Microsoft.CmdPal.Core.ViewModels;
using Microsoft.CmdPal.Core.ViewModels.Models;
using Microsoft.CommandPalette.Extensions;
namespace Microsoft.CmdPal.UI.ViewModels;

View File

@@ -3,7 +3,8 @@
// See the LICENSE file in the project root for more information.
using System.Collections.ObjectModel;
using Microsoft.CmdPal.UI.ViewModels.Models;
using Microsoft.CmdPal.Core.ViewModels;
using Microsoft.CmdPal.Core.ViewModels.Models;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
@@ -37,7 +38,7 @@ public partial class ContentTreeViewModel(ITreeContent _tree, WeakReference<IPag
var root = model.RootContent;
if (root != null)
{
RootContent = ContentPageViewModel.ViewModelFromContent(root, PageContext);
RootContent = ViewModelFromContent(root, PageContext);
RootContent?.InitializeProperties();
UpdateProperty(nameof(RootContent));
UpdateProperty(nameof(Root));
@@ -48,6 +49,20 @@ public partial class ContentTreeViewModel(ITreeContent _tree, WeakReference<IPag
model.ItemsChanged += Model_ItemsChanged;
}
// Theoretically, we should unify this with the one in CommandPalettePageViewModelFactory
// and maybe just have a ContentViewModelFactory or something
public ContentViewModel? ViewModelFromContent(IContent content, WeakReference<IPageContext> context)
{
ContentViewModel? viewModel = content switch
{
IFormContent form => new ContentFormViewModel(form, context),
IMarkdownContent markdown => new ContentMarkdownViewModel(markdown, context),
ITreeContent tree => new ContentTreeViewModel(tree, context),
_ => null,
};
return viewModel;
}
// TODO: Does this need to hop to a _different_ thread, so that we don't block the extension while we're fetching?
private void Model_ItemsChanged(object sender, IItemsChangedEventArgs args) => FetchContent();
@@ -78,7 +93,7 @@ public partial class ContentTreeViewModel(ITreeContent _tree, WeakReference<IPag
var root = model.RootContent;
if (root != null)
{
RootContent = ContentPageViewModel.ViewModelFromContent(root, PageContext);
RootContent = ViewModelFromContent(root, PageContext);
}
else
{
@@ -103,7 +118,7 @@ public partial class ContentTreeViewModel(ITreeContent _tree, WeakReference<IPag
foreach (var item in newItems)
{
var viewModel = ContentPageViewModel.ViewModelFromContent(item, PageContext);
var viewModel = ViewModelFromContent(item, PageContext);
if (viewModel != null)
{
viewModel.InitializeProperties();

View File

@@ -56,6 +56,7 @@
<ItemGroup>
<ProjectReference Include="..\Microsoft.CmdPal.Common\Microsoft.CmdPal.Common.csproj" />
<ProjectReference Include="..\Microsoft.CmdPal.Core.ViewModels\Microsoft.CmdPal.Core.ViewModels.csproj" />
<ProjectReference Include="..\extensionsdk\Microsoft.CommandPalette.Extensions.Toolkit\Microsoft.CommandPalette.Extensions.Toolkit.csproj" />
<ProjectReference Include="..\ext\Microsoft.CmdPal.Ext.Apps\Microsoft.CmdPal.Ext.Apps.csproj" />

View File

@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
@@ -12,7 +12,6 @@ using Windows.Win32;
using Windows.Win32.System.Com;
using WinRT;
// [assembly: System.Runtime.CompilerServices.DisableRuntimeMarshalling]
namespace Microsoft.CmdPal.UI.ViewModels.Models;
public class ExtensionWrapper : IExtensionWrapper

View File

@@ -6,7 +6,8 @@ using System.Diagnostics.CodeAnalysis;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Messaging;
using Microsoft.CmdPal.Common.Services;
using Microsoft.CmdPal.UI.ViewModels.Messages;
using Microsoft.CmdPal.Core.ViewModels;
using Microsoft.CmdPal.Core.ViewModels.Messages;
using Microsoft.CmdPal.UI.ViewModels.Properties;
using Microsoft.Extensions.DependencyInjection;

View File

@@ -10,7 +10,8 @@ using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using ManagedCommon;
using Microsoft.CmdPal.Common.Services;
using Microsoft.CmdPal.UI.ViewModels.Messages;
using Microsoft.CmdPal.Core.ViewModels;
using Microsoft.CmdPal.Core.ViewModels.Messages;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
using Microsoft.Extensions.DependencyInjection;

View File

@@ -6,7 +6,8 @@ using System.Collections.ObjectModel;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Messaging;
using ManagedCommon;
using Microsoft.CmdPal.UI.ViewModels.Messages;
using Microsoft.CmdPal.Core.ViewModels;
using Microsoft.CmdPal.Core.ViewModels.Messages;
using Microsoft.CmdPal.UI.ViewModels.Settings;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
@@ -254,7 +255,7 @@ public sealed partial class TopLevelViewModel : ObservableObject, IListItem
private void UpdateTags()
{
List<Tag> tags = new();
List<Tag> tags = [];
if (Hotkey != null)
{
@@ -341,4 +342,9 @@ public sealed partial class TopLevelViewModel : ObservableObject, IListItem
return false;
}
public PerformCommandMessage GetPerformCommandMessage()
{
return new PerformCommandMessage(this.CommandViewModel.Model, new Core.ViewModels.Models.ExtensionObject<IListItem>(this));
}
}

View File

@@ -5,6 +5,7 @@
using ManagedCommon;
using Microsoft.CmdPal.Common.Helpers;
using Microsoft.CmdPal.Common.Services;
using Microsoft.CmdPal.Core.ViewModels;
using Microsoft.CmdPal.Ext.Apps;
using Microsoft.CmdPal.Ext.Bookmarks;
using Microsoft.CmdPal.Ext.Calc;
@@ -70,6 +71,11 @@ public partial class App : Application
AppWindow?.Close();
Environment.Exit(0);
});
// Connect the PT logging to the core project's logging.
// This way, log statements from the core project will be captured by the PT logs
var logWrapper = new LogWrapper();
CoreLogger.InitializeLogger(logWrapper);
}
/// <summary>
@@ -145,10 +151,12 @@ public partial class App : Application
services.AddSingleton<TrayIconService>();
services.AddSingleton<IRootPageService, PowerToysRootPageService>();
services.AddSingleton<IAppHostService, PowerToysAppHostService>();
services.AddSingleton(new TelemetryForwarder());
// ViewModels
services.AddSingleton<ShellViewModel>();
services.AddSingleton<IPageViewModelFactoryService, CommandPalettePageViewModelFactory>();
return services.BuildServiceProvider();
}

View File

@@ -12,6 +12,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI"
xmlns:viewModels="using:Microsoft.CmdPal.UI.ViewModels"
xmlns:coreViewModels="using:Microsoft.CmdPal.Core.ViewModels"
Background="Transparent"
mc:Ignorable="d">
@@ -87,7 +88,7 @@
ItemsSource="{x:Bind CurrentPageViewModel.StatusMessages, Mode=OneWay}"
Layout="{StaticResource VerticalStackLayout}">
<ItemsRepeater.ItemTemplate>
<DataTemplate x:DataType="viewModels:StatusMessageViewModel">
<DataTemplate x:DataType="coreViewModels:StatusMessageViewModel">
<StackPanel
Grid.Row="0"
Margin="0"

View File

@@ -3,8 +3,8 @@
// See the LICENSE file in the project root for more information.
using CommunityToolkit.Mvvm.Messaging;
using Microsoft.CmdPal.UI.ViewModels;
using Microsoft.CmdPal.UI.ViewModels.Messages;
using Microsoft.CmdPal.Core.ViewModels;
using Microsoft.CmdPal.Core.ViewModels.Messages;
using Microsoft.CmdPal.UI.Views;
using Microsoft.UI.Input;
using Microsoft.UI.Xaml;

View File

@@ -12,7 +12,8 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:toolkit="using:CommunityToolkit.WinUI.Controls"
xmlns:ui="using:CommunityToolkit.WinUI"
xmlns:viewmodels="using:Microsoft.CmdPal.UI.ViewModels"
xmlns:viewModels="using:Microsoft.CmdPal.UI.ViewModels"
xmlns:coreViewModels="using:Microsoft.CmdPal.Core.ViewModels"
Background="Transparent"
mc:Ignorable="d">
@@ -27,7 +28,7 @@
Separator="{StaticResource SeparatorContextMenuViewModelTemplate}" />
<!-- Template for context items in the context item menu -->
<DataTemplate x:Key="DefaultContextMenuViewModelTemplate" x:DataType="viewmodels:CommandContextItemViewModel">
<DataTemplate x:Key="DefaultContextMenuViewModelTemplate" x:DataType="coreViewModels:CommandContextItemViewModel">
<Grid AutomationProperties.Name="{x:Bind Title}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="32" />
@@ -57,7 +58,7 @@
</DataTemplate>
<!-- Template for context items flagged as critical -->
<DataTemplate x:Key="CriticalContextMenuViewModelTemplate" x:DataType="viewmodels:CommandContextItemViewModel">
<DataTemplate x:Key="CriticalContextMenuViewModelTemplate" x:DataType="coreViewModels:CommandContextItemViewModel">
<Grid AutomationProperties.Name="{x:Bind Title}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="32" />
@@ -88,7 +89,7 @@
</DataTemplate>
<!-- Template for context item separators -->
<DataTemplate x:Key="SeparatorContextMenuViewModelTemplate" x:DataType="viewmodels:SeparatorContextItemViewModel">
<DataTemplate x:Key="SeparatorContextMenuViewModelTemplate" x:DataType="coreViewModels:SeparatorContextItemViewModel">
<Rectangle
Height="1"
Margin="-16,-12,-12,-12"

View File

@@ -2,17 +2,12 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Messaging;
using CommunityToolkit.WinUI;
using Microsoft.CmdPal.Ext.System;
using Microsoft.CmdPal.UI.ViewModels;
using Microsoft.CmdPal.UI.ViewModels.Messages;
using Microsoft.CmdPal.UI.Views;
using Microsoft.CmdPal.Core.ViewModels;
using Microsoft.CmdPal.Core.ViewModels.Messages;
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 Windows.System;
using Windows.UI.Core;

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.CmdPal.Core.ViewModels;
using Microsoft.CmdPal.UI.Deferred;
using Microsoft.CmdPal.UI.ViewModels;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;

View File

@@ -5,8 +5,8 @@
using System.Diagnostics;
using CommunityToolkit.Mvvm.Messaging;
using CommunityToolkit.WinUI;
using Microsoft.CmdPal.UI.ViewModels;
using Microsoft.CmdPal.UI.ViewModels.Messages;
using Microsoft.CmdPal.Core.ViewModels;
using Microsoft.CmdPal.Core.ViewModels.Messages;
using Microsoft.CmdPal.UI.Views;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Input;

Some files were not shown because too many files have changed in this diff Show More