FloatingMenu.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. using System;
  2. using System.Collections.Generic;
  3. using JetBrains.Annotations;
  4. using Unity.Cloud.Collaborate.UserInterface;
  5. using Unity.Cloud.Collaborate.Utilities;
  6. using UnityEditor;
  7. using UnityEngine;
  8. using UnityEngine.UIElements;
  9. namespace Unity.Cloud.Collaborate.Components.Menus
  10. {
  11. [UsedImplicitly]
  12. internal class FloatingMenu
  13. {
  14. public const string ussClassName = "unity-floating-menu";
  15. // Fields used to display the option list.
  16. const float k_ItemHeight = 28f;
  17. readonly List<(string Text, Action Action, bool Enabled)> m_Items;
  18. /// <summary>
  19. /// Location the uss file for this element is stored.
  20. /// </summary>
  21. static readonly string k_StylePath = $"{CollaborateWindow.StylePath}/{nameof(FloatingMenu)}.uss";
  22. /// <summary>
  23. /// Container for the menu items.
  24. /// </summary>
  25. readonly VisualElement m_Content;
  26. /// <summary>
  27. /// Direction to open the menu.
  28. /// </summary>
  29. MenuUtilities.OpenDirection m_OpenDirection = MenuUtilities.OpenDirection.DownLeft;
  30. /// <summary>
  31. /// Create a new floating menu. Follows the builder pattern.
  32. /// </summary>
  33. public FloatingMenu()
  34. {
  35. m_Items = new List<(string Text, Action Action, bool Enabled)>();
  36. m_Content = new VisualElement();
  37. m_Content.AddToClassList(ussClassName);
  38. m_Content.styleSheets.Add(AssetDatabase.LoadAssetAtPath<StyleSheet>(k_StylePath));
  39. }
  40. /// <summary>
  41. /// Add a single option to the menu.
  42. /// </summary>
  43. /// <param name="text">Text in the option.</param>
  44. /// <param name="action">Action to invoke on click.</param>
  45. /// <param name="enabled">State of the entry.</param>
  46. /// <returns>This.</returns>
  47. public FloatingMenu AddEntry(string text, Action action, bool enabled)
  48. {
  49. m_Items.Add((text, action, enabled));
  50. return this;
  51. }
  52. /// <summary>
  53. /// Add a list of entries.
  54. /// </summary>
  55. /// <param name="items">Entries to add.</param>
  56. /// <returns>This.</returns>
  57. public FloatingMenu AddEntries(IEnumerable<(string Text, Action Action, bool Enabled)> items)
  58. {
  59. m_Items.AddRange(items);
  60. return this;
  61. }
  62. /// <summary>
  63. /// Sets the open direction of the menu.
  64. /// </summary>
  65. /// <param name="openDirection">Direction the menu opens towards.</param>
  66. /// <returns>This.</returns>
  67. public FloatingMenu SetOpenDirection(MenuUtilities.OpenDirection openDirection)
  68. {
  69. m_OpenDirection = openDirection;
  70. return this;
  71. }
  72. /// <summary>
  73. /// Opens the constructed menu.
  74. /// </summary>
  75. /// <param name="x">World x coordinate.</param>
  76. /// <param name="y">World y coordinate.</param>
  77. public void Open(float x, float y)
  78. {
  79. FloatingDialogue.Instance.Open(x, y, GenerateContent(), m_OpenDirection);
  80. }
  81. /// <summary>
  82. /// Generate the visual element that displays the content of this menu.
  83. /// </summary>
  84. /// <returns>The constructed visual element.</returns>
  85. VisualElement GenerateContent()
  86. {
  87. m_Content.Clear();
  88. foreach (var item in m_Items)
  89. {
  90. // Ensure the dialogue closes once the option is selected
  91. void Action()
  92. {
  93. FloatingDialogue.Instance.Close();
  94. item.Action();
  95. }
  96. var elem = new FloatingMenuItem(item.Text, Action, item.Enabled, k_ItemHeight);
  97. m_Content.Add(elem);
  98. }
  99. return m_Content;
  100. }
  101. }
  102. }