Browse Source

Merge pull request #710 from PixiEditor/fixes/02.01.2025

Fixes/02.01.2025
Krzysztof Krysiński 7 months ago
parent
commit
7086fa1b46

+ 1 - 1
src/PixiDocks

@@ -1 +1 @@
-Subproject commit 42b1f6939f7b56726ed6aba09e49897b507f569d
+Subproject commit 1bbf5698bd734cb263a364b6d08f52a9f004dec8

+ 5 - 2
src/PixiEditor.Beta/PixiEditor.Beta.csproj

@@ -8,9 +8,12 @@
     <Nullable>disable</Nullable>
     <Nullable>disable</Nullable>
     <PublishTrimmed>true</PublishTrimmed>
     <PublishTrimmed>true</PublishTrimmed>
     <WasmSingleFileBundle>true</WasmSingleFileBundle>
     <WasmSingleFileBundle>true</WasmSingleFileBundle>
+    <EventSourceSupport>false</EventSourceSupport>
+    <UseSystemResourceKeys>true</UseSystemResourceKeys>
+    <EnableUnsafeUTF7Encoding>false</EnableUnsafeUTF7Encoding>
+    <HttpActivityPropagationSupport>false</HttpActivityPropagationSupport>
+    <DebuggerSupport>false</DebuggerSupport>
     <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
     <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
-    <!--TODO: Temp solution, make it properly build by build system and copy to target dir on publish-->
-    <PixiExtOutputPath>$(MSBuildProjectDirectory)\..\PixiEditor\Extensions</PixiExtOutputPath>
     <ValidateExecutableReferencesMatchSelfContained>false</ValidateExecutableReferencesMatchSelfContained>
     <ValidateExecutableReferencesMatchSelfContained>false</ValidateExecutableReferencesMatchSelfContained>
     <RootNamespace>PixiEditor.Beta</RootNamespace>
     <RootNamespace>PixiEditor.Beta</RootNamespace>
   </PropertyGroup>
   </PropertyGroup>

+ 1 - 1
src/PixiEditor.Beta/extension.json

@@ -2,7 +2,7 @@
   "displayName": "PixiEditor Beta",
   "displayName": "PixiEditor Beta",
   "uniqueName": "PixiEditor.Beta",
   "uniqueName": "PixiEditor.Beta",
   "description": "Open Beta of PixiEditor 2.0",
   "description": "Open Beta of PixiEditor 2.0",
