Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Fixed issue where icons were not displayed on submenus of shell extensions #14070

Merged
merged 1 commit into from
Nov 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Files.App/App.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
<ResourceDictionary Source="ms-appx:///ResourceDictionaries/PathIcons.xaml" />
<ResourceDictionary Source="ms-appx:///UserControls/SideBar/SideBarControls.xaml" />
<ResourceDictionary Source="ms-appx:///ResourceDictionaries/App.Theme.TextBlockStyles.xaml" />
<ResourceDictionary Source="ms-appx:///ResourceDictionaries/MenuFlyoutSubItemWithImageStyle.xaml" />
<ResourceDictionary>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Light">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) 2023 Files Community
// Licensed under the MIT License. See the LICENSE.

using Files.App.UserControls.Menus;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
Expand Down Expand Up @@ -86,6 +87,21 @@ private static MenuFlyoutItemBase GetMenuFlyoutItem(ContextMenuFlyoutItemViewMod
Text = item.Text,
Tag = item.Tag,
};

if (item.BitmapIcon is not null)
{
flyoutSubItem.Style = App.Current.Resources["MenuFlyoutSubItemWithImageStyle"] as Style;
flyoutSubItem.CornerRadius = new(4);
try
{
MenuFlyoutSubItemCustomProperties.SetBitmapIcon(flyoutSubItem, item.BitmapIcon);
}
catch (Exception e)
{
Debug.WriteLine(e);
}
}

item.Items.ForEach(i =>
{
flyoutSubItem.Items.Add(GetMenuItem(i));
Expand All @@ -109,6 +125,7 @@ private static MenuFlyoutItemBase GetItem(ContextMenuFlyoutItemViewModel i)
Tag = i.Tag,
Command = i.Command,
CommandParameter = i.CommandParameter,
CornerRadius = new(4),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth putting the 4 inside a variable since it's repeated l.94?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is a static resource from WinUI we can use.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is for MenuFlyoutItemWithImage, not for MenuFlyoutSubItem. You may notice corners are not rounded when hovering over menu items with an icon in current stable or preview release.

I think there is a static resource from WinUI we can use.

I thought so too, but couldn't find it right away.

};
try
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
<!-- Copyright (c) 2023 Files Community. Licensed under the MIT License. See the LICENSE. -->
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:menus="using:Files.App.UserControls.Menus">

<Style x:Key="MenuFlyoutSubItemWithImageStyle" TargetType="MenuFlyoutSubItem">
<Setter Property="Padding" Value="{ThemeResource MenuFlyoutItemThemePadding}" />
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="MenuFlyoutSubItem">

<Grid
x:Name="LayoutRoot"
Margin="{StaticResource MenuFlyoutItemMargin}"
Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>

<Viewbox
x:Name="IconRoot"
Grid.Column="0"
Width="16"
Height="16"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Visibility="Collapsed">
<ContentPresenter x:Name="IconContent" Content="{TemplateBinding Icon}" />
</Viewbox>

<Image
Grid.Column="0"
Width="16"
Height="16"
Margin="0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Source="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=(menus:MenuFlyoutSubItemCustomProperties.BitmapIcon)}"
Stretch="Uniform" />

<TextBlock
x:Name="TextBlock"
Grid.Column="0"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Foreground="{TemplateBinding Foreground}"
Text="{TemplateBinding Text}"
TextTrimming="Clip" />

<FontIcon
x:Name="SubItemChevron"
Grid.Column="1"
Margin="{StaticResource MenuFlyoutItemChevronMargin}"
AutomationProperties.AccessibilityView="Raw"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="12"
Foreground="{ThemeResource MenuFlyoutSubItemChevron}"
Glyph="&#xE974;"
MirroredWhenRightToLeft="True" />
</Grid>

