Skip to content

Commit 728914e

Browse files
committed
Add setting to always search the root category - fixes #9
1 parent faeb7d7 commit 728914e

7 files changed

Lines changed: 48 additions & 15 deletions

File tree

ComponentSelectorAdditions/Events/EnumerateCategoriesEvent.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
namespace ComponentSelectorAdditions.Events
88
{
9-
public sealed class EnumerateCategoriesEvent : CancelableSortedItemsEvent<CategoryNode<Type>>
9+
public sealed class EnumerateCategoriesEvent : CancelableSortedItemsEvent<CategoryNode<Type>>, IEnumerateSelectorResultEvent
1010
{
1111
public override IEnumerable<CategoryNode<Type>> Items
1212
=> sortableItems.OrderBy(entry => entry.Value)

ComponentSelectorAdditions/Events/EnumerateComponentsEvent.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
namespace ComponentSelectorAdditions.Events
99
{
10-
public sealed class EnumerateComponentsEvent : CancelableSortedItemsEvent<ComponentResult>
10+
public sealed class EnumerateComponentsEvent : CancelableSortedItemsEvent<ComponentResult>, IEnumerateSelectorResultEvent
1111
{
1212
public Predicate<Type> ComponentFilter { get; }
1313

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using FrooxEngine;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Text;
5+
6+
namespace ComponentSelectorAdditions.Events
7+
{
8+
public interface IEnumerateSelectorResultEvent
9+
{
10+
public SelectorPath Path { get; }
11+
public CategoryNode<Type> RootCategory { get; }
12+
public ComponentSelector Selector { get; }
13+
}
14+
}

ComponentSelectorAdditions/Injector.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ private static void BuildCategoryUI(ComponentSelector selector, UIBuilder ui, Se
107107

108108
if (rootCategory is null)
109109
{
110-
selector._rootPath.Value = null;
110+
selector._rootPath.Value = null!;
111111
selectorData.CurrentPath = new SelectorPath("/", selectorData.CurrentPath.Search, false, null, true);
112112
rootCategory = WorkerInitializer.ComponentLibrary;
113113
}
@@ -224,7 +224,7 @@ private static bool BuildUIPrefix(ComponentSelector __instance, string path, boo
224224

225225
__instance._uiRoot.Target.DestroyChildren();
226226
__instance._customGenericArguments.Clear();
227-
__instance._genericType.Value = null;
227+
__instance._genericType.Value = null!;
228228

229229
var ui = SetupStyle(new UIBuilder(__instance._uiRoot.Target));
230230

@@ -314,8 +314,8 @@ private static BuildCustomGenericBuilder OnBuildCustomGenericBuilder(ComponentSe
314314
if (!eventData.AddsCreateCustomTypeButton)
315315
Logger.Warn(() => "No event handler handled adding a create custom type button!");
316316

317-
selector._customGenericTypeLabel.Target = eventData.CreateCustomTypeButton?.Label.Content;
318-
selector._customGenericTypeColor.Target = eventData.CreateCustomTypeButton?.BaseColor;
317+
selector._customGenericTypeLabel.Target = eventData.CreateCustomTypeButton?.Label.Content!;
318+
selector._customGenericTypeColor.Target = eventData.CreateCustomTypeButton?.BaseColor!;
319319

320320
return eventData;
321321
}
@@ -465,7 +465,7 @@ private static bool SetupUIPrefix(ComponentSelector __instance, LocaleString tit
465465
if (selectorData.HasSearchBar)
466466
selectorData.SearchBar.Text.Content.OnValueChange += MakeBuildUICall(__instance, selectorData);
467467

468-
__instance.BuildUI(null);
468+
__instance.BuildUI(null!);
469469

470470
return false;
471471
}

ComponentSelectorAdditions/SearchBar.cs

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ namespace ComponentSelectorAdditions
1818
internal sealed class SearchBar : ConfiguredResoniteMonkey<SearchBar, SearchConfig>, IEventHandler<BuildSelectorHeaderEvent>,
1919
ICancelableEventHandler<EnumerateCategoriesEvent>, ICancelableEventHandler<EnumerateComponentsEvent>
2020
{
21+
private const string ProtoFluxPath = "/ProtoFlux/Runtimes/Execution/Nodes";
2122
private static readonly char[] _searchSplits = new[] { ' ', ',', '+', '|' };
2223
public override bool CanBeDisabled => true;
2324
public int Priority => HarmonyLib.Priority.VeryHigh;
@@ -39,7 +40,7 @@ public void Handle(BuildSelectorHeaderEvent eventData)
3940
searchLayout.DestroyWhenLocalUserLeaves();
4041

4142
ui.Style.FlexibleWidth = 1;
42-
var textField = ui.TextField(null, parseRTF: false);
43+
var textField = ui.TextField(null!, parseRTF: false);
4344
var details = new SelectorSearchBar(searchLayout, textField.Editor.Target, () => ConfigSection.SearchRefreshDelay);
4445
eventData.SearchBar = details;
4546

@@ -48,20 +49,23 @@ public void Handle(BuildSelectorHeaderEvent eventData)
4849

4950
ui.Style.FlexibleWidth = -1;
5051
ui.Style.ButtonTextAlignment = Alignment.MiddleCenter;
51-
ui.LocalActionButton("∅", _ => details.Content = null);
52+
53+
var clearButton = ui.Button("∅");
54+
var clearAction = clearButton.Slot.AttachComponent<ButtonValueSet<string>>();
55+
clearAction.TargetValue.Target = details.Text.Content;
5256

5357
ui.PopStyle();
5458
ui.NestOut();
5559
}
5660

5761
public void Handle(EnumerateCategoriesEvent eventData)
5862
{
59-
if (!eventData.Path.HasSearch || (eventData.Path.IsSelectorRoot && eventData.Path.Search.Length < 3))
63+
if (!eventData.Path.HasSearch || ((eventData.Path.IsSelectorRoot || ConfigSection.AlwaysSearchRoot) && eventData.Path.Search.Length < 3))
6064
return;
6165

6266
var search = eventData.Path.Search.Split(_searchSplits, StringSplitOptions.RemoveEmptyEntries);
6367

64-
foreach (var category in SearchCategories(eventData.RootCategory, search))
68+
foreach (var category in SearchCategories(PickSearchCategory(eventData), search))
6569
eventData.AddItem(category);
6670

6771
eventData.Canceled = true;
@@ -73,10 +77,12 @@ public void Handle(EnumerateComponentsEvent eventData)
7377
return;
7478

7579
var search = eventData.Path.Search.Split(_searchSplits, StringSplitOptions.RemoveEmptyEntries);
76-
var results = eventData.RootCategory.Elements
77-
.Select(type => (Category: eventData.RootCategory, Type: type, Matches: SearchContains(type.Name, search)))
80+
var searchCategory = PickSearchCategory(eventData);
81+
82+
var results = searchCategory.Elements
83+
.Select(type => (Category: searchCategory, Type: type, Matches: SearchContains(type.Name, search)))
7884
.Concat(
79-
SearchCategories(eventData.RootCategory)
85+
SearchCategories(searchCategory)
8086
.SelectMany(category => category.Elements
8187
.Select(type => (Category: category, Type: type, Matches: SearchContains(type.Name, search)))))
8288
.Where(match => match.Matches > 0)
@@ -141,5 +147,16 @@ private static IEnumerable<CategoryNode<Type>> SearchCategories(CategoryNode<Typ
141147

142148
private static int SearchContains(string haystack, string[] needles)
143149
=> needles.Count(needle => CultureInfo.InvariantCulture.CompareInfo.IndexOf(haystack, needle, CompareOptions.IgnoreCase) >= 0);
150+
151+
private CategoryNode<Type> PickSearchCategory(IEnumerateSelectorResultEvent eventData)
152+
{
153+
var isProtoFlux = eventData.Path.Path.StartsWith(ProtoFluxPath);
154+
155+
return ConfigSection.AlwaysSearchRoot
156+
? (isProtoFlux
157+
? WorkerInitializer.ComponentLibrary.GetSubcategory(ProtoFluxPath)
158+
: WorkerInitializer.ComponentLibrary)
159+
: eventData.RootCategory;
160+
}
144161
}
145162
}

ComponentSelectorAdditions/SearchConfig.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ namespace ComponentSelectorAdditions
2020
/// </summary>
2121
public sealed class SearchConfig : ConfigSection
2222
{
23+
private static readonly DefiningConfigKey<bool> _alwaysSearchRoot = new("AlwaysSearchRoot", "Always starts searching from the root category, regardless of the current one.", () => false);
2324
private static readonly Dictionary<string, bool> _excludedCategories = new(StringComparer.OrdinalIgnoreCase);
2425

2526
private static readonly DefiningConfigKey<int> _maxResultCount = new("MaxResultCount", "The maximum number of component / node results to display. 'Better' results are listed first. Categories don't count.", () => 64)
@@ -49,6 +50,7 @@ public sealed class SearchConfig : ConfigSection
4950
/// <inheritdoc/>
5051
public override Version Version { get; } = new(1, 0, 0);
5152

53+
internal bool AlwaysSearchRoot => _alwaysSearchRoot;
5254
internal int MaxResultCount => _maxResultCount;
5355
internal int SearchRefreshDelay => (int)(1000 * _searchRefreshDelay);
5456

ComponentSelectorAdditions/SelectorSearchBar.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public bool Active
3333
public string? Content
3434
{
3535
get => Active ? Text.Content.Value : null;
36-
set => Text.Content.Value = value;
36+
set => Text.Content.Value = value!;
3737
}
3838

3939
/// <summary>

0 commit comments

Comments
 (0)