Browse Source

Merge pull request #652 from PixiEditor/fixes-26-11

A lot of fixes
Krzysztof Krysiński 9 months ago
parent
commit
c549a2d4df
27 changed files with 199 additions and 236 deletions
  1. 1 1
      src/Directory.Build.props
  2. 1 1
      src/PixiDocks
  3. 4 1
      src/PixiEditor.ChangeableDocument/Changes/Drawing/CombineStructureMembersOnto_Change.cs
  4. 56 21
      src/PixiEditor.ChangeableDocument/Changes/Root/CenterContent_Change.cs
  5. 4 1
      src/PixiEditor.ChangeableDocument/DocumentChangeTracker.cs
  6. 0 149
      src/PixiEditor/Helpers/UI/DragDropEvents.cs
  7. 9 7
      src/PixiEditor/Models/Files/ImageFileType.cs
  8. 25 12
      src/PixiEditor/ViewModels/Document/DocumentViewModel.cs
  9. 4 5
      src/PixiEditor/Views/Layers/FolderControl.axaml
  10. 12 0
      src/PixiEditor/Views/Layers/FolderControl.axaml.cs
  11. 3 8
      src/PixiEditor/Views/Layers/LayerControl.axaml
  12. 11 0
      src/PixiEditor/Views/Layers/LayerControl.axaml.cs
  13. 1 1
      src/PixiEditor/Views/Layers/LayersManager.axaml
  14. 5 0
      src/PixiEditor/Views/Layers/LayersManager.axaml.cs
  15. 2 4
      src/PixiEditor/Views/Layers/ReferenceLayer.axaml
  16. 4 0
      src/PixiEditor/Views/Layers/ReferenceLayer.axaml.cs
  17. 7 7
      src/PixiEditor/Views/Main/ActionDisplayBar.axaml
  18. 1 2
      src/PixiEditor/Views/MainView.axaml
  19. 3 0
      src/PixiEditor/Views/MainView.axaml.cs
  20. 3 1
      src/PixiEditor/Views/Overlays/PathOverlay/VectorPathOverlay.cs
  21. 2 0
      src/PixiEditor/Views/Overlays/TransformOverlay/TransformOverlay.cs
  22. 1 1
      src/PixiEditor/Views/Palettes/ColorReplacer.axaml
  23. 6 5
      src/PixiEditor/Views/Palettes/ColorReplacer.axaml.cs
  24. 17 1
      src/PixiEditor/Views/Palettes/PaletteColorControl.axaml.cs
  25. 5 5
      src/PixiEditor/Views/Palettes/PaletteViewer.axaml
  26. 11 2
      src/PixiEditor/Views/Palettes/PaletteViewer.axaml.cs
  27. 1 1
      tests/Directory.Build.props

+ 1 - 1
src/Directory.Build.props

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

+ 1 - 1
src/PixiDocks

@@ -1 +1 @@
-Subproject commit ff4fdf7e67b75131eef961bb0f77c0710e24dae3
+Subproject commit 578cd1cde73b10dad264fbeefd860c44905e28a1

+ 4 - 1
src/PixiEditor.ChangeableDocument/Changes/Drawing/CombineStructureMembersOnto_Change.cs

@@ -197,7 +197,10 @@ internal class CombineStructureMembersOnto_Change : Change
         foreach (var toMerge in membersToMerge)
         foreach (var toMerge in membersToMerge)
         {
         {
             var member = target.FindMemberOrThrow<LayerNode>(toMerge);
             var member = target.FindMemberOrThrow<LayerNode>(toMerge);
-            maxFrame = Math.Max(maxFrame, member.KeyFrames.Max(x => x.StartFrame + x.Duration));
+            if (member.KeyFrames.Count > 0)
+            {
+                maxFrame = Math.Max(maxFrame, member.KeyFrames.Max(x => x.StartFrame + x.Duration));
+            }
         }
         }
 
 
         return maxFrame;
         return maxFrame;

+ 56 - 21
src/PixiEditor.ChangeableDocument/Changes/Root/CenterContent_Change.cs

@@ -1,7 +1,11 @@
-using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
+using ChunkyImageLib.Operations;
+using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
 using PixiEditor.ChangeableDocument.Changes.Drawing;
 using PixiEditor.ChangeableDocument.Changes.Drawing;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Numerics;
 using Drawie.Numerics;
 using Drawie.Numerics;
+using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
+using PixiEditor.ChangeableDocument.ChangeInfos.Objects;
+using PixiEditor.ChangeableDocument.ChangeInfos.Vectors;
 
 
 namespace PixiEditor.ChangeableDocument.Changes.Root;
 namespace PixiEditor.ChangeableDocument.Changes.Root;
 
 
@@ -11,6 +15,7 @@ internal class CenterContent_Change : Change
     private List<Guid> affectedLayers;
     private List<Guid> affectedLayers;
     private Dictionary<Guid, CommittedChunkStorage>? originalLayerChunks;
     private Dictionary<Guid, CommittedChunkStorage>? originalLayerChunks;
     private int frame;
     private int frame;
+    private VecD oldDelta;
 
 
     [GenerateMakeChangeAction]
     [GenerateMakeChangeAction]
     public CenterContent_Change(List<Guid> layers, int frame)
     public CenterContent_Change(List<Guid> layers, int frame)
@@ -18,7 +23,7 @@ internal class CenterContent_Change : Change
         this.frame = frame;
         this.frame = frame;
         affectedLayers = layers;
         affectedLayers = layers;
     }
     }
-    
+
     public override bool InitializeAndValidate(Document target)
     public override bool InitializeAndValidate(Document target)
     {
     {
         if (affectedLayers.Count == 0)
         if (affectedLayers.Count == 0)
@@ -34,7 +39,7 @@ internal class CenterContent_Change : Change
         }
         }
 
 
         _oldOffset = CalculateCurrentOffset(target);
         _oldOffset = CalculateCurrentOffset(target);
-        
+
         return true;
         return true;
     }
     }
 
 
@@ -54,31 +59,42 @@ internal class CenterContent_Change : Change
                     currentBounds.Value.Y + currentBounds.Value.Height / 2);
                     currentBounds.Value.Y + currentBounds.Value.Height / 2);
             }
             }
         }
         }
-        
+
         return currentCenter;
         return currentCenter;
     }
     }
 
 
-    public override OneOf<None, IChangeInfo, List<IChangeInfo>> Apply(Document target, bool firstApply, out bool ignoreInUndo)
+    public override OneOf<None, IChangeInfo, List<IChangeInfo>> Apply(Document target, bool firstApply,
+        out bool ignoreInUndo)
     {
     {
         VecI documentCenter = target.Size / 2;
         VecI documentCenter = target.Size / 2;
         VecI currentOffset = _oldOffset;
         VecI currentOffset = _oldOffset;
         
         
         VecI shift = documentCenter - currentOffset;
         VecI shift = documentCenter - currentOffset;
 
 
+        oldDelta = shift;
+        
         List<IChangeInfo> changes = new List<IChangeInfo>();
         List<IChangeInfo> changes = new List<IChangeInfo>();
         originalLayerChunks = new Dictionary<Guid, CommittedChunkStorage>();
         originalLayerChunks = new Dictionary<Guid, CommittedChunkStorage>();
-        
+
         foreach (var layerGuid in affectedLayers)
         foreach (var layerGuid in affectedLayers)
         {
         {
-            ImageLayerNode node = target.FindMemberOrThrow<ImageLayerNode>(layerGuid);
-            var chunks = ShiftLayerHelper.DrawShiftedLayer(target, layerGuid, false, shift, frame);
-            changes.Add(new LayerImageArea_ChangeInfo(layerGuid, chunks));
-
-            // TODO: Adding support for non-raster layer should be easy, add
-            
-            var image = node.GetLayerImageAtFrame(frame);
-            originalLayerChunks[layerGuid] = new CommittedChunkStorage(image, image.FindAffectedArea().Chunks);
-            image.CommitChanges();
+            LayerNode node = target.FindMemberOrThrow<LayerNode>(layerGuid);
+
+            if (node is ImageLayerNode imageLayerNode)
+            {
+                var chunks = ShiftLayerHelper.DrawShiftedLayer(target, layerGuid, false, shift, frame);
+                changes.Add(new LayerImageArea_ChangeInfo(layerGuid, chunks));
+                var image = imageLayerNode.GetLayerImageAtFrame(frame);
+                originalLayerChunks[layerGuid] = new CommittedChunkStorage(image, image.FindAffectedArea().Chunks);
+                image.CommitChanges();
+            }
+            else if (node is ITransformableObject transformable)
+            {
+                transformable.TransformationMatrix = transformable.TransformationMatrix.PostConcat(
+                    Matrix3X3.CreateTranslation(shift.X, shift.Y));
+                var affectedArea = FromSize(target);
+                changes.Add(new TransformObject_ChangeInfo(layerGuid, affectedArea));
+            }
         }
         }
 
 
         ignoreInUndo = shift.TaxicabLength == 0;
         ignoreInUndo = shift.TaxicabLength == 0;
@@ -90,15 +106,34 @@ internal class CenterContent_Change : Change
         List<IChangeInfo> changes = new List<IChangeInfo>();
         List<IChangeInfo> changes = new List<IChangeInfo>();
         foreach (var layerGuid in affectedLayers)
         foreach (var layerGuid in affectedLayers)
         {
         {
-            var image = target.FindMemberOrThrow<ImageLayerNode>(layerGuid).GetLayerImageAtFrame(frame);
-            CommittedChunkStorage? originalChunks = originalLayerChunks?[layerGuid];
-            var affected = DrawingChangeHelper.ApplyStoredChunksDisposeAndSetToNull(image, ref originalChunks);
-            changes.Add(new LayerImageArea_ChangeInfo(layerGuid, affected));
+            var layerNode = target.FindMemberOrThrow<LayerNode>(layerGuid);
+
+            if (layerNode is ImageLayerNode imageNode)
+            {
+                var image = imageNode.GetLayerImageAtFrame(frame);
+                CommittedChunkStorage? originalChunks = originalLayerChunks?[layerGuid];
+                var affected = DrawingChangeHelper.ApplyStoredChunksDisposeAndSetToNull(image, ref originalChunks);
+                changes.Add(new LayerImageArea_ChangeInfo(layerGuid, affected));
+            }
+            else if (layerNode is ITransformableObject transformable)
+            {
+                transformable.TransformationMatrix = transformable.TransformationMatrix.PostConcat(
+                    Matrix3X3.CreateTranslation((float)-oldDelta.X, (float)-oldDelta.Y));
+                
+                var affectedArea = FromSize(target);
+                changes.Add(new TransformObject_ChangeInfo(layerGuid, affectedArea));
+            }
         }
         }
-        
+
         return changes;
         return changes;
     }
     }
 
 
+    private AffectedArea FromSize(Document target)
+    {
+        RectI bounds = new RectI(VecI.Zero, target.Size);
+        return new AffectedArea(OperationHelper.FindChunksTouchingRectangle(bounds, ChunkyImage.FullChunkSize));
+    }
+
     public override void Dispose()
     public override void Dispose()
     {
     {
         if (originalLayerChunks == null)
         if (originalLayerChunks == null)
@@ -110,7 +145,7 @@ internal class CenterContent_Change : Change
         {
         {
             layerChunk.Value.Dispose();
             layerChunk.Value.Dispose();
         }
         }
-        
+
         originalLayerChunks = null;
         originalLayerChunks = null;
     }
     }
 }
 }

+ 4 - 1
src/PixiEditor.ChangeableDocument/DocumentChangeTracker.cs

@@ -97,7 +97,10 @@ public class DocumentChangeTracker : IDisposable
              (IsHomologous(undoStack.Peek()) &&
              (IsHomologous(undoStack.Peek()) &&
               undoStack.Peek().changes[^1].IsMergeableWith(activePacket[0].change))))
               undoStack.Peek().changes[^1].IsMergeableWith(activePacket[0].change))))
         {
         {
-            undoStack.Peek().changes.Add(activePacket[0].change);
+            var last = undoStack.Pop();
+            last.changes.Add(activePacket[0].change);
+            last.source = activePacket.Any(x => x.source == ActionSource.User) ? ActionSource.User : source;
+            undoStack.Push(last);
         }
         }
         else
         else
         {
         {

+ 0 - 149
src/PixiEditor/Helpers/UI/DragDropEvents.cs

@@ -1,149 +0,0 @@
-using Avalonia.Input;
-using Avalonia.Interactivity;
-
-namespace PixiEditor.Helpers.UI;
-
-public delegate void DragEventHandler(object sender, DragEventArgs e);
-
-public static class DragDropEvents
-{
-    public static readonly RoutedEvent<DragEventArgs> DragEnterEvent =
-        RoutedEvent.Register<DragEventArgs>(
-            "DragEnter",
-            RoutingStrategies.Bubble,
-            typeof(DragDropEvents));
-
-
-    public static readonly RoutedEvent<DragEventArgs> DragLeaveEvent =
-        RoutedEvent.Register<DragEventArgs>(
-            "DragLeave",
-            RoutingStrategies.Bubble,
-            typeof(DragDropEvents));
-
-
-    public static readonly RoutedEvent<RoutedEventArgs> DragOverEvent =
-        RoutedEvent.Register<RoutedEventArgs>(
-            "DragOver",
-            RoutingStrategies.Bubble,
-            typeof(DragDropEvents));
-
-
-    public static readonly RoutedEvent<DragEventArgs> DropEvent =
-        RoutedEvent.Register<DragEventArgs>(
-            "Drop",
-            RoutingStrategies.Bubble,
-            typeof(DragDropEvents));
-
-    public static void AddDragEnterHandler(Interactive control, EventHandler<DragEventArgs> handler)
-    {
-        var checkedHandler = WithCheck(control, handler);
-        control.AddHandler(
-            DragEnterEvent,
-            checkedHandler,
-            RoutingStrategies.Bubble);
-
-        control.AddHandler(
-            DragDrop.DragEnterEvent,
-            checkedHandler,
-            RoutingStrategies.Bubble);
-    }
-
-    public static void AddDragLeaveHandler(Interactive control, EventHandler<DragEventArgs> handler)
-    {
-        var checkedHandler = WithCheck(control, handler);
-
-        control.AddHandler(
-            DragLeaveEvent,
-            checkedHandler,
-            RoutingStrategies.Bubble);
-
-        control.AddHandler(
-            DragDrop.DragLeaveEvent,
-            checkedHandler,
-            RoutingStrategies.Bubble);
-    }
-
-    public static void AddDragOverHandler(Interactive control, EventHandler<DragEventArgs> handler)
-    {
-        var checkedHandler = WithCheck(control, handler);
-
-        control.AddHandler(
-            DragOverEvent,
-            checkedHandler,
-            RoutingStrategies.Bubble);
-
-        control.AddHandler(
-            DragDrop.DragOverEvent,
-            checkedHandler,
-            RoutingStrategies.Bubble);
-    }
-
-    public static void AddDropHandler(Interactive control, EventHandler<DragEventArgs> handler)
-    {
-        var checkedHandler = WithCheck(control, handler);
-        control.AddHandler(
-            DropEvent,
-            checkedHandler,
-            RoutingStrategies.Bubble);
-
-        control.AddHandler(
-            DragDrop.DropEvent,
-            checkedHandler,
-            RoutingStrategies.Bubble);
-    }
-
-    public static void RemoveDragEnterHandler(Interactive control, EventHandler<DragEventArgs> handler)
-    {
-        control.RemoveHandler(
-            DragEnterEvent,
-            handler);
-
-        control.RemoveHandler(
-            DragDrop.DragEnterEvent,
-            handler);
-    }
-
-    public static void RemoveDragLeaveHandler(Interactive control, EventHandler<DragEventArgs> handler)
-    {
-        control.RemoveHandler(
-            DragLeaveEvent,
-            handler);
-
-        control.RemoveHandler(
-            DragDrop.DragLeaveEvent,
-            handler);
-    }
-
-    public static void RemoveDragOverHandler(Interactive control, EventHandler<DragEventArgs> handler)
-    {
-        control.RemoveHandler(
-            DragOverEvent,
-            handler);
-
-        control.RemoveHandler(
-            DragDrop.DragOverEvent,
-            handler);
-    }
-
-    public static void RemoveDropHandler(Interactive control, EventHandler<DragEventArgs> handler)
-    {
-        control.RemoveHandler(
-            DropEvent,
-            handler);
-
-        control.RemoveHandler(
-            DragDrop.DropEvent,
-            handler);
-    }
-
-    private static EventHandler<T> WithCheck<T>(object source, EventHandler<T> handler) where T : RoutedEventArgs
-    {
-        return (sender, args) =>
-        {
-            if (source == sender)
-            {
-                handler(sender, args);
-            }
-        };
-    }
-}

+ 9 - 7
src/PixiEditor/Models/Files/ImageFileType.cs

@@ -32,17 +32,19 @@ internal abstract class ImageFileType : IoFileType
         }
         }
         else
         else
         {
         {
-            job?.Report(0, new LocalizedString("RENDERING_IMAGE")); 
-            var maybeBitmap = document.TryRenderWholeImage(0);
+            job?.Report(0, new LocalizedString("RENDERING_IMAGE"));
+            
+            var exportSize = exportConfig.ExportSize;
+            if (exportSize.X <= 0 || exportSize.Y <= 0)
+            {
+                return SaveResult.UnknownError; // TODO: Add InvalidParameters error type
+            }
+            
+            var maybeBitmap = document.TryRenderWholeImage(0, exportSize);
             if (maybeBitmap.IsT0)
             if (maybeBitmap.IsT0)
                 return SaveResult.ConcurrencyError;
                 return SaveResult.ConcurrencyError;
 
 
             finalSurface = maybeBitmap.AsT1;
             finalSurface = maybeBitmap.AsT1;
-            if (maybeBitmap.AsT1.Size != exportConfig.ExportSize && exportConfig.ExportSize.X > 0 && exportConfig.ExportSize.Y > 0)
-            {
-                finalSurface = finalSurface.ResizeNearestNeighbor(exportConfig.ExportSize);
-                maybeBitmap.AsT1.Dispose();
-            }
         }
         }
 
 
         EncodedImageFormat mappedFormat = EncodedImageFormat;
         EncodedImageFormat mappedFormat = EncodedImageFormat;

+ 25 - 12
src/PixiEditor/ViewModels/Document/DocumentViewModel.cs

@@ -234,13 +234,13 @@ internal partial class DocumentViewModel : PixiObservableObject, IDocument
 
 
         TransformViewModel = new(this);
         TransformViewModel = new(this);
         TransformViewModel.TransformMoved += (_, args) => Internals.ChangeController.TransformMovedInlet(args);
         TransformViewModel.TransformMoved += (_, args) => Internals.ChangeController.TransformMovedInlet(args);
-        
+
         PathOverlayViewModel = new(this, Internals);
         PathOverlayViewModel = new(this, Internals);
         PathOverlayViewModel.PathChanged += path =>
         PathOverlayViewModel.PathChanged += path =>
         {
         {
             Internals.ChangeController.PathOverlayChangedInlet(path);
             Internals.ChangeController.PathOverlayChangedInlet(path);
         };
         };
-        
+
         LineToolOverlayViewModel = new();
         LineToolOverlayViewModel = new();
         LineToolOverlayViewModel.LineMoved += (_, args) =>
         LineToolOverlayViewModel.LineMoved += (_, args) =>
             Internals.ChangeController.LineOverlayMovedInlet(args.Item1, args.Item2);
             Internals.ChangeController.LineOverlayMovedInlet(args.Item1, args.Item2);
@@ -519,22 +519,22 @@ internal partial class DocumentViewModel : PixiObservableObject, IDocument
         OnPropertyChanged(nameof(AllChangesSaved));
         OnPropertyChanged(nameof(AllChangesSaved));
     }
     }
 
 
-
-    /// <summary>
-    /// Tries rendering the whole document
-    /// </summary>
-    /// <returns><see cref="Error"/> if the ChunkyImage was disposed, otherwise a <see cref="Surface"/> of the rendered document</returns>
-    public OneOf<Error, Surface> TryRenderWholeImage(KeyFrameTime frameTime)
+    public OneOf<Error, Surface> TryRenderWholeImage(KeyFrameTime frameTime, VecI renderSize)
     {
     {
         try
         try
         {
         {
-            Surface finalSurface = null; 
+            Surface finalSurface = null;
             DrawingBackendApi.Current.RenderingDispatcher.Invoke(() =>
             DrawingBackendApi.Current.RenderingDispatcher.Invoke(() =>
             {
             {
-                using Texture texture = new Texture(SizeBindable);
-                Renderer.RenderDocument(texture.DrawingSurface, frameTime);
+                using Texture texture = new Texture(renderSize);
+                texture.DrawingSurface.Canvas.Save();
+                VecD scaling = new VecD(renderSize.X / (double)SizeBindable.X, renderSize.Y / (double)SizeBindable.Y);
                 
                 
-                finalSurface = new Surface(SizeBindable);
+                texture.DrawingSurface.Canvas.Scale((float)scaling.X, (float)scaling.Y);
+                Renderer.RenderDocument(texture.DrawingSurface, frameTime);
+
+                texture.DrawingSurface.Canvas.Restore();
+                finalSurface = new Surface(renderSize);
                 finalSurface.DrawingSurface.Canvas.DrawImage(texture.DrawingSurface.Snapshot(), 0, 0);
                 finalSurface.DrawingSurface.Canvas.DrawImage(texture.DrawingSurface.Snapshot(), 0, 0);
             });
             });
 
 
@@ -546,6 +546,16 @@ internal partial class DocumentViewModel : PixiObservableObject, IDocument
         }
         }
     }
     }
 
 
+    /// <summary>
+    /// Tries rendering the whole document
+    /// </summary>
+    /// <returns><see cref="Error"/> if the ChunkyImage was disposed, otherwise a <see cref="Surface"/> of the rendered document</returns>
+    public OneOf<Error, Surface> TryRenderWholeImage(KeyFrameTime frameTime)
+    {
+        return TryRenderWholeImage(frameTime, SizeBindable);
+    }
+
+
     /// <summary>
     /// <summary>
     /// Takes the selected area and converts it into a surface
     /// Takes the selected area and converts it into a surface
     /// </summary>
     /// </summary>
@@ -604,6 +614,9 @@ internal partial class DocumentViewModel : PixiObservableObject, IDocument
                 finalBounds = finalBounds.Union(combinedBounds);
                 finalBounds = finalBounds.Union(combinedBounds);
             }
             }
         }
         }
+        
+        if (finalBounds.IsZeroOrNegativeArea)
+            return new None();
 
 
         Surface output = new(finalBounds.Size);
         Surface output = new(finalBounds.Size);
 
 

+ 4 - 5
src/PixiEditor/Views/Layers/FolderControl.axaml

@@ -40,8 +40,8 @@
                 <RowDefinition Height="16"/>
                 <RowDefinition Height="16"/>
                 <RowDefinition Height="10"/>
                 <RowDefinition Height="10"/>
             </Grid.RowDefinitions>
             </Grid.RowDefinitions>
-            <Grid DragDrop.AllowDrop="True" helpers:DragDropEvents.DragEnter="Grid_DragEnter" helpers:DragDropEvents.Drop="Grid_Drop_Top" helpers:DragDropEvents.DragLeave="Grid_DragLeave" Grid.Row="0" Grid.ColumnSpan="3" Background="Transparent" Panel.ZIndex="3"/>
-            <Grid IsVisible="True" Margin="20, 0, 0,0" x:Name="middleDropGrid" Grid.Row="1" DragDrop.AllowDrop="True" Panel.ZIndex="2" Background="Transparent" helpers:DragDropEvents.DragEnter="Grid_CenterEnter" helpers:DragDropEvents.Drop="Grid_Drop_Center" helpers:DragDropEvents.DragLeave="Grid_CenterLeave" />
+            <Grid DragDrop.AllowDrop="True" Name="TopDropGrid" Grid.Row="0" Grid.ColumnSpan="3" Background="Transparent" Panel.ZIndex="3"/>
+            <Grid IsVisible="True" Margin="20, 0, 0,0" x:Name="middleDropGrid" Grid.Row="1" DragDrop.AllowDrop="True" Panel.ZIndex="2" Background="Transparent"  />
             <Grid x:Name="centerGrid" Grid.Row="0" Grid.RowSpan="3" Background="Transparent">
             <Grid x:Name="centerGrid" Grid.Row="0" Grid.RowSpan="3" Background="Transparent">
                 <Grid.ColumnDefinitions>
                 <Grid.ColumnDefinitions>
                     <ColumnDefinition Width="24"/>
                     <ColumnDefinition Width="24"/>
@@ -130,9 +130,8 @@
             </Grid>
             </Grid>
             <Grid
             <Grid
                   Grid.Row="2"
                   Grid.Row="2"
-                  helpers:DragDropEvents.DragEnter="Grid_DragEnter" helpers:DragDropEvents.Drop="Grid_Drop_Bottom"
-                  helpers:DragDropEvents.DragLeave="Grid_DragLeave"
-                  DragDrop.AllowDrop="false"
+                  Name="BottomDropGrid"
+                  DragDrop.AllowDrop="True"
                   Grid.ColumnSpan="2" Background="Transparent"/>
                   Grid.ColumnSpan="2" Background="Transparent"/>
         </Grid>
         </Grid>
         <Border.ContextMenu>
         <Border.ContextMenu>

+ 12 - 0
src/PixiEditor/Views/Layers/FolderControl.axaml.cs

@@ -48,6 +48,18 @@ internal partial class FolderControl : UserControl
 
 
         Loaded += OnLoaded;
         Loaded += OnLoaded;
         Unloaded += OnUnloaded;
         Unloaded += OnUnloaded;
+        
+        TopDropGrid.AddHandler(DragDrop.DragEnterEvent, Grid_DragEnter);
+        TopDropGrid.AddHandler(DragDrop.DragLeaveEvent, Grid_DragLeave);
+        TopDropGrid.AddHandler(DragDrop.DropEvent, Grid_Drop_Top);
+        
+        BottomDropGrid.AddHandler(DragDrop.DragEnterEvent, Grid_DragEnter);
+        BottomDropGrid.AddHandler(DragDrop.DragLeaveEvent, Grid_DragLeave);
+        BottomDropGrid.AddHandler(DragDrop.DropEvent, Grid_Drop_Bottom);
+        
+        middleDropGrid.AddHandler(DragDrop.DragEnterEvent, Grid_CenterEnter);
+        middleDropGrid.AddHandler(DragDrop.DragLeaveEvent, Grid_CenterLeave);
+        middleDropGrid.AddHandler(DragDrop.DropEvent, Grid_Drop_Center);
     }
     }
 
 
     private void OnUnloaded(object? sender, RoutedEventArgs e)
     private void OnUnloaded(object? sender, RoutedEventArgs e)

+ 3 - 8
src/PixiEditor/Views/Layers/LayerControl.axaml

@@ -42,8 +42,8 @@
                 <RowDefinition Height="10" />
                 <RowDefinition Height="10" />
                 <RowDefinition Height="26" />
                 <RowDefinition Height="26" />
             </Grid.RowDefinitions>
             </Grid.RowDefinitions>
