Skip to content

[API Proposal] Introducing AccentColor as SystemColors #9295

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

Closed
dipeshmsft opened this issue Jun 26, 2024 · 13 comments
Closed

[API Proposal] Introducing AccentColor as SystemColors #9295

dipeshmsft opened this issue Jun 26, 2024 · 13 comments
Labels
api-approved API was approved in API review, it can be implemented Win 11 Theming

Comments

@dipeshmsft
Copy link
Member

Background and Motivation

Since Windows 10 onwards, Accent color has been one of the key compoenents of visual styles in Windows controls. However, there is no easy way to get the system's accent color. Accent colors can be used in custom styles to align the styling of controls with what the OS is showing.

In earlier versions of Windows, visual styles were defined using system colors and brushes, and corresponding to that we had SystemColors static class that contained getters to all the system colors, brushes and corresponding resource keys for using the colors and brushes in XAML.

Since, Accent color and it's variations are also system wide defined colors, we propose to expose them using the SystemColors class.

API Proposal

    public static class SystemColors
    {
        // Accent Colors
        public static Color AccentColor;
        public static Color AccentColorLight1;
        public static Color AccentColorLight2;
        public static Color AccentColorLight3;
        public static Color AccentColorDark1;
        public static Color AccentColorDark2;
        public static Color AccentColorDark3;

        // Accent Color Keys
        public static ResourceKey AccentColorKey;
        public static ResourceKey AccentColorLight1Key;
        public static ResourceKey AccentColorLight2Key;
        public static ResourceKey AccentColorLight3Key;
        public static ResourceKey AccentColorDark1Key;
        public static ResourceKey AccentColorDark2Key;
        public static ResourceKey AccentColorDark3Key;
        
        // Accent Color Brushes
        public static SolidColorBrush AccentColorBrush;
        public static SolidColorBrush AccentColorLight1Brush;
        public static SolidColorBrush AccentColorLight2Brush;
        public static SolidColorBrush AccentColorLight3Brush;
        public static SolidColorBrush AccentColorDark1Brush;
        public static SolidColorBrush AccentColorDark2Brush;
        public static SolidColorBrush AccentColorDark3Brush;

        // Accent Color Brush Keys
        public static ResourceKey AccentColorBrushKey;
        public static ResourceKey AccentColorLight1BrushKey;
        public static ResourceKey AccentColorLight2BrushKey;
        public static ResourceKey AccentColorLight3BrushKey;
        public static ResourceKey AccentColorDark1BrushKey;
        public static ResourceKey AccentColorDark2BrushKey;
        public static ResourceKey AccentColorDark3BrushKey;
    }

I think it may be possible to reduce the number of properties that we are exposing here, if the operations to calculate the variations of AccentColor are simpler. We don't know that yet so, I would like to keep these APIs experimental.

Alternative Design

Rather than having the accent colors defined here, we can introduce a new class, say AccentColorManager which will store the system accent and opens up possibility for theme related customization.

@dipeshmsft dipeshmsft added API suggestion Early API idea and discussion, it is NOT ready for implementation Win 11 Theming labels Jun 26, 2024
@miloush
Copy link
Contributor

miloush commented Jun 26, 2024

LGTM.

@robert-abeo
Copy link

I think it may be possible to reduce the number of properties that we are exposing here, if the operations to calculate the variations of AccentColor are simpler.

This was widely discussed a few years ago in the WinUI and CommunityToolkit repositories. Accent color calculations are not a simple algorithm and it's hidden by Microsoft within Windows. Your design team considers this algorithm proprietary and you won't release it publicly. This means everyone has to read AccentLight1-3, AccentDark1-3, etc. directly from Windows which does the calculation.

The calculation is fairly complex too and it making sure the Accent colors 1-3 are calculated from the base color in a way that ensures contrast and good visibility. It isn't simply adjusting the luminence, value or brightness of colors. It also adjusts Hue in some cases.

In earlier versions of Windows, visual styles were defined using system colors and brushes, and corresponding to that we had SystemColors static class that contained getters to all the system colors, brushes and corresponding resource keys for using the colors and brushes in XAML.

Yes, but keep in mind the structure of Fluent theme is as follows. I simplified by removing light/dark/contrast variations and non-color resources like FontSize, Padding, etc.

