|
@@ -2,14 +2,20 @@
|
|
using System.Windows.Input;
|
|
using System.Windows.Input;
|
|
using Avalonia;
|
|
using Avalonia;
|
|
using Avalonia.Controls;
|
|
using Avalonia.Controls;
|
|
|
|
+using Avalonia.Controls.Metadata;
|
|
using Avalonia.Controls.Primitives;
|
|
using Avalonia.Controls.Primitives;
|
|
|
|
+using Avalonia.Input;
|
|
using Avalonia.Interactivity;
|
|
using Avalonia.Interactivity;
|
|
using Avalonia.Markup.Xaml;
|
|
using Avalonia.Markup.Xaml;
|
|
using CommunityToolkit.Mvvm.Input;
|
|
using CommunityToolkit.Mvvm.Input;
|
|
|
|
+using PixiEditor.Helpers.Nodes;
|
|
|
|
+using PixiEditor.Models.Nodes;
|
|
using PixiEditor.Numerics;
|
|
using PixiEditor.Numerics;
|
|
|
|
+using PixiEditor.Views.Input;
|
|
|
|
|
|
namespace PixiEditor.Views.Nodes;
|
|
namespace PixiEditor.Views.Nodes;
|
|
|
|
|
|
|
|
+[TemplatePart("PART_InputBox", typeof(InputBox))]
|
|
public partial class NodePicker : TemplatedControl
|
|
public partial class NodePicker : TemplatedControl
|
|
{
|
|
{
|
|
public static readonly StyledProperty<string> SearchQueryProperty = AvaloniaProperty.Register<NodePicker, string>(
|
|
public static readonly StyledProperty<string> SearchQueryProperty = AvaloniaProperty.Register<NodePicker, string>(
|
|
@@ -21,23 +27,23 @@ public partial class NodePicker : TemplatedControl
|
|
set => SetValue(SearchQueryProperty, value);
|
|
set => SetValue(SearchQueryProperty, value);
|
|
}
|
|
}
|
|
|
|
|
|
- public static readonly StyledProperty<ObservableCollection<Type>> AllNodeTypesProperty =
|
|
|
|
- AvaloniaProperty.Register<NodePicker, ObservableCollection<Type>>(
|
|
|
|
|
|
+ public static readonly StyledProperty<ObservableCollection<NodeTypeInfo>> AllNodeTypeInfosProperty =
|
|
|
|
+ AvaloniaProperty.Register<NodePicker, ObservableCollection<NodeTypeInfo>>(
|
|
"AllNodeTypes");
|
|
"AllNodeTypes");
|
|
|
|
|
|
- public static readonly StyledProperty<ObservableCollection<Type>> FilteredNodeTypesProperty =
|
|
|
|
- AvaloniaProperty.Register<NodePicker, ObservableCollection<Type>>(nameof(FilteredNodeTypes));
|
|
|
|
|
|
+ public static readonly StyledProperty<ObservableCollection<NodeTypeInfo>> FilteredNodeTypeInfosProperty =
|
|
|
|
+ AvaloniaProperty.Register<NodePicker, ObservableCollection<NodeTypeInfo>>(nameof(FilteredNodeTypeInfos));
|
|
|
|
|
|
- public ObservableCollection<Type> AllNodeTypes
|
|
|
|
|
|
+ public ObservableCollection<NodeTypeInfo> AllNodeTypeInfos
|
|
{
|
|
{
|
|
- get => GetValue(AllNodeTypesProperty);
|
|
|
|
- set => SetValue(AllNodeTypesProperty, value);
|
|
|
|
|
|
+ get => GetValue(AllNodeTypeInfosProperty);
|
|
|
|
+ set => SetValue(AllNodeTypeInfosProperty, value);
|
|
}
|
|
}
|
|
|
|
|
|
- public ObservableCollection<Type> FilteredNodeTypes
|
|
|
|
|
|
+ public ObservableCollection<NodeTypeInfo> FilteredNodeTypeInfos
|
|
{
|
|
{
|
|
- get { return (ObservableCollection<Type>)GetValue(FilteredNodeTypesProperty); }
|
|
|
|
- set { SetValue(FilteredNodeTypesProperty, value); }
|
|
|
|
|
|
+ get => GetValue(FilteredNodeTypeInfosProperty);
|
|
|
|
+ set => SetValue(FilteredNodeTypeInfosProperty, value);
|
|
}
|
|
}
|
|
|
|
|
|
public static readonly StyledProperty<ICommand> SelectNodeCommandProperty = AvaloniaProperty.Register<NodePicker, ICommand>(
|
|
public static readonly StyledProperty<ICommand> SelectNodeCommandProperty = AvaloniaProperty.Register<NodePicker, ICommand>(
|
|
@@ -48,27 +54,72 @@ public partial class NodePicker : TemplatedControl
|
|
get => GetValue(SelectNodeCommandProperty);
|
|
get => GetValue(SelectNodeCommandProperty);
|
|
set => SetValue(SelectNodeCommandProperty, value);
|
|
set => SetValue(SelectNodeCommandProperty, value);
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
static NodePicker()
|
|
static NodePicker()
|
|
{
|
|
{
|
|
SearchQueryProperty.Changed.Subscribe(OnSearchQueryChanged);
|
|
SearchQueryProperty.Changed.Subscribe(OnSearchQueryChanged);
|
|
- AllNodeTypesProperty.Changed.Subscribe(OnAllNodeTypesChanged);
|
|
|
|
|
|
+ AllNodeTypeInfosProperty.Changed.Subscribe(OnAllNodeTypesChanged);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
|
|
|
+ {
|
|
|
|
+ var inputBox = e.NameScope.Find<InputBox>("PART_InputBox");
|
|
|
|
+
|
|
|
|
+ inputBox.KeyDown += OnInputBoxKeyDown;
|
|
}
|
|
}
|
|
|
|
|
|
private static void OnSearchQueryChanged(AvaloniaPropertyChangedEventArgs e)
|
|
private static void OnSearchQueryChanged(AvaloniaPropertyChangedEventArgs e)
|
|
{
|
|
{
|
|
- if (e.Sender is NodePicker nodePicker)
|
|
|
|
|
|
+ if (e.Sender is not NodePicker nodePicker)
|
|
{
|
|
{
|
|
- nodePicker.FilteredNodeTypes = new ObservableCollection<Type>(nodePicker.AllNodeTypes
|
|
|
|
- .Where(x => x.Name.ToLower().Contains(nodePicker.SearchQuery.ToLower())));
|
|
|
|
|
|
+ return;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ if (NodeAbbreviation.IsAbbreviation(nodePicker.SearchQuery, out var abbreviationName))
|
|
|
|
+ {
|
|
|
|
+ nodePicker.FilteredNodeTypeInfos = new ObservableCollection<NodeTypeInfo>(nodePicker.AllNodeTypeInfos
|
|
|
|
+ .Where(x => SearchComparer(x, abbreviationName)));
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ nodePicker.FilteredNodeTypeInfos = new ObservableCollection<NodeTypeInfo>(nodePicker.AllNodeTypeInfos
|
|
|
|
+ .Where(x => SearchComparer(x, nodePicker.SearchQuery)));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ bool SearchComparer(NodeTypeInfo x, string lookFor) =>
|
|
|
|
+ x.FinalPickerName.Value.Replace(" ", "")
|
|
|
|
+ .Contains(lookFor.Replace(" ", ""), StringComparison.OrdinalIgnoreCase);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ private void OnInputBoxKeyDown(object? sender, KeyEventArgs e)
|
|
|
|
+ {
|
|
|
|
+ if (e.Key != Key.Enter)
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var nodes = NodeAbbreviation.FromString(SearchQuery, AllNodeTypeInfos);
|
|
|
|
+
|
|
|
|
+ if (nodes == null && FilteredNodeTypeInfos.Count > 0)
|
|
|
|
+ {
|
|
|
|
+ SelectNodeCommand.Execute(FilteredNodeTypeInfos[0]);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ foreach (var node in nodes)
|
|
|
|
+ {
|
|
|
|
+ SelectNodeCommand.Execute(node);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
private static void OnAllNodeTypesChanged(AvaloniaPropertyChangedEventArgs e)
|
|
private static void OnAllNodeTypesChanged(AvaloniaPropertyChangedEventArgs e)
|
|
{
|
|
{
|
|
if (e.Sender is NodePicker nodePicker)
|
|
if (e.Sender is NodePicker nodePicker)
|
|
{
|
|
{
|
|
- nodePicker.FilteredNodeTypes = new ObservableCollection<Type>(nodePicker.AllNodeTypes);
|
|
|
|
|
|
+ nodePicker.FilteredNodeTypeInfos = new ObservableCollection<NodeTypeInfo>(nodePicker.AllNodeTypeInfos);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|