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

An Iconic Disaster #1494

Open
verelpode opened this issue Oct 24, 2019 · 44 comments
Open

An Iconic Disaster #1494

verelpode opened this issue Oct 24, 2019 · 44 comments
Assignees
Labels
feature proposal New feature proposal team-Controls Issue for the Controls team

Comments

@verelpode
Copy link

verelpode commented Oct 24, 2019

WinUI has delivered innovative and impressive new GUI elements, designs, and techniques, and the WinUI team has implemented many clever improvements. But of course, nobody is capable of 100% pure perfection, so some deficiences must exist in WinUI. So now I'd like to talk about a glaring exception in the impressive track record of WinUI; an area desperately in need of improvement: Icon rendering in WinUI hardly works -- it's a disaster currently.

Icons are a very important topic, considering that most apps uses multiple icons in multiple places in multiple kinds of GUI elements (icons in buttons, toolbars, menus, tabs, standalone, etc). Thus it's really surprising to observe that, currently, icon rendering hardly works in WinUI/UWP unfortunately. Considering the extreme ubiquity of icons in apps, I consider this to be a high priority topic.

Use a PNG image as an icon?

For starters, look at a really simple case where you have an instance of Windows.UI.Xaml.Media.Imaging.BitmapImage that was produced from a PNG, and you want to use this PNG BitmapImage as an icon. This should be super simple, right? But no, unfortunately neither Windows.UI.Xaml.Controls.BitmapIconSource nor Windows.UI.Xaml.Controls.BitmapIcon support the ability to render a specified instance of BitmapImage -- surprising but true.

To use your BitmapImage instance as an icon, you are forced to use Windows.UI.Xaml.Controls.Image to render it because BitmapIconSource cannot. This means that, in combination with the other problems I will describe, Windows.UI.Xaml.Controls.IconSourceElement is a nice idea but so badly broken that it's practically unusable currently.

See also: Proposal: Create IconSource from Bitmap stream #601

Use an SVG image as an icon?

For example, you have an SVG image file that you want to use as an icon in multiple places in your app. You're out of luck because the SVG renderer contains bugs. See the most recent messages in this issue:
SVG Image sources behave unpredictably. #825

The names of BitmapIconSource and BitmapIcon suggest that they will not render SVG images because SVG images are vector not bitmap. I haven't actually tested what happens if you try to set BitmapIconSource.UriSource to the URI of an SVG instead of a bitmap. Unfortunately an IconSource subclass named ImageIconSource does not exist currently.

I am surprised to observe that WinUI does not yet have good support for scalable vector icons, neither colored vector icons (such as SVG) nor monochrome vector icons/symbols (such as paths).

SymbolIconSource and SymbolIcon are often unusable

For example, imagine you want to create a button that looks similar to this:
image

Thus you write XAML like this:

<Button Margin="20">
	<StackPanel Orientation="Vertical">
		<IconSourceElement Width="64" Height="64" Margin="8">
			<IconSourceElement.IconSource>
				<SymbolIconSource Symbol="Refresh"/>
			</IconSourceElement.IconSource>
		</IconSourceElement>
		<TextBlock Text="Reload Data" FontSize="20" FontWeight="SemiBold"/>
	</StackPanel>
</Button>

But it fails because the above XAML renders as follows:
image

As you can see, regardless of how large or small you make your IconSourceElement, the symbol still renders at a constant size of 20! Yes, a constant size! I could hardly believe it. Shockingly, SymbolIconSource and SymbolIcon don't scale, and don't provide any way to manually configure the size of the icon, and don't have a FontSize property either. (A FontSize property wouldn't be the right solution but anyway it doesn't exist.)

Following is an awkward inconvenient inefficient workaround that uses a Viewbox element to hack the icon into scaling. An alternative workaround is to view SymbolIconSource as unusable, and stop using it entirely, and instead use a TextBlock element and set its TextBlock.FontSize property.

<Button Margin="20">
	<StackPanel Orientation="Vertical">
		<Viewbox Width="64" Height="64" Margin="8">
			<IconSourceElement>
				<IconSourceElement.IconSource>
					<SymbolIconSource Symbol="Refresh"/>
				</IconSourceElement.IconSource>
			</IconSourceElement>
		</Viewbox>
		<TextBlock Text="Reload Data" FontSize="20" FontWeight="SemiBold"/>
	</StackPanel>
</Button>

How IconSourceElement with SymbolIconSource should behave: The same as BitmapIconSource and Windows.UI.Xaml.Controls.Image -- both of those scale the icon/image whereas SymbolIconSource does not -- a strange inconsistency. The icon should be scaled in the same manner as an Windows.UI.Xaml.Controls.Image element does with its default setting of Stretch="Uniform", or the same as a Windows.UI.Xaml.Shapes.Path element with Stretch set to Uniform.

FontIconSource and FontIcon are also broken

FontIconSource and FontIcon are slightly less broken than SymbolIconSource because they have a FontSize property. Actually a FontSize property is a bad solution but at least there exists some way of changing the icon size, and a bad way of changing the icon size is better (less bad) than the nothing that SymbolIconSource provides.

The idea of applying a FontSize to an icon is strange and doesn't make sense. What makes sense is applying a Width and Height to an icon or image or path, not a FontSize. A FontSize property is applicable to text but an icon is not text, rather an icon is akin to an image or path.

Instead of trying to apply font size to an icon, SymbolIconSource and FontIconSource should scale the icon in the same manner as BitmapIconSource does.

SymbolIconSource handles white space better than FontIconSource. For example, have a look at how this SymbolIconSource snippet renders:

image

<Border Padding="0" HorizontalAlignment="Left" VerticalAlignment="Top" BorderBrush="CadetBlue" BorderThickness="2">
	<IconSourceElement Margin="0">
		<IconSourceElement.IconSource>
			<SymbolIconSource Symbol="Refresh"/>
		</IconSourceElement.IconSource>
	</IconSourceElement>
</Border>

The above rendering makes sense. The Border encloses the icon without padding. Now compare it with the failure of FontIconSource and FontIcon:

image

<Border Padding="0" HorizontalAlignment="Left" VerticalAlignment="Top" BorderBrush="CadetBlue" BorderThickness="2">
	<IconSourceElement Margin="0">
		<IconSourceElement.IconSource>
			<FontIconSource Glyph="" FontFamily="Global User Interface" />
		</IconSourceElement.IconSource>
	</IconSourceElement>
</Border>

As you can see above, FontIconSource and FontIcon render with padding/whitespace around the icon. In practice, this makes it difficult to use the icon in a button because the spacing/layout looks strange because of the uncontrollable extra space introduced by FontIconSource. The amount of white space on the left, top, right, and bottom sides varies depending on the font -- the white space comes from the font.

If you have several IconSourceElement instances, such as 10 different buttons (in a row) with icons, and some of those IconSourceElement instances use SymbolIconSource and some use FontIconSource and some use PathIconSource, then the 10 buttons look strange and inconsistent with each other because some have extra whitespace/padding (those that use FontIconSource) while the others don't.

FontIconSource and FontIcon are not any better than using a TextBlock element. They render the same as TextBlock. This rendering behavior makes no sense because they are supposed to render as icons not text.

If you use TextBlock instead of FontIcon, you might try to use the OpticalMarginAlignment property to eliminate the problematic whitespace/padding, but it doesn't work, as you can see following. The first image (left) is with OpticalMarginAlignment="None" and the second image (right) is with OpticalMarginAlignment="TrimSideBearings". As you can see, TrimSideBearings didn't trim anything at all, rather it moved the space on the left side to the right side (the total width remains unchanged), and it didn't trim the top and bottom sides, and no other trimming option exists in OpticalMarginAlignment.

image

<StackPanel Orientation="Horizontal">
	<Border Margin="5" Padding="0" HorizontalAlignment="Left" VerticalAlignment="Top" BorderBrush="CadetBlue" BorderThickness="2">
		<TextBlock Text="" FontFamily="Global User Interface" FontSize="100" OpticalMarginAlignment="None" Margin="0" Padding="0"/>
	</Border>
	<Border Margin="5" Padding="0" HorizontalAlignment="Left" VerticalAlignment="Top" BorderBrush="CadetBlue" BorderThickness="2">
		<TextBlock Text="" FontFamily="Global User Interface" FontSize="100" OpticalMarginAlignment="TrimSideBearings" Margin="0" Padding="0"/>
	</Border>
</StackPanel>

In WPF, one way of rendering a glyph/character as an icon (without whitespace/padding) is to do this:

  1. Use either System.Windows.Media.FormattedText.BuildGeometry or System.Windows.Media.GlyphRun.BuildGeometry to convert the glyph/character to a Geometry instance.
  2. Create an instance of System.Windows.Shapes.Path and set the Path.Data property to the Geometry returned by BuildGeometry.
  3. Set the Path.Stretch property to Uniform.

