using System; using GamecraftModdingAPI.Utility; using Svelto.DataStructures; using UnityEngine; namespace GamecraftModdingAPI.Interface.IMGUI { /// /// A group of elements. /// This wraps Unity's GUILayout Area and GUI Group system. /// public class Group : UIElement { private bool automaticLayout; private FasterList elements = new FasterList(); /// /// The rectangular area in the window that the UI group can use /// public Rect Box { get; set; } public void OnGUI() { /*if (Constants.Default == null) return; if (Constants.Default.box == null) return;*/ GUIStyle guiStyle = Constants.Default.box; UIElement[] elems = elements.ToArrayFast(out uint count); if (automaticLayout) { GUILayout.BeginArea(Box, guiStyle); for (uint i = 0; i < count; i++) { /*try { if (elems[i].Enabled) elems[i].OnGUI(); } catch (ArgumentException) { // ignore these, since this is (hopefully) just Unity being dumb } catch (Exception e) { Logging.MetaDebugLog($"Element '{elems[i].Name}' threw exception:\n{e.ToString()}"); }*/ if (elems[i].Enabled) elems[i].OnGUI(); } GUILayout.EndArea(); } else { GUI.BeginGroup(Box, guiStyle); for (uint i = 0; i < count; i++) { if (elems[i].Enabled) elems[i].OnGUI(); } GUI.EndGroup(); } } /// /// The group's unique name. /// public string Name { get; } /// /// Whether to display the group and everything in it. /// public bool Enabled { set; get; } = true; /// /// The amount of elements in the group. /// public int Length { get => elements.count; } /// /// Initializes a new instance of the class. /// /// The rectangular area to use in the window. /// Name of the group. /// Whether to use automatic UI layout. public Group(Rect box, string name = null, bool automaticLayout = false) { Box = box; if (name == null) { this.Name = typeof(Group).FullName + "::" + box.ToString().Replace(" ", ""); } else { this.Name = name; } this.automaticLayout = automaticLayout; IMGUIManager.AddElement(this); } /// /// Add an element to the group. /// /// The element to add. /// Index of the new element. public int AddElement(UIElement element) { IMGUIManager.RemoveElement(element); // groups manage internal elements themselves elements.Add(element); return elements.count - 1; } /// /// Remove an element from the group. /// /// The element to remove. /// Whether removal was successful. public bool RemoveElement(UIElement element) { int index = IndexOf(element); return RemoveAt(index); } /// /// Remove the element in a specific location. /// /// Index of the element. /// Whether removal was successful. public bool RemoveAt(int index) { if (index < 0 || index >= elements.count) return false; IMGUIManager.AddElement(elements[index]); // re-add to global manager elements.RemoveAt(index); return true; } /// /// Get the index of an element. /// /// The element to search for. /// The element's index, or -1 if not found. public int IndexOf(UIElement element) { UIElement[] elems = elements.ToArrayFast(out uint count); for (int i = 0; i < count; i++) { if (elems[i].Name == element.Name) { return i; } } return -1; } } }