You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
123 lines
4.6 KiB
123 lines
4.6 KiB
using UnityEngine; |
|
using UnityEditor; |
|
|
|
namespace Unity.Burst.Editor |
|
{ |
|
internal static class LabeledPopup |
|
{ |
|
// Because the function given to dropdown menu needs takes its parameter |
|
// in the form of an object, we need someway to wrap the integer into one. |
|
private struct IntegerWrapper |
|
{ |
|
public int Value { get; } |
|
|
|
public IntegerWrapper(int v) |
|
{ |
|
Value = v; |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// Enables having several popup menus functioning independently at the same time. |
|
/// </summary> |
|
private class PopperCallBack |
|
{ |
|
public static PopperCallBack Instance = null; |
|
|
|
/// <summary> |
|
/// Name of the event send when an index have been chosen. |
|
/// </summary> |
|
private const string IndexChangeEventName = "PopperChangingIndex"; |
|
|
|
private readonly int _controlID; |
|
private int _selectedIdx; |
|
private readonly GUIView _view; |
|
|
|
public PopperCallBack(int controlID) |
|
{ |
|
_controlID = controlID; |
|
_selectedIdx = -1; |
|
_view = GUIView.current; |
|
} |
|
|
|
/// <summary> |
|
/// Tries to get selection chosen by dropdown menu <see cref="controlID"/>. |
|
/// </summary> |
|
/// <param name="controlId">ID of popup menu.</param> |
|
/// <param name="selectedIdx">Current selected index.</param> |
|
/// <returns> |
|
/// Either the selected target, or the <see cref="selectedIdx"/> |
|
/// if none were chosen yet. |
|
/// </returns> |
|
internal static int GetSelectionValue(int controlId, int selectedIdx) |
|
{ |
|
var selected = selectedIdx; |
|
|
|
// A command event with message IndexChangeEvent will be sent whenever a choice on |
|
// the dropdown menu has been made. So if this is not the case return whatever index was given |
|
var evt = Event.current; |
|
if (evt.type != EventType.ExecuteCommand || evt.commandName != IndexChangeEventName) return selected; |
|
|
|
// If this is the popup opened right now: Set the selection idx appropriately |
|
if (Instance != null && controlId == Instance._controlID) |
|
{ |
|
selected = Instance._selectedIdx; |
|
Instance = null; |
|
} |
|
|
|
return selected; |
|
} |
|
|
|
/// <summary> |
|
/// Sets selection on the opened dropdown, and sends an event |
|
/// to the view the popup is within. |
|
/// </summary> |
|
/// <param name="index">Index selected.</param> |
|
internal void SetSelection(object index) |
|
{ |
|
_selectedIdx = ((IntegerWrapper)index).Value; |
|
_view.SendEvent(EditorGUIUtility.CommandEvent(IndexChangeEventName)); |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// Name used for getting a controlID for popup menus. |
|
/// </summary> |
|
private const string LabelControlName = "LabeledPopup"; |
|
|
|
/// <summary> |
|
/// Create a immediate automatically positioned popup menu. |
|
/// </summary> |
|
/// <param name="index">Current active selection index.</param> |
|
/// <param name="display">Name to display as the button.</param> |
|
/// <param name="options">Display name for the dropdown menu.</param> |
|
/// <returns>The possibly new active selection index.</returns> |
|
public static int Popup(int index, string display, string[] options) |
|
{ |
|
// GetControlRect so space is reserved for the button, and we get a |
|
// position to place the drop down context menu at. |
|
var pos = EditorGUILayout.GetControlRect(false, EditorGUI.kSingleLineHeight, |
|
EditorStyles.popup); |
|
|
|
var controlID = GUIUtility.GetControlID(LabelControlName.GetHashCode(), FocusType.Keyboard, pos); |
|
|
|
var selected = PopperCallBack.GetSelectionValue(controlID, index); |
|
|
|
if (GUI.Button(pos, display, EditorStyles.popup)) |
|
{ |
|
PopperCallBack.Instance = new PopperCallBack(controlID); |
|
|
|
var menu = new GenericMenu(); |
|
for (var i = 0; i < options.Length; i++) |
|
{ |
|
var size = options[i]; |
|
|
|
menu.AddItem(EditorGUIUtility.TrTextContent(size), i == index, PopperCallBack.Instance.SetSelection, new IntegerWrapper(i)); |
|
} |
|
menu.Popup(pos, index); |
|
} |
|
|
|
return selected; |
|
} |
|
} |
|
} |