using System; using System.Collections.Generic; using UnityEditor; using UnityEditorInternal; using UnityEngine; using UnityEngine.Profiling; namespace Ingvar.LiveWatch.Editor { public class LiveWatchWindow : EditorWindow { public static bool IsRepaintRequested { get; set; } public static int SelectedColumnIndex { get; set; } = -1; public static float MaxPlayRepaintDelay { get; set; } = 1f; public static float MinSoftRepaintDelay { get; set; } = 0.3f; private Vector2 _watchesScrollPosition; [SerializeField] private ToolbarGUI _toolbarGUI = new ToolbarGUI(); [SerializeField] private VariablesListGUI _variablesListGUI = new VariablesListGUI(); [SerializeField] private InfoGUI _infoGUI = new InfoGUI(); [SerializeField] private ResizerGUI _horizontalResizerSearchToList = new ResizerGUI(true, 8, 1, Color.black); [SerializeField] private ResizerGUI _horizontalResizerListToInfo = new ResizerGUI(true, 8, 1, Color.black, 1); [SerializeField] private ResizerGUI _verticalResizerNameToValues = new ResizerGUI(false, 8, 1, Color.black); private float previousRepaintTime; [MenuItem("Window/LiveWatch")] static void Init() { LiveWatchWindow window = (LiveWatchWindow)EditorWindow.GetWindow(typeof(LiveWatchWindow)); window.titleContent = new GUIContent("LiveWatch"); window.Show(); } private void OnEnable() { IsRepaintRequested = false; _variablesListGUI.OnEnable(); EditorApplication.update += OnEditorUpdate; Watch.OnClearedAll += OnWatchClearedAll; Watch.OnDestroyedAll += OnWatchDestroyedAll; } private void OnDisable() { EditorApplication.update -= OnEditorUpdate; Watch.OnClearedAll -= OnWatchClearedAll; Watch.OnDestroyedAll -= OnWatchDestroyedAll; } private void OnEditorUpdate() { if (EditorApplication.isPlaying) { if (Time.realtimeSinceStartup < previousRepaintTime + MaxPlayRepaintDelay) return; Repaint(); } else if (IsRepaintRequested) { if (Time.realtimeSinceStartup < previousRepaintTime + MinSoftRepaintDelay) return; IsRepaintRequested = false; Repaint(); } } private void OnGUI() { if (Event.current.type == EventType.Repaint) previousRepaintTime = Time.realtimeSinceStartup; Profiler.BeginSample("Watch GUI"); HandleResizers(); DrawVariableList(); DrawToolbar(); DrawInfo(); DrawResizers(); Profiler.EndSample(); } private void OnWatchClearedAll() { _variablesListGUI.Clear(); } private void OnWatchDestroyedAll() { _variablesListGUI.Clear(); } private void HandleResizers() { if (_toolbarGUI.Search) { _horizontalResizerSearchToList.LocalArea = new Rect(0, 0, position.width, position.height) .CropFromStartToPosition(CropEdge.TopLocal, _horizontalResizerListToInfo.Position) .CropFromPositionToEnd(CropEdge.TopLocal, Constants.ToolbarAreaHeight + Constants.SearchAreaMinHeight) .CropFromPositionToEnd(CropEdge.BottomLocal, Constants.VariablesAreaMinHeight); _horizontalResizerSearchToList.ProcessHandle(); } _verticalResizerNameToValues.LocalArea = new Rect(0, 0, position.width, position.height) .CropFromStartToPosition(CropEdge.TopLocal, _horizontalResizerListToInfo.Position) .CropFromPositionToEnd(CropEdge.TopLocal, _toolbarGUI.Search ? _horizontalResizerSearchToList.Position : Constants.ToolbarAreaHeight) .CropFromPositionToEnd(CropEdge.LeftLocal, Constants.VariableLabelMinWidth) .CropFromPositionToEnd(CropEdge.RightLocal, Constants.VariableValuesMinWidth); _horizontalResizerListToInfo.LocalArea = new Rect(0, 0, position.width, position.height) .CropFromPositionToEnd(CropEdge.TopLocal, Constants.ToolbarAreaHeight + Constants.SearchAreaMinHeight + Constants.VariablesAreaMinHeight) .CropFromPositionToEnd(CropEdge.BottomLocal, Constants.InfoAreaMinHeight); _verticalResizerNameToValues.ProcessHandle(); _horizontalResizerListToInfo.ProcessHandle(); } private void DrawResizers() { if (_toolbarGUI.Search) { _horizontalResizerSearchToList.DrawLine(); } _verticalResizerNameToValues.DrawLine(); _horizontalResizerListToInfo.DrawLine(); } private void DrawToolbar() { var toolbarRect = new Rect(0, 0, position.width + 1, Constants.ToolbarAreaHeight); _toolbarGUI.WindowRect = position; _toolbarGUI.OnGUI(toolbarRect); } private void DrawVariableList() { var contentRect = new Rect(0, 0, position.width + 1, position.height) .CropFromPositionToPosition( CropEdge.TopLocal, _toolbarGUI.Search ? _horizontalResizerSearchToList.Position : Constants.ToolbarAreaHeight, _horizontalResizerListToInfo.Position); _variablesListGUI.Search = _toolbarGUI.Search; _variablesListGUI.NameColumnWidth = _verticalResizerNameToValues.Position; _variablesListGUI.OnGUI(contentRect); } private void DrawInfo() { var infoRect = new Rect(0, _horizontalResizerListToInfo.Position + 1, position.width + 1, position.height - _horizontalResizerListToInfo.Position - 1); _infoGUI.SelectedVariable = _variablesListGUI.SelectedVariable; _infoGUI.IsTitleSelected = _variablesListGUI.IsTitleSelected; _infoGUI.SelectedColumn = _variablesListGUI.SelectedColumnIndex; _infoGUI.OnGUI(infoRect); } } }