Browse Source

feat(DevTools): Add Avalonia_DevTools_Selectors Clipoard format for quicks IDE recongnize. (#14603)

workgroupengineering 1 year ago
parent
commit
a3762291c1

+ 15 - 0
src/Avalonia.Diagnostics/Diagnostics/Constants.cs

@@ -0,0 +1,15 @@
+namespace Avalonia.Diagnostics;
+
+internal static  class Constants
+{
+    /// <summary>
+    /// DevTools Clipboard data format
+    /// </summary>
+    static public class DataFormats
+    {
+        /// <summary>
+        /// Clipboard data format for the selector. It is added for quick format recognition in IDEs
+        /// </summary>
+        public const string Avalonia_DevTools_Selector = nameof(Avalonia_DevTools_Selector);
+    }
+}

+ 11 - 11
src/Avalonia.Diagnostics/Diagnostics/ViewModels/TreePageViewModel.cs

@@ -25,7 +25,7 @@ namespace Avalonia.Diagnostics.ViewModels
         }
 
         public event EventHandler<string>? ClipboardCopyRequested;
-        
+
         public MainViewModel MainView { get; }
 
         public FilterViewModel PropertiesFilter { get; }
@@ -117,11 +117,11 @@ namespace Avalonia.Diagnostics.ViewModels
             if (currentVisual is not null)
             {
                 var selector = GetVisualSelector(currentVisual);
-                
+
                 ClipboardCopyRequested?.Invoke(this, selector);
             }
         }
-        
+
         public void CopySelectorFromTemplateParent()
         {
             var parts = new List<string>();
@@ -130,7 +130,7 @@ namespace Avalonia.Diagnostics.ViewModels
             while (currentVisual is not null)
             {
                 parts.Add(GetVisualSelector(currentVisual));
-                
+
                 currentVisual = currentVisual.TemplatedParent as Visual;
             }
 
@@ -148,7 +148,7 @@ namespace Avalonia.Diagnostics.ViewModels
             if (SelectedNode is { } selectedNode)
             {
                 ExpandNode(selectedNode);
-                
+
                 var stack = new Stack<TreeNode>();
                 stack.Push(selectedNode);
 
@@ -192,8 +192,8 @@ namespace Avalonia.Diagnostics.ViewModels
         {
             (SelectedNode?.Visual as Control)?.BringIntoView();
         }
-        
-        
+
+
         public void Focus()
         {
             (SelectedNode?.Visual as Control)?.Focus();
@@ -205,10 +205,10 @@ namespace Avalonia.Diagnostics.ViewModels
             var classes = string.Concat(visual.Classes
                 .Where(c => !c.StartsWith(":"))
                 .Select(c => '.' + c));
-            var typeName = StyledElement.GetStyleKey(visual);
-
-            return $"{typeName}{name}{classes}";
-        } 
+            var pseudo = string.Concat(visual.Classes.Where(c => c[0] == ':').Select(c => c));
+            var type = StyledElement.GetStyleKey(visual);
+            return $$"""{{{type.Assembly.FullName}}}{{type.Namespace}}|{{type.Name}}{{name}}{{classes}}{{pseudo}}""";
+        }
 
         private void ExpandNode(TreeNode? node)
         {

+ 33 - 2
src/Avalonia.Diagnostics/Diagnostics/Views/TreePageView.xaml.cs

@@ -75,9 +75,40 @@ namespace Avalonia.Diagnostics.Views
             AvaloniaXamlLoader.Load(this);
         }
 
-        private void OnClipboardCopyRequested(object? sender, string e)
+        private void OnClipboardCopyRequested(object? sender, string selector)
         {
-            TopLevel.GetTopLevel(this)?.Clipboard?.SetTextAsync(e);
+            if (TopLevel.GetTopLevel(this)?.Clipboard is { } clipboard)
+            {
+                var @do = new DataObject();
+                var text = ToText(selector);
+                @do.Set(DataFormats.Text, text);
+                @do.Set(Constants.DataFormats.Avalonia_DevTools_Selector, selector);
+                clipboard.SetDataObjectAsync(@do);
+            }
+        }
+
+        private static string ToText(string text)
+        {
+            var sb = new System.Text.StringBuilder();
+            var bufferStartIndex = -1;
+            for (var ic = 0; ic < text.Length; ic++)
+            {
+                var c = text[ic];
+                switch (c)
+                {
+                    case '{':
+                        bufferStartIndex = sb.Length;
+                        break;
+                    case '}' when bufferStartIndex > -1:
+                        sb.Remove(bufferStartIndex, sb.Length - bufferStartIndex);
+                        bufferStartIndex = sb.Length;
+                        break;
+                    default:
+                        sb.Append(c);
+                        break;
+                }
+            }
+            return sb.ToString();
         }
     }
 }