Skip to content

Commit 5d5d86f

Browse files
author
msftbot[bot]
authored
Attached Shadows (Composition and Win2D + Animations) (#4179)
## Fixes #3122 #3607 #3516 _Also implements #3693 for the new DropShadow._ FYI @seanocali as this is a different implementation approach (which is simpler to use outside of the DropShadowPanel we've been working on) but should hopefully achieve the same result. This PR adds attached shadows which can easily be attached to any FrameworkElement without needing to modify the layout like DropShadowPanel does today. They can also be shared using a resource, added to the style of an element, and animated! All the things! 🎉 ## PR Type What kind of change does this PR introduce? <!-- Please uncomment one or more options below that apply to this PR. --> <!-- - Bugfix --> - Feature by @Ryken100 and integrated/extended by @michael-hawker <!-- - Code style update (formatting) --> <!-- - Refactoring (no functional changes, no api changes) --> <!-- - Build or CI related changes --> <!-- - Documentation content changes --> <!-- - Sample app changes --> <!-- - Other... Please describe: --> ## What is the current behavior? DropShadowPanel is clunky and requires modifying how you layout your app. ## What is the new behavior? Just attach a shadow and be done! (DropShadowPanel is deprecated.) ## PR Checklist - [x] Composition Only Shadow Support? (with Target) - [x] Add XML Docs - [x] Animation Support to Explicit Animation System? - [x] Bug can't use `AttachedCardShadow` directly with `Border`? Please check if your PR fulfills the following requirements: <!-- and remove the ones that are not applicable to the current PR --> - [ ] Tested code with current [supported SDKs](../#supported) - [ ] Pull Request has been submitted to the documentation repository [instructions](../blob/main/Contributing.md#docs). Link: <!-- docs PR link --> - [ ] Sample in sample app has been added / updated (for bug fixes / features) - [ ] Icon has been created (if new sample) following the [Thumbnail Style Guide and templates](https://github.com/CommunityToolkit/WindowsCommunityToolkit-design-assets) - [ ] New major technical changes in the toolkit have or will be added to the [Wiki](https://github.com/CommunityToolkit/WindowsCommunityToolkit/wiki) e.g. build changes, source generators, testing infrastructure, sample creation changes, etc... - [ ] Tests for the changes have been added (for bug fixes / features) (if applicable) - [ ] Header has been added to all new source files (run _build/UpdateHeaders.bat_) - [ ] Contains **NO** breaking changes <!-- If this PR contains a breaking change, please describe the impact and migration path for existing applications below. Please note that breaking changes are likely to be rejected within minor release cycles or held until major versions. --> ## Other information <!-- Please add any other information that might be helpful to reviewers. -->
2 parents fe9ac89 + e418928 commit 5d5d86f

File tree

45 files changed

+2083
-129
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+2083
-129
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
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+
5+
using System;
6+
using System.Linq;
7+
using System.Numerics;
8+
using Windows.UI.Xaml;
9+
using Windows.UI.Xaml.Data;
10+
11+
namespace Microsoft.Toolkit.Uwp.SampleApp.Common
12+
{
13+
public class Vector3Converter : IValueConverter
14+
{
15+
public object Convert(object value, Type targetType, object parameter, string language)
16+
{
17+
if (value is string)
18+
{
19+
return value;
20+
}
21+
22+
var thickness = (Vector3)value;
23+
24+
return thickness.ToString().TrimStart('<').Replace(" ", string.Empty).TrimEnd('>');
25+
}
26+
27+
public object ConvertBack(object value, Type targetType, object parameter, string language)
28+
{
29+
if (value is string vectorString)
30+
{
31+
var vectorTokens = vectorString.Split(',')
32+
.Where(tkn => !string.IsNullOrWhiteSpace(tkn))
33+
.ToArray();
34+
switch (vectorTokens.Length)
35+
{
36+
case 1:
37+
var vectorValue = float.Parse(vectorString);
38+
return new Vector3(vectorValue);
39+
case 2:
40+
var xValue = float.Parse(vectorTokens[0]);
41+
var yValue = float.Parse(vectorTokens[1]);
42+
43+
return new Vector3(xValue, yValue, 0);
44+
case 3:
45+
return new Vector3(
46+
float.Parse(vectorTokens[0]),
47+
float.Parse(vectorTokens[1]),
48+
float.Parse(vectorTokens[2]));
49+
default:
50+
return default(Vector3);
51+
}
52+
}
53+
54+
return value.ToString();
55+
}
56+
}
57+
}

Microsoft.Toolkit.Uwp.SampleApp/Controls/PropertyControl.xaml.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,14 @@ private void PropertyControl_OnDataContextChanged(FrameworkElement sender, DataC
179179
converter = new ThicknessConverter();
180180
break;
181181

182+
case PropertyKind.Vector3:
183+
var vectorTextBox = new TextBox { Text = (propertyDict[option.Name] as ValueHolder).Value.ToString() };
184+
185+
controlToAdd = vectorTextBox;
186+
dependencyProperty = TextBox.TextProperty;
187+
converter = new Vector3Converter();
188+
break;
189+
182190
default:
183191
var textBox = new TextBox { Text = (propertyDict[option.Name] as ValueHolder).Value.ToString() };
184192

Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -316,10 +316,10 @@
316316
<Content Include="SamplePages\FocusTracker\FocusTracker.png" />
317317
<Content Include="SamplePages\BladeView\BladeView.png" />
318318
<Content Include="SamplePages\Carousel\Carousel.png" />
319-
<Content Include="SamplePages\DropShadowPanel\DropShadowPanel.png" />
319+
<Content Include="SamplePages\Shadows\DropShadowPanel.png" />
320320
<Content Include="SamplePages\Expander\Expander.png" />
321-
<Content Include="SamplePages\DropShadowPanel\Trex.png" />
322-
<Content Include="SamplePages\DropShadowPanel\Unicorn.png" />
321+
<Content Include="SamplePages\Shadows\Trex.png" />
322+
<Content Include="SamplePages\Shadows\Unicorn.png" />
323323
<Content Include="SamplePages\GazeInteraction\GazeInteraction.png" />
324324
<Content Include="SamplePages\GazeTracing\GazeTracing.png" />
325325
<Content Include="SamplePages\GridSplitter\GridSplitter.png" />
@@ -398,7 +398,7 @@
398398
<Content Include="SamplePages\ImageCache\ImageCacheXaml.bind" />
399399
<Content Include="SamplePages\Incremental Loading Collection\IncrementalLoadingCollectionCode.bind" />
400400
<Content Include="SamplePages\ImageCache\ImageCacheCode.bind" />
401-
<Content Include="SamplePages\DropShadowPanel\DropShadowPanelXaml.bind" />
401+
<Content Include="SamplePages\Shadows\DropShadowPanelXaml.bind" />
402402
<Content Include="SamplePages\Object Storage\ObjectStorageCode.bind" />
403403
<Content Include="SamplePages\BackgroundTaskHelper\BackgroundTaskHelperCode.bind" />
404404
<Content Include="SamplePages\ListDetailsView\ListDetailsView.bind" />
@@ -489,6 +489,7 @@
489489
<Content Include="SamplePages\DataGrid\DataGridCode.bind" />
490490
<Content Include="SamplePages\ViewportBehavior\ViewportBehaviorCode.bind" />
491491
<Compile Include="Common\TextBlockHyperlinkBehavior.cs" />
492+
<Compile Include="Common\Vector3Converter.cs" />
492493
<Compile Include="SamplePages\AutoFocusBehavior\AutoFocusBehaviorPage.xaml.cs">
493494
<DependentUpon>AutoFocusBehaviorPage.xaml</DependentUpon>
494495
</Compile>
@@ -507,6 +508,9 @@
507508
<Compile Include="SamplePages\MetadataControl\MetadataControlPage.xaml.cs">
508509
<DependentUpon>MetadataControlPage.xaml</DependentUpon>
509510
</Compile>
511+
<Compile Include="SamplePages\Shadows\AttachedDropShadowPage.xaml.cs">
512+
<DependentUpon>AttachedDropShadowPage.xaml</DependentUpon>
513+
</Compile>
510514
<Compile Include="SamplePages\RichSuggestBox\RichSuggestBoxPage.xaml.cs">
511515
<DependentUpon>RichSuggestBoxPage.xaml</DependentUpon>
512516
</Compile>
@@ -631,6 +635,9 @@
631635
<Content Include="SamplePages\Primitives\ConstrainedBox.bind">
632636
<SubType>Designer</SubType>
633637
</Content>
638+
<Content Include="SamplePages\Shadows\AttachedShadowWin2DXaml.bind" />
639+
<Content Include="SamplePages\Shadows\AttachedShadowCompositionXaml.bind" />
640+
<Content Include="SamplePages\Animations\Shadows\AnimatedCardShadowXaml.bind" />
634641
<Content Include="SamplePages\KeyDownTriggerBehavior\KeyDownTriggerBehaviorXaml.bind" />
635642
<Content Include="SamplePages\RichSuggestBox\RichSuggestBoxCode.bind" />
636643
</ItemGroup>
@@ -669,7 +676,6 @@
669676
<Compile Include="SamplePages\UniformGrid\UniformGridPage.xaml.cs">
670677
<DependentUpon>UniformGridPage.xaml</DependentUpon>
671678
</Compile>
672-
<Compile Include="Models\PropertyDescriptor\ThicknessPropertyOptions.cs" />
673679
<Compile Include="Models\ThemeChangedArgs.cs" />
674680
<Compile Include="Pages\SampleController.xaml.cs">
675681
<DependentUpon>SampleController.xaml</DependentUpon>
@@ -815,9 +821,6 @@
815821
<Compile Include="SamplePages\DispatcherQueueHelper\DispatcherQueueHelperPage.xaml.cs">
816822
<DependentUpon>DispatcherQueueHelperPage.xaml</DependentUpon>
817823
</Compile>
818-
<Compile Include="SamplePages\DropShadowPanel\DropShadowPanelPage.xaml.cs">
819-
<DependentUpon>DropShadowPanelPage.xaml</DependentUpon>
820-
</Compile>
821824
<Compile Include="SamplePages\Expander\ExpanderPage.xaml.cs">
822825
<DependentUpon>ExpanderPage.xaml</DependentUpon>
823826
</Compile>
@@ -992,6 +995,10 @@
992995
<Content Include="SamplePages\Primitives\SwitchPresenter.bind">
993996
<SubType>Designer</SubType>
994997
</Content>
998+
<Page Include="SamplePages\Shadows\AttachedDropShadowPage.xaml">
999+
<Generator>MSBuild:Compile</Generator>
1000+
<SubType>Designer</SubType>
1001+
</Page>
9951002
<Content Include="SamplePages\RichSuggestBox\RichSuggestBoxXaml.bind">
9961003
<SubType>Designer</SubType>
9971004
<Generator>MSBuild:Compile</Generator>
@@ -1287,10 +1294,6 @@
12871294
<Generator>MSBuild:Compile</Generator>
12881295
<SubType>Designer</SubType>
12891296
</Page>
1290-
<Page Include="SamplePages\DropShadowPanel\DropShadowPanelPage.xaml">
1291-
<SubType>Designer</SubType>
1292-
<Generator>MSBuild:Compile</Generator>
1293-
</Page>
12941297
<Page Include="SamplePages\GridSplitter\GridSplitterPage.xaml">
12951298
<SubType>Designer</SubType>
12961299
<Generator>MSBuild:Compile</Generator>
@@ -1559,4 +1562,4 @@
15591562
</Target>
15601563
<!-- No-op to avoid build error when packing solution from commandline -->
15611564
<Target Name="Pack" />
1562-
</Project>
1565+
</Project>

Microsoft.Toolkit.Uwp.SampleApp/Models/PropertyDescriptor/PropertyKind.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public enum PropertyKind
1313
Bool,
1414
Brush,
1515
TimeSpan,
16-
Thickness
16+
Thickness,
17+
Vector3,
1718
}
1819
}

Microsoft.Toolkit.Uwp.SampleApp/Models/Sample.cs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -418,8 +418,12 @@ public string UpdatedXamlCode
418418
{
419419
if (proxy[option.Name] is ValueHolder value)
420420
{
421-
var newString = value.Value is Windows.UI.Xaml.Media.SolidColorBrush brush ?
422-
brush.Color.ToString() : value.Value.ToString();
421+
var newString = value.Value switch
422+
{
423+
Windows.UI.Xaml.Media.SolidColorBrush brush => brush.Color.ToString(),
424+
System.Numerics.Vector3 vector => vector.ToString().TrimStart('<').Replace(" ", string.Empty).TrimEnd('>'),
425+
_ => value.Value.ToString()
426+
};
423427

424428
result = result.Replace(option.OriginalString, newString);
425429
result = result.Replace("@[" + option.Label + "]@", newString);
@@ -630,12 +634,27 @@ public async Task PreparePropertyDescriptorAsync()
630634
case PropertyKind.Thickness:
631635
try
632636
{
633-
var thicknessOptions = new ThicknessPropertyOptions { DefaultValue = value };
637+
var thicknessOptions = new PropertyOptions { DefaultValue = value };
634638
options = thicknessOptions;
635639
}
636640
catch (Exception ex)
637641
{
638-
Debug.WriteLine($"Unable to extract slider info from {value}({ex.Message})");
642+
Debug.WriteLine($"Unable to extract thickness info from {value}({ex.Message})");
643+
TrackingManager.TrackException(ex);
644+
continue;
645+
}
646+
647+
break;
648+
649+
case PropertyKind.Vector3:
650+
try
651+
{
652+
var vector3Options = new PropertyOptions { DefaultValue = value };
653+
options = vector3Options;
654+
}
655+
catch (Exception ex)
656+
{
657+
Debug.WriteLine($"Unable to extract vector3 info from {value}({ex.Message})");
639658
TrackingManager.TrackException(ex);
640659
continue;
641660
}

Microsoft.Toolkit.Uwp.SampleApp/Models/Samples.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ public static async Task<List<SampleCategory>> GetCategoriesAsync()
6060
{
6161
allCategories = await JsonSerializer.DeserializeAsync<List<SampleCategory>>(jsonStream.AsStream(), new JsonSerializerOptions
6262
{
63-
ReadCommentHandling = JsonCommentHandling.Skip
63+
ReadCommentHandling = JsonCommentHandling.Skip,
64+
AllowTrailingCommas = true,
6465
});
6566
}
6667

Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Animations/Effects/FadeBehaviorXaml.bind

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
xmlns:interactions="using:Microsoft.Xaml.Interactions.Core"
88
xmlns:ani="using:Microsoft.Toolkit.Uwp.UI.Animations"
99
xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Behaviors"
10-
xmlns:core="using:Microsoft.Xaml.Interactions.Core"
1110
mc:Ignorable="d">
1211

1312
<Button Background="Gray" Width="200" Height="200" HorizontalAlignment="Center" VerticalAlignment="Center">
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<Page
2+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
6+
xmlns:ui="using:Microsoft.Toolkit.Uwp.UI"
7+
xmlns:media="using:Microsoft.Toolkit.Uwp.UI.Media"
8+
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
9+
xmlns:interactions="using:Microsoft.Xaml.Interactions.Core"
10+
xmlns:ani="using:Microsoft.Toolkit.Uwp.UI.Animations"
11+
xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Behaviors"
12+
mc:Ignorable="d">
13+
14+
<Page.Resources>
15+
<media:AttachedCardShadow x:Key="CommonShadow" Offset="4" CornerRadius="0"/>
16+
17+
<ani:AnimationSet x:Key="ShadowEnterAnimation">
18+
<ani:OffsetDropShadowAnimation To="12"/>
19+
</ani:AnimationSet>
20+
21+
<ani:AnimationSet x:Key="ShadowExitAnimation">
22+
<ani:OffsetDropShadowAnimation To="4"/>
23+
</ani:AnimationSet>
24+
25+
<ani:AnimationSet x:Key="ShadowPopAnimation" IsSequential="True">
26+
<ani:TranslationAnimation To="-8" Duration="0:0:1"/>
27+
<ani:OffsetDropShadowAnimation To="16" Duration="0:0:2" Target="{StaticResource CommonShadow}"/>
28+
<ani:OffsetDropShadowAnimation To="4" Delay="0:0:0.5" Duration="0:0:2" Target="{StaticResource CommonShadow}"/>
29+
<ani:TranslationAnimation To="0" Duration="0:0:1"/>
30+
</ani:AnimationSet>
31+
</Page.Resources>
32+
33+
<Grid>
34+
<Grid.RowDefinitions>
35+
<RowDefinition/>
36+
<RowDefinition/>
37+
</Grid.RowDefinitions>
38+
<Grid.ColumnDefinitions>
39+
<ColumnDefinition/>
40+
<ColumnDefinition/>
41+
</Grid.ColumnDefinitions>
42+
<Image ui:Effects.Shadow="{StaticResource CommonShadow}"
43+
Height="100" Width="100"
44+
Source="ms-appx:///Assets/Photos/Owl.jpg">
45+
<interactivity:Interaction.Behaviors>
46+
<interactions:EventTriggerBehavior EventName="PointerEntered">
47+
<behaviors:StartAnimationAction Animation="{StaticResource ShadowEnterAnimation}"/>
48+
</interactions:EventTriggerBehavior>
49+
<interactions:EventTriggerBehavior EventName="PointerExited">
50+
<behaviors:StartAnimationAction Animation="{StaticResource ShadowExitAnimation}"/>
51+
</interactions:EventTriggerBehavior>
52+
</interactivity:Interaction.Behaviors>
53+
</Image>
54+
<Image ui:Effects.Shadow="{StaticResource CommonShadow}"
55+
Height="100" Width="100"
56+
Grid.Column="1"
57+
Source="ms-appx:///Assets/Photos/Owl.jpg">
58+
<interactivity:Interaction.Behaviors>
59+
<interactions:EventTriggerBehavior EventName="PointerEntered">
60+
<behaviors:StartAnimationAction Animation="{StaticResource ShadowEnterAnimation}"/>
61+
</interactions:EventTriggerBehavior>
62+
<interactions:EventTriggerBehavior EventName="PointerExited">
63+
<behaviors:StartAnimationAction Animation="{StaticResource ShadowExitAnimation}"/>
64+
</interactions:EventTriggerBehavior>
65+
</interactivity:Interaction.Behaviors>
66+
</Image>
67+
<Button Grid.Row="1" Grid.ColumnSpan="2" HorizontalAlignment="Center" VerticalAlignment="Top" Content="Click Me">
68+
<interactivity:Interaction.Behaviors>
69+
<interactions:EventTriggerBehavior EventName="Click">
70+
<behaviors:StartAnimationAction Animation="{StaticResource ShadowPopAnimation}"/>
71+
</interactions:EventTriggerBehavior>
72+
</interactivity:Interaction.Behaviors>
73+
</Button>
74+
</Grid>
75+
</Page>

Microsoft.Toolkit.Uwp.SampleApp/SamplePages/DropShadowPanel/DropShadowPanelPage.xaml

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

Microsoft.Toolkit.Uwp.SampleApp/SamplePages/DropShadowPanel/DropShadowPanelPage.xaml.cs

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

0 commit comments

Comments
 (0)