ConsoleTabController.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. //#define SR_CONSOLE_DEBUG
  2. using System.Collections;
  3. namespace SRDebugger.UI.Tabs
  4. {
  5. using System;
  6. using Controls;
  7. using Internal;
  8. using Services;
  9. using SRF;
  10. using UnityEngine;
  11. using UnityEngine.UI;
  12. public class ConsoleTabController : SRMonoBehaviourEx
  13. {
  14. private const int MaxLength = 2600;
  15. private Canvas _consoleCanvas;
  16. private bool _isDirty;
  17. private static bool _hasWarnedAboutLogHandler;
  18. private static bool _hasWarnedAboutLoggingDisabled;
  19. [Import]
  20. public IConsoleFilterState FilterState;
  21. [RequiredField]
  22. public ConsoleLogControl ConsoleLogControl;
  23. [RequiredField]
  24. public Toggle PinToggle;
  25. //public bool IsListening = true;
  26. [RequiredField]
  27. public ScrollRect StackTraceScrollRect;
  28. [RequiredField]
  29. public Text StackTraceText;
  30. [RequiredField]
  31. public Toggle ToggleErrors;
  32. [RequiredField]
  33. public Text ToggleErrorsText;
  34. [RequiredField]
  35. public Toggle ToggleInfo;
  36. [RequiredField]
  37. public Text ToggleInfoText;
  38. [RequiredField]
  39. public Toggle ToggleWarnings;
  40. [RequiredField]
  41. public Text ToggleWarningsText;
  42. [RequiredField]
  43. public GameObject CopyToClipboardContainer;
  44. [RequiredField]
  45. public GameObject CopyToClipboardButton;
  46. [RequiredField]
  47. public GameObject CopyToClipboardMessage;
  48. [RequiredField]
  49. public CanvasGroup CopyToClipboardMessageCanvasGroup;
  50. [RequiredField]
  51. public GameObject LoggingIsDisabledCanvasGroup;
  52. [RequiredField]
  53. public GameObject LogHandlerHasBeenOverridenGroup;
  54. [RequiredField]
  55. public Toggle FilterToggle;
  56. [RequiredField]
  57. public InputField FilterField;
  58. [RequiredField]
  59. public GameObject FilterBarContainer;
  60. private ConsoleEntry _selectedItem;
  61. private Coroutine _fadeButtonCoroutine;
  62. protected override void Start()
  63. {
  64. base.Start();
  65. _consoleCanvas = GetComponent<Canvas>();
  66. ToggleErrors.isOn = FilterState.GetConsoleFilterState(LogType.Error);
  67. ToggleWarnings.isOn = FilterState.GetConsoleFilterState(LogType.Warning);
  68. ToggleInfo.isOn = FilterState.GetConsoleFilterState(LogType.Log);
  69. ToggleErrors.onValueChanged.AddListener(isOn =>
  70. {
  71. FilterState.SetConsoleFilterState(LogType.Error, isOn);
  72. _isDirty = true;
  73. });
  74. ToggleWarnings.onValueChanged.AddListener(isOn =>
  75. {
  76. FilterState.SetConsoleFilterState(LogType.Warning, isOn);
  77. _isDirty = true;
  78. });
  79. ToggleInfo.onValueChanged.AddListener(isOn =>
  80. {
  81. FilterState.SetConsoleFilterState(LogType.Log, isOn);
  82. _isDirty = true;
  83. });
  84. PinToggle.onValueChanged.AddListener(PinToggleValueChanged);
  85. FilterToggle.onValueChanged.AddListener(FilterToggleValueChanged);
  86. FilterBarContainer.SetActive(FilterToggle.isOn);
  87. #if UNITY_5_3_OR_NEWER
  88. FilterField.onValueChanged.AddListener(FilterValueChanged);
  89. #else
  90. FilterField.onValueChange.AddListener(FilterValueChanged);
  91. #endif
  92. ConsoleLogControl.SelectedItemChanged = ConsoleLogSelectedItemChanged;
  93. Service.Console.Updated += ConsoleOnUpdated;
  94. Service.Panel.VisibilityChanged += PanelOnVisibilityChanged;
  95. FilterState.FilterStateChange += OnFilterStateChange;
  96. StackTraceText.supportRichText = Settings.Instance.RichTextInConsole;
  97. PopulateStackTraceArea(null);
  98. Refresh();
  99. }
  100. private void OnFilterStateChange(LogType logtype, bool newstate)
  101. {
  102. switch (logtype)
  103. {
  104. case LogType.Error:
  105. ToggleErrors.isOn = newstate;
  106. break;
  107. case LogType.Warning:
  108. ToggleWarnings.isOn = newstate;
  109. break;
  110. case LogType.Log:
  111. ToggleInfo.isOn = newstate;
  112. break;
  113. }
  114. }
  115. private void FilterToggleValueChanged(bool isOn)
  116. {
  117. if (isOn)
  118. {
  119. FilterBarContainer.SetActive(true);
  120. ConsoleLogControl.Filter = FilterField.text;
  121. }
  122. else
  123. {
  124. ConsoleLogControl.Filter = null;
  125. FilterBarContainer.SetActive(false);
  126. }
  127. }
  128. private void FilterValueChanged(string filterText)
  129. {
  130. if (FilterToggle.isOn && !string.IsNullOrEmpty(filterText) && filterText.Trim().Length != 0)
  131. {
  132. ConsoleLogControl.Filter = filterText;
  133. }
  134. else
  135. {
  136. ConsoleLogControl.Filter = null;
  137. }
  138. }
  139. private void PanelOnVisibilityChanged(IDebugPanelService debugPanelService, bool b)
  140. {
  141. if (_consoleCanvas == null)
  142. {
  143. return;
  144. }
  145. if (b)
  146. {
  147. _consoleCanvas.enabled = true;
  148. }
  149. else
  150. {
  151. _consoleCanvas.enabled = false;
  152. StopAnimations();
  153. }
  154. }
  155. private void PinToggleValueChanged(bool isOn)
  156. {
  157. Service.DockConsole.IsVisible = isOn;
  158. }
  159. protected override void OnDestroy()
  160. {
  161. StopAnimations();
  162. if (Service.Console != null)
  163. {
  164. Service.Console.Updated -= ConsoleOnUpdated;
  165. }
  166. FilterState.FilterStateChange -= OnFilterStateChange;
  167. base.OnDestroy();
  168. }
  169. protected override void OnEnable()
  170. {
  171. base.OnEnable();
  172. _isDirty = true;
  173. }
  174. protected override void OnDisable()
  175. {
  176. base.OnDisable();
  177. StopAnimations();
  178. }
  179. private void ConsoleLogSelectedItemChanged(object item)
  180. {
  181. var log = item as ConsoleEntry;
  182. PopulateStackTraceArea(log);
  183. }
  184. protected override void Update()
  185. {
  186. base.Update();
  187. if (_isDirty)
  188. {
  189. Refresh();
  190. }
  191. }
  192. private void PopulateStackTraceArea(ConsoleEntry entry)
  193. {
  194. if (entry == null)
  195. {
  196. SetCopyToClipboardButtonState(CopyToClipboardStates.Hidden);
  197. StackTraceText.text = "";
  198. }
  199. else
  200. {
  201. if (SRDebug.CopyConsoleItemCallback != null)
  202. {
  203. SetCopyToClipboardButtonState(CopyToClipboardStates.Visible);
  204. }
  205. var text = entry.Message + Environment.NewLine +
  206. (!string.IsNullOrEmpty(entry.StackTrace)
  207. ? entry.StackTrace
  208. : SRDebugStrings.Current.Console_NoStackTrace);
  209. if (text.Length > MaxLength)
  210. {
  211. text = text.Substring(0, MaxLength);
  212. text += "\n" + SRDebugStrings.Current.Console_MessageTruncated;
  213. }
  214. StackTraceText.text = text;
  215. }
  216. StackTraceScrollRect.normalizedPosition = new Vector2(0, 1);
  217. _selectedItem = entry;
  218. }
  219. public void CopyToClipboard()
  220. {
  221. if (_selectedItem != null)
  222. {
  223. SetCopyToClipboardButtonState(CopyToClipboardStates.Activated);
  224. if (SRDebug.CopyConsoleItemCallback != null)
  225. {
  226. SRDebug.CopyConsoleItemCallback(_selectedItem);
  227. }
  228. else
  229. {
  230. Debug.LogError("[SRDebugger] Copy to clipboard is not available.");
  231. }
  232. }
  233. }
  234. public enum CopyToClipboardStates
  235. {
  236. Hidden,
  237. Visible,
  238. Activated
  239. }
  240. void SetCopyToClipboardButtonState(CopyToClipboardStates state)
  241. {
  242. StopAnimations();
  243. switch (state)
  244. {
  245. case CopyToClipboardStates.Hidden:
  246. CopyToClipboardContainer.SetActive(false);
  247. CopyToClipboardButton.SetActive(false);
  248. CopyToClipboardMessage.SetActive(false);
  249. break;
  250. case CopyToClipboardStates.Visible:
  251. CopyToClipboardContainer.SetActive(true);
  252. CopyToClipboardButton.SetActive(true);
  253. CopyToClipboardMessage.SetActive(false);
  254. break;
  255. case CopyToClipboardStates.Activated:
  256. CopyToClipboardMessageCanvasGroup.alpha = 1;
  257. CopyToClipboardContainer.SetActive(true);
  258. CopyToClipboardButton.SetActive(false);
  259. CopyToClipboardMessage.SetActive(true);
  260. _fadeButtonCoroutine = StartCoroutine(FadeCopyButton());
  261. break;
  262. default:
  263. throw new ArgumentOutOfRangeException("state", state, null);
  264. }
  265. }
  266. IEnumerator FadeCopyButton()
  267. {
  268. yield return new WaitForSecondsRealtime(2f);
  269. float startTime = Time.realtimeSinceStartup;
  270. float endTime = Time.realtimeSinceStartup + 1f;
  271. while (Time.realtimeSinceStartup < endTime)
  272. {
  273. float currentAlpha = Mathf.InverseLerp(endTime, startTime, Time.realtimeSinceStartup);
  274. CopyToClipboardMessageCanvasGroup.alpha = currentAlpha;
  275. yield return new WaitForEndOfFrame();
  276. }
  277. CopyToClipboardMessageCanvasGroup.alpha = 0;
  278. _fadeButtonCoroutine = null;
  279. }
  280. void StopAnimations()
  281. {
  282. if (_fadeButtonCoroutine != null)
  283. {
  284. StopCoroutine(_fadeButtonCoroutine);
  285. _fadeButtonCoroutine = null;
  286. CopyToClipboardMessageCanvasGroup.alpha = 0;
  287. }
  288. }
  289. private void Refresh()
  290. {
  291. // Update total counts labels
  292. ToggleInfoText.text = SRDebuggerUtil.GetNumberString(Service.Console.InfoCount, 999, "999+");
  293. ToggleWarningsText.text = SRDebuggerUtil.GetNumberString(Service.Console.WarningCount, 999, "999+");
  294. ToggleErrorsText.text = SRDebuggerUtil.GetNumberString(Service.Console.ErrorCount, 999, "999+");
  295. ConsoleLogControl.ShowErrors = ToggleErrors.isOn;
  296. ConsoleLogControl.ShowWarnings = ToggleWarnings.isOn;
  297. ConsoleLogControl.ShowInfo = ToggleInfo.isOn;
  298. PinToggle.isOn = Service.DockConsole.IsVisible;
  299. _isDirty = false;
  300. if (!_hasWarnedAboutLogHandler && Service.Console.LogHandlerIsOverriden)
  301. {
  302. LogHandlerHasBeenOverridenGroup.SetActive(true);
  303. _hasWarnedAboutLogHandler = true;
  304. }
  305. if (!_hasWarnedAboutLoggingDisabled && !Service.Console.LoggingEnabled)
  306. {
  307. LoggingIsDisabledCanvasGroup.SetActive(true);
  308. }
  309. }
  310. private void ConsoleOnUpdated(IConsoleService console)
  311. {
  312. _isDirty = true;
  313. }
  314. public void Clear()
  315. {
  316. Service.Console.Clear();
  317. _isDirty = true;
  318. }
  319. public void LogHandlerHasBeenOverridenOkayButtonPress()
  320. {
  321. _hasWarnedAboutLogHandler = true;
  322. LogHandlerHasBeenOverridenGroup.SetActive(false);
  323. }
  324. public void LoggingDisableCloseAndIgnorePressed()
  325. {
  326. LoggingIsDisabledCanvasGroup.SetActive(false);
  327. _hasWarnedAboutLoggingDisabled = true;
  328. }
  329. public void LoggingDisableReenablePressed()
  330. {
  331. Service.Console.LoggingEnabled = true;
  332. LoggingIsDisabledCanvasGroup.SetActive(false);
  333. Debug.Log("[SRDebugger] Re-enabled logging.");
  334. }
  335. }
  336. }