public static bool Perform(string data, RowLocation location) { if (!CanPaste(data, location)) { return(false); } Frame frame; try { var stream = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(data)); frame = Serialization.ReadObject <Frame>(Document.Current.Path, stream); } catch (System.Exception e) { Debug.Write(e); return(false); } FolderItemLocation folderLocation; if (location.ParentRow.Rows.Count > 0) { folderLocation = Row.GetFolderItemLocation(location.ParentRow.Rows[location.Index]); folderLocation.Index++; } else { folderLocation = new FolderItemLocation { Index = 0, Folder = location.ParentRow.Components.Get <FolderRow>().Folder }; } if (!folderLocation.Folder.Expanded) { SetProperty.Perform(folderLocation.Folder, nameof(Folder.Expanded), true); } var items = frame.RootFolder().Items.ToList(); foreach (var n in items.OfType <Node>()) { Document.Current.Decorate(n); } frame.RootFolder().Items.Clear(); frame.RootFolder().SyncDescriptorsAndNodes(frame); ClearRowSelection.Perform(); while (items.Count > 0) { var item = items.First(); var bone = item as Bone; if (bone != null) { if (bone.BaseIndex != 0) { continue; } var newIndex = Document.Current.Container.Nodes.OfType <Bone>().Max(b => b.Index) + 1; var children = BoneUtils.FindBoneDescendats(bone, items.OfType <Bone>()).ToList(); var map = new Dictionary <int, int>(); map.Add(bone.Index, newIndex); bone.BaseIndex = location.ParentRow.Components.Get <BoneRow>()?.Bone.Index ?? 0; bone.Index = newIndex; InsertFolderItem.Perform( Document.Current.Container, folderLocation, bone); folderLocation.Index++; foreach (var b in children) { b.BaseIndex = map[b.BaseIndex]; map.Add(b.Index, b.Index = ++newIndex); InsertFolderItem.Perform( Document.Current.Container, folderLocation, b); folderLocation.Index++; items.Remove(b); } Document.Current.Container.RootFolder().SyncDescriptorsAndNodes(Document.Current.Container); SortBonesInChain.Perform(bone); SelectRow.Perform(Document.Current.GetRowForObject(item)); } else { if (!location.ParentRow.Components.Contains <BoneRow>()) { InsertFolderItem.Perform( Document.Current.Container, folderLocation, item); folderLocation.Index++; SelectRow.Perform(Document.Current.GetRowForObject(item)); } } items.Remove(item); } return(true); }
public static bool PasteNodes(string data, RowLocation location, Vector2?mousePosition) { bool CanPaste() { // We are support only paste into folders for now. return(location.ParentRow.Components.Contains <FolderRow>() || location.ParentRow.Components.Contains <BoneRow>()); } if (!CanPaste()) { return(false); } Frame frame; try { var stream = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(data)); frame = TangerinePersistence.Instance.ReadObject <Frame>(Document.Current.Path, stream); } catch (System.Exception e) { Debug.Write(e); return(false); } var animators = frame.Animators; var items = frame.RootFolder().Items.Where(item => NodeCompositionValidator.IsCopyPasteAllowed(item.GetType())).ToList(); if (items.Count == 0) { if (animators.Count != 0) { foreach (var row in Document.Current.TopLevelSelectedRows().ToList()) { if (!(row.Components.Get <NodeRow>()?.Node is IAnimationHost animable)) { continue; } Document.Current.History.DoTransaction(() => { foreach (var animator in animators) { if (animable.GetType().GetProperty(animator.TargetPropertyPath) == null) { continue; } foreach (var keyframe in animator.Keys) { SetKeyframe.Perform(animable, animator.TargetPropertyPath, animator.AnimationId, keyframe); } } }); } } return(true); } var folderLocation = location.ParentRow.Rows.Count > 0 ? Row.GetFolderItemLocation(location.ParentRow.Rows[location.Index]) : new FolderItemLocation { Index = 0, Folder = location.ParentRow.Components.Get <FolderRow>().Folder }; if (!folderLocation.Folder.Expanded) { SetProperty.Perform(folderLocation.Folder, nameof(Folder.Expanded), true); } mousePosition *= Document.Current.Container.AsWidget?.LocalToWorldTransform.CalcInversed(); var shift = mousePosition - items.OfType <Widget>().FirstOrDefault()?.Position; foreach (var n in items.OfType <Node>()) { Document.Current.Decorate(n); } if (shift.HasValue) { foreach (var w in items.OfType <Widget>()) { w.Position += shift.Value; } } frame.RootFolder().Items.Clear(); frame.RootFolder().SyncDescriptorsAndNodes(frame); ClearRowSelection.Perform(); while (items.Count > 0) { var item = items.First(); if (item is Bone bone) { if (bone.BaseIndex != 0) { continue; } var newIndex = 1; var bones = Document.Current.Container.Nodes.OfType <Bone>(); if (bones.Any()) { newIndex = bones.Max(b => b.Index) + 1; } var children = BoneUtils.FindBoneDescendats(bone, items.OfType <Bone>()).ToList(); var map = new Dictionary <int, int> { { bone.Index, newIndex } }; bone.BaseIndex = location.ParentRow.Components.Get <BoneRow>()?.Bone.Index ?? 0; bone.Index = newIndex; InsertFolderItem.Perform( Document.Current.Container, folderLocation, bone); folderLocation.Index++; foreach (var b in children) { b.BaseIndex = map[b.BaseIndex]; map.Add(b.Index, b.Index = ++newIndex); InsertFolderItem.Perform( Document.Current.Container, folderLocation, b); folderLocation.Index++; items.Remove(b); } Document.Current.Container.RootFolder().SyncDescriptorsAndNodes(Document.Current.Container); SortBonesInChain.Perform(bone); SelectRow.Perform(Document.Current.GetRowForObject(item)); } else { if (!location.ParentRow.Components.Contains <BoneRow>()) { InsertFolderItem.Perform( Document.Current.Container, folderLocation, item); folderLocation.Index++; SelectRow.Perform(Document.Current.GetRowForObject(item)); } } items.Remove(item); } return(true); }