/Xceed.Silverlight.ListBox/(Transitions)/RemovingItemTransitionAnimation.cs
C# | 326 lines | 226 code | 69 blank | 31 comment | 20 complexity | 839136bb3d4b40637daac036263b29c6 MD5 | raw file
- /************************************************************************
-
- Extended Silverlight Toolkit
-
- Copyright (C) 2010-2012 Xceed Software Inc.
-
- This program is provided to you under the terms of the Microsoft Public
- License (Ms-PL) as published at http://extendedsilverlight.codeplex.com/license
-
- Please purchase a commercial version of this toolkit if you are using
- it in a commercial product. The commercial versions support the project,
- and also include more features for each control, priority support,
- source code, updates, removed watermark, and a proprietary license.
-
- Visit http://xceed.com and follow @datagrid on Twitter.
-
- **********************************************************************/
-
- using System.Collections.Generic;
- using System.Linq;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Media.Animation;
-
- namespace Xceed.Silverlight.ListBox
- {
- internal class RemovingItemTransitionAnimation : TransitionAnimation
- {
- internal RemovingItemTransitionAnimation( ListBoxAnimationSettings animationSettings )
- : base( animationSettings.GetRemovingItemDuration() )
- {
- PowerEase opacityEasing = new PowerEase();
- opacityEasing.EasingMode = EasingMode.EaseOut;
- opacityEasing.Power = 6;
-
- PowerEase itemsRemovedEasing = new PowerEase();
- itemsRemovedEasing.EasingMode = EasingMode.EaseOut;
- itemsRemovedEasing.Power = 6;
-
- PowerEase otherItemsEasing = new PowerEase();
- otherItemsEasing.EasingMode = EasingMode.EaseInOut;
- otherItemsEasing.Power = 6;
-
- m_opacityEasing = opacityEasing;
- m_removedItemsMovementEasing = itemsRemovedEasing;
- m_otherItemsMovementEasing = otherItemsEasing;
-
- }
-
- internal double RemovePositionX
- {
- get;
- private set;
- }
-
- internal double RemovePositionY
- {
- get;
- private set;
- }
-
- internal double RemoveWidth
- {
- get;
- private set;
- }
-
- internal double RemoveHeight
- {
- get;
- private set;
- }
-
- internal Orientation Orientation
- {
- get;
- set;
- }
-
- internal override void AddContainer( ListBoxContainer container )
- {
- //Nothing to do
- }
-
- internal override LayoutChangeInfo CreateLayoutChangeInfo()
- {
- return new LayoutChangeInfo();
- }
-
- internal override void DetermineLayoutChangesCore( Dictionary<ListBoxContainer, LayoutChangeInfo> changedElements )
- {
- //For this transition animation, I need to assess the position ("pixels") where the remove is performed.
-
- //I also need to know total items travel to impact added containers correctly.
-
- double lowestRemovalX = double.MaxValue;
- double lowestRemovalY = double.MaxValue;
-
- double highestRemovalX = double.MinValue;
- double highestRemovalY = double.MinValue;
-
- IEnumerable<ListBoxContainer> removedElements = from kvp in changedElements
- let layoutChangeInfo = kvp.Value
- let removedContainer = kvp.Key
- where layoutChangeInfo.ChangeType == ChangeType.ElementRemoved
- select removedContainer;
-
- bool hadRemoval = false;
-
- foreach( ListBoxContainer container in removedElements )
- {
- Point containerPosition = container.ActualComputedPosition;
-
- double elementHeight = container.ActualElementHeight;
- double elementWidth = container.AbsoluteElementWidth;
-
- if( containerPosition.X < lowestRemovalX )
- {
- lowestRemovalX = containerPosition.X;
- }
-
- if( containerPosition.Y < lowestRemovalY )
- {
- lowestRemovalY = containerPosition.Y;
- }
-
- if( ( containerPosition.X + elementWidth ) > highestRemovalX )
- {
- highestRemovalX = containerPosition.X + elementWidth;
- }
-
- if( ( containerPosition.Y + elementHeight ) > highestRemovalY )
- {
- highestRemovalY = containerPosition.Y + elementHeight;
- }
-
- hadRemoval = true;
- }
-
-
- if( hadRemoval )
- {
- this.RemovePositionX = lowestRemovalX;
- this.RemovePositionY = lowestRemovalY;
- this.RemoveWidth = highestRemovalX - lowestRemovalX;
- this.RemoveHeight = highestRemovalY - lowestRemovalY;
- }
- }
-
- internal override bool PrepareContainerCore( ListBoxContainer container, LayoutChangeInfo changeInfo )
- {
- switch( changeInfo.ChangeType )
- {
- case ChangeType.ElementAdded:
- this.PrepareAddedElement( container, changeInfo );
- break;
-
- case ChangeType.ElementRemoved:
- this.PrepareRemovedElement( container, changeInfo );
- break;
-
- //If element is changed, don't change a thing.
- case ChangeType.ElementChanged:
- this.PrepareChangedElement( container, changeInfo );
- break;
- default:
- break;
- }
-
- //systematically return true. All elements flagged as changed are handled in this transition.
- return true;
- }
-
- internal override bool UpdateContainerCore( double normalizedElapsedTime, ListBoxContainer container )
- {
-
- if( container == null )
- throw new ListBoxInternalException();
-
-
- container.UpdateAnimations( normalizedElapsedTime );
-
- //There is no custom animations in this transition, only those handled by the EasingFunctions.
- //Since I have no custom timeline, I do not have to decide when its "finished". Returning false
- //will just make it so that the animation will proceed for every frame of every item.
- return false;
- }
-
- internal override void CleanContainerCore( ListBoxContainer container )
- {
- if( container == null )
- throw new ListBoxInternalException();
-
- }
-
- private void PrepareAddedElement( ListBoxContainer container, LayoutChangeInfo changeInfo )
- {
-
- if( changeInfo == null )
- throw new ListBoxInternalException();
-
- //In the case of an Remove action, added elements are those brought into the layout because some content is removed from the layout.
- //In that case, this class will animate them from the height of removal to their respective position
-
- SizeAnimation sizeAnimation = new SizeAnimation();
- OpacityAnimation opacityAnimation = new OpacityAnimation();
- PositionAnimation positionAnimation = new PositionAnimation();
-
- ( ( IAnimation )opacityAnimation ).AnimationDirection = AnimationDirection.ToReferencePosition;
- ( ( IAnimation )opacityAnimation ).EasingFunction = m_opacityEasing;
- ( ( IAnimation )opacityAnimation ).ParentTransition = this;
-
- ( ( IAnimation )sizeAnimation ).EasingFunction = m_otherItemsMovementEasing;
- ( ( IAnimation )sizeAnimation ).ParentTransition = this;
-
- ( ( IAnimation )positionAnimation ).EasingFunction = m_otherItemsMovementEasing;
- ( ( IAnimation )positionAnimation ).ParentTransition = this;
-
- if( this.Orientation == Orientation.Vertical )
- {
- positionAnimation.XChange = double.NaN;
- positionAnimation.YChange = this.RemoveHeight;
-
- sizeAnimation.MaximumHeightChange = -this.RemoveHeight;
- }
- else
- {
- positionAnimation.XChange = this.RemoveWidth;
- positionAnimation.YChange = double.NaN;
-
- sizeAnimation.MaximumWidthChange = -this.RemoveWidth;
- }
-
- sizeAnimation.WidthChange = double.NaN;
- sizeAnimation.HeightChange = double.NaN;
-
- opacityAnimation.OpacityChange = -changeInfo.OpacityChange;
-
- container.AddAnimation( sizeAnimation );
- container.AddAnimation( opacityAnimation );
- container.AddAnimation( positionAnimation );
-
- }
-
- private void PrepareChangedElement( ListBoxContainer container, LayoutChangeInfo changeInfo )
- {
-
- if( changeInfo == null )
- throw new ListBoxInternalException();
-
- //In the case of an Remove action, added elements are those brought into the layout because some content is removed from the layout.
- //In that case, this class will animate them from the height of removal to their respective position
- PositionAnimation positionAnimation = new PositionAnimation();
- SizeAnimation sizeAnimation = new SizeAnimation();
- RotateAnimation rotationAnimation = new RotateAnimation();
- ScaleAnimation scaleAnimation = new ScaleAnimation();
-
- ( ( IAnimation )positionAnimation ).EasingFunction = m_otherItemsMovementEasing;
- ( ( IAnimation )positionAnimation ).ParentTransition = this;
- ( ( IAnimation )sizeAnimation ).EasingFunction = m_otherItemsMovementEasing;
- ( ( IAnimation )sizeAnimation ).ParentTransition = this;
- ( ( IAnimation )rotationAnimation ).ParentTransition = this;
- ( ( IAnimation )rotationAnimation ).EasingFunction = m_otherItemsMovementEasing;
- ( ( IAnimation )scaleAnimation ).ParentTransition = this;
- ( ( IAnimation )scaleAnimation ).EasingFunction = m_otherItemsMovementEasing;
-
- positionAnimation.XChange = changeInfo.XChange;
- positionAnimation.YChange = changeInfo.YChange;
- rotationAnimation.AngleChange = changeInfo.AngleChange;
- if( this.Orientation == Orientation.Vertical )
- {
- sizeAnimation.MaximumHeightChange = -this.RemoveHeight;
- }
- else
- {
- sizeAnimation.MaximumWidthChange = -this.RemoveWidth;
- }
-
- sizeAnimation.WidthChange = double.NaN;
- sizeAnimation.HeightChange = double.NaN;
- scaleAnimation.ScaleChange = changeInfo.ScaleChange;
-
- container.AddAnimation( rotationAnimation );
- container.AddAnimation( positionAnimation );
- container.AddAnimation( sizeAnimation );
- container.AddAnimation( scaleAnimation );
- }
-
- private void PrepareRemovedElement( ListBoxContainer container, LayoutChangeInfo changeInfo )
- {
- //Removed items in the case of a Remove are items that are shifted out of view ( they are removed )
-
- if( changeInfo == null )
- throw new ListBoxInternalException();
-
- //Animation for these items is to push them away by the amount of inserted items.
- Point elementActualPosition = container.ActualComputedPosition;
- SizeAnimation sizeAnimation = new SizeAnimation();
- OpacityAnimation opacityAnimation = new OpacityAnimation();
- RotateAnimation rotateAnimation = new RotateAnimation();
-
- ( ( IAnimation )sizeAnimation ).EasingFunction = m_removedItemsMovementEasing;
- ( ( IAnimation )sizeAnimation ).ParentTransition = this;
- ( ( IAnimation )opacityAnimation ).EasingFunction = m_opacityEasing;
- ( ( IAnimation )opacityAnimation ).ParentTransition = this;
- ( ( IAnimation )opacityAnimation ).AnimationDirection = AnimationDirection.FromReferencePosition;
- ( ( IAnimation )rotateAnimation ).EasingFunction = m_removedItemsMovementEasing;
- ( ( IAnimation )rotateAnimation ).ParentTransition = this;
- rotateAnimation.AngleChange = changeInfo.AngleChange;
-
- sizeAnimation.WidthChange = double.NaN; // do not change its width
- sizeAnimation.HeightChange = double.NaN; // do not change its height.
-
- opacityAnimation.OpacityChange = changeInfo.OpacityChange;
-
- container.AddAnimation( rotateAnimation );
- container.AddAnimation( sizeAnimation );
- container.AddAnimation( opacityAnimation );
-
- }
-
- private IEasingFunction m_opacityEasing;
- private IEasingFunction m_removedItemsMovementEasing;
- private IEasingFunction m_otherItemsMovementEasing;
- }
- }