diff --git a/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Helpers/PinnedDockItem.cs b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Helpers/PinnedDockItem.cs
new file mode 100644
index 0000000000..ca1ce06c2c
--- /dev/null
+++ b/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Helpers/PinnedDockItem.cs
@@ -0,0 +1,23 @@
+// 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;
+using Microsoft.CommandPalette.Extensions.Toolkit;
+
+namespace Microsoft.CmdPal.Core.Common.Helpers;
+
+public partial class PinnedDockItem : WrappedDockItem
+{
+ public override string Title => $"{base.Title} ({Properties.Resources.PinnedItemSuffix})";
+
+ public PinnedDockItem(ICommand command)
+ : base(command, command.Name)
+ {
+ }
+
+ public PinnedDockItem(ICommandItem item, string id)
+ : base(item, id, item.Title)
+ {
+ }
+}
diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/CommandProviderWrapper.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/CommandProviderWrapper.cs
index 21e47ca033..b0b6f8c217 100644
--- a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/CommandProviderWrapper.cs
+++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/CommandProviderWrapper.cs
@@ -163,20 +163,27 @@ public sealed class CommandProviderWrapper
UnsafePreCacheApiAdditions(two);
}
- if (model is IExtendedAttributesProvider iHaveProperties)
+ // if (model is IExtendedAttributesProvider iHaveProperties)
+ if (model is ICommandProvider3 supportsDockBands)
{
- var props = iHaveProperties.GetProperties();
- var hasBands = props.TryGetValue("DockBands", out var obj);
- if (hasBands && obj is not null)
+ // var props = iHaveProperties.GetProperties();
+ // var hasBands = props.TryGetValue("DockBands", out var obj);
+ // if (hasBands && obj is not null)
+ // {
+ // // CoreLogger.LogDebug($"Found bands object on {DisplayName} ({ProviderId}) ");
+ // // var bands = (ICommandItem[])obj;
+ // var bands = obj as ICommandItem[];
+ // if (bands is not null)
+ // {
+ // CoreLogger.LogDebug($"Found {bands.Length} bands on {DisplayName} ({ProviderId}) ");
+ // dockBands = bands;
+ // }
+ // }
+ var bands = supportsDockBands.GetDockBands();
+ if (bands is not null)
{
- // CoreLogger.LogDebug($"Found bands object on {DisplayName} ({ProviderId}) ");
- // var bands = (ICommandItem[])obj;
- var bands = obj as ICommandItem[];
- if (bands is not null)
- {
- CoreLogger.LogDebug($"Found {bands.Length} bands on {DisplayName} ({ProviderId}) ");
- dockBands = bands;
- }
+ CoreLogger.LogDebug($"Found {bands.Length} bands on {DisplayName} ({ProviderId}) ");
+ dockBands = bands;
}
}
diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Commands/BuiltInsCommandProvider.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Commands/BuiltInsCommandProvider.cs
index 54b124ded7..aef3bdfd61 100644
--- a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Commands/BuiltInsCommandProvider.cs
+++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Commands/BuiltInsCommandProvider.cs
@@ -13,7 +13,7 @@ namespace Microsoft.CmdPal.UI.ViewModels.BuiltinCommands;
///
/// Built-in Provider for a top-level command which can quit the application. Invokes the , which sends a .
///
-public sealed partial class BuiltInsCommandProvider : CommandProvider, IExtendedAttributesProvider
+public sealed partial class BuiltInsCommandProvider : CommandProvider
{
private readonly OpenSettingsCommand openSettings = new();
private readonly QuitCommand quitCommand = new();
@@ -45,16 +45,13 @@ public sealed partial class BuiltInsCommandProvider : CommandProvider, IExtended
_rootPageService = rootPageService;
}
- public IDictionary GetProperties()
+ public override ICommandItem[]? GetDockBands()
{
var rootPage = _rootPageService.GetRootPage();
List bandItems = new();
bandItems.Add(new WrappedDockItem(rootPage, Properties.Resources.builtin_command_palette_title));
- return new PropertySet()
- {
- { "DockBands", bandItems.ToArray() },
- };
+ return bandItems.ToArray();
}
public override void InitializeWithHost(IExtensionHost host) => BuiltinsExtensionHost.Instance.Initialize(host);
diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Dock/DockViewModel.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Dock/DockViewModel.cs
index da5dc2f359..45f969fd57 100644
--- a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Dock/DockViewModel.cs
+++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/Dock/DockViewModel.cs
@@ -67,12 +67,9 @@ public sealed partial class DockViewModel : IDisposable,
var commandId = band.Id;
var topLevelCommand = _topLevelCommandManager.LookupDockBand(commandId);
- // TODO! temp hack: fallback to looking up a top-level command
- // remove this once the API is added
if (topLevelCommand is null)
{
- Logger.LogWarning($"Temporary fallback to loading top-level command '{commandId}'");
- topLevelCommand = _topLevelCommandManager.LookupCommand(commandId);
+ Logger.LogWarning($"Failed to find band {commandId}");
}
if (topLevelCommand is not null)
diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.TimeDate/TimeDateCommandsProvider.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.TimeDate/TimeDateCommandsProvider.cs
index febaa3c6d0..2bd217838b 100644
--- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.TimeDate/TimeDateCommandsProvider.cs
+++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.TimeDate/TimeDateCommandsProvider.cs
@@ -3,7 +3,6 @@
// See the LICENSE file in the project root for more information.
using System;
-using System.Collections.Generic;
using System.Globalization;
using System.Text;
using Microsoft.CmdPal.Core.Common.Helpers;
@@ -11,11 +10,10 @@ using Microsoft.CmdPal.Ext.TimeDate.Helpers;
using Microsoft.CmdPal.Ext.TimeDate.Pages;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
-using Windows.Foundation.Collections;
namespace Microsoft.CmdPal.Ext.TimeDate;
-public sealed partial class TimeDateCommandsProvider : CommandProvider, IExtendedAttributesProvider
+public sealed partial class TimeDateCommandsProvider : CommandProvider
{
private readonly CommandItem _command;
private static readonly SettingsManager _settingsManager = new SettingsManager();
@@ -56,17 +54,14 @@ public sealed partial class TimeDateCommandsProvider : CommandProvider, IExtende
public override IFallbackCommandItem[] FallbackCommands() => [_fallbackTimeDateItem];
- public IDictionary GetProperties()
+ public override ICommandItem[] GetDockBands()
{
var wrappedBand = new WrappedDockItem(
_bandItem,
"com.microsoft.cmdpal.timedate.dockband",
Resources.Microsoft_plugin_timedate_dock_band_title);
- return new PropertySet()
- {
- { "DockBands", new ICommandItem[] { wrappedBand } },
- };
+ return new ICommandItem[] { wrappedBand };
}
}
#pragma warning disable SA1402 // File may only contain a single type
diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowWalker/WindowWalkerCommandsProvider.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowWalker/WindowWalkerCommandsProvider.cs
index ab59228f07..7f5460ab72 100644
--- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowWalker/WindowWalkerCommandsProvider.cs
+++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WindowWalker/WindowWalkerCommandsProvider.cs
@@ -1,15 +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;
-using System.Collections.Generic;
using Microsoft.CmdPal.Ext.WindowWalker.Helpers;
using Microsoft.CmdPal.Ext.WindowWalker.Pages;
using Microsoft.CmdPal.Ext.WindowWalker.Properties;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
-using Windows.Foundation.Collections;
using Windows.Win32;
using Windows.Win32.Foundation;
using Windows.Win32.UI.Accessibility;
@@ -17,7 +15,7 @@ using Windows.Win32.UI.WindowsAndMessaging;
namespace Microsoft.CmdPal.Ext.WindowWalker;
-public partial class WindowWalkerCommandsProvider : CommandProvider, IExtendedAttributesProvider
+public partial class WindowWalkerCommandsProvider : CommandProvider
{
private readonly CommandItem _windowWalkerPageItem;
private readonly CommandItem _bandItem;
@@ -45,12 +43,9 @@ public partial class WindowWalkerCommandsProvider : CommandProvider, IExtendedAt
public override ICommandItem[] TopLevelCommands() => [_windowWalkerPageItem];
- public IDictionary GetProperties()
+ public override ICommandItem[]? GetDockBands()
{
- return new PropertySet()
- {
- { "DockBands", new ICommandItem[] { _bandItem } },
- };
+ return new ICommandItem[] { _bandItem };
}
}
diff --git a/src/modules/cmdpal/ext/SamplePagesExtension/SampleButtonsDockBand.cs b/src/modules/cmdpal/ext/SamplePagesExtension/SampleButtonsDockBand.cs
new file mode 100644
index 0000000000..c7012b2d25
--- /dev/null
+++ b/src/modules/cmdpal/ext/SamplePagesExtension/SampleButtonsDockBand.cs
@@ -0,0 +1,30 @@
+// 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.Generic;
+using Microsoft.CommandPalette.Extensions;
+using Microsoft.CommandPalette.Extensions.Toolkit;
+
+namespace SamplePagesExtension;
+
+///
+/// A sample dock band with multiple buttons.
+/// Each button shows a toast message when clicked.
+///
+internal sealed partial class SampleButtonsDockBand : WrappedDockItem
+{
+ public SampleButtonsDockBand()
+ : base([], "com.microsoft.cmdpal.samples.buttons_band", "Sample Buttons Band")
+ {
+ ListItem[] buttons = [
+ new(new ShowToastCommand("Button 1")) { Title = "1" },
+ new(new ShowToastCommand("Button B")) { Icon = new IconInfo("\uF094") }, // B button
+ new(new ShowToastCommand("Button 3")) { Title = "Items have Icons &", Icon = new IconInfo("\uED1E"), Subtitle = "titles & subtitles" }, // Subtitles
+ ];
+ Icon = new IconInfo("\uEECA"); // ButtonView2
+ Items = buttons;
+ }
+}
+
+#pragma warning restore SA1402 // File may only contain a single type
diff --git a/src/modules/cmdpal/ext/SamplePagesExtension/SampleDockBand.cs b/src/modules/cmdpal/ext/SamplePagesExtension/SampleDockBand.cs
new file mode 100644
index 0000000000..b95a50ab69
--- /dev/null
+++ b/src/modules/cmdpal/ext/SamplePagesExtension/SampleDockBand.cs
@@ -0,0 +1,22 @@
+// 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.Toolkit;
+
+namespace SamplePagesExtension;
+#pragma warning disable SA1402 // File may only contain a single type
+
+///
+/// A sample dock band with one button.
+/// Clicking on this button will open the palette to the samples list page
+///
+internal sealed partial class SampleDockBand : WrappedDockItem
+{
+ public SampleDockBand()
+ : base(new SamplesListPage(), "Command Palette Samples")
+ {
+ }
+}
+
+#pragma warning restore SA1402 // File may only contain a single type
diff --git a/src/modules/cmdpal/ext/SamplePagesExtension/SamplePagesCommandsProvider.cs b/src/modules/cmdpal/ext/SamplePagesExtension/SamplePagesCommandsProvider.cs
index e500c25d8d..d24d4964d3 100644
--- a/src/modules/cmdpal/ext/SamplePagesExtension/SamplePagesCommandsProvider.cs
+++ b/src/modules/cmdpal/ext/SamplePagesExtension/SamplePagesCommandsProvider.cs
@@ -2,6 +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.Collections.Generic;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
@@ -27,4 +28,15 @@ public partial class SamplePagesCommandsProvider : CommandProvider
{
return _commands;
}
+
+ public override ICommandItem[] GetDockBands()
+ {
+ List bands = new()
+ {
+ new SampleDockBand(),
+ new SampleButtonsDockBand(),
+ };
+
+ return bands.ToArray();
+ }
}
diff --git a/src/modules/cmdpal/ext/SamplePagesExtension/ShowToastCommand.cs b/src/modules/cmdpal/ext/SamplePagesExtension/ShowToastCommand.cs
new file mode 100644
index 0000000000..67bbd30fc5
--- /dev/null
+++ b/src/modules/cmdpal/ext/SamplePagesExtension/ShowToastCommand.cs
@@ -0,0 +1,19 @@
+// 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.Generic;
+using Microsoft.CommandPalette.Extensions;
+using Microsoft.CommandPalette.Extensions.Toolkit;
+
+namespace SamplePagesExtension;
+
+internal sealed partial class ShowToastCommand(string message) : InvokableCommand
+{
+ public override ICommandResult Invoke()
+ {
+ return CommandResult.ShowToast(message);
+ }
+}
+
+#pragma warning restore SA1402 // File may only contain a single type
diff --git a/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/CommandProvider.cs b/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/CommandProvider.cs
index ca64c87b23..79f952dbe7 100644
--- a/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/CommandProvider.cs
+++ b/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/CommandProvider.cs
@@ -6,7 +6,10 @@ using Windows.Foundation;
namespace Microsoft.CommandPalette.Extensions.Toolkit;
-public abstract partial class CommandProvider : ICommandProvider, ICommandProvider2
+public abstract partial class CommandProvider :
+ ICommandProvider,
+ ICommandProvider2,
+ ICommandProvider3
{
public virtual string Id { get; protected set; } = string.Empty;
@@ -48,6 +51,11 @@ public abstract partial class CommandProvider : ICommandProvider, ICommandProvid
}
}
+ public virtual ICommandItem[]? GetDockBands()
+ {
+ return null;
+ }
+
///
/// This is used to manually populate the WinRT type cache in CmdPal with
/// any interfaces that might not follow a straight linear path of requires.
diff --git a/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Helpers/WrappedDockItem.cs b/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Dock/WrappedDockItem.cs
similarity index 50%
rename from src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Helpers/WrappedDockItem.cs
rename to src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Dock/WrappedDockItem.cs
index 6ad2291f6a..8d0d8aecfe 100644
--- a/src/modules/cmdpal/Core/Microsoft.CmdPal.Core.Common/Helpers/WrappedDockItem.cs
+++ b/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions.Toolkit/Dock/WrappedDockItem.cs
@@ -2,10 +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.CommandPalette.Extensions;
-using Microsoft.CommandPalette.Extensions.Toolkit;
-
-namespace Microsoft.CmdPal.Core.Common.Helpers;
+namespace Microsoft.CommandPalette.Extensions.Toolkit;
#pragma warning disable SA1402 // File may only contain a single type
@@ -15,14 +12,19 @@ public partial class WrappedDockItem : CommandItem
public override IIconInfo? Icon => _icon;
+ public override ICommand? Command => _backingList;
+
private readonly string _itemTitle;
private readonly IIconInfo? _icon;
+ private readonly WrappedDockList _backingList;
+
+ public IListItem[] Items { get => _backingList.GetItems(); set => _backingList.SetItems(value); }
public WrappedDockItem(
ICommand command,
string displayTitle)
{
- Command = new WrappedDockList(command);
+ _backingList = new WrappedDockList(command);
_itemTitle = string.IsNullOrEmpty(displayTitle) ? command.Name : displayTitle;
_icon = command.Icon;
}
@@ -32,55 +34,44 @@ public partial class WrappedDockItem : CommandItem
string id,
string displayTitle)
{
- Command = new WrappedDockList(item, id);
+ _backingList = new WrappedDockList(item, id);
_itemTitle = string.IsNullOrEmpty(displayTitle) ? item.Title : displayTitle;
_icon = item.Icon;
}
-}
-public partial class PinnedDockItem : WrappedDockItem
-{
- public override string Title => $"{base.Title} ({Properties.Resources.PinnedItemSuffix})";
-
- public PinnedDockItem(ICommand command)
- : base(command, command.Name)
- {
- }
-
- public PinnedDockItem(ICommandItem item, string id)
- : base(item, id, item.Title)
+ public WrappedDockItem(IListItem[] items, string id, string displayTitle)
{
+ _backingList = new WrappedDockList(items, id, displayTitle);
+ _itemTitle = displayTitle;
}
}
public partial class WrappedDockList : ListPage
{
- public override string Name => _command.Name;
-
private string _id;
public override string Id => _id;
- private ICommand _command;
- private IListItem[] _items;
+ // private ICommand _command;
+ private List _items;
public WrappedDockList(ICommand command)
{
- _command = command;
- _items = new IListItem[] { new ListItem(command) };
- Name = _command.Name;
- _id = _command.Id;
+ // _command = command;
+ _items = new() { new ListItem(command) };
+ Name = command.Name;
+ _id = command.Id;
}
public WrappedDockList(ICommandItem item, string id)
{
- _command = item.Command;
+ var command = item.Command;
// TODO! This isn't _totally correct, because the wrapping item will not
// listen for property changes on the inner item.
- _items = new IListItem[]
+ _items = new()
{
- new ListItem(_command)
+ new ListItem(command)
{
Title = item.Title,
Subtitle = item.Subtitle,
@@ -88,13 +79,45 @@ public partial class WrappedDockList : ListPage
MoreCommands = item.MoreCommands,
},
};
- Name = _command.Name;
- _id = string.IsNullOrEmpty(id) ? _command.Id : id;
+ Name = command.Name;
+ _id = string.IsNullOrEmpty(id) ? command.Id : id;
+ }
+
+ public WrappedDockList(IListItem[] items, string id, string name)
+ {
+ _items = new(items);
+ Name = name;
+ _id = id;
+ }
+
+ public WrappedDockList(ICommand[] items, string id, string name)
+ {
+ _items = new();
+ foreach (var item in items)
+ {
+ _items.Add(new ListItem(item));
+ }
+
+ Name = name;
+ _id = id;
}
public override IListItem[] GetItems()
{
- return _items;
+ return _items.ToArray();
+ }
+
+ internal void SetItems(IListItem[]? newItems)
+ {
+ if (newItems == null)
+ {
+ _items = [];
+ RaiseItemsChanged(0);
+ return;
+ }
+
+ ListHelpers.InPlaceUpdateList(_items, newItems);
+ RaiseItemsChanged(_items.Count);
}
}
diff --git a/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions/Microsoft.CommandPalette.Extensions.idl b/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions/Microsoft.CommandPalette.Extensions.idl
index 68fd928955..f9f515a0ce 100644
--- a/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions/Microsoft.CommandPalette.Extensions.idl
+++ b/src/modules/cmdpal/extensionsdk/Microsoft.CommandPalette.Extensions/Microsoft.CommandPalette.Extensions.idl
@@ -391,6 +391,11 @@ namespace Microsoft.CommandPalette.Extensions
{
Object[] GetApiExtensionStubs();
};
-
+
+ [contract(Microsoft.CommandPalette.Extensions.ExtensionsContract, 1)]
+ interface ICommandProvider3 requires ICommandProvider2
+ {
+ ICommandItem[] GetDockBands();
+ };
}