-            <Grid DragDrop.AllowDrop="True" helpers:DragDropEvents.DragEnter="Grid_DragEnter"
-                  helpers:DragDropEvents.Drop="Grid_Drop_Top" helpers:DragDropEvents.DragLeave="Grid_DragLeave"
+            <Grid DragDrop.AllowDrop="True"
+                  Name="TopGrid"
                   Grid.Row="0" Grid.ColumnSpan="3" Background="Transparent" />
                   Grid.Row="0" Grid.ColumnSpan="3" Background="Transparent" />
             <Grid Grid.Row="1" Margin="0,-17,0,0" VerticalAlignment="Center" DragDrop.AllowDrop="False">
             <Grid Grid.Row="1" Margin="0,-17,0,0" VerticalAlignment="Center" DragDrop.AllowDrop="False">
                 <Grid.ColumnDefinitions>
                 <Grid.ColumnDefinitions>
@@ -154,10 +154,7 @@
                     </WrapPanel>
                     </WrapPanel>
                 </StackPanel>
                 </StackPanel>
                 <Grid Margin="0, 0, 0, -2.5"
                 <Grid Margin="0, 0, 0, -2.5"
-                      helpers:DragDropEvents.DragEnter="Grid_DragEnter"
                       VerticalAlignment="Bottom"
                       VerticalAlignment="Bottom"
-                      helpers:DragDropEvents.Drop="Grid_Drop_Below"
-                      helpers:DragDropEvents.DragLeave="Grid_DragLeave"
                       Height="10" Grid.Row="2" Grid.Column="0"
                       Height="10" Grid.Row="2" Grid.Column="0"
                       DragDrop.AllowDrop="True" Background="Transparent" Name="dropBelowGrid" />
                       DragDrop.AllowDrop="True" Background="Transparent" Name="dropBelowGrid" />
                 <Grid Margin="0, 0, 0, -2.5"
                 <Grid Margin="0, 0, 0, -2.5"
@@ -168,9 +165,7 @@
 
 
                 <Grid Margin="0, 0, 0, -2.5" VerticalAlignment="Bottom"
                 <Grid Margin="0, 0, 0, -2.5" VerticalAlignment="Bottom"
                       Height="10" Grid.Row="2" Grid.Column="2"
                       Height="10" Grid.Row="2" Grid.Column="2"
-                      helpers:DragDropEvents.DragEnter="Grid_DragEnter"
-                      helpers:DragDropEvents.Drop="Grid_Drop_Bottom"
-                      helpers:DragDropEvents.DragLeave="Grid_DragLeave"
+                      Name="thirdDropGrid"
                       DragDrop.AllowDrop="True" Background="Transparent" />
                       DragDrop.AllowDrop="True" Background="Transparent" />
             </Grid>
             </Grid>
         </Grid>
         </Grid>

+ 11 - 0
src/PixiEditor/Views/Layers/LayerControl.axaml.cs

@@ -5,6 +5,7 @@ using Avalonia.Input;
 using Avalonia.Interactivity;
 using Avalonia.Interactivity;
 using Avalonia.Media;
 using Avalonia.Media;
 using CommunityToolkit.Mvvm.Input;
 using CommunityToolkit.Mvvm.Input;
+using PixiEditor.Helpers.UI;
 using PixiEditor.Models.Controllers.InputDevice;
 using PixiEditor.Models.Controllers.InputDevice;
 using PixiEditor.Models.Handlers;
 using PixiEditor.Models.Handlers;
 using PixiEditor.Models.Layers;
 using PixiEditor.Models.Layers;
@@ -86,6 +87,16 @@ internal partial class LayerControl : UserControl
         {
         {
             highlightColor = value as IBrush;
             highlightColor = value as IBrush;
         }
         }
+     
+        TopGrid.AddHandler(DragDrop.DragEnterEvent, Grid_DragEnter);
+        TopGrid.AddHandler(DragDrop.DragLeaveEvent, Grid_DragLeave);
+        TopGrid.AddHandler(DragDrop.DropEvent, Grid_Drop_Top);
+        dropBelowGrid.AddHandler(DragDrop.DragEnterEvent, Grid_DragEnter);
+        dropBelowGrid.AddHandler(DragDrop.DragLeaveEvent, Grid_DragLeave);
+        dropBelowGrid.AddHandler(DragDrop.DropEvent, Grid_Drop_Below);
+        thirdDropGrid.AddHandler(DragDrop.DragEnterEvent, Grid_DragEnter);
+        thirdDropGrid.AddHandler(DragDrop.DragLeaveEvent, Grid_DragLeave);
+        thirdDropGrid.AddHandler(DragDrop.DropEvent, Grid_Drop_Bottom);
     }
     }
     
     
     private void LayerControl_Unloaded(object? sender, RoutedEventArgs e)
     private void LayerControl_Unloaded(object? sender, RoutedEventArgs e)

+ 1 - 1
src/PixiEditor/Views/Layers/LayersManager.axaml

@@ -155,7 +155,7 @@
                     </DataTemplate>
                     </DataTemplate>
                 </TreeView.DataTemplates>
                 </TreeView.DataTemplates>
             </TreeView>
             </TreeView>
-            <Border Name="dropBorder" ui1:DragDropEvents.DragEnter="Grid_DragEnter" ui1:DragDropEvents.DragLeave="Grid_DragLeave" DragDrop.AllowDrop="True" ui1:DragDropEvents.Drop="Grid_Drop" Background="Transparent" BorderThickness="0, 5, 0, 0" />
+            <Border Name="dropBorder" DragDrop.AllowDrop="True" Background="Transparent" BorderThickness="0, 5, 0, 0" />
         </DockPanel>
         </DockPanel>
     </Grid>
     </Grid>
 </UserControl>
 </UserControl>

+ 5 - 0
src/PixiEditor/Views/Layers/LayersManager.axaml.cs

@@ -4,6 +4,7 @@ using Avalonia.Interactivity;
 using Avalonia.Media;
 using Avalonia.Media;
 using Avalonia.Threading;
 using Avalonia.Threading;
 using PixiEditor.Helpers;
 using PixiEditor.Helpers;
+using PixiEditor.Helpers.UI;
 using PixiEditor.Models.Controllers;
 using PixiEditor.Models.Controllers;
 using PixiEditor.Models.Handlers;
 using PixiEditor.Models.Handlers;
 using PixiEditor.Models.Layers;
 using PixiEditor.Models.Layers;
@@ -28,6 +29,10 @@ internal partial class LayersManager : UserControl
         {
         {
             highlightColor = value as IBrush;
             highlightColor = value as IBrush;
         }
         }
+      
+        dropBorder.AddHandler(DragDrop.DragEnterEvent, Grid_DragEnter);
+        dropBorder.AddHandler(DragDrop.DragLeaveEvent, Grid_DragLeave);
+        dropBorder.AddHandler(DragDrop.DropEvent, Grid_Drop);
     }
     }
 
 
     private void LayerControl_MouseDown(object sender, PointerPressedEventArgs e)
     private void LayerControl_MouseDown(object sender, PointerPressedEventArgs e)

