Skip to content

Commit c51e301

Browse files
Sergio0694michael-hawkerazchohfi
authored
FontIcon markup extension (#3110)
* Added FontIcon markup extension * Removed unnecessary using directives * Renamed the FontIcon markup extension * Added FontIcon tests * Fixed a typo in the test XAML * Update UnitTests/Extensions/Test_FontIconExtensionMarkupExtension.cs Co-Authored-By: Michael Hawker MSFT (XAML Llama) <[email protected]> * Update UnitTests/Extensions/Test_FontIconExtensionMarkupExtension.cs Co-Authored-By: Michael Hawker MSFT (XAML Llama) <[email protected]> * Update UnitTests/Extensions/Test_FontIconExtensionMarkupExtension.cs Co-Authored-By: Michael Hawker MSFT (XAML Llama) <[email protected]> * Added new FontIcon properties * Added more tests for the new properties * Added FontIconSourceExtension * Added BitmapIconExtension * Added tests for the FontIconSource extension * Fixed namespace for BitmapIconExtension type * Added tests for BitmapIconExtension type * Removed [Bindable] attribute from markup extensions See #3191 for more info about this * Added a sample page for the FontIconExtension type * Added sample for the BitmapIcon extension * Added FontIconSource sample page (not loading) * Minor code style tweaks, also tests work now ¯\_(ツ)_/¯ * Added shallow copy for icon markup extensions * Fixed a missing resource in the icon markup sample page * Code refactoring * Updated samples page * Code refactoring, minor optimizations * Added SymbolIconSourceExtension type * Added SymbolIconSourceExtension sample * Added foreground property to icon extensions * Fixed a typo in a unit test * Fixed remaining unit tests * Removed unnecessary using directives * Fixed BitmapIcon and FontIcon extension tests * Fixed FontIconSource extension tests * Fixed build errors after merge Co-authored-by: Michael Hawker MSFT (XAML Llama) <[email protected]> Co-authored-by: Alexandre Zollinger Chohfi <[email protected]>
1 parent 81975b0 commit c51e301

21 files changed

+796
-10
lines changed

Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,9 @@
520520
<Compile Include="SamplePages\ImageEx\ImageExLazyLoadingControl.xaml.cs">
521521
<DependentUpon>ImageExLazyLoadingControl.xaml</DependentUpon>
522522
</Compile>
523+
<Compile Include="SamplePages\IconExtensions\IconExtensionsPage.xaml.cs">
524+
<DependentUpon>IconExtensionsPage.xaml</DependentUpon>
525+
</Compile>
523526
<Compile Include="SamplePages\ObservableGroup\ObservableGroupPage.xaml.cs">
524527
<DependentUpon>ObservableGroupPage.xaml</DependentUpon>
525528
</Compile>
@@ -581,6 +584,7 @@
581584
<Content Include="SamplePages\Eyedropper\EyedropperXaml.bind" />
582585
<Content Include="SamplePages\Eyedropper\EyedropperCode.bind" />
583586
<Content Include="SamplePages\TokenizingTextBox\TokenizingTextBoxCode.bind" />
587+
<Content Include="SamplePages\IconExtensions\IconExtensionsXaml.bind" />
584588
<Content Include="SamplePages\WrapLayout\WrapLayout.bind" />
585589
<Content Include="SamplePages\StaggeredLayout\StaggeredLayout.bind" />
586590
<Content Include="SamplePages\ObservableGroup\ObservableGroup.bind" />
@@ -990,6 +994,10 @@
990994
<SubType>Designer</SubType>
991995
<Generator>MSBuild:Compile</Generator>
992996
</Page>
997+
<Page Include="SamplePages\IconExtensions\IconExtensionsPage.xaml">
998+
<Generator>MSBuild:Compile</Generator>
999+
<SubType>Designer</SubType>
1000+
</Page>
9931001
<Page Include="SamplePages\ObservableGroup\ObservableGroupPage.xaml">
9941002
<SubType>Designer</SubType>
9951003
<Generator>MSBuild:Compile</Generator>
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<Page x:Class="Microsoft.Toolkit.Uwp.SampleApp.SamplePages.IconExtensionsPage"
2+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
6+
xmlns:ex="using:Microsoft.Toolkit.Uwp.UI.Extensions"
7+
mc:Ignorable="d">
8+
<Grid>
9+
<StackPanel>
10+
11+
<CommandBar>
12+
<AppBarButton Icon="{ex:FontIcon Glyph=&#xE102;}"/>
13+
<AppBarButton Icon="{ex:SymbolIcon Glyph=Play}"/>
14+
</CommandBar>
15+
16+
<SwipeControl>
17+
<SwipeControl.LeftItems>
18+
<SwipeItems Mode="Reveal">
19+
<SwipeItem Text="Accept" IconSource="{ex:FontIconSource Glyph=&#xE10B;}"/>
20+
<SwipeItem Text="Play" IconSource="{ex:SymbolIconSource Glyph=Play}"/>
21+
</SwipeItems>
22+
</SwipeControl.LeftItems>
23+
</SwipeControl>
24+
25+
<Button>
26+
<Button.Flyout>
27+
<MenuFlyout>
28+
<MenuFlyoutItem Icon="{ex:BitmapIcon Source=/Assets/ToolkitLogo.png}" />
29+
</MenuFlyout>
30+
</Button.Flyout>
31+
</Button>
32+
</StackPanel>
33+
</Grid>
34+
</Page>
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System.Linq;
6+
using Microsoft.Toolkit.Uwp.UI.Animations.Behaviors;
7+
using Microsoft.Toolkit.Uwp.UI.Extensions;
8+
using Microsoft.Xaml.Interactivity;
9+
using Windows.UI.Xaml;
10+
11+
namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages
12+
{
13+
/// <summary>
14+
/// A page that shows how to use the offset behavior.
15+
/// </summary>
16+
public sealed partial class IconExtensionsPage : IXamlRenderListener
17+
{
18+
/// <summary>
19+
/// Initializes a new instance of the <see cref="IconExtensionsPage"/> class.
20+
/// </summary>
21+
public IconExtensionsPage()
22+
{
23+
InitializeComponent();
24+
}
25+
26+
public void OnXamlRendered(FrameworkElement control)
27+
{
28+
}
29+
}
30+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<Page
2+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4+
xmlns:local="using:Microsoft.Toolkit.Uwp.SampleApp.SamplePages.IconExtensionsPage"
5+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
6+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
7+
xmlns:ex="using:Microsoft.Toolkit.Uwp.UI.Extensions"
8+
mc:Ignorable="d">
9+
<Grid>
10+
<StackPanel Spacing="8"
11+
HorizontalAlignment="Center"
12+
VerticalAlignment="Center">
13+
14+
<TextBlock Text="Use the FontIcon extension to create FontIcon items from custom glyphs."
15+
TextWrapping="Wrap"
16+
Style="{StaticResource BodyTextBlockStyle}"/>
17+
18+
<CommandBar>
19+
<AppBarButton Icon="{ex:FontIcon Glyph=&#xE102;}"/>
20+
<AppBarButton Icon="{ex:FontIcon Glyph=&#xE103;}"/>
21+
<AppBarButton Icon="{ex:FontIcon Glyph=&#xE10F;}"/>
22+
</CommandBar>
23+
24+
<TextBlock Text="Use the SymbolIcon extension to create FontIcon items from known symbols."
25+
TextWrapping="Wrap"
26+
Style="{StaticResource BodyTextBlockStyle}"/>
27+
28+
<CommandBar>
29+
<AppBarButton Icon="{ex:SymbolIcon Glyph=Play}"/>
30+
<AppBarButton Icon="{ex:SymbolIcon Glyph=Pause}"/>
31+
<AppBarButton Icon="{ex:SymbolIcon Glyph=Home}"/>
32+
</CommandBar>
33+
34+
<TextBlock Text="Use the FontIconSource extension to create FontIconSource items from custom glyphs."
35+
TextWrapping="Wrap"
36+
Style="{StaticResource BodyTextBlockStyle}"/>
37+
38+
<SwipeControl BorderThickness="1"
39+
Background="#40000000"
40+
Width="300" Margin="12" Height="68">
41+
<SwipeControl.LeftItems>
42+
<SwipeItems Mode="Reveal">
43+
<SwipeItem Text="Accept" IconSource="{ex:FontIconSource Glyph=&#xE10B;}"/>
44+
<SwipeItem Text="Flag" IconSource="{ex:FontIconSource Glyph=&#xE129;}"/>
45+
</SwipeItems>
46+
</SwipeControl.LeftItems>
47+
<TextBlock Text="Swipe Right"
48+
Margin="12"
49+
HorizontalAlignment="Center" VerticalAlignment="Center"/>
50+
</SwipeControl>
51+
52+
<TextBlock Text="Use the SymbolIconSource extension to create FontIconSource items from known symbols."
53+
TextWrapping="Wrap"
54+
Style="{StaticResource BodyTextBlockStyle}"/>
55+
56+
<SwipeControl BorderThickness="1"
57+
Background="#40000000"
58+
Width="300" Margin="12" Height="68">
59+
<SwipeControl.LeftItems>
60+
<SwipeItems Mode="Reveal">
61+
<SwipeItem Text="Accept" IconSource="{ex:FontIconSource Glyph=Accept}"/>
62+
<SwipeItem Text="Flag" IconSource="{ex:FontIconSource Glyph=Flag}"/>
63+
</SwipeItems>
64+
</SwipeControl.LeftItems>
65+
<TextBlock Text="Swipe Right"
66+
Margin="12"
67+
HorizontalAlignment="Center" VerticalAlignment="Center"/>
68+
</SwipeControl>
69+
70+
<TextBlock Text="Use the BitmapIcon extension to create BitmapIcon items from images."
71+
TextWrapping="Wrap"
72+
Style="{StaticResource BodyTextBlockStyle}"/>
73+
74+
<Button Content="Click me!">
75+
<Button.Flyout>
76+
<MenuFlyout>
77+
<MenuFlyoutItem Text="Toolkit app"
78+
Icon="{ex:BitmapIcon Source=/Assets/ToolkitLogo.png}" />
79+
<MenuFlyoutItem Text="Microsoft"
80+
Icon="{ex:BitmapIcon Source=/Assets/mslogo.png}" />
81+
</MenuFlyout>
82+
</Button.Flyout>
83+
</Button>
84+
</StackPanel>
85+
</Grid>
86+
</Page>

Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1223,7 +1223,16 @@
12231223
"Icon": "/SamplePages/OnDevice/OnDevice.png",
12241224
"XamlCodeFile": "OnDeviceXaml.bind",
12251225
"DocumentationUrl": "https://raw.githubusercontent.com/MicrosoftDocs/WindowsCommunityToolkitDocs/master/docs/extensions/OnDeviceMarkup.md"
1226-
}
1226+
},
1227+
{
1228+
"Name": "IconExtensions",
1229+
"Type": "IconExtensionsPage",
1230+
"About": "Markup extensions to easily create various types of icons.",
1231+
"CodeUrl": "https://github.com/windows-toolkit/WindowsCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.UI/Extensions/Markup/FontIconExtension",
1232+
"XamlCodeFile": "IconExtensionsXaml.bind",
1233+
"Icon": "/Assets/Helpers.png",
1234+
"DocumentationUrl": "https://raw.githubusercontent.com/MicrosoftDocs/WindowsCommunityToolkitDocs/master/docs/extensions/IconExtensions.md"
1235+
}
12271236
]
12281237
},
12291238
{
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System;
6+
using Windows.UI.Text;
7+
using Windows.UI.Xaml.Markup;
8+
using Windows.UI.Xaml.Media;
9+
10+
namespace Microsoft.Toolkit.Uwp.UI.Extensions
11+
{
12+
/// <summary>
13+
/// An abstract <see cref="MarkupExtension"/> which to produce text-based icons.
14+
/// </summary>
15+
public abstract class TextIconExtension : MarkupExtension
16+
{
17+
/// <summary>
18+
/// Gets or sets the size of the icon to display.
19+
/// </summary>
20+
public double FontSize { get; set; }
21+
22+
[ThreadStatic]
23+
private static FontFamily segoeMDL2AssetsFontFamily;
24+
25+
/// <summary>
26+
/// Gets the reusable "Segoe MDL2 Assets" <see cref="FontFamily"/> instance.
27+
/// </summary>
28+
protected static FontFamily SegoeMDL2AssetsFontFamily
29+
{
30+
get => segoeMDL2AssetsFontFamily ??= new FontFamily("Segoe MDL2 Assets");
31+
}
32+
33+
/// <summary>
34+
/// Gets or sets the thickness of the icon glyph.
35+
/// </summary>
36+
public FontWeight FontWeight { get; set; } = FontWeights.Normal;
37+
38+
/// <summary>
39+
/// Gets or sets the font style for the icon glyph.
40+
/// </summary>
41+
public FontStyle FontStyle { get; set; } = FontStyle.Normal;
42+
43+
/// <summary>
44+
/// Gets or sets the foreground <see cref="Brush"/> for the icon.
45+
/// </summary>
46+
public Brush Foreground { get; set; }
47+
48+
/// <summary>
49+
/// Gets or sets a value indicating whether automatic text enlargement, to reflect the system text size setting, is enabled.
50+
/// </summary>
51+
public bool IsTextScaleFactorEnabled { get; set; }
52+
53+
/// <summary>
54+
/// Gets or sets a value indicating whether the icon is mirrored when the flow direction is right to left.
55+
/// </summary>
56+
public bool MirroredWhenRightToLeft { get; set; }
57+
}
58+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using Windows.UI.Xaml.Markup;
6+
7+
namespace Microsoft.Toolkit.Uwp.UI.Extensions
8+
{
9+
/// <summary>
10+
/// An abstract <see cref="MarkupExtension"/> which to produce text-based icons.
11+
/// </summary>
12+
/// <typeparam name="T">The type representing the glyph for the current icon.</typeparam>
13+
public abstract class TextIconExtension<T> : TextIconExtension
14+
{
15+
/// <summary>
16+
/// Gets or sets the <typeparamref name="T"/> value representing the icon to display.
17+
/// </summary>
18+
public T Glyph { get; set; }
19+
}
20+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System;
6+
using Windows.UI.Xaml.Controls;
7+
using Windows.UI.Xaml.Markup;
8+
9+
namespace Microsoft.Toolkit.Uwp.UI.Extensions
10+
{
11+
/// <summary>
12+
/// Custom <see cref="MarkupExtension"/> which can provide <see cref="BitmapIcon"/> values.
13+
/// </summary>
14+
[MarkupExtensionReturnType(ReturnType = typeof(BitmapIcon))]
15+
public sealed class BitmapIconExtension : MarkupExtension
16+
{
17+
/// <summary>
18+
/// Gets or sets the <see cref="Uri"/> representing the image to display.
19+
/// </summary>
20+
public Uri Source { get; set; }
21+
22+
/// <summary>
23+
/// Gets or sets a value indicating whether to display the icon as monochrome.
24+
/// </summary>
25+
public bool ShowAsMonochrome { get; set; }
26+
27+
/// <inheritdoc/>
28+
protected override object ProvideValue()
29+
{
30+
return new BitmapIcon
31+
{
32+
ShowAsMonochrome = ShowAsMonochrome,
33+
UriSource = Source
34+
};
35+
}
36+
}
37+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using Windows.UI.Xaml.Controls;
6+
using Windows.UI.Xaml.Markup;
7+
using Windows.UI.Xaml.Media;
8+
9+
namespace Microsoft.Toolkit.Uwp.UI.Extensions
10+
{
11+
/// <summary>
12+
/// Custom <see cref="MarkupExtension"/> which can provide <see cref="FontIcon"/> values.
13+
/// </summary>
14+
[MarkupExtensionReturnType(ReturnType = typeof(FontIcon))]
15+
public class FontIconExtension : TextIconExtension<string>
16+
{
17+
/// <summary>
18+
/// Gets or sets the font family to use to display the icon. If <see langword="null"/>, "Segoe MDL2 Assets" will be used.
19+
/// </summary>
20+
public FontFamily FontFamily { get; set; }
21+
22+
/// <inheritdoc/>
23+
protected override object ProvideValue()
24+
{
25+
var fontIcon = new FontIcon
26+
{
27+
Glyph = Glyph,
28+
FontFamily = FontFamily ?? SegoeMDL2AssetsFontFamily,
29+
FontWeight = FontWeight,
30+
FontStyle = FontStyle,
31+
IsTextScaleFactorEnabled = IsTextScaleFactorEnabled,
32+
MirroredWhenRightToLeft = MirroredWhenRightToLeft
33+
};
34+
35+
if (FontSize > 0)
36+
{
37+
fontIcon.FontSize = FontSize;
38+
}
39+
40+
if (Foreground != null)
41+
{
42+
fontIcon.Foreground = Foreground;
43+
}
44+
45+
return fontIcon;
46+
}
47+
}
48+
}

0 commit comments

Comments
 (0)