説明なし
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

LabeledPopup.cs 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. using UnityEngine;
  2. using UnityEditor;
  3. namespace Unity.Burst.Editor
  4. {
  5. internal static class LabeledPopup
  6. {
  7. // Because the function given to dropdown menu needs takes its parameter
  8. // in the form of an object, we need someway to wrap the integer into one.
  9. private struct IntegerWrapper
  10. {
  11. public int Value { get; }
  12. public IntegerWrapper(int v)
  13. {
  14. Value = v;
  15. }
  16. }
  17. /// <summary>
  18. /// Enables having several popup menus functioning independently at the same time.
  19. /// </summary>
  20. private class PopperCallBack
  21. {
  22. public static PopperCallBack Instance = null;
  23. /// <summary>
  24. /// Name of the event send when an index have been chosen.
  25. /// </summary>
  26. private const string IndexChangeEventName = "PopperChangingIndex";
  27. private readonly int _controlID;
  28. private int _selectedIdx;
  29. private readonly GUIView _view;
  30. public PopperCallBack(int controlID)
  31. {
  32. _controlID = controlID;
  33. _selectedIdx = -1;
  34. _view = GUIView.current;
  35. }
  36. /// <summary>
  37. /// Tries to get selection chosen by dropdown menu <see cref="controlID"/>.
  38. /// </summary>
  39. /// <param name="controlId">ID of popup menu.</param>
  40. /// <param name="selectedIdx">Current selected index.</param>
  41. /// <returns>
  42. /// Either the selected target, or the <see cref="selectedIdx"/>
  43. /// if none were chosen yet.
  44. /// </returns>
  45. internal static int GetSelectionValue(int controlId, int selectedIdx)
  46. {
  47. var selected = selectedIdx;
  48. // A command event with message IndexChangeEvent will be sent whenever a choice on
  49. // the dropdown menu has been made. So if this is not the case return whatever index was given
  50. var evt = Event.current;
  51. if (evt.type != EventType.ExecuteCommand || evt.commandName != IndexChangeEventName) return selected;
  52. // If this is the popup opened right now: Set the selection idx appropriately
  53. if (Instance != null && controlId == Instance._controlID)
  54. {
  55. selected = Instance._selectedIdx;
  56. Instance = null;
  57. }
  58. return selected;
  59. }
  60. /// <summary>
  61. /// Sets selection on the opened dropdown, and sends an event
  62. /// to the view the popup is within.
  63. /// </summary>
  64. /// <param name="index">Index selected.</param>
  65. internal void SetSelection(object index)
  66. {
  67. _selectedIdx = ((IntegerWrapper)index).Value;
  68. _view.SendEvent(EditorGUIUtility.CommandEvent(IndexChangeEventName));
  69. }
  70. }
  71. /// <summary>
  72. /// Name used for getting a controlID for popup menus.
  73. /// </summary>
  74. private const string LabelControlName = "LabeledPopup";
  75. /// <summary>
  76. /// Create a immediate automatically positioned popup menu.
  77. /// </summary>
  78. /// <param name="index">Current active selection index.</param>
  79. /// <param name="display">Name to display as the button.</param>
  80. /// <param name="options">Display name for the dropdown menu.</param>
  81. /// <returns>The possibly new active selection index.</returns>
  82. public static int Popup(int index, GUIContent display, string[] options)
  83. {
  84. // GetControlRect so space is reserved for the button, and we get a
  85. // position to place the drop down context menu at.
  86. var pos = EditorGUILayout.GetControlRect(false, EditorGUI.kSingleLineHeight,
  87. EditorStyles.popup);
  88. var controlID = GUIUtility.GetControlID(LabelControlName.GetHashCode(), FocusType.Keyboard, pos);
  89. var selected = PopperCallBack.GetSelectionValue(controlID, index);
  90. if (GUI.Button(pos, display, EditorStyles.popup))
  91. {
  92. PopperCallBack.Instance = new PopperCallBack(controlID);
  93. var menu = new GenericMenu();
  94. for (var i = 0; i < options.Length; i++)
  95. {
  96. var size = options[i];
  97. menu.AddItem(EditorGUIUtility.TrTextContent(size), i == index, PopperCallBack.Instance.SetSelection, new IntegerWrapper(i));
  98. }
  99. menu.Popup(pos, index);
  100. }
  101. return selected;
  102. }
  103. }
  104. }