Browse Source

Implement ColorPaletteResources as a public API

pull/11097/head
Max Katz 3 years ago
parent
commit
c9b1ed8f51
  1. 2
      src/Avalonia.Base/Collections/AvaloniaDictionaryExtensions.cs
  2. 69
      src/Avalonia.Themes.Fluent/Accents/BaseColorsPalette.xaml
  3. 154
      src/Avalonia.Themes.Fluent/Accents/BaseResources.xaml
  4. 153
      src/Avalonia.Themes.Fluent/ColorPaletteResources.Properties.cs
  5. 118
      src/Avalonia.Themes.Fluent/ColorPaletteResources.cs
  6. 65
      src/Avalonia.Themes.Fluent/ColorPaletteResourcesCollection.cs
  7. 12
      src/Avalonia.Themes.Fluent/FluentTheme.xaml
  8. 6
      src/Avalonia.Themes.Fluent/FluentTheme.xaml.cs

2
src/Avalonia.Base/Collections/AvaloniaDictionaryExtensions.cs

@ -35,7 +35,7 @@ namespace Avalonia.Collections
/// Indicates if a weak subscription should be used to track changes to the collection.
/// </param>
/// <returns>A disposable used to terminate the subscription.</returns>
internal static IDisposable ForEachItem<TKey, TValue>(
public static IDisposable ForEachItem<TKey, TValue>(
this IAvaloniaReadOnlyDictionary<TKey, TValue> collection,
Action<TKey, TValue> added,
Action<TKey, TValue> removed,

69
src/Avalonia.Themes.Fluent/Accents/BaseColorsPalette.xaml

@ -0,0 +1,69 @@
<ResourceDictionary xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- https://docs.microsoft.com/en-us/previous-versions/windows/apps/dn518235(v=win.10)?redirectedfrom=MSDN -->
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Default">
<Color x:Key="SystemAltHighColor">#FFFFFFFF</Color>
<Color x:Key="SystemAltLowColor">#33FFFFFF</Color>
<Color x:Key="SystemAltMediumColor">#99FFFFFF</Color>
<Color x:Key="SystemAltMediumHighColor">#CCFFFFFF</Color>
<Color x:Key="SystemAltMediumLowColor">#66FFFFFF</Color>
<Color x:Key="SystemBaseHighColor">#FF000000</Color>
<Color x:Key="SystemBaseLowColor">#33000000</Color>
<Color x:Key="SystemBaseMediumColor">#99000000</Color>
<Color x:Key="SystemBaseMediumHighColor">#CC000000</Color>
<Color x:Key="SystemBaseMediumLowColor">#66000000</Color>
<Color x:Key="SystemChromeAltLowColor">#FF171717</Color>
<Color x:Key="SystemChromeBlackHighColor">#FF000000</Color>
<Color x:Key="SystemChromeBlackLowColor">#33000000</Color>
<Color x:Key="SystemChromeBlackMediumLowColor">#66000000</Color>
<Color x:Key="SystemChromeBlackMediumColor">#CC000000</Color>
<Color x:Key="SystemChromeDisabledHighColor">#FFCCCCCC</Color>
<Color x:Key="SystemChromeDisabledLowColor">#FF7A7A7A</Color>
<Color x:Key="SystemChromeHighColor">#FFCCCCCC</Color>
<Color x:Key="SystemChromeLowColor">#FFF2F2F2</Color>
<Color x:Key="SystemChromeMediumColor">#FFE6E6E6</Color>
<Color x:Key="SystemChromeMediumLowColor">#FFF2F2F2</Color>
<Color x:Key="SystemChromeWhiteColor">#FFFFFFFF</Color>
<Color x:Key="SystemChromeGrayColor">#FF767676</Color>
<Color x:Key="SystemListLowColor">#19000000</Color>
<Color x:Key="SystemListMediumColor">#33000000</Color>
<Color x:Key="SystemErrorTextColor">#C50500</Color>
<Color x:Key="RegionColor">#FFFFFFFF</Color>
<Color x:Key="SystemRevealListLowColor">#17000000</Color>
<Color x:Key="SystemRevealListMediumColor">#2E000000</Color>
</ResourceDictionary>
<ResourceDictionary x:Key="Dark">
<Color x:Key="SystemAltHighColor">#FF000000</Color>
<Color x:Key="SystemAltLowColor">#33000000</Color>
<Color x:Key="SystemAltMediumColor">#99000000</Color>
<Color x:Key="SystemAltMediumHighColor">#CC000000</Color>
<Color x:Key="SystemAltMediumLowColor">#66000000</Color>
<Color x:Key="SystemBaseHighColor">#FFFFFFFF</Color>
<Color x:Key="SystemBaseLowColor">#33FFFFFF</Color>
<Color x:Key="SystemBaseMediumColor">#99FFFFFF</Color>
<Color x:Key="SystemBaseMediumHighColor">#CCFFFFFF</Color>
<Color x:Key="SystemBaseMediumLowColor">#66FFFFFF</Color>
<Color x:Key="SystemChromeAltLowColor">#FFF2F2F2</Color>
<Color x:Key="SystemChromeBlackHighColor">#FF000000</Color>
<Color x:Key="SystemChromeBlackLowColor">#33000000</Color>
<Color x:Key="SystemChromeBlackMediumLowColor">#66000000</Color>
<Color x:Key="SystemChromeBlackMediumColor">#CC000000</Color>
<Color x:Key="SystemChromeDisabledHighColor">#FF333333</Color>
<Color x:Key="SystemChromeDisabledLowColor">#FF858585</Color>
<Color x:Key="SystemChromeHighColor">#FF767676</Color>
<Color x:Key="SystemChromeLowColor">#FF171717</Color>
<Color x:Key="SystemChromeMediumColor">#FF1F1F1F</Color>
<Color x:Key="SystemChromeMediumLowColor">#FF2B2B2B</Color>
<Color x:Key="SystemChromeWhiteColor">#FFFFFFFF</Color>
<Color x:Key="SystemChromeGrayColor">#FF767676</Color>
<Color x:Key="SystemListLowColor">#19FFFFFF</Color>
<Color x:Key="SystemListMediumColor">#33FFFFFF</Color>
<Color x:Key="SystemErrorTextColor">#FFF000</Color>
<Color x:Key="RegionColor">#FF000000</Color>
<Color x:Key="SystemRevealListLowColor">#18FFFFFF</Color>
<Color x:Key="SystemRevealListMediumColor">#30FFFFFF</Color>
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>

154
src/Avalonia.Themes.Fluent/Accents/Base.xaml → src/Avalonia.Themes.Fluent/Accents/BaseResources.xaml

@ -2,7 +2,6 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="using:System"
xmlns:converters="using:Avalonia.Controls.Converters">
<!-- https://docs.microsoft.com/en-us/previous-versions/windows/apps/dn518235(v=win.10)?redirectedfrom=MSDN -->
<FontFamily x:Key="ContentControlThemeFontFamily">fonts:Inter#Inter, $Default</FontFamily>
<sys:Double x:Key="ControlContentThemeFontSize">14</sys:Double>
@ -28,39 +27,33 @@
<converters:CornerRadiusFilterConverter x:Key="BottomCornerRadiusFilterConverter" Filter="BottomLeft, BottomRight" />
<converters:CornerRadiusFilterConverter x:Key="LeftCornerRadiusFilterConverter" Filter="TopLeft, BottomLeft" />
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Default">
<!-- System Control Colors -->
<Color x:Key="SystemAltHighColor">#FFFFFFFF</Color>
<Color x:Key="SystemAltLowColor">#33FFFFFF</Color>
<Color x:Key="SystemAltMediumColor">#99FFFFFF</Color>
<Color x:Key="SystemAltMediumHighColor">#CCFFFFFF</Color>
<Color x:Key="SystemAltMediumLowColor">#66FFFFFF</Color>
<Color x:Key="SystemBaseHighColor">#FF000000</Color>
<Color x:Key="SystemBaseLowColor">#33000000</Color>
<Color x:Key="SystemBaseMediumColor">#99000000</Color>
<Color x:Key="SystemBaseMediumHighColor">#CC000000</Color>
<Color x:Key="SystemBaseMediumLowColor">#66000000</Color>
<Color x:Key="SystemChromeAltLowColor">#FF171717</Color>
<Color x:Key="SystemChromeBlackHighColor">#FF000000</Color>
<Color x:Key="SystemChromeBlackLowColor">#33000000</Color>
<Color x:Key="SystemChromeBlackMediumLowColor">#66000000</Color>
<Color x:Key="SystemChromeBlackMediumColor">#CC000000</Color>
<Color x:Key="SystemChromeDisabledHighColor">#FFCCCCCC</Color>
<Color x:Key="SystemChromeDisabledLowColor">#FF7A7A7A</Color>
<Color x:Key="SystemChromeHighColor">#FFCCCCCC</Color>
<Color x:Key="SystemChromeLowColor">#FFF2F2F2</Color>
<Color x:Key="SystemChromeMediumColor">#FFE6E6E6</Color>
<Color x:Key="SystemChromeMediumLowColor">#FFF2F2F2</Color>
<Color x:Key="SystemChromeWhiteColor">#FFFFFFFF</Color>
<Color x:Key="SystemChromeGrayColor">#FF767676</Color>
<Color x:Key="SystemListLowColor">#19000000</Color>
<Color x:Key="SystemListMediumColor">#33000000</Color>
<Color x:Key="SystemErrorTextColor">#C50500</Color>
<x:Double x:Key="AutoCompleteListMaxHeight">374</x:Double>
<Thickness x:Key="AutoCompleteListMargin">0,2,0,2</Thickness>
<Thickness x:Key="AutoCompleteListBorderThemeThickness">1</Thickness>
<Thickness x:Key="AutoCompleteListPadding">-1,0,-1,0</Thickness>
<x:Double x:Key="TextControlThemeMinHeight">32</x:Double>
<x:Double x:Key="TextControlThemeMinWidth">64</x:Double>
<x:Double x:Key="FlyoutThemeMaxWidth">456</x:Double>
<Thickness x:Key="DateTimeFlyoutButtonBorderThickness">0</Thickness>
<Thickness x:Key="DateTimeFlyoutBorderThickness">1</Thickness>
<Thickness x:Key="DateTimeFlyoutBorderPadding">0</Thickness>
<Thickness x:Key="FlyoutContentThemePadding">12,11,12,12</Thickness>
<x:Double x:Key="FlyoutThemeMinWidth">96</x:Double>
<x:Double x:Key="FlyoutThemeMinHeight">40</x:Double>
<x:Double x:Key="FlyoutThemeMaxHeight">758</x:Double>
<Color x:Key="SystemRevealListLowColor">#17000000</Color>
<Color x:Key="SystemRevealListMediumColor">#2E000000</Color>
<!-- Moved from FlyoutPresenter.xaml -->
<Thickness x:Key="FlyoutBorderThemePadding">0</Thickness>
<!-- Moved from MenuItem.xaml -->
<Thickness x:Key="MenuFlyoutScrollerMargin">0,4,0,4</Thickness>
<!-- Moved from Menu.xaml -->
<Thickness x:Key="MenuBarItemPadding">12,0,12,0</Thickness>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Default">
<SolidColorBrush x:Key="SystemControlBackgroundAccentBrush" Color="{DynamicResource SystemAccentColor}" />
<SolidColorBrush x:Key="SystemControlBackgroundAltHighBrush" Color="{StaticResource SystemAltHighColor}" />
<SolidColorBrush x:Key="SystemControlBackgroundAltMediumHighBrush"
@ -211,82 +204,17 @@
Color="{StaticResource SystemChromeWhiteColor}" />
<SolidColorBrush x:Key="SystemControlHighlightAltTransparentRevealBorderBrush" Color="Transparent" />
<SolidColorBrush x:Key="SystemControlBackgroundTransparentRevealBorderBrush" Color="Transparent" />
<!-- TODO implement AcrylicBrush -->
<!--<AcrylicBrush x:Key="SystemControlTransientBackgroundBrush" BackgroundSource="HostBackdrop" TintColor="{StaticResource SystemChromeAltHighColor}" TintOpacity="0.8" FallbackColor="{StaticResource SystemChromeMediumLowColor}" />-->
<SolidColorBrush x:Key="SystemControlTransientBackgroundBrush"
Color="{StaticResource SystemChromeMediumLowColor}" />
<StaticResource x:Key="SystemControlDescriptionTextForegroundBrush"
ResourceKey="SystemControlPageTextBaseMediumBrush" />
<!--<AcrylicBrush x:Key="SystemControlAcrylicWindowBrush" BackgroundSource="HostBackdrop" TintColor="{ThemeResource SystemChromeAltHighColor}" TintOpacity="0.8" FallbackColor="{ThemeResource SystemChromeMediumColor}" />-->
<!--<RevealBackgroundBrush x:Key="SystemControlTransparentRevealBackgroundBrush" TargetTheme="Dark" Color="Transparent" FallbackColor="Transparent" />-->
<SolidColorBrush x:Key="SystemControlTransparentRevealBackgroundBrush" Color="Transparent" />
<!--<RevealBorderBrush x:Key="SystemControlTransparentRevealBorderBrush" TargetTheme="Dark" Color="Transparent" FallbackColor="Transparent" />-->
<SolidColorBrush x:Key="SystemControlTransparentRevealBorderBrush" Color="Transparent" />
<!--<RevealBackgroundBrush x:Key="SystemControlHighlightListLowRevealBackgroundBrush" TargetTheme="Light" Color="{ThemeResource SystemRevealListMediumColor}" FallbackColor="{ StaticResource SystemListMediumColor}" />-->
<Color x:Key="RegionColor">#FFFFFFFF</Color>
<SolidColorBrush x:Key="RegionBrush" Color="{StaticResource RegionColor}" />
<x:Double x:Key="AutoCompleteListMaxHeight">374</x:Double>
<Thickness x:Key="AutoCompleteListMargin">0,2,0,2</Thickness>
<Thickness x:Key="AutoCompleteListBorderThemeThickness">1</Thickness>
<Thickness x:Key="AutoCompleteListPadding">-1,0,-1,0</Thickness>
<x:Double x:Key="TextControlThemeMinHeight">32</x:Double>
<x:Double x:Key="TextControlThemeMinWidth">64</x:Double>
<x:Double x:Key="FlyoutThemeMaxWidth">456</x:Double>
<Thickness x:Key="DateTimeFlyoutButtonBorderThickness">0</Thickness>
<Thickness x:Key="DateTimeFlyoutBorderThickness">1</Thickness>
<Thickness x:Key="DateTimeFlyoutBorderPadding">0</Thickness>
<Thickness x:Key="FlyoutContentThemePadding">12,11,12,12</Thickness>
<x:Double x:Key="FlyoutThemeMinWidth">96</x:Double>
<x:Double x:Key="FlyoutThemeMinHeight">40</x:Double>
<x:Double x:Key="FlyoutThemeMaxHeight">758</x:Double>
<!-- Moved from FlyoutPresenter.xaml -->
<Thickness x:Key="FlyoutBorderThemePadding">0</Thickness>
<!-- Moved from MenuItem.xaml -->
<Thickness x:Key="MenuFlyoutScrollerMargin">0,4,0,4</Thickness>
<!-- Moved from Menu.xaml -->
<Thickness x:Key="MenuBarItemPadding">12,0,12,0</Thickness>
</ResourceDictionary>
<ResourceDictionary x:Key="Dark">
<!-- System Control Colors -->
<Color x:Key="SystemAltHighColor">#FF000000</Color>
<Color x:Key="SystemAltLowColor">#33000000</Color>
<Color x:Key="SystemAltMediumColor">#99000000</Color>
<Color x:Key="SystemAltMediumHighColor">#CC000000</Color>
<Color x:Key="SystemAltMediumLowColor">#66000000</Color>
<Color x:Key="SystemBaseHighColor">#FFFFFFFF</Color>
<Color x:Key="SystemBaseLowColor">#33FFFFFF</Color>
<Color x:Key="SystemBaseMediumColor">#99FFFFFF</Color>
<Color x:Key="SystemBaseMediumHighColor">#CCFFFFFF</Color>
<Color x:Key="SystemBaseMediumLowColor">#66FFFFFF</Color>
<Color x:Key="SystemChromeAltLowColor">#FFF2F2F2</Color>
<Color x:Key="SystemChromeBlackHighColor">#FF000000</Color>
<Color x:Key="SystemChromeBlackLowColor">#33000000</Color>
<Color x:Key="SystemChromeBlackMediumLowColor">#66000000</Color>
<Color x:Key="SystemChromeBlackMediumColor">#CC000000</Color>
<Color x:Key="SystemChromeDisabledHighColor">#FF333333</Color>
<Color x:Key="SystemChromeDisabledLowColor">#FF858585</Color>
<Color x:Key="SystemChromeHighColor">#FF767676</Color>
<Color x:Key="SystemChromeLowColor">#FF171717</Color>
<Color x:Key="SystemChromeMediumColor">#FF1F1F1F</Color>
<Color x:Key="SystemChromeMediumLowColor">#FF2B2B2B</Color>
<Color x:Key="SystemChromeWhiteColor">#FFFFFFFF</Color>
<Color x:Key="SystemChromeGrayColor">#FF767676</Color>
<Color x:Key="SystemListLowColor">#19FFFFFF</Color>
<Color x:Key="SystemListMediumColor">#33FFFFFF</Color>
<Color x:Key="SystemErrorTextColor">#FFF000</Color>
<Color x:Key="SystemRevealListLowColor">#18FFFFFF</Color>
<Color x:Key="SystemRevealListMediumColor">#30FFFFFF</Color>
<SolidColorBrush x:Key="SystemControlBackgroundAccentBrush" Color="{DynamicResource SystemAccentColor}" />
<SolidColorBrush x:Key="SystemControlBackgroundAltHighBrush" Color="{StaticResource SystemAltHighColor}" />
<SolidColorBrush x:Key="SystemControlBackgroundAltMediumHighBrush"
@ -437,46 +365,14 @@
Color="{StaticResource SystemChromeWhiteColor}" />
<SolidColorBrush x:Key="SystemControlHighlightAltTransparentRevealBorderBrush" Color="Transparent" />
<SolidColorBrush x:Key="SystemControlBackgroundTransparentRevealBorderBrush" Color="Transparent" />
<!-- TODO implement AcrylicBrush -->
<!--<AcrylicBrush x:Key="SystemControlTransientBackgroundBrush" BackgroundSource="HostBackdrop" TintColor="{StaticResource SystemChromeAltHighColor}" TintOpacity="0.8" FallbackColor="{StaticResource SystemChromeMediumLowColor}" />-->
<SolidColorBrush x:Key="SystemControlTransientBackgroundBrush"
Color="{StaticResource SystemChromeMediumLowColor}" />
<StaticResource x:Key="SystemControlDescriptionTextForegroundBrush"
ResourceKey="SystemControlPageTextBaseMediumBrush" />
<!--<AcrylicBrush x:Key="SystemControlAcrylicWindowBrush" BackgroundSource="HostBackdrop" TintColor="{ThemeResource SystemChromeAltHighColor}" TintOpacity="0.8" FallbackColor="{ThemeResource SystemChromeMediumColor}" />-->
<!--<RevealBackgroundBrush x:Key="SystemControlTransparentRevealBackgroundBrush" TargetTheme="Dark" Color="Transparent" FallbackColor="Transparent" />-->
<SolidColorBrush x:Key="SystemControlTransparentRevealBackgroundBrush" Color="Transparent" />
<!--<RevealBorderBrush x:Key="SystemControlTransparentRevealBorderBrush" TargetTheme="Dark" Color="Transparent" FallbackColor="Transparent" />-->
<SolidColorBrush x:Key="SystemControlTransparentRevealBorderBrush" Color="Transparent" />
<Color x:Key="RegionColor">#FF000000</Color>
<SolidColorBrush x:Key="RegionBrush" Color="{StaticResource RegionColor}" />
<x:Double x:Key="AutoCompleteListMaxHeight">374</x:Double>
<Thickness x:Key="AutoCompleteListMargin">0,2,0,2</Thickness>
<Thickness x:Key="AutoCompleteListBorderThemeThickness">1</Thickness>
<Thickness x:Key="AutoCompleteListPadding">-1,0,-1,0</Thickness>
<x:Double x:Key="TextControlThemeMinHeight">32</x:Double>
<x:Double x:Key="TextControlThemeMinWidth">64</x:Double>
<x:Double x:Key="FlyoutThemeMaxWidth">456</x:Double>
<Thickness x:Key="DateTimeFlyoutButtonBorderThickness">0</Thickness>
<Thickness x:Key="DateTimeFlyoutBorderThickness">1</Thickness>
<Thickness x:Key="DateTimeFlyoutBorderPadding">0</Thickness>
<Thickness x:Key="FlyoutContentThemePadding">12,11,12,12</Thickness>
<x:Double x:Key="FlyoutThemeMinWidth">96</x:Double>
<x:Double x:Key="FlyoutThemeMinHeight">40</x:Double>
<x:Double x:Key="FlyoutThemeMaxHeight">758</x:Double>
<!-- Moved from FlyoutPresenter.xaml -->
<Thickness x:Key="FlyoutBorderThemePadding">0</Thickness>
<!-- Moved from MenuItem.xaml -->
<Thickness x:Key="MenuFlyoutScrollerMargin">0,4,0,4</Thickness>
<!-- Moved from Menu.xaml -->
<Thickness x:Key="MenuBarItemPadding">12,0,12,0</Thickness>
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>

153
src/Avalonia.Themes.Fluent/ColorPaletteResources.Properties.cs

@ -0,0 +1,153 @@
using Avalonia.Media;
namespace Avalonia.Themes.Fluent;
public partial class ColorPaletteResources
{
private bool _hasAccentColor;
private Color _accentColor;
private Color _accentColorDark1, _accentColorDark2, _accentColorDark3;
private Color _accentColorLight1, _accentColorLight2, _accentColorLight3;
public static readonly DirectProperty<ColorPaletteResources, Color> AccentProperty
= AvaloniaProperty.RegisterDirect<ColorPaletteResources, Color>(nameof(Accent), r => r.Accent, (r, v) => r.Accent = v);
/// <summary>
/// Gets or sets the Accent color value.
/// </summary>
public Color Accent
{
get => _accentColor;
set => SetAndRaise(AccentProperty, ref _accentColor, value);
}
/// <summary>
/// Gets or sets the AltHigh color value.
/// </summary>
public Color AltHigh { get => GetColor("SystemAltHighColor"); set => SetColor("SystemAltHighColor", value); }
/// <summary>
/// Gets or sets the AltLow color value.
/// </summary>
public Color AltLow { get => GetColor("SystemAltLowColor"); set => SetColor("SystemAltLowColor", value); }
/// <summary>
/// Gets or sets the AltMedium color value.
/// </summary>
public Color AltMedium { get => GetColor("SystemAltMediumColor"); set => SetColor("SystemAltMediumColor", value); }
/// <summary>
/// Gets or sets the AltMediumHigh color value.
/// </summary>
public Color AltMediumHigh { get => GetColor("SystemAltMediumHighColor"); set => SetColor("SystemAltMediumHighColor", value); }
/// <summary>
/// Gets or sets the AltMediumLow color value.
/// </summary>
public Color AltMediumLow { get => GetColor("SystemAltMediumLowColor"); set => SetColor("SystemAltMediumLowColor", value); }
/// <summary>
/// Gets or sets the BaseHigh color value.
/// </summary>
public Color BaseHigh { get => GetColor("SystemBaseHighColor"); set => SetColor("SystemBaseHighColor", value); }
/// <summary>
/// Gets or sets the BaseLow color value.
/// </summary>
public Color BaseLow { get => GetColor("SystemBaseLowColor"); set => SetColor("SystemBaseLowColor", value); }
/// <summary>
/// Gets or sets the BaseMedium color value.
/// </summary>
public Color BaseMedium { get => GetColor("SystemBaseMediumColor"); set => SetColor("SystemBaseMediumColor", value); }
/// <summary>
/// Gets or sets the BaseMediumHigh color value.
/// </summary>
public Color BaseMediumHigh { get => GetColor("SystemBaseMediumHighColor"); set => SetColor("SystemBaseMediumHighColor", value); }
/// <summary>
/// Gets or sets the BaseMediumLow color value.
/// </summary>
public Color BaseMediumLow { get => GetColor("SystemBaseMediumLowColor"); set => SetColor("SystemBaseMediumLowColor", value); }
/// <summary>
/// Gets or sets the ChromeAltLow color value.
/// </summary>
public Color ChromeAltLow { get => GetColor("SystemChromeAltLowColor"); set => SetColor("SystemChromeAltLowColor", value); }
/// <summary>
/// Gets or sets the ChromeBlackHigh color value.
/// </summary>
public Color ChromeBlackHigh { get => GetColor("SystemChromeBlackHighColor"); set => SetColor("SystemChromeBlackHighColor", value); }
/// <summary>
/// Gets or sets the ChromeBlackLow color value.
/// </summary>
public Color ChromeBlackLow { get => GetColor("SystemChromeBlackLowColor"); set => SetColor("SystemChromeBlackLowColor", value); }
/// <summary>
/// Gets or sets the ChromeBlackMedium color value.
/// </summary>
public Color ChromeBlackMedium { get => GetColor("SystemChromeBlackMediumColor"); set => SetColor("SystemChromeBlackMediumColor", value); }
/// <summary>
/// Gets or sets the ChromeBlackMediumLow color value.
/// </summary>
public Color ChromeBlackMediumLow { get => GetColor("SystemChromeBlackMediumLowColor"); set => SetColor("SystemChromeBlackMediumLowColor", value); }
/// <summary>
/// Gets or sets the ChromeDisabledHigh color value.
/// </summary>
public Color ChromeDisabledHigh { get => GetColor("SystemChromeDisabledHighColor"); set => SetColor("SystemChromeDisabledHighColor", value); }
/// <summary>
/// Gets or sets the ChromeDisabledLow color value.
/// </summary>
public Color ChromeDisabledLow { get => GetColor("SystemChromeDisabledLowColor"); set => SetColor("SystemChromeDisabledLowColor", value); }
/// <summary>
/// Gets or sets the ChromeGray color value.
/// </summary>
public Color ChromeGray { get => GetColor("SystemChromeGrayColor"); set => SetColor("SystemChromeGrayColor", value); }
/// <summary>
/// Gets or sets the ChromeHigh color value.
/// </summary>
public Color ChromeHigh { get => GetColor("SystemChromeHighColor"); set => SetColor("SystemChromeHighColor", value); }
/// <summary>
/// Gets or sets the ChromeLow color value.
/// </summary>
public Color ChromeLow { get => GetColor("SystemChromeLowColor"); set => SetColor("SystemChromeLowColor", value); }
/// <summary>
/// Gets or sets the ChromeMedium color value.
/// </summary>
public Color ChromeMedium { get => GetColor("SystemChromeMediumColor"); set => SetColor("SystemChromeMediumColor", value); }
/// <summary>
/// Gets or sets the ChromeMediumLow color value.
/// </summary>
public Color ChromeMediumLow { get => GetColor("SystemChromeMediumLowColor"); set => SetColor("SystemChromeMediumLowColor", value); }
/// <summary>
/// Gets or sets the ChromeWhite color value.
/// </summary>
public Color ChromeWhite { get => GetColor("SystemChromeWhiteColor"); set => SetColor("SystemChromeWhiteColor", value); }
/// <summary>
/// Gets or sets the ErrorText color value.
/// </summary>
public Color ErrorText { get => GetColor("SystemErrorTextColor"); set => SetColor("SystemErrorTextColor", value); }
/// <summary>
/// Gets or sets the ListLow color value.
/// </summary>
public Color ListLow { get => GetColor("SystemListLowColor"); set => SetColor("SystemListLowColor", value); }
/// <summary>
/// Gets or sets the ListMedium color value.
/// </summary>
public Color ListMedium { get => GetColor("SystemListMediumColor"); set => SetColor("SystemListMediumColor", value); }
}

118
src/Avalonia.Themes.Fluent/ColorPaletteResources.cs

@ -0,0 +1,118 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Avalonia.Controls;
using Avalonia.Media;
using Avalonia.Styling;
using Avalonia.Themes.Fluent.Accents;
namespace Avalonia.Themes.Fluent;
/// <summary>
/// Represents a specialized resource dictionary that contains color resources used by FluentTheme elements.
/// </summary>
/// <remarks>
/// This class can only be used in <see cref="FluentTheme.Palettes"/>.
/// </remarks>
public partial class ColorPaletteResources : AvaloniaObject, IResourceNode
{
private readonly Dictionary<string, Color> _colors = new(StringComparer.InvariantCulture);
public bool HasResources => _hasAccentColor || _colors.Count > 0;
public bool TryGetResource(object key, ThemeVariant? theme, out object? value)
{
if (key is string strKey)
{
if (strKey.Equals(SystemAccentColors.AccentKey, StringComparison.InvariantCulture))
{
value = _accentColor;
return _hasAccentColor;
}
if (strKey.Equals(SystemAccentColors.AccentDark1Key, StringComparison.InvariantCulture))
{
value = _accentColorDark1;
return _hasAccentColor;
}
if (strKey.Equals(SystemAccentColors.AccentDark2Key, StringComparison.InvariantCulture))
{
value = _accentColorDark2;
return _hasAccentColor;
}
if (strKey.Equals(SystemAccentColors.AccentDark3Key, StringComparison.InvariantCulture))
{
value = _accentColorDark3;
return _hasAccentColor;
}
if (strKey.Equals(SystemAccentColors.AccentLight1Key, StringComparison.InvariantCulture))
{
value = _accentColorLight1;
return _hasAccentColor;
}
if (strKey.Equals(SystemAccentColors.AccentLight2Key, StringComparison.InvariantCulture))
{
value = _accentColorLight2;
return _hasAccentColor;
}
if (strKey.Equals(SystemAccentColors.AccentLight3Key, StringComparison.InvariantCulture))
{
value = _accentColorLight3;
return _hasAccentColor;
}
if (_colors.TryGetValue(strKey, out var color))
{
value = color;
return true;
}
}
value = null;
return false;
}
private Color GetColor(string key)
{
if (_colors.TryGetValue(key, out var color))
{
return color;
}
return default;
}
private void SetColor(string key, Color value)
{
if (value == default)
{
_colors.Remove(key);
}
else
{
_colors[key] = value;
}
}
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
base.OnPropertyChanged(change);
if (change.Property == AccentProperty)
{
_hasAccentColor = _accentColor != default;
if (_hasAccentColor)
{
(_accentColorDark1, _accentColorDark2, _accentColorDark3,
_accentColorLight1, _accentColorLight2, _accentColorLight3) =
SystemAccentColors.CalculateAccentShades(_accentColor);
}
}
}
}

65
src/Avalonia.Themes.Fluent/ColorPaletteResourcesCollection.cs

@ -0,0 +1,65 @@
using System;
using Avalonia.Collections;
using Avalonia.Controls;
using Avalonia.Styling;
namespace Avalonia.Themes.Fluent;
internal class ColorPaletteResourcesCollection : AvaloniaDictionary<ThemeVariant, ColorPaletteResources>, IResourceProvider
{
public ColorPaletteResourcesCollection() : base(2)
{
this.ForEachItem(
(_, x) =>
{
if (Owner is not null)
{
x.PropertyChanged += Palette_PropertyChanged;
}
},
(_, x) =>
{
if (Owner is not null)
{
x.PropertyChanged -= Palette_PropertyChanged;
}
},
() => throw new NotSupportedException("Dictionary reset not supported"));
}
public bool HasResources => Count > 0;
public bool TryGetResource(object key, ThemeVariant? theme, out object? value)
{
theme ??= ThemeVariant.Default;
if (base.TryGetValue(theme, out var paletteResources)
&& paletteResources.TryGetResource(key, theme, out value))
{
return true;
}
value = null;
return false;
}
public IResourceHost? Owner { get; private set; }
public event EventHandler? OwnerChanged;
public void AddOwner(IResourceHost owner)
{
Owner = owner;
OwnerChanged?.Invoke(this, EventArgs.Empty);
}
public void RemoveOwner(IResourceHost owner)
{
Owner = null;
OwnerChanged?.Invoke(this, EventArgs.Empty);
}
private void Palette_PropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e)
{
if (e.Property == ColorPaletteResources.AccentProperty)
{
Owner?.NotifyHostedResourcesChanged(ResourcesChangedEventArgs.Empty);
}
}
}

