using System;
using System.Collections.Generic;
using JetBrains.Annotations;
using Unity.Cloud.Collaborate.UserInterface;
using Unity.Cloud.Collaborate.Utilities;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
namespace Unity.Cloud.Collaborate.Components.Menus
{
[UsedImplicitly]
internal class FloatingMenu
{
public const string ussClassName = "unity-floating-menu";
// Fields used to display the option list.
const float k_ItemHeight = 28f;
readonly List<(string Text, Action Action, bool Enabled)> m_Items;
///
/// Location the uss file for this element is stored.
///
static readonly string k_StylePath = $"{CollaborateWindow.StylePath}/{nameof(FloatingMenu)}.uss";
///
/// Container for the menu items.
///
readonly VisualElement m_Content;
///
/// Direction to open the menu.
///
MenuUtilities.OpenDirection m_OpenDirection = MenuUtilities.OpenDirection.DownLeft;
///
/// Create a new floating menu. Follows the builder pattern.
///
public FloatingMenu()
{
m_Items = new List<(string Text, Action Action, bool Enabled)>();
m_Content = new VisualElement();
m_Content.AddToClassList(ussClassName);
m_Content.styleSheets.Add(AssetDatabase.LoadAssetAtPath(k_StylePath));
}
///
/// Add a single option to the menu.
///
/// Text in the option.
/// Action to invoke on click.
/// State of the entry.
/// This.
public FloatingMenu AddEntry(string text, Action action, bool enabled)
{
m_Items.Add((text, action, enabled));
return this;
}
///
/// Add a list of entries.
///
/// Entries to add.
/// This.
public FloatingMenu AddEntries(IEnumerable<(string Text, Action Action, bool Enabled)> items)
{
m_Items.AddRange(items);
return this;
}
///
/// Sets the open direction of the menu.
///
/// Direction the menu opens towards.
/// This.
public FloatingMenu SetOpenDirection(MenuUtilities.OpenDirection openDirection)
{
m_OpenDirection = openDirection;
return this;
}
///
/// Opens the constructed menu.
///
/// World x coordinate.
/// World y coordinate.
public void Open(float x, float y)
{
FloatingDialogue.Instance.Open(x, y, GenerateContent(), m_OpenDirection);
}
///
/// Generate the visual element that displays the content of this menu.
///
/// The constructed visual element.
VisualElement GenerateContent()
{
m_Content.Clear();
foreach (var item in m_Items)
{
// Ensure the dialogue closes once the option is selected
void Action()
{
FloatingDialogue.Instance.Close();
item.Action();
}
var elem = new FloatingMenuItem(item.Text, Action, item.Enabled, k_ItemHeight);
m_Content.Add(elem);
}
return m_Content;
}
}
}