Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

Xamarin.Forms.FontIconSource Spec #3189

Closed
hartez opened this issue Jun 29, 2018 · 23 comments · Fixed by #4747
Closed

Xamarin.Forms.FontIconSource Spec #3189

hartez opened this issue Jun 29, 2018 · 23 comments · Fixed by #4747

Comments

@hartez
Copy link
Contributor

hartez commented Jun 29, 2018

Font Icons

The goal of this spec is to support the use of font icons (e.g., the Segoe MDL 2 icons or Font Awesome) as image sources.

Note: Nothing in this specification is guaranteed to be final; all features, implementations, and interfaces are subject to change.

API

IFontElement

Implementing classes support setting various font properties.

Note: this is not a new interface; it's already part of Forms. It is included here only for reference purposes.

public interface IFontElement
{
	FontAttributes FontAttributes { get; }
	string FontFamily { get; }
	double FontSize { get; }
}

FontIconSource

Supports using glyph icons.

public class FontIconSource : ImageSource, IFontElement
{
	public static readonly BindableProperty GlyphProperty;
	public string Glyph { get; set; }

	public static readonly BindableProperty ColorProperty;
	public Color Color { get; set; }

	public static readonly BindableProperty NameProperty;
	public string Name { get; set; }
}

Properties

API Description
Glyph Gets or sets the charactor code to be displayed.
Color Gets or sets the color of the glyph.
Name Gets or sets the 'friendly' name of the glyph. If this property is set, the value of Glyph will be retrieved from the FontIconRegistry.

LayeredFontIconSource

Supports layering glyph icons (e.g., see: https://docs.microsoft.com/en-us/windows/uwp/design/style/segoe-ui-symbol-font#layering-and-mirroring).

[ContentProperty("Layers")]
public class LayeredFontIconSource : ImageSource, IFontElement
{
	public IList<FontIconSource> Layers { get; }
}

Properties

API Description
Layers Gets the set of icons to be displayed. The icons are stacked in the order they are defined, last one on top.

If a FontIconSource in the Layers list does not specify a font property, that property's value is inherited from the LayeredFontIconSource.

FontIconRegistry

Supports registering 'friendly' names for icon glyphs. A Forms application has a single instance of this class.

public class FontIconRegistry
{
	public void SetDefaultIconFontFamily(string fontFamily);
	public void Clear();
	public void SetGlyphName(string fontFamily, string glyph, string name);
	public void SetGlyphName(string glyph, string name);
	public string GetGlyph(string name);
	public string GetGlyph(string fontFamily, string name);
}

Methods

API Description
SetDefaultIconFontFamily Sets the default font family to use when registering and resolving glyphs. If this value is set, it will be used by any FontIconSource which does not specify a FontFamily.
Clear Removes all entries from the regsitry.
SetGlyphName(string fontFamily, string glyph, string name) Registers a friendly name for a glyph with a specific font family.
SetGlyphName(string glyph, string name) Registers a friendly name for a glyph with the default font family. Throws an exception if a default font family is not set.
GetGlyph(string name) Retrieves the glyph for the specified name using the default font family. Throws an exception if the default font family is not set or the name is not found.
GetGlyph(string name) Retrieves the glyph for the specified name and font family. Throws an exception if either the font family or name are not found.

FontIconExtension

Supports specifying a FontIconSource inline in an Image tag's Source property. For example,

<Image Source="{FontIcon Name=share,Color={StaticResource primaryColor}}" />
public sealed class FontIconExtension : IMarkupExtension<ImageSource>
{
...
}
@hartez
Copy link
Contributor Author

hartez commented Jun 29, 2018

WRT to @GalaxiaGuy's comment on the CollectionView spec, this spec now includes LayeredFontIconSource.

@hartez
Copy link
Contributor Author

hartez commented Jun 29, 2018

Linking to @dansiegel's suggestions from the CollectionView spec.

@ChaseFlorell
Copy link

ChaseFlorell commented Jun 29, 2018

we're using Iconize right now and I had to build a map.

public static IList<IIcon> Items { get; } = new List<IIcon>();

Items.Add(fcc_instagram, '\uE039');
Items.Add(fcc_linkedin, '\uE017');
Items.Add(fcc_twitter, '\uE02c');
Items.Add(fcc_youtube, '\uE031');

public const string fcc_adjustment = nameof(fcc_instagram);
public const string fcc_ag_news = nameof(fcc_linkedin);
public const string fcc_bell = nameof(fcc_twitter);
public const string fcc_calendar = nameof(fcc_youtube);
// etc

It works well, and the best part is that it is discoverable via intellisense.

Now I know that you won't have the same API, but I do strongly suggest that any font come with an associated map of constant values that we can use via intellisense, and also it should be pluggable in such a way that we can drop our own fonts in and register them with the service.

@ChaseFlorell
Copy link

per @dansiegel's comment,
if you wanted your markup extension to also include intellisense, you'd maybe have to switch from constant strings to an Enum... Not 💯% sure what that'd look like though.

@hartez
Copy link
Contributor Author

hartez commented Jun 29, 2018

@ChaseFlorell Ha! We are literally having this exact conversation in slack right now.

@ChaseFlorell
Copy link

@hartez this is what our xaml looks like

<pages:BasePage.ToolbarItems>
    <iconize:IconToolbarItem Icon="{x:Static xaml:Icons.fcc_filter}" IconColor="White" Command="{Binding GoToActivityFilterPageCommand}" />
    <iconize:IconToolbarItem Icon="{x:Static xaml:Icons.fcc_circle_plus}" IconColor="White" Command="{Binding ShowActivityActionSheetCommand}" />
</pages:BasePage.ToolbarItems>

@dansiegel
Copy link
Contributor

dansiegel commented Jun 29, 2018

@ChaseFlorell I think this may ultimately be just need to be a separate community effort to maintain plugins for each font, and I'm not sure that you can simultaneously architect this for intellisense and extensibility. At least not on the core Forms side.. you can provide your own types but that's a totally different topic

@ChaseFlorell
Copy link

@dansiegel I don't disagree.
I think my comment is more along the lines of having them architect it in such a way that we CAN plug in whatever font we want. There needs to be a registration mechanism...

// pseudo code... naming is hard
public static void RegisterFontIcon(IFontIcon fontIcon)
{
}

// then
Xamarin.Forms.RegisterFontIcon(new MyFontIconPack());

@hartez
Copy link
Contributor Author

hartez commented Jun 29, 2018

@dansiegel @ChaseFlorell You're converging on what I think our ultimate plan will be: a mechanism for registering "friendly" names which map to actual code points. Forms would provide a set of them out of the box (at least for UWP; I'm not yet sure what we can do about the other platforms). Users can add their own mappings to the registry at startup. With that in place, it should be possible for community contributors to create NuGet packages with fonts and/or mappings.

And something like MyFontIconPack could provide at least some degree of Intellisense by including a set of constants, e.g.

namespace MyFontIconPack {
...
public const string Add = "Add";
public const string Add = "Share";
...
}

I need to mull this over a bit; I'll update the spec on Monday.

@dansiegel
Copy link
Contributor

Personally I'm not sure that Forms should be handling anything with non-system fonts. That said there is probably some room here to finally introduce cross platform support for common system icons like Add & Share which should be doable on iOS, Android, and UWP IMO. That said I would personally be against Forms registering everything under the sun OOB. I think it would lead to too much app bloat. But extensibility also brings the ability to opt-in

@charlesroddie
Copy link

@hartez a mechanism for registering "friendly" names which map to actual code points. Forms would provide a set of them out of the box (at least for UWP; I'm not yet sure what we can do about the other platforms). Users can add their own mappings to the registry at startup.

I don't agree with either of these suggestions.

  1. With font icons you should be able to choose the font. There is no need for Xamarin to provide any font.
  2. Keeping track of the unicode for useful icons in a given font is extremely easy and doesn't need any special mechanism to be created by Xamarin.

@SparkieLabs
Copy link

If the aim is to support cross-platform vector-based icons (which I would certainly love) then isn't SVG a better solution? Font Awesome is also available as SVGs and if Microsoft were to make Segoe MDL 2 icons available as SVGs them even better.

@rogihee
Copy link
Contributor

rogihee commented Jul 1, 2018

@sparkie108 I think part of the implementation of this Spec is to replace all occurences of FileImageSource with ImageSource, thus finally enabling SVG also in areas such as tabbars and navigition bars. Because then you can use SvgImage or FontImage anywhere.

@programmation
Copy link

@rogihee Agreed 1000%. The change in the XF code is trivial.

@hartez
Copy link
Contributor Author

hartez commented Jul 2, 2018

@charlesroddie

With font icons you should be able to choose the font. There is no need for Xamarin to provide any font.

The spec doesn't prevent you from choosing your own font. That's why everything inherits IFontElement (which includes FontFamily). I've updated the spec to make this clearer.

As for Xamarin providing fonts, we don't really intend to. UWP comes with a glyph icon font built in; we don't ship it, it's just there. We want to make sure that using it from Forms is as easy as possible. And we want to make sure that developers can use other fonts they add. If the other platforms start shipping built-in glyph icon fonts, we would also make sure those were supported.

@hartez
Copy link
Contributor Author

hartez commented Jul 2, 2018

Keeping track of the unicode for useful icons in a given font is extremely easy and doesn't need any special mechanism to be created by Xamarin.

Keep in mind that in a given application, several different icon fonts may be in use; each may use different Unicode values for the icons. Let's say I'm using the built-in Segoe MDL2 for UWP, Font Awesome for iOS, and the Material Design Iconic Font on Android. To display a '+', I need code points E710, F067, and F278. Not only would I have to keep track of those values, I would also need to use OnPlatform everywhere I declared an icon. That makes my XAML unwieldy pretty quickly.

This gets worse if I start to use C# alongside my XAML; the two languages have different ways of referencing Unicode values. The XAML looks like
<Label Text="&#xF04B;" />
whereas in C# I need to write something like
var s = @"\uF04B"

With a friendly name registry, I can simply refer to the icon as 'plus' or 'add' and let Forms work out the rest. It's much less error-prone, the code looks nicer, and it's more maintainable.

The registry would be pre-populated with values which make sense (similar to the Symbol enumeration in UWP) to make it easy to get started; obviously the registry can be modified (or even cleared out entirely) by developers so they can configure it in a way which makes sense for their application.

@hartez
Copy link
Contributor Author

hartez commented Jul 2, 2018

@rogihee @programmation While I'm not opposed to the idea of changing those properties to be ImageSource instead of FileImageSource, any discussion or implementation of that will be part of a separate effort from this one.

@rogihee
Copy link
Contributor

rogihee commented Jul 3, 2018

@hartez, ok, can I raise it as a separate enhancement then?

@hartez
Copy link
Contributor Author

hartez commented Jul 3, 2018

@rogihee Oh, absolutely. If you do, you might want to reference 1955; I think it's calling for a subset of what you want.

@hartez hartez removed this from New in Triage Jul 3, 2018
@rogihee
Copy link
Contributor

rogihee commented Jul 3, 2018

@hartez: done, see #3207

@charlesroddie
Copy link

@hartez Let's say I'm using the built-in Segoe MDL2 for UWP, Font Awesome for iOS, and the Material Design Iconic Font on Android.

Thanks for the explanation. I didn't realize there were different built-in symbol fonts on the main platforms. A common way to access equivalent symbols does make sense then.

@samhouts samhouts added this to To do in Sprint 144 Oct 31, 2018
@kingces95 kingces95 self-assigned this Oct 31, 2018
@samhouts samhouts added this to To do in Sprint 145 Nov 26, 2018
@samhouts samhouts moved this from To do to In progress in Sprint 145 Nov 29, 2018
@kingces95
Copy link
Contributor

kingces95 commented Nov 29, 2018

@groege
Copy link

groege commented Nov 30, 2018

@rogihee @programmation While I'm not opposed to the idea of changing those properties to be ImageSource instead of FileImageSource, any discussion or implementation of that will be part of a separate effort from this one.

Could we also do this at the same time, since this should not be very much work to do right?
I would really appreciate it :)

@samhouts samhouts added this to To do in Sprint 146 via automation Dec 15, 2018
@samhouts samhouts moved this from To do to In progress in Sprint 146 Dec 15, 2018
@samhouts samhouts added this to In Progress in v3.6.0 Dec 15, 2018
@samhouts samhouts moved this from In progress to Ready for Review (Issues) in Sprint 145 Dec 15, 2018
@samhouts samhouts moved this from In progress to Ready for Review (Issues) in Sprint 146 Dec 17, 2018
@samhouts samhouts added this to Closed in Enhancements via automation Jan 3, 2019
Sprint 146 automation moved this from Ready for Review (Issues) to Done Jan 3, 2019
@samhouts samhouts moved this from In Progress to Done in v3.6.0 Jan 4, 2019
@samhouts samhouts removed this from Closed in Enhancements Jan 4, 2019
@samhouts samhouts added this to In Progress in v4.0.0 Feb 2, 2019
@samhouts samhouts removed this from Done in v3.6.0 Feb 2, 2019
@samhouts samhouts moved this from In Progress to Done in v4.0.0 Feb 4, 2019
@samhouts samhouts removed this from Done in v4.0.0 Feb 7, 2019
@samhouts samhouts added this to In Progress in v3.6.0 Feb 7, 2019
@samhouts samhouts moved this from In Progress to Done in v3.6.0 Feb 7, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
No open projects
Sprint 144
  
To do
Sprint 145
  
Ready for Review (Issues)
Sprint 146
  
Done
v3.6.0
  
Done
Development

Successfully merging a pull request may close this issue.

9 participants