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

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

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

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

@ -16,6 +16,15 @@
</MenuItem.Icon> </MenuItem.Icon>
</MenuItem> </MenuItem>
</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> </Menu>
<TabStrip Grid.Row="1" SelectedIndex="{Binding SelectedTab, Mode=TwoWay}"> <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;
using Avalonia.Controls.Generators; using Avalonia.Controls.Generators;
using Avalonia.Controls.Primitives; using Avalonia.Controls.Primitives;
using Avalonia.Controls.Shapes;
using Avalonia.Diagnostics.ViewModels; using Avalonia.Diagnostics.ViewModels;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
@ -11,45 +11,78 @@ namespace Avalonia.Diagnostics.Views
{ {
internal class TreePageView : UserControl internal class TreePageView : UserControl
{ {
private Control _adorner; private readonly Panel _adorner;
private AdornerLayer _currentLayer;
private TreeView _tree; private TreeView _tree;
public TreePageView() public TreePageView()
{ {
this.InitializeComponent(); InitializeComponent();
_tree.ItemContainerGenerator.Index.Materialized += TreeViewItemMaterialized; _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) protected void AddAdorner(object sender, PointerEventArgs e)
{ {
var node = (TreeNode)((Control)sender).DataContext; 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) return;
{ }
((Panel)_adorner.Parent).Children.Remove(_adorner);
_adorner = null;
}
_adorner = new Rectangle _currentLayer.Children.Add(_adorner);
{ AdornerLayer.SetAdornedElement(_adorner, visual);
Fill = new SolidColorBrush(0x80a0c5e8),
[AdornerLayer.AdornedElementProperty] = node.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) protected void RemoveAdorner(object sender, PointerEventArgs e)
{ {
if (_adorner != null) foreach (var border in _adorner.Children.OfType<Border>())
{ {
((Panel)_adorner.Parent).Children.Remove(_adorner); border.Margin = default;
_adorner = null; border.Padding = default;
border.BorderThickness = default;
} }
_currentLayer?.Children.Remove(_adorner);
_currentLayer = null;
} }
private void InitializeComponent() private void InitializeComponent()

Loading…
Cancel
Save