Browse Source

ExportZoneNode wip

Krzysztof Krysiński 3 months ago
parent
commit
4908662b47

+ 3 - 5
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/CustomOutputNode.cs → src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Workspace/CustomOutputNode.cs

@@ -1,11 +1,9 @@
-using PixiEditor.ChangeableDocument.Changeables.Animations;
+using Drawie.Backend.Core.Surfaces;
+using Drawie.Numerics;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
 using PixiEditor.ChangeableDocument.Rendering;
-using Drawie.Backend.Core;
-using Drawie.Backend.Core.Surfaces;
-using Drawie.Numerics;
 
-namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
+namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Workspace;
 
 [NodeInfo("CustomOutput")]
 public class CustomOutputNode : Node, IRenderInput, IPreviewRenderable

+ 35 - 0
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/Workspace/ExportZoneNode.cs

@@ -0,0 +1,35 @@
+using Drawie.Numerics;
+using PixiEditor.ChangeableDocument.Rendering;
+
+namespace PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Workspace;
+
+[NodeInfo("ExportZone")]
+public class ExportZoneNode : Node
+{
+    public const string IsDefaultName = "IsDefault";
+    public const string SizeName = "Size";
+    public const string OffsetName = "Offset";
+    public InputProperty<string> Name { get; }
+    public InputProperty<VecI> Offset { get; }
+    public InputProperty<VecI> Size { get; }
+    public InputProperty<bool> IsDefault { get; }
+
+    public ExportZoneNode()
+    {
+        Name = CreateInput<string>("Name", "NAME", string.Empty);
+        Offset = CreateInput<VecI>(OffsetName, "POSITION", VecI.Zero);
+        Size = CreateInput<VecI>(SizeName, "SIZE", VecI.One);
+        IsDefault = CreateInput<bool>(IsDefaultName, "IS_DEFAULT", false);
+    }
+
+    protected override void OnExecute(RenderContext context)
+    {
+        // This node is used to define the export zone, so it doesn't need to do anything in the execution phase.
+        // The export zone is defined by the position and size inputs.
+    }
+
+    public override Node CreateCopy()
+    {
+        return new ExportZoneNode();
+    }
+}

+ 1 - 0
src/PixiEditor.ChangeableDocument/Rendering/RenderingUtils.cs

@@ -1,6 +1,7 @@
 using PixiEditor.ChangeableDocument.Changeables.Graph;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
+using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Workspace;
 using PixiEditor.ChangeableDocument.Changeables.Interfaces;
 
 namespace PixiEditor.ChangeableDocument.Rendering;

+ 4 - 1
src/PixiEditor/Data/Localization/Languages/en.json

@@ -1037,5 +1037,8 @@
    "AUTOSAVE_OPEN_FOLDER_DESCRIPTIVE": "Open the folder where autosaves are stored",
   "AUTOSAVE_TOGGLE_DESCRIPTIVE": "Enable/disable autosave",
   "ERROR_GRAPH": "Graph Setup produced an error. Fix it the node graph",
-  "COLOR_MATRIX_FILTER_NODE": "Color Matrix Filter"
+  "COLOR_MATRIX_FILTER_NODE": "Color Matrix Filter",
+  "WORKSPACE": "Workspace",
+  "EXPORT_ZONE_NODE": "Export Zone",
+  "IS_DEFAULT": "Is default"
 }

+ 1 - 0
src/PixiEditor/Models/DocumentModels/DocumentUpdater.cs

@@ -24,6 +24,7 @@ using PixiEditor.Models.Handlers;
 using PixiEditor.Models.Layers;
 using Drawie.Numerics;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Context;
+using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Workspace;
 using PixiEditor.Models.Dialogs;
 using PixiEditor.Models.DocumentModels.UpdateableChangeExecutors.Features;
 using PixiEditor.ViewModels.Document;

+ 32 - 0
src/PixiEditor/ViewModels/Document/DocumentViewModel.cs

@@ -51,11 +51,13 @@ using PixiEditor.Models.Serialization.Factories;
 using PixiEditor.Models.Structures;
 using PixiEditor.Models.Tools;
 using Drawie.Numerics;
+using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Workspace;
 using PixiEditor.ChangeableDocument.ChangeInfos.NodeGraph;
 using PixiEditor.Models.IO;
 using PixiEditor.Parser;
 using PixiEditor.Parser.Skia;
 using PixiEditor.ViewModels.Document.Nodes;
+using PixiEditor.ViewModels.Document.Nodes.Workspace;
 using PixiEditor.ViewModels.Document.TransformOverlays;
 using PixiEditor.Views.Overlays.SymmetryOverlay;
 using BlendMode = Drawie.Backend.Core.Surfaces.BlendMode;
@@ -600,6 +602,36 @@ internal partial class DocumentViewModel : PixiObservableObject, IDocument
         }
     }
 
