From: huiyu <35286162+huiyueun@users.noreply.github.com> Date: Fri, 17 Sep 2021 08:14:46 +0000 (+0900) Subject: [NUI] Separate the LayoutTransition from LayoutController (#3592) X-Git-Tag: accepted/tizen/unified/20231205.024657~1420 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=84c047fb4a68161c5f97301b3d6b874e46a862a6;p=platform%2Fcore%2Fcsapi%2Ftizenfx.git [NUI] Separate the LayoutTransition from LayoutController (#3592) Separate class to help understanding for layout process. Signed-off-by: huiyu.eun --- diff --git a/src/Tizen.NUI/src/internal/Layouting/LayoutController.cs b/src/Tizen.NUI/src/internal/Layouting/LayoutController.cs index b6574c7..adb9e41 100755 --- a/src/Tizen.NUI/src/internal/Layouting/LayoutController.cs +++ b/src/Tizen.NUI/src/internal/Layouting/LayoutController.cs @@ -16,9 +16,8 @@ */ using Tizen.NUI.BaseComponents; -using System.Collections.Generic; -using System; using System.ComponentModel; +using System; namespace Tizen.NUI { @@ -32,11 +31,9 @@ namespace Tizen.NUI private int id; private Window window; - private Animation coreAnimation; - private List layoutTransitionDataQueue; - private List itemRemovalQueue; private float windowWidth; private float windowHeight; + private LayoutTransitionManager transitionManager; private bool subscribed; @@ -46,23 +43,40 @@ namespace Tizen.NUI /// public LayoutController(Window window) { - this.window = window; - this.window.Resized += OnWindowResized; - var windowSize = window.GetSize(); - windowWidth = windowSize.Width; - windowHeight = windowSize.Height; - - layoutTransitionDataQueue = new List(); + transitionManager = new LayoutTransitionManager(); id = layoutControllerID++; - windowSize.Dispose(); - windowSize = null; + SetBaseWindowAndSize(window); } - private void OnWindowResized(object sender, Window.ResizedEventArgs e) + /// + /// Dispose Explicit or Implicit + /// + protected override void Dispose(DisposeTypes type) { - windowWidth = e.WindowSize.Width; - windowHeight = e.WindowSize.Height; + if (Disposed) + { + return; + } + + if (subscribed) + { + ProcessorController.Instance.LayoutProcessorEvent -= Process; + subscribed = false; + } + + //Release your own unmanaged resources here. + //You should not access any managed member here except static instance. + //because the execution order of Finalizes is non-deterministic. + + if (SwigCPtr.Handle != global::System.IntPtr.Zero) + { + SwigCPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero); + } + + transitionManager.Dispose(); + + base.Dispose(type); } /// @@ -71,7 +85,17 @@ namespace Tizen.NUI /// Reset to False if explicit control no longer required. /// [EditorBrowsable(EditorBrowsableState.Never)] - public bool OverrideCoreAnimation { get; set; } = false; + public bool OverrideCoreAnimation + { + get + { + return transitionManager.OverrideCoreAnimation; + } + set + { + transitionManager.OverrideCoreAnimation = value; + } + } /// /// Get the unique id of the LayoutController @@ -99,7 +123,6 @@ namespace Tizen.NUI } } - /// /// Entry point into the C# Layouting that starts the Processing /// @@ -116,11 +139,9 @@ namespace Tizen.NUI }); }); - if (SetupCoreAnimation() && OverrideCoreAnimation == false) - { - PlayAnimation(); - } + transitionManager.SetupCoreAndPlayAnimation(); } + /// /// Get the Layouting animation object that transitions layouts and content. /// Use OverrideCoreAnimation to explicitly control Playback. @@ -129,7 +150,7 @@ namespace Tizen.NUI [EditorBrowsable(EditorBrowsableState.Never)] public Animation GetCoreAnimation() { - return coreAnimation; + return transitionManager.CoreAnimation; } /// @@ -150,7 +171,7 @@ namespace Tizen.NUI /// Transition data for a LayoutItem. internal void AddTransitionDataEntry(LayoutData transitionDataEntry) { - layoutTransitionDataQueue.Add(transitionDataEntry); + transitionManager.AddTransitionDataEntry(transitionDataEntry); } /// @@ -159,39 +180,7 @@ namespace Tizen.NUI /// LayoutItem to remove. internal void AddToRemovalStack(LayoutItem itemToRemove) { - if (itemRemovalQueue == null) - { - itemRemovalQueue = new List(); - } - itemRemovalQueue.Add(itemToRemove); - } - - /// - /// Dispose Explicit or Implicit - /// - protected override void Dispose(DisposeTypes type) - { - if (disposed) - { - return; - } - - if (subscribed) - { - ProcessorController.Instance.LayoutProcessorEvent -= Process; - subscribed = false; - } - - //Release your own unmanaged resources here. - //You should not access any managed member here except static instance. - //because the execution order of Finalizes is non-deterministic. - - if (SwigCPtr.Handle != global::System.IntPtr.Zero) - { - SwigCPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero); - } - - base.Dispose(type); + transitionManager.AddToRemovalStack(itemToRemove); } // Traverse the tree looking for a root node that is a layout. @@ -294,266 +283,22 @@ namespace Tizen.NUI root.Layout?.Layout(left, top, right, bottom); } - /// - /// Play the animation. - /// - private void PlayAnimation() - { - NUILog.Debug("LayoutController Playing, Core Duration:" + coreAnimation.Duration); - coreAnimation.Play(); - } - - private void AnimationFinished(object sender, EventArgs e) - { - // Iterate list of LayoutItem that were set for removal. - // Now the core animation has finished their Views can be removed. - if (itemRemovalQueue != null) - { - foreach (LayoutItem item in itemRemovalQueue) - { - // Check incase the parent was already removed and the Owner was - // removed already. - if (item.Owner) - { - // Check again incase the parent has already been removed. - ILayoutParent layoutParent = item.GetParent(); - LayoutGroup layoutGroup = layoutParent as LayoutGroup; - if (layoutGroup != null) - { - layoutGroup.Owner?.RemoveChild(item.Owner); - } - - } - } - itemRemovalQueue.Clear(); - // If LayoutItems added to stack whilst the core animation is playing - // they would have been cleared here. - // Could have another stack to be added to whilst the animation is running. - // After the running stack is cleared it can be populated with the content - // of the other stack. Then the main removal stack iterated when AnimationFinished - // occurs again. - } - NUILog.Debug("LayoutController AnimationFinished"); - coreAnimation?.Clear(); - } - - /// - /// Set up the animation from each LayoutItems position data. - /// Iterates the transition stack, adding an Animator to the core animation. - /// - private bool SetupCoreAnimation() + private void SetBaseWindowAndSize(Window window) { - // Initialize animation for this layout run. - bool animationPending = false; - - NUILog.Debug("LayoutController SetupCoreAnimation for:" + layoutTransitionDataQueue.Count); - - if (layoutTransitionDataQueue.Count > 0) // Something to animate - { - if (!coreAnimation) - { - coreAnimation = new Animation(); - } - coreAnimation.EndAction = Animation.EndActions.StopFinal; - coreAnimation.Finished += AnimationFinished; - - // Iterate all items that have been queued for repositioning. - foreach (LayoutData layoutPositionData in layoutTransitionDataQueue) - { - AddAnimatorsToAnimation(layoutPositionData); - } - - animationPending = true; - - // transitions have now been applied, clear stack, ready for new transitions on - // next layout traversal. - layoutTransitionDataQueue.Clear(); - } - return animationPending; - } - - private void SetupAnimationForPosition(LayoutData layoutPositionData, TransitionComponents positionTransitionComponents) - { - // A removed item does not have a valid target position within the layout so don't try to position. - if (layoutPositionData.ConditionForAnimation != TransitionCondition.Remove) - { - coreAnimation.AnimateTo(layoutPositionData.Item.Owner, "Position", - new Vector3(layoutPositionData.Left, - layoutPositionData.Top, - layoutPositionData.Item.Owner.Position.Z), - positionTransitionComponents.Delay, - positionTransitionComponents.Duration, - positionTransitionComponents.AlphaFunction); - - NUILog.Debug("LayoutController SetupAnimationForPosition View:" + layoutPositionData.Item.Owner.Name + - " left:" + layoutPositionData.Left + - " top:" + layoutPositionData.Top + - " delay:" + positionTransitionComponents.Delay + - " duration:" + positionTransitionComponents.Duration); - } - } - - private void SetupAnimationForSize(LayoutData layoutPositionData, TransitionComponents sizeTransitionComponents) - { - // Text size cant be animated so is set to it's final size. - // It is due to the internals of the Text not being able to recalculate fast enough. - if (layoutPositionData.Item.Owner is TextLabel || layoutPositionData.Item.Owner is TextField) - { - float itemWidth = layoutPositionData.Right - layoutPositionData.Left; - float itemHeight = layoutPositionData.Bottom - layoutPositionData.Top; - // Set size directly. - layoutPositionData.Item.Owner.Size2D = new Size2D((int)itemWidth, (int)itemHeight); - } - else - { - coreAnimation.AnimateTo(layoutPositionData.Item.Owner, "Size", - new Vector3(layoutPositionData.Right - layoutPositionData.Left, - layoutPositionData.Bottom - layoutPositionData.Top, - layoutPositionData.Item.Owner.Position.Z), - sizeTransitionComponents.Delay, - sizeTransitionComponents.Duration, - sizeTransitionComponents.AlphaFunction); - - NUILog.Debug("LayoutController SetupAnimationForSize View:" + layoutPositionData.Item.Owner.Name + - " width:" + (layoutPositionData.Right - layoutPositionData.Left) + - " height:" + (layoutPositionData.Bottom - layoutPositionData.Top) + - " delay:" + sizeTransitionComponents.Delay + - " duration:" + sizeTransitionComponents.Duration); - } - } - - void SetupAnimationForCustomTransitions(TransitionList transitionsToAnimate, View view) - { - if (transitionsToAnimate?.Count > 0) - { - foreach (LayoutTransition transition in transitionsToAnimate) - { - if (transition.AnimatableProperty != AnimatableProperties.Position && - transition.AnimatableProperty != AnimatableProperties.Size) - { - coreAnimation.AnimateTo(view, - transition.AnimatableProperty.ToString(), - transition.TargetValue, - transition.Animator.Delay, - transition.Animator.Duration, - transition.Animator.AlphaFunction); - - NUILog.Debug("LayoutController SetupAnimationForCustomTransitions View:" + view.Name + - " Property:" + transition.AnimatableProperty.ToString() + - " delay:" + transition.Animator.Delay + - " duration:" + transition.Animator.Duration); - } - } - } - } - - /// - /// Iterate transitions and replace Position Components if replacements found in list. - /// - private void FindAndReplaceAnimatorComponentsForProperty(TransitionList sourceTransitionList, - AnimatableProperties propertyToMatch, - ref TransitionComponents transitionComponentToUpdate) - { - foreach (LayoutTransition transition in sourceTransitionList) - { - if (transition.AnimatableProperty == propertyToMatch) - { - // Matched property to animate is for the propertyToMatch so use provided Animator. - transitionComponentToUpdate = transition.Animator; - } - } - } + this.window = window; + this.window.Resized += OnWindowResized; - private TransitionComponents CreateDefaultTransitionComponent(int delay, int duration) - { - AlphaFunction alphaFunction = new AlphaFunction(AlphaFunction.BuiltinFunctions.Linear); - return new TransitionComponents(delay, duration, alphaFunction); + var windowSize = window.GetSize(); + windowWidth = windowSize.Width; + windowHeight = windowSize.Height; + windowSize.Dispose(); + windowSize = null; } - /// - /// Sets up the main animation with the animators for each item (each layoutPositionData structure) - /// - private void AddAnimatorsToAnimation(LayoutData layoutPositionData) + private void OnWindowResized(object sender, Window.ResizedEventArgs e) { - LayoutTransition positionTransition = new LayoutTransition(); - LayoutTransition sizeTransition = new LayoutTransition(); - TransitionCondition conditionForAnimators = layoutPositionData.ConditionForAnimation; - - // LayoutChanged transitions overrides ChangeOnAdd and ChangeOnRemove as siblings will - // reposition to the new layout not to the insertion/removal of a sibling. - if (layoutPositionData.ConditionForAnimation.HasFlag(TransitionCondition.LayoutChanged)) - { - conditionForAnimators = TransitionCondition.LayoutChanged; - } - - // Set up a default transitions, will be overwritten if inherited from parent or set explicitly. - TransitionComponents positionTransitionComponents = CreateDefaultTransitionComponent(0, 300); - TransitionComponents sizeTransitionComponents = CreateDefaultTransitionComponent(0, 300); - - bool matchedCustomTransitions = false; - - - TransitionList transitionsForCurrentCondition = new TransitionList(); - // Note, Transitions set on View rather than LayoutItem so if the Layout changes the transition persist. - - // Check if item to animate has it's own Transitions for this condition. - // If a key exists then a List of at least 1 transition exists. - if (layoutPositionData.Item.Owner.LayoutTransitions.ContainsKey(conditionForAnimators)) - { - // Child has transitions for the condition - matchedCustomTransitions = layoutPositionData.Item.Owner.LayoutTransitions.TryGetValue(conditionForAnimators, out transitionsForCurrentCondition); - } - - if (!matchedCustomTransitions) - { - // Inherit parent transitions as none already set on View for the condition. - ILayoutParent layoutParent = layoutPositionData.Item.GetParent(); - if (layoutParent != null) - { - // Item doesn't have it's own transitions for this condition so copy parents if - // has a parent with transitions. - LayoutGroup layoutGroup = layoutParent as LayoutGroup; - TransitionList parentTransitionList; - // Note TryGetValue returns null if key not matched. - if (layoutGroup != null && layoutGroup.Owner.LayoutTransitions.TryGetValue(conditionForAnimators, out parentTransitionList)) - { - // Copy parent transitions to temporary TransitionList. List contains transitions for the current condition. - LayoutTransitionsHelper.CopyTransitions(parentTransitionList, - transitionsForCurrentCondition); - } - } - } - - - // Position/Size transitions can be displayed for a layout changing to another layout or an item being added or removed. - - // There can only be one position transition and one size position, they will be replaced if set multiple times. - // transitionsForCurrentCondition represent all non position (custom) properties that should be animated. - - // Search for Position property in the transitionsForCurrentCondition list of custom transitions, - // and only use the particular parts of the animator as custom transitions should not effect all parameters of Position. - // Typically Delay, Duration and Alphafunction can be custom. - FindAndReplaceAnimatorComponentsForProperty(transitionsForCurrentCondition, - AnimatableProperties.Position, - ref positionTransitionComponents); - - // Size - FindAndReplaceAnimatorComponentsForProperty(transitionsForCurrentCondition, - AnimatableProperties.Size, - ref sizeTransitionComponents); - - // Add animators to the core Animation, - - SetupAnimationForCustomTransitions(transitionsForCurrentCondition, layoutPositionData.Item.Owner); - - SetupAnimationForPosition(layoutPositionData, positionTransitionComponents); - - SetupAnimationForSize(layoutPositionData, sizeTransitionComponents); - - // Dispose components - positionTransitionComponents.Dispose(); - sizeTransitionComponents.Dispose(); + windowWidth = e.WindowSize.Width; + windowHeight = e.WindowSize.Height; } - } // class LayoutController } // namespace Tizen.NUI diff --git a/src/Tizen.NUI/src/internal/Layouting/LayoutTransitionManager.cs b/src/Tizen.NUI/src/internal/Layouting/LayoutTransitionManager.cs new file mode 100755 index 0000000..803a8bc --- /dev/null +++ b/src/Tizen.NUI/src/internal/Layouting/LayoutTransitionManager.cs @@ -0,0 +1,361 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +using System; +using System.Collections.Generic; +using Tizen.NUI.BaseComponents; + +namespace Tizen.NUI +{ + internal class LayoutTransitionManager : Disposable + { + private bool overrideCoreAnimation = false; + private Animation coreAnimation; + private List layoutTransitionDataQueue; + private List itemRemovalQueue; + + internal LayoutTransitionManager() + { + layoutTransitionDataQueue = new List(); + + } + + /// + /// Dispose Explicit or Implicit + /// + protected override void Dispose(DisposeTypes type) + { + if (Disposed) + { + return; + } + + if (coreAnimation != null) + { + coreAnimation.Dispose(); + coreAnimation = null; + } + + base.Dispose(type); + } + + public Animation CoreAnimation => coreAnimation; + + public bool OverrideCoreAnimation + { + get + { + return overrideCoreAnimation; + } + set + { + overrideCoreAnimation = value; + } + } + + /// + /// Add transition data for a LayoutItem to the transition stack. + /// + /// Transition data for a LayoutItem. + internal void AddTransitionDataEntry(LayoutData transitionDataEntry) + { + layoutTransitionDataQueue.Add(transitionDataEntry); + } + + /// + /// Add LayoutItem to a removal stack for removal after transitions finish. + /// + /// LayoutItem to remove. + internal void AddToRemovalStack(LayoutItem itemToRemove) + { + if (itemRemovalQueue == null) + { + itemRemovalQueue = new List(); + } + itemRemovalQueue.Add(itemToRemove); + } + + /// + /// Play the animation. + /// + internal void SetupCoreAndPlayAnimation() + { + if (EnabledCoreAnimation()) + { + SetupCoreAnimation(); + + NUILog.Debug("LayoutController Playing, Core Duration:" + coreAnimation.Duration); + coreAnimation.Play(); + } + } + + /// + /// Check if layout animation is needed + /// + private bool EnabledCoreAnimation() + { + return layoutTransitionDataQueue.Count > 0 && !OverrideCoreAnimation; + } + + /// + /// Set up the animation from each LayoutItems position data. + /// Iterates the transition stack, adding an Animator to the core animation. + /// + private void SetupCoreAnimation() + { + NUILog.Debug("LayoutController SetupCoreAnimation for:" + layoutTransitionDataQueue.Count); + + if (!coreAnimation) + { + coreAnimation = new Animation(); + coreAnimation.EndAction = Animation.EndActions.StopFinal; + coreAnimation.Finished += AnimationFinished; + } + + // Iterate all items that have been queued for repositioning. + foreach (var layoutPositionData in layoutTransitionDataQueue) + { + AddAnimatorsToAnimation(layoutPositionData); + } + // transitions have now been applied, clear stack, ready for new transitions on + // next layout traversal. + layoutTransitionDataQueue.Clear(); + } + + + private void SetupAnimationForCustomTransitions(TransitionList transitionsToAnimate, View view) + { + if (transitionsToAnimate?.Count > 0) + { + foreach (LayoutTransition transition in transitionsToAnimate) + { + if (transition.AnimatableProperty != AnimatableProperties.Position && + transition.AnimatableProperty != AnimatableProperties.Size) + { + coreAnimation.AnimateTo(view, + transition.AnimatableProperty.ToString(), + transition.TargetValue, + transition.Animator.Delay, + transition.Animator.Duration, + transition.Animator.AlphaFunction); + + NUILog.Debug("LayoutController SetupAnimationForCustomTransitions View:" + view.Name + + " Property:" + transition.AnimatableProperty.ToString() + + " delay:" + transition.Animator.Delay + + " duration:" + transition.Animator.Duration); + } + } + } + } + + /// + /// Iterate transitions and replace Position Components if replacements found in list. + /// + private void FindAndReplaceAnimatorComponentsForProperty(TransitionList sourceTransitionList, + AnimatableProperties propertyToMatch, + ref TransitionComponents transitionComponentToUpdate) + { + foreach (LayoutTransition transition in sourceTransitionList) + { + if (transition.AnimatableProperty == propertyToMatch) + { + // Matched property to animate is for the propertyToMatch so use provided Animator. + transitionComponentToUpdate = transition.Animator; + } + } + } + + private TransitionComponents CreateDefaultTransitionComponent(int delay, int duration) + { + AlphaFunction alphaFunction = new AlphaFunction(AlphaFunction.BuiltinFunctions.Linear); + return new TransitionComponents(delay, duration, alphaFunction); + } + + /// + /// Sets up the main animation with the animators for each item (each layoutPositionData structure) + /// + private void AddAnimatorsToAnimation(LayoutData layoutPositionData) + { + LayoutTransition positionTransition = new LayoutTransition(); + LayoutTransition sizeTransition = new LayoutTransition(); + TransitionCondition conditionForAnimators = layoutPositionData.ConditionForAnimation; + + // LayoutChanged transitions overrides ChangeOnAdd and ChangeOnRemove as siblings will + // reposition to the new layout not to the insertion/removal of a sibling. + if (layoutPositionData.ConditionForAnimation.HasFlag(TransitionCondition.LayoutChanged)) + { + conditionForAnimators = TransitionCondition.LayoutChanged; + } + + // Set up a default transitions, will be overwritten if inherited from parent or set explicitly. + TransitionComponents positionTransitionComponents = CreateDefaultTransitionComponent(0, 300); + TransitionComponents sizeTransitionComponents = CreateDefaultTransitionComponent(0, 300); + + bool matchedCustomTransitions = false; + + + TransitionList transitionsForCurrentCondition = new TransitionList(); + // Note, Transitions set on View rather than LayoutItem so if the Layout changes the transition persist. + + // Check if item to animate has it's own Transitions for this condition. + // If a key exists then a List of at least 1 transition exists. + if (layoutPositionData.Item.Owner.LayoutTransitions.ContainsKey(conditionForAnimators)) + { + // Child has transitions for the condition + matchedCustomTransitions = layoutPositionData.Item.Owner.LayoutTransitions.TryGetValue(conditionForAnimators, out transitionsForCurrentCondition); + } + + if (!matchedCustomTransitions) + { + // Inherit parent transitions as none already set on View for the condition. + ILayoutParent layoutParent = layoutPositionData.Item.GetParent(); + if (layoutParent != null) + { + // Item doesn't have it's own transitions for this condition so copy parents if + // has a parent with transitions. + LayoutGroup layoutGroup = layoutParent as LayoutGroup; + TransitionList parentTransitionList; + // Note TryGetValue returns null if key not matched. + if (layoutGroup != null && layoutGroup.Owner.LayoutTransitions.TryGetValue(conditionForAnimators, out parentTransitionList)) + { + // Copy parent transitions to temporary TransitionList. List contains transitions for the current condition. + LayoutTransitionsHelper.CopyTransitions(parentTransitionList, + transitionsForCurrentCondition); + } + } + } + + + // Position/Size transitions can be displayed for a layout changing to another layout or an item being added or removed. + + // There can only be one position transition and one size position, they will be replaced if set multiple times. + // transitionsForCurrentCondition represent all non position (custom) properties that should be animated. + + // Search for Position property in the transitionsForCurrentCondition list of custom transitions, + // and only use the particular parts of the animator as custom transitions should not effect all parameters of Position. + // Typically Delay, Duration and Alphafunction can be custom. + FindAndReplaceAnimatorComponentsForProperty(transitionsForCurrentCondition, + AnimatableProperties.Position, + ref positionTransitionComponents); + + // Size + FindAndReplaceAnimatorComponentsForProperty(transitionsForCurrentCondition, + AnimatableProperties.Size, + ref sizeTransitionComponents); + + // Add animators to the core Animation, + + SetupAnimationForCustomTransitions(transitionsForCurrentCondition, layoutPositionData.Item.Owner); + + SetupAnimationForPosition(layoutPositionData, positionTransitionComponents); + + SetupAnimationForSize(layoutPositionData, sizeTransitionComponents); + + // Dispose components + positionTransitionComponents.Dispose(); + sizeTransitionComponents.Dispose(); + } + + private void AnimationFinished(object sender, EventArgs e) + { + // Iterate list of LayoutItem that were set for removal. + // Now the core animation has finished their Views can be removed. + if (itemRemovalQueue != null) + { + foreach (LayoutItem item in itemRemovalQueue) + { + // Check incase the parent was already removed and the Owner was + // removed already. + if (item.Owner) + { + // Check again incase the parent has already been removed. + if (item.GetParent() is LayoutGroup layoutGroup) + { + layoutGroup.Owner?.RemoveChild(item.Owner); + } + + } + } + itemRemovalQueue.Clear(); + // If LayoutItems added to stack whilst the core animation is playing + // they would have been cleared here. + // Could have another stack to be added to whilst the animation is running. + // After the running stack is cleared it can be populated with the content + // of the other stack. Then the main removal stack iterated when AnimationFinished + // occurs again. + } + NUILog.Debug("LayoutController AnimationFinished"); + coreAnimation?.Clear(); + } + + private void SetupAnimationForPosition(LayoutData layoutPositionData, TransitionComponents positionTransitionComponents) + { + // A removed item does not have a valid target position within the layout so don't try to position. + if (layoutPositionData.ConditionForAnimation != TransitionCondition.Remove) + { + var vector = new Vector3(layoutPositionData.Left, + layoutPositionData.Top, + layoutPositionData.Item.Owner.Position.Z); + coreAnimation.AnimateTo(layoutPositionData.Item.Owner, "Position", + vector, + positionTransitionComponents.Delay, + positionTransitionComponents.Duration, + positionTransitionComponents.AlphaFunction); + + NUILog.Debug("LayoutController SetupAnimationForPosition View:" + layoutPositionData.Item.Owner.Name + + " left:" + layoutPositionData.Left + + " top:" + layoutPositionData.Top + + " delay:" + positionTransitionComponents.Delay + + " duration:" + positionTransitionComponents.Duration); + vector.Dispose(); + vector = null; + } + } + + private void SetupAnimationForSize(LayoutData layoutPositionData, TransitionComponents sizeTransitionComponents) + { + // Text size cant be animated so is set to it's final size. + // It is due to the internals of the Text not being able to recalculate fast enough. + if (layoutPositionData.Item.Owner is TextLabel || layoutPositionData.Item.Owner is TextField) + { + float itemWidth = layoutPositionData.Right - layoutPositionData.Left; + float itemHeight = layoutPositionData.Bottom - layoutPositionData.Top; + // Set size directly. + layoutPositionData.Item.Owner.Size2D = new Size2D((int)itemWidth, (int)itemHeight); + } + else + { + var vector = new Vector3(layoutPositionData.Right - layoutPositionData.Left, + layoutPositionData.Bottom - layoutPositionData.Top, + layoutPositionData.Item.Owner.Position.Z); + coreAnimation.AnimateTo(layoutPositionData.Item.Owner, "Size", + vector, + sizeTransitionComponents.Delay, + sizeTransitionComponents.Duration, + sizeTransitionComponents.AlphaFunction); + + NUILog.Debug("LayoutController SetupAnimationForSize View:" + layoutPositionData.Item.Owner.Name + + " width:" + (layoutPositionData.Right - layoutPositionData.Left) + + " height:" + (layoutPositionData.Bottom - layoutPositionData.Top) + + " delay:" + sizeTransitionComponents.Delay + + " duration:" + sizeTransitionComponents.Duration); + vector.Dispose(); + vector = null; + } + } + } +}