示例#1
0
        void SetKeyframe(bool value)
        {
            int currentFrame = Document.Current.AnimationFrame;

            foreach (var(animable, owner) in editorParams.RootObjects.Zip(editorParams.Objects, (ro, o) => (ro as IAnimationHost, o)))
            {
                bool hasKey = false;
                if (animable.Animators.TryFind(editorParams.PropertyPath, out IAnimator animator, Document.Current.AnimationId))
                {
                    hasKey = animator.ReadonlyKeys.Any(i => i.Frame == currentFrame);
                    if (hasKey && !value)
                    {
                        Core.Operations.RemoveKeyframe.Perform(animator, currentFrame);
                    }
                }

                if (!hasKey && value)
                {
                    var propValue = editorParams.IndexInList == -1
                                                ? new Property(owner, editorParams.PropertyName).Getter()
                                                : new IndexedProperty(owner, editorParams.PropertyName, editorParams.IndexInList).Getter();
                    var keyFunction = animator?.Keys.LastOrDefault(k => k.Frame <= currentFrame)?.Function ??
                                      CoreUserPreferences.Instance.DefaultKeyFunction;
                    IKeyframe keyframe = Keyframe.CreateForType(editorParams.PropertyInfo.PropertyType, currentFrame, propValue, keyFunction);
                    Core.Operations.SetKeyframe.Perform(animable, editorParams.PropertyPath, Document.Current.AnimationId, keyframe);
                }
            }
        }
示例#2
0
        void SetKeyframe(bool value)
        {
            int currentFrame = Document.Current.AnimationFrame;

            foreach (var animable in editorParams.Objects.OfType <IAnimable>())
            {
                IAnimator animator;
                bool      hasKey = false;

                if (animable.Animators.TryFind(editorParams.PropertyName, out animator, Document.Current.AnimationId))
                {
                    hasKey = animator.ReadonlyKeys.Any(i => i.Frame == currentFrame);
                    if (hasKey && !value)
                    {
                        Core.Operations.RemoveKeyframe.Perform(animator, currentFrame);
                    }
                }

                if (!hasKey && value)
                {
                    var propValue = new Property(animable, editorParams.PropertyName).Getter();
                    if (animator == null)
                    {
                        animator = AnimatorRegistry.Instance.CreateAnimator(editorParams.PropertyInfo.PropertyType);
                        animator.TargetProperty = editorParams.PropertyName;
                        animator.AnimationId    = Document.Current.AnimationId;
                        Core.Operations.SetAnimator.Perform(animable, animator);
                    }
                    var       keyFunction = animator.Keys.LastOrDefault(k => k.Frame < currentFrame)?.Function ?? KeyFunction.Linear;
                    IKeyframe keyframe    = Keyframe.CreateForType(editorParams.PropertyInfo.PropertyType, currentFrame, propValue, keyFunction);

                    Core.Operations.SetKeyframe.Perform(animable, editorParams.PropertyName, Document.Current.AnimationId, keyframe);
                }
            }
        }
示例#3
0
        public static void Perform(object @object, string propertyPath, object value, bool createAnimatorIfNeeded = false, bool createInitialKeyframeForNewAnimator = true, int atFrame = -1)
        {
            IAnimator animator;
            var       animationHost = @object as IAnimationHost;
            object    owner         = @object;
            int       index         = -1;

            AnimationUtils.PropertyData propertyData = AnimationUtils.PropertyData.Empty;
            if (animationHost != null)
            {
                (propertyData, owner, index) = AnimationUtils.GetPropertyByPath(animationHost, propertyPath);
            }
            if (index == -1)
            {
                SetProperty.Perform(owner, propertyData.Info?.Name ?? propertyPath, value);
            }
            else
            {
                SetIndexedProperty.Perform(owner, propertyData.Info?.Name ?? propertyPath, index, value);
            }
            if (animationHost != null && (animationHost.Animators.TryFind(propertyPath, out animator, Document.Current.AnimationId) || createAnimatorIfNeeded))
            {
                if (animator == null && createInitialKeyframeForNewAnimator)
                {
                    var propertyValue = propertyData.Info.GetValue(owner);
                    Perform(animationHost, propertyPath, propertyValue, true, false, 0);
                }

                int savedFrame = -1;
                if (atFrame >= 0 && Document.Current.AnimationFrame != atFrame)
                {
                    savedFrame = Document.Current.AnimationFrame;
                    Document.Current.AnimationFrame = atFrame;
                }

                try {
                    var type = propertyData.Info.PropertyType;
                    var key  =
                        animator?.ReadonlyKeys.GetByFrame(Document.Current.AnimationFrame)?.Clone() ??
                        Keyframe.CreateForType(type);
                    key.Frame    = Document.Current.AnimationFrame;
                    key.Function = animator?.Keys.LastOrDefault(k => k.Frame <= key.Frame)?.Function ?? KeyFunction.Linear;
                    key.Value    = value;
                    SetKeyframe.Perform(animationHost, propertyPath, Document.Current.AnimationId, key);
                } finally {
                    if (savedFrame >= 0)
                    {
                        Document.Current.AnimationFrame = savedFrame;
                    }
                }
            }
        }
示例#4
0
        public static void Perform(object @object, string propertyName, object value)
        {
            SetProperty.Perform(@object, propertyName, value);
            IAnimator animator;
            var       animable = @object as IAnimable;

            if (animable != null && animable.Animators.TryFind(propertyName, out animator, Document.Current.AnimationId))
            {
                var type = animable.GetType().GetProperty(propertyName).PropertyType;
                var key  =
                    animator.ReadonlyKeys.FirstOrDefault(i => i.Frame == Document.Current.AnimationFrame)?.Clone() ??
                    Keyframe.CreateForType(type);
                key.Frame    = Document.Current.AnimationFrame;
                key.Function = animator.Keys.LastOrDefault(k => k.Frame < key.Frame)?.Function ?? KeyFunction.Linear;
                key.Value    = value;
                SetKeyframe.Perform(animable, propertyName, Document.Current.AnimationId, key);
            }
        }
示例#5
0
        private void ShowContextMenu()
        {
            SelectAnimationBasedOnMousePosition();
            var menu     = new Menu();
            var rootNode = Document.Current.RootNode;

            menu.Add(new Command("Add", () => AddAnimation(rootNode, false)));
            menu.Add(new Command("Add Compound", () => AddAnimation(rootNode, true)));
            menu.Add(new Command("Add ZeroPose", () => AddZeroPoseAnimation(rootNode))
            {
                Enabled = !rootNode.Animations.TryFind(Animation.ZeroPoseId, out _)
            });
            var path = GetNodePath(Document.Current.Container);

            if (!string.IsNullOrEmpty(path))
            {
                var container = Document.Current.Container;
                menu.Add(new Command($"Add To '{path}'", () => AddAnimation(container, false)));
                menu.Add(new Command($"Add Compound To '{path}'", () => AddAnimation(container, true)));
                menu.Add(new Command($"Add ZeroPose To '{path}'", () => AddZeroPoseAnimation(container))
                {
                    Enabled = !container.Animations.TryFind(Animation.ZeroPoseId, out _)
                });
            }
            menu.Add(Command.MenuSeparator);
            menu.Add(new Command("Rename", RenameAnimation));
            menu.Add(new Command("Duplicate", DuplicateAnimation));
            menu.Add(Command.Delete);
            menu.Popup();

            void AddAnimation(Node node, bool compound)
            {
                Document.Current.History.DoTransaction(() => {
                    var animation = new Animation {
                        Id = GenerateAnimationId("NewAnimation"), IsCompound = compound
                    };
                    Core.Operations.InsertIntoList.Perform(node.Animations, node.Animations.Count, animation);
                    SelectAnimation(GetAnimations().IndexOf(animation));
                    if (compound)
                    {
                        var track = new AnimationTrack {
                            Id = "Track1"
                        };
                        Core.Operations.InsertIntoList <AnimationTrackList, AnimationTrack> .Perform(animation.Tracks, 0, track);
                    }
                });
                // Schedule animation rename on the next update, since the widgets are not built yet
                panelWidget.Tasks.Add(DelayedRenameAnimation());
            }

            void AddZeroPoseAnimation(Node node)
            {
                Document.Current.History.DoTransaction(() => {
                    var animation = new Animation {
                        Id = Animation.ZeroPoseId
                    };
                    InsertIntoList.Perform(node.Animations, node.Animations.Count, animation);
                    foreach (var a in node.Descendants.SelectMany(n => n.Animators).ToList())
                    {
                        var(propertyData, animable, index) =
                            AnimationUtils.GetPropertyByPath(a.Owner, a.TargetPropertyPath);
                        var zeroPoseKey   = Keyframe.CreateForType(propertyData.Info.PropertyType);
                        zeroPoseKey.Value = index == -1
                                                        ? propertyData.Info.GetValue(animable)
                                                        : propertyData.Info.GetValue(animable, new object[] { index });
                        zeroPoseKey.Function = KeyFunction.Steep;
                        SetKeyframe.Perform(a.Owner, a.TargetPropertyPath, Animation.ZeroPoseId, zeroPoseKey);
                    }
                    SelectAnimation(GetAnimations().IndexOf(animation));
                });
            }

            IEnumerator <object> DelayedRenameAnimation()
            {
                yield return(null);

                RenameAnimation();
            }
        }