+    public RectI GetDefaultRenderZone()
+    {
+        // TODO: This should be a part of the ChangeableDocument
+
+        var exportNodes = NodeGraph.AllNodes.Where(
+            x => x is ExportZoneNodeViewModel exportZone
+                 && exportZone.Inputs.Any(x => x is { PropertyName: ExportZoneNode.IsDefaultName, Value: true })).ToArray();
+
+        if (exportNodes.Length == 0)
+            return new RectI(VecI.Zero, SizeBindable);
+
+        var exportNode = exportNodes.FirstOrDefault();
+
+        if (exportNode is null)
+            return new RectI(VecI.Zero, SizeBindable);
+
+        var exportSize = exportNode.Inputs.FirstOrDefault(x => x.PropertyName == ExportZoneNode.SizeName);
+
+        if (exportSize is null)
+            return new RectI(VecI.Zero, SizeBindable);
+
+        if (exportSize.Value is VecI finalSize)
+        {
+            VecI offset = exportNode.Inputs.FirstOrDefault(x => x.PropertyName == ExportZoneNode.OffsetName)?.ComputedValue as VecI? ?? VecI.Zero;
+            return new RectI(offset, finalSize);
+        }
+
+        return new RectI(VecI.Zero, SizeBindable);
+    }
+
     public ICrossDocumentPipe<T> ShareNode<T>(Guid layerId) where T : class, IReadOnlyNode
     {
         return Internals.Tracker.Document.CreateNodePipe<T>(layerId);

+ 1 - 0
src/PixiEditor/ViewModels/Document/NodeGraphViewModel.cs

@@ -12,6 +12,7 @@ using PixiEditor.ChangeableDocument.ChangeInfos.NodeGraph;
 using PixiEditor.Models.DocumentModels;
 using PixiEditor.Models.Handlers;
 using Drawie.Numerics;
+using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Workspace;
 using PixiEditor.ViewModels.Nodes;
 
 namespace PixiEditor.ViewModels.Document;

+ 0 - 8
src/PixiEditor/ViewModels/Document/Nodes/CustomOutputNodeViewModel.cs

@@ -1,8 +0,0 @@
-using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
-using PixiEditor.Extensions.Common.Localization;
-using PixiEditor.ViewModels.Nodes;
-
-namespace PixiEditor.ViewModels.Document.Nodes;
-
-[NodeViewModel("CUSTOM_OUTPUT_NODE", null, "\uE81A")]
-internal class CustomOutputNodeViewModel : NodeViewModel<CustomOutputNode>;

+ 7 - 0
src/PixiEditor/ViewModels/Document/Nodes/Workspace/CustomOutputNodeViewModel.cs

@@ -0,0 +1,7 @@
+using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Workspace;
+using PixiEditor.ViewModels.Nodes;
+
+namespace PixiEditor.ViewModels.Document.Nodes.Workspace;
+
+[NodeViewModel("CUSTOM_OUTPUT_NODE", "WORKSPACE", "\uE81A")]
+internal class CustomOutputNodeViewModel : NodeViewModel<CustomOutputNode>;

+ 11 - 0
src/PixiEditor/ViewModels/Document/Nodes/Workspace/ExportZoneNodeViewModel.cs

@@ -0,0 +1,11 @@
+using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Workspace;
+using PixiEditor.UI.Common.Fonts;
+using PixiEditor.ViewModels.Nodes;
+
+namespace PixiEditor.ViewModels.Document.Nodes.Workspace;
+
+[NodeViewModel("EXPORT_ZONE_NODE", "WORKSPACE", PixiPerfectIcons.CanvasResize)]
+internal class ExportZoneNodeViewModel : NodeViewModel<ExportZoneNode>
+{
+
+}

+ 1 - 1
src/PixiEditor/ViewModels/SubViewModels/FileViewModel.cs

@@ -589,7 +589,7 @@ internal class FileViewModel : SubViewModel<ViewModelMain>
             if (doc is null)
                 return;
 
-            ExportFileDialog info = new ExportFileDialog(MainWindow.Current, doc.SizeBindable, doc)
+            ExportFileDialog info = new ExportFileDialog(MainWindow.Current, doc)
             {
                 SuggestedName = Path.GetFileNameWithoutExtension(doc.FileName)
             };

+ 32 - 3
src/PixiEditor/Views/Dialogs/ExportFileDialog.cs

@@ -20,16 +20,21 @@ internal class ExportFileDialog : CustomDialog
 
     private int fileWidth;
 
+    private int offsetX;
+    private int offsetY;
+
     private string suggestedName;
     
     private DocumentViewModel document;
     
     public ExportConfig ExportConfig { get; set; } = new ExportConfig(VecI.Zero);
 
-    public ExportFileDialog(Window owner, VecI size, DocumentViewModel doc) : base(owner)
+    public ExportFileDialog(Window owner, DocumentViewModel doc) : base(owner)
     {
-        FileWidth = size.X;
-        FileHeight = size.Y;
+        RectI zone = doc.GetDefaultRenderZone();
+        FileWidth = zone.Width;
+        FileHeight = zone.Height;
+
         document = doc;
     }
 
@@ -69,6 +74,30 @@ internal class ExportFileDialog : CustomDialog
         }
     }
 
+    public int OffsetX
+    {
+        get => offsetX;
+        set
+        {
+            if (offsetX != value)
+            {
+                this.SetProperty(ref offsetX, value);
+            }
+        }
+    }
+
+    public int OffsetY
+    {
+        get => offsetY;
+        set
+        {
+            if (offsetY != value)
+            {
+                this.SetProperty(ref offsetY, value);
+            }
+        }
+    }
+
     public IoFileType ChosenFormat
     {
         get => _chosenFormat;

+ 9 - 0
src/PixiEditor/Views/Dialogs/ExportFilePopup.axaml.cs

@@ -63,6 +63,15 @@ internal partial class ExportFilePopup : PixiEditorPopup
         AvaloniaProperty.Register<ExportFilePopup, int>(
             nameof(SpriteSheetRows), 1);
 
+    public static readonly StyledProperty<string> ExportZoneProperty = AvaloniaProperty.Register<ExportFilePopup, string>(
+        nameof(ExportZone));
+
+    public string ExportZone
+    {
+        get => GetValue(ExportZoneProperty);
+        set => SetValue(ExportZoneProperty, value);
+    }
+
     public int SpriteSheetRows
     {
         get => GetValue(SpriteSheetRowsProperty);