Created
May 8, 2024 06:47
-
-
Save cdr9042/a8b89bb9c7b5ca309b3b6ad770f8a03e to your computer and use it in GitHub Desktop.
Use SearchablePopupContent to show a popup with a search field input, a TreeView containing the options will be populated using parameter string[] data. Example of usage is in RoadSegmentDataDrawer.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using JacatGames.ShapeShifting; | |
using UnityEditor; | |
using UnityEngine; | |
namespace JacatGames.ShapeShifting | |
{ | |
[CustomPropertyDrawer(typeof(RoadSegmentData))] | |
public class RoadSegmentDataDrawer : PropertyDrawer | |
{ | |
// You can define your dropdown options here | |
private string[] _dropdownOptions; | |
private string[] DropdownOptions | |
{ | |
get | |
{ | |
if (_dropdownOptions == null) | |
{ | |
_dropdownOptions = StageSetupConfig.GetConfig().SegmentsId.ToArray(); | |
} | |
return _dropdownOptions; | |
} | |
} | |
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) | |
{ | |
EditorGUI.BeginProperty(position, label, property); | |
// Drawing the label | |
position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label); | |
// Getting the 'Id' property | |
SerializedProperty idProperty = property.FindPropertyRelative("_id"); | |
// Checking if the property is null | |
if (idProperty != null) | |
{ | |
if (GUI.Button(position, idProperty.stringValue)) | |
{ | |
PopupWindow.Show(position, new SearchablePopupContent(idProperty, DropdownOptions)); | |
} | |
} | |
EditorGUI.EndProperty(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using System.Linq; | |
using UnityEditor; | |
using UnityEditor.IMGUI.Controls; | |
using UnityEngine; | |
public class SearchablePopupContent : PopupWindowContent | |
{ | |
private SerializedProperty property; | |
private SearchField searchField; | |
private MyTreeView treeView; | |
private List<string> data; | |
private bool focused; | |
public SearchablePopupContent(SerializedProperty property, string[] data) | |
{ | |
this.property = property; | |
this.data = data.ToList(); | |
searchField = new SearchField(); | |
treeView = new MyTreeView(new TreeViewState(), this.data, property, this); | |
treeView.Reload(); | |
searchField.SetFocus(); | |
searchField.downOrUpArrowKeyPressed += OnArrowKeyPressed; | |
} | |
private void OnArrowKeyPressed() | |
{ | |
treeView.SetFocusAndEnsureSelectedItem(); | |
} | |
public override void OnGUI(Rect rect) | |
{ | |
Rect searchRect = new Rect(rect.x, rect.y, rect.width, 25); | |
treeView.searchString = searchField.OnGUI(searchRect, treeView.searchString); | |
Rect treeViewRect = new Rect(rect.x, rect.y + 25, rect.width, rect.height - 25); | |
treeView.OnGUI(treeViewRect); | |
if (Event.current.type == EventType.KeyUp && Event.current.keyCode == KeyCode.Return) | |
{ | |
treeView.SelectItem(0); | |
} | |
} | |
private class MyTreeView : TreeView | |
{ | |
private List<string> data; | |
private SerializedProperty property; | |
private PopupWindowContent parentWindow; | |
private IList<TreeViewItem> filteredItems; | |
public MyTreeView(TreeViewState state, List<string> data, SerializedProperty property, PopupWindowContent parentWindow) : | |
base(state) | |
{ | |
this.data = data; | |
this.property = property; | |
this.parentWindow = parentWindow; | |
} | |
protected override IList<TreeViewItem> BuildRows(TreeViewItem root) | |
{ | |
filteredItems = new List<TreeViewItem>(); | |
for (int i = 0; i < data.Count; i++) | |
{ | |
if (string.IsNullOrEmpty(searchString) || data[i].Contains(searchString)) | |
{ | |
filteredItems.Add(new TreeViewItem { id = i, depth = 1, displayName = data[i] }); | |
} | |
} | |
SetupParentsAndChildrenFromDepths(root, filteredItems); | |
return filteredItems; | |
} | |
protected override void SingleClickedItem(int id) | |
{ | |
base.SingleClickedItem(id); | |
SelectItem(id); | |
// var item = FindItem(id, rootItem); | |
// OnSelectItem(item.displayName); | |
} | |
protected override TreeViewItem BuildRoot() | |
{ | |
var root = new TreeViewItem { id = 0, depth = -1, displayName = data[0] }; | |
var allItems = new List<TreeViewItem>(); | |
for (int i = 0; i < data.Count; i++) | |
{ | |
allItems.Add(new TreeViewItem { id = i + 1, depth = 0, displayName = data[i] }); | |
} | |
SetupParentsAndChildrenFromDepths(root, allItems); | |
return root; | |
} | |
public override void OnGUI(Rect rect) | |
{ | |
base.OnGUI(rect); | |
if (Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Return) | |
{ | |
// Set the value of the property when the Return key is pressed | |
var selecteds = (IEnumerable<int>)GetSelection(); | |
if (selecteds.Count() > 0) | |
{ | |
int id = selecteds.First(); | |
SelectItem(id); | |
} | |
} | |
} | |
public void SelectItem(int id) | |
{ | |
// Debug.Log($"selecting:{id}"); | |
var item = FindItem(id, rootItem); | |
// var item = filteredItems[id]; | |
// Debug.Log($"selected:{item.displayName}"); | |
OnSelectItem(item.displayName); | |
} | |
void OnSelectItem(string value) | |
{ | |
property.stringValue = value; | |
property.serializedObject.ApplyModifiedProperties(); | |
parentWindow.editorWindow.Close(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment