dotnet / maui

.NET MAUI is the .NET Multi-platform App UI, a framework for building native device applications spanning mobile, tablet, and desktop.
https://dot.net/maui
MIT License
22.2k stars 1.75k forks source link

Support direct use of Path's as the Source property in the ImageButton, Image, and Button controls #24084

Closed CraigBelser closed 1 month ago

CraigBelser commented 2 months ago

Description

Would like to have the ability to place a Path directly as an image, imagebutton, or button control Source property, and to directly bind path variables (like fill and stroke) using DynamicResource. (example implementation: WPF Path)

This change should support ResourceDictionary based theming to give the ability go beyond two themes (for accessibility and other reasons). (i.e. Light, Dark, High Contrast, Other?).

Reason; There is no current functioning way to control the colors of an SVG file/.png image for theming. The SVG does not support binding, and the community toolkit IconTintBehavior has too many functional issues (does not support multi color binding, use in popups, or DynamicBinding to name a few

Public API Changes

<Geometry x:Key="TestPathGeometry">M 10,100 C 10,300 300,-200 300,100</Geometry>

<Path Data="{StaticResource TestPathGeometry}" Fill="{DynamicResource DifferentDictionaryColor}"/>

Intended Use-Case

Many cross platform enterprise level desktop applications require support for more than 2 themes (Beyond Dark and Light) to deliver a UI that has full Accessibility. Theme Examples: Dark, Light, high contrast, and other. For purposes of this request let’s assume we need a least these four with the ability to add others in the future. Further assume we will be using different control styles on some themes (but not all) for features like semantic properties.

Theming should address Color changes, Image Color Changes, Font changes, different control styles and templates, and should ideally, be able to happen on the fly (Hot Swapping) vs at application startup (Start up Swapping). *Note Due to current limitations (Only two themes supported) of the MAUI AppThemeBinding method, current focus is on ResourceDictionary based theming, The solution should use DynamicResource binding vs AppThemeBinding to reduce the proliferation of extraneous XAML.

We really don’t want to see this:

<StackLayout>
    <Label Text="Some important label"
           TextColor="{AppThemeBinding Light=Green, Dark=Red, HighContrast=Purple, Other=Pink, Other2=White}" />
    <Image Source="{AppThemeBinding Light="Green.png", Dark="Red.png", HighContrast="Purple.png", Other="Pink.png", Other2=White}" />
</StackLayout>
github-actions[bot] commented 2 months ago

Hi I'm an AI powered bot that finds similar issues based off the issue title.

Please view the issues below to see if they solve your problem, and if the issue describes your problem please consider closing this one and thumbs upping the other issue to help us prioritize it. Thank you!

Open similar issues:

Note: You can give me feedback by thumbs upping or thumbs downing this comment.

Redth commented 2 months ago

We have a similar capability already in .NET MAUI.

For example, with the path and color in the resource dictionary:

<ContentPage.Resources>
    <ResourceDictionary>
        <x:String x:Key="TestPath">M 10,100 C 10,300 300,-200 300,100</x:String>
        <Color x:Key="DictionaryColor">Red</Color>
    </ResourceDictionary>
</ContentPage.Resources>

And using it in the Path control:

<Path Data="{StaticResource TestPath}"
  Stroke="{DynamicResource DictionaryColor}"
  Aspect="Uniform"
  HorizontalOptions="Center" />

image

Are there shortcomings to this existing API for your use case?

CraigBelser commented 2 months ago

@Redth @PureWeen @mikeparker104

Quick clarification overview We want to use the Path as the image source for Image, ImageButton, and Button controls (and any other control that uses a Source).

We are trying to develop a very large desktop application on both the apple and windows platforms and need to be able to control the Colors / and or shapes of the image for Theming beyond just Two themes. The SVG/Png route does not have sufficient capabilities (outlined below) and the CommunityToolkit IconTintColorBehavior has too many issues (bugs) and limitations (single color). We are working with Mike Parker at Microsoft and he asked for the feature request to be added. The full issue history leading to the request is found here: ( https://github.com/xamcat/fid-nxt-gen-dsktp/issues/483 ).

Loads more details: Reference: Issue prototype for theming found here: https://github.com/xamcat/fid-protos/tree/features/application_themeing/src/application_themeing

Theming Requirements Background: An Enterprise level desktop application requires support for more than 2 themes (Dark and Light) to deliver a UI that has full accessibility. Theme Examples: Dark, Light, high contrast, and other. For the purposes of this request let’s assume we need these four with the ability to add others in the future. Further assume we will be using different control styles on some themes (but not all) for features like semantic properties (https://learn.microsoft.com/en-us/dotnet/maui/fundamentals/accessibility?view=net-maui-8.0)

Theming should address Color changes, Image Color Changes, Font changes, different control styles and templates, and should ideally, be able to happen on the fly (Hot Swapping) vs at application startup (Start up Swapping). *Note Due to current limitations (Only two themes supported) of the MAUI AppThemeBinding method, this request will focus on Startup Swapping using Resource Dictionaries as defined here. Hot swapping will be implemented as soon as the relevant issues are corrected in the controls (see below)

Starting Info: https://learn.microsoft.com/en-us/dotnet/maui/user-interface/theming Issues:

  1. Images/Icons a) Button, Image, and ImageButton do not have native color tinting options for theming. (Other controls with images need to be addressed as well) b) Using the community toolkit, the ImageButton and Image can respond to limited color changes using the IconTintColorBehavior (https://learn.microsoft.com/en-us/dotnet/communitytoolkit/maui/behaviors/icon-tint-color-behavior) c) The community toolkit IconTintColorBehavior does not support the button control until Mike Parkers fix goes live

  2. Theming Approach 1 (AppThemeBinding) (Not Useable Scale) a) a) Limited to two themes (Dark or light) and therefore does not meet the requirements for accessibility (More than two themes) b) b) Base MS Guidance found here (https://learn.microsoft.com/en-us/dotnet/maui/user-interface/system-theme-changes) c) c) Having to use AppThemeBinding on every UI control for each property for an application of substantial size is massive code bloat!

  3. Theming approach 2 (Resource Dictionary) a) a) Supports the more than two themes requirment. b) b) Would support theme changing on the fly (Hot Swapping) if DynamicResource binding worked correctly (Multiple issues documented below). c) Having to use IconTintColorBehavior for Images, ImageButtons, and Buttons is one reason DynamicResource binding will not work as is. (reference: dotnet/maui#23578). c) d) The community toolkit IconTintColorBehavior does not support the button control. d) e) DynamicResource doesn't work when combined with AppThemeBinding (dotnet/maui#13619) e) f) Without full DynamicResource binding support (including use with IconTintColorBehavior), changing the app theme on the fly is not possible. Application must be restarted for the changes to take effect. f) g) Responding to system theme changes (https://learn.microsoft.com/en-us/dotnet/maui/user-interface/system-theme-changes) will not work without DynamicBinding g) h) The theme changing methods from (https://github.com/davidortinau/SimpleCalculator) were explored and again without full application DynamicBinding support (including image colors) it will not work. h) i) FYI: IconTintColorBehavior was used as an attached behavior in styles as suggested here: https://devblogs.microsoft.com/dotnet/customizing-dotnet-maui-controls/

Additional Issues: Per the documentation above, we are using ResourceDictionary based theming and will be using more than 3 Themes moving forward for Accessibility ie, Light, Dark and High Contrast themes as well as others in the future.

When looking at color theming images used directly or in other controls (Button, Image Button...), there is no native way to control the colors of the SVG/.png image source. We have used IconTintColor behavior from the Community Toolkit, but it have several issues that are show stoppers.

Some of these are:

  1. Does not support multi color images.
  2. Does not Dynamically bind as mentioned above. (We have a work around but yuk)
  3. Does not work in popups on windows (ie, strips the TintColor after first popup). (bug report in process)
  4. Images have random size fluctuations on windows on occasion. (bug report in process)
  5. Does not support ability to bind different colors of a multi path SVG
  6. Colors are lost during some navigation events ([BUG] IconTintColorBehavior sample not working as expected on windows CommunityToolkit/Maui#1734)
  7. Is generally unstable and we have had to use messy workarounds.

I can get a more complete list, but IconTintBehavior is a best a Band-Aid to the issue (IMO). Would love to see paths for the Source in image, imagebuttons, and buttons in like wpf has.

This would solve our issues and would fix the Theme icon issue for real:

CraigBelser commented 2 months ago

For the feature we are requesting the ability to use multiple paths in the Image Source. It would be really nice if we had the ability to toggle the visibility of each path. This would allow images/icons to more readily support Accessibility. Think of the Ghost Busters icon example. One path for the Ghost, one for the Circle Cross out. Toggling the circle off gives us the ability to change the meaning of the Image (there are ghosts), and address accessibility beyond colors. Again, nice to have, not a requirement.

CraigBelser commented 1 month ago

After further discussion this issue is what we are after: https://github.com/dotnet/maui/issues/16170