<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter Target="LayoutRoot.Background" Value="{ThemeResource MenuFlyoutSubItemBackgroundPointerOver}" />
<Setter Target="TextBlock.Foreground" Value="{ThemeResource MenuFlyoutSubItemForegroundPointerOver}" />
<Setter Target="SubItemChevron.Foreground" Value="{ThemeResource MenuFlyoutSubItemChevronPointerOver}" />
<Setter Target="IconContent.Foreground" Value="{ThemeResource MenuFlyoutSubItemForegroundPointerOver}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Pressed">
<VisualState.Setters>
<Setter Target="LayoutRoot.Background" Value="{ThemeResource MenuFlyoutSubItemBackgroundPressed}" />
<Setter Target="TextBlock.Foreground" Value="{ThemeResource MenuFlyoutSubItemForegroundPressed}" />
<Setter Target="SubItemChevron.Foreground" Value="{ThemeResource MenuFlyoutSubItemChevronPressed}" />
<Setter Target="IconContent.Foreground" Value="{ThemeResource MenuFlyoutSubItemForegroundPressed}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="SubMenuOpened">
<VisualState.Setters>
<Setter Target="LayoutRoot.Background" Value="{ThemeResource MenuFlyoutSubItemBackgroundSubMenuOpened}" />
<Setter Target="TextBlock.Foreground" Value="{ThemeResource MenuFlyoutSubItemForegroundSubMenuOpened}" />
<Setter Target="SubItemChevron.Foreground" Value="{ThemeResource MenuFlyoutSubItemChevronSubMenuOpened}" />
<Setter Target="IconContent.Foreground" Value="{ThemeResource MenuFlyoutSubItemForegroundSubMenuOpened}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Target="LayoutRoot.Background" Value="{ThemeResource MenuFlyoutSubItemBackgroundDisabled}" />
<Setter Target="TextBlock.Foreground" Value="{ThemeResource MenuFlyoutSubItemForegroundDisabled}" />
<Setter Target="SubItemChevron.Foreground" Value="{ThemeResource MenuFlyoutSubItemChevronDisabled}" />
<Setter Target="IconContent.Foreground" Value="{ThemeResource MenuFlyoutSubItemForegroundDisabled}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CheckPlaceholderStates">
<VisualState x:Name="NoPlaceholder" />
<VisualState x:Name="CheckPlaceholder">
<VisualState.Setters>
<Setter Target="TextBlock.Margin" Value="{ThemeResource MenuFlyoutItemPlaceholderThemeThickness}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="IconPlaceholder">
<VisualState.Setters>
<Setter Target="TextBlock.Margin" Value="{ThemeResource MenuFlyoutItemPlaceholderThemeThickness}" />
<Setter Target="IconRoot.Visibility" Value="Visible" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="CheckAndIconPlaceholder">
<VisualState.Setters>
<Setter Target="TextBlock.Margin" Value="{ThemeResource MenuFlyoutItemDoublePlaceholderThemeThickness}" />
<Setter Target="IconRoot.Margin" Value="{ThemeResource MenuFlyoutItemPlaceholderThemeThickness}" />
<Setter Target="IconRoot.Visibility" Value="Visible" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="PaddingSizeStates">
<VisualState x:Name="DefaultPadding" />
<VisualState x:Name="NarrowPadding">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="Padding">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource MenuFlyoutItemThemePaddingNarrow}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) 2023 Files Community
// Licensed under the MIT License. See the LICENSE.

using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media.Imaging;

namespace Files.App.UserControls.Menus
{
[Microsoft.UI.Xaml.Data.Bindable]
public class MenuFlyoutSubItemCustomProperties : DependencyObject
{
public static readonly DependencyProperty BitmapIconProperty =
DependencyProperty.Register("BitmapIcon", typeof(BitmapImage), typeof(MenuFlyoutSubItemCustomProperties), new PropertyMetadata(null, OnBitmapIconChanged));

public static BitmapImage GetBitmapIcon(DependencyObject obj)
{
return (BitmapImage)obj.GetValue(BitmapIconProperty);
}

public static void SetBitmapIcon(DependencyObject obj, BitmapImage value)
{
obj.SetValue(BitmapIconProperty, value);
}

private static void OnBitmapIconChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as MenuFlyoutSubItem).Icon = e.NewValue is not null ? new IconSourceElement() : null;
}
}
}