Sadly, this technique cannot be used in WinUI because an equivalent of FormattedText.BuildGeometry does not exist in WinUI (or not that I'm aware of).

PathIconSource and PathIcon are unusable

For example, you have an instance of Windows.UI.Xaml.Media.PathGeometry that you want to use as a monochrome vector icon in multiple buttons, pages, or places in your app. This should be super simple, right? Just use Windows.UI.Xaml.Controls.PathIconSource or Windows.UI.Xaml.Controls.PathIcon and give it whatever PathGeometry instance you want? But no, unfortunately this fails to render. Surprising but true.

Following you can see the success of Windows.UI.Xaml.Shapes.Path versus the failure of Windows.UI.Xaml.Controls.PathIconSource (or PathIcon), when rendering the same PathGeometry (a house symbol). The first image (left) is the Path element -- it works. The second image (right) is PathIconSource -- a failed (truncated) rendering of an icon.

image

<StackPanel Orientation="Horizontal">
	<Border Margin="5" Padding="0" HorizontalAlignment="Left" VerticalAlignment="Top" BorderBrush="CadetBlue" BorderThickness="2">
		<Path Width="90" Height="90" Stretch="Uniform" Fill="Black">
			<Path.Data>
				M81.799,0 L163.599,75.636001 146.368,75.636001 146.368,136.341 17.229999,136.341 17.229999,75.636001 0,75.636001 23.987998,53.455336 23.987998,16.938999 53.620998,16.938999 53.620998,26.054981 z
			</Path.Data>
		</Path>
	</Border>

	<Border Margin="5" Padding="0" HorizontalAlignment="Left" VerticalAlignment="Top" BorderBrush="CadetBlue" BorderThickness="2">
		<IconSourceElement Width="90" Height="90">
			<IconSourceElement.IconSource>
				<PathIconSource>
					<PathIconSource.Data>
						M81.799,0 L163.599,75.636001 146.368,75.636001 146.368,136.341 17.229999,136.341 17.229999,75.636001 0,75.636001 23.987998,53.455336 23.987998,16.938999 53.620998,16.938999 53.620998,26.054981 z
					</PathIconSource.Data>
				</PathIconSource>
			</IconSourceElement.IconSource>
		</IconSourceElement>
	</Border>
</StackPanel>

The Path element succeeds because I set its Stretch property to Uniform, but this solution does not work for PathIconSource nor PathIcon -- they have no Stretch property. Thus PathIconSource and PathIcon are unusable and you're forced to use the Path element instead, which means that IconSourceElement is a nice idea but so badly broken that it's practically unusable currently.

The fact that PathIconSource and PathIcon don't scale the icon is especially strange when you consider that BitmapIconSource does scale the icon.

A second reason why PathIconSource and PathIcon are broken is that if you try to use the same icon in multiple buttons, pages, or places in your app, it fails (throws an exception). Unfortunately the Path element also suffers from the same failure, but it only fails in WinUI, not in WPF. In WPF, you can "freeze" a Geometry instance and then use it in an unlimited number of places in your app. For more info, see this issue:
PathIconSource claims to support sharing but throws exception (AKA shared Geometry issue) #827

If your PathGeometry instance represents a stroked figure instead of a filled figure, such as a "+" symbol consisting of a horizontal stroked lines over a vertical stroked line, then PathIconSource does not support your PathGeometry. See issue:
PathIcon/PathIconSource should allow stroke to be set as well as fill #1279

Library of icons in app (re ResourceDictionary)

Edited:
I remembered another important part of this issue. When using PathIconSource, obviously every app needs to store a collection of all the icons that the app uses (icons as paths/geometries in the case of PathIconSource). This should be super simple to do because WinUI already supports the excellent ResourceDictionary feature. Therefore, our problem is simply solved by storing the app's icons in a "MyResourceDictionary.xaml" file, right? But no, unfortunately this only works in WPF, whereas it is still broken in WinUI, even after the number of years that have elapsed since the release of UWP/WinUI.

In WPF, you can easily store a collection of icons in your app like this:

<ResourceDictionary xmlns="..." xmlns:x="...">

	<PathGeometry x:Key="HouseSymbol">
		M81.799,0 L163.599,75.636001 146.368,75.636001 146.368,136.341 17.229999,136.341 17.229999,75.636001 0,75.636001 23.987998,53.455336 23.987998,16.938999 53.620998,16.938999 53.620998,26.054981 z
	</PathGeometry>

	<PathGeometry x:Key="RefreshSymbol">
		...
	</PathGeometry>

	<PathGeometry x:Key="SettingsSymbol">
		...
	</PathGeometry>

</ResourceDictionary>

Actually, to be precise, in WPF, it's recommended to optimize the above by simply replacing PathGeometry with the optimized read-only equivalent of PathGeometry that is named StreamGeometry. Easily done:

<StreamGeometry x:Key="HouseSymbol">
	M81.799,0 L163.599,75.636001 146.368,75.636001 146.368,136.341 17.229999,136.341 17.229999,75.636001 0,75.636001 23.987998,53.455336 23.987998,16.938999 53.620998,16.938999 53.620998,26.054981 z
</StreamGeometry>

So that works great in WPF, but StreamGeometry is unsupported in WinUI. As for the other class, PathGeometry, it does exist in WinUI but it still produces a compile-time error message when you try to use it (PathGeometry) in a ResourceDictionary XAML file:

Error XLS0503
A value of type 'String' cannot be added to a collection or dictionary of type 'PathFigureCollection'.

This bug could be easily fixed AFAIK, because most of the necessary work is already done, therefore I find it surprising that this bug still hasn't been prioritized after this number of years. I thought it was standard recommended practice to increase the priority of a bugfix when the bug is easy to fix.

AFAIK the PathGeometry bug is easy to fix because the WinUI XAML compiler already compiles the following successfully, therefore most of the work is already done for PathGeometry.

<ResourceDictionary xmlns="..." xmlns:x="...">

	<Path x:Key="HousePathElement">
		<Path.Data>
			M81.799,0 L163.599,75.636001 146.368,75.636001 146.368,136.341 17.229999,136.341 17.229999,75.636001 0,75.636001 23.987998,53.455336 23.987998,16.938999 53.620998,16.938999 53.620998,26.054981 z
		</Path.Data>
	</Path>

</ResourceDictionary>

Although Path in ResourceDictionary compiles successfully, you should use PathGeometry not Path. Path is derived from Windows.UI.Xaml.FrameworkElement and Windows.UI.Xaml.UIElement, and each FrameworkElement instance is permitted to have only one parent FrameworkElement instance, and this won't change. Thus you cannot (and should not) try to share the same Path instance among multiple different buttons in your app where the same icon needs to be used in multiple places.

Unlike the Path element, PathGeometry and/or StreamGeometry are suitable for being shared/used in multiple places, but as I mentioned in issue #827, it only works in WPF. Currently WinUI malfunctions (throws an exception) when you try to share/use the same PathGeometry or PathIconSource instance in multiple places, even despite the fact that the documentation says that sharing is supported:

"PathIconSource is similar to PathIcon. However, because it is not a FrameworkElement, it can be shared."

Notice how the documentation says "because it is not a FrameworkElement". This is the same reason why the ResourceDictionary should contain PathGeometry not Path. Path derives from FrameworkElement whereas PathGeometry does not.

The conclusion is that WPF (but not yet WinUI) supports the storage of the app's icons in a "MyResourceDictionary.xaml" file. This is very strange when you consider the fact that the only thing stopping WinUI from supporting it is a small easily-fixed bug in the XAML compiler. (Or maybe the bugfix is more difficult to implement than it appears, because maybe some reason exists that I don't know about, but anyway, this bug needs to be fixed.)

Apps definitely need this ability to store their own icons/symbols, instead of being limited to predefined icons from Microsoft. SymbolIconSource is an excellent feature (thanks!) but obviously it's unreasonable to limit apps to using only the predefined icons/symbols in the Windows.UI.Xaml.Controls.Symbol enumeration.

Classes were not updated for IconSource

When the IconSourceElement and IconSource classes was created in WinUI in order to replace the defective IconElement subclasses, unfortunately various other classes were not updated accordingly. They should have been updated at the same time as when IconSource was released. For example, in order to update MenuFlyoutItem, this needed to be done:

  1. Create a property in MenuFlyoutItem named IconSource of type IconSource.
  2. Mark the old property MenuFlyoutItem.Icon as obsolete by applying System.ObsoleteAttribute. (This old property uses Windows.UI.Xaml.Controls.IconElement.)
public class MenuFlyoutItem : ...
{
	public Windows.UI.Xaml.Controls.IconSource IconSource { get; set; }

	[System.ObsoleteAttribute("Use IconSource property instead of Icon property.")]
	public Windows.UI.Xaml.Controls.IconElement Icon { get; set; }
}

The following have not yet been updated:

  • Windows.UI.Xaml.Controls.AppBarButton.Icon
  • Windows.UI.Xaml.Controls.AppBarToggleButton.Icon
  • Windows.UI.Xaml.Controls.MenuFlyoutItem.Icon
  • Windows.UI.Xaml.Controls.MenuFlyoutSubItem.Icon
  • Windows.UI.Xaml.Controls.NavigationViewItem.Icon
  • Windows.UI.Xaml.Controls.Primitives.NavigationViewItemPresenter.Icon
  • Windows.UI.Xaml.Controls.SettingsFlyout.IconSource (uses ImageSource not IconSource)

Already up-to-date:

  • Windows.UI.Xaml.Controls.SwipeItem.IconSource
  • Windows.UI.Xaml.Input.XamlUICommand.IconSource

Although the subclasses of IconSource currently render in a broken manner, this will be fixed and IconSource is still a good idea, thus the various other classes need to be updated to support IconSource instead of the old IconElement subclasses.

Conclusion: They're all broken!

Windows.UI.Xaml.Controls.IconSourceElement is a nice idea and its concept makes good sense, but unfortunately all subclasses of IconSource are currently broken:

  • BitmapIconSource
  • SymbolIconSource
  • FontIconSource
  • PathIconSource

Fixing this iconic disaster should be a high priority because icons are very common in apps. Despite the fact that nearly all apps use icons, icon rendering hardly works in WinUI!

@adrientetar
Copy link

A FontSize property is applicable to text but an icon is not text

In this case it is, that's why it's called FontIcon.

@verelpode
Copy link
Author

In this case it is, that's why it's called FontIcon.

It's called FontIcon not TextIcon therefore it shouldn't behave like text, but currently it does behave like text and this text-like behavior causes failures. We could interpret (or re-interpret) it as being named "FontIcon/FontIconSource" because the icon comes from a glyph in a font, and don't interpret the name "FontIcon" as meaning that it should behave like text. Thus it shouldn't have a property that controls the size of the text, but it does. It's meant to (or needs to) behave as an icon not text.

In order to control the icon size, wouldn't you prefer to set the Width and Height properties of IconSourceElement or an ancestor element of your choice, rather than trying to control the icon size via FontIcon/FontIconSource.FontSize?

Before you answer, keep in mind that the concept of IconSourceElement is better than its predecessors BitmapIcon, SymbolIcon, FontIcon, PathIcon. The issue is that BitmapIcon etc are fundamentally defective designs because, for example, if you write some XAML for a ControlTemplate, UserControl, or Page etc and your XAML displays an icon by using BitmapIcon, then the icon is locked to being a bitmap -- that's a problem. The icon cannot be later changed to a path-based or font-based icon because your XAML uses BitmapIcon and BitmapIcon only supports bitmap icons.

