Krzysztof Krysiński преди 4 седмици
родител
ревизия
ddc3554f1f

+ 6 - 0
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/NestedDocumentNode.cs

@@ -441,6 +441,12 @@ public class NestedDocumentNode : LayerNode, IInputDependentOutputs, ITransforma
         return new NestedDocumentNode() { TransformationMatrix = this.TransformationMatrix };
     }
 
+    public override void Dispose()
+    {
+        Graph.Value = null; // Prevent disposing nested document's graph
+        base.Dispose();
+    }
+
     private bool AnyConnectionExists()
     {
         foreach (var output in OutputProperties)

+ 2 - 1
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/RenderNode.cs

@@ -13,6 +13,7 @@ namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
 
 public abstract class RenderNode : Node, IHighDpiRenderNode
 {
+    public const string OutputPropertyName = "Output";
     public RenderOutputProperty Output { get; }
 
     public bool AllowHighDpiRendering { get; set; } = false;
@@ -26,7 +27,7 @@ public abstract class RenderNode : Node, IHighDpiRenderNode
     public RenderNode()
     {
         Painter painter = new Painter(Paint);
-        Output = CreateRenderOutput("Output", "OUTPUT",
+        Output = CreateRenderOutput(OutputPropertyName, "OUTPUT",
             () => painter,
             () => this is IRenderInput renderInput ? renderInput.Background.Value : null);
     }

+ 12 - 0
src/PixiEditor/Helpers/DocumentViewModelBuilder.cs

@@ -446,6 +446,18 @@ internal class NodeGraphBuilder
         return node;
     }
 
+    public NodeBuilder WithNodeOfType(Type nodeType, out int id)
+    {
+        var node = new NodeBuilder();
+        node.WithUniqueNodeName(nodeType.GetCustomAttribute<NodeInfoAttribute>().UniqueName);
+
+        AllNodes.Add(node);
+
+        id = AllNodes.Count;
+
+        return node;
+    }
+
     public NodeBuilder WithNodeOfType<T>(out int id) where T : IReadOnlyNode
     {
         NodeBuilder builder = this.WithNodeOfType(typeof(T))

+ 37 - 0
src/PixiEditor/Models/DocumentModels/Public/DocumentOperationsModule.cs

@@ -23,6 +23,8 @@ using PixiEditor.Models.Tools;
 using Drawie.Numerics;
 using PixiEditor.ChangeableDocument.Changeables;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
+using PixiEditor.Helpers;
+using PixiEditor.ViewModels.Document;
 using PixiEditor.ViewModels.Nodes;
 
 namespace PixiEditor.Models.DocumentModels.Public;
@@ -1099,4 +1101,39 @@ internal class DocumentOperationsModule : IDocumentOperations
     {
         Internals.ActionAccumulator.AddFinishedActions(new DebugRecordFrame_PassthroughAction());
     }
+
+    public void CreateNestedDocumentFromMember(Guid memberId)
+    {
+        if (Internals.ChangeController.IsBlockingChangeActive)
+            return;
+
+        Internals.ChangeController.TryStopActiveExecutor();
+
+
+        var member = Document.StructureHelper.FindNode<IStructureMemberHandler>(memberId);
+        if (member is null)
+        {
+            return;
+        }
+
+        Guid referenceId = Guid.NewGuid();
+        var embedded = DocumentViewModel.Build(builder =>
+            builder.WithSize(Document.SizeBindable).WithGraph(graph => graph.WithOutputNode(null, null)));
+        embedded.Operations.ImportMember(memberId, Document);
+        embedded.Operations.InvokeCustomAction(() =>
+        {
+            using var block = StartChangeBlock();
+            Guid? nestedDocId = CreateStructureMember(StructureMemberType.Document, member.NodeNameBindable);
+
+            if (nestedDocId is null)
+            {
+                embedded.Dispose();
+                return;
+            }
+
+            Internals.ActionAccumulator.AddActions(new UpdatePropertyValue_Action(nestedDocId.Value, NestedDocumentNode.DocumentPropertyName, new DocumentReference(null, referenceId, embedded.AccessInternalReadOnlyDocument())), new EndUpdatePropertyValue_Action());
+            MoveStructureMember(nestedDocId.Value, memberId, StructureMemberPlacement.Above);
+            DeleteStructureMember(memberId);
+        });
+    }
 }

+ 10 - 0
src/PixiEditor/ViewModels/SubViewModels/LayersViewModel.cs

@@ -256,6 +256,16 @@ internal class LayersViewModel : SubViewModel<ViewModelMain>
         nestedDocVm.Document.Operations.UnlinkNestedDocument(nestedDocVm.Id);
     }
 
+    [Command.Internal("PixiEditor.Layer.CreateNestedFromLayer")]
+    public void CreateNestedFromLayer(Guid layerGuid)
+    {
+        var doc = Owner.DocumentManagerSubViewModel.ActiveDocument;
+        if (doc is null)
+            return;
+
+        doc.Operations.CreateNestedDocumentFromMember(layerGuid);
+    }
+
     [Evaluator.CanExecute("PixiEditor.Layer.SelectedMemberIsLayer",
         nameof(DocumentManagerViewModel.ActiveDocument), nameof(DocumentViewModel.SelectedStructureMember))]
     public bool SelectedMemberIsLayer(object property)

+ 2 - 0
src/PixiEditor/Views/Layers/LayerControl.axaml

@@ -232,6 +232,8 @@
                           Command="{xaml:Command PixiEditor.Layer.UnlinkNestedDocument}" />
                 <MenuItem ui:Translator.Key="RELINK" IsVisible="{Binding $parent[UserControl].Layer.IsLinked, FallbackValue=False}"
                           Command="{Binding $parent[UserControl].Layer.RelinkWithDialogCommand}" />
+                <MenuItem ui:Translator.Key="TO_SMART_LAYER" Command="{xaml:Command PixiEditor.Layer.CreateNestedFromLayer, UseProvided=True}"
+                          CommandParameter="{Binding $parent[UserControl].Layer.Id}" />
             </ContextMenu>
         </Border.ContextMenu>
     </Border>