private bool AnimateChildren(MetaElementStateDict stateDict, ICollection elements)
{
// Find number of milliseconds elapsed since last animation calculation, note that if not
// currently animating then the elapsed time since the last animation cycle must be 0.
double elapsedMilliseconds = (!IsAnimating || (_lastTicks == -1) ? 0 : (_nextTicks - _lastTicks) / (double)(10000));
if (IsAnimationAllowed)
{
// Ask the chain of animation classes to apply any required movement changes
Animates.ApplyAnimation(AnimateId, this, stateDict, elements, elapsedMilliseconds);
}
// Post-process on animation state
bool moreAnimation = false;
foreach (MetaElementState elementState in stateDict.Values)
{
// At end of animation cycle the new/remove values must have been calculated
elementState.NewCalculating = false;
if (elementState.Status == MetaElementStatus.Removing)
elementState.RemoveCalculated = true;
// Has the element finished being removed?
if (elementState.AnimateComplete && (elementState.Status == MetaElementStatus.Removing))
_removeList.Add(elementState);
else
{
// If the element has not finished being animated
if (!elementState.AnimateComplete)
{
// Always reset to being completed, ready for next cycle
elementState.AnimateComplete = true;
moreAnimation = true;
}
else
{
// Has element finished being 'new'?
if (elementState.Status == MetaElementStatus.New)
elementState.Status = MetaElementStatus.Existing;
// Animation is completed so ensure the current rect is same as the target
// rect. This ensures that if there are no animation classes actually doing
// size/position animation then the child elements actually do get positioned.
elementState.CurrentRect = elementState.TargetRect;
}
}
// Reset the target changed flag
elementState.TargetChanged = false;
// Never allow the current rect to be empty
if (elementState.CurrentRect.IsEmpty)
elementState.CurrentRect = elementState.TargetRect;
}
// Process the removal list
foreach (MetaElementState elementState in _removeList)
{
RemoveChildElement(elementState.Element);
stateDict.Remove(elementState.Element);
moreAnimation = true;
}
// Must clear list to prevent dangling references to the removed UIElement instances
_removeList.Clear();
return moreAnimation;
}