From df4f6f19a21b4dcdd63a3418d7215cc8cfd56c4c Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 6 Feb 2026 06:35:21 -0600 Subject: [PATCH] This does at least work to have an invokable command --- .../CommandContextItemViewModel.cs | 12 +++- .../CommandItemViewModel.cs | 62 +++++++++++++++---- 2 files changed, 60 insertions(+), 14 deletions(-) diff --git a/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.ViewModels/CommandContextItemViewModel.cs b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.ViewModels/CommandContextItemViewModel.cs index bc07fca640..a12e8c911e 100644 --- a/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.ViewModels/CommandContextItemViewModel.cs +++ b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.ViewModels/CommandContextItemViewModel.cs @@ -5,16 +5,15 @@ using System.Diagnostics.CodeAnalysis; using Microsoft.CmdPal.Core.ViewModels.Models; using Microsoft.CommandPalette.Extensions; -using Microsoft.CommandPalette.Extensions.Toolkit; namespace Microsoft.CmdPal.Core.ViewModels; [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] -public partial class CommandContextItemViewModel(ICommandContextItem contextItem, WeakReference context) : CommandItemViewModel(new(contextItem), context), IContextItemViewModel +public partial class CommandContextItemViewModel : CommandItemViewModel, IContextItemViewModel { private readonly KeyChord nullKeyChord = new(0, 0, 0); - public new ExtensionObject Model { get; } = new(contextItem); + public new ExtensionObject Model { get; } public bool IsCritical { get; private set; } @@ -22,6 +21,13 @@ public partial class CommandContextItemViewModel(ICommandContextItem contextItem public bool HasRequestedShortcut => RequestedShortcut is not null && (RequestedShortcut.Value != nullKeyChord); + public CommandContextItemViewModel(ICommandContextItem contextItem, WeakReference context) + : base(new(contextItem), context) + { + Model = new(contextItem); + IsContextMenuItem = true; + } + public override void InitializeProperties() { if (IsInitialized) diff --git a/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.ViewModels/CommandItemViewModel.cs b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.ViewModels/CommandItemViewModel.cs index e01d4f3868..d2fd592b0a 100644 --- a/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.ViewModels/CommandItemViewModel.cs +++ b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.ViewModels/CommandItemViewModel.cs @@ -30,6 +30,8 @@ public partial class CommandItemViewModel : ExtensionObjectViewModel, ICommandBa protected bool IsSelectedInitialized => IsInErrorState || Initialized.HasFlag(InitializedState.SelectionInitialized); + protected bool IsContextMenuItem { get; init; } + public bool IsInErrorState => Initialized.HasFlag(InitializedState.Error); // These are properties that are "observable" from the extension object @@ -544,23 +546,24 @@ public partial class CommandItemViewModel : ExtensionObjectViewModel, ICommandBa results.Add(new SeparatorViewModel()); } } - - // MoreCommands = more - // .Select(item => - // { - // return item is ICommandContextItem contextItem ? new CommandContextItemViewModel(contextItem, PageContext) : new SeparatorViewModel(); - // }) - // .ToList(); } + // TODO! move to a factory or something, so that the UI layer is + // responsible for stealth-adding this pin command. if (PageContext.TryGetTarget(out var pageContext)) { - if (pageContext.ExtensionSupportsPinning) + // * The extension needs to support the GetCommandItem API to support pinning + // * We need to have an ID to pin it by + // * We don't want to show "Pin to Dock" on items that are already context menu items + if (pageContext.ExtensionSupportsPinning && + !string.IsNullOrEmpty(Command.Id) && + !IsContextMenuItem) { - // test: just add a bunch of separators - results.Add(new SeparatorViewModel()); - results.Add(new SeparatorViewModel()); results.Add(new SeparatorViewModel()); + var pinCommand = new PinToDockIten(this); + var pinCommandViewModel = new CommandContextItemViewModel(pinCommand, PageContext); + pinCommandViewModel.SlowInitializeProperties(); + results.Add(pinCommandViewModel); } } @@ -576,6 +579,43 @@ public partial class CommandItemViewModel : ExtensionObjectViewModel, ICommandBa .ToList() .ForEach(c => c.SafeCleanup()); } + + private sealed partial class PinToDockIten : CommandContextItem + { + private static readonly PinToDockCommand PinCommand = new(); + private readonly CommandItemViewModel _owner; + + internal CommandItemViewModel Owner => _owner; + + public PinToDockIten(CommandItemViewModel owner) + : base(PinCommand) + { + _owner = owner; + } + } + + private sealed partial class PinToDockCommand : InvokableCommand + { + public override string Name => "Toggle pinned to dock"; // TODO!LOC + + public PinToDockCommand() + { + } + + public override ICommandResult Invoke(object? sender) + { + if (sender is PinToDockIten contextItemViewModel) + { + // if (contextItemViewModel.PageContext.TryGetTarget(out var pageContext)) + // { + // pageContext.TogglePinnedToDock(contextItemViewModel); + // } + return CommandResult.ShowToast($"Attempted to toggle pin to dock for {contextItemViewModel.Owner.Title}"); + } + + return CommandResult.ShowToast($"Failed to get sender for command"); + } + } } [Flags]