12
src/Avalonia.Themes.Fluent/FluentTheme.xaml

@ -1,11 +1,19 @@
<Styles x:Class="Avalonia.Themes.Fluent.FluentTheme"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:fluent="using:Avalonia.Themes.Fluent"
xmlns:accents="clr-namespace:Avalonia.Themes.Fluent.Accents">
<Styles.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<MergeResourceInclude Source="/Accents/Base.xaml" />
<!-- Resources and brushes will be merged into current dictionary for slightly better performance and possible optimizations -->
<MergeResourceInclude Source="/Accents/BaseResources.xaml" />
<MergeResourceInclude Source="/Accents/FluentControlResources.xaml" />
<!-- Keep custom palettes higher priority than default BaseColorsPalette and SystemAccentColors
As that's an only place for user to redefine palette in a good way -->
<fluent:ColorPaletteResourcesCollection />
<accents:SystemAccentColors />
<ResourceInclude Source="/Accents/BaseColorsPalette.xaml" />
</ResourceDictionary.MergedDictionaries>

6
src/Avalonia.Themes.Fluent/FluentTheme.xaml.cs

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Avalonia.Styling;
@ -31,6 +32,9 @@ namespace Avalonia.Themes.Fluent
EnsureCompactStyles();
Palettes = Resources.MergedDictionaries.OfType<ColorPaletteResourcesCollection>().FirstOrDefault()
?? throw new InvalidOperationException("FluentTheme was initialized with missing ColorPaletteResourcesCollection.");
object GetAndRemove(string key)
{
var val = Resources[key]
@ -52,6 +56,8 @@ namespace Avalonia.Themes.Fluent
set => SetValue(DensityStyleProperty, value);
}
public IDictionary<ThemeVariant, ColorPaletteResources> Palettes { get; }
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
base.OnPropertyChanged(change);

Loading…
Cancel
Save