From 2efdbb6cbde0d152080f972c9ec4444ddabda5c4 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Thu, 9 Jan 2025 16:30:25 -0600 Subject: [PATCH] Allow both light and dark icons (#286) This adds one _last_ change to the API to allow apps to specify different icons for light and dark mode. If it's important to an app to specify different icons for light vs dark mode, then `IconInfo` is exactly what you want to use. It contains _two_ `IconDataType`s, for two different icons. Simple as that. And to keep things even easier, I slapped on a `IconInfo(string)` constructor, so that you can easily build a `IconInfo` with both icons set to the same string. Especially useful for font icons, which we're using everywhere already. That allows almost all the extensions to have _no code change_ here, so that's super! Some of the places where we were evaluating if an icon existed or not - that needs to move into the view. `ShellPage.xaml.cs` does one variant of that already for `IDetails.HeroImage`. The view is the only part of the app that knows what the theme is. Closes #78 --- .../Helpers/ServiceHelper.cs | 48 ++++------- .../CommandItemViewModel.cs | 8 +- .../CommandProviderWrapper.cs | 2 +- .../DetailsViewModel.cs | 5 +- .../PageViewModel.cs | 2 +- .../ProviderSettingsViewModel.cs | 2 +- .../TagViewModel.cs | 5 +- .../TopLevelCommandWrapper.cs | 2 +- .../Microsoft.CmdPal.UI/Controls/IconBox.cs | 5 +- .../Controls/SourceRequestedEventArgs.cs | 5 +- .../ExtViews/IconCacheService.cs | 6 +- .../Helpers/IconCacheProvider.cs | 11 ++- .../cmdpal/Microsoft.CmdPal.UI/ShellPage.xaml | 3 +- .../Microsoft.CmdPal.UI/ShellPage.xaml.cs | 36 +++++++- .../WindowsCommandPalette/ActionViewModel.cs | 2 +- .../ContextItemViewModel.cs | 2 +- .../ListItemViewModel.cs | 4 +- .../Microsoft.CmdPal.UI.Poc.csproj | 1 - .../WindowsCommandPalette/TagViewModel.cs | 6 +- .../Views/CommandAlias.cs | 15 ---- .../Views/DetailsViewModel.xaml.cs | 4 +- .../Views/MainViewModel.xaml.cs | 2 - .../initial-sdk-spec/generate-interface.ps1 | 15 +++- .../doc/initial-sdk-spec/initial-sdk-spec.md | 83 ++++++++++++------- .../Command.cs | 4 +- .../CommandItem.cs | 4 +- .../CommandProvider.cs | 4 +- .../Details.cs | 4 +- .../Filter.cs | 2 +- .../Tag.cs | 4 +- .../Microsoft.CmdPal.Extensions/IconData.cpp | 5 ++ .../Microsoft.CmdPal.Extensions/IconData.h | 52 ++++++++++++ .../IconDataType.cpp | 4 - .../IconDataType.h | 30 ------- .../Microsoft.CmdPal.Extensions.idl | 27 ++++-- .../Microsoft.CmdPal.Extensions.vcxproj | 4 +- 36 files changed, 244 insertions(+), 174 deletions(-) create mode 100644 src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions/IconData.cpp create mode 100644 src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions/IconData.h delete mode 100644 src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions/IconDataType.cpp delete mode 100644 src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions/IconDataType.h diff --git a/src/modules/cmdpal/Exts/Microsoft.CmdPal.Ext.WindowsServices/Helpers/ServiceHelper.cs b/src/modules/cmdpal/Exts/Microsoft.CmdPal.Ext.WindowsServices/Helpers/ServiceHelper.cs index 93f174821b..f7a1731b1d 100644 --- a/src/modules/cmdpal/Exts/Microsoft.CmdPal.Ext.WindowsServices/Helpers/ServiceHelper.cs +++ b/src/modules/cmdpal/Exts/Microsoft.CmdPal.Ext.WindowsServices/Helpers/ServiceHelper.cs @@ -64,7 +64,7 @@ public static class ServiceHelper ]; } - IconDataType icon = new("\U0001f7e2"); // unicode LARGE GREEN CIRCLE + IconInfo icon = new("\U0001f7e2"); // unicode LARGE GREEN CIRCLE switch (s.Status) { case ServiceControllerStatus.Stopped: @@ -191,15 +191,13 @@ public static class ServiceHelper { return Resources.wox_plugin_service_running; } - else if (status == ServiceControllerStatus.ContinuePending) - { - return Resources.wox_plugin_service_continue_pending; - } else { - return status == ServiceControllerStatus.PausePending - ? Resources.wox_plugin_service_pause_pending - : status == ServiceControllerStatus.Paused ? Resources.wox_plugin_service_paused : status.ToString(); + return status == ServiceControllerStatus.ContinuePending + ? Resources.wox_plugin_service_continue_pending + : status == ServiceControllerStatus.PausePending + ? Resources.wox_plugin_service_pause_pending + : status == ServiceControllerStatus.Paused ? Resources.wox_plugin_service_paused : status.ToString(); } } @@ -213,44 +211,32 @@ public static class ServiceHelper { return Resources.wox_plugin_service_start_mode_system; } - else if (startMode == ServiceStartMode.Automatic) - { - return !IsDelayedStart(serviceName) ? Resources.wox_plugin_service_start_mode_automatic : Resources.wox_plugin_service_start_mode_automaticDelayed; - } else { - return startMode == ServiceStartMode.Manual - ? Resources.wox_plugin_service_start_mode_manual - : startMode == ServiceStartMode.Disabled ? Resources.wox_plugin_service_start_mode_disabled : startMode.ToString(); + return startMode == ServiceStartMode.Automatic + ? !IsDelayedStart(serviceName) ? Resources.wox_plugin_service_start_mode_automatic : Resources.wox_plugin_service_start_mode_automaticDelayed + : startMode == ServiceStartMode.Manual + ? Resources.wox_plugin_service_start_mode_manual + : startMode == ServiceStartMode.Disabled ? Resources.wox_plugin_service_start_mode_disabled : startMode.ToString(); } } private static string GetLocalizedMessage(Action action) { - if (action == Action.Start) - { - return Resources.wox_plugin_service_started_notification; - } - else - { - return action == Action.Stop + return action == Action.Start + ? Resources.wox_plugin_service_started_notification + : action == Action.Stop ? Resources.wox_plugin_service_stopped_notification : action == Action.Restart ? Resources.wox_plugin_service_restarted_notification : string.Empty; - } } private static string GetLocalizedErrorMessage(Action action) { - if (action == Action.Start) - { - return Resources.wox_plugin_service_start_error_notification; - } - else - { - return action == Action.Stop + return action == Action.Start + ? Resources.wox_plugin_service_start_error_notification + : action == Action.Stop ? Resources.wox_plugin_service_stop_error_notification : action == Action.Restart ? Resources.wox_plugin_service_restart_error_notification : string.Empty; - } } private static bool IsDelayedStart(string serviceName) diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/CommandItemViewModel.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/CommandItemViewModel.cs index 88fd390816..01afe7de98 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/CommandItemViewModel.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/CommandItemViewModel.cs @@ -25,7 +25,7 @@ public partial class CommandItemViewModel : ExtensionObjectViewModel public string Subtitle { get; private set; } = string.Empty; - public IconDataType Icon { get; private set; } = new(string.Empty); + public IconInfo Icon { get; private set; } = new(string.Empty); public ExtensionObject Command { get; private set; } = new(null); @@ -81,9 +81,7 @@ public partial class CommandItemViewModel : ExtensionObjectViewModel Subtitle = model.Subtitle; var listIcon = model.Icon; - Icon = !string.IsNullOrEmpty(listIcon.Icon) ? - listIcon : - Command.Unsafe!.Icon; + Icon = listIcon ?? Command.Unsafe!.Icon; var more = model.MoreCommands; if (more != null) @@ -171,7 +169,7 @@ public partial class CommandItemViewModel : ExtensionObjectViewModel break; case nameof(Icon): var listIcon = model.Icon; - Icon = !string.IsNullOrEmpty(listIcon.Icon) ? listIcon : Command.Unsafe!.Icon; + Icon = listIcon != null ? listIcon : Command.Unsafe!.Icon; break; // TODO! MoreCommands array, which needs to also raise HasMoreCommands diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/CommandProviderWrapper.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/CommandProviderWrapper.cs index e221e25eea..65843d29b0 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/CommandProviderWrapper.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/CommandProviderWrapper.cs @@ -28,7 +28,7 @@ public sealed class CommandProviderWrapper public string DisplayName { get; private set; } = string.Empty; - public IconDataType Icon { get; private set; } = new(string.Empty); + public IconInfo Icon { get; private set; } = new(string.Empty); public string ProviderId => $"{extensionWrapper?.PackageFamilyName ?? string.Empty}/{Id}"; diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/DetailsViewModel.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/DetailsViewModel.cs index e1fe6a5338..66622411f6 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/DetailsViewModel.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/DetailsViewModel.cs @@ -13,9 +13,7 @@ public partial class DetailsViewModel(IDetails _details, IPageContext context) : // Remember - "observable" properties from the model (via PropChanged) // cannot be marked [ObservableProperty] - public IconDataType HeroImage { get; private set; } = new(string.Empty); - - public bool HasHeroImage => !string.IsNullOrEmpty(HeroImage.Icon) || HeroImage.Data != null; + public IconInfo HeroImage { get; private set; } = new(string.Empty); // TODO: Metadata is an array of IDetailsElement, // where IDetailsElement = {IDetailsTags, IDetailsLink, IDetailsSeparator} @@ -38,6 +36,5 @@ public partial class DetailsViewModel(IDetails _details, IPageContext context) : UpdateProperty(nameof(Title)); UpdateProperty(nameof(Body)); UpdateProperty(nameof(HeroImage)); - UpdateProperty(nameof(HasHeroImage)); } } diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/PageViewModel.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/PageViewModel.cs index 7dbb4630bb..a760c0ecb0 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/PageViewModel.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/PageViewModel.cs @@ -45,7 +45,7 @@ public partial class PageViewModel : ExtensionObjectViewModel, IPageContext // `IsLoading` property as a combo of this value and `IsInitialized` public bool ModelIsLoading { get; protected set; } = true; - public IconDataType Icon { get; protected set; } = new(string.Empty); + public IconInfo Icon { get; protected set; } = new(string.Empty); public PageViewModel(IPage? model, TaskScheduler scheduler) : base(null) diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/ProviderSettingsViewModel.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/ProviderSettingsViewModel.cs index f80eb2e01a..7372414f09 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/ProviderSettingsViewModel.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/ProviderSettingsViewModel.cs @@ -13,7 +13,7 @@ public partial class ProviderSettingsViewModel(CommandProviderWrapper _provider, public string ExtensionName => _provider.Extension?.ExtensionDisplayName ?? "Built-in"; - public IconDataType Icon => _provider.Icon; + public IconInfo Icon => _provider.Icon; public bool IsEnabled { diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/TagViewModel.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/TagViewModel.cs index ffc50e0cc3..e6152b8f02 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/TagViewModel.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/TagViewModel.cs @@ -21,9 +21,10 @@ public partial class TagViewModel(ITag _tag, IPageContext context) : ExtensionOb public OptionalColor Background { get; private set; } - public IconDataType Icon { get; private set; } = new(string.Empty); + public IconInfo Icon { get; private set; } = new(string.Empty); - public bool HasIcon => !string.IsNullOrEmpty(Icon.Icon); + // TODO Terrible. When we redo the icons in tags, make this something the view exposes + public bool HasIcon => !string.IsNullOrEmpty(Icon.Light.Icon); public ExtensionObject Command { get; private set; } = new(null); diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/TopLevelCommandWrapper.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/TopLevelCommandWrapper.cs index 7cb0042fc0..3d525fdcb7 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/TopLevelCommandWrapper.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI.ViewModels/TopLevelCommandWrapper.cs @@ -46,7 +46,7 @@ public partial class TopLevelCommandWrapper : ListItem Title = model.Title; Subtitle = model.Subtitle; - Icon = new(model.Icon.Icon); + Icon = model.Icon; MoreCommands = model.MoreCommands; model.PropChanged += Model_PropChanged; diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/IconBox.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/IconBox.cs index fd95c264f3..aa694aac0d 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/IconBox.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/IconBox.cs @@ -92,7 +92,8 @@ public partial class IconBox : ContentControl // _ = @this._queue.EnqueueAsync(() => @this._queue.TryEnqueue(new(() => { - var eventArgs = new SourceRequestedEventArgs(e.NewValue); + var requestedTheme = @this.ActualTheme; + var eventArgs = new SourceRequestedEventArgs(e.NewValue, requestedTheme); if (@this.SourceRequested != null) { @@ -110,7 +111,7 @@ public partial class IconBox : ContentControl // Segoe icons, then let's give the icon some extra space @this.Padding = new Thickness(0); - if (eventArgs.Key is IconDataType iconData && + if (eventArgs.Key is IconData iconData && @this.Source is FontIconSource) { if (!string.IsNullOrEmpty(iconData.Icon) && iconData.Icon.Length <= 2) diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/SourceRequestedEventArgs.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/SourceRequestedEventArgs.cs index f7a2015d67..670bf13a7a 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/SourceRequestedEventArgs.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/SourceRequestedEventArgs.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using CommunityToolkit.Common.Deferred; +using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; namespace Microsoft.CmdPal.UI.Controls; @@ -10,9 +11,11 @@ namespace Microsoft.CmdPal.UI.Controls; /// /// See event. /// -public class SourceRequestedEventArgs(object? key) : DeferredEventArgs +public class SourceRequestedEventArgs(object? key, ElementTheme requestedTheme) : DeferredEventArgs { public object? Key { get; private set; } = key; public IconSource? Value { get; set; } + + public ElementTheme Theme => requestedTheme; } diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/ExtViews/IconCacheService.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI/ExtViews/IconCacheService.cs index 5af4d4c806..158f658df3 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/ExtViews/IconCacheService.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/ExtViews/IconCacheService.cs @@ -13,14 +13,14 @@ namespace Microsoft.CmdPal.UI.ExtViews; public sealed class IconCacheService(DispatcherQueue dispatcherQueue) { - public Task GetIconSource(IconDataType icon) => + public Task GetIconSource(IconData icon) => // todo: actually implement a cache of some sort IconToSource(icon); - private async Task IconToSource(IconDataType icon) + private async Task IconToSource(IconData icon) { - // bodgy: apparently IconDataType, despite being a struct, doesn't get + // bodgy: apparently IconData, despite being a struct, doesn't get // MarshalByValue'd into our process. What's even the point then? try { diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/Helpers/IconCacheProvider.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI/Helpers/IconCacheProvider.cs index 07c4966486..aec6cd5fdd 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/Helpers/IconCacheProvider.cs +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/Helpers/IconCacheProvider.cs @@ -24,12 +24,21 @@ public static partial class IconCacheProvider return; } - if (args.Key is IconDataType iconData) + if (args.Key is IconData iconData) { var deferral = args.GetDeferral(); args.Value = await IconService.GetIconSource(iconData); + deferral.Complete(); + } + else if (args.Key is IconInfo iconInfo) + { + var deferral = args.GetDeferral(); + + var data = args.Theme == Microsoft.UI.Xaml.ElementTheme.Dark ? iconInfo.Dark : iconInfo.Light; + args.Value = await IconService.GetIconSource(data); + deferral.Complete(); } } diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/ShellPage.xaml b/src/modules/cmdpal/Microsoft.CmdPal.UI/ShellPage.xaml index 9470973a64..d58577c3ca 100644 --- a/src/modules/cmdpal/Microsoft.CmdPal.UI/ShellPage.xaml +++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/ShellPage.xaml @@ -168,10 +168,9 @@ x:Name="HeroImageBorder" Width="64" Height="64" - x:Load="{x:Bind IsLoaded, Mode=OneWay}" SourceKey="{x:Bind ViewModel.Details.HeroImage, Mode=OneWay}" SourceRequested="{x:Bind help:IconCacheProvider.SourceRequested}" - Visibility="{x:Bind ViewModel.Details.HasHeroImage, Mode=OneWay}" /> + Visibility="{x:Bind HasHeroImage, Mode=OneWay}" /> , IRecipient, IRecipient, - IRecipient + IRecipient, + INotifyPropertyChanged { private readonly DispatcherQueue _queue = DispatcherQueue.GetForCurrentThread(); @@ -37,7 +39,8 @@ public sealed partial class ShellPage : public ShellViewModel ViewModel { get; private set; } = App.Current.Services.GetService()!; - // private readonly SettingsViewModel _settingsViewModel; + public event PropertyChangedEventHandler? PropertyChanged; + public ShellPage() { this.InitializeComponent(); @@ -229,6 +232,10 @@ public sealed partial class ShellPage : { ViewModel.Details = message.Details; ViewModel.IsDetailsVisible = true; + + // Trigger a re-evaluation of whether we have a hero image based on + // the current theme + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(HasHeroImage))); } public void Receive(HideDetailsMessage message) => HideDetails(); @@ -285,4 +292,29 @@ public sealed partial class ShellPage : ViewModel.CurrentPage = page; } } + + /// + /// Gets a value indicating whether determines if the current Details have a HeroImage, given the theme + /// we're currently in. This needs to be evaluated in the view, because the + /// viewModel doesn't actually know what the current theme is. + /// + public bool HasHeroImage + { + get + { + var requestedTheme = ActualTheme; + var iconInfo = ViewModel.Details?.HeroImage; + var data = requestedTheme == Microsoft.UI.Xaml.ElementTheme.Dark ? + iconInfo?.Dark : + iconInfo?.Light; + + // We have an icon, AND EITHER: + // We have a string icon, OR + // we have a data blob + var hasIcon = (data != null) && + (!string.IsNullOrEmpty(data.Icon) || + data.Data != null); + return hasIcon; + } + } } diff --git a/src/modules/cmdpal/WindowsCommandPalette/ActionViewModel.cs b/src/modules/cmdpal/WindowsCommandPalette/ActionViewModel.cs index e2c1f0f1c6..c8384f9ca5 100644 --- a/src/modules/cmdpal/WindowsCommandPalette/ActionViewModel.cs +++ b/src/modules/cmdpal/WindowsCommandPalette/ActionViewModel.cs @@ -13,5 +13,5 @@ public sealed class ActionViewModel(ICommand cmd) internal bool CanInvoke => cmd is IInvokableCommand; - internal IconElement IcoElement => Microsoft.Terminal.UI.IconPathConverter.IconMUX(Command.Icon.Icon); + internal IconElement IcoElement => Microsoft.Terminal.UI.IconPathConverter.IconMUX(Command.Icon.Dark.Icon); } diff --git a/src/modules/cmdpal/WindowsCommandPalette/ContextItemViewModel.cs b/src/modules/cmdpal/WindowsCommandPalette/ContextItemViewModel.cs index 3f49f43f1c..e95f8eb002 100644 --- a/src/modules/cmdpal/WindowsCommandPalette/ContextItemViewModel.cs +++ b/src/modules/cmdpal/WindowsCommandPalette/ContextItemViewModel.cs @@ -14,7 +14,7 @@ public sealed class ContextItemViewModel : INotifyPropertyChanged internal string Name => Command.Name; - internal IconDataType Icon => Command.Icon; + internal IconData Icon => Command.Icon.Dark; public event PropertyChangedEventHandler? PropertyChanged; diff --git a/src/modules/cmdpal/WindowsCommandPalette/ListItemViewModel.cs b/src/modules/cmdpal/WindowsCommandPalette/ListItemViewModel.cs index b8bfb10a79..622157c6a8 100644 --- a/src/modules/cmdpal/WindowsCommandPalette/ListItemViewModel.cs +++ b/src/modules/cmdpal/WindowsCommandPalette/ListItemViewModel.cs @@ -107,7 +107,7 @@ public sealed class ListItemViewModel : INotifyPropertyChanged, IDisposable, IEq this.ListItem = new(model); this.Title = model.Title; this.Subtitle = model.Subtitle; - this.Icon = model.Icon.Icon; + this.Icon = model.Icon.Dark.Icon; this.TextToSuggest = model.TextToSuggest; if (model.Tags != null) @@ -151,7 +151,7 @@ public sealed class ListItemViewModel : INotifyPropertyChanged, IDisposable, IEq BubbleXamlPropertyChanged(nameof(ContextActions)); break; case nameof(Icon): - this.Icon = item.Command.Icon.Icon; + this.Icon = item.Command.Icon.Dark.Icon; BubbleXamlPropertyChanged(nameof(IcoElement)); break; case nameof(TextToSuggest): diff --git a/src/modules/cmdpal/WindowsCommandPalette/Microsoft.CmdPal.UI.Poc.csproj b/src/modules/cmdpal/WindowsCommandPalette/Microsoft.CmdPal.UI.Poc.csproj index f9a6d62eec..8c91294aa8 100644 --- a/src/modules/cmdpal/WindowsCommandPalette/Microsoft.CmdPal.UI.Poc.csproj +++ b/src/modules/cmdpal/WindowsCommandPalette/Microsoft.CmdPal.UI.Poc.csproj @@ -90,7 +90,6 @@ - diff --git a/src/modules/cmdpal/WindowsCommandPalette/TagViewModel.cs b/src/modules/cmdpal/WindowsCommandPalette/TagViewModel.cs index 1a68a65c5f..cc6939cb58 100644 --- a/src/modules/cmdpal/WindowsCommandPalette/TagViewModel.cs +++ b/src/modules/cmdpal/WindowsCommandPalette/TagViewModel.cs @@ -12,13 +12,13 @@ public sealed class TagViewModel { private readonly ITag _tag; - internal IconDataType Icon => _tag.Icon; + internal IconInfo Icon => _tag.Icon; internal string Text => _tag.Text; - public bool HasIcon => !string.IsNullOrEmpty(Icon?.Icon); + public bool HasIcon => !string.IsNullOrEmpty(Icon?.Dark?.Icon); - internal IconElement IcoElement => Microsoft.Terminal.UI.IconPathConverter.IconMUX(Icon?.Icon ?? string.Empty, 10); + internal IconElement IcoElement => Microsoft.Terminal.UI.IconPathConverter.IconMUX(Icon?.Dark?.Icon ?? string.Empty, 10); public Windows.UI.Color Foreground { diff --git a/src/modules/cmdpal/WindowsCommandPalette/Views/CommandAlias.cs b/src/modules/cmdpal/WindowsCommandPalette/Views/CommandAlias.cs index 3ce0d022c3..10ffe119db 100644 --- a/src/modules/cmdpal/WindowsCommandPalette/Views/CommandAlias.cs +++ b/src/modules/cmdpal/WindowsCommandPalette/Views/CommandAlias.cs @@ -2,21 +2,6 @@ // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Collections.ObjectModel; -using Microsoft.CmdPal.Ext.Apps.Programs; -using Microsoft.CmdPal.Ext.Bookmarks; -using Microsoft.CmdPal.Ext.Calc; -using Microsoft.CmdPal.Ext.Registry; -using Microsoft.CmdPal.Ext.Settings; -using Microsoft.CmdPal.Ext.WindowsServices; -using Microsoft.CmdPal.Ext.WindowsSettings; -using Microsoft.CmdPal.Ext.WindowsTerminal; -using Microsoft.CmdPal.Extensions; -using Microsoft.CmdPal.Extensions.Helpers; -using Windows.Foundation; -using WindowsCommandPalette.BuiltinCommands; -using WindowsCommandPalette.Models; - namespace WindowsCommandPalette.Views; public class CommandAlias(string shortcut, string commandId, bool direct = false) diff --git a/src/modules/cmdpal/WindowsCommandPalette/Views/DetailsViewModel.xaml.cs b/src/modules/cmdpal/WindowsCommandPalette/Views/DetailsViewModel.xaml.cs index f16cb47623..fe9305bf40 100644 --- a/src/modules/cmdpal/WindowsCommandPalette/Views/DetailsViewModel.xaml.cs +++ b/src/modules/cmdpal/WindowsCommandPalette/Views/DetailsViewModel.xaml.cs @@ -13,7 +13,7 @@ public sealed class DetailsViewModel internal string Body { get; init; } = string.Empty; - internal IconDataType HeroImage { get; init; } = new(string.Empty); + internal IconData HeroImage { get; init; } = new(string.Empty); internal IconElement IcoElement => Microsoft.Terminal.UI.IconPathConverter.IconMUX(HeroImage.Icon); @@ -21,6 +21,6 @@ public sealed class DetailsViewModel { this.Title = details.Title; this.Body = details.Body; - this.HeroImage = details.HeroImage ?? new(string.Empty); + this.HeroImage = details.HeroImage?.Dark ?? new(string.Empty); } } diff --git a/src/modules/cmdpal/WindowsCommandPalette/Views/MainViewModel.xaml.cs b/src/modules/cmdpal/WindowsCommandPalette/Views/MainViewModel.xaml.cs index 4c59493197..36d65f9d52 100644 --- a/src/modules/cmdpal/WindowsCommandPalette/Views/MainViewModel.xaml.cs +++ b/src/modules/cmdpal/WindowsCommandPalette/Views/MainViewModel.xaml.cs @@ -8,7 +8,6 @@ using Microsoft.CmdPal.Ext.Bookmarks; using Microsoft.CmdPal.Ext.Calc; using Microsoft.CmdPal.Ext.Indexer; using Microsoft.CmdPal.Ext.Registry; -using Microsoft.CmdPal.Ext.Settings; using Microsoft.CmdPal.Ext.Shell; using Microsoft.CmdPal.Ext.WebSearch; using Microsoft.CmdPal.Ext.WindowsServices; @@ -59,7 +58,6 @@ public sealed class MainViewModel : IDisposable BuiltInCommands.Add(new IndexerCommandsProvider()); BuiltInCommands.Add(new BookmarksCommandProvider()); BuiltInCommands.Add(new CalculatorCommandProvider()); - BuiltInCommands.Add(new SettingsCommandProvider()); BuiltInCommands.Add(_quitCommandProvider); BuiltInCommands.Add(_reloadCommandProvider); BuiltInCommands.Add(new WindowsTerminalCommandsProvider()); diff --git a/src/modules/cmdpal/doc/initial-sdk-spec/generate-interface.ps1 b/src/modules/cmdpal/doc/initial-sdk-spec/generate-interface.ps1 index 0c44f9b4ef..5b7a0f4756 100644 --- a/src/modules/cmdpal/doc/initial-sdk-spec/generate-interface.ps1 +++ b/src/modules/cmdpal/doc/initial-sdk-spec/generate-interface.ps1 @@ -65,14 +65,23 @@ namespace Microsoft.CmdPal.Extensions }; [contract(Microsoft.CmdPal.Extensions.ExtensionsContract, 1)] - runtimeclass IconDataType { - IconDataType(String iconString); - static IconDataType FromStream(Windows.Storage.Streams.IRandomAccessStreamReference stream); + runtimeclass IconData { + IconData(String iconString); + static IconData FromStream(Windows.Storage.Streams.IRandomAccessStreamReference stream); String Icon { get; }; Windows.Storage.Streams.IRandomAccessStreamReference Data { get; }; }; + [contract(Microsoft.CmdPal.Extensions.ExtensionsContract, 1)] + runtimeclass IconInfo { + IconInfo(String iconString); + IconInfo(IconData lightIcon, IconData darkIcon); + + IconData Light { get; }; + IconData Dark { get; }; + }; + [contract(Microsoft.CmdPal.Extensions.ExtensionsContract, 1)] runtimeclass KeyChord { diff --git a/src/modules/cmdpal/doc/initial-sdk-spec/initial-sdk-spec.md b/src/modules/cmdpal/doc/initial-sdk-spec/initial-sdk-spec.md index 8f45036cee..07033f4ca6 100644 --- a/src/modules/cmdpal/doc/initial-sdk-spec/initial-sdk-spec.md +++ b/src/modules/cmdpal/doc/initial-sdk-spec/initial-sdk-spec.md @@ -1,13 +1,13 @@ --- author: Mike Griese created on: 2024-07-19 -last updated: 2024-12-31 +last updated: 2025-01-08 issue id: n/a --- # Run v2 Extensions SDK -_aka "DevPal", "PT Run v2", "DevSearch", "Windows Command Palette", this thing has many names. I'll use DevPal throughout the doc_ +_aka "DevPal", "PT Run v2", "DevSearch", "Windows Command Palette", this thing has many names. I'll use "DevPal" throughout the doc_ > [NOTE!] > Are you here to just see what the SDK looks like? Skip to the [Actions @@ -59,7 +59,7 @@ functionality. - [Form Pages](#form-pages) - [Other types](#other-types) - [`ContextItem`s](#contextitems) - - [`IconDataType`](#icondatatype) + - [Icons - `IconInfo` and `IconData`](#icons---iconinfo-and-icondatatype) - [`OptionalColor`](#optionalcolor) - [`Details`](#details) - [`INotifyPropChanged`](#inotifypropchanged) @@ -533,7 +533,7 @@ Use `cs` for samples. interface ICommand requires INotifyPropChanged{ String Name{ get; }; String Id{ get; }; - IconDataType Icon{ get; }; + IconInfo Icon{ get; }; } enum CommandResultKind { @@ -716,7 +716,7 @@ interface IContextItem {} interface ICommandItem requires INotifyPropChanged { ICommand Command{ get; }; IContextItem[] MoreCommands{ get; }; - IconDataType Icon{ get; }; + IconInfo Icon{ get; }; String Title{ get; }; String Subtitle{ get; }; } @@ -1045,7 +1045,7 @@ interface ISeparatorFilterItem requires IFilterItem {} interface IFilter requires IFilterItem { String Id { get; }; String Name { get; }; - IconDataType Icon { get; }; + IconInfo Icon { get; }; } interface IFilters { @@ -1223,10 +1223,10 @@ flyout. Mostly, these are just commands and seperators. If an `ICommandContextItem` has `MoreCommands`, then when it's invoked, we'll create a sub-menu with those items in it. -#### `IconDataType` +#### Icons - `IconInfo` and `IconData` -This is a wrapper type for passing information about an icon to DevPal. This -allows extensions to specify apps in a variety of ways, including: +`IconData` is a wrapper type for passing information about an icon to +DevPal. This allows extensions to specify apps in a variety of ways, including: * A URL to an image on the web or filesystem * A string for an emoji or Segoe Fluent icon @@ -1235,15 +1235,25 @@ allows extensions to specify apps in a variety of ways, including: extensions that want to pass us raw image data, which isn't necessarily a file which DevPal can load itself. +When specifying icons, elements can specify both the light theme and dark theme +versions of an icon with `IconInfo`. + ```cs -struct IconDataType { - IconDataType(String iconString); - static IconDataType FromStream(Windows.Storage.Streams.IRandomAccessStreamReference stream); +struct IconData { + IconData(String iconString); + static IconData FromStream(Windows.Storage.Streams.IRandomAccessStreamReference stream); String Icon { get; }; Windows.Storage.Streams.IRandomAccessStreamReference Data { get; }; } +struct IconInfo { + IconInfo(String iconString); + IconInfo(IconData lightIcon, IconData darkIcon); + + IconData Light { get; }; + IconData Dark { get; }; +} ``` Terminal already has a robust arbitrary string -> icon loader that we can easily @@ -1302,7 +1312,7 @@ block, and the generator will pull this into the file first. --> ```c# interface ITag { - IconDataType Icon { get; }; + IconInfo Icon { get; }; String Text { get; }; OptionalColor Foreground { get; }; OptionalColor Background { get; }; @@ -1317,7 +1327,7 @@ interface IDetailsElement { IDetailsData Data { get; }; } interface IDetails { - IconDataType HeroImage { get; }; + IconInfo HeroImage { get; }; String Title { get; }; String Body { get; }; IDetailsElement[] Metadata { get; }; @@ -1383,7 +1393,7 @@ interface ICommandProvider requires Windows.Foundation.IClosable, INotifyItemsCh { String Id { get; }; String DisplayName { get; }; - IconDataType Icon { get; }; + IconInfo Icon { get; }; ICommandSettings Settings { get; }; Boolean Frozen { get; }; @@ -1585,9 +1595,12 @@ For example, we should have something like: ```cs class OpenUrlAction(string targetUrl, ActionResult result) : Microsoft.Windows.Run.Extensions.InvokableCommand { - public string Name => "Open"; - public IconDataType Icon => "\uE8A7"; // OpenInNewWindow - public ActionResult Invoke() { + public OpenUrlAction() + { + Name = "Open"; + Icon = new("\uE8A7"); // OpenInNewWindow + } + public CommandResult Invoke() { Process.Start(new ProcessStartInfo(targetUrl) { UseShellExecute = true }); return result; } @@ -1599,12 +1612,17 @@ that no longer do we need to add additional classes for the actions. We just use the helper: ```cs -class NewsListItem(NewsPost post) : Microsoft.Windows.Run.Extensions.ListItem { - public string Title => post.Title; - public string Subtitle => post.Url; +class NewsListItem : Microsoft.Windows.Run.Extensions.ListItem { + private NewsPost _post; + public NewsListItem(NewsPost post) + { + _post = post; + Title = post.Title; + Subtitle = post.Url; + } public IContextItem[] Commands => [ - new CommandContextItem(new Microsoft.Windows.Run.Extensions.OpenUrlAction(post.Url, ActionResult.KeepOpen)), - new CommandContextItem(new Microsoft.Windows.Run.Extensions.OpenUrlAction(post.CommentsUrl, ActionResult.KeepOpen){ + new CommandContextItem(new OpenUrlAction(post.Url, CommandResult.KeepOpen)), + new CommandContextItem(new OpenUrlAction(post.CommentsUrl, CommandResult.KeepOpen){ Name = "Open comments", Icon = "\uE8F2" // ChatBubbles }) @@ -1612,7 +1630,10 @@ class NewsListItem(NewsPost post) : Microsoft.Windows.Run.Extensions.ListItem { public ITag[] Tags => [ new Tag(){ Text=post.Poster, new Tag(){ Text=post.Points } } ]; } class HackerNewsPage: Microsoft.Windows.Run.Extensions.ListPage { - public bool Loading => true; + public HackerNewsPage() + { + Loading = true; + } IListItem[] GetItems(String query) { List items = /* do some RSS feed stuff */; this.IsLoading = false; @@ -1832,7 +1853,7 @@ When displaying a page: ## Class diagram -This is a diagram attempting to show the relationships between the various types we've defined for the SDK. Some elements are omitted for clarity. (Notably, `IconDataType` and `IPropChanged`, which are used in many places.) +This is a diagram attempting to show the relationships between the various types we've defined for the SDK. Some elements are omitted for clarity. (Notably, `IconData` and `IPropChanged`, which are used in many places.) The notes on the arrows help indicate the multiplicity of the relationship. * "*" means 0 or more (for arrays) @@ -1844,7 +1865,7 @@ classDiagram class ICommand { String Name String Id - IconDataType Icon + IconInfo Icon } IPage --|> ICommand class IPage { @@ -1889,7 +1910,7 @@ classDiagram class IFilter { String Id String Name - IconDataType Icon + IconInfo Icon } class IFilters { @@ -1905,7 +1926,7 @@ classDiagram %% IListItem --|> INotifyPropChanged class IListItem { - IconDataType Icon + IconInfo Icon String Title String Subtitle ICommand Command @@ -1948,14 +1969,14 @@ classDiagram } class IDetails { - IconDataType HeroImage + IconInfo HeroImage String Title String Body IDetailsElement[] Metadata } class ITag { - IconDataType Icon + IconInfo Icon String Text Color Color String ToolTip @@ -1980,7 +2001,7 @@ classDiagram class ICommandProvider { String DisplayName - IconDataType Icon + IconInfo Icon Boolean Frozen ICommandItem[] TopLevelCommands() diff --git a/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions.Helpers/Command.cs b/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions.Helpers/Command.cs index a79c343bba..451da6d4e6 100644 --- a/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions.Helpers/Command.cs +++ b/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions.Helpers/Command.cs @@ -8,7 +8,7 @@ public class Command : BaseObservable, ICommand { private string _name = string.Empty; private string _id = string.Empty; - private IconDataType _icon = new(string.Empty); + private IconInfo _icon = new(string.Empty); public string Name { @@ -22,7 +22,7 @@ public class Command : BaseObservable, ICommand public string Id { get => _id; protected set => _id = value; } - public IconDataType Icon + public IconInfo Icon { get => _icon; set diff --git a/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions.Helpers/CommandItem.cs b/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions.Helpers/CommandItem.cs index bf9be61849..21140871aa 100644 --- a/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions.Helpers/CommandItem.cs +++ b/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions.Helpers/CommandItem.cs @@ -6,13 +6,13 @@ namespace Microsoft.CmdPal.Extensions.Helpers; public partial class CommandItem : BaseObservable, ICommandItem { - private IconDataType? _icon; + private IconInfo? _icon; private string _title = string.Empty; private string _subtitle = string.Empty; private ICommand? _command; private IContextItem[] _moreCommands = []; - public IconDataType? Icon + public IconInfo? Icon { get => _icon ?? _command?.Icon; set diff --git a/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions.Helpers/CommandProvider.cs b/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions.Helpers/CommandProvider.cs index aac0febea0..e8f6f694c3 100644 --- a/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions.Helpers/CommandProvider.cs +++ b/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions.Helpers/CommandProvider.cs @@ -12,7 +12,7 @@ public abstract partial class CommandProvider : ICommandProvider private string _displayName = string.Empty; - private IconDataType _icon = new(string.Empty); + private IconInfo _icon = new(string.Empty); private ICommandSettings? _settings; @@ -20,7 +20,7 @@ public abstract partial class CommandProvider : ICommandProvider public string DisplayName { get => _displayName; protected set => _displayName = value; } - public IconDataType Icon { get => _icon; protected set => _icon = value; } + public IconInfo Icon { get => _icon; protected set => _icon = value; } public event TypedEventHandler? ItemsChanged; diff --git a/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions.Helpers/Details.cs b/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions.Helpers/Details.cs index 4e2215540e..fdd75dd172 100644 --- a/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions.Helpers/Details.cs +++ b/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions.Helpers/Details.cs @@ -6,12 +6,12 @@ namespace Microsoft.CmdPal.Extensions.Helpers; public class Details : BaseObservable, IDetails { - private IconDataType _heroImage = new(string.Empty); + private IconInfo _heroImage = new(string.Empty); private string _title = string.Empty; private string _body = string.Empty; private IDetailsElement[] _metadata = []; - public IconDataType HeroImage + public IconInfo HeroImage { get => _heroImage; set diff --git a/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions.Helpers/Filter.cs b/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions.Helpers/Filter.cs index 3ea38fa9b5..0dac64d460 100644 --- a/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions.Helpers/Filter.cs +++ b/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions.Helpers/Filter.cs @@ -6,7 +6,7 @@ namespace Microsoft.CmdPal.Extensions.Helpers; public class Filter : IFilter { - public IconDataType Icon => throw new NotImplementedException(); + public IconInfo Icon => throw new NotImplementedException(); public string Id => throw new NotImplementedException(); diff --git a/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions.Helpers/Tag.cs b/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions.Helpers/Tag.cs index 087ff5f8f5..0d793a10ff 100644 --- a/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions.Helpers/Tag.cs +++ b/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions.Helpers/Tag.cs @@ -8,7 +8,7 @@ public class Tag : BaseObservable, ITag { private OptionalColor _foreground; private OptionalColor _background; - private IconDataType _icon = new(string.Empty); + private IconInfo _icon = new(string.Empty); private string _text = string.Empty; private string _toolTip = string.Empty; private ICommand? _command; @@ -33,7 +33,7 @@ public class Tag : BaseObservable, ITag } } - public IconDataType Icon + public IconInfo Icon { get => _icon; set diff --git a/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions/IconData.cpp b/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions/IconData.cpp new file mode 100644 index 0000000000..bf84a3c380 --- /dev/null +++ b/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions/IconData.cpp @@ -0,0 +1,5 @@ +#include "pch.h" +#include "IconData.h" +#include "IconData.g.cpp" +#include "IconInfo.g.cpp" + \ No newline at end of file diff --git a/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions/IconData.h b/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions/IconData.h new file mode 100644 index 0000000000..2c591ad9f6 --- /dev/null +++ b/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions/IconData.h @@ -0,0 +1,52 @@ +#pragma once +#include "IconData.g.h" +#include "IconInfo.g.h" + +namespace winrt::Microsoft::CmdPal::Extensions::implementation +{ + struct IconData : IconDataT + { + IconData(hstring iconPath) : + Icon(iconPath){}; + + IconData(Windows::Storage::Streams::IRandomAccessStreamReference iconData) : + Data(iconData){}; + + static Microsoft::CmdPal::Extensions::IconData FromStream(Windows::Storage::Streams::IRandomAccessStreamReference stream) + { + return *winrt::make_self(stream); + } + + til::property Icon; + til::property Data; + }; +} +namespace winrt::Microsoft::CmdPal::Extensions::factory_implementation +{ + struct IconData : IconDataT + { + }; +} + +namespace winrt::Microsoft::CmdPal::Extensions::implementation +{ + struct IconInfo : IconInfoT + { + IconInfo(hstring iconPath) : + Light(iconPath), + Dark(iconPath){}; + + IconInfo(Extensions::IconData light, Extensions::IconData dark) : + Light(light), + Dark(dark) {}; + + til::property Light; + til::property Dark; + }; +} +namespace winrt::Microsoft::CmdPal::Extensions::factory_implementation +{ + struct IconInfo : IconInfoT + { + }; +} diff --git a/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions/IconDataType.cpp b/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions/IconDataType.cpp deleted file mode 100644 index 8da15248c0..0000000000 --- a/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions/IconDataType.cpp +++ /dev/null @@ -1,4 +0,0 @@ -#include "pch.h" -#include "IconDataType.h" -#include "IconDataType.g.cpp" - \ No newline at end of file diff --git a/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions/IconDataType.h b/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions/IconDataType.h deleted file mode 100644 index 741bde8ec8..0000000000 --- a/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions/IconDataType.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once -#include "IconDataType.g.h" - -namespace winrt::Microsoft::CmdPal::Extensions::implementation -{ - struct IconDataType : IconDataTypeT - { - IconDataType(hstring iconPath) : - Icon(iconPath){}; - - IconDataType(Windows::Storage::Streams::IRandomAccessStreamReference iconData) : - Data(iconData){}; - - static Microsoft::CmdPal::Extensions::IconDataType FromStream(Windows::Storage::Streams::IRandomAccessStreamReference stream) - { - return *winrt::make_self(stream); - } - - til::property Icon; - til::property Data; - - - }; -} -namespace winrt::Microsoft::CmdPal::Extensions::factory_implementation -{ - struct IconDataType : IconDataTypeT - { - }; -} diff --git a/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions/Microsoft.CmdPal.Extensions.idl b/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions/Microsoft.CmdPal.Extensions.idl index eaa733239e..94709a9dd1 100644 --- a/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions/Microsoft.CmdPal.Extensions.idl +++ b/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions/Microsoft.CmdPal.Extensions.idl @@ -15,14 +15,23 @@ namespace Microsoft.CmdPal.Extensions }; [contract(Microsoft.CmdPal.Extensions.ExtensionsContract, 1)] - runtimeclass IconDataType { - IconDataType(String iconString); - static IconDataType FromStream(Windows.Storage.Streams.IRandomAccessStreamReference stream); + runtimeclass IconData { + IconData(String iconString); + static IconData FromStream(Windows.Storage.Streams.IRandomAccessStreamReference stream); String Icon { get; }; Windows.Storage.Streams.IRandomAccessStreamReference Data { get; }; }; + [contract(Microsoft.CmdPal.Extensions.ExtensionsContract, 1)] + runtimeclass IconInfo { + IconInfo(String iconString); + IconInfo(IconData lightIcon, IconData darkIcon); + + IconData Light { get; }; + IconData Dark { get; }; + }; + [contract(Microsoft.CmdPal.Extensions.ExtensionsContract, 1)] runtimeclass KeyChord { @@ -62,7 +71,7 @@ namespace Microsoft.CmdPal.Extensions interface ICommand requires INotifyPropChanged{ String Name{ get; }; String Id{ get; }; - IconDataType Icon{ get; }; + IconInfo Icon{ get; }; } enum CommandResultKind { @@ -114,7 +123,7 @@ namespace Microsoft.CmdPal.Extensions interface IFilter requires IFilterItem { String Id { get; }; String Name { get; }; - IconDataType Icon { get; }; + IconInfo Icon { get; }; } [contract(Microsoft.CmdPal.Extensions.ExtensionsContract, 1)] @@ -139,7 +148,7 @@ namespace Microsoft.CmdPal.Extensions [contract(Microsoft.CmdPal.Extensions.ExtensionsContract, 1)] interface ITag { - IconDataType Icon { get; }; + IconInfo Icon { get; }; String Text { get; }; OptionalColor Foreground { get; }; OptionalColor Background { get; }; @@ -157,7 +166,7 @@ namespace Microsoft.CmdPal.Extensions } [contract(Microsoft.CmdPal.Extensions.ExtensionsContract, 1)] interface IDetails { - IconDataType HeroImage { get; }; + IconInfo HeroImage { get; }; String Title { get; }; String Body { get; }; IDetailsElement[] Metadata { get; }; @@ -234,7 +243,7 @@ namespace Microsoft.CmdPal.Extensions interface ICommandItem requires INotifyPropChanged { ICommand Command{ get; }; IContextItem[] MoreCommands{ get; }; - IconDataType Icon{ get; }; + IconInfo Icon{ get; }; String Title{ get; }; String Subtitle{ get; }; } @@ -323,7 +332,7 @@ namespace Microsoft.CmdPal.Extensions { String Id { get; }; String DisplayName { get; }; - IconDataType Icon { get; }; + IconInfo Icon { get; }; ICommandSettings Settings { get; }; Boolean Frozen { get; }; diff --git a/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions/Microsoft.CmdPal.Extensions.vcxproj b/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions/Microsoft.CmdPal.Extensions.vcxproj index 5c23f8fe2c..6600e15afd 100644 --- a/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions/Microsoft.CmdPal.Extensions.vcxproj +++ b/src/modules/cmdpal/extensionsdk/Microsoft.CmdPal.Extensions/Microsoft.CmdPal.Extensions.vcxproj @@ -141,7 +141,7 @@ - + @@ -151,7 +151,7 @@ Create - +