+ 2 - 4
src/PixiEditor/Views/Layers/ReferenceLayer.axaml

@@ -23,10 +23,8 @@
         </Style>
         </Style>
     </UserControl.Styles>
     </UserControl.Styles>
     <Border BorderThickness="0 2 0 0" MinWidth="60"
     <Border BorderThickness="0 2 0 0" MinWidth="60"
-            Focusable="True" DragDrop.AllowDrop="True"
-            ui1:DragDropEvents.DragEnter="ReferenceLayer_DragEnter"
-            ui1:DragDropEvents.Drop="ReferenceLayer_Drop"
-            ui1:DragDropEvents.DragLeave="ReferenceLayer_DragLeave">
+            Name="DragBorder"
+            Focusable="True" DragDrop.AllowDrop="True">
         <Interaction.Behaviors>
         <Interaction.Behaviors>
             <behaviours:ClearFocusOnClickBehavior />
             <behaviours:ClearFocusOnClickBehavior />
         </Interaction.Behaviors>
         </Interaction.Behaviors>

+ 4 - 0
src/PixiEditor/Views/Layers/ReferenceLayer.axaml.cs

@@ -32,6 +32,10 @@ internal partial class ReferenceLayer : UserControl
     {
     {
         command = CommandController.Current.Commands["PixiEditor.Clipboard.PasteReferenceLayer"];
         command = CommandController.Current.Commands["PixiEditor.Clipboard.PasteReferenceLayer"];
         InitializeComponent();
         InitializeComponent();
+        
+        DragBorder.AddHandler(DragDrop.DragEnterEvent, ReferenceLayer_DragEnter);
+        DragBorder.AddHandler(DragDrop.DragLeaveEvent, ReferenceLayer_DragLeave);
+        DragBorder.AddHandler(DragDrop.DropEvent, ReferenceLayer_Drop);
     }
     }
     
     
     private static void OnDocumentChanged(AvaloniaPropertyChangedEventArgs<DocumentViewModel> e)
     private static void OnDocumentChanged(AvaloniaPropertyChangedEventArgs<DocumentViewModel> e)

+ 7 - 7
src/PixiEditor/Views/Main/ActionDisplayBar.axaml

@@ -24,8 +24,8 @@
                 Width="290" />
                 Width="290" />
         </Grid.ColumnDefinitions>
         </Grid.ColumnDefinitions>
         <!--<visuals:ColorsPreviewer/>-->
         <!--<visuals:ColorsPreviewer/>-->
-        <colorPicker:ColorDisplay SelectedColor="{Binding ColorsSubViewModel.PrimaryColor, Converter={converters:GenericColorToMediaColorConverter}}"
-                                  SecondaryColor="{Binding ColorsSubViewModel.SecondaryColor, Converter={converters:GenericColorToMediaColorConverter}}">
+        <colorPicker:ColorDisplay SelectedColor="{Binding DataContext.ColorsSubViewModel.PrimaryColor, Converter={converters:GenericColorToMediaColorConverter}, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}"
+                                  SecondaryColor="{Binding DataContext.ColorsSubViewModel.SecondaryColor, Converter={converters:GenericColorToMediaColorConverter}, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}">
             <colorPicker:ColorDisplay.Styles>
             <colorPicker:ColorDisplay.Styles>
                 <Style Selector="Button">
                 <Style Selector="Button">
                     <Setter Property="IsVisible" Value="False"/>
                     <Setter Property="IsVisible" Value="False"/>
@@ -34,7 +34,7 @@
         </colorPicker:ColorDisplay>
         </colorPicker:ColorDisplay>
         <DockPanel Grid.Column="1">
         <DockPanel Grid.Column="1">
             <TextBlock
             <TextBlock
-                ui:Translator.LocalizedString="{Binding ActiveActionDisplay}"
+                ui:Translator.LocalizedString="{Binding DataContext.ActiveActionDisplay, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}"
                 Foreground="White"
                 Foreground="White"
                 FontSize="15"
                 FontSize="15"
                 Margin="10,0,0,0"
                 Margin="10,0,0,0"
@@ -45,7 +45,7 @@
                 HorizontalAlignment="Right"
                 HorizontalAlignment="Right"
                 VerticalAlignment="Center">
                 VerticalAlignment="Center">
                 <TextBlock
                 <TextBlock
-                    Text="{Binding DocumentManagerSubViewModel.ActiveDocument.CoordinatesString}"
+                    Text="{Binding DataContext.DocumentManagerSubViewModel.ActiveDocument.CoordinatesString, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}"
                     Foreground="White"
                     Foreground="White"
                     FontSize="16" />
                     FontSize="16" />
             </StackPanel>
             </StackPanel>
@@ -56,17 +56,17 @@
             Grid.Column="2"
             Grid.Column="2"
             Orientation="Horizontal">
             Orientation="Horizontal">
             <Button
             <Button
-                IsVisible="{Binding UpdateSubViewModel.UpdateReadyToInstall, FallbackValue=False}"
+                IsVisible="{Binding DataContext.UpdateSubViewModel.UpdateReadyToInstall, FallbackValue=False, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}"
                 FontSize="14"
                 FontSize="14"
                 Height="20"
                 Height="20"
                 Command="{xaml:Command PixiEditor.Restart}" ui:Translator.Key="RESTART" />
                 Command="{xaml:Command PixiEditor.Restart}" ui:Translator.Key="RESTART" />
             <TextBlock
             <TextBlock
                 VerticalAlignment="Center"
                 VerticalAlignment="Center"
-                Padding="10"
+                Padding="10, 0"
                 HorizontalAlignment="Right"
                 HorizontalAlignment="Right"
                 Foreground="White"
                 Foreground="White"
                 FontSize="14"
                 FontSize="14"
-                Text="{Binding UpdateSubViewModel.VersionText}" />
+                Text="{Binding DataContext.UpdateSubViewModel.VersionText, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}" />
         </StackPanel>
         </StackPanel>
     </Grid>
     </Grid>
 </UserControl>
 </UserControl>

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

@@ -19,8 +19,7 @@
             <InvokeCommandAction Command="{Binding StartupCommand}" />
             <InvokeCommandAction Command="{Binding StartupCommand}" />
         </EventTriggerBehavior>
         </EventTriggerBehavior>
     </Interaction.Behaviors>
     </Interaction.Behaviors>
-    <Grid DragDrop.AllowDrop="True" ui:DragDropEvents.DragEnter="MainView_DragEnter" ui:DragDropEvents.DragLeave="MainView_DragLeave"
-          ui:DragDropEvents.Drop="MainView_Drop">
+    <Grid DragDrop.AllowDrop="True" Name="DropGrid">
         <DockPanel>
         <DockPanel>
             <main1:MainTitleBar DockPanel.Dock="Top" DataContext="{Binding MenuBarViewModel}"/>
             <main1:MainTitleBar DockPanel.Dock="Top" DataContext="{Binding MenuBarViewModel}"/>
             <Grid Focusable="True" Name="FocusableGrid">
             <Grid Focusable="True" Name="FocusableGrid">