0 System provided colors (accent)
   1 Base Fluent Colors & Brushes
      2 Fluent Control-Specific Brushes
         3 Fluent Control Theme Styles

Mapping the Fluent theme to SystemColors essentially means you need to provide levels 0 and 1. Level zero is the accent colors. But level 1 is:

<!-- Colors -->
<Color x:Key="TextFillColorPrimary">#E4000000</Color>
<Color x:Key="TextFillColorSecondary">#9E000000</Color>
<Color x:Key="TextFillColorTertiary">#72000000</Color>
<Color x:Key="TextFillColorDisabled">#5C000000</Color>
<Color x:Key="TextPlaceholderColor">#9E000000</Color>
<Color x:Key="TextFillColorInverse">#FFFFFF</Color>
<Color x:Key="AccentTextFillColorDisabled">#5C000000</Color>
<Color x:Key="TextOnAccentFillColorSelectedText">#FFFFFF</Color>
<Color x:Key="TextOnAccentFillColorPrimary">#FFFFFF</Color>
<Color x:Key="TextOnAccentFillColorSecondary">#B3FFFFFF</Color>
<Color x:Key="TextOnAccentFillColorDisabled">#A3FFFFFF</Color>
<Color x:Key="ControlFillColorDefault">#B3FFFFFF</Color>
<Color x:Key="ControlFillColorSecondary">#80F9F9F9</Color>
<Color x:Key="ControlFillColorTertiary">#4DF9F9F9</Color>
<Color x:Key="ControlFillColorDisabled">#4DF9F9F9</Color>
<Color x:Key="ControlFillColorTransparent">#00FFFFFF</Color>
<Color x:Key="ControlFillColorInputActive">#FFFFFF</Color>
<Color x:Key="ControlStrongFillColorDefault">#72000000</Color>
<Color x:Key="ControlStrongFillColorDisabled">#51000000</Color>
<Color x:Key="ControlSolidFillColorDefault">#FFFFFF</Color>
<Color x:Key="SubtleFillColorTransparent">#00FFFFFF</Color>
<Color x:Key="SubtleFillColorSecondary">#09000000</Color>
<Color x:Key="SubtleFillColorTertiary">#06000000</Color>
<Color x:Key="SubtleFillColorDisabled">#00FFFFFF</Color>
<Color x:Key="SubtleBorderBrushTertiary">#B6B6B6</Color>
<Color x:Key="ControlAltFillColorTransparent">#00FFFFFF</Color>
<Color x:Key="ControlAltFillColorSecondary">#06000000</Color>
<Color x:Key="ControlAltFillColorTertiary">#FFE9E9E9</Color>
<Color x:Key="ControlAltFillColorQuarternary">#18000000</Color>
<Color x:Key="ControlAltFillColorDisabled">#00FFFFFF</Color>
<Color x:Key="ControlOnImageFillColorDefault">#C9FFFFFF</Color>
<Color x:Key="ControlOnImageFillColorSecondary">#F3F3F3</Color>
<Color x:Key="ControlOnImageFillColorTertiary">#EBEBEB</Color>
<Color x:Key="ControlOnImageFillColorDisabled">#00FFFFFF</Color>
<Color x:Key="AccentFillColorDisabled">#37000000</Color>
<Color x:Key="ControlStrokeColorDefault">#0F000000</Color>
<Color x:Key="ControlStrokeColorSecondary">#29000000</Color>
<Color x:Key="ControlStrokeColorTertiary">#9E000000</Color>
<Color x:Key="ControlStrokeColorOnAccentDefault">#14FFFFFF</Color>
<Color x:Key="ControlStrokeColorOnAccentSecondary">#66000000</Color>
<Color x:Key="ControlStrokeColorOnAccentTertiary">#37000000</Color>
<Color x:Key="ControlStrokeColorOnAccentDisabled">#0F000000</Color>
<Color x:Key="ControlStrokeColorForStrongFillWhenOnImage">#59FFFFFF</Color>
<Color x:Key="CardStrokeColorDefault">#0F000000</Color>
<Color x:Key="CardStrokeColorDefaultSolid">#EBEBEB</Color>
<Color x:Key="ControlStrongStrokeColorDefault">#72000000</Color>
<Color x:Key="ControlStrongStrokeColorDisabled">#37000000</Color>
<Color x:Key="SurfaceStrokeColorDefault">#66757575</Color>
<Color x:Key="SurfaceStrokeColorFlyout">#0F000000</Color>
<Color x:Key="SurfaceStrokeColorInverse">#15FFFFFF</Color>
<Color x:Key="DividerStrokeColorDefault">#0F000000</Color>
<Color x:Key="FocusStrokeColorOuter">#E4000000</Color>
<Color x:Key="FocusStrokeColorInner">#B3FFFFFF</Color>
<Color x:Key="CardBackgroundFillColorDefault">#B3FFFFFF</Color>
<Color x:Key="CardBackgroundFillColorSecondary">#80F6F6F6</Color>
<Color x:Key="SmokeFillColorDefault">#4D000000</Color>
<Color x:Key="LayerFillColorDefault">#80FFFFFF</Color>
<Color x:Key="LayerFillColorAlt">#FFFFFF</Color>
<Color x:Key="LayerOnAcrylicFillColorDefault">#40FFFFFF</Color>
<Color x:Key="LayerOnAccentAcrylicFillColorDefault">#40FFFFFF</Color>
<!-- Fallback color for missing Acrylic used for e.g. Flyouts -->
<Color x:Key="AcrylicBackgroundFillColorDefault">#F9F9F9</Color>
<Color x:Key="LayerOnMicaBaseAltFillColorDefault">#B3FFFFFF</Color>
<Color x:Key="LayerOnMicaBaseAltFillColorSecondary">#0A000000</Color>
<Color x:Key="LayerOnMicaBaseAltFillColorTertiary">#F9F9F9</Color>
<Color x:Key="LayerOnMicaBaseAltFillColorTransparent">#00000000</Color>
<Color x:Key="SolidBackgroundFillColorBase">#F3F3F3</Color>
<Color x:Key="SolidBackgroundFillColorSecondary">#EEEEEE</Color>
<Color x:Key="SolidBackgroundFillColorTertiary">#F9F9F9</Color>
<Color x:Key="SolidBackgroundFillColorQuarternary">#FFFFFF</Color>
<Color x:Key="SolidBackgroundFillColorTransparent">#00F3F3F3</Color>
<Color x:Key="SolidBackgroundFillColorBaseAlt">#DADADA</Color>
<Color x:Key="SystemFillColorSuccess">#0F7B0F</Color>
<Color x:Key="SystemFillColorCaution">#9D5D00</Color>
<Color x:Key="SystemFillColorCritical">#C42B1C</Color>
<Color x:Key="SystemFillColorNeutral">#72000000</Color>
<Color x:Key="SystemFillColorSolidNeutral">#8A8A8A</Color>
<Color x:Key="SystemFillColorAttentionBackground">#80F6F6F6</Color>
<Color x:Key="SystemFillColorSuccessBackground">#DFF6DD</Color>
<Color x:Key="SystemFillColorCautionBackground">#FFF4CE</Color>
<Color x:Key="SystemFillColorCriticalBackground">#FDE7E9</Color>
<Color x:Key="SystemFillColorNeutralBackground">#06000000</Color>
<Color x:Key="SystemFillColorSolidAttentionBackground">#F7F7F7</Color>
<Color x:Key="SystemFillColorSolidNeutralBackground">#F3F3F3</Color>
<!-- Brushes -->
<SolidColorBrush x:Key="TextFillColorPrimaryBrush" Color="{StaticResource TextFillColorPrimary}" />
<SolidColorBrush x:Key="TextFillColorSecondaryBrush" Color="{StaticResource TextFillColorSecondary}" />
<SolidColorBrush x:Key="TextFillColorTertiaryBrush" Color="{StaticResource TextFillColorTertiary}" />
<SolidColorBrush x:Key="TextFillColorDisabledBrush" Color="{StaticResource TextFillColorDisabled}" />
<SolidColorBrush x:Key="TextPlaceholderColorBrush" Color="{StaticResource TextPlaceholderColor}" />
<SolidColorBrush x:Key="TextFillColorInverseBrush" Color="{StaticResource TextFillColorInverse}" />
<SolidColorBrush x:Key="AccentTextFillColorDisabledBrush" Color="{StaticResource AccentTextFillColorDisabled}" />
<SolidColorBrush x:Key="TextOnAccentFillColorSelectedTextBrush" Color="{StaticResource TextOnAccentFillColorSelectedText}" />
<SolidColorBrush x:Key="TextOnAccentFillColorPrimaryBrush" Color="{StaticResource TextOnAccentFillColorPrimary}" />
<SolidColorBrush x:Key="TextOnAccentFillColorSecondaryBrush" Color="{StaticResource TextOnAccentFillColorSecondary}" />
<SolidColorBrush x:Key="TextOnAccentFillColorDisabledBrush" Color="{StaticResource TextOnAccentFillColorDisabled}" />
<SolidColorBrush x:Key="ControlFillColorDefaultBrush" Color="{StaticResource ControlFillColorDefault}" />
<SolidColorBrush x:Key="ControlFillColorSecondaryBrush" Color="{StaticResource ControlFillColorSecondary}" />
<SolidColorBrush x:Key="ControlFillColorTertiaryBrush" Color="{StaticResource ControlFillColorTertiary}" />
<SolidColorBrush x:Key="ControlFillColorDisabledBrush" Color="{StaticResource ControlFillColorDisabled}" />
<SolidColorBrush x:Key="ControlFillColorTransparentBrush" Color="{StaticResource ControlFillColorTransparent}" />
<SolidColorBrush x:Key="ControlFillColorInputActiveBrush" Color="{StaticResource ControlFillColorInputActive}" />
<SolidColorBrush x:Key="ControlStrongFillColorDefaultBrush" Color="{StaticResource ControlStrongFillColorDefault}" />
<SolidColorBrush x:Key="ControlStrongFillColorDisabledBrush" Color="{StaticResource ControlStrongFillColorDisabled}" />
<SolidColorBrush x:Key="ControlSolidFillColorDefaultBrush" Color="{StaticResource ControlSolidFillColorDefault}" />
<SolidColorBrush x:Key="SubtleFillColorTransparentBrush" Color="{StaticResource SubtleFillColorTransparent}" />
<SolidColorBrush x:Key="SubtleFillColorSecondaryBrush" Color="{StaticResource SubtleFillColorSecondary}" />
<SolidColorBrush x:Key="SubtleFillColorTertiaryBrush" Color="{StaticResource SubtleFillColorTertiary}" />
<SolidColorBrush x:Key="SubtleFillColorDisabledBrush" Color="{StaticResource SubtleFillColorDisabled}" />
<SolidColorBrush x:Key="ControlAltFillColorTransparentBrush" Color="{StaticResource ControlAltFillColorTransparent}" />
<SolidColorBrush x:Key="ControlAltFillColorSecondaryBrush" Color="{StaticResource ControlAltFillColorSecondary}" />
<SolidColorBrush x:Key="ControlAltFillColorTertiaryBrush" Color="{StaticResource ControlAltFillColorTertiary}" />
<SolidColorBrush x:Key="ControlAltFillColorQuarternaryBrush" Color="{StaticResource ControlAltFillColorQuarternary}" />
<SolidColorBrush x:Key="ControlAltFillColorDisabledBrush" Color="{StaticResource ControlAltFillColorDisabled}" />
<SolidColorBrush x:Key="ControlOnImageFillColorDefaultBrush" Color="{StaticResource ControlOnImageFillColorDefault}" />
<SolidColorBrush x:Key="ControlOnImageFillColorSecondaryBrush" Color="{StaticResource ControlOnImageFillColorSecondary}" />
<SolidColorBrush x:Key="ControlOnImageFillColorTertiaryBrush" Color="{StaticResource ControlOnImageFillColorTertiary}" />
<SolidColorBrush x:Key="ControlOnImageFillColorDisabledBrush" Color="{StaticResource ControlOnImageFillColorDisabled}" />
<SolidColorBrush x:Key="AccentFillColorDisabledBrush" Color="{StaticResource AccentFillColorDisabled}" />
<SolidColorBrush x:Key="ControlStrokeColorDefaultBrush" Color="{StaticResource ControlStrokeColorDefault}" />
<SolidColorBrush x:Key="ControlStrokeColorSecondaryBrush" Color="{StaticResource ControlStrokeColorSecondary}" />
<SolidColorBrush x:Key="ControlStrokeColorTertiaryBrush" Color="{StaticResource ControlStrokeColorTertiary}" />
<SolidColorBrush x:Key="ControlStrokeColorOnAccentDefaultBrush" Color="{StaticResource ControlStrokeColorOnAccentDefault}" />
<SolidColorBrush x:Key="ControlStrokeColorOnAccentSecondaryBrush" Color="{StaticResource ControlStrokeColorOnAccentSecondary}" />
<SolidColorBrush x:Key="ControlStrokeColorOnAccentTertiaryBrush" Color="{StaticResource ControlStrokeColorOnAccentTertiary}" />
<SolidColorBrush x:Key="ControlStrokeColorOnAccentDisabledBrush" Color="{StaticResource ControlStrokeColorOnAccentDisabled}" />
<SolidColorBrush x:Key="ControlStrokeColorForStrongFillWhenOnImageBrush" Color="{StaticResource ControlStrokeColorForStrongFillWhenOnImage}" />
<SolidColorBrush x:Key="CardStrokeColorDefaultBrush" Color="{StaticResource CardStrokeColorDefault}" />
<SolidColorBrush x:Key="CardStrokeColorDefaultSolidBrush" Color="{StaticResource CardStrokeColorDefaultSolid}" />
<SolidColorBrush x:Key="ControlStrongStrokeColorDefaultBrush" Color="{StaticResource ControlStrongStrokeColorDefault}" />
<SolidColorBrush x:Key="ControlStrongStrokeColorDisabledBrush" Color="{StaticResource ControlStrongStrokeColorDisabled}" />
<SolidColorBrush x:Key="SurfaceStrokeColorDefaultBrush" Color="{StaticResource SurfaceStrokeColorDefault}" />
<SolidColorBrush x:Key="SurfaceStrokeColorFlyoutBrush" Color="{StaticResource SurfaceStrokeColorFlyout}" />
<SolidColorBrush x:Key="SurfaceStrokeColorInverseBrush" Color="{StaticResource SurfaceStrokeColorInverse}" />
<SolidColorBrush x:Key="DividerStrokeColorDefaultBrush" Color="{StaticResource DividerStrokeColorDefault}" />
<SolidColorBrush x:Key="FocusStrokeColorOuterBrush" Color="{StaticResource FocusStrokeColorOuter}" />
<SolidColorBrush x:Key="FocusStrokeColorInnerBrush" Color="{StaticResource FocusStrokeColorInner}" />
<SolidColorBrush x:Key="CardBackgroundFillColorDefaultBrush" Color="{StaticResource CardBackgroundFillColorDefault}" />
<SolidColorBrush x:Key="CardBackgroundFillColorSecondaryBrush" Color="{StaticResource CardBackgroundFillColorSecondary}" />
<SolidColorBrush x:Key="SmokeFillColorDefaultBrush" Color="{StaticResource SmokeFillColorDefault}" />
<SolidColorBrush x:Key="LayerFillColorDefaultBrush" Color="{StaticResource LayerFillColorDefault}" />
<SolidColorBrush x:Key="LayerFillColorAltBrush" Color="{StaticResource LayerFillColorAlt}" />
<SolidColorBrush x:Key="LayerOnAcrylicFillColorDefaultBrush" Color="{StaticResource LayerOnAcrylicFillColorDefault}" />
<SolidColorBrush x:Key="LayerOnAccentAcrylicFillColorDefaultBrush" Color="{StaticResource LayerOnAccentAcrylicFillColorDefault}" />
<SolidColorBrush x:Key="LayerOnMicaBaseAltFillColorDefaultBrush" Color="{StaticResource LayerOnMicaBaseAltFillColorDefault}" />
<SolidColorBrush x:Key="LayerOnMicaBaseAltFillColorSecondaryBrush" Color="{StaticResource LayerOnMicaBaseAltFillColorSecondary}" />
<SolidColorBrush x:Key="LayerOnMicaBaseAltFillColorTertiaryBrush" Color="{StaticResource LayerOnMicaBaseAltFillColorTertiary}" />
<SolidColorBrush x:Key="LayerOnMicaBaseAltFillColorTransparentBrush" Color="{StaticResource LayerOnMicaBaseAltFillColorTransparent}" />
<SolidColorBrush x:Key="SolidBackgroundFillColorBaseBrush" Color="{StaticResource SolidBackgroundFillColorBase}" />
<SolidColorBrush x:Key="SolidBackgroundFillColorSecondaryBrush" Color="{StaticResource SolidBackgroundFillColorSecondary}" />
<SolidColorBrush x:Key="SolidBackgroundFillColorTertiaryBrush" Color="{StaticResource SolidBackgroundFillColorTertiary}" />
<SolidColorBrush x:Key="SolidBackgroundFillColorQuarternaryBrush" Color="{StaticResource SolidBackgroundFillColorQuarternary}" />
<SolidColorBrush x:Key="SolidBackgroundFillColorBaseAltBrush" Color="{StaticResource SolidBackgroundFillColorBaseAlt}" />
<SolidColorBrush x:Key="SystemFillColorSuccessBrush" Color="{StaticResource SystemFillColorSuccess}" />
<SolidColorBrush x:Key="SystemFillColorCautionBrush" Color="{StaticResource SystemFillColorCaution}" />
<SolidColorBrush x:Key="SystemFillColorCriticalBrush" Color="{StaticResource SystemFillColorCritical}" />
<SolidColorBrush x:Key="SystemFillColorNeutralBrush" Color="{StaticResource SystemFillColorNeutral}" />
<SolidColorBrush x:Key="SystemFillColorSolidNeutralBrush" Color="{StaticResource SystemFillColorSolidNeutral}" />
<SolidColorBrush x:Key="SystemFillColorAttentionBackgroundBrush" Color="{StaticResource SystemFillColorAttentionBackground}" />
<SolidColorBrush x:Key="SystemFillColorSuccessBackgroundBrush" Color="{StaticResource SystemFillColorSuccessBackground}" />
<SolidColorBrush x:Key="SystemFillColorCautionBackgroundBrush" Color="{StaticResource SystemFillColorCautionBackground}" />
<SolidColorBrush x:Key="SystemFillColorCriticalBackgroundBrush" Color="{StaticResource SystemFillColorCriticalBackground}" />
<SolidColorBrush x:Key="SystemFillColorNeutralBackgroundBrush" Color="{StaticResource SystemFillColorNeutralBackground}" />
<SolidColorBrush x:Key="SystemFillColorSolidAttentionBackgroundBrush" Color="{StaticResource SystemFillColorSolidAttentionBackground}" />
<SolidColorBrush x:Key="SystemFillColorSolidNeutralBackgroundBrush" Color="{StaticResource SystemFillColorSolidNeutralBackground}" />
<!-- Elevation border brushes -->
<LinearGradientBrush x:Key="ControlElevationBorderBrush" MappingMode="RelativeToBoundingBox" StartPoint="0,1" EndPoint="0,0">
<LinearGradientBrush.GradientStops>
<GradientStop Offset="0.025" Color="{StaticResource ControlStrokeColorSecondary}" />
<GradientStop Offset="0.075" Color="{StaticResource ControlStrokeColorDefault}" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<LinearGradientBrush x:Key="CircleElevationBorderBrush" MappingMode="RelativeToBoundingBox" StartPoint="0,0" EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStop Offset="0.50" Color="{StaticResource ControlStrokeColorDefault}" />
<GradientStop Offset="0.70" Color="{StaticResource ControlStrokeColorSecondary}" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<LinearGradientBrush x:Key="AccentControlElevationBorderBrush" MappingMode="RelativeToBoundingBox" StartPoint="0,1" EndPoint="0,0">
<LinearGradientBrush.GradientStops>
<GradientStop Offset="0.025" Color="{StaticResource ControlStrokeColorOnAccentSecondary}" />
<GradientStop Offset="0.075" Color="{StaticResource ControlStrokeColorOnAccentDefault}" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<LinearGradientBrush x:Key="TextControlElevationBorderBrush" MappingMode="Absolute" StartPoint="0,0" EndPoint="0,2">
<LinearGradientBrush.RelativeTransform>
<ScaleTransform CenterY="0.5" ScaleY="-1" />
</LinearGradientBrush.RelativeTransform>
<LinearGradientBrush.GradientStops>
<GradientStop Offset="0.5" Color="{StaticResource ControlStrongStrokeColorDefault}" />
<GradientStop Offset="1.0" Color="{StaticResource ControlStrokeColorDefault}" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<DrawingBrush
x:Key="StripedBackgroundBrush"
Stretch="UniformToFill"
TileMode="Tile"
Viewport="0,0,10,10"
ViewportUnits="Absolute">
<DrawingBrush.Drawing>
<DrawingGroup>
<DrawingGroup.Children>
<GeometryDrawing Brush="#0E000000">
<GeometryDrawing.Geometry>
<GeometryGroup FillRule="Nonzero">
<PathGeometry>
<PathFigure StartPoint="0,0">
<LineSegment Point="25,0" />
<LineSegment Point="100,75" />
<LineSegment Point="100,100" />
<LineSegment Point="75,100" />
<LineSegment Point="0,25" />
<LineSegment Point="0,0" />
</PathFigure>
<PathFigure StartPoint="75,0">
<LineSegment Point="100,25" />
<LineSegment Point="100,0" />
</PathFigure>
<PathFigure StartPoint="0,75">
<LineSegment Point="25,100" />
<LineSegment Point="0,100" />
</PathFigure>
</PathGeometry>
</GeometryGroup>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingGroup.Children>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>

We need access to level 2 resources to be able to re-template but that is part of another discussion.

@dipeshmsft
Copy link
Member Author

@robert-abeo , thanks for the insight on the history of accent colors. It pretty much means that we would have to access all of them from WinUI's UISetting type then.

Yeah, while working with Fluent I have understood the layering in the resources and styles and I will try to keep that in order.
But I have included the brush keys here because that has been the general use in theme styles. So basically it will support either scenario.

@dipeshmsft
Copy link
Member Author

cc @ThomasGoulet73 @lindexi @batzen @Symbai @pomianowski @rladuca @vatsan-madhavan

@pomianowski
Copy link
Contributor

Looks great, what about the change while the application is running, maybe some 'AccentColorsChanged' delegate?

@miloush
Copy link
Contributor

miloush commented Jun 27, 2024

These would be updated, so if you use DynamicResource with the keys, the color will change when it changes in the system. There is also UserPreferenceChanged event generated when the theme changes.

@lindexi
Copy link
Member

lindexi commented Jun 28, 2024

LGTM for SystemColors.

@dipeshmsft
Copy link
Member Author

If the community is okay with the shape of this API and there are no objections, I will go ahead and mark it as ready for review tomorrow.

@dipeshmsft dipeshmsft changed the title [Draft] Introducing AccentColor as SystemColors [API Proposal] Introducing AccentColor as SystemColors Jul 1, 2024
@robert-abeo
Copy link

