Browse Source

Merge pull request #4523 from pr8x/feature-devtools-padding-margin

Adding margin/padding visualization to DevTools
pull/4532/head
danwalmsley 6 years ago
committed by GitHub
parent
commit
b06b0f8200
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 16
      src/Avalonia.Diagnostics/Diagnostics/ViewModels/MainViewModel.cs
  2. 7
      src/Avalonia.Diagnostics/Diagnostics/ViewModels/TreePageViewModel.cs
  3. 9
      src/Avalonia.Diagnostics/Diagnostics/Views/MainView.xaml
  4. 71
      src/Avalonia.Diagnostics/Diagnostics/Views/TreePageView.xaml.cs

16
src/Avalonia.Diagnostics/Diagnostics/ViewModels/MainViewModel.cs

@ -18,12 +18,13 @@ namespace Avalonia.Diagnostics.ViewModels
private int _selectedTab;
private string _focusedControl;
private string _pointerOverElement;
private bool _shouldVisualizeMarginPadding = true;
public MainViewModel(IControl root)
{
_root = root;
_logicalTree = new TreePageViewModel(LogicalTreeNode.Create(root));
_visualTree = new TreePageViewModel(VisualTreeNode.Create(root));
_logicalTree = new TreePageViewModel(this, LogicalTreeNode.Create(root));
_visualTree = new TreePageViewModel(this, VisualTreeNode.Create(root));
_events = new EventsPageViewModel(root);
UpdateFocusedControl();
@ -34,6 +35,17 @@ namespace Avalonia.Diagnostics.ViewModels
Console = new ConsoleViewModel(UpdateConsoleContext);
}
public bool ShouldVisualizeMarginPadding
{
get => _shouldVisualizeMarginPadding;
set => RaiseAndSetIfChanged(ref _shouldVisualizeMarginPadding, value);
}
public void ToggleVisualizeMarginPadding()
{
ShouldVisualizeMarginPadding = !ShouldVisualizeMarginPadding;
}
public ConsoleViewModel Console { get; }
public ViewModelBase Content

7
src/Avalonia.Diagnostics/Diagnostics/ViewModels/TreePageViewModel.cs

@ -10,8 +10,9 @@ namespace Avalonia.Diagnostics.ViewModels
private ControlDetailsViewModel _details;
private string _propertyFilter;
public TreePageViewModel(TreeNode[] nodes)
public TreePageViewModel(MainViewModel mainView, TreeNode[] nodes)
{
MainView = mainView;
Nodes = nodes;
Selection = new SelectionModel
{
@ -23,7 +24,9 @@ namespace Avalonia.Diagnostics.ViewModels
{
SelectedNode = (TreeNode)Selection.SelectedItem;
};
}
}
public MainViewModel MainView { get; }
public TreeNode[] Nodes { get; protected set; }

9
src/Avalonia.Diagnostics/Diagnostics/Views/MainView.xaml

@ -16,6 +16,15 @@
</MenuItem.Icon>
</MenuItem>
</MenuItem>
<MenuItem Header="_Options">
<MenuItem Header="Visualize margin/padding" Command="{Binding ToggleVisualizeMarginPadding}">
<MenuItem.Icon>
<CheckBox BorderThickness="0"
IsChecked="{Binding ShouldVisualizeMarginPadding}"
IsEnabled="False"/>
</MenuItem.Icon>
</MenuItem>
</MenuItem>
</Menu>
<TabStrip Grid.Row="1" SelectedIndex="{Binding SelectedTab, Mode=TwoWay}">

71
src/Avalonia.Diagnostics/Diagnostics/Views/TreePageView.xaml.cs

@ -1,7 +1,7 @@
using System.Linq;
using Avalonia.Controls;
using Avalonia.Controls.Generators;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Shapes;
using Avalonia.Diagnostics.ViewModels;
using Avalonia.Input;
using Avalonia.Markup.Xaml;
@ -11,45 +11,78 @@ namespace Avalonia.Diagnostics.Views
{
internal class TreePageView : UserControl
{
private Control _adorner;
private readonly Panel _adorner;
private AdornerLayer _currentLayer;
private TreeView _tree;
public TreePageView()
{
this.InitializeComponent();
InitializeComponent();
_tree.ItemContainerGenerator.Index.Materialized += TreeViewItemMaterialized;
_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) }
},
};
}
protected void AddAdorner(object sender, PointerEventArgs e)
{
var node = (TreeNode)((Control)sender).DataContext;
var layer = AdornerLayer.GetAdornerLayer(node.Visual);
var visual = (Visual)node.Visual;
_currentLayer = AdornerLayer.GetAdornerLayer(visual);
if (layer != null)
if (_currentLayer == null ||
_currentLayer.Children.Contains(_adorner))
{
if (_adorner != null)
{
((Panel)_adorner.Parent).Children.Remove(_adorner);
_adorner = null;
}
return;
}
_adorner = new Rectangle
{
Fill = new SolidColorBrush(0x80a0c5e8),
[AdornerLayer.AdornedElementProperty] = node.Visual,
};
_currentLayer.Children.Add(_adorner);
AdornerLayer.SetAdornedElement(_adorner, visual);
var vm = (TreePageViewModel) DataContext;
layer.Children.Add(_adorner);
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));
}
}
private static Thickness InvertThickness(Thickness input)
{
return new Thickness(-input.Left, -input.Top, -input.Right, -input.Bottom);
}
protected void RemoveAdorner(object sender, PointerEventArgs e)
{
if (_adorner != null)
foreach (var border in _adorner.Children.OfType<Border>())
{
((Panel)_adorner.Parent).Children.Remove(_adorner);
_adorner = null;
border.Margin = default;
border.Padding = default;
border.BorderThickness = default;
}
_currentLayer?.Children.Remove(_adorner);
_currentLayer = null;
}
private void InitializeComponent()

Loading…
Cancel
Save