Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Experiment] Initial CompositionCollectionView implementation and basic samples #277

Open
wants to merge 54 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
d1b9aa1
CompositionCollectionView port and basic sample
arcadiogarcia Jul 7, 2022
8a959a9
Samples
arcadiogarcia Jul 8, 2022
7cfe44d
Maze WIP
arcadiogarcia Sep 5, 2022
6e9dcb6
Merge branch 'main' of https://github.com/CommunityToolkit/Labs-Windo…
arcadiogarcia Sep 5, 2022
61be6d3
CCV project
arcadiogarcia Sep 5, 2022
028c635
Merge branch 'feature/compositionCollectionView' into feature/composi…
arcadiogarcia Sep 6, 2022
11a1a43
Fix maze layout
arcadiogarcia Sep 6, 2022
d9b54e3
Sample text
arcadiogarcia Sep 8, 2022
c63d0a4
Generic model
arcadiogarcia Sep 12, 2022
7ebb3aa
Cleanup
arcadiogarcia Sep 12, 2022
27c94d4
Restore file from master
arcadiogarcia Sep 12, 2022
1304e6c
Disable code for non-UWP targets
arcadiogarcia Sep 19, 2022
252b5be
Adjust colors
arcadiogarcia Sep 19, 2022
efb3d1f
Fix z index
arcadiogarcia Sep 19, 2022
7df0634
Fix xaml styling
arcadiogarcia Sep 19, 2022
0dbd25e
Address PR feedback
arcadiogarcia Sep 22, 2022
218ee1c
Break down layout file
arcadiogarcia Sep 22, 2022
885cf60
Report last state of interaction trackers + fix animatable nodes repo…
arcadiogarcia Oct 27, 2022
cd5c508
WIP
arcadiogarcia Oct 27, 2022
b3ddd06
Fix sample
arcadiogarcia Oct 27, 2022
86406e6
Increase version
arcadiogarcia Oct 27, 2022
39d744e
Remove IsUserInteracting property
arcadiogarcia Oct 28, 2022
7c1774a
WIp
arcadiogarcia Oct 30, 2022
fa5cc2b
Fix transition bug
arcadiogarcia Nov 1, 2022
d55fb2b
Run xaml styler
arcadiogarcia Nov 1, 2022
437667a
Cleanup element when deleted
arcadiogarcia Nov 3, 2022
cdd5aff
Expose composer value in animatable nodes
arcadiogarcia Nov 4, 2022
3846011
Configure each of the sub ITBs in ElementInteractionTrackerBehavior
arcadiogarcia Nov 8, 2022
bb0ef5d
Address Dispose warning
arcadiogarcia Nov 9, 2022
0de0f1e
Merge branch 'main' of https://github.com/CommunityToolkit/Labs-Windo…
arcadiogarcia Nov 9, 2022
5f7a680
Ignore "not implemented in Uno" warnings
arcadiogarcia Nov 9, 2022
c0826a3
Add missing Scale reference to Evaluate
arcadiogarcia Nov 11, 2022
bf1d7e6
Make add/removebehavior methods public
arcadiogarcia Nov 14, 2022
78bd506
Improve Evaluate not implemented error messages and implement Length()
arcadiogarcia Nov 18, 2022
75661bc
Merge branch 'main' into feature/compositionCollectionView2
Arlodotexe Dec 8, 2022
635fb6d
Updated with project changes from #327
Arlodotexe Dec 8, 2022
e8720e2
Merge branch 'main' into feature/compositionCollectionView2
Arlodotexe Dec 21, 2022
5f128fb
Updated with project changes from #330
Arlodotexe Dec 21, 2022
8d28c32
Added missing discussion-id and issue-id to front matter
Arlodotexe Dec 21, 2022
d582d29
Merge branch 'main' into feature/compositionCollectionView2
Arlodotexe Feb 23, 2023
840e331
Migrating to new component folder layout
Arlodotexe Feb 23, 2023
b194ba7
Merge branch 'main' into feature/compositionCollectionView2
Arlodotexe Feb 24, 2023
9aae744
Fixed compilation errors for tests
Arlodotexe Feb 24, 2023
c06af8c
Fixed compilation errors
Arlodotexe Feb 24, 2023
05c6051
Merged with local changes
arcadiogarcia Mar 10, 2023
790fdd0
Remove extra shared project
arcadiogarcia Mar 10, 2023
8bac431
Fix lerp implementation & compile error
arcadiogarcia Mar 10, 2023
5421485
Merge branch 'main' into feature/compositionCollectionView2
Arlodotexe Mar 11, 2023
fdc41d6
Merge fix
Arlodotexe Mar 11, 2023
9c2a469
Address feedback
arcadiogarcia Mar 11, 2023
6a0b6c0
Fix styling
arcadiogarcia Mar 11, 2023
4024c1a
Merge branch 'main' into feature/compositionCollectionView2
Arlodotexe Mar 13, 2023
5929330
Add missing globalusing
Arlodotexe Mar 13, 2023
6f978ed
Update components/CompositionCollectionView/samples/CanvasSample.cs
Arlodotexe May 27, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
310 changes: 310 additions & 0 deletions labs/CompositionCollectionView/CompositionCollectionView.sln

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,308 @@
// 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 Windows.UI.Composition;
using Windows.UI.Composition.Interactions;

namespace Microsoft.Toolkit.Uwp.UI.Animations.ExpressionsFork
{
/// <summary>
/// Class CompositionExtensions.
/// </summary>
public static class CompositionExtensions
{
/// <summary>
/// Create an ExpressionNode reference to this CompositionObject.
/// </summary>
/// <param name="compObj">The comp object.</param>
/// <returns>AmbientLightReferenceNode.</returns>
public static AmbientLightReferenceNode GetReference(this AmbientLight compObj)
{
return new AmbientLightReferenceNode(null, compObj);
}

/// <summary>
/// Create an ExpressionNode reference to this CompositionObject.
/// </summary>
/// <param name="compObj">The comp object.</param>
/// <returns>ColorBrushReferenceNode.</returns>
public static ColorBrushReferenceNode GetReference(this CompositionColorBrush compObj)
{
return new ColorBrushReferenceNode(null, compObj);
}

/// <summary>
/// Create an ExpressionNode reference to this CompositionObject.
/// </summary>
/// <param name="compObj">The comp object.</param>
/// <returns>DistantLightReferenceNode.</returns>
public static DistantLightReferenceNode GetReference(this DistantLight compObj)
{
return new DistantLightReferenceNode(null, compObj);
}

/// <summary>
/// Create an ExpressionNode reference to this CompositionObject.
/// </summary>
/// <param name="compObj">The comp object.</param>
/// <returns>DropShadowReferenceNode.</returns>
public static DropShadowReferenceNode GetReference(this DropShadow compObj)
{
return new DropShadowReferenceNode(null, compObj);
}

/// <summary>
/// Create an ExpressionNode reference to this CompositionObject.
/// </summary>
/// <param name="compObj">The comp object.</param>
/// <returns>InsetClipReferenceNode.</returns>
public static InsetClipReferenceNode GetReference(this InsetClip compObj)
{
return new InsetClipReferenceNode(null, compObj);
}

/// <summary>
/// Create an ExpressionNode reference to this CompositionObject.
/// </summary>
/// <param name="compObj">The comp object.</param>
/// <returns>InteractionTrackerReferenceNode.</returns>
public static InteractionTrackerReferenceNode GetReference(this InteractionTracker compObj)
{
return new InteractionTrackerReferenceNode(null, compObj);
}

/// <summary>
/// Create an ExpressionNode reference to this CompositionObject.
/// </summary>
/// <param name="compObj">The comp object.</param>
/// <returns>NineGridBrushReferenceNode.</returns>
public static NineGridBrushReferenceNode GetReference(this CompositionNineGridBrush compObj)
{
return new NineGridBrushReferenceNode(null, compObj);
}

/// <summary>
/// Create an ExpressionNode reference to this CompositionObject.
/// </summary>
/// <param name="compObj">The comp object.</param>
/// <returns>PointLightReferenceNode.</returns>
public static PointLightReferenceNode GetReference(this PointLight compObj)
{
return new PointLightReferenceNode(null, compObj);
}

/// <summary>
/// Create an ExpressionNode reference to this CompositionObject.
/// </summary>
/// <param name="compObj">The comp object.</param>
/// <returns>PropertySetReferenceNode.</returns>
public static PropertySetReferenceNode GetReference(this CompositionPropertySet compObj)
{
return new PropertySetReferenceNode(null, compObj);
}

/// <summary>
/// Create an ExpressionNode reference to this CompositionObject.
/// </summary>
/// <param name="compObj">The comp object.</param>
/// <returns>SpotLightReferenceNode.</returns>
public static SpotLightReferenceNode GetReference(this SpotLight compObj)
{
return new SpotLightReferenceNode(null, compObj);
}

/// <summary>
/// Create an ExpressionNode reference to this CompositionObject.
/// </summary>
/// <param name="compObj">The comp object.</param>
/// <returns>SurfaceBrushReferenceNode.</returns>
public static SurfaceBrushReferenceNode GetReference(this CompositionSurfaceBrush compObj)
{
return new SurfaceBrushReferenceNode(null, compObj);
}

/// <summary>
/// Create an ExpressionNode reference to this CompositionObject.
/// </summary>
/// <param name="compObj">The comp object.</param>
/// <returns>VisualReferenceNode.</returns>
public static VisualReferenceNode GetReference(this Visual compObj)
{
return new VisualReferenceNode(null, compObj);
}

/// <summary>
/// Create an ExpressionNode reference to this specialized PropertySet.
/// </summary>
/// <typeparam name="T">A class that derives from PropertySetReferenceNode.</typeparam>
/// <param name="ps">The ps.</param>
/// <returns>T.</returns>
/// <exception cref="System.Exception">Invalid property set specialization</exception>
public static T GetSpecializedReference<T>(this CompositionPropertySet ps)
where T : PropertySetReferenceNode
{
if (typeof(T) == typeof(ManipulationPropertySetReferenceNode))
{
return new ManipulationPropertySetReferenceNode(null, ps) as T;
}
else if (typeof(T) == typeof(PointerPositionPropertySetReferenceNode))
{
return new PointerPositionPropertySetReferenceNode(null, ps) as T;
}
else
{
throw new System.Exception("Invalid property set specialization");
}
}

/// <summary>
/// Connects the specified ExpressionNode with the specified property of the object.
/// </summary>
/// <param name="compObject">The comp object.</param>
/// <param name="propertyName">The name of the property that the expression will target.</param>
/// <param name="expressionNode">The root ExpressionNode that represents the ExpressionAnimation.</param>
public static void StartAnimation(this CompositionObject compObject, string propertyName, ExpressionNode expressionNode)
{
compObject.StartAnimation(propertyName, CreateExpressionAnimationFromNode(compObject.Compositor, expressionNode));
}

/// <summary>
/// Inserts a KeyFrame whose value is calculated using the specified ExpressionNode.
/// </summary>
/// <param name="keyframeAnimation">The keyframe animation.</param>
/// <param name="normalizedProgressKey">The time the key frame should occur at, expressed as a percentage of the animation Duration. Allowed value is from 0.0 to 1.0.</param>
/// <param name="expressionNode">The root ExpressionNode that represents the ExpressionAnimation.</param>
/// <param name="easing">The easing function to use when interpolating between frames.</param>
public static void InsertExpressionKeyFrame(this KeyFrameAnimation keyframeAnimation, float normalizedProgressKey, ExpressionNode expressionNode, CompositionEasingFunction easing = null)
{
expressionNode.ClearReferenceInfo();

keyframeAnimation.InsertExpressionKeyFrame(normalizedProgressKey, expressionNode.ToExpressionString(), easing);

expressionNode.SetAllParameters(keyframeAnimation);
}

/// <summary>
/// Use the value of specified ExpressionNode to determine if this inertia modifier should be chosen.
/// </summary>
/// <param name="modifier">The modifier.</param>
/// <param name="expressionNode">The root ExpressionNode that represents the ExpressionAnimation.</param>
public static void SetCondition(this InteractionTrackerInertiaRestingValue modifier, ExpressionNode expressionNode)
{
modifier.Condition = CreateExpressionAnimationFromNode(modifier.Compositor, expressionNode);
}

/// <summary>
/// Use the value of specified ExpressionNode as the resting value for this inertia modifier.
/// </summary>
/// <param name="modifier">The modifier.</param>
/// <param name="expressionNode">The root ExpressionNode that represents the ExpressionAnimation.</param>
public static void SetRestingValue(this InteractionTrackerInertiaRestingValue modifier, ExpressionNode expressionNode)
{
modifier.RestingValue = CreateExpressionAnimationFromNode(modifier.Compositor, expressionNode);
}

/// <summary>
/// Use the value of specified ExpressionNode to determine if this inertia modifier should be chosen.
/// </summary>
/// <param name="modifier">The modifier.</param>
/// <param name="expressionNode">The root ExpressionNode that represents the ExpressionAnimation.</param>
public static void SetCondition(this InteractionTrackerInertiaMotion modifier, ExpressionNode expressionNode)
{
modifier.Condition = CreateExpressionAnimationFromNode(modifier.Compositor, expressionNode);
}

/// <summary>
/// Use the value of specified ExpressionNode to dictate the motion for this inertia modifier.
/// </summary>
/// <param name="modifier">The modifier.</param>
/// <param name="expressionNode">The root ExpressionNode that represents the ExpressionAnimation.</param>
public static void SetMotion(this InteractionTrackerInertiaMotion modifier, ExpressionNode expressionNode)
{
modifier.Motion = CreateExpressionAnimationFromNode(modifier.Compositor, expressionNode);
}

/// <summary>
/// Use the value of specified ExpressionNode to determine if this composition conditional value modifier should be chosen.
/// </summary>
/// <param name="modifier">The modifier.</param>
/// <param name="expressionNode">The root ExpressionNode that represents the ExpressionAnimation.</param>
public static void SetCondition(this CompositionConditionalValue modifier, ExpressionNode expressionNode)
{
modifier.Condition = CreateExpressionAnimationFromNode(modifier.Compositor, expressionNode);
}

/// <summary>
/// Use the value of specified ExpressionNode as the value for this composition conditional value
/// </summary>
/// <param name="modifier">The modifier.</param>
/// <param name="expressionNode">The root ExpressionNode that represents the ExpressionAnimation.</param>
public static void SetValue(this CompositionConditionalValue modifier, ExpressionNode expressionNode)
{
modifier.Value = CreateExpressionAnimationFromNode(modifier.Compositor, expressionNode);
}

/// <summary>
/// Creates the expression animation from node.
/// </summary>
/// <param name="compositor">The compositor.</param>
/// <param name="expressionNode">The expression node.</param>
/// <returns>ExpressionAnimation.</returns>
private static ExpressionAnimation CreateExpressionAnimationFromNode(Compositor compositor, ExpressionNode expressionNode)
{
// Only create a new animation if this node hasn't already generated one before, so we don't have to re-parse the expression string.
if (expressionNode.ExpressionAnimation == null)
{
expressionNode.ClearReferenceInfo();
expressionNode.ExpressionAnimation = compositor.CreateExpressionAnimation(expressionNode.ToExpressionString());
}

// We need to make sure all parameters are up to date, even if the animation already existed.
expressionNode.SetAllParameters(expressionNode.ExpressionAnimation);

return expressionNode.ExpressionAnimation;
}

internal static float EvaluateSubchannel(this ExpressionNode node, string subchannel) => (node, subchannel) switch
{
(Vector2Node n, "X") => n.Evaluate().X,
(Vector2Node n, "Y") => n.Evaluate().Y,

(Vector3Node n, "X") => n.Evaluate().X,
(Vector3Node n, "Y") => n.Evaluate().Y,
(Vector3Node n, "Z") => n.Evaluate().Z,

(Vector4Node n, "X") => n.Evaluate().X,
(Vector4Node n, "Y") => n.Evaluate().Y,
(Vector4Node n, "Z") => n.Evaluate().Z,
(Vector4Node n, "W") => n.Evaluate().W,

(Matrix3x2Node n, "Channel11") => n.Evaluate().M11,
(Matrix3x2Node n, "Channel12") => n.Evaluate().M12,
(Matrix3x2Node n, "Channel21") => n.Evaluate().M21,
(Matrix3x2Node n, "Channel22") => n.Evaluate().M22,
(Matrix3x2Node n, "Channel31") => n.Evaluate().M31,
(Matrix3x2Node n, "Channel32") => n.Evaluate().M32,

(Matrix4x4Node n, "Channel11") => n.Evaluate().M11,
(Matrix4x4Node n, "Channel12") => n.Evaluate().M12,
(Matrix4x4Node n, "Channel13") => n.Evaluate().M13,
(Matrix4x4Node n, "Channel14") => n.Evaluate().M14,
(Matrix4x4Node n, "Channel21") => n.Evaluate().M21,
(Matrix4x4Node n, "Channel22") => n.Evaluate().M22,
(Matrix4x4Node n, "Channel23") => n.Evaluate().M23,
(Matrix4x4Node n, "Channel24") => n.Evaluate().M24,
(Matrix4x4Node n, "Channel31") => n.Evaluate().M31,
(Matrix4x4Node n, "Channel32") => n.Evaluate().M32,
(Matrix4x4Node n, "Channel33") => n.Evaluate().M33,
(Matrix4x4Node n, "Channel34") => n.Evaluate().M34,
(Matrix4x4Node n, "Channel41") => n.Evaluate().M41,
(Matrix4x4Node n, "Channel42") => n.Evaluate().M42,
(Matrix4x4Node n, "Channel43") => n.Evaluate().M43,
(Matrix4x4Node n, "Channel44") => n.Evaluate().M44,

_ => 0
};
}
}
Loading