Based on latest strategy for a "hybrid" registration of styles I think it does make sense to only extend SystemColors with the accent colors.

Summarizing the longer comment above, Fluent2 defines system colors in XAML resources directly (a small subset below). If we were to loose access to these by string key the next best option would have been to add as many as possible to SystemColors. That will no longer be needed. The hope is in .NET 10+ WPF will stop mangling theme style resource keys as well so this can all be simplified further in the future again. Either way SystemColors won't need this information now.

<Color x:Key="SystemFillColorSuccess">#0F7B0F</Color>
<Color x:Key="SystemFillColorCaution">#9D5D00</Color>
<Color x:Key="SystemFillColorCritical">#C42B1C</Color>
<Color x:Key="SystemFillColorNeutral">#72000000</Color>
<Color x:Key="SystemFillColorSolidNeutral">#8A8A8A</Color>
<Color x:Key="SystemFillColorAttentionBackground">#80F6F6F6</Color>
<Color x:Key="SystemFillColorSuccessBackground">#DFF6DD</Color>
<Color x:Key="SystemFillColorCautionBackground">#FFF4CE</Color>
<Color x:Key="SystemFillColorCriticalBackground">#FDE7E9</Color>
<Color x:Key="SystemFillColorNeutralBackground">#06000000</Color>
<Color x:Key="SystemFillColorSolidAttentionBackground">#F7F7F7</Color>
<Color x:Key="SystemFillColorSolidNeutralBackground">#F3F3F3</Color>

