Skip to content

Instantly share code, notes, and snippets.

@Schwapo
Last active September 13, 2022 10:11
Show Gist options
  • Save Schwapo/3c1a55462a581da46c3055de6bd0586e to your computer and use it in GitHub Desktop.
Save Schwapo/3c1a55462a581da46c3055de6bd0586e to your computer and use it in GitHub Desktop.
An extension method that allows you to change the current search term of the searchable attribute by calling: InspectorProperty.SearchFor(SearchTerm)
#if UNITY_EDITOR
using System;
using System.Collections.Generic;
using System.Reflection;
using Sirenix.OdinInspector;
using Sirenix.OdinInspector.Editor;
using UnityEngine;
public static class InspectorPropertyExtensions
{
private const BindingFlags PublicInstance = BindingFlags.Public | BindingFlags.Instance;
private const BindingFlags PrivateInstance = BindingFlags.NonPublic | BindingFlags.Instance;
private static readonly Dictionary<InspectorProperty, SearchDelegates> Delegates = new Dictionary<InspectorProperty, SearchDelegates>();
public static void SearchFor(this InspectorProperty property, string searchTerm)
{
if (!property.Attributes.HasAttribute<SearchableAttribute>())
{
Debug.LogException(new Exception($"The property '{property.Name}' has no [Searchable] attribute applied to it."));
return;
}
if (Delegates.TryGetValue(property, out var delegates))
{
delegates.UpdateSearch?.Invoke(searchTerm);
delegates.ScheduleUpdate?.Invoke();
return;
}
delegates = property.ChildResolver is ICollectionResolver
? SetupCollectionDelegates(property)
: SetupDelegates(property);
delegates.UpdateSearch?.Invoke(searchTerm);
delegates.ScheduleUpdate?.Invoke();
Delegates.Add(property, delegates);
}
private static SearchDelegates SetupCollectionDelegates(InspectorProperty property)
{
var collectionDrawer = property.GetActiveDrawerChain().Current;
var listDrawerConfigInfo = collectionDrawer.GetType().GetField("info", PrivateInstance).GetValue(collectionDrawer);
var filteredChildren = listDrawerConfigInfo.GetType().GetField("FilteredChildren", PublicInstance).GetValue(listDrawerConfigInfo);
var searchFilter = filteredChildren.GetType().GetField("SearchFilter", PublicInstance).GetValue(filteredChildren);
searchFilter.GetType().GetField("Property", PublicInstance).SetValue(searchFilter, property);
var updateSearch = (Action<string>)Delegate.CreateDelegate(typeof(Action<string>), searchFilter, "UpdateSearch");
var scheduleUpdate = (Action)Delegate.CreateDelegate(typeof(Action), filteredChildren, "ScheduleUpdate");
return new SearchDelegates()
{
UpdateSearch = updateSearch,
ScheduleUpdate = scheduleUpdate,
};
}
private static SearchDelegates SetupDelegates(InspectorProperty property)
{
property.Tree.SetSearchable(true);
var searchFilter = typeof(PropertyTree).GetField("searchFilter", PrivateInstance).GetValue(property.Tree);
var updateSearch = (Action<string>)Delegate.CreateDelegate(typeof(Action<string>), searchFilter, "UpdateSearch");
return new SearchDelegates()
{
UpdateSearch = updateSearch,
ScheduleUpdate = null,
};
}
private struct SearchDelegates
{
public Action<string> UpdateSearch;
public Action ScheduleUpdate;
}
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment