Example #1
0
        public IEnumerator <object> Task()
        {
            var g = Timeline.Instance.Globals;

            while (true)
            {
                var rq = g.Get <DragKeyframesRequest>();
                if (rq != null)
                {
                    Document.Current.History.DoTransaction(() => {
                        Operations.DragKeyframes.Perform(rq.Offset, rq.RemoveOriginals);
                        Operations.ShiftGridSelection.Perform(rq.Offset);
                        if (rq.Offset.Y != 0)
                        {
                            var selected = Document.Current.SelectedRows().Where(r => r.Selected).Select(r => r.Index).ToDictionary(x => x);
                            ClearRowSelection.Perform();
                            foreach (var row in Document.Current.Rows)
                            {
                                if (selected.ContainsKey(row.Index - rq.Offset.Y))
                                {
                                    SelectRow.Perform(row, select: true);
                                }
                            }
                        }
                        g.Remove <DragKeyframesRequest>();
                    });
                }
                yield return(null);
            }
        }
Example #2
0
        public override void ExecuteTransaction()
        {
            var groups = Document.Current?.SelectedNodes().OfType <Frame>().ToList();

            if (groups?.Count == 0)
            {
                return;
            }
            var container = (Widget)Document.Current.Container;
            var p         = container.RootFolder().Find(groups[0]);

            ClearRowSelection.Perform();
            UntieWidgetsFromBones.Perform(Document.Current.Container.Nodes.OfType <Bone>(), groups);
            foreach (var group in groups)
            {
                UnlinkFolderItem.Perform(container, group);
            }

            foreach (var group in groups)
            {
                var flipXFactor            = group.Scale.X < 0 ? -1 : 1;
                var flipYFactor            = group.Scale.Y < 0 ? -1 : 1;
                var flipVector             = Vector2.Right + Vector2.Down * flipXFactor * flipYFactor;
                var groupRootBones         = new List <Bone>();
                var groupNodes             = group.Nodes.ToList().Where(GroupNodes.IsValidNode).ToList();
                var localToParentTransform = group.CalcLocalToParentTransform();
                foreach (var node in groupNodes)
                {
                    UnlinkFolderItem.Perform(group, node);
                    InsertFolderItem.Perform(container, p, node);
                    SelectNode.Perform(node);
                    p.Index++;
                    if (node is Widget)
                    {
                        GroupNodes.TransformPropertyAndKeyframes <Vector2>(node, nameof(Widget.Position), v => localToParentTransform * v);
                        GroupNodes.TransformPropertyAndKeyframes <Vector2>(node, nameof(Widget.Scale), v => v * group.Scale);
                        GroupNodes.TransformPropertyAndKeyframes <float>(node, nameof(Widget.Rotation),
                                                                         v => v * Mathf.Sign(group.Scale.X * group.Scale.Y) + group.Rotation);
                        GroupNodes.TransformPropertyAndKeyframes <Color4>(node, nameof(Widget.Color), v => group.Color * v);
                    }
                    else if (node is Bone)
                    {
                        var root = BoneUtils.FindBoneRoot((Bone)node, groupNodes);
                        if (!groupRootBones.Contains(root))
                        {
                            GroupNodes.TransformPropertyAndKeyframes <Vector2>(node, nameof(Bone.Position), v => localToParentTransform * v);
                            GroupNodes.TransformPropertyAndKeyframes <float>(node, nameof(Bone.Rotation),
                                                                             v => (Matrix32.Rotation(v * Mathf.DegToRad) * localToParentTransform).ToTransform2().Rotation);
                            groupRootBones.Add(root);
                        }
                        else if (flipVector != Vector2.One)
                        {
                            GroupNodes.TransformPropertyAndKeyframes <Vector2>(node, nameof(Bone.Position), v => v * flipVector);
                            GroupNodes.TransformPropertyAndKeyframes <float>(node, nameof(Bone.Rotation), v => - v);
                        }
                        GroupNodes.TransformPropertyAndKeyframes <Vector2>(node, nameof(Bone.RefPosition), v => localToParentTransform * v);
                        GroupNodes.TransformPropertyAndKeyframes <float>(node, nameof(Bone.RefRotation),
                                                                         v => (Matrix32.Rotation(v * Mathf.DegToRad) * localToParentTransform).ToTransform2().Rotation);
                    }
                }
            }
        }
Example #3
0
        public override void ExecuteTransaction()
        {
            var selectedNodes = Document.Current.SelectedNodes().Where(IsValidNode).ToList();

            if (!Utils.CalcHullAndPivot(selectedNodes, out var hull, out _))
            {
                return;
            }

            hull = hull.Transform(Document.Current.Container.AsWidget.LocalToWorldTransform.CalcInversed());
            var aabb      = hull.ToAABB();
            var container = Document.Current.Container;

            foreach (var row in Document.Current.SelectedRows())
            {
                if (row.Components.Contains <BoneRow>())
                {
                    var boneRow = row.Components.Get <BoneRow>();
                    if (!boneRow.ChildrenExpanded)
                    {
                        selectedNodes.AddRange(BoneUtils.FindBoneDescendats(boneRow.Bone, container.Nodes.OfType <Bone>()));
                    }
                }
            }
            var selectedBones = selectedNodes.OfType <Bone>().ToList();

            var   loc = container.RootFolder().Find(selectedNodes[0]);
            Frame group;

            try {
                group = (Frame)Core.Operations.CreateNode.Perform(container, loc, typeof(Frame));
            } catch (InvalidOperationException e) {
                AlertDialog.Show(e.Message);
                return;
            }
            group.Id       = selectedNodes[0].Id + "Group";
            group.Pivot    = Vector2.Half;
            group.Position = aabb.Center;
            group.Size     = aabb.Size;
            var bonesExceptSelected = container.Nodes.Except(selectedNodes).OfType <Bone>().ToList();

            UntieWidgetsFromBones.Perform(bonesExceptSelected, selectedNodes.OfType <Widget>());
            UntieWidgetsFromBones.Perform(selectedBones, container.Nodes.Except(selectedNodes).OfType <Widget>());
            var nodeKeyframesDict = new Dictionary <Node, BoneAnimationData>();
            var localRoots        = new List <Bone>();

            foreach (var bone in BoneUtils.SortBones(container.Nodes.OfType <Bone>()))
            {
                Bone localRoot;
                var  delta          = Vector2.Zero;
                var  isSelectedBone = selectedBones.Contains(bone);
                if (isSelectedBone)
                {
                    localRoot = BoneUtils.FindBoneRoot(bone, selectedNodes);
                    delta     = -aabb.A;
                }
                else
                {
                    localRoot = BoneUtils.FindBoneRoot(bone, bonesExceptSelected);
                }
                if (!localRoots.Contains(localRoot))
                {
                    if (!isSelectedBone && localRoot.BaseIndex == 0)
                    {
                        localRoots.Add(localRoot);
                        continue;
                    }
                    nodeKeyframesDict.Add(localRoot, EvaluateBoneAnimationUsingParent(localRoot, v => v + delta));
                    localRoots.Add(localRoot);
                }
            }
            SetKeyframes(nodeKeyframesDict);
            foreach (var n in selectedNodes)
            {
                UnlinkFolderItem.Perform(container, n);
            }
            int i = 0;

            foreach (var node in selectedNodes)
            {
                InsertFolderItem.Perform(group, new FolderItemLocation(group.RootFolder(), i++), node);
                if (node is Widget)
                {
                    TransformPropertyAndKeyframes <Vector2>(node, nameof(Widget.Position), v => v - aabb.A);
                }
                if (node is Bone)
                {
                    TransformPropertyAndKeyframes <Vector2>(node, nameof(Bone.RefPosition), v => v - aabb.A);
                }
            }
            group.DefaultAnimation.Frame = container.DefaultAnimation.Frame;
            ClearRowSelection.Perform();
            SelectNode.Perform(group);
        }
Example #4
0
        public IEnumerator <object> Task()
        {
            Probers.Add(new BoneRowProber());
            Probers.Add(new FolderRowProber());
            Probers.Add(new NodeRowProber());
            Probers.Add(new AnimationTrackRowProber());
            var roll  = Timeline.Instance.Roll;
            var input = roll.RootWidget.Input;

            var cg = new ClickGesture(0, () => {
                var row = RowUnderMouse(input.MousePosition);
                if (row == null)
                {
                    return;
                }
                if (input.IsKeyPressed(Key.Shift))
                {
                    if (Document.Current.SelectedRows().Any())
                    {
                        var firstRow = Document.Current.SelectedRows().FirstOrDefault();
                        Document.Current.History.DoTransaction(() => {
                            ClearRowSelection.Perform();
                            SelectRowRange.Perform(firstRow, row);
                        });
                    }
                    else
                    {
                        Document.Current.History.DoTransaction(() => {
                            ClearRowSelection.Perform();
                            SelectRow.Perform(row);
                        });
                    }
                }
                else if (input.IsKeyPressed(Key.Control))
                {
                    Document.Current.History.DoTransaction(() => {
                        SelectRow.Perform(row, !row.Selected);
                    });
                }
                else
                {
                    Document.Current.History.DoTransaction(() => {
                        ClearRowSelection.Perform();
                        SelectRow.Perform(row);
                    });
                    input.ConsumeKey(Key.Mouse0);
                }
            });

            var dg = new DragGesture(0);

            dg.Recognized += () => {
                var row = RowUnderMouse(dg.MousePressPosition);
                // Have to turn off PreviewAnimation manually in order
                // to provide the same behaviour whether widget is selected or not
                // (PreviewAnimation is turned off when performing operation)
                if (Document.Current.PreviewAnimation)
                {
                    Document.Current.TogglePreviewAnimation();
                }
                if (!row?.Selected ?? false)
                {
                    Document.Current.History.DoTransaction(() => {
                        ClearRowSelection.Perform();
                        SelectRow.Perform(row);
                    });
                }
                roll.OnRenderOverlay += OnRollRenderOverlay;
                dragLocation          = new RowLocation(Document.Current.RowTree, 0);
            };
            dg.Changed += () => {
                dragLocation = MouseToRowLocation(input.MousePosition);
                CommonWindow.Current.Invalidate();
            };
            dg.Ended += () => {
                if (!dg.IsRecognizing())
                {
                    roll.OnRenderOverlay -= OnRollRenderOverlay;
                    CommonWindow.Current.Invalidate();
                    if (dragLocation != null)
                    {
                        DragRows(dragLocation.Value);
                    }
                }
            };

            roll.RootWidget.Gestures.Add(dg);
            roll.RootWidget.Gestures.Add(cg);
            yield break;
        }
