/// <summary>
        /// Updates view field animator.
        /// </summary>
        public void UpdateViewFieldAnimator()
        {
            //Debug.Log(String.Format("Updating View Field Animator: {0}: {1}, {2}", Field, From, To));
            if (From != null && From is String)
            {
                FromStringValue = (String)From;
            }

            if (To != null && To is String)
            {
                ToStringValue = (String)To;
            }

            if (_viewFieldAnimator == null)
            {
                _viewFieldAnimator = new ViewFieldAnimator();
            }

            _viewFieldAnimator.EasingFunction  = EasingFunction;
            _viewFieldAnimator.AutoReset       = AutoReset;
            _viewFieldAnimator.AutoReverse     = AutoReverse;
            _viewFieldAnimator.Field           = Field;
            _viewFieldAnimator.From            = From;
            _viewFieldAnimator.To              = To;
            _viewFieldAnimator.FromStringValue = FromStringValue;
            _viewFieldAnimator.ToStringValue   = ToStringValue;
            _viewFieldAnimator.ReverseSpeed    = ReverseSpeed;
            _viewFieldAnimator.Duration        = Duration;
            _viewFieldAnimator.StartOffset     = StartOffset;

            var view = Target != null ? Target :
                       (Parent != null ? Parent : null);

            _viewFieldAnimator.TargetView = view;
        }
        /// <summary>
        /// Called when animation completed.
        /// </summary>
        void _viewFieldAnimator_Completed(ViewFieldAnimator viewFieldAnimator)
        {
            AnimationCompleted.Trigger();

            // notify parent
            if (LayoutParent is ViewAnimation)
            {
                (LayoutParent as ViewAnimation).ChildAnimationCompleted();
            }
        }
        /// <summary>
        /// Initializes the view.
        /// </summary>
        public override void Initialize()
        {
            base.Initialize();
            _viewFieldAnimator = new ViewFieldAnimator();
            UpdateViewFieldAnimator();

            _viewFieldAnimator.Started   += _viewFieldAnimator_Started;
            _viewFieldAnimator.Completed += _viewFieldAnimator_Completed;
            _viewFieldAnimator.Paused    += _viewFieldAnimator_Paused;
            _viewFieldAnimator.Resumed   += _viewFieldAnimator_Resumed;
            _viewFieldAnimator.Stopped   += _viewFieldAnimator_Stopped;
            _viewFieldAnimator.Reversed  += _viewFieldAnimator_Reversed;
        }
        /// <summary>
        /// Updates menu views and offset animators.
        /// </summary>
        public void UpdateMenu()
        {
            _menuAnimators.Clear();
            int activeChildCount = _menuItems.Count() - _deactivatedMenuItems.Count();

            if (activeChildCount > 0)
            {
                float deltaAngle = Mathf.Deg2Rad * ((EndAngle - StartAngle) / activeChildCount);
                float angle      = Mathf.Deg2Rad * StartAngle;

                foreach (var child in _menuItems)
                {
                    if (_deactivatedMenuItems.Contains(child))
                    {
                        continue;
                    }

                    // calculate offset
                    float xOffset = Radius * Mathf.Sin(angle);
                    float yOffset = Radius * Mathf.Cos(angle);

                    // set offset animator
                    var offsetAnimator = new ViewFieldAnimator();
                    offsetAnimator.EasingFunction = EasingFunctionType.Linear;
                    offsetAnimator.Field          = "OffsetFromParent";
                    offsetAnimator.From           = new ElementMargin(_menuOffset.x, _menuOffset.y);
                    offsetAnimator.To             = new ElementMargin(xOffset + _menuOffset.x, -yOffset + _menuOffset.y, 0, 0);
                    offsetAnimator.Duration       = AnimationDuration.IsSet ? AnimationDuration : 0.2f;
                    offsetAnimator.TargetView     = child;
                    _menuAnimators.Add(offsetAnimator);

                    child.OffsetFromParent.DirectValue = new ElementMargin(_menuOffset.x, _menuOffset.y, 0, 0);
                    child.Alignment.DirectValue        = ElementAlignment.Center;
                    child.Deactivate();
                    child.LayoutChanged();
                    angle += deltaAngle;
                }
            }

            foreach (var deactivatedItem in _deactivatedMenuItems)
            {
                deactivatedItem.Deactivate();
                deactivatedItem.LayoutChanged();
            }
        }
 /// <summary>
 /// Called when animation resumed.
 /// </summary>
 void _viewFieldAnimator_Resumed(ViewFieldAnimator viewFieldAnimator)
 {
     AnimationResumed.Trigger();
 }
 /// <summary>
 /// Called when animation stopped.
 /// </summary>
 void _viewFieldAnimator_Stopped(ViewFieldAnimator viewFieldAnimator)
 {
     AnimationStopped.Trigger();
 }
 /// <summary>
 /// Called when animation paused.
 /// </summary>
 void _viewFieldAnimator_Paused(ViewFieldAnimator viewFieldAnimator)
 {
     AnimationPaused.Trigger();
 }