using System; using System.Collections; using System.Collections.Generic; using UnityEngine; namespace UnityEditor.U2D.Path.GUIFramework { /// /// Represents a system of GUI elements and controls. /// public class GUISystem { private readonly int kControlIDCheckHashCode = "ControlIDCheckHashCode".GetHashCode(); private List m_Controls = new List(); private List m_Actions = new List(); private IGUIState m_GUIState; private int m_PrevNearestControl = -1; private LayoutData m_PrevNearestLayoutData = LayoutData.zero; private int m_ControlIDCheck = -1; /// /// Initializes and returns an instance of GUISystem /// /// The current state of the custom editor. public GUISystem(IGUIState guiState) { m_GUIState = guiState; } /// /// Adds a control to the internal list of controls. /// /// The control to add. public void AddControl(Control control) { if (control == null) throw new NullReferenceException("Control is null"); m_Controls.Add(control); } /// /// Removes a control from the internal list of controls. /// /// The control to remove. public void RemoveControl(Control control) { m_Controls.Remove(control); } /// /// Adds an action to the internal list of actions. /// /// The action to add. public void AddAction(GUIAction action) { if (action == null) throw new NullReferenceException("Action is null"); m_Actions.Add(action); } /// /// Removes an action from the internal list of actions. /// /// The action to remove. public void RemoveAction(GUIAction action) { m_Actions.Remove(action); } /// /// Calls the methods in its invocation list when Unity draws this GUISystems's GUI. /// public void OnGUI() { var controlIDCheck = m_GUIState.GetControlID(kControlIDCheckHashCode, FocusType.Passive); if (m_GUIState.eventType == EventType.Layout) m_ControlIDCheck = controlIDCheck; else if (m_GUIState.eventType != EventType.Used && m_ControlIDCheck != controlIDCheck) Debug.LogWarning("GetControlID at event " + m_GUIState.eventType + " returns a controlID different from the one in Layout event"); var nearestLayoutData = LayoutData.zero; foreach (var control in m_Controls) control.GetControl(m_GUIState); if (m_GUIState.eventType == EventType.Layout) { foreach (var control in m_Controls) control.BeginLayout(m_GUIState); foreach (var control in m_Controls) { control.Layout(m_GUIState); nearestLayoutData = LayoutData.Nearest(nearestLayoutData, control.layoutData); } foreach (var control in m_Controls) m_GUIState.AddControl(control.ID, control.layoutData.distance); foreach (var control in m_Controls) control.EndLayout(m_GUIState); if (m_PrevNearestControl == m_GUIState.nearestControl) { if (nearestLayoutData.index != m_PrevNearestLayoutData.index) m_GUIState.Repaint(); } else { m_PrevNearestControl = m_GUIState.nearestControl; m_GUIState.Repaint(); } m_PrevNearestLayoutData = nearestLayoutData; } if (m_GUIState.eventType == EventType.Repaint) { foreach (var action in m_Actions) if (action.IsRepaintEnabled(m_GUIState)) action.PreRepaint(m_GUIState); foreach (var control in m_Controls) control.Repaint(m_GUIState); } var repaintOnMouseMove = false; foreach (var action in m_Actions) { if (IsMouseMoveEvent()) repaintOnMouseMove |= action.IsRepaintOnMouseMoveEnabled(m_GUIState); action.OnGUI(m_GUIState); } if (repaintOnMouseMove) m_GUIState.Repaint(); } /// /// Calls the methods in its invocation list when the mouse moves. /// /// Returns `true` if the mouse moved. Otherwise, returns `false`. private bool IsMouseMoveEvent() { return m_GUIState.eventType == EventType.MouseMove || m_GUIState.eventType == EventType.MouseDrag; } } }