-  "version": "1.0.0",
+  "version": "1.0.1",
   "author": {
   "author": {
     "name": "PixiEditor",
     "name": "PixiEditor",
     "email": "[email protected]",
     "email": "[email protected]",

+ 62 - 3
src/PixiEditor.Builder/build/Program.cs

@@ -23,6 +23,8 @@ public class BuildContext : FrostingContext
 {
 {
     public string PathToProject { get; set; } = "../PixiEditor/PixiEditor.csproj";
     public string PathToProject { get; set; } = "../PixiEditor/PixiEditor.csproj";
 
 
+    public string[] ExtensionProjectsToInclude { get; set; } = [];
+
     public string CrashReportWebhookUrl { get; set; }
     public string CrashReportWebhookUrl { get; set; }
 
 
     public string AnalyticsUrl { get; set; }
     public string AnalyticsUrl { get; set; }
@@ -34,7 +36,7 @@ public class BuildContext : FrostingContext
     public string OutputDirectory { get; set; } = "Builds";
     public string OutputDirectory { get; set; } = "Builds";
 
 
     public bool SelfContained { get; set; } = false;
     public bool SelfContained { get; set; } = false;
-    
+
     public string Runtime { get; set; }
     public string Runtime { get; set; }
 
 
     public BuildContext(ICakeContext context)
     public BuildContext(ICakeContext context)
@@ -49,6 +51,12 @@ public class BuildContext : FrostingContext
             PathToProject = context.Arguments.GetArgument("project-path");
             PathToProject = context.Arguments.GetArgument("project-path");
         }
         }
 
 
+        bool hasCustomExtensionProjects = context.Arguments.HasArgument("extension-projects");
+        if (hasCustomExtensionProjects)
+        {
+            ExtensionProjectsToInclude = context.Arguments.GetArgument("extension-projects").Split(';');
+        }
+
         bool hasCustomConfiguration = context.Arguments.HasArgument("build-configuration");
         bool hasCustomConfiguration = context.Arguments.HasArgument("build-configuration");
         if (hasCustomConfiguration)
         if (hasCustomConfiguration)
         {
         {
@@ -60,7 +68,7 @@ public class BuildContext : FrostingContext
         {
         {
             OutputDirectory = context.Arguments.GetArgument("o");
             OutputDirectory = context.Arguments.GetArgument("o");
         }
         }
-        
+
         bool hasSelfContained = context.Arguments.HasArgument("self-contained");
         bool hasSelfContained = context.Arguments.HasArgument("self-contained");
         if (hasSelfContained)
         if (hasSelfContained)
         {
         {
@@ -80,7 +88,7 @@ public class BuildContext : FrostingContext
 }
 }
 
 
 [TaskName("Default")]
 [TaskName("Default")]
-[IsDependentOn(typeof(BuildProjectTask))]
+[IsDependentOn(typeof(CopyExtensionsTask))]
 public sealed class DefaultTask : FrostingTask<BuildContext>
 public sealed class DefaultTask : FrostingTask<BuildContext>
 {
 {
     public override void Run(BuildContext context)
     public override void Run(BuildContext context)
@@ -144,3 +152,54 @@ public sealed class BuildProjectTask : FrostingTask<BuildContext>
         File.WriteAllText(constantsPath, context.BackedUpConstants);
         File.WriteAllText(constantsPath, context.BackedUpConstants);
     }
     }
 }
 }
+
+[TaskName("BuildExtensions")]
+[IsDependentOn(typeof(BuildProjectTask))]
+public sealed class BuildExtensionsTask : FrostingTask<BuildContext>
+{
+    public override void Run(BuildContext context)
+    {
+        context.Log.Information("Building extensions...");
+        foreach (var project in context.ExtensionProjectsToInclude)
+        {
+            var settings = new DotNetPublishSettings() { Configuration = context.BuildConfiguration, };
+
+            context.DotNetPublish(project, settings);
+        }
+    }
+}
+
+[TaskName("CopyExtensions")]
+[IsDependentOn(typeof(BuildExtensionsTask))]
+public sealed class CopyExtensionsTask : FrostingTask<BuildContext>
+{
+    public override void Run(BuildContext context)
+    {
+        context.Log.Information("Copying extensions...");
+        foreach (var project in context.ExtensionProjectsToInclude)
+        {
+            string outputDir = Path.Combine(context.OutputDirectory, "Extensions");
+            string sourceDir = Path.Combine(project, "bin",
+                context.BuildConfiguration, "wasi-wasm", "Extensions");
+
+            CopyDirectoryContents(sourceDir, outputDir, context);
+        }
+    }
+
+    private void CopyDirectoryContents(string sourceDir, string targetDir, BuildContext context)
+    {
+        if (!Directory.Exists(targetDir))
+        {
+            Directory.CreateDirectory(targetDir);
+        }
+
+        context.Log.Information($"Copying contents of {sourceDir} to {targetDir}");
+
+        foreach (var file in Directory.GetFiles(sourceDir))
+        {
+            string targetFile = Path.Combine(targetDir, Path.GetFileName(file));
+            context.Log.Information($"Copying {file} to {targetFile}");
+            File.Copy(file, targetFile, true);
+        }
+    }
+}

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changes/Structure/CreateStructureMember_Change.cs

@@ -27,7 +27,7 @@ internal class CreateStructureMember_Change : Change
 
 
     public override bool InitializeAndValidate(Document target)
     public override bool InitializeAndValidate(Document target)
     {
     {
-        if(structureMemberOfType.IsAbstract || structureMemberOfType.IsInterface || !structureMemberOfType.IsAssignableTo(typeof(StructureNode)))
+        if(structureMemberOfType == null || structureMemberOfType.IsAbstract || structureMemberOfType.IsInterface || !structureMemberOfType.IsAssignableTo(typeof(StructureNode)))
             return false;
             return false;
         
         
         return target.TryFindNode<Node>(parentGuid, out _);
         return target.TryFindNode<Node>(parentGuid, out _);

+ 244 - 0
src/PixiEditor.Extensions.Sdk/build/PixiEditor.Extensions.MSPackageBuilder.deps.json

@@ -0,0 +1,244 @@
+{
+  "runtimeTarget": {
+    "name": ".NETStandard,Version=v2.0/",
+    "signature": ""
+  },
+  "compilationOptions": {},
+  "targets": {
+    ".NETStandard,Version=v2.0": {},
+    ".NETStandard,Version=v2.0/": {
+      "PixiEditor.Extensions.MSPackageBuilder/1.0.0": {
+        "dependencies": {
+          "Microsoft.Build.Utilities.Core": "17.12.6",
+          "NETStandard.Library": "2.0.3",
+          "Newtonsoft.Json": "13.0.3",
+          "StyleCop.Analyzers": "1.1.118"
+        },
+        "runtime": {
+          "PixiEditor.Extensions.MSPackageBuilder.dll": {}
+        }
+      },
+      "Microsoft.Build.Framework/17.12.6": {
+        "dependencies": {
+          "Microsoft.Win32.Registry": "5.0.0",
+          "System.Memory": "4.5.5",
+          "System.Runtime.CompilerServices.Unsafe": "6.0.0",
+          "System.Security.Principal.Windows": "5.0.0"
+        }
+      },
+      "Microsoft.Build.Utilities.Core/17.12.6": {
+        "dependencies": {
+          "Microsoft.Build.Framework": "17.12.6",
+          "Microsoft.NET.StringTools": "17.12.6",
+          "Microsoft.Win32.Registry": "5.0.0",
+          "System.Collections.Immutable": "8.0.0",
+          "System.Configuration.ConfigurationManager": "8.0.0",
+          "System.Memory": "4.5.5",
+          "System.Runtime.CompilerServices.Unsafe": "6.0.0",
+          "System.Security.Principal.Windows": "5.0.0",
+          "System.Text.Encoding.CodePages": "7.0.0"
+        }
+      },
+      "Microsoft.NET.StringTools/17.12.6": {
+        "dependencies": {
+          "System.Memory": "4.5.5",
+          "System.Runtime.CompilerServices.Unsafe": "6.0.0"
+        }
+      },
+      "Microsoft.NETCore.Platforms/1.1.0": {},
+      "Microsoft.Win32.Registry/5.0.0": {
+        "dependencies": {
+          "System.Buffers": "4.5.1",
+          "System.Memory": "4.5.5",
+          "System.Security.AccessControl": "5.0.0",
+          "System.Security.Principal.Windows": "5.0.0"
+        }
+      },
+      "NETStandard.Library/2.0.3": {
+        "dependencies": {
+          "Microsoft.NETCore.Platforms": "1.1.0"
+        }
+      },
+      "Newtonsoft.Json/13.0.3": {
+        "runtime": {
+          "lib/netstandard2.0/Newtonsoft.Json.dll": {
+            "assemblyVersion": "13.0.0.0",
+            "fileVersion": "13.0.3.27908"
+          }
+        }
+      },
+      "StyleCop.Analyzers/1.1.118": {},
+      "System.Buffers/4.5.1": {},
+      "System.Collections.Immutable/8.0.0": {
+        "dependencies": {
+          "System.Memory": "4.5.5",
+          "System.Runtime.CompilerServices.Unsafe": "6.0.0"
+        }
+      },
+      "System.Configuration.ConfigurationManager/8.0.0": {
+        "dependencies": {
+          "System.Security.Cryptography.ProtectedData": "8.0.0"
+        }
+      },
+      "System.Memory/4.5.5": {
+        "dependencies": {
+          "System.Buffers": "4.5.1",
+          "System.Numerics.Vectors": "4.4.0",
+          "System.Runtime.CompilerServices.Unsafe": "6.0.0"
+        }
+      },
+      "System.Numerics.Vectors/4.4.0": {},
+      "System.Runtime.CompilerServices.Unsafe/6.0.0": {},
+      "System.Security.AccessControl/5.0.0": {
+        "dependencies": {
+          "System.Security.Principal.Windows": "5.0.0"
+        }
+      },
+      "System.Security.Cryptography.ProtectedData/8.0.0": {
+        "dependencies": {
+          "System.Memory": "4.5.5"
+        }
+      },
+      "System.Security.Principal.Windows/5.0.0": {},
+      "System.Text.Encoding.CodePages/7.0.0": {
+        "dependencies": {
+          "System.Memory": "4.5.5",
+          "System.Runtime.CompilerServices.Unsafe": "6.0.0"
+        }
+      }
+    }
+  },
+  "libraries": {
+    "PixiEditor.Extensions.MSPackageBuilder/1.0.0": {
+      "type": "project",
+      "serviceable": false,
+      "sha512": ""
+    },
+    "Microsoft.Build.Framework/17.12.6": {
+      "type": "package",
+      "serviceable": true,
+      "sha512": "sha512-jleteC0seumLGTmTVwob97lcwPj/dfgzL/V3g/VVcMZgo2Ic7jzdy8AYpByPDh8e3uRq0SjCl6HOFCjhy5GzRQ==",
+      "path": "microsoft.build.framework/17.12.6",
+      "hashPath": "microsoft.build.framework.17.12.6.nupkg.sha512"
+    },
+    "Microsoft.Build.Utilities.Core/17.12.6": {
+      "type": "package",
+      "serviceable": true,
+      "sha512": "sha512-pU3GnHcXp8VRMGKxdJCq+tixfhFn+QwEbpqmZmc/nqFHFyuhlGwjonWZMIWcwuCv/8EHgxoOttFvna1vrN+RrA==",
+      "path": "microsoft.build.utilities.core/17.12.6",
+      "hashPath": "microsoft.build.utilities.core.17.12.6.nupkg.sha512"
+    },
+    "Microsoft.NET.StringTools/17.12.6": {
+      "type": "package",
+      "serviceable": true,
+      "sha512": "sha512-w8Ehofqte5bJoR+Fa3f6JwkwFEkGtXxqvQHGOVOSHDzgNVySvL5FSNhavbQSZ864el9c3rjdLPLAtBW8dq6fmg==",
+      "path": "microsoft.net.stringtools/17.12.6",
+      "hashPath": "microsoft.net.stringtools.17.12.6.nupkg.sha512"
+    },
+    "Microsoft.NETCore.Platforms/1.1.0": {
+      "type": "package",
+      "serviceable": true,
+      "sha512": "sha512-kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==",
+      "path": "microsoft.netcore.platforms/1.1.0",
+      "hashPath": "microsoft.netcore.platforms.1.1.0.nupkg.sha512"
+    },
+    "Microsoft.Win32.Registry/5.0.0": {
+      "type": "package",
+      "serviceable": true,
+      "sha512": "sha512-dDoKi0PnDz31yAyETfRntsLArTlVAVzUzCIvvEDsDsucrl33Dl8pIJG06ePTJTI3tGpeyHS9Cq7Foc/s4EeKcg==",
+      "path": "microsoft.win32.registry/5.0.0",
+      "hashPath": "microsoft.win32.registry.5.0.0.nupkg.sha512"
+    },
+    "NETStandard.Library/2.0.3": {
+      "type": "package",
+      "serviceable": true,
+      "sha512": "sha512-st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==",
+      "path": "netstandard.library/2.0.3",
+      "hashPath": "netstandard.library.2.0.3.nupkg.sha512"
+    },
+    "Newtonsoft.Json/13.0.3": {
+      "type": "package",
+      "serviceable": true,
+      "sha512": "sha512-HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==",
+      "path": "newtonsoft.json/13.0.3",
+      "hashPath": "newtonsoft.json.13.0.3.nupkg.sha512"
+    },
+    "StyleCop.Analyzers/1.1.118": {
+      "type": "package",
+      "serviceable": true,
+      "sha512": "sha512-Onx6ovGSqXSK07n/0eM3ZusiNdB6cIlJdabQhWGgJp3Vooy9AaLS/tigeybOJAobqbtggTamoWndz72JscZBvw==",
+      "path": "stylecop.analyzers/1.1.118",
+      "hashPath": "stylecop.analyzers.1.1.118.nupkg.sha512"
+    },
+    "System.Buffers/4.5.1": {
+      "type": "package",
+      "serviceable": true,
+      "sha512": "sha512-Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==",
+      "path": "system.buffers/4.5.1",
+      "hashPath": "system.buffers.4.5.1.nupkg.sha512"
+    },
+    "System.Collections.Immutable/8.0.0": {
+      "type": "package",
+      "serviceable": true,
+      "sha512": "sha512-AurL6Y5BA1WotzlEvVaIDpqzpIPvYnnldxru8oXJU2yFxFUy3+pNXjXd1ymO+RA0rq0+590Q8gaz2l3Sr7fmqg==",
+      "path": "system.collections.immutable/8.0.0",
+      "hashPath": "system.collections.immutable.8.0.0.nupkg.sha512"
+    },
+    "System.Configuration.ConfigurationManager/8.0.0": {
+      "type": "package",
+      "serviceable": true,
+      "sha512": "sha512-JlYi9XVvIREURRUlGMr1F6vOFLk7YSY4p1vHo4kX3tQ0AGrjqlRWHDi66ImHhy6qwXBG3BJ6Y1QlYQ+Qz6Xgww==",
+      "path": "system.configuration.configurationmanager/8.0.0",
+      "hashPath": "system.configuration.configurationmanager.8.0.0.nupkg.sha512"
+    },
+    "System.Memory/4.5.5": {
+      "type": "package",
+      "serviceable": true,
+      "sha512": "sha512-XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==",
+      "path": "system.memory/4.5.5",
+      "hashPath": "system.memory.4.5.5.nupkg.sha512"
+    },
+    "System.Numerics.Vectors/4.4.0": {
+      "type": "package",
+      "serviceable": true,
+      "sha512": "sha512-UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ==",
+      "path": "system.numerics.vectors/4.4.0",
+      "hashPath": "system.numerics.vectors.4.4.0.nupkg.sha512"
+    },
+    "System.Runtime.CompilerServices.Unsafe/6.0.0": {
+      "type": "package",
+      "serviceable": true,
+      "sha512": "sha512-/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==",
+      "path": "system.runtime.compilerservices.unsafe/6.0.0",
+      "hashPath": "system.runtime.compilerservices.unsafe.6.0.0.nupkg.sha512"
+    },
+    "System.Security.AccessControl/5.0.0": {
+      "type": "package",
+      "serviceable": true,
+      "sha512": "sha512-dagJ1mHZO3Ani8GH0PHpPEe/oYO+rVdbQjvjJkBRNQkX4t0r1iaeGn8+/ybkSLEan3/slM0t59SVdHzuHf2jmw==",
+      "path": "system.security.accesscontrol/5.0.0",
+      "hashPath": "system.security.accesscontrol.5.0.0.nupkg.sha512"
+    },
+    "System.Security.Cryptography.ProtectedData/8.0.0": {
+      "type": "package",
+      "serviceable": true,
+      "sha512": "sha512-+TUFINV2q2ifyXauQXRwy4CiBhqvDEDZeVJU7qfxya4aRYOKzVBpN+4acx25VcPB9ywUN6C0n8drWl110PhZEg==",
+      "path": "system.security.cryptography.protecteddata/8.0.0",
+      "hashPath": "system.security.cryptography.protecteddata.8.0.0.nupkg.sha512"
+    },
+    "System.Security.Principal.Windows/5.0.0": {
+      "type": "package",
+      "serviceable": true,
+      "sha512": "sha512-t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA==",
+      "path": "system.security.principal.windows/5.0.0",
+      "hashPath": "system.security.principal.windows.5.0.0.nupkg.sha512"
+    },
+    "System.Text.Encoding.CodePages/7.0.0": {
+      "type": "package",
+      "serviceable": true,
+      "sha512": "sha512-LSyCblMpvOe0N3E+8e0skHcrIhgV2huaNcjUUEa8hRtgEAm36aGkRoC8Jxlb6Ra6GSfF29ftduPNywin8XolzQ==",
+      "path": "system.text.encoding.codepages/7.0.0",
+      "hashPath": "system.text.encoding.codepages.7.0.0.nupkg.sha512"
+    }
+  }
+}

BIN
src/PixiEditor.Extensions.Sdk/build/PixiEditor.Extensions.MSPackageBuilder.dll


BIN
src/PixiEditor/Extensions/PixiEditor.Beta.pixiext


+ 4 - 0
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/LineExecutor.cs

@@ -164,7 +164,11 @@ internal abstract class LineExecutor<T> : SimpleShapeToolExecutor where T : ILin
     {
     {
         if (!startedDrawing)
         if (!startedDrawing)
         {
         {
+            internals.ActionAccumulator.AddFinishedActions(EndDraw());
+            AddMemberToSnapping();
+            
             base.OnLeftMouseButtonUp(argsPositionOnCanvas);
             base.OnLeftMouseButtonUp(argsPositionOnCanvas);
+            ActiveMode = ShapeToolMode.Preview;
             onEnded!(this);
             onEnded!(this);
             return;
             return;
         }
         }

+ 1 - 1
src/PixiEditor/Models/Handlers/IToolHandler.cs

@@ -52,7 +52,7 @@ internal interface IToolHandler : IHandler
     /// <summary>
     /// <summary>
     ///     Layer type that should be created if no layer is selected incompatible one.
     ///     Layer type that should be created if no layer is selected incompatible one.
     /// </summary>
     /// </summary>
-    public Type LayerTypeToCreateOnEmptyUse { get; }
+    public Type? LayerTypeToCreateOnEmptyUse { get; }
 
 
     public virtual string? DefaultNewLayerName => null;
     public virtual string? DefaultNewLayerName => null;
 
 

+ 0 - 3
src/PixiEditor/PixiEditor.csproj

@@ -132,9 +132,6 @@
     <None Include="../../Third Party Licenses/**" LinkBase="Third Party Licenses/">
     <None Include="../../Third Party Licenses/**" LinkBase="Third Party Licenses/">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </None>
     </None>
-    <None Update="Extensions\PixiEditor.Beta.pixiext">
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </None>
   </ItemGroup>
   </ItemGroup>
 
 
   <ItemGroup>
   <ItemGroup>

+ 0 - 8
src/PixiEditor/ViewModels/Dock/LayoutManager.cs

@@ -66,15 +66,7 @@ internal class LayoutManager
                     First = new DockableArea()
                     First = new DockableArea()
                     {
                     {
                         Id = "DocumentArea", FallbackContent = new CreateDocumentFallbackView(),
                         Id = "DocumentArea", FallbackContent = new CreateDocumentFallbackView(),
-                        Dockables = [ DockContext.CreateDockable(nodeGraphDockViewModel) ]
                     },
                     },
-                    SecondSize = 200,
-                    SplitDirection = DockingDirection.Bottom,
-                    Second = new DockableArea
-                    {
-                        Id = "TimelineArea", 
-                        Dockables = [ DockContext.CreateDockable(timelineDockViewModel) ]
-                    }
                 },
                 },
                 SecondSize = 360,
                 SecondSize = 360,
                 SplitDirection = DockingDirection.Right,
                 SplitDirection = DockingDirection.Right,

+ 11 - 1
src/PixiEditor/ViewModels/Nodes/Properties/GenericEnumPropertyViewModel.cs

@@ -1,4 +1,5 @@
-using PixiEditor.Models.Handlers;
+using System.ComponentModel;
+using PixiEditor.Models.Handlers;
 
 
 namespace PixiEditor.ViewModels.Nodes.Properties;
 namespace PixiEditor.ViewModels.Nodes.Properties;
 
 
@@ -7,6 +8,15 @@ internal class GenericEnumPropertyViewModel : NodePropertyViewModel
     public GenericEnumPropertyViewModel(INodeHandler node, Type propertyType, Type enumType) : base(node, propertyType)
     public GenericEnumPropertyViewModel(INodeHandler node, Type propertyType, Type enumType) : base(node, propertyType)
     {
     {
         Values = Enum.GetValues(enumType);
         Values = Enum.GetValues(enumType);
+        PropertyChanged += OnPropertyChanged;
+    }
+
+    private void OnPropertyChanged(object? sender, PropertyChangedEventArgs e)
+    {
+        if (e.PropertyName == nameof(Value))
+        {
+            OnPropertyChanged(nameof(SelectedIndex));
+        }
     }
     }
 
 
     public Array Values { get; }
     public Array Values { get; }

+ 5 - 0
src/PixiEditor/ViewModels/SubViewModels/ToolsViewModel.cs

@@ -131,9 +131,12 @@ internal class ToolsViewModel : SubViewModel<ViewModelMain>, IToolsHandler
 
 
     public void SetActiveToolSet(IToolSetHandler toolSetHandler)
     public void SetActiveToolSet(IToolSetHandler toolSetHandler)
     {
     {
+        ActiveTool?.OnToolDeselected(false);
         ActiveToolSet = toolSetHandler;
         ActiveToolSet = toolSetHandler;
         ActiveToolSet.ApplyToolSetSettings();
         ActiveToolSet.ApplyToolSetSettings();
         UpdateEnabledState();
         UpdateEnabledState();
+        
+        ActiveTool?.OnToolSelected(false);
     }
     }
 
 
     public void SetupToolsTooltipShortcuts()
     public void SetupToolsTooltipShortcuts()
@@ -382,6 +385,8 @@ internal class ToolsViewModel : SubViewModel<ViewModelMain>, IToolsHandler
 
 
         if (ActiveTool is not { CanBeUsedOnActiveLayer: true })
         if (ActiveTool is not { CanBeUsedOnActiveLayer: true })
         {
         {
+            if(ActiveTool.LayerTypeToCreateOnEmptyUse == null) return;
+            
             Guid? createdLayer = Owner.LayersSubViewModel.NewLayer(
             Guid? createdLayer = Owner.LayersSubViewModel.NewLayer(
                 ActiveTool.LayerTypeToCreateOnEmptyUse,
                 ActiveTool.LayerTypeToCreateOnEmptyUse,
                 ActionSource.Automated,
                 ActionSource.Automated,

+ 2 - 1
src/PixiEditor/Views/LoadingWindow.axaml

@@ -7,7 +7,7 @@
         xmlns:indicators="clr-namespace:PixiEditor.Views.Indicators"
         xmlns:indicators="clr-namespace:PixiEditor.Views.Indicators"
         mc:Ignorable="d" ShowInTaskbar="False" SystemDecorations="None"
         mc:Ignorable="d" ShowInTaskbar="False" SystemDecorations="None"
         CanResize="False" WindowStartupLocation="CenterScreen"
         CanResize="False" WindowStartupLocation="CenterScreen"
-        Title="LoadingWindow" Height="180" Width="160"
+        Title="LoadingWindow" MinHeight="180" MinWidth="160" MaxHeight="180" MaxWidth="160"
         Background="Transparent"
         Background="Transparent"
         x:Name="Window">
         x:Name="Window">
     <Border Background="{StaticResource ThemeBackgroundBrush}"
     <Border Background="{StaticResource ThemeBackgroundBrush}"
@@ -17,6 +17,7 @@
            <indicators:LoadingIndicator/>
            <indicators:LoadingIndicator/>
             <TextBlock Foreground="White" Text="PixiEditor"
             <TextBlock Foreground="White" Text="PixiEditor"
                        FontFamily="Roboto" FontWeight="900" FontSize="28"
                        FontFamily="Roboto" FontWeight="900" FontSize="28"
+                       HorizontalAlignment="Center" 
                        Margin="0,10,0,0"/>
                        Margin="0,10,0,0"/>
         </StackPanel>
         </StackPanel>
     </Border>
     </Border>

+ 2 - 2
src/PixiEditor/Views/LoadingWindow.axaml.cs

@@ -15,10 +15,10 @@ public partial class LoadingWindow : Window
 
 
     public static void ShowInNewThread()
     public static void ShowInNewThread()
     {
     {
-        /*var thread = new Thread(ThreadStart) { IsBackground = true };
+        var thread = new Thread(ThreadStart) { IsBackground = true };
 
 
         thread.SetApartmentState(ApartmentState.STA);
         thread.SetApartmentState(ApartmentState.STA);
-        thread.Start();*/
+        thread.Start();
     }
     }
 
 
     public void SafeClose()
     public void SafeClose()

+ 12 - 0
src/PixiEditor/Views/Nodes/NodeGraphView.cs

@@ -254,6 +254,18 @@ internal class NodeGraphView : Zoombox.Zoombox
                 nodeView.PropertyChanged += NodeView_PropertyChanged;
                 nodeView.PropertyChanged += NodeView_PropertyChanged;
             }
             }
         }
         }
+        
+        if(e.Property == Canvas.LeftProperty || e.Property == Canvas.TopProperty)
+        {
+            if (e.Sender is ContentPresenter presenter && presenter.Child is NodeView nodeView)
+            {
+                Dispatcher.UIThread.Post(
+                    () =>
+                {
+                    UpdateConnections(nodeView);
+                }, DispatcherPriority.Render);
+            }
+        }
     }
     }
 
 
     private void CreateNodeType(NodeTypeInfo nodeType)
     private void CreateNodeType(NodeTypeInfo nodeType)