diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt
index a43e81d077..064e9ec94b 100644
--- a/.github/actions/spell-check/expect.txt
+++ b/.github/actions/spell-check/expect.txt
@@ -1527,6 +1527,7 @@ randi
RAquadrant
rasterization
Rasterize
+rasterizing
RAWINPUTDEVICE
RAWINPUTHEADER
RAWMODE
diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/IconBox.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/IconBox.cs
index 72bca70715..2fad25cec3 100644
--- a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/IconBox.cs
+++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/IconBox.cs
@@ -16,12 +16,12 @@ namespace Microsoft.CmdPal.UI.Controls;
///
public partial class IconBox : ContentControl
{
+ private const double DefaultIconFontSize = 16.0;
+
private double _lastScale;
private ElementTheme _lastTheme;
private double _lastFontSize;
- private const double DefaultIconFontSize = 16.0;
-
///
/// Gets or sets the to display within the . Overwritten, if is used instead.
///
@@ -62,6 +62,12 @@ public partial class IconBox : ContentControl
{
Refresh();
}
+#if DEBUG
+ if (_sourceRequested?.GetInvocationList().Length > 1)
+ {
+ Logger.LogWarning("There shouldn't be more than one handler for IconBox.SourceRequested");
+ }
+#endif
}
remove => _sourceRequested -= value;
}
@@ -102,9 +108,12 @@ public partial class IconBox : ContentControl
if (Source is FontIconSource fontIcon)
{
fontIcon.FontSize = _lastFontSize;
+ UpdatePaddingForFontIcon();
}
}
+ private void UpdatePaddingForFontIcon() => Padding = new Thickness(Math.Round(_lastFontSize * -0.2));
+
private void OnActualThemeChanged(FrameworkElement sender, object args)
{
if (_lastTheme == ActualTheme)
@@ -150,10 +159,7 @@ public partial class IconBox : ContentControl
private void Refresh()
{
- if (SourceKey is not null)
- {
- UpdateSourceKey(this, SourceKey);
- }
+ UpdateSourceKey(this, SourceKey);
}
private static void OnSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
@@ -170,8 +176,10 @@ public partial class IconBox : ContentControl
self.Padding = default;
break;
case FontIconSource fontIcon:
+ self.UpdateLastFontSize();
if (self.Content is IconSourceElement iconSourceElement)
{
+ fontIcon.FontSize = self._lastFontSize;
iconSourceElement.IconSource = fontIcon;
}
else
@@ -190,7 +198,7 @@ public partial class IconBox : ContentControl
self.Content = elem;
}
- self.Padding = new Thickness(Math.Round(self._lastFontSize * -0.2));
+ self.UpdatePaddingForFontIcon();
break;
case BitmapIconSource bitmapIcon:
@@ -206,10 +214,12 @@ public partial class IconBox : ContentControl
self.Padding = default;
break;
+
case IconSource source:
self.Content = source.CreateIconElement();
self.Padding = default;
break;
+
default:
throw new InvalidOperationException($"New value of {e.NewValue} is not of type IconSource.");
}
@@ -233,10 +243,10 @@ public partial class IconBox : ContentControl
return;
}
- Callback(iconBox, sourceKey);
+ RequestIconFromSource(iconBox, sourceKey);
}
- private static async void Callback(IconBox iconBox, object? sourceKey)
+ private static async void RequestIconFromSource(IconBox iconBox, object? sourceKey)
{
try
{
@@ -256,17 +266,12 @@ public partial class IconBox : ContentControl
// list virtualization situation, it's very possible we
// may have already been set to a new icon before we
// even got back from the await.
- if (eventArgs.Key != sourceKey)
+ if (!ReferenceEquals(sourceKey, iconBox.SourceKey))
{
// If the requested icon has changed, then just bail
return;
}
- if (eventArgs.Value == iconBox.Source)
- {
- return;
- }
-
iconBox.Source = eventArgs.Value;
}
catch (Exception ex)
diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/Helpers/Icons/IconLoaderService.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI/Helpers/Icons/IconLoaderService.cs
index ef93ccb040..6935802b50 100644
--- a/src/modules/cmdpal/Microsoft.CmdPal.UI/Helpers/Icons/IconLoaderService.cs
+++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/Helpers/Icons/IconLoaderService.cs
@@ -219,6 +219,6 @@ internal sealed partial class IconLoaderService : IIconLoaderService
iconSize = DefaultIconSize;
}
- return IconPathConverter.IconSourceMUX(iconString, false, fontFamily, iconSize);
+ return IconPathConverter.IconSourceMUX(iconString, fontFamily, iconSize);
}
}
diff --git a/src/modules/cmdpal/Microsoft.Terminal.UI/IconPathConverter.cpp b/src/modules/cmdpal/Microsoft.Terminal.UI/IconPathConverter.cpp
index c9ab37e3fc..a1dee068e8 100644
--- a/src/modules/cmdpal/Microsoft.Terminal.UI/IconPathConverter.cpp
+++ b/src/modules/cmdpal/Microsoft.Terminal.UI/IconPathConverter.cpp
@@ -94,40 +94,49 @@ namespace winrt::Microsoft::Terminal::UI::implementation
// - : The type of IconSource (MUX, WUX) to generate.
// Arguments:
// - path: the full, expanded path to the icon.
+ // - targetSize: the target size for decoding/rasterizing the icon.
// Return Value:
// - An IconElement with its IconSource set, if possible.
template
- TIconSource _getColoredBitmapIcon(const winrt::hstring& path, bool monochrome)
+ TIconSource _getColoredBitmapIcon(const winrt::hstring& path, int targetSize)
{
// FontIcon uses glyphs in the private use area, whereas valid URIs only contain ASCII characters.
// To skip throwing on Uri construction, we can quickly check if the first character is ASCII.
- if (!path.empty() && path.front() < 128)
+ if (path.empty() || path.front() >= 128)
{
- try
- {
- winrt::Windows::Foundation::Uri iconUri{ path };
-
- if (til::equals_insensitive_ascii(iconUri.Extension(), L".svg"))
- {
- typename ImageIconSource::type iconSource;
- winrt::Microsoft::UI::Xaml::Media::Imaging::SvgImageSource source{ iconUri };
- iconSource.ImageSource(source);
- return iconSource;
- }
- else
- {
- typename BitmapIconSource::type iconSource;
- // Make sure to set this to false, so we keep the RGB data of the
- // image. Otherwise, the icon will be white for all the
- // non-transparent pixels in the image.
- iconSource.ShowAsMonochrome(monochrome);
- iconSource.UriSource(iconUri);
- return iconSource;
- }
- }
- CATCH_LOG();
+ return nullptr;
}
+ try
+ {
+ winrt::Windows::Foundation::Uri iconUri{ path };
+
+ if (til::equals_insensitive_ascii(iconUri.Extension(), L".svg"))
+ {
+ typename ImageIconSource::type iconSource;
+ winrt::Microsoft::UI::Xaml::Media::Imaging::SvgImageSource source{ iconUri };
+ source.RasterizePixelWidth(static_cast(targetSize));
+ // Set only single dimension here; the image might not be square and
+ // this will preserve the aspect ratio (for the price of keeping height unbound).
+ // source.RasterizePixelHeight(static_cast(targetSize));
+ iconSource.ImageSource(source);
+ return iconSource;
+ }
+ else
+ {
+ typename ImageIconSource::type iconSource;
+ winrt::Microsoft::UI::Xaml::Media::Imaging::BitmapImage bitmapImage;
+ bitmapImage.DecodePixelWidth(targetSize);
+ // Set only single dimension here; the image might not be square and
+ // this will preserve the aspect ratio (for the price of keeping height unbound).
+ // bitmapImage.DecodePixelHeight(targetSize);
+ bitmapImage.UriSource(iconUri);
+ iconSource.ImageSource(bitmapImage);
+ return iconSource;
+ }
+ }
+ CATCH_LOG();
+
return nullptr;
}
@@ -158,14 +167,14 @@ namespace winrt::Microsoft::Terminal::UI::implementation
// Return Value:
// - An IconElement with its IconSource set, if possible.
template
- TIconSource _getIconSource(const winrt::hstring& iconPath, bool monochrome, const winrt::hstring& fontFamily, const int targetSize)
+ TIconSource _getIconSource(const winrt::hstring& iconPath, const winrt::hstring& fontFamily, const int targetSize)
{
TIconSource iconSource{ nullptr };
if (iconPath.size() != 0)
{
const auto expandedIconPath{ _expandIconPath(iconPath) };
- iconSource = _getColoredBitmapIcon(expandedIconPath, monochrome);
+ iconSource = _getColoredBitmapIcon(expandedIconPath, targetSize);
// If we fail to set the icon source using the "icon" as a path,
// let's try it as a symbol/emoji.
@@ -235,9 +244,9 @@ namespace winrt::Microsoft::Terminal::UI::implementation
// return _getIconSource(path, false);
// }
- static Microsoft::UI::Xaml::Controls::IconSource _IconSourceMUX(const hstring& path, bool monochrome, const winrt::hstring& fontFamily, const int targetSize)
+ static Microsoft::UI::Xaml::Controls::IconSource _IconSourceMUX(const hstring& path, const winrt::hstring& fontFamily, const int targetSize)
{
- return _getIconSource(path, monochrome, fontFamily, targetSize);
+ return _getIconSource(path, fontFamily, targetSize);
}
static SoftwareBitmap _convertToSoftwareBitmap(HICON hicon,
@@ -352,7 +361,6 @@ namespace winrt::Microsoft::Terminal::UI::implementation
}
MUX::Controls::IconSource IconPathConverter::IconSourceMUX(const winrt::hstring& iconPath,
- const bool monochrome,
const winrt::hstring& fontFamily,
const int targetSize)
{
@@ -360,7 +368,7 @@ namespace winrt::Microsoft::Terminal::UI::implementation
const auto indexOpt = _getIconIndex(iconPath, iconPathWithoutIndex);
if (!indexOpt.has_value())
{
- return _IconSourceMUX(iconPath, monochrome, fontFamily, targetSize);
+ return _IconSourceMUX(iconPath, fontFamily, targetSize);
}
const auto bitmapSource = _getImageIconSourceForBinary(iconPathWithoutIndex, indexOpt.value(), targetSize);
@@ -374,13 +382,14 @@ namespace winrt::Microsoft::Terminal::UI::implementation
Microsoft::UI::Xaml::Controls::IconElement IconPathConverter::IconMUX(const winrt::hstring& iconPath) {
return IconMUX(iconPath, 24);
}
+
Microsoft::UI::Xaml::Controls::IconElement IconPathConverter::IconMUX(const winrt::hstring& iconPath, const int targetSize)
{
std::wstring_view iconPathWithoutIndex;
const auto indexOpt = _getIconIndex(iconPath, iconPathWithoutIndex);
if (!indexOpt.has_value())
{
- auto source = IconSourceMUX(iconPath, false, L"", targetSize);
+ auto source = IconSourceMUX(iconPath, L"", targetSize);
Microsoft::UI::Xaml::Controls::IconSourceElement icon;
icon.IconSource(source);
return icon;
diff --git a/src/modules/cmdpal/Microsoft.Terminal.UI/IconPathConverter.h b/src/modules/cmdpal/Microsoft.Terminal.UI/IconPathConverter.h
index 8f504eb8c7..de3698a923 100644
--- a/src/modules/cmdpal/Microsoft.Terminal.UI/IconPathConverter.h
+++ b/src/modules/cmdpal/Microsoft.Terminal.UI/IconPathConverter.h
@@ -10,7 +10,7 @@ namespace winrt::Microsoft::Terminal::UI::implementation
//static Windows::UI::Xaml::Controls::IconElement IconWUX(const winrt::hstring& iconPath);
//static Windows::UI::Xaml::Controls::IconSource IconSourceWUX(const winrt::hstring& iconPath);
- static Microsoft::UI::Xaml::Controls::IconSource IconSourceMUX(const winrt::hstring& iconPath, bool convertToGrayscale, const winrt::hstring& fontFamily, const int targetSize=24);
+ static Microsoft::UI::Xaml::Controls::IconSource IconSourceMUX(const winrt::hstring& iconPath, const winrt::hstring& fontFamily, const int targetSize=24);
static Microsoft::UI::Xaml::Controls::IconElement IconMUX(const winrt::hstring& iconPath);
static Microsoft::UI::Xaml::Controls::IconElement IconMUX(const winrt::hstring& iconPath, const int targetSize);
diff --git a/src/modules/cmdpal/Microsoft.Terminal.UI/IconPathConverter.idl b/src/modules/cmdpal/Microsoft.Terminal.UI/IconPathConverter.idl
index 38aabcf822..41bde322b9 100644
--- a/src/modules/cmdpal/Microsoft.Terminal.UI/IconPathConverter.idl
+++ b/src/modules/cmdpal/Microsoft.Terminal.UI/IconPathConverter.idl
@@ -7,7 +7,7 @@ namespace Microsoft.Terminal.UI
{
// static Windows.UI.Xaml.Controls.IconElement IconWUX(String path);
// static Windows.UI.Xaml.Controls.IconSource IconSourceWUX(String path);
- static Microsoft.UI.Xaml.Controls.IconSource IconSourceMUX(String path, Boolean convertToGrayscale, String fontFamily, Int32 targetSize);
+ static Microsoft.UI.Xaml.Controls.IconSource IconSourceMUX(String path, String fontFamily, Int32 targetSize);
static Microsoft.UI.Xaml.Controls.IconElement IconMUX(String path);
static Microsoft.UI.Xaml.Controls.IconElement IconMUX(String path, Int32 targetSize);
};