Skip to content

Commit 71322fc

Browse files
Fix issues with XML documentation for new shadows feature
1 parent 614a6e4 commit 71322fc

File tree

8 files changed

+113
-213
lines changed

8 files changed

+113
-213
lines changed

Microsoft.Toolkit.Uwp.UI.Media/Shadows/AttachedCardShadow.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,18 @@
55
using System.Numerics;
66
using Microsoft.Graphics.Canvas.Geometry;
77
using Windows.Foundation;
8-
using Windows.Foundation.Metadata;
98
using Windows.UI;
109
using Windows.UI.Composition;
1110
using Windows.UI.Xaml;
1211

1312
namespace Microsoft.Toolkit.Uwp.UI.Media
1413
{
14+
/// <summary>
15+
/// A performant rectangular <see cref="DropShadow"/> which can be attached to any <see cref="FrameworkElement"/>. It uses Win2D to create a clipped area of the outline of the element such that transparent elements don't see the shadow below them, and the shadow can be attached without having to project to another surface. It is animatable, can be shared via a resource, and used in a <see cref="Style"/>.
16+
/// </summary>
17+
/// <remarks>
18+
/// This shadow will not work on <see cref="FrameworkElement"/> which is directly clipping to its bounds (e.g. a <see cref="Windows.UI.Xaml.Controls.Border"/> using a <see cref="Windows.UI.Xaml.Controls.Control.CornerRadius"/>). An extra <see cref="Windows.UI.Xaml.Controls.Border"/> can instead be applied around the clipped border with the Shadow to create the desired effect. Most existing controls due to how they're templated will not encounter this behavior or require this workaround.
19+
/// </remarks>
1520
public class AttachedCardShadow : AttachedShadowBase
1621
{
1722
private const float MaxBlurRadius = 72;
@@ -109,6 +114,12 @@ protected override CompositionBrush GetShadowMask(AttachedShadowElementContext c
109114
/// <inheritdoc/>
110115
protected override CompositionClip GetShadowClip(AttachedShadowElementContext context)
111116
{
117+
// The way this shadow works without the need to project on another element is because
118+
// we're clipping the inner part of the shadow which would be cast on the element
119+
// itself away. This method is creating an outline so that we are only showing the
120+
// parts of the shadow that are outside the element's context.
121+
// Note: This does cause an issue if the element does clip itself to its bounds, as then
122+
// the shadowed area is clipped as well.
112123
var pathGeom = context.GetResource(PathGeometryResourceKey) ??
113124
context.AddResource(PathGeometryResourceKey, context.Compositor.CreatePathGeometry());
114125
var clip = context.GetResource(ClipResourceKey) ?? context.AddResource(ClipResourceKey, context.Compositor.CreateGeometricClip(pathGeom));

Microsoft.Toolkit.Uwp.UI.Media/Shadows/AttachedShadowBaseWithOpacityMask.cs

Lines changed: 0 additions & 110 deletions
This file was deleted.

Microsoft.Toolkit.Uwp.UI/Shadows/AttachedDropShadow.cs

Lines changed: 10 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
15
using System;
26
using System.Collections.Generic;
37
using System.Linq;
@@ -27,12 +31,6 @@ public class AttachedDropShadow : AttachedShadowBase
2731
/// <inheritdoc/>
2832
protected internal override bool SupportsOnSizeChangedEvent => true;
2933

30-
private static readonly TypedResourceKey<ContainerVisual> ShadowContainerResourceKey = "ShadowContainer";
31-
32-
private static readonly TypedResourceKey<CompositionPathGeometry> PathGeometryResourceKey = "PathGeometry";
33-
private static readonly TypedResourceKey<CompositionRoundedRectangleGeometry> RectangleGeometryResourceKey = "RectGeometry";
34-
private static readonly TypedResourceKey<CompositionGeometricClip> ClipResourceKey = "Clip";
35-
3634
private static readonly TypedResourceKey<CompositionRoundedRectangleGeometry> RoundedRectangleGeometryResourceKey = "RoundedGeometry";
3735
private static readonly TypedResourceKey<CompositionSpriteShape> ShapeResourceKey = "Shape";
3836
private static readonly TypedResourceKey<ShapeVisual> ShapeVisualResourceKey = "ShapeVisual";
@@ -277,43 +275,6 @@ private void CustomMaskedElement_Loaded(object sender, RoutedEventArgs e)
277275
UpdateShadowMask(context);
278276
}
279277

280-
/// <inheritdoc/>
281-
/*protected override CompositionClip GetShadowClip(AttachedShadowElementContext context)
282-
{
283-
var rectGeom = context.GetResource(RectangleGeometryResourceKey) ??
284-
context.AddResource(RectangleGeometryResourceKey, context.Compositor.CreateRoundedRectangleGeometry());
285-
286-
rectGeom.Offset = Offset.ToVector2();
287-
rectGeom.Size = new Vector2((float)context.Element.ActualWidth, (float)context.Element.ActualHeight);
288-
rectGeom.CornerRadius = new Vector2((float)CornerRadius, (float)CornerRadius);
289-
290-
var clip = context.GetResource(ClipResourceKey) ?? context.AddResource(ClipResourceKey, context.Compositor.CreateGeometricClip(rectGeom));
291-
292-
return clip;*/
293-
294-
/*var pathGeom = context.GetResource(PathGeometryResourceKey) ??
295-
context.AddResource(PathGeometryResourceKey, context.Compositor.CreatePathGeometry());
296-
297-
// Create rounded rectangle geometry at a larger size that compensates for the size of the stroke,
298-
// as we want the inside edge of the stroke to match the edges of the element.
299-
// Additionally, the inside edge of the stroke will have a smaller radius than the radius we specified.
300-
// Using "(StrokeThickness / 2) + Radius" as our rectangle's radius will give us an inside stroke radius that matches the radius we want.
301-
var radius = (MaxBlurRadius / 2) + (float)CornerRadius;
302-
var canvasRectangle = context.Compositor.CreateRoundedRectangleGeometry();
303-
canvasRectangle.Offset = new Vector2(-MaxBlurRadius / 2, -MaxBlurRadius / 2);
304-
canvasRectangle.Size = new Vector2((float)context.Element.ActualWidth + MaxBlurRadius, (float)context.Element.ActualHeight + MaxBlurRadius);
305-
canvasRectangle.CornerRadius = new Vector2(radius, radius);
306-
307-
var rectangleShape = context.Compositor.CreateSpriteShape(canvasRectangle);
308-
rectangleShape.StrokeThickness = MaxBlurRadius;
309-
310-
var clip = context.GetResource(ClipResourceKey) ?? context.AddResource(ClipResourceKey, context.Compositor.CreateGeometricClip(rectangleShape.Geometry));
311-
312-
return clip;*/
313-
314-
//// return null;
315-
////}
316-
317278
/// <inheritdoc/>
318279
protected internal override void OnSizeChanged(AttachedShadowElementContext context, Size newSize, Size previousSize)
319280
{
@@ -336,13 +297,13 @@ protected override void OnPropertyChanged(AttachedShadowElementContext context,
336297
}
337298
else if (property == CornerRadiusProperty)
338299
{
339-
//var geometry = context.GetResource(RectangleGeometryResourceKey);
340-
//if (geometry != null)
341-
//{
342-
// geometry.CornerRadius = new Vector2((float)(double)newValue);
343-
//}
300+
var geometry = context.GetResource(RoundedRectangleGeometryResourceKey);
301+
if (geometry != null)
302+
{
303+
geometry.CornerRadius = new Vector2((float)(double)newValue);
304+
}
344305

345-
UpdateShadowClip(context);
306+
UpdateShadowMask(context);
346307
}
347308
else
348309
{

Microsoft.Toolkit.Uwp.UI/Shadows/AttachedShadowBase.cs

Lines changed: 17 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ namespace Microsoft.Toolkit.Uwp.UI
1717
/// <summary>
1818
/// The base class for attached shadows.
1919
/// </summary>
20-
public abstract class AttachedShadowBase : DependencyObject
20+
public abstract class AttachedShadowBase : DependencyObject, IAttachedShadow
2121
{
2222
/// <summary>
2323
/// Gets a value indicating whether or not Composition's VisualSurface is supported.
@@ -67,36 +67,28 @@ static AttachedShadowBase()
6767
/// </summary>
6868
private ConditionalWeakTable<FrameworkElement, AttachedShadowElementContext> ShadowElementContextTable { get; set; }
6969

70-
/// <summary>
71-
/// Gets or sets the blur radius of the shadow.
72-
/// </summary>
70+
/// <inheritdoc/>
7371
public double BlurRadius
7472
{
7573
get => (double)GetValue(BlurRadiusProperty);
7674
set => SetValue(BlurRadiusProperty, value);
7775
}
7876

79-
/// <summary>
80-
/// Gets or sets the opacity of the shadow.
81-
/// </summary>
77+
/// <inheritdoc/>
8278
public double Opacity
8379
{
8480
get => (double)GetValue(OpacityProperty);
8581
set => SetValue(OpacityProperty, value);
8682
}
8783

88-
/// <summary>
89-
/// Gets or sets the offset of the shadow as a string representation of a <see cref="Vector3"/>.
90-
/// </summary>
84+
/// <inheritdoc/>
9185
public string Offset
9286
{
9387
get => (string)GetValue(OffsetProperty);
9488
set => SetValue(OffsetProperty, value);
9589
}
9690

97-
/// <summary>
98-
/// Gets or sets the color of the shadow.
99-
/// </summary>
91+
/// <inheritdoc/>
10092
public Color Color
10193
{
10294
get => (Color)GetValue(ColorProperty);
@@ -108,6 +100,14 @@ public Color Color
108100
/// </summary>
109101
protected internal abstract bool SupportsOnSizeChangedEvent { get; }
110102

103+
/// <summary>
104+
/// Use this method as the <see cref="PropertyChangedCallback"/> for <see cref="DependencyProperty">DependencyProperties</see> in derived classes.
105+
/// </summary>
106+
protected static void OnDependencyPropertyChanged(object sender, DependencyPropertyChangedEventArgs args)
107+
{
108+
(sender as AttachedShadowBase)?.CallPropertyChangedForEachElement(args.Property, args.OldValue, args.NewValue);
109+
}
110+
111111
internal void ConnectElement(FrameworkElement element)
112112
{
113113
if (!IsSupported)
@@ -165,10 +165,7 @@ protected internal virtual void OnElementContextUninitialized(AttachedShadowElem
165165
ElementCompositionPreview.SetElementChildVisual(context.Element, null);
166166
}
167167

168-
/// <summary>
169-
/// Get the associated <see cref="AttachedShadowElementContext"/> for the specified <see cref="FrameworkElement"/>.
170-
/// </summary>
171-
/// <returns>The <see cref="AttachedShadowElementContext"/> for the element.</returns>
168+
/// <inheritdoc/>
172169
public AttachedShadowElementContext GetElementContext(FrameworkElement element)
173170
{
174171
if (ShadowElementContextTable != null && ShadowElementContextTable.TryGetValue(element, out var context))
@@ -179,10 +176,7 @@ public AttachedShadowElementContext GetElementContext(FrameworkElement element)
179176
return null;
180177
}
181178

182-
/// <summary>
183-
/// Gets an enumerator over the current list of <see cref="AttachedShadowElementContext"/> of elements using this shared shadow definition.
184-
/// </summary>
185-
/// <returns>Enumeration of <see cref="AttachedShadowElementContext"/> objects.</returns>
179+
/// <inheritdoc/>
186180
public IEnumerable<AttachedShadowElementContext> GetElementContextEnumerable()
187181
{
188182
foreach (var kvp in ShadowElementContextTable)
@@ -200,14 +194,6 @@ protected virtual void SetElementChildVisual(AttachedShadowElementContext contex
200194
ElementCompositionPreview.SetElementChildVisual(context.Element, context.SpriteVisual);
201195
}
202196

203-
/// <summary>
204-
/// Use this method as the <see cref="PropertyChangedCallback"/> for <see cref="DependencyProperty">DependencyProperties</see> in derived classes.
205-
/// </summary>
206-
protected static void OnDependencyPropertyChanged(object sender, DependencyPropertyChangedEventArgs args)
207-
{
208-
(sender as AttachedShadowBase)?.CallPropertyChangedForEachElement(args.Property, args.OldValue, args.NewValue);
209-
}
210-
211197
private void CallPropertyChangedForEachElement(DependencyProperty property, object oldValue, object newValue)
212198
{
213199
if (ShadowElementContextTable == null)
@@ -227,6 +213,7 @@ private void CallPropertyChangedForEachElement(DependencyProperty property, obje
227213
/// <summary>
228214
/// Get a <see cref="CompositionBrush"/> in the shape of the element that is casting the shadow.
229215
/// </summary>
216+
/// <returns>A <see cref="CompositionBrush"/> representing the shape of an element.</returns>
230217
protected virtual CompositionBrush GetShadowMask(AttachedShadowElementContext context)
231218
{
232219
return null;
@@ -235,6 +222,7 @@ protected virtual CompositionBrush GetShadowMask(AttachedShadowElementContext co
235222
/// <summary>
236223
/// Get the <see cref="CompositionClip"/> for the shadow's <see cref="SpriteVisual"/>
237224
/// </summary>
225+
/// <returns>A <see cref="CompositionClip"/> for the extent of the shadowed area.</returns>
238226
protected virtual CompositionClip GetShadowClip(AttachedShadowElementContext context)
239227
{
240228
return null;

0 commit comments

Comments
 (0)