This problem cannot be solved by simply editing the XAML to change BitmapIcon to PathIcon whenever you want to switch from a bitmap to a path -- this doesn't work because the person who writes the XAML of a ControlTemplate is often a different person than the various people who use it. The solution is to use IconSourceElement instead of BitmapIcon etc, and then the ControlTemplate works for everyone regardless of what kind of icon they want/need to use, and the ControlTemplate XAML doesn't require modification whenever someone simply needs to display a different kind of icon.

Thus IconSourceElement is an excellent concept, but in practice it only succeeds if IconSourceElement.IconSource can be set to any subclass of IconSource (any kind of icon) without breaking the size of the rendered icon. This means that each subclass of IconSource needs to behave consistently in regards to icon size, but currently they behave wildly differently than each other.

Currently, when you use IconSourceElement in the XAML of your ControlTemplate or Page or wherever, you can easily configure your IconSourceElement instance in a way that makes it render perfectly when IconSourceElement.IconSource is set to BitmapIconSource, but then your IconSourceElement instance breaks (renders incorrectly) as soon as IconSourceElement.IconSource is set to FontIconSource, SymbolIconSource, or PathIconSource. This causes IconSourceElement to be practically unusable, or at least it defeats the purpose of IconSourceElement.

In order to make IconSourceElement.IconSource interchangeable with any subclass of IconSource (any kind of icon), each subclass of IconSource needs to render the icon consistently with the same size as BitmapIconSource and Controls.Image do, meaning all subclasses of IconSource need to scale the icon to fit the available space. IconSourceElement breaks when different different subclasses of IconSource use completely different ways of controlling icon size such as FontIconSource.FontSize.

Thus the existence of FontIconSource.FontSize represents a design defect and it should be removed. However, if people still desire the option to use FontIconSource.FontSize, then instead of removing this property entirely, it could be made optional, meaning it could operate like this:

  • When FontIconSource.FontSize is set to System.Double.NaN or defaults to NaN (similar to how the default value of FrameworkElement.Width is NaN), then it would render like BitmapIconSource, Controls.BitmapIcon, and Controls.Image already do: Scale the icon. This also makes the Width/Height/MinWidth/MaxHeight properties usable/settable in either IconSourceElement or an ancestor element of your choice.
  • When FontIconSource.FontSize is not NaN, then it would operate the same as it does today: The FontSize property controls the size of the icon instead of the normal behavior of scaling the icon. This mode might be useful in some circumstances, but the disadvantage of this mode is that it breaks the interchangeability of IconSourceElement.IconSource.

@verelpode
Copy link
Author

An analogy with the Image Control

Windows.UI.Xaml.Controls.Image defines these Source and Stretch properties:

public class Image : ...
{
	public Windows.UI.Xaml.Media.ImageSource Source { get; set; }
	public Windows.UI.Xaml.Media.Stretch Stretch { get; set; }
	...
}

The current design of the Image Control works well. Now imagine what would happen if you remove the Stretch property from Image and instead place it in ImageSource.

public class Image
{
	public Windows.UI.Xaml.Media.ImageSource Source { get; set; }
	...
}

public class ImageSource
{
	public Windows.UI.Xaml.Media.Stretch Stretch { get; set; }
	...
}

That would be madness, but let's imagine making it even worse by adding settable sizing properties to ImageSource akin to the Width/Height properties that Image contains/inherits from FrameworkElement:

public class FrameworkElement
{
	public double Width { get; set; }
	public double Height { get; set; }
	...
}

public class Image : FrameworkElement
{
	public Windows.UI.Xaml.Media.ImageSource Source { get; set; }
	...
}

public class ImageSource
{
	public Windows.UI.Xaml.Media.Stretch Stretch { get; set; }
	public double Width { get; set; }
	public double Height { get; set; }
	...
}

That would really be madness -- it'd cause chaos! I believe I don't need to explain why this would cause chaos, because everyone already understands and agrees that the Stretch, Width, Height properties need to be located in Image not in ImageSource. That's obvious.

However, despite the fact that everyone knows that placing Stretch, Width, Height in ImageSource would be madness, the current version of WinUI does engage in this madness anyway, but only in the case of IconSource not ImageSource.

I'm not saying that IconSource.Stretch exists (it doesn't exist), rather I mean that in principle IconSource subclasses behave with the same kind of madness as if IconSource.Stretch did exist:

  • BitmapIconSource renders like Windows.UI.Xaml.Media.Stretch.Uniform.
  • PathIconSource renders like Windows.UI.Xaml.Media.Stretch.None.
  • SymbolIconSource renders like Windows.UI.Xaml.Media.Stretch.None plus a constant size of 20.
  • FontIconSource renders like Windows.UI.Xaml.Media.Stretch.None plus a size determined by FontIconSource.FontSize. This FontSize property is the same madness as if ImageSource.Width/Height would exist instead of (or in addition to) Image.Width/Height.

In principle, the current behavior of IconSource subclasses is the same madness and chaos as if the Image.Stretch property would be moved to ImageSource.Stretch. Also in principle, FontIconSource.FontSize is the same chaos as if settable ImageSource.Width/Height properties would exist.

The WinUI team has repeatedly delivered impressive stuff, except for the dysfunctional icon rendering. No big deal; just fix it and become even greater! 😄

@jevansaks jevansaks added the feature proposal New feature proposal label Oct 25, 2019
@kikisaints
Copy link

@jevansaks - is this a proposal? It feels more like a discussion that should lead to one or more proposals.

@verelpode you make some really good points - to summarize and ensure I understand what you're saying, it's that:

  • IconSource's API structure/behavior is inconsistent with that of similar components, like Image and ImageSource
  • Subclassing IconSource to Bitmap/Symbol/Font/PathIconSource all result in different sizing behavior that isn't consistent and renders IconSource rather unusable because of this
  • If IconSource's sizing behavior operated in a similar way to how Image and ImageSource work, it would mean that FontIconSource is practically obsolete, because the need to size the icon would be mostly handled by the system or through height/width properties instead of a "FontSize" property.

Is the above summary correct?

@verelpode
Copy link
Author

Hi @kikisaints, thanks for the quick reply.

IconSource's API structure/behavior is inconsistent with that of similar components, like Image and ImageSource.

Correct.

Subclassing IconSource to Bitmap/Symbol/Font/PathIconSource all result in different sizing behavior that isn't consistent and renders IconSource rather unusable because of this.

Correct.

If IconSource's sizing behavior operated in a similar way to how Image and ImageSource work, it would mean that FontIconSource is practically obsolete, because the need to size the icon would be mostly handled by the system or through height/width properties instead of a "FontSize" property.

There's a typo in that point. The typo can be correct as follows:

"If IconSource's sizing behavior operated in a similar way to how Image and ImageSource work, it would mean that FontIconSource the property FontIconSource.FontSize is practically obsolete, because ...."

The FontIconSource class is a good idea; don't throw it in the garbage bin; just fix its problems and it will become great. The two problems with FontIconSource are:

  1. The sizing behavior / "FontSize" property as mentioned above.
  2. The glyph needs to be rendered without the whitespace/padding that currently surrounds the glyph. In other words, the whitespace/padding behavior of FontIconSource needs to be made consistent with SymbolIconSource. (To implement this fix, note that in WPF, BuildGeometry is one way of eliminating the whitespace/padding.)

I also suggest that the following points are important for inclusion in a summary:

  • A common requirement is to share or use the same icon in multiple different places in the app, but this fails (throws an exception) despite the documentation saying that PathIconSource supports sharing.
  • The WinUI XAML compiler fails to compile PathGeometry in ResourceDictionary XAML files. See details in my next message.

The first or second version of something is hardly ever great, but who cares? What I love about software development is that we can produce a third or fourth version that is great, and erase the mistakes of the first and second versions. The concept of IconSourceElement is solid and if a new version is released, then WinUI's support for icons can definitely become great. Success is not far away! 😄

@verelpode
Copy link
Author

Library of icons in app (re ResourceDictionary)

I remembered another important part of this issue. When using PathIconSource, obviously every app needs to store a collection of all the icons that the app uses (icons as paths/geometries in the case of PathIconSource). This should be super simple to do because WinUI already supports the excellent ResourceDictionary feature. Therefore, our problem is simply solved by storing the app's icons in a "MyResourceDictionary.xaml" file, right? But no, unfortunately this only works in WPF, whereas it is still broken in WinUI, even after the number of years that have elapsed since the release of UWP/WinUI.

In WPF, you can easily store a collection of icons in your app like this:

<ResourceDictionary xmlns="..." xmlns:x="...">

	<PathGeometry x:Key="HouseSymbol">
		M81.799,0 L163.599,75.636001 146.368,75.636001 146.368,136.341 17.229999,136.341 17.229999,75.636001 0,75.636001 23.987998,53.455336 23.987998,16.938999 53.620998,16.938999 53.620998,26.054981 z
	</PathGeometry>

	<PathGeometry x:Key="RefreshSymbol">
		...
	</PathGeometry>

	<PathGeometry x:Key="SettingsSymbol">
		...
	</PathGeometry>

</ResourceDictionary>

Actually, to be precise, in WPF, it's recommended to optimize the above by simply replacing PathGeometry with the optimized read-only equivalent of PathGeometry that is named StreamGeometry. Easily done:

<StreamGeometry x:Key="HouseSymbol">
	M81.799,0 L163.599,75.636001 146.368,75.636001 146.368,136.341 17.229999,136.341 17.229999,75.636001 0,75.636001 23.987998,53.455336 23.987998,16.938999 53.620998,16.938999 53.620998,26.054981 z
</StreamGeometry>

So that works great in WPF, but StreamGeometry is unsupported in WinUI. As for the other class, PathGeometry, it does exist in WinUI but it still produces a compile-time error message when you try to use it (PathGeometry) in a ResourceDictionary XAML file:

Error XLS0503
A value of type 'String' cannot be added to a collection or dictionary of type 'PathFigureCollection'.

This bug could be easily fixed AFAIK, because most of the necessary work is already done, therefore I find it surprising that this bug still hasn't been prioritized after this number of years. I thought it was standard recommended practice to increase the priority of a bugfix when the bug is easy to fix.

