9 changed files with 197 additions and 222 deletions
@ -1,97 +0,0 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using Avalonia.Diagnostics.Models; |
|||
using Avalonia.Interactivity; |
|||
using Avalonia.Threading; |
|||
using Avalonia.VisualTree; |
|||
|
|||
namespace Avalonia.Diagnostics.ViewModels |
|||
{ |
|||
internal class EventEntryTreeNode : EventTreeNode |
|||
{ |
|||
RoutedEvent _event; |
|||
EventsViewModel _parentViewModel; |
|||
bool _isRegistered; |
|||
FiredEvent _currentEvent; |
|||
|
|||
public EventEntryTreeNode(ControlTreeNode parent, RoutedEvent @event, EventsViewModel vm) |
|||
: base(parent, @event.Name) |
|||
{ |
|||
Contract.Requires<ArgumentNullException>(@event != null); |
|||
Contract.Requires<ArgumentNullException>(vm != null); |
|||
|
|||
this._event = @event; |
|||
this._parentViewModel = vm; |
|||
} |
|||
|
|||
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) |
|||
{ |
|||
_event.AddClassHandler(typeof(object), HandleEvent, (RoutingStrategies)7, handledEventsToo: true); |
|||
_isRegistered = true; |
|||
} |
|||
} |
|||
|
|||
private void HandleEvent(object sender, RoutedEventArgs e) |
|||
{ |
|||
if (!_isRegistered || IsEnabled == false) |
|||
return; |
|||
if (sender is IVisual v && DevTools.BelongsToDevTool(v)) |
|||
return; |
|||
|
|||
var s = sender; |
|||
var handled = e.Handled; |
|||
var route = e.Route; |
|||
|
|||
Action handler = delegate |
|||
{ |
|||
if (_currentEvent == null || !_currentEvent.IsPartOfSameEventChain(e)) |
|||
{ |
|||
_currentEvent = new FiredEvent(e, new ChainLink(s, handled, route)); |
|||
|
|||
_parentViewModel.RecordedEvents.Add(_currentEvent); |
|||
|
|||
while (_parentViewModel.RecordedEvents.Count > 100) |
|||
_parentViewModel.RecordedEvents.RemoveAt(0); |
|||
} |
|||
else |
|||
{ |
|||
_currentEvent.AddToChain(new ChainLink(s, handled, route)); |
|||
} |
|||
}; |
|||
|
|||
if (!Dispatcher.UIThread.CheckAccess()) |
|||
Dispatcher.UIThread.Post(handler); |
|||
else |
|||
handler(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,80 +1,98 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System.Diagnostics; |
|||
using Avalonia.Collections; |
|||
using System; |
|||
|
|||
using Avalonia.Diagnostics.Models; |
|||
using Avalonia.Interactivity; |
|||
using Avalonia.Threading; |
|||
using Avalonia.VisualTree; |
|||
|
|||
namespace Avalonia.Diagnostics.ViewModels |
|||
{ |
|||
internal abstract class EventTreeNode : ViewModelBase |
|||
internal class EventTreeNode : EventTreeNodeBase |
|||
{ |
|||
internal bool _updateChildren = true; |
|||
internal bool _updateParent = true; |
|||
private bool _isExpanded; |
|||
private bool? _isEnabled = false; |
|||
|
|||
public EventTreeNode(EventTreeNode parent, string text) |
|||
{ |
|||
this.Parent = parent; |
|||
this.Text = text; |
|||
} |
|||
private RoutedEvent _event; |
|||
private EventsViewModel _parentViewModel; |
|||
private bool _isRegistered; |
|||
private FiredEvent _currentEvent; |
|||
|
|||
public IAvaloniaReadOnlyList<EventTreeNode> Children |
|||
public EventTreeNode(EventOwnerTreeNode parent, RoutedEvent @event, EventsViewModel vm) |
|||
: base(parent, @event.Name) |
|||
{ |
|||
get; |
|||
protected set; |
|||
} |
|||
Contract.Requires<ArgumentNullException>(@event != null); |
|||
Contract.Requires<ArgumentNullException>(vm != null); |
|||
|
|||
public bool IsExpanded |
|||
{ |
|||
get { return _isExpanded; } |
|||
set { RaiseAndSetIfChanged(ref _isExpanded, value); } |
|||
this._event = @event; |
|||
this._parentViewModel = vm; |
|||
} |
|||
|
|||
public virtual bool? IsEnabled |
|||
public override bool? IsEnabled |
|||
{ |
|||
get { return _isEnabled; } |
|||
set { RaiseAndSetIfChanged(ref _isEnabled, value); } |
|||
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; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
public EventTreeNode Parent |
|||
private void UpdateTracker() |
|||
{ |
|||
get; |
|||
if (IsEnabled.GetValueOrDefault() && !_isRegistered) |
|||
{ |
|||
_event.AddClassHandler(typeof(object), HandleEvent, (RoutingStrategies)7, handledEventsToo: true); |
|||
_isRegistered = true; |
|||
} |
|||
} |
|||
|
|||
public string Text |
|||
private void HandleEvent(object sender, RoutedEventArgs e) |
|||
{ |
|||
get; |
|||
private set; |
|||
} |
|||
if (!_isRegistered || IsEnabled == false) |
|||
return; |
|||
if (sender is IVisual v && DevTools.BelongsToDevTool(v)) |
|||
return; |
|||
|
|||
internal void UpdateChecked() |
|||
{ |
|||
IsEnabled = GetValue(); |
|||
var s = sender; |
|||
var handled = e.Handled; |
|||
var route = e.Route; |
|||
|
|||
bool? GetValue() |
|||
Action handler = delegate |
|||
{ |
|||
if (Children == null) |
|||
return false; |
|||
bool? value = false; |
|||
for (int i = 0; i < Children.Count; i++) |
|||
if (_currentEvent == null || !_currentEvent.IsPartOfSameEventChain(e)) |
|||
{ |
|||
if (i == 0) |
|||
{ |
|||
value = Children[i].IsEnabled; |
|||
continue; |
|||
} |
|||
_currentEvent = new FiredEvent(e, new EventChainLink(s, handled, route)); |
|||
|
|||
if (value != Children[i].IsEnabled) |
|||
{ |
|||
value = null; |
|||
break; |
|||
} |
|||
_parentViewModel.RecordedEvents.Add(_currentEvent); |
|||
|
|||
while (_parentViewModel.RecordedEvents.Count > 100) |
|||
_parentViewModel.RecordedEvents.RemoveAt(0); |
|||
} |
|||
else |
|||
{ |
|||
_currentEvent.AddToChain(new EventChainLink(s, handled, route)); |
|||
} |
|||
}; |
|||
|
|||
return value; |
|||
} |
|||
if (!Dispatcher.UIThread.CheckAccess()) |
|||
Dispatcher.UIThread.Post(handler); |
|||
else |
|||
handler(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,78 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using Avalonia.Collections; |
|||
|
|||
namespace Avalonia.Diagnostics.ViewModels |
|||
{ |
|||
internal abstract class EventTreeNodeBase : ViewModelBase |
|||
{ |
|||
internal bool _updateChildren = true; |
|||
internal bool _updateParent = true; |
|||
private bool _isExpanded; |
|||
private bool? _isEnabled = false; |
|||
|
|||
public EventTreeNodeBase(EventTreeNodeBase parent, string text) |
|||
{ |
|||
this.Parent = parent; |
|||
this.Text = text; |
|||
} |
|||
|
|||
public IAvaloniaReadOnlyList<EventTreeNodeBase> Children |
|||
{ |
|||
get; |
|||
protected set; |
|||
} |
|||
|
|||
public bool IsExpanded |
|||
{ |
|||
get { return _isExpanded; } |
|||
set { RaiseAndSetIfChanged(ref _isExpanded, value); } |
|||
} |
|||
|
|||
public virtual bool? IsEnabled |
|||
{ |
|||
get { return _isEnabled; } |
|||
set { RaiseAndSetIfChanged(ref _isEnabled, value); } |
|||
} |
|||
|
|||
public EventTreeNodeBase Parent |
|||
{ |
|||
get; |
|||
} |
|||
|
|||
public string Text |
|||
{ |
|||
get; |
|||
private set; |
|||
} |
|||
|
|||
internal void UpdateChecked() |
|||
{ |
|||
IsEnabled = GetValue(); |
|||
|
|||
bool? GetValue() |
|||
{ |
|||
if (Children == null) |
|||
return false; |
|||
bool? value = false; |
|||
for (int i = 0; i < Children.Count; i++) |
|||
{ |
|||
if (i == 0) |
|||
{ |
|||
value = Children[i].IsEnabled; |
|||
continue; |
|||
} |
|||
|
|||
if (value != Children[i].IsEnabled) |
|||
{ |
|||
value = null; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
return value; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue