Browse Source

Categories filter

flabbet 11 months ago
parent
commit
3e894040ff

+ 1 - 1
src/PixiEditor/Styles/Templates/NodePicker.axaml

@@ -22,7 +22,7 @@
                         Text="{Binding SearchQuery, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
                         Name="PART_InputBox" />
                     
-                    <ListBox Grid.Column="0" Grid.Row="1" ItemsSource="{TemplateBinding AllCategories}" 
+                    <ListBox Grid.Column="0" Grid.Row="1" ItemsSource="{TemplateBinding FilteredCategories}" 
                              SelectedItem="{Binding SelectedCategory, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}">
                         <ListBox.ItemTemplate>
                             <DataTemplate>

+ 49 - 7
src/PixiEditor/Views/Nodes/NodePicker.cs

@@ -58,6 +58,16 @@ public partial class NodePicker : TemplatedControl
         AvaloniaProperty.Register<NodePicker, ObservableCollection<string>>(
             nameof(AllCategories));
 
+    public static readonly StyledProperty<ObservableCollection<string>> FilteredCategoriesProperty =
+        AvaloniaProperty.Register<NodePicker, ObservableCollection<string>>(
+            nameof(FilteredCategories));
+
+    public ObservableCollection<string> FilteredCategories
+    {
+        get => GetValue(FilteredCategoriesProperty);
+        set => SetValue(FilteredCategoriesProperty, value);
+    }
+
     public ObservableCollection<string> AllCategories
     {
         get => GetValue(AllCategoriesProperty);
@@ -89,7 +99,7 @@ public partial class NodePicker : TemplatedControl
     private ScrollViewer? _scrollViewer;
 
     private const string MiscCategory = "MISC";
-    
+
     private bool SuppressCategoryChanged { get; set; }
 
     static NodePicker()
@@ -146,6 +156,9 @@ public partial class NodePicker : TemplatedControl
         {
             if (string.IsNullOrEmpty(nodePicker.SearchQuery))
             {
+                nodePicker.FilteredCategories = new ObservableCollection<string>(nodePicker.AllCategories);
+                UpdateCategoryDict(nodePicker);
+                
                 nodePicker.FilteredNodeTypeInfos =
                     OrderByCategory(nodePicker);
             }
@@ -153,6 +166,8 @@ public partial class NodePicker : TemplatedControl
             {
                 nodePicker.FilteredNodeTypeInfos = new ObservableCollection<NodeTypeInfo>(nodePicker.AllNodeTypeInfos
                     .Where(x => SearchComparer(x, nodePicker.SearchQuery)));
+                
+                FilterCategories(nodePicker);
             }
         }
 
@@ -163,12 +178,21 @@ public partial class NodePicker : TemplatedControl
                 .Contains(lookFor.Replace(" ", ""), StringComparison.OrdinalIgnoreCase);
     }
 
+    private static void UpdateCategoryDict(NodePicker nodePicker)
+    {
+        nodePicker._categoryIndexes = nodePicker.FilteredCategories
+            .Select((x, i) => (x, i))
+            .ToDictionary(x => x.x, x => x.i);
+    }
+
     private static ObservableCollection<NodeTypeInfo> OrderByCategory(NodePicker nodePicker)
     {
         return new ObservableCollection<NodeTypeInfo>(nodePicker.AllNodeTypeInfos
             .Where(x => x.Category != null)
             .OrderBy(
-                x => string.IsNullOrEmpty(x.Category) ? nodePicker._categoryIndexes[MiscCategory] : nodePicker._categoryIndexes[x.Category]));
+                x => string.IsNullOrEmpty(x.Category)
+                    ? nodePicker._categoryIndexes[MiscCategory]
+                    : nodePicker._categoryIndexes[x.Category]));
     }
 
     private void OnInputBoxKeyDown(object? sender, KeyEventArgs e)
@@ -204,13 +228,27 @@ public partial class NodePicker : TemplatedControl
 
             nodePicker.AllCategories.Add(MiscCategory);
 
-            nodePicker._categoryIndexes = nodePicker.AllCategories
-                .Select((x, i) => (x, i))
-                .ToDictionary(x => x.x, x => x.i);
+            nodePicker.FilteredCategories = new ObservableCollection<string>(nodePicker.AllCategories);
+
+            UpdateCategoryDict(nodePicker); 
 
             nodePicker.FilteredNodeTypeInfos = OrderByCategory(nodePicker);
         }
     }
+    
+    private static void FilterCategories(NodePicker nodePicker)
+    {
+        nodePicker.FilteredCategories = new ObservableCollection<string>(nodePicker.AllCategories
+            .Where(x => nodePicker.FilteredNodeTypeInfos.Any(y => y.Category == x)));
+        
+        bool miscCategoryExists = nodePicker.FilteredNodeTypeInfos.Any(x => string.IsNullOrEmpty(x.Category));
+        if (miscCategoryExists)
+        {
+            nodePicker.FilteredCategories.Add(MiscCategory);
+        }
+        
+        UpdateCategoryDict(nodePicker); 
+    }
 
     private static void SelectedCategoryChanged(AvaloniaPropertyChangedEventArgs e)
     {
@@ -220,14 +258,18 @@ public partial class NodePicker : TemplatedControl
             {
                 return;
             }
-            
+
             int indexOfFirstItemInCategory = nodePicker.FilteredNodeTypeInfos
                 .Select((x, i) => (x, i))
                 .FirstOrDefault(x => x.x.Category == nodePicker.SelectedCategory).i;
 
             double normalizedY = indexOfFirstItemInCategory / (double)nodePicker.FilteredNodeTypeInfos.Count;
+
+            double y = normalizedY * nodePicker._scrollViewer.ScrollBarMaximum.Y;
             
-            nodePicker.ScrollOffset = new Vector(0, normalizedY * nodePicker._scrollViewer.ScrollBarMaximum.Y);
+            if(double.IsNaN(y)) return;
+
+            nodePicker.ScrollOffset = new Vector(0, y);
         }
     }
 }