AFAIK the PathGeometry bug is easy to fix because the WinUI XAML compiler already compiles the following successfully, therefore most of the work is already done for PathGeometry.

<ResourceDictionary xmlns="..." xmlns:x="...">

	<Path x:Key="HousePathElement">
		<Path.Data>
			M81.799,0 L163.599,75.636001 146.368,75.636001 146.368,136.341 17.229999,136.341 17.229999,75.636001 0,75.636001 23.987998,53.455336 23.987998,16.938999 53.620998,16.938999 53.620998,26.054981 z
		</Path.Data>
	</Path>

</ResourceDictionary>

Although Path in ResourceDictionary compiles successfully, you should use PathGeometry not Path. Path is derived from Windows.UI.Xaml.FrameworkElement and Windows.UI.Xaml.UIElement, and each FrameworkElement instance is permitted to have only one parent FrameworkElement instance, and this won't change. Thus you cannot (and should not) try to share the same Path instance among multiple different buttons in your app where the same icon needs to be used in multiple places.

Unlike the Path element, PathGeometry and/or StreamGeometry are suitable for being shared/used in multiple places, but as I mentioned in issue #827, it only works in WPF. Currently WinUI malfunctions (throws an exception) when you try to share/use the same PathGeometry or PathIconSource instance in multiple places, even despite the fact that the documentation says that sharing is supported:

"PathIconSource is similar to PathIcon. However, because it is not a FrameworkElement, it can be shared."

Notice how the documentation says "because it is not a FrameworkElement". This is the same reason why the ResourceDictionary should contain PathGeometry not Path. Path derives from FrameworkElement whereas PathGeometry does not.

The conclusion is that WPF (but not yet WinUI) supports the storage of the app's icons in a "MyResourceDictionary.xaml" file. This is very strange when you consider the fact that the only thing stopping WinUI from supporting it is a small easily-fixed bug in the XAML compiler. (Or maybe the bugfix is more difficult to implement than it appears, because maybe some reason exists that I don't know about, but anyway, this bug needs to be fixed.)

Apps definitely need this ability to store their own icons/symbols, instead of being limited to predefined icons from Microsoft. SymbolIconSource is an excellent feature (thanks!) but obviously it's unreasonable to limit apps to using only the predefined icons/symbols in the Windows.UI.Xaml.Controls.Symbol enumeration.

Note my message here is a different issue than #827 because #827 describes the sharing failure whereas the main point of my message here is the failure of the XAML Compiler to compile PathGeometry in ResourceDictionary.

@verelpode
Copy link
Author

Classes were not updated for IconSource

When the IconSourceElement and IconSource classes was created in WinUI in order to replace the defective IconElement subclasses, unfortunately various other classes were not updated accordingly. They should have been updated at the same time as when IconSource was released. For example, in order to update MenuFlyoutItem, this needed to be done:

  1. Create a property in MenuFlyoutItem named IconSource of type IconSource.
  2. Mark the old property MenuFlyoutItem.Icon as obsolete by applying System.ObsoleteAttribute. (This old property uses Windows.UI.Xaml.Controls.IconElement.)
public class MenuFlyoutItem : ...
{
	public Windows.UI.Xaml.Controls.IconSource IconSource { get; set; }

	[System.ObsoleteAttribute("Use IconSource property instead of Icon property.")]
	public Windows.UI.Xaml.Controls.IconElement Icon { get; set; }
}

The following have not yet been updated:

  • Windows.UI.Xaml.Controls.AppBarButton.Icon
  • Windows.UI.Xaml.Controls.AppBarToggleButton.Icon
  • Windows.UI.Xaml.Controls.MenuFlyoutItem.Icon
  • Windows.UI.Xaml.Controls.MenuFlyoutSubItem.Icon
  • Windows.UI.Xaml.Controls.NavigationViewItem.Icon
  • Windows.UI.Xaml.Controls.Primitives.NavigationViewItemPresenter.Icon
  • Windows.UI.Xaml.Controls.SettingsFlyout.IconSource (uses ImageSource not IconSource)

Already up-to-date:

  • Windows.UI.Xaml.Controls.SwipeItem.IconSource
  • Windows.UI.Xaml.Input.XamlUICommand.IconSource

@jevansaks jevansaks added the team-Controls Issue for the Controls team label Nov 7, 2019
@msft-github-bot msft-github-bot added the needs-triage Issue needs to be triaged by the area owners label Nov 7, 2019
@jevansaks jevansaks removed the needs-triage Issue needs to be triaged by the area owners label Nov 7, 2019
@verelpode
Copy link
Author

verelpode commented Nov 12, 2019

Icons in "Visual Assets" in manifest

On the topic of icons, unfortunately I also had a disappointing experience when configuring the icons in the "Visual Assets" tab in the "Package.appxmanifest" of a WinUI UWP app in Visual Studio 2019.

Lack of knowledge of runtime image scaling

The current design of "Visual Assets" represents a surprising lack of knowledge of the commonly-known fact that at runtime an image can be quickly and easily rendered at a smaller or larger size -- scaled to fit any rectangle. This rendering-with-scaling is quick regardless of whether the app is running in a smartphone or desktop computer. When the image is rendered at exactly 50% or 25% size, the scaling is even faster and delivers excellent image quality. Here is a screenshot of the current GUI for "Large Tile":

image

As you can see above, it recommends that the app developer provide 3 sizes of the same image, plus 2 optional sizes (up to 5 sizes of the same image). Thus it represents lack of knowledge of the fact that only one image file is required for "Large Tile" because the image can be scaled at runtime.

As I mentioned, the quality and speed is especially good when the rendered size is 50% or 25% of original. As you can see in the screenshot above, the 3 recommended sizes are 1240, 620, and 310 and those are multiples of 310. 50% of 1240 is 620, and 25% of 1240 is 310. Thus if only one image is provided, and if that one image is 1240x1240 px, then the 620 and 310 versions can be rendered at runtime with excellent image quality and speed, even better than if they weren't multiples. The current GUI for configuring "Large Tile" (with 5 sizes of the same image) is nonsense.

"Scaling Mode" option makes no sense

This lack of knowledge of image scaling is further evident in the "Scaling Mode" option that provides 2 choices named:

  • "Bicubic (Sharper Edges)"
  • "Nearest Neighbor (Smoother Edges)"

Both of those descriptions are wrong. For "Nearest Neighbor", it says "Smoother Edges", but Adobe Photoshop says the opposite: "Nearest Neighbor (preserve hard edges)". Visual Studio says the opposite of both Photoshop and Wikipedia. Wikipedia says "Nearest-neighbor ... introduce jaggedness in previously smooth images."

Not only are the descriptions wrong, but Visual Studio's "Scaling Mode" option shouldn't exist at all, because "Nearest Neighbor" never produces a better result than bicubic scaling (for the purpose of Visual Studio). Furthermore, the scaling should be performed at runtime, not in Visual Studio, meaning only one image file should be provided for "Large Tile". Thus the "Scaling Mode" option should be removed from "Visual Assets".

Word wrapping is broken

Another problem is word wrapping. In the section titled "Display Settings", you can enter a name in the textbox "Short name" and you can tick "Show name", but when the tile is displayed in the Start menu, the name fails to wrap onto 2 lines, despite the fact that other Microsoft products somehow do achieve 2 lines. For example, MS Blend displays as:

image

In your own app, if you set "Display Settings" to "Blend for Visual Studio 2019", then it appears with only one line, truncated:

image

Nonsense file names

For "Small Tile", the default file name is "SmallTile.png" and that makes sense. Likewise for "Large Tile", the default file name is "LargeTile.png" and again that makes sense. Now what do you think the file name is for "Medium Tile"? A sensible guess would be "MediumTile.png", but no, the name is "Square150x150Logo.png", even when the PNG file is not 150x150 pixels. That's nonsense.

The problem repeats itself for "App Icon". What do you think the file name is for "App Icon"? A sensible guess would be "AppIcon.png", but no, the name is "Square44x44Logo.png", even when the PNG file is not 44x44 pixels. Likewise for "Wide Tile", you'd expect "WideTile.png", but no, the name is "Assets\Wide310x150Logo.png". The file name says "Logo" instead of "Tile", and it says 310x150 even when the PNG file is not 310x150 pixels.

A file named "Wide310x150Logo.scale-200.png" is not 310x150 pixels. It's actually 620 x 300 pixels. The file name includes the text "scale-200" but that's ridiculous, as I explained previously in regards to runtime image scaling and 50% and 25%.

When you click any asset within the "Large Tile" section, such as when you click 620x620 px, a window appears and describes the asset incorrectly. It says the wrong name and wrong size. Instead of saying "Large Tile 620x620", it says "Square 310x310 logo". It says: "This asset is used for the Square 310x310 logo field and is shown in the following location(s)." The underlying XML schema says "Square310x310Logo" but unfortunately that design is nonsense.

Requirement for "Wide Tile" is nonsense

Here is a screenshot of the nonsensical message that appears when you try to delete "Wide Tile":

image

Reasons why that message is nonsense:

  • The words "Square 310x310 logo" are nonsense -- it actually means "Large Tile".
  • The logic of the requirement is reversed. Logically speaking, if the Medium and Large Tiles are supplied, then they can also be used to render the Wide Tile by default, by rendering the icon in the center of the Wide Tile. If you have a medium icon, you can use it to render a wide tile, but the message says the opposite: It says if you have an icon, then you must provide another icon. It's nonsense.
  • (I do realize that some apps will want or need to supply a Wide Tile image, but it shouldn't be mandatory, and it shouldn't have 5 size of the same image.)

In the "Wide Tile" section, 3 assets are recommended, but nothing should be recommended by default in Wide Tile, and nothing in Wide Tile should be mandatory (regardless of whether "Square 310x310" is supplied). "Wide Tile" can be supported but it's hardly a good recommendation. Except for games, none of the Microsoft apps use the "Wide Tile" visual asset. The Microsoft Weather app does not use it either. Weather supports wide tiles via live tile, NOT via a Visual Asset.

"Medium Tile" is mandatory for no reason

I fully supplied the "App Icon" section of "Visual Assets", and then I tried to delete the unnecessary images in the "Medium Tile" section, and then it displayed the following nonsensical error message:

