소스 검색

Improved picking with move tool

Krzysztof Krysiński 1 개월 전
부모
커밋
522911f93b

+ 20 - 7
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/TransformSelectedExecutor.cs

@@ -166,17 +166,30 @@ internal class TransformSelectedExecutor : UpdateableChangeExecutor, ITransforma
             }
         }
 
-        var topMostWithinClick = QueryLayers<ILayerHandler>(args.PositionOnCanvas);
+        var topMostWithinClick = QueryLayers<IStructureMemberHandler>(args.PositionOnCanvas);
 
-        var nonSelected = topMostWithinClick.Where(x => x != document.SelectedStructureMember
-                                                        && !document.SoftSelectedStructureMembers.Contains(x))
-            .ToArray();
+        var orderedBySize = topMostWithinClick
+            .Where(x => x.TightBounds is not null)
+            .OrderByDescending(x => x.TightBounds?.Size.Length + (x is IFolderHandler ? 1 : 0) ?? double.MaxValue)
+            .ToList();
+
+        var nonSelected = orderedBySize.Where(x => x != document.SelectedStructureMember
+                                              && !document.SoftSelectedStructureMembers.Contains(x));
+
+        var smallestSizeDifferenceList = nonSelected
+            .Where(x => x.TightBounds is not null && (x.TightBounds.Value.Size.Length + (x is IFolderHandler ? 1 : 0)) <= (document.SelectedStructureMember?.TightBounds?.Size.Length ?? double.MaxValue))
+            .ToList();
+
+        if (!smallestSizeDifferenceList.Any() && orderedBySize.Count != 0)
+        {
+            smallestSizeDifferenceList.Add(orderedBySize.First());
+        }
 
         bool isHoldingShift = args.KeyModifiers.HasFlag(KeyModifiers.Shift);
 
-        if (nonSelected.Any())
+        if (smallestSizeDifferenceList.Any())
         {
-            var topMost = nonSelected.First();
+            var topMost = smallestSizeDifferenceList.First();
 
             if (!isHoldingShift)
             {
@@ -220,7 +233,7 @@ internal class TransformSelectedExecutor : UpdateableChangeExecutor, ITransforma
         DuplicateIfRequired();
     }
 
-    private void Deselect(List<ILayerHandler> topMostWithinClick)
+    private void Deselect(List<IStructureMemberHandler> topMostWithinClick)
     {
         var topMost = topMostWithinClick.FirstOrDefault();
         if (topMost is not null)

+ 5 - 5
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/UpdateableChangeExecutor.cs

@@ -63,9 +63,9 @@ internal abstract class UpdateableChangeExecutor
     public virtual void OnColorChanged(Color color, bool primary) { }
     public virtual void OnMembersSelected(List<Guid> memberGuids) { }
 
-    protected T[] QueryLayers<T>(VecD pos) where T : ILayerHandler
+    protected T[] QueryLayers<T>(VecD pos) where T : IStructureMemberHandler
     {
-        var allLayers = document.StructureHelper.GetAllLayers();
+        var allLayers = document.StructureHelper.GetAllMembers();
         FilterOutInvisible(allLayers);
         var topMostWithinClick = allLayers.Where(x =>
                 x is T { TightBounds: not null } &&
@@ -74,11 +74,11 @@ internal abstract class UpdateableChangeExecutor
         return topMostWithinClick.Cast<T>().ToArray();
     }
 
-    private void FilterOutInvisible(List<ILayerHandler> allLayers)
+    private void FilterOutInvisible(List<IStructureMemberHandler> allLayers)
     {
-        allLayers.RemoveAll(x => x is ILayerHandler { IsVisibleBindable: false });
+        allLayers.RemoveAll(x => x is IStructureMemberHandler { IsVisibleBindable: false });
 
-        List<ILayerHandler> toRemove = new List<ILayerHandler>();
+        List<IStructureMemberHandler> toRemove = new List<IStructureMemberHandler>();
         foreach (var layer in allLayers)
         {
             var parents = document.StructureHelper.GetParents(layer.Id);

+ 12 - 1
src/PixiEditor/ViewModels/SubViewModels/ToolsViewModel.cs

@@ -369,7 +369,18 @@ internal class ToolsViewModel : SubViewModel<ViewModelMain>, IToolsHandler
         if (!typeof(ToolViewModel).IsAssignableFrom(toolType))
             throw new ArgumentException($"'{toolType}' does not inherit from {typeof(ToolViewModel)}");
         IToolHandler foundTool = ActiveToolSet!.Tools.FirstOrDefault(x => x.GetType().IsAssignableFrom(toolType));
-        if (foundTool == null) return;
+        if (foundTool == null)
+        {
+            foundTool = allTools.FirstOrDefault(x => x.GetType().IsAssignableFrom(toolType));
+            if(foundTool == null)
+                return;
+
+            var toolset = AllToolSets.FirstOrDefault(x => x.Tools.Contains(foundTool));
+            if (toolset is not null)
+            {
+                SetActiveToolSet(toolset);
+            }
+        }
 
         SetActiveTool(foundTool, transient, sourceInfo);
     }