public override void ExecuteTransaction() { var nodes = Document.Current?.SelectedNodes().Editable().ToList(); if (nodes.Count != 1) { AlertDialog.Show("Please, select a single node"); return; } if (!(nodes[0] is Widget w && NodeCompositionValidator.CanHaveChildren(w.GetType()) && Document.Current != null)) { AlertDialog.Show($"Can't inline {nodes[0].GetType()}"); return; } var node = nodes[0]; var clone = node.Clone(); clone.ContentsPath = null; var location = Document.Current.Container.RootFolder().Find(node); UnlinkFolderItem.Perform(Document.Current.Container, node); InsertFolderItem.Perform(Document.Current.Container, location, clone); }
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); } } } }
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); }