|
|
|
@ -1,99 +1,21 @@ |
|
|
|
using System.Linq; |
|
|
|
using Avalonia.Controls; |
|
|
|
using Avalonia.Controls.Primitives; |
|
|
|
using Avalonia.Diagnostics.ViewModels; |
|
|
|
using Avalonia.Input; |
|
|
|
using Avalonia.LogicalTree; |
|
|
|
using Avalonia.Markup.Xaml; |
|
|
|
using Avalonia.Media; |
|
|
|
|
|
|
|
namespace Avalonia.Diagnostics.Views |
|
|
|
{ |
|
|
|
internal class TreePageView : UserControl |
|
|
|
{ |
|
|
|
private readonly Panel _adorner; |
|
|
|
private AdornerLayer? _currentLayer; |
|
|
|
private TreeViewItem? _hovered; |
|
|
|
private TreeView _tree; |
|
|
|
private System.IDisposable? _adorner; |
|
|
|
|
|
|
|
public TreePageView() |
|
|
|
{ |
|
|
|
InitializeComponent(); |
|
|
|
_tree = this.GetControl<TreeView>("tree"); |
|
|
|
|
|
|
|
_adorner = new Panel |
|
|
|
{ |
|
|
|
ClipToBounds = false, |
|
|
|
Children = |
|
|
|
{ |
|
|
|
//Padding frame
|
|
|
|
new Border { BorderBrush = new SolidColorBrush(Colors.Green, 0.5) }, |
|
|
|
//Content frame
|
|
|
|
new Border { Background = new SolidColorBrush(Color.FromRgb(160, 197, 232), 0.5) }, |
|
|
|
//Margin frame
|
|
|
|
new Border { BorderBrush = new SolidColorBrush(Colors.Yellow, 0.5) } |
|
|
|
}, |
|
|
|
}; |
|
|
|
AdornerLayer.SetIsClipEnabled(_adorner, false); |
|
|
|
} |
|
|
|
|
|
|
|
private static Thickness InvertThickness(Thickness input) |
|
|
|
{ |
|
|
|
return new Thickness(-input.Left, -input.Top, -input.Right, -input.Bottom); |
|
|
|
} |
|
|
|
|
|
|
|
protected void AddAdorner(object? sender, PointerEventArgs e) |
|
|
|
{ |
|
|
|
var node = (TreeNode?)((Control)sender!).DataContext; |
|
|
|
var vm = (TreePageViewModel?)DataContext; |
|
|
|
if (node is null || vm is null) |
|
|
|
{ |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
var visual = node.Visual as Visual; |
|
|
|
|
|
|
|
if (visual is null) |
|
|
|
{ |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
_currentLayer = AdornerLayer.GetAdornerLayer(visual); |
|
|
|
|
|
|
|
if (_currentLayer == null || |
|
|
|
_currentLayer.Children.Contains(_adorner)) |
|
|
|
{ |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
_currentLayer.Children.Add(_adorner); |
|
|
|
AdornerLayer.SetAdornedElement(_adorner, visual); |
|
|
|
|
|
|
|
if (vm.MainView.ShouldVisualizeMarginPadding) |
|
|
|
{ |
|
|
|
var paddingBorder = (Border)_adorner.Children[0]; |
|
|
|
paddingBorder.BorderThickness = visual.GetValue(PaddingProperty); |
|
|
|
|
|
|
|
var contentBorder = (Border)_adorner.Children[1]; |
|
|
|
contentBorder.Margin = visual.GetValue(PaddingProperty); |
|
|
|
|
|
|
|
var marginBorder = (Border)_adorner.Children[2]; |
|
|
|
marginBorder.BorderThickness = visual.GetValue(MarginProperty); |
|
|
|
marginBorder.Margin = InvertThickness(visual.GetValue(MarginProperty)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
protected void RemoveAdorner(object? sender, PointerEventArgs e) |
|
|
|
{ |
|
|
|
foreach (var border in _adorner.Children.OfType<Border>()) |
|
|
|
{ |
|
|
|
border.Margin = default; |
|
|
|
border.Padding = default; |
|
|
|
border.BorderThickness = default; |
|
|
|
} |
|
|
|
|
|
|
|
_currentLayer?.Children.Remove(_adorner); |
|
|
|
_currentLayer = null; |
|
|
|
} |
|
|
|
|
|
|
|
protected void UpdateAdorner(object? sender, PointerEventArgs e) |
|
|
|
@ -109,7 +31,7 @@ namespace Avalonia.Diagnostics.Views |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
RemoveAdorner(sender, e); |
|
|
|
_adorner?.Dispose(); |
|
|
|
|
|
|
|
if (item is null || item.TreeViewOwner != _tree) |
|
|
|
{ |
|
|
|
@ -118,7 +40,15 @@ namespace Avalonia.Diagnostics.Views |
|
|
|
} |
|
|
|
|
|
|
|
_hovered = item; |
|
|
|
AddAdorner(item, e); |
|
|
|
|
|
|
|
var visual = (item.DataContext as TreeNode)?.Visual as Visual; |
|
|
|
var shouldVisualizeMarginPadding = (DataContext as TreePageViewModel)?.MainView.ShouldVisualizeMarginPadding; |
|
|
|
if (visual is null || shouldVisualizeMarginPadding is null) |
|
|
|
{ |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
_adorner = Controls.ControlHighlightAdorner.Add(visual, visualizeMarginPadding: shouldVisualizeMarginPadding == true); |
|
|
|
} |
|
|
|
|
|
|
|
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) |
|
|
|
|