image

That error message is nonsense because:

  1. The words "Square 150x150 logo" are incomprehensible and need to be replaced with a choice of words that people can actually understand, meaning it needs to say "Medium Tile" instead of "Square 150x150 logo". I have a double degree from a respected university but the words "Square 150x150 logo" are still mumbo-jumbo that I could not understand and were forced to decipher.
  2. The error message does not state any reason for making "Medium Tile" mandatory, because no reason exists, but if something will be made mandatory, then it's necessary to have at least one reason for making it mandatory. In this case, the number of reasons is zero, thus it shouldn't be mandatory.
  3. The idea of making "Medium Tile" contain a duplicate of the image in "App Icon" makes no sense. There is no need for "Visual Assets" to produce so many duplicates of the same image.

Here is a sensible design: If "Medium Tile" is supplied, then use it. If it's unsupplied, then use the image(s) in "App Icon" to render the "Medium Tile" at runtime, as the default behavior. Visual Studio's default behavior of duplicating the same image in "Medium Tile" and "App Icon" makes no sense. You click the "Generate" button and suddenly you have many unnecessary duplicates of the same image!

Other problems in "Visual Assets"

  • The "Visual Assets" GUI fails to provide any way to delete an unwanted asset or scale. You can delete an entire group but not an individual scale.
  • When you click the 1240 x 1240 large tile, it displays the image in a window but the window has no scrollbars and the window is so large that the "Close" button is offscreen, despite the fact that my computer has a relatively large monitor attached.
  • Too many assets are recommended yet unnecessary and serve no purpose.
  • By default, the "Asset Generator" auto-generates images for "App Icon" and tiles, but it strangely also generates an image for the splashscreen, despite the fact that it makes no sense to display an icon as a splashscreen.
  • "Apply recommended padding" would be more useful if it allowed the app developer to choose an amount of padding, instead of using the "recommended" amount that doesn't work well for all icons/tiles.
  • When you click "Large Tile" on the lefthand side, you expect it to show the settings for "Large Tile", but it also shows some settings that affect "Medium Tile" and "Wide Tile" (the settings in the "Display Settings" section).

@verelpode
Copy link
Author

verelpode commented Nov 12, 2019

On a few occasions in the past, I produced amateurish work, but I'm proud to say that I revisited my work and transformed it from amateurish to professional, and the customers loved receiving the improvements. Everyone produces amateurish work sometimes. The current version of "Visual Assets" is one of these examples of things that need to be transformed from amateurish to professional.

Here is a screenshot of the files that Visual Studio 2019 produces when you auto-generate every image in "Visual Assets". A fair and accurate description of this behavior is: Amateurish. The file list is not long because it's advanced and powerful. In reality, the list is long because it's amateurish work and falls far below the usual high standards of UWP. Many things in UWP are advanced and powerful and wonderful, but "Visual Assets" is not yet one of them.

image

Microsoft has experienced some difficulties in convincing app developers to develop for Windows Phone instead of (or in addition to) Android and Apple iOS. One factor to keep in mind is the effect of first impressions. First impressions count. When an app developer used other products in the past, and one day uses Visual Studio for the first time, what will his/her first impression be?

The first impression when seeing "Visual Assets" is that Microsoft seems amateurish, and then the app developer begins to wonder: "If Microsoft couldn't even manage to do the app icon/tile, then what's the rest of UWP like? Is the whole thing amateurish?"

In reality, UWP is really great stuff -- UWP is advanced and professional -- but app developers can be misled by the bad first impression of "Visual Assets". What happens next? App developers swallow the amateurish "Visual Assets" and then start writing an app and they try to create some icons inside of their app, and then they discover that WinUI's icon rendering is badly broken, hardly works, and the first impressions deteriorate even further. This is a sad result because in reality many things in WinUI and UWP are wonderful, but the first impressions (icons) can mislead developers into thinking that UWP is low quality.

@moshegutman
Copy link

I struggled with that form too. I was trying to figure out the unplated/plated/light mode/dark mode rules and this form was no help. It is a very unintuitive “tool”.

@verelpode
Copy link
Author

@moshegutman -- Oh yes, "unplated" is another problem; thanks for reminding me. I can explain "unplated". Surprisingly, the newly-invented term/jargon "unplated icon" means "a normal icon" in the normal sense of the word "icon".

This raises the question: If "unplated icon" just simply means a normal icon, then why not speak normally and just simply say "icon" instead of confusing everyone by inventing a new term that means the same as the preexisting word "icon"?

I can think of two possible answers to this perplexing question. I'm pretty sure that the answer is one of these:

  1. An honest mistake; or
  2. The same as the reason why lawyers and judges invented a bunch of legal jargon: Because it sounds impressive and intelligent to use jargon, and it separates "insiders" from "outsiders". In reality, the use of obscure legal jargon (or tax jargon) represents juvenile behavior, but it sounds intelligent and it impresses people, and that's why lawyers, judges, and accountants use it, despite the juvenile and unprofessional nature of such behavior. I wish they would just grow up, but unfortunately it's not going to happen.

In the case of the "unplated" jargon, I think the answer is probably number 1, an honest mistake. In various other cases in life, the answer is number 2.

@moshegutman
Copy link

moshegutman commented Nov 12, 2019

Yeah, I think it goes back to the windows phone days where the tile background in the start menu is the “plate” that the icon is on. But either way, through Visual Studio it isn’t possible to make all the variations of icons needed for a proper app.

@mdtauk
Copy link
Contributor

mdtauk commented Nov 12, 2019

I suspect that the Visual Assets recommendations will be changing with WinUI 3.0 - because of the new icon styles used by Windows 10 X

@verelpode
Copy link
Author

Here are a few more things that are unfortunately bungled in "Visual Assets".
Firstly, imagine that I wrote an app and in my app there is a place to choose a color for some purpose. However, instead of using something like ColorPicker, I use TextBox and require the user to type in a hexadecimal RGB color. It would be accurate to describe that part of my app as amateurish. As a matter of fact, I really did that once, in a real app, but later I improved it and eliminated my amateurish work. I'd expect the same to be done for "Visual Assets" -- fix it. In the following screenshot, I've circled the part of "Visual Assets" that has the amateurish way of choosing colors:

image

More is bungled. The following screenshot shows the default setting of "Tile background" -- "transparent". When "Tile background" is "transparent", the tile background is opaque! Yes, in this case, "Visual Assets" uses the word "transparent" to mean "opaque". How can you configure it to be truly transparent? You cannot. It's always opaque. I have no complaint about it being always opaque, but if it's always opaque, then it shouldn't say transparent. "Visual Assets" uses the word "transparent" to mean "non-transparent default tile background color".

image

@mdtauk wrote:

I suspect that the Visual Assets recommendations will be changing with WinUI 3.0 - because of the new icon styles used by Windows 10 X

I haven't looked at 10X, but do you mean the "Windows Light Theme"? If yes, then this is already in Visual Studio 2019 -- see the icons called "Light Unplated Target" in the "App Icon" section of "Visual Assets".

In the "Asset Generator" section, the option "Apply color conversion for Windows Light Theme" seems to be badly broken, or at least it didn't work with the icons I tested it with. I didn't have time to perform a comprehensive test with many icons, but I did test the main feature that should work: I tested with an icon that has a light gray border meaning it is intended for use on a dark background. This means that for the "Windows Light Theme", the light version of the icon needs the light gray border to be changed to a dark gray border, but "Apply color conversion for Windows Light Theme" completely failed to do this. It did make a modification to the icon, but it was a weird pixelated modification that didn't appear to be even remotely successful.

Not often, but occasionally Microsoft does attempt impossibly difficult tasks -- tasks that are far too difficult to achieve, even for a company as large as Microsoft. My impression of "Apply color conversion for Windows Light Theme" is that it seems to be one of these few cases where Microsoft attempts an impossibly difficult task. Therefore I think that Microsoft shouldn't attempt to repair this option, rather Microsoft should remove it entirely, because Microsoft does not possess sufficient resources to achieve impossibly difficult tasks.

Alternatively, if it won't be removed, then give it a completely different name such that it will no longer be an impossibly difficult task.

I gave this issue the title "An Iconic Disaster" because the current situation for icons really is an iconic disaster. The icon support is terrible currently. But overall UWP and WinUI are excellent. Keep up the good work! 😄

@verelpode
Copy link
Author

verelpode commented Nov 15, 2019

Unfortunately I still haven't finished the substantial work of documenting the list of defects in "Visual Assets" ☹️
In the following screenshot, you can see that I've set "Tile background" to a blue color, and understandably this blue color is displayed in the previews in the sections "Small Tile", "Medium Tile", "Large Tile". That part of it behaves correctly.

image

"Tile background" behaves incorrectly in the "App Icon" section:

image

You can see in the above screenshot that the first row is labelled "Scaled Assets" but the other 3 rows are missing their labels -- that's a strange inconsistency. The last 2 rows are the so-called "unplated icons" meaning actually "normal icons" that don't have a plate/tile. Confusingly, Visual Assets uses multiple different words for the same things, thus plate = tile, and unplated = non-tile. As you can see above, the non-tile icons (the last 2 rows) are incorrectly rendered with the blue tile background. Obviously that's a mistake because non-tile icons shouldn't be rendered as tiles, thus the color specified in the "Tile background" textbox shouldn't be rendered under the non-tile ("unplated") icons, but it is.

If you click on any of the unplated icons, it displays a window like the following, and you can see it says the icon is used in Windows Explorer etc, but NOT used as a tile. The "Tile background" color is incorrectly rendered in the preview despite the fact that it isn't a tile.

image

A few other defects are also visible in the above window, such as the wrong name ("Square 44x44 Logo"), and also the fact that it doesn't say "unplated" in this window despite the fact that I clicked on an icon that did say "unplated".

