diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj index c3982a685b1..6c5fe2387e6 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj +++ b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj @@ -832,9 +832,6 @@ MarkdownTextBlockPage.xaml - - TileControlPage.xaml - RadialProgressBarPage.xaml @@ -1245,10 +1242,6 @@ MSBuild:Compile Designer - - MSBuild:Compile - Designer - MSBuild:Compile Designer diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/TileControl/TileControl.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/TileControl/TileControl.bind index 81ae40efb10..5a762c40c9e 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/TileControl/TileControl.bind +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/TileControl/TileControl.bind @@ -2,75 +2,34 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls" + xmlns:ani="using:Microsoft.Toolkit.Uwp.UI.Animations" + xmlns:media="using:Microsoft.Toolkit.Uwp.UI.Media" + xmlns:i="using:Microsoft.Xaml.Interactivity" + xmlns:b="using:Microsoft.Xaml.Interactions.Core" + xmlns:tb="using:Microsoft.Toolkit.Uwp.UI.Behaviors" mc:Ignorable="d"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/TileControl/TileControlPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/TileControl/TileControlPage.xaml deleted file mode 100644 index 633ab8d8920..00000000000 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/TileControl/TileControlPage.xaml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/TileControl/TileControlPage.xaml.cs b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/TileControl/TileControlPage.xaml.cs deleted file mode 100644 index 91dc562f839..00000000000 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/TileControl/TileControlPage.xaml.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Microsoft.Toolkit.Uwp.SampleApp.Models; -using Windows.UI.Xaml.Navigation; - -namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages -{ - public sealed partial class TileControlPage - { - public TileControlPage() - { - InitializeComponent(); - } - } -} diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/XamlOnlyPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/XamlOnlyPage.xaml index 2a74f960039..6e627244084 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/XamlOnlyPage.xaml +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/XamlOnlyPage.xaml @@ -46,6 +46,7 @@ + @@ -60,12 +61,16 @@ + + + + diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json index 766ba4b922f..19cb315e2dc 100644 --- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json +++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json @@ -205,11 +205,10 @@ }, { "Name": "TileControl", - "Type": "TileControlPage", "Subcategory": "Layout", "About": "A ContentControl that show an image repeated many times.The control can be synchronized with a Scrollviewer and animated easily", "CodeUrl": "https://github.com/windows-toolkit/WindowsCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.UI.Controls.Core/TileControl", - "XamlCodeFile": "TileControl.bind", + "XamlCodeFile": "/SamplePages/TileControl/TileControl.bind", "Icon": "/SamplePages/TileControl/TileControl.png", "DocumentationUrl": "https://raw.githubusercontent.com/MicrosoftDocs/WindowsCommunityToolkitDocs/master/docs/controls/TileControl.md" }, diff --git a/Microsoft.Toolkit.Uwp.UI.Controls.Core/TileControl/TileControl.cs b/Microsoft.Toolkit.Uwp.UI.Controls.Core/TileControl/TileControl.cs index 20df3bf2c04..e593147d06f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Controls.Core/TileControl/TileControl.cs +++ b/Microsoft.Toolkit.Uwp.UI.Controls.Core/TileControl/TileControl.cs @@ -22,6 +22,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls /// A ContentControl that show an image repeated many times. /// The control can be synchronized with a ScrollViewer and animated easily. /// + [Obsolete("The TileControl will be removed in a future update. Please look at the TilesBrush for static backgrounds, animating a SurfaceBrushFactory element for a scrolling tiled background, or the ParallaxView element for background effects for a container being scrolled.")] public partial class TileControl : ContentControl { /// diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Animations/Abstract/EffectAnimation{TEffect,TValue,TKeyFrame}.cs b/Microsoft.Toolkit.Uwp.UI.Media/Animations/Abstract/EffectAnimation{TEffect,TValue,TKeyFrame}.cs index 7b9e3481129..9237b44d827 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Animations/Abstract/EffectAnimation{TEffect,TValue,TKeyFrame}.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Animations/Abstract/EffectAnimation{TEffect,TValue,TKeyFrame}.cs @@ -23,7 +23,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Animations /// /// The actual type of keyframe values in use. public abstract class EffectAnimation : Animation - where TEffect : class, IPipelineEffect + where TEffect : class, IBrushEffect where TKeyFrame : unmanaged { /// diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Animations/Brushes/AnchorPointBrushAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Media/Animations/Brushes/AnchorPointBrushAnimation.cs new file mode 100644 index 00000000000..33327563f63 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Animations/Brushes/AnchorPointBrushAnimation.cs @@ -0,0 +1,25 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Numerics; +using Microsoft.Toolkit.Uwp.UI.Media; +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// An anchor point animation working on a . + /// + public sealed class AnchorPointBrushAnimation : EffectAnimation + { + /// + protected override string ExplicitTarget => nameof(CompositionSurfaceBrush.AnchorPoint); + + /// + protected override (Vector2?, Vector2?) GetParsedValues() + { + return (To?.ToVector2(), From?.ToVector2()); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Animations/Brushes/CenterPointBrushAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Media/Animations/Brushes/CenterPointBrushAnimation.cs new file mode 100644 index 00000000000..7f586278526 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Animations/Brushes/CenterPointBrushAnimation.cs @@ -0,0 +1,25 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Numerics; +using Microsoft.Toolkit.Uwp.UI.Media; +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// A center point animation working on a . + /// + public sealed class CenterPointBrushAnimation : EffectAnimation + { + /// + protected override string ExplicitTarget => nameof(CompositionSurfaceBrush.CenterPoint); + + /// + protected override (Vector2?, Vector2?) GetParsedValues() + { + return (To?.ToVector2(), From?.ToVector2()); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Animations/Brushes/OffsetBrushAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Media/Animations/Brushes/OffsetBrushAnimation.cs new file mode 100644 index 00000000000..a3c23121810 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Animations/Brushes/OffsetBrushAnimation.cs @@ -0,0 +1,25 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Numerics; +using Microsoft.Toolkit.Uwp.UI.Media; +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// An offset animation working on a . + /// + public sealed class OffsetBrushAnimation : EffectAnimation + { + /// + protected override string ExplicitTarget => nameof(CompositionSurfaceBrush.Offset); + + /// + protected override (Vector2?, Vector2?) GetParsedValues() + { + return (To?.ToVector2(), From?.ToVector2()); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Animations/Brushes/RotationAngleInDegreesBrushAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Media/Animations/Brushes/RotationAngleInDegreesBrushAnimation.cs new file mode 100644 index 00000000000..484d1ffee14 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Animations/Brushes/RotationAngleInDegreesBrushAnimation.cs @@ -0,0 +1,24 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.Toolkit.Uwp.UI.Media; +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// A rotation animation working on a . + /// + public sealed class RotationAngleInDegreesBrushAnimation : EffectAnimation + { + /// + protected override string ExplicitTarget => nameof(CompositionSurfaceBrush.RotationAngleInDegrees); + + /// + protected override (double?, double?) GetParsedValues() + { + return (To, From); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Animations/Brushes/RotationBrushAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Media/Animations/Brushes/RotationBrushAnimation.cs new file mode 100644 index 00000000000..a2bbb9ba1e9 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Animations/Brushes/RotationBrushAnimation.cs @@ -0,0 +1,24 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.Toolkit.Uwp.UI.Media; +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// A rotation animation working on a . + /// + public sealed class RotationBrushAnimation : EffectAnimation + { + /// + protected override string ExplicitTarget => nameof(CompositionSurfaceBrush.RotationAngle); + + /// + protected override (double?, double?) GetParsedValues() + { + return (To, From); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Animations/Brushes/ScaleBrushAnimation.cs b/Microsoft.Toolkit.Uwp.UI.Media/Animations/Brushes/ScaleBrushAnimation.cs new file mode 100644 index 00000000000..156b7d5c67e --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Animations/Brushes/ScaleBrushAnimation.cs @@ -0,0 +1,25 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Numerics; +using Microsoft.Toolkit.Uwp.UI.Media; +using Windows.UI.Composition; + +namespace Microsoft.Toolkit.Uwp.UI.Animations +{ + /// + /// A scale animation working on a . + /// + public sealed class ScaleBrushAnimation : EffectAnimation + { + /// + protected override string ExplicitTarget => nameof(CompositionSurfaceBrush.Scale); + + /// + protected override (Vector2?, Vector2?) GetParsedValues() + { + return (To?.ToVector2(), From?.ToVector2()); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Effects/BorderEffect.cs b/Microsoft.Toolkit.Uwp.UI.Media/Effects/BorderEffect.cs new file mode 100644 index 00000000000..8fe851ed0bd --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Effects/BorderEffect.cs @@ -0,0 +1,35 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Microsoft.Graphics.Canvas; +using Microsoft.Toolkit.Uwp.UI.Media.Pipelines; + +#nullable enable + +namespace Microsoft.Toolkit.Uwp.UI.Media +{ + /// + /// A border effect useful for tiling a surface, it is not animatable directly, animate the incoming surface. + /// + /// This effect maps to the Win2D effect + public sealed class BorderEffect : PipelineEffect + { + /// + /// Gets or sets the wrapping behavior in the horizontal direction. + /// + public CanvasEdgeBehavior ExtendX { get; set; } = CanvasEdgeBehavior.Wrap; + + /// + /// Gets or sets the wrapping behavior in the vertical direction. + /// + public CanvasEdgeBehavior ExtendY { get; set; } = CanvasEdgeBehavior.Wrap; + + /// + public override PipelineBuilder AppendToBuilder(PipelineBuilder builder) + { + return builder.Border(ExtendX, ExtendY); + } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Effects/Interfaces/IBrushEffect.cs b/Microsoft.Toolkit.Uwp.UI.Media/Effects/Interfaces/IBrushEffect.cs new file mode 100644 index 00000000000..d84bd1dd876 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Effects/Interfaces/IBrushEffect.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.Toolkit.Uwp.UI.Media.Pipelines; +using Windows.UI.Composition; + +#nullable enable + +namespace Microsoft.Toolkit.Uwp.UI.Media +{ + /// + /// The base for all the builder effects to be used in a . + /// + public interface IBrushEffect + { + /// + /// Gets the current instance, if one is in use. + /// + CompositionBrush? Brush { get; } + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Effects/Interfaces/IPipelineEffect.cs b/Microsoft.Toolkit.Uwp.UI.Media/Effects/Interfaces/IPipelineEffect.cs index c4fa00040ed..7e81c3a1a3f 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Effects/Interfaces/IPipelineEffect.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Effects/Interfaces/IPipelineEffect.cs @@ -12,13 +12,8 @@ namespace Microsoft.Toolkit.Uwp.UI.Media /// /// The base for all the builder effects to be used in a . /// - public interface IPipelineEffect + public interface IPipelineEffect : IBrushEffect { - /// - /// Gets the current instance, if one is in use. - /// - CompositionBrush? Brush { get; } - /// /// Appends the current effect to the input instance. /// diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Pipelines/PipelineBuilder.Effects.cs b/Microsoft.Toolkit.Uwp.UI.Media/Pipelines/PipelineBuilder.Effects.cs index bc0980e6e35..0bf1911f064 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Pipelines/PipelineBuilder.Effects.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Pipelines/PipelineBuilder.Effects.cs @@ -7,10 +7,12 @@ using System.Diagnostics.Contracts; using System.Linq; using System.Threading.Tasks; +using Microsoft.Graphics.Canvas; using Microsoft.Graphics.Canvas.Effects; using Windows.Graphics.Effects; using Windows.UI; using Windows.UI.Composition; +using CanvasBorderEffect = Microsoft.Graphics.Canvas.Effects.BorderEffect; using CanvasExposureEffect = Microsoft.Graphics.Canvas.Effects.ExposureEffect; using CanvasGrayscaleEffect = Microsoft.Graphics.Canvas.Effects.GrayscaleEffect; using CanvasHueRotationEffect = Microsoft.Graphics.Canvas.Effects.HueRotationEffect; @@ -104,6 +106,25 @@ public PipelineBuilder Blur(float blur, out EffectAnimation animation, Ef return new PipelineBuilder(this, Factory, new[] { $"{id}.{nameof(GaussianBlurEffect.BlurAmount)}" }); } + /// + /// Adds a new to the current pipeline + /// + /// The in the horizontal direction + /// The in the vertical direction + /// A new instance to use to keep adding new effects + [Pure] + public PipelineBuilder Border(CanvasEdgeBehavior extendX, CanvasEdgeBehavior extendY) + { + async ValueTask Factory() => new CanvasBorderEffect + { + ExtendX = extendX, + ExtendY = extendY, + Source = await this.sourceProducer() + }; + + return new PipelineBuilder(this, Factory); + } + /// /// Adds a new to the current pipeline /// diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Pipelines/PipelineBuilder.Initialization.cs b/Microsoft.Toolkit.Uwp.UI.Media/Pipelines/PipelineBuilder.Initialization.cs index 92f3bb86f62..32a83bd4b45 100644 --- a/Microsoft.Toolkit.Uwp.UI.Media/Pipelines/PipelineBuilder.Initialization.cs +++ b/Microsoft.Toolkit.Uwp.UI.Media/Pipelines/PipelineBuilder.Initialization.cs @@ -15,6 +15,7 @@ using Windows.UI.Composition; using Windows.UI.Xaml; using Windows.UI.Xaml.Hosting; +using CanvasBorderEffect = Microsoft.Graphics.Canvas.Effects.BorderEffect; namespace Microsoft.Toolkit.Uwp.UI.Media.Pipelines { @@ -298,7 +299,7 @@ public static PipelineBuilder FromTiles(Uri uri, DpiMode dpiMode = DpiMode.Displ { var image = FromImage(uri, dpiMode, cacheMode); - async ValueTask Factory() => new BorderEffect + async ValueTask Factory() => new CanvasBorderEffect { ExtendX = CanvasEdgeBehavior.Wrap, ExtendY = CanvasEdgeBehavior.Wrap, diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Visuals/SurfaceBrushFactory.BrushProperties.cs b/Microsoft.Toolkit.Uwp.UI.Media/Visuals/SurfaceBrushFactory.BrushProperties.cs new file mode 100644 index 00000000000..0ae8f141a95 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Visuals/SurfaceBrushFactory.BrushProperties.cs @@ -0,0 +1,132 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Numerics; +using System.Threading.Tasks; +using Microsoft.Toolkit.Uwp.UI.Media.Pipelines; +using Windows.Foundation; +using Windows.UI.Composition; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Markup; +using Windows.UI.Xaml.Media; + +namespace Microsoft.Toolkit.Uwp.UI.Media +{ + /// + /// Contains the properties for passthrue to the . + /// + public sealed partial class SurfaceBrushFactory + { + /// + /// Gets or sets the property of the underlying . + /// + public Point AnchorPoint + { + get => _brush.AnchorPoint.ToPoint(); + set => _brush.AnchorPoint = value.ToVector2(); + } + + /// + /// Gets or sets the property of the underlying . + /// + public CompositionBitmapInterpolationMode BitmapInterpolationMode + { + get => _brush.BitmapInterpolationMode; + set => _brush.BitmapInterpolationMode = value; + } + + /// + /// Gets or sets the property of the underlying . + /// + public Point CenterPoint + { + get => _brush.CenterPoint.ToPoint(); + set => _brush.CenterPoint = value.ToVector2(); + } + + /// + /// Gets or sets the property of the underlying . + /// + public double HorizontalAlignmentRatio + { + get => _brush.HorizontalAlignmentRatio; + set => _brush.HorizontalAlignmentRatio = (float)Math.Clamp(value, 0.0f, 1.0f); + } + + /// + /// Gets or sets the property of the underlying . + /// + public Point Offset + { + get => _brush.Offset.ToPoint(); + set => _brush.Offset = value.ToVector2(); + } + + /// + /// Gets or sets the property of the underlying . + /// + public double RotationAngle + { + get => _brush.RotationAngle; + set => _brush.RotationAngle = (float)value; + } + + /// + /// Gets or sets the property of the underlying . + /// + public double RotationAngleInDegrees + { + get => _brush.RotationAngleInDegrees; + set => _brush.RotationAngleInDegrees = (float)value; + } + + /// + /// Gets or sets the property of the underlying . + /// + public Point Scale + { + get => _brush.Scale.ToPoint(); + set => _brush.Scale = value.ToVector2(); + } + + /// + /// Gets or sets a value indicating whether property of the underlying is set. + /// + public bool SnapToPixels + { + get => _brush.SnapToPixels; + set => _brush.SnapToPixels = value; + } + + /// + /// Gets or sets the property of the underlying . + /// + public CompositionStretch Stretch + { + get => _brush.Stretch; + set => _brush.Stretch = value; + } + + /// + /// Gets or sets the property of the underlying . + /// + public Matrix3x2 TransformMatrix + { + get => _brush.TransformMatrix; + set => _brush.TransformMatrix = value; + } + + /// + /// Gets or sets the property of the underlying . + /// + public double VerticalAlignmentRatio + { + get => _brush.VerticalAlignmentRatio; + set => _brush.VerticalAlignmentRatio = (float)Math.Clamp(value, 0.0f, 1.0f); + } + + } +} diff --git a/Microsoft.Toolkit.Uwp.UI.Media/Visuals/SurfaceBrushFactory.cs b/Microsoft.Toolkit.Uwp.UI.Media/Visuals/SurfaceBrushFactory.cs new file mode 100644 index 00000000000..f1f0381bad2 --- /dev/null +++ b/Microsoft.Toolkit.Uwp.UI.Media/Visuals/SurfaceBrushFactory.cs @@ -0,0 +1,109 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.Toolkit.Uwp.UI.Media.Pipelines; +using Windows.UI.Composition; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Markup; +using Windows.UI.Xaml.Media; + +namespace Microsoft.Toolkit.Uwp.UI.Media +{ + /// + /// A builder type for a to apply to the visual of UI elements. + /// + [ContentProperty(Name = nameof(Effects))] + public sealed partial class SurfaceBrushFactory : PipelineVisualFactoryBase, IBrushEffect + { + private CompositionSurfaceBrush _brush; + + /// + public CompositionBrush Brush => _brush; + + private Uri _uri; + + /// + /// Gets or sets the source of an image to use to start the Pipeline. + /// + public Uri Source + { + get + { + return _uri; + } + + set + { + _uri = value; + + if (_uri != null) + { + //// TODO: I think we want a few different options, like make this a provider and have another one to take the Win2D Path somehow maybe? + _brush = Window.Current.Compositor.CreateSurfaceBrush(LoadedImageSurface.StartLoadFromUri(_uri)); + } + else + { + _brush = null; + } + } + } + + /// + /// Gets or sets the collection of effects to use in the current pipeline. + /// + public IList Effects + { + get + { + if (GetValue(EffectsProperty) is not IList effects) + { + effects = new List(); + + SetValue(EffectsProperty, effects); + } + + return effects; + } + set => SetValue(EffectsProperty, value); + } + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty EffectsProperty = DependencyProperty.Register( + nameof(Effects), + typeof(IList), + typeof(PipelineVisualFactory), + new PropertyMetadata(null)); + + /// + public override async ValueTask GetAttachedVisualAsync(UIElement element) + { + var visual = (SpriteVisual)await base.GetAttachedVisualAsync(element); + + foreach (IPipelineEffect effect in Effects) + { + effect.NotifyCompositionBrushInUse(visual.Brush); + } + + return visual; + } + + /// + protected override PipelineBuilder OnPipelineRequested() + { + PipelineBuilder builder = PipelineBuilder.FromBrush(Brush); + + foreach (IPipelineEffect effect in Effects) + { + builder = effect.AppendToBuilder(builder); + } + + return builder; + } + } +}