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
- ButtonDesigner.cs
- ReturnEventArgs.cs
- SystemNetworkInterface.cs
- FixedSOMPage.cs
- RolePrincipal.cs
- MediaElementAutomationPeer.cs
- UIElement3D.cs
- ListSortDescription.cs
- RayMeshGeometry3DHitTestResult.cs
- Operator.cs
- CompositeDuplexBindingElementImporter.cs
- DoubleCollection.cs
- TransformConverter.cs
- _AutoWebProxyScriptEngine.cs
- TransformDescriptor.cs
- ViewLoader.cs
- HtmlElement.cs
- CustomWebEventKey.cs
- DocumentSequence.cs
- _ListenerAsyncResult.cs
- QilChoice.cs
- ByteArrayHelperWithString.cs
- precedingsibling.cs
- EntitySqlQueryBuilder.cs
- AtomServiceDocumentSerializer.cs
- ShapeTypeface.cs
- OdbcStatementHandle.cs
- AssemblyAttributesGoHere.cs
- ErrorHandlerModule.cs
- CompilationRelaxations.cs
- ListSourceHelper.cs
- PropertyValueChangedEvent.cs
- CreateDataSourceDialog.cs
- PermissionRequestEvidence.cs
- Currency.cs
- DataStreamFromComStream.cs
- FormParameter.cs
- ListSortDescription.cs
- SafeRightsManagementEnvironmentHandle.cs
- TypeToken.cs
- MessageSecurityOverHttp.cs
- TableLayoutStyleCollection.cs
- ResXBuildProvider.cs
- CustomPopupPlacement.cs
- SqlUdtInfo.cs
- ConnectionsZone.cs
- ByteStorage.cs
- MiniConstructorInfo.cs
- RegexStringValidatorAttribute.cs
- Timer.cs
- XmlDocumentFieldSchema.cs
- AsymmetricKeyExchangeFormatter.cs
- WebPartEditorApplyVerb.cs
- XamlRtfConverter.cs
- StateDesigner.cs
- BindingOperations.cs
- TextElementEditingBehaviorAttribute.cs
- RequestBringIntoViewEventArgs.cs
- XmlSchemaSimpleContent.cs
- DataGridViewTextBoxCell.cs
- Triplet.cs
- _AutoWebProxyScriptEngine.cs
- AnnotationComponentManager.cs
- CodeDomSerializer.cs
- Stylesheet.cs
- UnsafeNativeMethods.cs
- RemoteDebugger.cs
- PathFigure.cs
- DefaultHttpHandler.cs
- InvalidDataException.cs
- CodeGenerator.cs
- DispatcherTimer.cs
- FormatException.cs
- InstanceCreationEditor.cs
- BinaryObjectWriter.cs
- SoapIncludeAttribute.cs
- ProvidersHelper.cs
- TokenBasedSet.cs
- XsltQilFactory.cs
- MyContact.cs
- METAHEADER.cs
- HierarchicalDataBoundControlAdapter.cs
- CustomWebEventKey.cs
- SchemaComplexType.cs
- AvTraceFormat.cs
- InternalBase.cs
- ToolStripManager.cs
- PerfCounters.cs
- ArglessEventHandlerProxy.cs
- ThicknessAnimationBase.cs
- ToolboxItemAttribute.cs
- CheckBox.cs
- InputElement.cs
- BypassElementCollection.cs
- LazyTextWriterCreator.cs
- SplitterEvent.cs
- Empty.cs
- SqlProfileProvider.cs
- EntityContainer.cs
- ToolBarOverflowPanel.cs