| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- using System;
- using Avalonia.Diagnostics.Models;
- using Avalonia.Diagnostics.Views;
- using Avalonia.Interactivity;
- using Avalonia.Threading;
- using Avalonia.VisualTree;
- namespace Avalonia.Diagnostics.ViewModels
- {
- internal class EventTreeNode : EventTreeNodeBase
- {
- private readonly EventsPageViewModel _parentViewModel;
- private bool _isRegistered;
- private FiredEvent? _currentEvent;
- public EventTreeNode(EventOwnerTreeNode parent, RoutedEvent @event, EventsPageViewModel vm)
- : base(parent, @event.Name)
- {
- Event = @event ?? throw new ArgumentNullException(nameof(@event));
- _parentViewModel = vm ?? throw new ArgumentNullException(nameof(vm));
- }
- public RoutedEvent Event { get; }
- public override bool? IsEnabled
- {
- get => base.IsEnabled;
- set
- {
- if (base.IsEnabled != value)
- {
- base.IsEnabled = value;
- UpdateTracker();
- if (Parent != null && _updateParent)
- {
- try
- {
- Parent._updateChildren = false;
- Parent.UpdateChecked();
- }
- finally
- {
- Parent._updateChildren = true;
- }
- }
- }
- }
- }
- private void UpdateTracker()
- {
- if (IsEnabled.GetValueOrDefault() && !_isRegistered)
- {
- var allRoutes = RoutingStrategies.Direct | RoutingStrategies.Tunnel | RoutingStrategies.Bubble;
- // FIXME: This leaks event handlers.
- Event.AddClassHandler(typeof(object), HandleEvent, allRoutes, handledEventsToo: true);
- Event.RouteFinished.Subscribe(HandleRouteFinished);
-
- _isRegistered = true;
- }
- }
- private void HandleEvent(object? sender, RoutedEventArgs e)
- {
- if (!_isRegistered || IsEnabled == false)
- return;
- if (sender is IVisual v && BelongsToDevTool(v))
- return;
- var s = sender!;
- var handled = e.Handled;
- var route = e.Route;
- void handler()
- {
- if (_currentEvent == null || !_currentEvent.IsPartOfSameEventChain(e))
- {
- _currentEvent = new FiredEvent(e, new EventChainLink(s, handled, route));
- _parentViewModel.RecordedEvents.Add(_currentEvent);
- while (_parentViewModel.RecordedEvents.Count > 100)
- _parentViewModel.RecordedEvents.RemoveAt(0);
- }
- else
- {
- _currentEvent.AddToChain(new EventChainLink(s, handled, route));
- }
- };
- if (!Dispatcher.UIThread.CheckAccess())
- Dispatcher.UIThread.Post(handler);
- else
- handler();
- }
-
- private void HandleRouteFinished(RoutedEventArgs e)
- {
- if (!_isRegistered || IsEnabled == false)
- return;
- if (e.Source is IVisual v && BelongsToDevTool(v))
- return;
- var s = e.Source;
- var handled = e.Handled;
- var route = e.Route;
- void handler()
- {
- if (_currentEvent != null && handled)
- {
- var linkIndex = _currentEvent.EventChain.Count - 1;
- var link = _currentEvent.EventChain[linkIndex];
- link.Handled = true;
- _currentEvent.HandledBy = link;
- }
- }
- if (!Dispatcher.UIThread.CheckAccess())
- Dispatcher.UIThread.Post(handler);
- else
- handler();
- }
- private static bool BelongsToDevTool(IVisual v)
- {
- var current = v;
- while (current != null)
- {
- if (current is MainView || current is MainWindow)
- {
- return true;
- }
- current = current.VisualParent;
- }
- return false;
- }
- }
- }
|