+ 3 - 0
src/PixiEditor/Views/MainView.axaml.cs

@@ -16,6 +16,9 @@ public partial class MainView : UserControl
     {
     {
         InitializeComponent();
         InitializeComponent();
         TextBoxFocusBehavior.FallbackFocusElement = FocusableGrid;
         TextBoxFocusBehavior.FallbackFocusElement = FocusableGrid;
+        DropGrid.AddHandler(DragDrop.DragEnterEvent, MainView_DragEnter);
+        DropGrid.AddHandler(DragDrop.DragLeaveEvent, MainView_DragLeave);
+        DropGrid.AddHandler(DragDrop.DropEvent, MainView_Drop);
     }
     }
     
     
     private void MainView_Drop(object sender, DragEventArgs e)
     private void MainView_Drop(object sender, DragEventArgs e)

+ 3 - 1
src/PixiEditor/Views/Overlays/PathOverlay/VectorPathOverlay.cs

@@ -68,7 +68,7 @@ public class VectorPathOverlay : Overlay
 
 
         AddHandle(transformHandle);
         AddHandle(transformHandle);
     }
     }
-
+    
     protected override void ZoomChanged(double newZoom)
     protected override void ZoomChanged(double newZoom)
     {
     {
         dashedStroke.UpdateZoom((float)newZoom);
         dashedStroke.UpdateZoom((float)newZoom);
@@ -809,11 +809,13 @@ public class VectorPathOverlay : Overlay
         {
         {
             overlay.SnappingController.RemoveAll("editingPath");
             overlay.SnappingController.RemoveAll("editingPath");
             overlay.ClearAnchorHandles();
             overlay.ClearAnchorHandles();
+            overlay.IsVisible = false;
         }
         }
         else
         else
         {
         {
             var path = args.NewValue.Value;
             var path = args.NewValue.Value;
             overlay.AdjustHandles(path.PointCount - (path.IsClosed ? 1 : 0));
             overlay.AdjustHandles(path.PointCount - (path.IsClosed ? 1 : 0));
+            overlay.IsVisible = true;
         }
         }
 
 
         if (args.OldValue.Value != null)
         if (args.OldValue.Value != null)

+ 2 - 0
src/PixiEditor/Views/Overlays/TransformOverlay/TransformOverlay.cs

@@ -496,6 +496,7 @@ internal class TransformOverlay : Overlay
             return;
             return;
         }
         }
 
 
+        IsSizeBoxEnabled = true;
         args.Pointer.Capture(this);
         args.Pointer.Capture(this);
         args.Handled = true;
         args.Handled = true;
     }
     }
@@ -573,6 +574,7 @@ internal class TransformOverlay : Overlay
         }
         }
 
 
         StopMoving();
         StopMoving();
+        IsSizeBoxEnabled = false;
     }
     }
 
 
     public override bool TestHit(VecD point)
     public override bool TestHit(VecD point)

+ 1 - 1
src/PixiEditor/Views/Palettes/ColorReplacer.axaml

@@ -36,7 +36,7 @@
                                                Height="35"
                                                Height="35"
                                                Width="35"
                                                Width="35"
                                                ui:Translator.TooltipKey="REPLACER_TOOLTIP"
                                                ui:Translator.TooltipKey="REPLACER_TOOLTIP"
-                                               ui1:DragDropEvents.Drop="PaletteColorControl_OnDrop"
+                                               Name="DropTarget"
                                                DragDrop.AllowDrop="True" />
                                                DragDrop.AllowDrop="True" />
                     <TextBlock Name="arrow" VerticalAlignment="Center" Text="{DynamicResource icon-arrow-right}" Classes="pixi-icon" 
                     <TextBlock Name="arrow" VerticalAlignment="Center" Text="{DynamicResource icon-arrow-right}" Classes="pixi-icon" 
                                FontSize="24" Margin="10 0" ui:Translator.UseLanguageFlowDirection="True"/>
                                FontSize="24" Margin="10 0" ui:Translator.UseLanguageFlowDirection="True"/>

+ 6 - 5
src/PixiEditor/Views/Palettes/ColorReplacer.axaml.cs

@@ -65,6 +65,12 @@ internal partial class ColorReplacer : UserControl
         set => SetValue(IsCollapsedProperty, value);
         set => SetValue(IsCollapsedProperty, value);
     }
     }
 
 
+    public ColorReplacer()
+    {
+        InitializeComponent();
+        DropTarget.AddHandler(DragDrop.DropEvent, PaletteColorControl_OnDrop);
+    }
+
     private void PaletteColorControl_OnDrop(object sender, DragEventArgs e)
     private void PaletteColorControl_OnDrop(object sender, DragEventArgs e)
     {
     {
         if (e.Data.Contains(PaletteColorControl.PaletteColorDaoFormat))
         if (e.Data.Contains(PaletteColorControl.PaletteColorDaoFormat))
@@ -79,11 +85,6 @@ internal partial class ColorReplacer : UserControl
         }
         }
     }
     }
 
 
-    public ColorReplacer()
-    {
-        InitializeComponent();
-    }
-
     private void ReplaceButton_OnClick(object sender, RoutedEventArgs e)
     private void ReplaceButton_OnClick(object sender, RoutedEventArgs e)
     {
     {
         PaletteColor first = ColorToReplace;
         PaletteColor first = ColorToReplace;

+ 17 - 1
src/PixiEditor/Views/Palettes/PaletteColorControl.axaml.cs

@@ -1,4 +1,5 @@
-using Avalonia;
+using System.Windows.Input;
+using Avalonia;
 using Avalonia.Controls;
 using Avalonia.Controls;
 using Avalonia.Input;
 using Avalonia.Input;
 using PixiEditor.Extensions.CommonApi.Palettes;
 using PixiEditor.Extensions.CommonApi.Palettes;
@@ -33,15 +34,30 @@ internal partial class PaletteColorControl : UserControl
         set { SetValue(CornerRadiusProperty, value); }
         set { SetValue(CornerRadiusProperty, value); }
     }
     }
 
 
+    public ICommand DropCommand
+    {
+        get { return (ICommand)GetValue(DropCommandProperty); }
+        set { SetValue(DropCommandProperty, value); }
+    }
+
 
 
     public static readonly StyledProperty<CornerRadius> CornerRadiusProperty =
     public static readonly StyledProperty<CornerRadius> CornerRadiusProperty =
         AvaloniaProperty.Register<PaletteColorControl, CornerRadius>(nameof(CornerRadius), new CornerRadius(5f));
         AvaloniaProperty.Register<PaletteColorControl, CornerRadius>(nameof(CornerRadius), new CornerRadius(5f));
 
 
     private Point clickPoint;
     private Point clickPoint;