To summarize, the defects in the "App Icon" section include these:

  • The "Tile background" color is incorrectly rendered underneath non-tile ("unplated") icons (the last 2 rows).
  • The purpose of each row is only displayed for the first row (the first row is labelled "Scaled Assets" but the other rows are unlabelled). For the remaining 3 rows, the purpose is displayed only in a tooltip when the mouse pauses above one of the previews. That's inconsistent and bad GUI design.
  • Lack of knowledge that images can be scaled at runtime. The 176x176 size is ridiculous. The following image sizes should be removed because they should be scaled at runtime from the 256x256 image: 176x176, 88x88, 66x66, 55x55, 48x48, 44x44.
  • The 16x16 size is ridiculous and should be removed. We're not living in the 1990's anymore. Nowadays computer and smartphone screen resolutions are much higher than in 1995, thus the tiny 16x16 size is ridiculous considering that 1995 was 25 years ago. As for the 32x32 size, it could be retained (an exception could be made for this small size) because it is so small that runtime scaling may produce an unsatisfactory result (when 256x256 is scaled to 32x32). Re 16x16, the need to render the icon at 16x16 size is unlikely but if it happens, then at runtime the 32x32 icon can be scaled to 16x16.
  • When using "Asset Generator" with default/recommended settings (when "Recommended Scales" is ticked), it auto-generates three 16x16 image files. This behavior makes no sense. It's completely illogical. If 16x16 is an auto-generated image, then there is no need to supply it. It's only logical to supply a 16x16 image if it is manually created by a graphic designer person who specially tweaks/adjusts it in order to make its appearance acceptable at such a tiny size.
  • It can be justifiable to supply multiple image sizes if they're manually created/tweaked images, whereas it's nonsense if they're auto-generated by "Asset Generator" because if they're auto-generated then they can be scaled at runtime. Back in the 1990's, it was slow to scale an image at runtime, but that was long ago, and nowadays we don't need to pre-generate many sizes of the same image.
  • It doesn't provide any way to delete one of the images within the "App Icon" section. For example, it doesn't allow you to click or right-click 44x44 and then click a "Delete" button or command.
  • The preview for 256x256 is rendered smaller than the preview for 176x176. That's the reverse of what you'd expect, considering that 256x256 is actually larger than 176x176. Various other previews also exhibit strange sizes.
  • The "App Icon" section uses absurd file names such as "Square44x44Logo.targetsize-256.png". The default file name for the "App Icon" section is expected to be "AppIcon.png" like how the "Small Tile" section uses "SmallTile.png". However, "App Icon" uses a nonsensical file name: "Square44x44Logo-XXXXXX.png". The name is especially nonsensical because it generates multiple variations of "Square44x44Logo-XXXXXX.png" (such as "Square44x44Logo.targetsize-256.png") that all say "44x44" despite the fact that most of these PNG files are NOT 44x44 pixels.
  • It uses multiple different names for the same things. "Unplated icon" = a normal icon. "Plate" = tile. "Square44x44Logo.png" = "App Icon". And others.

Icons and tiles for an app should be a simple issue. It shouldn't require a PhD to understand it. It shouldn't require hours of deciphering. It shouldn't require the following ridiculous translation table.

Term Meaning
Asset Image.
Unplated icon A normal icon in the normal sense of the word "icon". There was no need to invent a confusing new term for normal icons.
Plate The same as tile. A duplicate term for the same thing.
Alternate Form (altform) Normal form. Unplated form.
Square 44x44 Logo App Icon. Although it says 44x44, these images are mostly not 44x44.
Square 71x71 Logo Small Tile. Although it says 71x71, these images are mostly not 71x71.
Square 150x150 Logo Medium Tile. Although it says 150x150, these images are mostly not 150x150.
Wide 310x150 Logo Not logo. Actually means tile, specifically "Wide Tile". Although it says 310x150, these images are mostly not 310x150.
Square 310x310 Logo Large Tile. Although it says 310x310, these images are mostly not 310x310.
Lock Screen Logo Badge Logo.
Store Logo Package Logo.
transparent Non-transparent. It means opaque default tile background color.
Bicubic (Sharper Edges) Softer edges.
Nearest Neighbor (Smoother Edges) Jagged edges.
Scale 100 Does not mean 100%. It actually means an arbitrarily chosen size such as 150x150 pixels. For "Medium Tile", the so-called "Scale 100" means 150x150 pixels but no reason exists to explain why an arbitrary size such as 150x150 pixels should be called "100%". The scaling system of "Visual Assets" is illogical.
Scale 400 The largest image supplied.
Scale 200 An unnecessary useless duplicate of the exact same image as "Scale 400", but scaled to 50% of the image "Scale 400". Serves no real purpose because normally images are scaled at runtime, not prior to compile-time. There is no reason to pre-generate multiple sizes of the same image.
Scale 150 Another unnecessary duplicate that serves no real purpose.
Scale 125 Yet another unnecessary duplicate that serves no real purpose. This image size served a purpose back in the year 1995 because back then it was slow to scale an image at runtime, but that was 25 years ago! Nowadays we don't need to store many duplicates of the same image.

I'd like to hilite an excellent piece of advice that @codendone mentioned in another issue. Although the other issue was unrelated to icons, this advice is also applicable to icons and many other topics in general. He wrote:

There are a couple challenges which come up: API: How do we keep the API simple yet still support full flexibility so it isn't too limited?

That's an important principle. The current version of "Visual Assets" runs very contrary to this important principle. I don't say that "Visual Assets" should be reduced to only one single PNG file, but it shouldn't be 55 PNG files. Let's not jump to either extreme. Currently it generates/uses up to 55 PNG files -- that's ridiculous. A reasonably balanced solution is needed and 55 images is far away from being reasonably balanced between simplicity and full functionality. The full functionality can be retained with a much simpler design of "Visual Assets".

@verelpode
Copy link
Author

I've saved the best for last. Here is the number 1 most absurd thing about the current version of "Visual Assets". When you use "Asset Generator" with its "Recommended Scales" setting, and you want to use the full tile area thus you untick "Apply recommended padding" (or tick it if you want), and you give it a source tile image of a reasonable size such as 300x300 or whatever, then as I said it generates many unnecessary smaller duplicates of the same image for no reason, but that's not all it does. Here comes the number 1 most absurd thing: In the "Large Tile" section, it takes the 300 x 300 source image file and scales it UPWARDS to produce a big blurry 1240 x 1240 PNG file that consumes roughly 1 megabyte on average!!

That upwards scaling to 1240 x 1240 is so absurd that if Mac users knew about this, they'd burst out laughing. Scaling it downwards is bad enough, but scaling it upwards is just... so... ridiculous. It's not any exaggeration whatsoever to describe it as absurd. Mac fanatics will say it's hilarious. It's even worse than I said because the 1240 x 1240 PNG file isn't the only one. It's one of multiple upscaled image files. It also scales up the 300x300 source image to produce PNG files of sizes 310x310, 310x150, 620x620, 620x300, 600x600, and 1240x600.

It's still even worse than I said. The default setting also includes scaling up the 300x300 image to produce a 2480 x 1200 splashscreen that also consumes roughly 1 megabyte on average. And a 1240 x 600 splashscreen. Wait, there's one more: It also scales upwards to a 620 x 300 splashscreen.

I do realize that the "Scale 400" image files are supposed to correspond with the setting in Start menu / Settings / Display / "Scale and layout", but this reasoning is completely illogical. It makes no sense whatsoever. 400% doesn't even exist in the ComboBox in "Scale and layout", and even if 400% did exist there, it would still be completely illogical to pre-generate upscaled PNG files.

The behavior of "Visual Assets" is just beyond belief. It's very unusual for Microsoft to publish something of very low quality, but this time it happened unfortunately. "Visual Assets" is extraordinarily low quality software.

@charlesroddie
Copy link

Instead of fixing all the resolution problems in @verelpode 's posts on visual assets directly, you could just obviate them by making a large simplification.

  1. SVG are by far the most important case, as almost all icons are vector graphics. A single svg file should be usable, with no need to generate or display scaled assets.
  2. To support bitmaps (for backwards compatibility), a single high-res image can be used for each case, and if there is a need to use smaller ones, these can be generated as a release build step. Again there is no need to display scaled assets in the UI. There isn't any need to support manual specification of multiple versions of the same image.

@verelpode
Copy link
Author

@charlesroddie -- I believe you've described an excellent solution that fits the needs: A modern design with a good balance between power and simplicity. Surely nobody will be able to think of a better plan than what you said.
Additionally, the same plan could also be applied to both of "external" icons ("Visual Assets") and "internal" icons displayed within the app, or at least X% of the source code could be shared between the "internal" and "external" icon scenarios when it operates like you described.

For comparison purposes, Android supports SVG icons, although the SVG must be converted first (AFAIK). Android has a GUI-based tool that converts the source SVG file to Android's own vector format called VectorDrawable. I think the following items belong in the list of top 10 reasons why Android won the battle between Android versus WinRT/UWP:

  1. vector graphics files,
  2. vector icons,
  3. managed code (Java),
  4. etc.

This is a good opportunity for Microsoft to change some things in order to attract more developers to UWP.

@lukasf
Copy link

lukasf commented Jan 16, 2020

@verelpode I think it would be more productive to not write these things in a "rant" kind of manner. But I fully agree with the IconSource and Path issues you pointed out, and also the flaws of the assets area. I ran into many of these problems myself.

But you miss some things about assets:

  1. It sure makes sense to provide different images for different target sizes. If you simply scale an icon up or down a lot, the result will look poor. If you optimize the icon for a specific resolution (e.g. change line sizes, font sizes, increase or decrease sharpening, add or remove details, add/remove borders), the result will look a lot better. The assets generator is only there to get you started quickly, later you should work on providing better, optimized icons.

  2. If you provide only one, high resolution image, then the system must always decode and scale that high res image, even if only a tiny 32x32 icon is to be shown in Windows Explorer. That leads to unneccessarily high CPU and memory usage. So I can see why they force us to ship pre-generated images for different formats and scale factors. But these could also be pre-generated during build, if you do not provide them yourself. A preview in the assets area could show you how good (or bad) your scaled images will look, so you can decide where to optimize and provide better versions, and where to use auto scaling.

  3. Adding SVG support will help a lot, but it will not solve all issues, because creating SVG images will require you to use very different tooling. If someone is used to work with Photoshop, they will want to continue with that (and that means, creating multiple scaled and optimized versions). And even if you use SVG, it probably makes sense to optimize for different targets sizes, by adding or removing details, adapting line sizes, etc etc. And I am not 100% sure on this, but I guess decoding SVG is rather CPU intensive, at least for detailed icons. It could still make sense to provide pre-generated (maybe auto-generated during build) JPG or PNG files, at least for icons to be shown in Windows Explorer.