@robert-abeo
Copy link

Note on the keys: You've dropped the System prefix which will require changing the references for all of us with existing Fluent2 theme styles. I think that makes sense though if you are placing them in SystemColors.

If you went with the separate AccentColorManager or even a FluentColors class, I would expect the keys to match 1-and-1 with WinUI though.

https://github.com/microsoft/microsoft-ui-xaml/blob/539e4de5bb6bf5973cc74110aa926b450b8aa53c/dxaml/xcp/components/theminginterop/inc/ThemingInterop.h#L12-L21

Side-note, you might find something useful here:

https://github.com/microsoft/microsoft-ui-xaml/blob/winui3/release/1.6-stable/dxaml/xcp/components/theminginterop/SystemThemingInterop.cpp

@ThomasGoulet73
Copy link
Contributor

LGTM except a small question:
Is the OS call used to retrieve the values of these properties available/working on all supported versions of Windows ? And if not, what should be the behavior in this case.

@dipeshmsft
Copy link
Member Author

@ThomasGoulet73, no we used a WinRT type UISettings to retreive the values, this is present from Windows 10. In the case where we don't have this type to provide a value, we will provide a fallback for the same.

@dipeshmsft dipeshmsft added api-ready-for-review API is ready for review, it is NOT ready for implementation and removed API suggestion Early API idea and discussion, it is NOT ready for implementation labels Jul 2, 2024
@dipeshmsft dipeshmsft added this to the 9.0.0 milestone Jul 2, 2024
@terrajobst
Copy link
Contributor

  • The API ref seems to imply they are fields, but they should be properties.
  • Otherwise looks good.
