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;
}
}
}