I'd recommend you to create three separate, real proposals, one for the IconSourceElement issues, one for Path issues and one for assets area (that one is not really WinUI related, still it should appear here to create awareness). And I think you should try to just write down things neutrally, without making it a rant. Let's just say that there is still some room for improvement in these areas :)

@dragonwolf83
Copy link

16x16 icons are far from obsolete. Small icons are required for list views like in Windows Explorer detail or list modes. They are used for status icons and titlebar icons, favicons, etc. They have a valid use case and a good app considers all the use cases and adapts their UI accordingly. You can certainly scale a bigger icon into a title bar, but then you are breaking the UX by wasting space in a Window Frame rather than giving that space to the Content.

This could be summed up as adaptable vs scaling UIs. Adaptable makes sure the icon works best for the placement, position, readability, etc. that is needed for it's use case. Scaling ensures its readable across different DPIs and form factors.

@charlesroddie
Copy link

charlesroddie commented Jan 19, 2020

Any x*x icons are obsolete since Windows Vista which introduced good support for dpi. Since scaling in windows can be anything, you would need to support every possible integer x of you do it that way. @verelpode is being constructive with detailed analysis. If you want images to vary by size and be sharp then two or three svgs should be used for the same icon.

@verelpode
Copy link
Author

@dragonwolf83

16x16 icons are far from obsolete.

Although I view 16x16 as obsolete, and although I view @lukasf's varying line thicknesses as overkill, nevertheless I would be willing to support a modified version of @charlesroddie's suggestion that supports those abilities, as follows. A single icon would consist of a list of images. Each image in the list can be either SVG or PNG. Thus a single icon consists of zero or more SVG images and zero or more PNG images.

The size of each PNG in the source image list should be determined by the app developer's own preferences (not by Visual Studio). For example, an app developer would be able to configure a single icon to consist of these 4 source images:

  1. An SVG image.
  2. A 512x512 PNG image.
  3. A 32x32 PNG image.
  4. A 16x16 PNG image.

I believe @lukasf, @mdtauk, and @dragonwolf83 should be happy now because the suggested plan includes support for what they want.

Visual Studio shouldn't stop you from supplying a non-standard size. For example, if you want to display wide 48x32 icons inside your app, then Visual Studio shouldn't stop you from supplying a 48x32 PNG image. The sizes of the supplied source images should be your own choice. When an icon is rendered at runtime, obviously it should inspect the list of images in the icon, and select whichever one is the best/closest match for the destination rectangle and resolution.

@charlesroddie

If you want images to vary by size and be sharp then two or three svgs should be used for the same icon.

Good point. I had already thought about multiple PNG images in the same icon, but I didn't realize that multiple SVG images in the same icon could be used to support varying line thicknesses, font sizes, borders. Note this idea of multiple SVG images only succeeds if each SVG image can be marked with a width and height, but SVG already supports this, IIRC. Even if I've remembered incorrectly and SVG doesn't support storage of a width and height, it would be trivially easy to separately store a width and height with each SVG image in the icon. So the point is, yes, a single icon can consist of a list of images, and each image should be either SVG or PNG.

@lukasf

Blurry, badly scaled images look horrible.

When scaling an image at runtime, some software still uses a very old and obsolete scaling algorithm that delivers poor image quality: The "Nearest Neighbor" algorithm. The use of this obsolete algorithm is a defect in those pieces of software. Those defective programs should be corrected to use the bicubic image scaling algorithm, which delivers much better image quality. Decades ago, CPU's had insufficient power to quickly perform bicubic at runtime, and GPU's didn't even exist, therefore the fast-but-bad "Nearest Neighbor" algorithm was the only choice at runtime, and bicubic could only be performed prior to runtime in separate program such as Photoshop.

Nowadays every computer has a GPU, and every tablet and smartphone has integrated GPU-like abilities, thus bicubic should be performed at runtime. Furthermore, in order to further enhance speed, bicubic scaling can be performed once and then cached and reused (not repeated every time an icon is rendered), as I mentioned in a previous message re the implementation of the Windows "Start" menu. Thus software that still uses "Nearest Neighbor" is incorrectly written and needs to be fixed to use bicubic.

@mdtauk
Copy link
Contributor

mdtauk commented Jan 20, 2020

"Nearest Neighbor" is a good option if dealing with pixel art and defined scaling ratios.

I think it could be useful to sum up what your request is, as opposed to a long and detailed explanation of what is broken.

Based on looking through the posts, I think you have a number of asks that are all related in some ways.

  • An option to resize FontIcon glyphs with width and height, and not just fontsizing;
  • Choice of scaling algorithms for bitmap icons/images;
  • Ability to use BitmapStreams rather than loading resource files;
  • The ability for Windows to use Vector files for Icons throughout the OS Shell;
  • (supposition) Grouping vector files based on TargetSize as a single icon;
  • Easier way to assign/generate/create App resource imagery;
  • Reduce the variations required, and remove redundant image formats and sizes;
  • Fitting non-standard sized images to the nearest applicable size;
  • Rationalise the Coloured, Unplated, Plated, Monochrome icon options for the shell;
  • Improve the previews for App resources in the packaging UI;

@verelpode
Copy link
Author

@mdtauk

I think it could be useful to sum up what your request is, as opposed to a long and detailed explanation of what is broken.

