EventsPageViewModel.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.ObjectModel;
  4. using System.Linq;
  5. using Avalonia.Controls;
  6. using Avalonia.Diagnostics.Models;
  7. using Avalonia.Input;
  8. using Avalonia.Interactivity;
  9. namespace Avalonia.Diagnostics.ViewModels
  10. {
  11. internal class EventsPageViewModel : ViewModelBase
  12. {
  13. private static readonly HashSet<RoutedEvent> s_defaultEvents = new HashSet<RoutedEvent>()
  14. {
  15. Button.ClickEvent,
  16. InputElement.KeyDownEvent,
  17. InputElement.KeyUpEvent,
  18. InputElement.TextInputEvent,
  19. InputElement.PointerReleasedEvent,
  20. InputElement.PointerPressedEvent
  21. };
  22. private readonly MainViewModel _mainViewModel;
  23. private FiredEvent? _selectedEvent;
  24. private EventTreeNodeBase? _selectedNode;
  25. public EventsPageViewModel(MainViewModel mainViewModel)
  26. {
  27. _mainViewModel = mainViewModel;
  28. Nodes = RoutedEventRegistry.Instance.GetAllRegistered()
  29. .GroupBy(e => e.OwnerType)
  30. .OrderBy(e => e.Key.Name)
  31. .Select(g => new EventOwnerTreeNode(g.Key, g, this))
  32. .ToArray();
  33. EventsFilter = new FilterViewModel();
  34. EventsFilter.RefreshFilter += (s, e) => UpdateEventFilters();
  35. EnableDefault();
  36. }
  37. public string Name => "Events";
  38. public EventTreeNodeBase[] Nodes { get; }
  39. public ObservableCollection<FiredEvent> RecordedEvents { get; } = new ObservableCollection<FiredEvent>();
  40. public FiredEvent? SelectedEvent
  41. {
  42. get => _selectedEvent;
  43. set => RaiseAndSetIfChanged(ref _selectedEvent, value);
  44. }
  45. public EventTreeNodeBase? SelectedNode
  46. {
  47. get => _selectedNode;
  48. set => RaiseAndSetIfChanged(ref _selectedNode, value);
  49. }
  50. public FilterViewModel EventsFilter { get; }
  51. public void Clear()
  52. {
  53. RecordedEvents.Clear();
  54. }
  55. public void DisableAll()
  56. {
  57. EvaluateNodeEnabled(_ => false);
  58. }
  59. public void EnableDefault()
  60. {
  61. EvaluateNodeEnabled(node => s_defaultEvents.Contains(node.Event));
  62. }
  63. public void RequestTreeNavigateTo(EventChainLink navTarget)
  64. {
  65. if (navTarget.Handler is IControl control)
  66. {
  67. _mainViewModel.RequestTreeNavigateTo(control, true);
  68. }
  69. }
  70. public void SelectEventByType(RoutedEvent evt)
  71. {
  72. foreach (var node in Nodes)
  73. {
  74. var result = FindNode(node, evt);
  75. if (result != null && result.IsVisible)
  76. {
  77. SelectedNode = result;
  78. break;
  79. }
  80. }
  81. static EventTreeNodeBase? FindNode(EventTreeNodeBase node, RoutedEvent eventType)
  82. {
  83. if (node is EventTreeNode eventNode && eventNode.Event == eventType)
  84. {
  85. return node;
  86. }
  87. if (node.Children != null)
  88. {
  89. foreach (var child in node.Children)
  90. {
  91. var result = FindNode(child, eventType);
  92. if (result != null)
  93. {
  94. return result;
  95. }
  96. }
  97. }
  98. return null;
  99. }
  100. }
  101. private void EvaluateNodeEnabled(Func<EventTreeNode, bool> eval)
  102. {
  103. void ProcessNode(EventTreeNodeBase node)
  104. {
  105. if (node is EventTreeNode eventNode)
  106. {
  107. node.IsEnabled = eval(eventNode);
  108. }
  109. if (node.Children != null)
  110. {
  111. foreach (var childNode in node.Children)
  112. {
  113. ProcessNode(childNode);
  114. }
  115. }
  116. }
  117. foreach (var node in Nodes)
  118. {
  119. ProcessNode(node);
  120. }
  121. }
  122. private void UpdateEventFilters()
  123. {
  124. foreach (var node in Nodes)
  125. {
  126. FilterNode(node, false);
  127. }
  128. bool FilterNode(EventTreeNodeBase node, bool isParentVisible)
  129. {
  130. bool matchesFilter = EventsFilter.Filter(node.Text);
  131. bool hasVisibleChild = false;
  132. if (node.Children != null)
  133. {
  134. foreach (var childNode in node.Children)
  135. {
  136. hasVisibleChild |= FilterNode(childNode, matchesFilter);
  137. }
  138. }
  139. node.IsVisible = hasVisibleChild || matchesFilter || isParentVisible;
  140. return node.IsVisible;
  141. }
  142. }
  143. }
  144. }