Browse Source

Merge branch 'master' into func-matrix

Krzysztof Krysiński 1 month ago
parent
commit
375e09f310

+ 1 - 1
samples/Directory.Build.props

@@ -1,7 +1,7 @@
 <Project>
     <PropertyGroup>
         <CodeAnalysisRuleSet>../Custom.ruleset</CodeAnalysisRuleSet>
-		    <AvaloniaVersion>11.3.0</AvaloniaVersion>
+		    <AvaloniaVersion>11.3.2</AvaloniaVersion>
     </PropertyGroup>
     <ItemGroup>
         <PackageReference Include="StyleCop.Analyzers" Version="1.1.118" />

+ 1 - 1
src/ColorPicker

@@ -1 +1 @@
-Subproject commit 66bae8cf20153b9273b10c7d37ac90dc57ef15bb
+Subproject commit 3136a8ee9b682d889df8e3ccd7b793df4e0ead0b

+ 1 - 1
src/Directory.Build.props

@@ -1,7 +1,7 @@
 <Project>
     <PropertyGroup>
         <CodeAnalysisRuleSet>../Custom.ruleset</CodeAnalysisRuleSet>
-		    <AvaloniaVersion>11.3.0</AvaloniaVersion>
+		    <AvaloniaVersion>11.3.2</AvaloniaVersion>
     </PropertyGroup>
     <ItemGroup>
         <PackageReference Include="StyleCop.Analyzers" Version="1.1.118" />

+ 1 - 1
src/Drawie

@@ -1 +1 @@
-Subproject commit 7a2e6d528b0b2c2a4353291170f19e61444eae4e
+Subproject commit 0aaaed404a98c5b482066dce8e02ca62c4242f8c

+ 1 - 1
src/PixiDocks

@@ -1 +1 @@
-Subproject commit c6778bd7a33f799263a64d4b39404e1aa05e9dd0
+Subproject commit daed2f25fbc530e4f6ebed2baedae4f33c4fa3d4

+ 4 - 4
src/PixiEditor/Helpers/SupportedFilesHelper.cs

@@ -53,12 +53,12 @@ internal class SupportedFilesHelper
 
     public static bool IsExtensionSupported(string fileExtension)
     {
-        return AllSupportedExtensions.Contains(fileExtension);
+        return AllSupportedExtensions.Contains(fileExtension, StringComparer.OrdinalIgnoreCase);
     }
     public static IoFileType? ParseImageFormat(string extension)
     {
         var allExts = FileTypes;
-        var fileData = allExts.SingleOrDefault(i => i.Extensions.Contains(extension));
+        var fileData = allExts.SingleOrDefault(i => i.Extensions.Contains(extension, StringComparer.OrdinalIgnoreCase));
         return fileData;
     }
 
@@ -84,7 +84,7 @@ internal class SupportedFilesHelper
             return null;
 
         string extension = Path.GetExtension(file.Path.LocalPath);
-        return allSupportedExtensions.Single(i => i.CanSave && i.Extensions.Contains(extension));
+        return allSupportedExtensions.Single(i => i.CanSave && i.Extensions.Contains(extension, StringComparer.OrdinalIgnoreCase));
     }
 
     public static List<FilePickerFileType> BuildOpenFilter()
@@ -95,6 +95,6 @@ internal class SupportedFilesHelper
 
     public static bool IsRasterFormat(string fileExtension)
     {
-        return FileTypes.Any(i => i.Extensions.Contains(fileExtension) && i.SetKind == FileTypeDialogDataSet.SetKind.Image);
+        return FileTypes.Any(i => i.Extensions.Contains(fileExtension, StringComparer.OrdinalIgnoreCase) && i.SetKind == FileTypeDialogDataSet.SetKind.Image);
     }
 }

+ 12 - 5
src/PixiEditor/Models/Commands/CommandController.cs

@@ -5,9 +5,11 @@ using System.Reflection;
 using System.Threading.Tasks;
 using Avalonia.Input;
 using Avalonia.Media;
+using Avalonia.Threading;
 using Microsoft.Extensions.DependencyInjection;
 using Newtonsoft.Json;
 using PixiEditor.Exceptions;
+using PixiEditor.Helpers;
 using PixiEditor.Helpers.Extensions;
 using PixiEditor.Models.AnalyticsAPI;
 using PixiEditor.Models.Commands.Attributes.Commands;
@@ -21,6 +23,7 @@ using PixiEditor.Models.Input;
 using PixiEditor.Models.Structures;
 using PixiEditor.OperatingSystem;
 using PixiEditor.UI.Common.Localization;
+using PixiEditor.ViewModels;
 using Command = PixiEditor.Models.Commands.Commands.Command;
 using CommandAttribute = PixiEditor.Models.Commands.Attributes.Commands.Command;
 
@@ -446,11 +449,14 @@ internal class CommandController
 
         return;
 
-        static async void ActionOnException(Task faultedTask)
+        static void ActionOnException(Task faultedTask)
         {
-            // since this method is "async void" and not "async Task", the runtime will propagate exceptions out if it
-            // (instead of putting them into the returned task and forgetting about them)
-            await faultedTask; // this instantly throws the exception from the already faulted task
+            if (faultedTask.Exception == null)
+            {
+                return;
+            }
+
+            Dispatcher.UIThread.Post(() => throw faultedTask.Exception); // Re-throw the exception on the UI thread
         }
 
         ValueTask ReportEndTime(Task originalTask)
@@ -706,7 +712,8 @@ internal class CommandController
         if (IOperatingSystem.Current.IsMacOs)
         {
             KeyCombination newCombination = combination;
-            if (combination.Modifiers.HasFlag(KeyModifiers.Control) && !combination.Modifiers.HasFlag(KeyModifiers.Meta))
+            if (combination.Modifiers.HasFlag(KeyModifiers.Control) &&
+                !combination.Modifiers.HasFlag(KeyModifiers.Meta))
             {
                 newCombination.Modifiers &= ~KeyModifiers.Control;
                 newCombination.Modifiers |= KeyModifiers.Meta;

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

@@ -471,6 +471,10 @@ internal class TransformSelectedExecutor : UpdateableChangeExecutor, ITransforma
         }
 
         internals!.ActionAccumulator.AddActions(new EndPreviewShiftLayers_Action());
+        if (!movedOnce)
+        {
+            DoTransform(lastCorners);
+        }
         internals!.ActionAccumulator.AddActions(new EndTransformSelected_Action());
         internals!.ActionAccumulator.AddFinishedActions();
         document!.TransformHandler.HideTransform();

+ 2 - 2
src/PixiEditor/Styles/Templates/NodeView.axaml

@@ -39,7 +39,7 @@
                         </Border>
                         <Border Grid.Row="1" Background="{DynamicResource ThemeControlMidBrush}">
                             <StackPanel>
-                                <ItemsControl ItemsSource="{TemplateBinding Outputs}"
+                                <ItemsControl Name="PART_Outputs" ItemsSource="{TemplateBinding Outputs}"
                                               ClipToBounds="False">
                                     <ItemsControl.ItemContainerTheme>
                                         <ControlTheme TargetType="ContentPresenter">
@@ -47,7 +47,7 @@
                                         </ControlTheme>
                                     </ItemsControl.ItemContainerTheme>
                                 </ItemsControl>
-                                <ItemsControl ItemsSource="{TemplateBinding Inputs}" ClipToBounds="False">
+                                <ItemsControl Name="PART_Inputs" ItemsSource="{TemplateBinding Inputs}" ClipToBounds="False">
                                     <ItemsControl.ItemContainerTheme>
                                         <ControlTheme TargetType="ContentPresenter">
                                             <Setter Property="DataContext" Value="." />

+ 7 - 1
src/PixiEditor/Views/Nodes/ConnectionView.cs

@@ -67,6 +67,7 @@ internal class ConnectionView : TemplatedControl
         set { SetValue(OutputNodePositionProperty, value); }
     }
 
+    private Canvas? mainCanvas;
 
     static ConnectionView()
     {
@@ -102,7 +103,12 @@ internal class ConnectionView : TemplatedControl
             return default;
         }
 