Yes, you're right, but why should I work for a wealthy corporation (such as Microsoft) for free? It would be wildly unreasonable to expect me to work as if I'm a Microsoft employee, in return for $0 of salary for my hard work. To be ethical and fair, software engineers need to be paid a reasonable salary in return for their long hours of hard work. Ethical and legal working conditions. Also, I'm not a pseudo-religious open source fanatic who works two jobs simultaneously; a so-called "day job" plus a so-called "night job". An unpaid "night job" that is quasi-illegal in regards to max allowed/legal working hours per week. Open source isn't bad, but open source fanaticism is very bad -- it causes much harm to society and to companies as well.
(That's not a complaint about you @mdtauk. I know you're no fanatic. That's a complaint about other people, not anyone here in issue #1494.)

Thus you and @lukasf are correct in saying that properly-written proposals would be better, but I am not going to do that work because it would make me feel as if I'm being unethically exploited/abused.

@lukasf
Copy link

lukasf commented Jan 20, 2020

I believe that it would have been less work to write 2 or 3 compact, focused proposals for the improvements that would be most valueable for you, compared to the very lengthy and overly detailed write down of everything that is wrong.

It's up to you to decide how much time you spend here. Microsoft won't pay you for creating issues here, obviously. Remember that creating an issue is usually only a tiny fraction of work, compared to the work required to actually resolve one of these issues.

@marcelwgn
Copy link
Contributor

Since it seems like @verelpode won't write a proposal, I would like to step in and do this since it would be hard for the WinUI team and the community to come up with feasible solutions solely from this discussion.

However I am not quite familiar with all the obstacles that are combined with using custom icons in UWP and WinUI, thus I will base it on the list @mdtauk kindly created in this issue
(comment link: #1494 (comment))

There seem to be two large areas where there should be improvement:

Using icons in app

  • Use SVG
  • Option to resize FontIcon glyphs with width and height, and not just fontsizing
  • Choice of scaling algorithms for bitmap icons/images
  • Ability to use BitmapStreams rather than loading resource files
  • Easier way to assign/generate/create App resource imagery

App/tile icon

  • Abilitiy to use SVG as app icon
  • Reduce the variations required, and remove redundant image formats and sizes
  • Make it clear what icon is used for what and why the developer should provide it

Are there any points missing @mdtauk , @charlesroddie, @verelpode , @lukasf, @moshegutman, @dragonwolf83 ?


@verelpode Mind expanding on the open source "fanaticism" ? 😅
Are there any cases you can point out where this has happened here?
Also mind elaborating in why you would feel being "unethically exploited/abused" if you were writing a proposal? Keep in mind that writing a proposal is one of the best ways to ensure that your ideas get understood correctly.

@verelpode
Copy link
Author

verelpode commented Jan 20, 2020

@lukasf

I believe that it would have been less work to write 2 or 3 compact, focused proposals for the improvements that would be most valueable for you, compared to the very lengthy and overly detailed write down of everything that is wrong.

Impossible. If someone doesn't understand the problems, then he/she cannot write proposals to solve those problems. NOW, today, we've eventually reached a stage where it's possible to write proposals. Previously it wasn't possible to write proposals because there was little or no understanding of what was wrong. How could I be expected to write a proposal when I didn't understand what was wrong and hadn't discussed the problems with anybody? Even if I thought I knew the problems, my understanding could be proven inaccurate after discussing it with people, thus it was necessary to have discussion first. Thus the first stage is to determine what is wrong and discuss it, and the second stage is to use this knowledge of what is wrong, in order to write a proposal.

It's up to you to decide how much time you spend here.

I've already done more than a generous amount of work for free in this and other issues. If I do more work for free, then I'll receive valid criticism from my colleagues and from customers/clients, for failing to prioritize the tasks necessary for our business and for our customers.

We've already solved our icon problems by NOT using any of WinUI's icon stuff. A client could legitimately criticize my task prioritization by saying to me: "Why on earth are you spending so much time on icons when scalable and bitmap icons already work wonderfully in the app, whereas we urgently need the other issue XYZ fixed ASAP please?"

@lukasf

Remember that creating an issue is usually only a tiny fraction of work, compared to the work required to actually resolve one of these issues.

If you mean the proposal is a small part of the work, then my experience has been the opposite. It takes me a month or two to write a solid proposal, and then when the proposal is finished, I can hammer out the source code within 1 week, and then fix any bugs in the following week.

@verelpode
Copy link
Author

@chingucoding

Are there any cases you can point out where this has happened here?

WinUI is not open source therefore open source fanaticism cannot occur in WinUI. This could potentially change when WinUI becomes open source with the release of WinUI 3 sometime this year, if the WinUI team is not careful to prevent the problem, but I believe the WinUI team will monitor and prevent the problem. Some open source programmers are fanatical and sacrifice their own lives and work hundreds of hours for free instead of negotiating a reasonable normal employment arrangement with fair and ethical remuneration. Their bizarre fanatical behavior is inexplicable and harmful to themselves and to Microsoft and to the software industry in general. But no, I don't think it happens in WinUI.

why you would feel being "unethically exploited/abused" if you were writing a proposal?

Perhaps your form of a proposal is much less work than my form of a proposal. I have to maintain a reasonable limit on the amount of work I do for free for any wealthy corporations, and I have to ensure that our customers/clients don't suffer as a result of me spending excessive time writing messages or proposals in GitHub.

@mdtauk
Copy link
Contributor

mdtauk commented Jan 21, 2020

@verelpode A WinUI 3.0 proposal would be a short list of wants, reasons why they are being asked for, and possibly some kind of visual mock up if that is relevant.

The time you spent "ranting" about the problems with how icons are treated in the framework, could have gone into a more approachable ask.

Of course there are Proposals, Bug Reports, Discussions, and other types of conversation on here. There are requests buried within the criticisms. And if you would like action to be taken on those wants, then wrapping them in a vitriolic negative tone, will make it easier to ignore them.

And there are valid issues there, that should be reconsidered with WinUI 3.0's release, and Windows 10 X's new Shell

@verelpode
Copy link
Author

verelpode commented Jan 22, 2020

@mdtauk

wrapping them in a vitriolic negative tone

I think you've misinterpreted the title of this issue. The title "An Iconic Disaster" is a play on words; a light joke. The light-hearted nature of this title becomes clear when reading the first sentence of this issue, where I gave a large compliment to the WinUI team:

"WinUI has delivered innovative and impressive new GUI elements, designs, and techniques, and the WinUI team has implemented many clever improvements. But of course, nobody is capable of 100% pure perfection, so some deficiences must exist in WinUI."

I have no vitriolic feelings in regards to icons in WinUI. I think the vitriol is the product of what you imagine my feelings are. If you heard me speaking verbally instead of in writing, you wouldn't have viewed it as vitriolic. This is a common problem when reading and writing -- it's easy for people to make the mistake of reading something and interpreting it as having a different tone/emotion than the writer had, because the verbal tone of voice is absent from writing.

Does the WinUI team consist of adults or teenagers? It consists of mature adults. Therefore these mature adults can take the good with the bad. I gave the WinUI team a big compliment, therefore if they accept the compliment then it's fair to also accept the criticism alongside the compliment. If they were immature, then they would only be able to handle positive news, but they're not immature.

I respect the WinUI team by giving them both compliments and criticism because I view them as mature adults who can handle it. In contrast, you appear to be showing disrespect for the WinUI team because you're treating them as if they're immature teenagers who lack the mental maturity necessary to take the good with the bad.

How you treat the WinUI team is your own choice, but if you ask me, my recommendation would be that you start showing them some respect by treating them as mature adults instead of teenagers. So-called "polite" wording is sometimes highly disrespectful to people.

A WinUI 3.0 proposal would be a short list of wants, reasons why they are being asked for, and possibly some kind of visual mock up if that is relevant.

Apparently your proposal method is different than mine, and neither method is better, rather both methods have pro's and con's. You say "a short list of wants" and that is clearly a method that has advantages but it also has disadvantages. You can use the proposal method that you feel works better for you, and I can use the proposal method that I feel works better for me.

The time you spent "ranting" about the problems with how icons are treated in the framework, could have gone into a more approachable ask.

Impossible. If someone doesn't understand the problems, then he/she cannot write proposals to solve those problems. NOW, today, we've eventually reached a stage where it's possible to write proposals. Previously it wasn't possible to write proposals because there was little or no understanding of what was wrong. How could I be expected to write a proposal when I didn't understand what was wrong and hadn't discussed the problems with anybody? Even if I thought I knew the problems, my understanding could be proven inaccurate after discussing it with people, thus it was necessary to have discussion first. Thus the first stage is to determine what is wrong and discuss it, and the second stage is to use this knowledge of what is wrong, in order to write a proposal.

will make it easier to ignore them.

You speak as if your preferred communication method is proven successful when in reality the opposite has already occurred. WinRT was released 8 years ago (2012). If your method is a successful method, then all the problems in UWP, WinRT, WinUI would have already been communicated easily and successfully YEARS AGO. You're trying really hard to convince me to switch to a failed method; a communications method that has been unsuccessful for the last 8 years.

Why do you care so much about which method I use? Is it because you're trying to convince yourself by convincing me first? This happens commonly. People commonly try to suppress their own self-doubt by trying very hard to convince other people to do the same unsuccessful thing. Thus people convince themselves by trying to convince other people. The end result is that a whole group of people start repeating the same mistakes as each other, because a few self-doubting people try very hard to convince the other people to repeat the same mistake in order to erase their own self-doubt. It's one of the most common problems in society.

@michael-hawker
Copy link
Collaborator

Realized my comment on TabView relates to this discussion as well.

@michael-hawker
Copy link
Collaborator

I definitely feel like it'd be useful to split this into multiple scoped issues. There's a lot of great problems pointed out here, but I feel like this is hard to act on as an all-up sink.

I just realized that I can't style an Icon/IconSource, when I get the FontIconSource from the developer's XAML it's fixed at 20 for FontSize, any amount of style I have in my template is ignored and won't inherit or override that FontSize value, even if I call ClearValue on the FontIcon, as that just sets it back to 20...

@stonapse64
Copy link

stonapse64 commented Jun 3, 2020

@verelpode: Just by chance I discovered that a negative margin enables scaling to some extend. See you're code snippet below with this "hack"...

<StackPanel Orientation="Vertical">
	<IconSourceElement Width="64" Height="64" Margin="-24">
		<IconSourceElement.IconSource>
			<SymbolIconSource Symbol="Refresh"/>
		</IconSourceElement.IconSource>
	</IconSourceElement>
	<TextBlock Text="Reload Data" FontSize="20" FontWeight="SemiBold"/>
</StackPanel>

@brechtb86
Copy link

I noticed that when I'm binding to a XamlUICommand, the icon doesn't show up. I don't know if I'm doing something wrong (the last time I programmed with XAML was 15 years ago, in Silverlight at the time, and WinUI is totally new for me atm).

I'm using version 3.0.0-preview3.201113.0

The ViewModel:

private void BindCommands()
{
    this.PickMovieFolder = new XamlUICommand
    {
        IconSource = new SymbolIconSource
        {
            Symbol = Symbol.Folder,
            Foreground = new SolidColorBrush(Color.FromArgb(1, 122, 16, 28))
        },
        Description = "Select a movie folder to add...",
    };
    this.PickMovieFolder.ExecuteRequested += (command, args) =>
    {
        command.DispatcherQueue.TryEnqueue(async () =>
        {
            var folderPicker = new FolderPicker
            {
                SuggestedStartLocation = PickerLocationId.VideosLibrary
            };

            folderPicker.FileTypeFilter.Add("*");

            folderPicker.As<IInitializeWithWindow>().Initialize(Process.GetCurrentProcess().MainWindowHandle);

            var folder = await folderPicker.PickSingleFolderAsync();

            if (folder != null)
            {
                // Do sthg
            }
        });
    };
}

The View:

<Grid Margin="0,12,0,0">
   <Grid.ColumnDefinitions>
       <ColumnDefinition Width="768px" />
       <ColumnDefinition Width="Auto" />
       <ColumnDefinition Width="Auto" />
       <ColumnDefinition Width="Auto" />
   </Grid.ColumnDefinitions>
   <TextBox Grid.Row="0" Grid.Column="0" HorizontalAlignment="Stretch" VerticalAlignment="Center" PlaceholderText="Path to your movie folder (eg: C:\Users\Zeus\Movies)"></TextBox>
   <Button Grid.Row="0" Grid.Column="1" Width="36" Height="32" Margin="-36,0,48,0" BorderThickness="0" CornerRadius="0,1, 1, 0" Command="{Binding Path=PickMovieFolder }" />
   <CheckBox Grid.Row="0" Grid.Column="2" Margin="0,0,12,0" VerticalAlignment="Center">Include subfolders</CheckBox>
   <Button Grid.Row="0" Grid.Column="3" VerticalAlignment="Center">Add folder</Button>
</Grid>

I tried removing the negative margin, but to no effect. When I set the property Label on the XamlUICommand , this shows correctly, only still no icon.

image

I don't know if I'm at the right place here.

@michael-hawker
Copy link
Collaborator

🦙 @brechtb86 probably best as a new issue, especially as it related to WinUI 3, I moved it over for you here: #4074

@michael-hawker
Copy link
Collaborator

🦙 Linking to an older Stack Overflow thread about this same type of issue for reference: https://stackoverflow.com/questions/50458126/how-to-set-appbarbutton-icon-using-svg-file-resource-in-uwp-c

@michael-hawker
Copy link
Collaborator

🦙 Linking to most of the other related issues I could find fairly directly related to this topic:

It's also important to note that the general platform design guidance here calls out using vector based formats where possible:

There are many ways to create an icon. You can use a symbol font like Segoe MDL2 Assets. You could create your own vector-based image. You can even use a bitmap image, although we don't recommend it. Here's a summary of the different ways you can add an icon to your app.

SVG resources are ideal for icons, because they always look sharp at any size or resolution. Most drawing applications can export to SVG.

@oliverw
Copy link

oliverw commented Feb 20, 2023

More than 3 years later this is still the status quo?

@Jay-o-Way
Copy link
Contributor

rather an icon is akin to an image or path.

Actually, that's a negative. MDL2 and Fluent Font are called font icons and they are literally that: .ttf fonts

@MPITech
Copy link

MPITech commented Feb 15, 2024

I just started with WinUI3 recently and I can't believe it isn't easy to load an SVG image anywhere you can load a PNG. I can do it in WinForms with DevExpress controls, for example. These elements need to scale nicely depending on DPI, why is there little-to-no support for SVGs in things like NavigationViewItems after all this time?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature proposal New feature proposal team-Controls Issue for the Controls team
Projects
None yet
Development

No branches or pull requests