+    public static readonly StyledProperty<ICommand> DropCommandProperty = AvaloniaProperty.Register<PaletteColorControl, ICommand>("DropCommand");
 
 
     public PaletteColorControl()
     public PaletteColorControl()
     {
     {
         InitializeComponent();
         InitializeComponent();
+        
+        this.AddHandler(DragDrop.DropEvent, PaletteColor_OnDrop);
+    }
+
+    private void PaletteColor_OnDrop(object? sender, DragEventArgs e)
+    {
+        e.Source = this;
+        DropCommand?.Execute(e);
     }
     }
 
 
     private void PaletteColor_OnMouseMove(object? sender, PointerEventArgs e)
     private void PaletteColor_OnMouseMove(object? sender, PointerEventArgs e)

+ 5 - 5
src/PixiEditor/Views/Palettes/PaletteViewer.axaml

@@ -14,9 +14,8 @@
                                     IsVisible="{Binding !IsCompact, ElementName=paletteControl}"
                                     IsVisible="{Binding !IsCompact, ElementName=paletteControl}"
                                     ReplaceColorsCommand="{Binding ElementName=paletteControl, Path=ReplaceColorsCommand}"
                                     ReplaceColorsCommand="{Binding ElementName=paletteControl, Path=ReplaceColorsCommand}"
                                     HintColor="{Binding ElementName=paletteControl, Path=HintColor}" />
                                     HintColor="{Binding ElementName=paletteControl, Path=HintColor}" />
-            <Grid DragDrop.AllowDrop="True" ui1:DragDropEvents.DragEnter="Grid_PreviewDragEnter"
-                  ui1:DragDropEvents.DragLeave="Grid_PreviewDragLeave"
-                  ui1:DragDropEvents.Drop="Grid_Drop">
+            <Grid DragDrop.AllowDrop="True"
+                  Name="MainDropTarget">
                 <Grid.RowDefinitions>
                 <Grid.RowDefinitions>
                     <RowDefinition Height="35" />
                     <RowDefinition Height="35" />
                     <RowDefinition Height="5" />
                     <RowDefinition Height="5" />
@@ -72,7 +71,7 @@
                                                               ui:Translator.TooltipKey="PALETTE_COLOR_TOOLTIP"
                                                               ui:Translator.TooltipKey="PALETTE_COLOR_TOOLTIP"
                                                               DragDrop.AllowDrop="True" Color="{Binding}"
                                                               DragDrop.AllowDrop="True" Color="{Binding}"
                                                               Margin="2.5"
                                                               Margin="2.5"
-                                                              ui1:DragDropEvents.Drop="PaletteColor_Drop">
+                                                              DropCommand="{Binding ElementName=paletteControl, Path=DropColorCommand}">
                                     <palettes:PaletteColorControl.AssociatedKey>
                                     <palettes:PaletteColorControl.AssociatedKey>
                                         <MultiBinding Converter="{converters:IndexToAssociatedKeyConverter}">
                                         <MultiBinding Converter="{converters:IndexToAssociatedKeyConverter}">
                                             <Binding Path="." />
                                             <Binding Path="." />
@@ -122,7 +121,8 @@
                                                           ui:Translator.TooltipKey="PALETTE_COLOR_TOOLTIP"
                                                           ui:Translator.TooltipKey="PALETTE_COLOR_TOOLTIP"
                                                           DragDrop.AllowDrop="True" Color="{Binding}"
                                                           DragDrop.AllowDrop="True" Color="{Binding}"
                                                           Height="24" Width="24" CornerRadius="0"
                                                           Height="24" Width="24" CornerRadius="0"
-                                                          ui1:DragDropEvents.Drop="PaletteColor_Drop">
+                                                          DropCommand="{Binding ElementName=paletteControl, Path=DropColorCommand}">
+                                >
                                 <Interaction.Behaviors>
                                 <Interaction.Behaviors>
                                     <EventTriggerBehavior EventName="PointerReleased">
                                     <EventTriggerBehavior EventName="PointerReleased">
                                         <InvokeCommandAction
                                         <InvokeCommandAction

+ 11 - 2
src/PixiEditor/Views/Palettes/PaletteViewer.axaml.cs

@@ -10,6 +10,7 @@ using Avalonia.Input;
 using Avalonia.Interactivity;
 using Avalonia.Interactivity;
 using Avalonia.Media;
 using Avalonia.Media;
 using Avalonia.Platform.Storage;
 using Avalonia.Platform.Storage;
+using CommunityToolkit.Mvvm.Input;
 using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.Extensions.Common.Localization;
 using PixiEditor.Helpers.Extensions;
 using PixiEditor.Helpers.Extensions;
 using PixiEditor.Extensions.CommonApi.Palettes;
 using PixiEditor.Extensions.CommonApi.Palettes;
@@ -112,11 +113,19 @@ internal partial class PaletteViewer : UserControl
         get => GetValue(IsCompactProperty);
         get => GetValue(IsCompactProperty);
         set => SetValue(IsCompactProperty, value);
         set => SetValue(IsCompactProperty, value);
     }
     }
+    
+    public ICommand DropColorCommand { get; set; }
 
 
     public PaletteViewer()
     public PaletteViewer()
     {
     {
         InitializeComponent();
         InitializeComponent();
         SizeChanged += OnSizeChanged;
         SizeChanged += OnSizeChanged;
+        
+        MainDropTarget.AddHandler(DragDrop.DragEnterEvent, Grid_PreviewDragEnter);
+        MainDropTarget.AddHandler(DragDrop.DragLeaveEvent, Grid_PreviewDragLeave);
+        MainDropTarget.AddHandler(DragDrop.DropEvent, Grid_Drop);
+
+        DropColorCommand = new RelayCommand<DragEventArgs>(PaletteColor_Drop);
     }
     }
 
 
     private void OnSizeChanged(object? sender, SizeChangedEventArgs e)
     private void OnSizeChanged(object? sender, SizeChangedEventArgs e)
@@ -310,7 +319,7 @@ internal partial class PaletteViewer : UserControl
         return false;
         return false;
     }
     }
 
 
-    private void PaletteColor_Drop(object sender, DragEventArgs e)
+    private void PaletteColor_Drop( DragEventArgs e)
     {
     {
         if (e.Data.Contains(PaletteColorControl.PaletteColorDaoFormat))
         if (e.Data.Contains(PaletteColorControl.PaletteColorDaoFormat))
         {
         {
@@ -319,7 +328,7 @@ internal partial class PaletteViewer : UserControl
             PaletteColor paletteColor = PaletteColor.Parse(data);
             PaletteColor paletteColor = PaletteColor.Parse(data);
             if (Colors.Contains(paletteColor))
             if (Colors.Contains(paletteColor))
             {
             {
-                PaletteColorControl paletteColorControl = sender as PaletteColorControl;
+                PaletteColorControl paletteColorControl = e.Source as PaletteColorControl;
                 int currIndex = Colors.IndexOf(paletteColor);
                 int currIndex = Colors.IndexOf(paletteColor);
                 if (paletteColorControl != null)
                 if (paletteColorControl != null)
                 {
                 {

+ 1 - 1
tests/Directory.Build.props

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