diff --git a/samples/RenderDemo/App.xaml b/samples/RenderDemo/App.xaml index eeeaf5b0ae..7cdcea2e1d 100644 --- a/samples/RenderDemo/App.xaml +++ b/samples/RenderDemo/App.xaml @@ -3,7 +3,7 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="RenderDemo.App"> - + diff --git a/samples/Sandbox/App.axaml b/samples/Sandbox/App.axaml index a351ba93e9..f601f9f78f 100644 --- a/samples/Sandbox/App.axaml +++ b/samples/Sandbox/App.axaml @@ -3,6 +3,6 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="Sandbox.App"> - + diff --git a/src/Avalonia.Themes.Fluent/ApiCompatBaseline.txt b/src/Avalonia.Themes.Fluent/ApiCompatBaseline.txt index 68dc477cbc..44e250b889 100644 --- a/src/Avalonia.Themes.Fluent/ApiCompatBaseline.txt +++ b/src/Avalonia.Themes.Fluent/ApiCompatBaseline.txt @@ -1,3 +1,4 @@ Compat issues with assembly Avalonia.Themes.Fluent: -TypesMustExist : Type 'Avalonia.Themes.Fluent.FluentTheme' does not exist in the implementation but it does exist in the contract. -Total Issues: 1 +CannotRemoveBaseTypeOrInterface : Type 'Avalonia.Themes.Fluent.FluentTheme' does not inherit from base type 'Avalonia.Styling.Styles' in the implementation but it does in the contract. +MembersMustExist : Member 'public void Avalonia.Themes.Fluent.FluentTheme..ctor()' does not exist in the implementation but it does exist in the contract. +Total Issues: 2 diff --git a/src/Avalonia.Themes.Fluent/FluentTheme.cs b/src/Avalonia.Themes.Fluent/FluentTheme.cs new file mode 100644 index 0000000000..43b71567fa --- /dev/null +++ b/src/Avalonia.Themes.Fluent/FluentTheme.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; +using Avalonia.Controls; +using Avalonia.Markup.Xaml; +using Avalonia.Styling; + +#nullable enable + +namespace Avalonia.Themes.Fluent +{ + public enum FluentThemeMode + { + Light, + Dark, + } + + /// + /// Includes the fluent theme in an application. + /// + public class FluentTheme : IStyle, IResourceProvider + { + private readonly Uri _baseUri; + private IStyle[]? _loaded; + private bool _isLoading; + + /// + /// Initializes a new instance of the class. + /// + /// The base URL for the XAML context. + public FluentTheme(Uri baseUri) + { + _baseUri = baseUri; + } + + /// + /// Initializes a new instance of the class. + /// + /// The XAML service provider. + public FluentTheme(IServiceProvider serviceProvider) + { + _baseUri = ((IUriContext)serviceProvider.GetService(typeof(IUriContext))).BaseUri; + } + + /// + /// Gets or sets the mode of the fluent theme (light, dark). + /// + public FluentThemeMode Mode { get; set; } + + public IResourceHost? Owner => (Loaded as IResourceProvider)?.Owner; + + /// + /// Gets the loaded style. + /// + public IStyle Loaded + { + get + { + if (_loaded == null) + { + _isLoading = true; + var loaded = (IStyle)AvaloniaXamlLoader.Load(GetUri(), _baseUri); + _loaded = new[] { loaded }; + _isLoading = false; + } + + return _loaded?[0]!; + } + } + + bool IResourceNode.HasResources => (Loaded as IResourceProvider)?.HasResources ?? false; + + IReadOnlyList IStyle.Children => _loaded ?? Array.Empty(); + + public event EventHandler OwnerChanged + { + add + { + if (Loaded is IResourceProvider rp) + { + rp.OwnerChanged += value; + } + } + remove + { + if (Loaded is IResourceProvider rp) + { + rp.OwnerChanged -= value; + } + } + } + + public SelectorMatchResult TryAttach(IStyleable target, IStyleHost? host) => Loaded.TryAttach(target, host); + + public bool TryGetResource(object key, out object? value) + { + if (!_isLoading && Loaded is IResourceProvider p) + { + return p.TryGetResource(key, out value); + } + + value = null; + return false; + } + + void IResourceProvider.AddOwner(IResourceHost owner) => (Loaded as IResourceProvider)?.AddOwner(owner); + void IResourceProvider.RemoveOwner(IResourceHost owner) => (Loaded as IResourceProvider)?.RemoveOwner(owner); + + private Uri GetUri() => Mode switch + { + FluentThemeMode.Dark => new Uri("avares://Avalonia.Themes.Fluent/FluentDark.xaml", UriKind.Absolute), + _ => new Uri("avares://Avalonia.Themes.Fluent/FluentLight.xaml", UriKind.Absolute), + }; + } +} diff --git a/src/Avalonia.Themes.Fluent/Properties/AssemblyInfo.cs b/src/Avalonia.Themes.Fluent/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..0bad226ba7 --- /dev/null +++ b/src/Avalonia.Themes.Fluent/Properties/AssemblyInfo.cs @@ -0,0 +1,3 @@ +using Avalonia.Metadata; + +[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Themes.Fluent")]