Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Core / System / Windows / Media / Animation / AnimationLayer.cs / 1 / AnimationLayer.cs
// AnimationLayer.cs
using System.Collections.Generic;
using System.Diagnostics;
namespace System.Windows.Media.Animation
{
internal class AnimationLayer
{
private object _snapshotValue = DependencyProperty.UnsetValue;
private IList _animationClocks;
private AnimationStorage _ownerStorage;
private EventHandler _removeRequestedHandler;
private bool _hasStickySnapshotValue;
internal AnimationLayer(AnimationStorage ownerStorage)
{
Debug.Assert(ownerStorage != null);
_ownerStorage = ownerStorage;
_removeRequestedHandler = new EventHandler(OnRemoveRequested);
}
internal void ApplyAnimationClocks(
IList newAnimationClocks,
HandoffBehavior handoffBehavior,
object defaultDestinationValue)
{
Debug.Assert(
newAnimationClocks == null
|| (newAnimationClocks.Count > 0
&& !newAnimationClocks.Contains(null)));
if (handoffBehavior == HandoffBehavior.SnapshotAndReplace)
{
Debug.Assert(defaultDestinationValue != DependencyProperty.UnsetValue,
"We need a valid default destination value when peforming a snapshot and replace.");
EventHandler handler = new EventHandler(OnCurrentStateInvalidated);
// If we have a sticky snapshot value, the clock that would have
// unstuck it is being replaced, so we need to remove our event
// handler from that clock.
if (_hasStickySnapshotValue)
{
_animationClocks[0].CurrentStateInvalidated -= handler;
DetachAnimationClocks();
}
// Otherwise if we have at least one clock take a new snapshot
// value.
else if (_animationClocks != null)
{
_snapshotValue = GetCurrentValue(defaultDestinationValue);
DetachAnimationClocks();
}
// Otherwise we can use the defaultDestinationValue as the
// new snapshot value.
else
{
_snapshotValue = defaultDestinationValue;
}
// If we have a new clock in a stopped state, then the snapshot
// value will be sticky.
if (newAnimationClocks != null
&& newAnimationClocks[0].CurrentState == ClockState.Stopped)
{
_hasStickySnapshotValue = true;
newAnimationClocks[0].CurrentStateInvalidated += handler;
}
// Otherwise it won't be sticky.
else
{
_hasStickySnapshotValue = false;
}
SetAnimationClocks(newAnimationClocks);
}
else
{
Debug.Assert(handoffBehavior == HandoffBehavior.Compose,
"Unhandled handoffBehavior value.");
Debug.Assert(defaultDestinationValue == DependencyProperty.UnsetValue,
"We shouldn't take the time to calculate a default destination value when it isn't needed.");
if (newAnimationClocks == null)
{
return;
}
else if (_animationClocks == null)
{
SetAnimationClocks(newAnimationClocks);
}
else
{
AppendAnimationClocks(newAnimationClocks);
}
}
}
private void DetachAnimationClocks()
{
Debug.Assert(_animationClocks != null);
int count = _animationClocks.Count;
for (int i = 0; i < count; i++)
{
_ownerStorage.DetachAnimationClock(_animationClocks[i], _removeRequestedHandler);
}
_animationClocks = null;
}
private void SetAnimationClocks(
IList animationClocks)
{
Debug.Assert(animationClocks != null);
Debug.Assert(animationClocks.Count > 0);
Debug.Assert(!animationClocks.Contains(null));
Debug.Assert(_animationClocks == null);
_animationClocks = animationClocks;
int count = animationClocks.Count;
for (int i = 0; i < count; i++)
{
_ownerStorage.AttachAnimationClock(animationClocks[i], _removeRequestedHandler);
}
}
private void OnCurrentStateInvalidated(object sender, EventArgs args)
{
Debug.Assert(_hasStickySnapshotValue,
"_hasStickySnapshotValue should be set to true if OnCurrentStateInvalidated has been called.");
_hasStickySnapshotValue = false;
((AnimationClock)sender).CurrentStateInvalidated -= new EventHandler(OnCurrentStateInvalidated);
}
private void OnRemoveRequested(object sender, EventArgs args)
{
Debug.Assert(_animationClocks != null
&& _animationClocks.Count > 0,
"An AnimationClock no longer associated with a property should not have a RemoveRequested event handler.");
AnimationClock animationClock = (AnimationClock)sender;
int index = _animationClocks.IndexOf(animationClock);
Debug.Assert(index >= 0,
"An AnimationClock no longer associated with a property should not have a RemoveRequested event handler.");
if (_hasStickySnapshotValue
&& index == 0)
{
_animationClocks[0].CurrentStateInvalidated -= new EventHandler(OnCurrentStateInvalidated);
_hasStickySnapshotValue = false;
}
_animationClocks.RemoveAt(index);
_ownerStorage.DetachAnimationClock(animationClock, _removeRequestedHandler);
AnimationStorage tmpOwnerStorage = _ownerStorage;
if (_animationClocks.Count == 0)
{
_animationClocks = null;
_snapshotValue = DependencyProperty.UnsetValue;
_ownerStorage.RemoveLayer(this);
_ownerStorage = null;
}
// _ownerStorage may be null here.
tmpOwnerStorage.WritePostscript();
}
private void AppendAnimationClocks(
IList newAnimationClocks)
{
Debug.Assert(newAnimationClocks != null);
Debug.Assert(newAnimationClocks.Count > 0);
Debug.Assert(!newAnimationClocks.Contains(null));
// _animationClocks may be null or non-null here.
int newClocksCount = newAnimationClocks.Count;
List animationClockList = _animationClocks as List;
// If _animationClocks is not a List then make it one.
if (animationClockList == null)
{
int oldClocksCount = (_animationClocks == null) ? 0 : _animationClocks.Count;
animationClockList = new List(oldClocksCount + newClocksCount);
for (int i = 0; i < oldClocksCount; i++)
{
animationClockList.Add(_animationClocks[i]);
}
_animationClocks = animationClockList;
}
for (int i = 0; i < newClocksCount; i++)
{
AnimationClock clock = newAnimationClocks[i];
animationClockList.Add(clock);
_ownerStorage.AttachAnimationClock(clock, _removeRequestedHandler);
}
}
internal object GetCurrentValue(
object defaultDestinationValue)
{
Debug.Assert(defaultDestinationValue != DependencyProperty.UnsetValue);
// We have a sticky snapshot value if changes have been made to the
// animations in this layer since the last tick. This flag will be
// unset when the next tick starts.
//
// Since CurrentTimeInvaliated is raised before CurrentStateInvalidated
// we need to check the state of the first clock as well to avoid
// potential first frame issues. In this case _hasStickySnapshotValue
// will be updated to false shortly.
if ( _hasStickySnapshotValue
&& _animationClocks[0].CurrentState == ClockState.Stopped)
{
return _snapshotValue;
}
// This layer just contains a snapshot value or a fill value after
// all the clocks have been completed.
if (_animationClocks == null)
{
Debug.Assert(_snapshotValue != DependencyProperty.UnsetValue);
// In this case, we're using _snapshotValue to store the value,
// but the value here does not represent the snapshotValue. It
// represents the fill value of an animation clock that has been
// removed for performance reason because we know it will never
// be restarted.
return _snapshotValue;
}
object currentLayerValue = _snapshotValue;
bool hasUnstoppedClocks = false;
if (currentLayerValue == DependencyProperty.UnsetValue)
{
currentLayerValue = defaultDestinationValue;
}
int count = _animationClocks.Count;
Debug.Assert(count > 0);
for (int i = 0; i < count; i++)
{
AnimationClock clock = _animationClocks[i];
if (clock.CurrentState != ClockState.Stopped)
{
hasUnstoppedClocks = true;
currentLayerValue = clock.GetCurrentValue(
currentLayerValue,
defaultDestinationValue);
}
}
if (hasUnstoppedClocks)
{
return currentLayerValue;
}
else
{
return defaultDestinationValue;
}
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- TemplateXamlTreeBuilder.cs
- StoreContentChangedEventArgs.cs
- SmtpReplyReaderFactory.cs
- SqlDataSourceEnumerator.cs
- EdmItemCollection.OcAssemblyCache.cs
- SqlServices.cs
- PointConverter.cs
- FolderBrowserDialog.cs
- X509CertificateTrustedIssuerElement.cs
- DataServiceHost.cs
- SelectionProcessor.cs
- QilTernary.cs
- XmlSchemaSet.cs
- TransformerConfigurationWizardBase.cs
- ScriptMethodAttribute.cs
- ZipIOZip64EndOfCentralDirectoryBlock.cs
- SqlProcedureAttribute.cs
- ResolveMatchesApril2005.cs
- PageBuildProvider.cs
- ViewStateException.cs
- SiteIdentityPermission.cs
- TemplateComponentConnector.cs
- UTF8Encoding.cs
- DataGridSortCommandEventArgs.cs
- BeginEvent.cs
- EntityContainer.cs
- TypefaceMap.cs
- ZoneLinkButton.cs
- ScriptReferenceEventArgs.cs
- AnnotationResource.cs
- TraceData.cs
- WizardForm.cs
- MetafileHeaderWmf.cs
- PostBackOptions.cs
- UnsafeNativeMethods.cs
- RichTextBoxConstants.cs
- DataControlPagerLinkButton.cs
- String.cs
- AssociationEndMember.cs
- MarkerProperties.cs
- MenuItemStyle.cs
- GiveFeedbackEventArgs.cs
- ModelPerspective.cs
- WebPartsPersonalization.cs
- WarningException.cs
- DefaultParameterValueAttribute.cs
- AlignmentXValidation.cs
- XmlSchemaInfo.cs
- PointLightBase.cs
- EntityDataSourceDesigner.cs
- AttributeInfo.cs
- XmlCharacterData.cs
- JournalNavigationScope.cs
- TimeSpanValidatorAttribute.cs
- coordinator.cs
- BitFlagsGenerator.cs
- TextAutomationPeer.cs
- StdRegProviderWrapper.cs
- PrintController.cs
- ServicePoint.cs
- QueryCorrelationInitializer.cs
- ZoneLinkButton.cs
- WebConfigManager.cs
- Cursors.cs
- MenuItemCollection.cs
- CodeSnippetCompileUnit.cs
- MbpInfo.cs
- ViewSimplifier.cs
- DispatcherEventArgs.cs
- ConfigXmlWhitespace.cs
- GroupItem.cs
- XsdDateTime.cs
- Configuration.cs
- AnimationStorage.cs
- XmlComplianceUtil.cs
- AuthenticationModulesSection.cs
- ModelItemDictionaryImpl.cs
- PositiveTimeSpanValidator.cs
- SplitterCancelEvent.cs
- Misc.cs
- Recipient.cs
- References.cs
- SqlGatherProducedAliases.cs
- MemberDescriptor.cs
- XmlAnyElementAttribute.cs
- IDictionary.cs
- LocalTransaction.cs
- HtmlButton.cs
- ClientConfigPaths.cs
- UInt32Storage.cs
- MetadataItemEmitter.cs
- HeaderLabel.cs
- CatalogZone.cs
- WindowsFormsHostPropertyMap.cs
- GridItemPattern.cs
- WebPermission.cs
- TemplatedAdorner.cs
- FragmentNavigationEventArgs.cs
- PolyLineSegment.cs
- WebPartMenu.cs