namespace System.Windows;

public static class SystemColors
{
    // Accent Colors
    public static Color AccentColor { get; }
    public static Color AccentColorLight1 { get; }
    public static Color AccentColorLight2 { get; }
    public static Color AccentColorLight3 { get; }
    public static Color AccentColorDark1 { get; }
    public static Color AccentColorDark2 { get; }
    public static Color AccentColorDark3 { get; }

    // Accent Color Keys
    public static ResourceKey AccentColorKey { get; }
    public static ResourceKey AccentColorLight1Key { get; }
    public static ResourceKey AccentColorLight2Key { get; }
    public static ResourceKey AccentColorLight3Key { get; }
    public static ResourceKey AccentColorDark1Key { get; }
    public static ResourceKey AccentColorDark2Key { get; }
    public static ResourceKey AccentColorDark3Key { get; }
    
    // Accent Color Brushes
    public static SolidColorBrush AccentColorBrush { get; }
    public static SolidColorBrush AccentColorLight1Brush { get; }
    public static SolidColorBrush AccentColorLight2Brush { get; }
    public static SolidColorBrush AccentColorLight3Brush { get; }
    public static SolidColorBrush AccentColorDark1Brush { get; }
    public static SolidColorBrush AccentColorDark2Brush { get; }
    public static SolidColorBrush AccentColorDark3Brush { get; }

    // Accent Color Brush Keys
    public static ResourceKey AccentColorBrushKey { get; }
    public static ResourceKey AccentColorLight1BrushKey { get; }
    public static ResourceKey AccentColorLight2BrushKey { get; }
    public static ResourceKey AccentColorLight3BrushKey { get; }
    public static ResourceKey AccentColorDark1BrushKey { get; }
    public static ResourceKey AccentColorDark2BrushKey { get; }
    public static ResourceKey AccentColorDark3BrushKey { get; }
}

@terrajobst terrajobst added api-approved API was approved in API review, it can be implemented and removed api-ready-for-review API is ready for review, it is NOT ready for implementation labels Jul 10, 2024
@dotnet-policy-service dotnet-policy-service bot removed this from the 9.0.0 milestone Jul 22, 2024
@github-actions github-actions bot locked and limited conversation to collaborators Aug 22, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api-approved API was approved in API review, it can be implemented Win 11 Theming
Projects
None yet
Development

No branches or pull requests

7 participants