-        Canvas canvas = this.FindAncestorOfType<NodeGraphView>().FindDescendantOfType<Canvas>();
+        if(mainCanvas != null && !mainCanvas.IsAttachedToVisualTree())
+        {
+            mainCanvas = null;
+        }
+
+        Canvas canvas = mainCanvas ??= this.FindAncestorOfType<NodeGraphView>().FindDescendantOfType<Canvas>();
 
         if (property.Node is null || canvas is null)
         {

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

@@ -239,7 +239,6 @@ internal class NodeGraphView : Zoombox.Zoombox
 
         Dispatcher.UIThread.Post(() =>
         {
-            nodeItemsControl.ItemsPanelRoot.Children.CollectionChanged += NodeItems_CollectionChanged;
             nodeViewsCache = nodeItemsControl.ItemsPanelRoot.Children.ToList();
             HandleNodesAdded(nodeViewsCache);
         });

+ 42 - 6
src/PixiEditor/Views/Nodes/NodeView.cs

@@ -1,4 +1,5 @@
 using System.Collections.ObjectModel;
+using System.Collections.Specialized;
 using System.Windows.Input;
 using Avalonia;
 using Avalonia.Controls;
@@ -6,6 +7,7 @@ using Avalonia.Controls.Metadata;
 using Avalonia.Controls.Primitives;
 using Avalonia.Input;
 using Avalonia.Media;
+using Avalonia.Threading;
 using Avalonia.VisualTree;
 using ChunkyImageLib;
 using PixiEditor.Helpers;
@@ -19,6 +21,8 @@ using PixiEditor.Views.Nodes.Properties;
 namespace PixiEditor.Views.Nodes;
 
 [PseudoClasses(":selected")]
+[TemplatePart("PART_Inputs", typeof(ItemsControl))]
+[TemplatePart("PART_Outputs", typeof(ItemsControl))]
 public class NodeView : TemplatedControl
 {
     public static readonly StyledProperty<INodeHandler> NodeProperty =
@@ -155,11 +159,41 @@ public class NodeView : TemplatedControl
     public static readonly StyledProperty<int> ActiveFrameProperty =
         AvaloniaProperty.Register<NodeView, int>("ActiveFrame");
 
+    private Dictionary<INodePropertyHandler, NodePropertyView> propertyViews = new();
+
+    private ItemsControl inputsControl;
+    private ItemsControl outputsControl;
+
     static NodeView()
     {
         IsSelectedProperty.Changed.Subscribe(NodeSelectionChanged);
     }
 
+    protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
+    {
+        base.OnApplyTemplate(e);
+
+        inputsControl = e.NameScope.Find<ItemsControl>("PART_Inputs");
+        outputsControl = e.NameScope.Find<ItemsControl>("PART_Outputs");
+
+        Dispatcher.UIThread.Post(
+            () =>
+        {
+            inputsControl.ItemsPanelRoot.Children.CollectionChanged += ChildrenOnCollectionChanged;
+            outputsControl.ItemsPanelRoot.Children.CollectionChanged += ChildrenOnCollectionChanged;
+
+            propertyViews.Clear();
+            propertyViews = this.GetVisualDescendants().OfType<NodePropertyView>()
+                .ToDictionary(x => (INodePropertyHandler)x.DataContext, x => x);
+        }, DispatcherPriority.Render);
+    }
+
+    private void ChildrenOnCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
+    {
+        propertyViews = this.GetVisualDescendants().OfType<NodePropertyView>()
+            .ToDictionary(x => (INodePropertyHandler)x.DataContext, x => x);
+    }
+
     protected override void OnPointerPressed(PointerPressedEventArgs e)
     {
         base.OnPointerPressed(e);
@@ -233,15 +267,17 @@ public class NodeView : TemplatedControl
 
     public NodeSocket GetSocket(INodePropertyHandler property)
     {
-        NodePropertyView propertyView = this.GetVisualDescendants().OfType<NodePropertyView>()
-            .FirstOrDefault(x => x.DataContext == property);
-
-        if (propertyView is null)
+        if (propertyViews.TryGetValue(property, out var view))
         {
-            return default;
+            if (view is null)
+            {
+                return default;
+            }
+
+            return property.IsInput ? view.InputSocket : view.OutputSocket;
         }
 
-        return property.IsInput ? propertyView.InputSocket : propertyView.OutputSocket;
+        return null;
     }
 
     public Point GetSocketPoint(INodePropertyHandler property, Canvas canvas)

+ 1 - 1
tests/Directory.Build.props

@@ -1,7 +1,7 @@
 <Project>
     <PropertyGroup>
         <CodeAnalysisRuleSet>../Custom.ruleset</CodeAnalysisRuleSet>
-		<AvaloniaVersion>11.3.0</AvaloniaVersion>
+		<AvaloniaVersion>11.3.2</AvaloniaVersion>
     </PropertyGroup>
     <ItemGroup>
         <PackageReference Include="StyleCop.Analyzers" Version="1.1.118" />