Example #5
0
        private static void InternalExpand(bool recursive = false)
        {
            void ExpandOrCollapseRow(Row row, object component, string property, bool expanded, int level)
            {
                if (!recursive)
                {
                    SetProperty.Perform(component, property, expanded, isChangingDocument: false);
                }
                else if (expanded)
                {
                    SetProperty.Perform(component, property, expanded, isChangingDocument: false);
                    foreach (var child in row.Rows.ToList())
                    {
                        SetExpanded(child, expanded, level);
                    }
                }
                else
                {
                    foreach (var child in row.Rows.ToList())
                    {
                        SetExpanded(child, expanded, level);
                    }
                    SetProperty.Perform(component, property, expanded, isChangingDocument: false);
                }
            }

            var processedRows = new HashSet <Row>();

            void SetExpanded(Row row, bool expanded = false, int level = 0)
            {
                if (processedRows.Contains(row))
                {
                    return;
                }

                processedRows.Add(row);
                foreach (var component in row.Components)
                {
                    switch (component)
                    {
                    case NodeRow nodeRow:
                        ExpandOrCollapseRow(row, nodeRow, nameof(NodeRow.Expanded), expanded, level + 1);
                        if (nodeRow.Expanded && row.Rows.Count > 0)
                        {
                            Timeline.Instance.EnsureRowChildsVisible(row);
                        }
                        break;

                    case BoneRow boneRow:
                        if (boneRow.HaveChildren)
                        {
                            ExpandOrCollapseRow(row, boneRow, nameof(BoneRow.ChildrenExpanded), expanded, level + 1);
                            if (boneRow.ChildrenExpanded)
                            {
                                Timeline.Instance.EnsureRowChildsVisible(row);
                            }
                        }
                        else if (row.Parent.Parent != null)
                        {
                            SetExpanded(row.Parent, expanded, level);
                            if (level == 0)
                            {
                                Core.Operations.SelectRow.Perform(row, select: false);
                                Core.Operations.SelectRow.Perform(row.Parent, select: true);
                            }
                        }
                        return;

                    case FolderRow folderRow:
                        var folder = folderRow.Folder;
                        if (folder.Items.Count > 0)
                        {
                            ExpandOrCollapseRow(row, folder, nameof(Folder.Expanded), expanded, level + 1);
                            if (folder.Expanded)
                            {
                                Timeline.Instance.EnsureRowChildsVisible(row);
                            }
                        }
                        return;

                    case PropertyRow propertyRow:
                        SetExpanded(row.Parent, expanded, level);
                        if (level == 0)
                        {
                            Core.Operations.SelectRow.Perform(row, select: false);
                            Core.Operations.SelectRow.Perform(row.Parent, select: true);
                        }
                        return;
                    }
                }
            }

            var topMostRows = new HashSet <Row>(Document.Current.SelectedRows());

            foreach (var row in Document.Current.SelectedRows())
            {
                for (var p = row.Parent; p != null; p = p.Parent)
                {
                    if (topMostRows.Contains(p))
                    {
                        topMostRows.Remove(row);
                        break;
                    }
                }
            }

            ClearRowSelection.Perform();
            foreach (var row in topMostRows)
            {
                Core.Operations.SelectRow.Perform(row);
                SetExpanded(row, expanded: !IsRowExpanded(row));
            }
        }
        public IEnumerator <object> Task()
        {
            var roll  = Timeline.Instance.Roll;
            var input = roll.RootWidget.Input;

            input.AcceptMouseThroughDescendants = true;
            while (true)
            {
                yield return(null);

                if (!input.WasMousePressed() || input.WasKeyPressed(Key.Mouse0DoubleClick))
                {
                    continue;
                }
                var initialMousePosition = input.MousePosition;
                var row = RowUnderMouse(initialMousePosition);
                if (row == null)
                {
                    continue;
                }
                if (input.IsKeyPressed(Key.Shift))
                {
                    if (Document.Current.SelectedRows().Any())
                    {
                        var firstRow = Document.Current.SelectedRows().FirstOrDefault();
                        Document.Current.History.DoTransaction(() => {
                            ClearRowSelection.Perform();
                            SelectRowRange.Perform(firstRow, row);
                        });
                    }
                    else
                    {
                        Document.Current.History.DoTransaction(() => {
                            ClearRowSelection.Perform();
                            SelectRow.Perform(row);
                        });
                    }
                }
                else if (input.IsKeyPressed(Key.Control))
                {
                    Document.Current.History.DoTransaction(() => {
                        SelectRow.Perform(row, !row.Selected);
                    });
                }
                else
                {
                    if (!row.Selected)
                    {
                        Document.Current.History.DoTransaction(() => {
                            ClearRowSelection.Perform();
                            SelectRow.Perform(row);
                        });
                    }
                    while (
                        input.IsMousePressed() &&
                        Math.Abs(initialMousePosition.Y - input.MousePosition.Y) < TimelineMetrics.DefaultRowHeight / 4
                        )
                    {
                        yield return(null);
                    }
                    if (input.IsMousePressed())
                    {
                        yield return(DragTask());
                    }
                    else
                    {
                        Document.Current.History.DoTransaction(() => {
                            ClearRowSelection.Perform();
                            SelectRow.Perform(row);
                        });
                    }
                }
            }
        }