diff --git a/src/Avalonia.Diagnostics/Diagnostics/Controls/ThicknessEditor.axaml b/src/Avalonia.Diagnostics/Diagnostics/Controls/ThicknessEditor.axaml
new file mode 100644
index 0000000000..c202d13778
--- /dev/null
+++ b/src/Avalonia.Diagnostics/Diagnostics/Controls/ThicknessEditor.axaml
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Diagnostics/Diagnostics/Views/ThicknessEditor.cs b/src/Avalonia.Diagnostics/Diagnostics/Controls/ThicknessEditor.cs
similarity index 98%
rename from src/Avalonia.Diagnostics/Diagnostics/Views/ThicknessEditor.cs
rename to src/Avalonia.Diagnostics/Diagnostics/Controls/ThicknessEditor.cs
index 2f03a23fdf..e5b3b080e2 100644
--- a/src/Avalonia.Diagnostics/Diagnostics/Views/ThicknessEditor.cs
+++ b/src/Avalonia.Diagnostics/Diagnostics/Controls/ThicknessEditor.cs
@@ -2,7 +2,7 @@ using Avalonia.Controls;
using Avalonia.Data;
using Avalonia.Media;
-namespace Avalonia.Diagnostics.Views
+namespace Avalonia.Diagnostics.Controls
{
internal class ThicknessEditor : ContentControl
{
@@ -35,12 +35,6 @@ namespace Avalonia.Diagnostics.Views
public static readonly StyledProperty HighlightProperty =
AvaloniaProperty.Register(nameof(Highlight));
- public IBrush Highlight
- {
- get => GetValue(HighlightProperty);
- set => SetValue(HighlightProperty, value);
- }
-
private Thickness _thickness;
private string _header;
private bool _isPresent = true;
@@ -92,6 +86,12 @@ namespace Avalonia.Diagnostics.Views
set => SetAndRaise(BottomProperty, ref _bottom, value);
}
+ public IBrush Highlight
+ {
+ get => GetValue(HighlightProperty);
+ set => SetValue(HighlightProperty, value);
+ }
+
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
base.OnPropertyChanged(change);
diff --git a/src/Avalonia.Diagnostics/Diagnostics/Converters/EnumToCheckedConverter.cs b/src/Avalonia.Diagnostics/Diagnostics/Converters/EnumToCheckedConverter.cs
new file mode 100644
index 0000000000..8d10981ba7
--- /dev/null
+++ b/src/Avalonia.Diagnostics/Diagnostics/Converters/EnumToCheckedConverter.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Globalization;
+using Avalonia.Data;
+using Avalonia.Data.Converters;
+
+namespace Avalonia.Diagnostics.Converters
+{
+ internal class EnumToCheckedConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return Equals(value, parameter);
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (value is bool isChecked && isChecked)
+ {
+ return parameter;
+ }
+
+ return BindingOperations.DoNothing;
+ }
+ }
+}
diff --git a/src/Avalonia.Diagnostics/Diagnostics/DevToolsOptions.cs b/src/Avalonia.Diagnostics/Diagnostics/DevToolsOptions.cs
index ee46192207..f9978f3b7e 100644
--- a/src/Avalonia.Diagnostics/Diagnostics/DevToolsOptions.cs
+++ b/src/Avalonia.Diagnostics/Diagnostics/DevToolsOptions.cs
@@ -19,8 +19,8 @@ namespace Avalonia.Diagnostics
public bool ShowAsChildWindow { get; set; } = true;
///
- /// Gets or sets the initial size of the DevTools window. The default value is 1024x512.
+ /// Gets or sets the initial size of the DevTools window. The default value is 1280x720.
///
- public Size Size { get; set; } = new Size(1024, 512);
+ public Size Size { get; set; } = new Size(1280, 720);
}
}
diff --git a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlLayoutViewModel.cs b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlLayoutViewModel.cs
index ef227f7374..b0718bc6ce 100644
--- a/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlLayoutViewModel.cs
+++ b/src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlLayoutViewModel.cs
@@ -10,27 +10,58 @@ namespace Avalonia.Diagnostics.ViewModels
internal class ControlLayoutViewModel : ViewModelBase
{
private readonly IVisual _control;
- private Thickness _marginThickness;
private Thickness _borderThickness;
- private Thickness _paddingThickness;
- private double _width;
private double _height;
- private string _widthConstraint;
private string _heightConstraint;
+ private HorizontalAlignment _horizontalAlignment;
+ private Thickness _marginThickness;
+ private Thickness _paddingThickness;
private bool _updatingFromControl;
+ private VerticalAlignment _verticalAlignment;
+ private double _width;
+ private string _widthConstraint;
+
+ public ControlLayoutViewModel(IVisual control)
+ {
+ _control = control;
+
+ HasPadding = AvaloniaPropertyRegistry.Instance.IsRegistered(control, Decorator.PaddingProperty);
+ HasBorder = AvaloniaPropertyRegistry.Instance.IsRegistered(control, Border.BorderThicknessProperty);
+
+ if (control is AvaloniaObject ao)
+ {
+ MarginThickness = ao.GetValue(Layoutable.MarginProperty);
+
+ if (HasPadding)
+ {
+ PaddingThickness = ao.GetValue(Decorator.PaddingProperty);
+ }
+
+ if (HasBorder)
+ {
+ BorderThickness = ao.GetValue(Border.BorderThicknessProperty);
+ }
+
+ HorizontalAlignment = ao.GetValue(Layoutable.HorizontalAlignmentProperty);
+ VerticalAlignment = ao.GetValue(Layoutable.VerticalAlignmentProperty);
+ }
+
+ UpdateSize();
+ UpdateSizeConstraints();
+ }
public Thickness MarginThickness
{
get => _marginThickness;
set => RaiseAndSetIfChanged(ref _marginThickness, value);
}
-
+
public Thickness BorderThickness
{
get => _borderThickness;
set => RaiseAndSetIfChanged(ref _borderThickness, value);
}
-
+
public Thickness PaddingThickness
{
get => _paddingThickness;
@@ -61,35 +92,21 @@ namespace Avalonia.Diagnostics.ViewModels
private set => RaiseAndSetIfChanged(ref _heightConstraint, value);
}
- public bool HasPadding { get; }
-
- public bool HasBorder { get; }
-
- public ControlLayoutViewModel(IVisual control)
+ public HorizontalAlignment HorizontalAlignment
{
- _control = control;
-
- HasPadding = AvaloniaPropertyRegistry.Instance.IsRegistered(control, Decorator.PaddingProperty);
- HasBorder = AvaloniaPropertyRegistry.Instance.IsRegistered(control, Border.BorderThicknessProperty);
-
- if (control is AvaloniaObject ao)
- {
- MarginThickness = ao.GetValue(Layoutable.MarginProperty);
+ get => _horizontalAlignment;
+ private set => RaiseAndSetIfChanged(ref _horizontalAlignment, value);
+ }
- if (HasPadding)
- {
- PaddingThickness = ao.GetValue(Decorator.PaddingProperty);
- }
+ public VerticalAlignment VerticalAlignment
+ {
+ get => _verticalAlignment;
+ private set => RaiseAndSetIfChanged(ref _verticalAlignment, value);
+ }
- if (HasBorder)
- {
- BorderThickness = ao.GetValue(Border.BorderThicknessProperty);
- }
- }
+ public bool HasPadding { get; }
- UpdateSize();
- UpdateSizeConstraints();
- }
+ public bool HasBorder { get; }
private void UpdateSizeConstraints()
{
@@ -151,6 +168,14 @@ namespace Avalonia.Diagnostics.ViewModels
{
ao.SetValue(Border.BorderThicknessProperty, BorderThickness);
}
+ else if (e.PropertyName == nameof(HorizontalAlignment))
+ {
+ ao.SetValue(Layoutable.HorizontalAlignmentProperty, HorizontalAlignment);
+ }
+ else if (e.PropertyName == nameof(VerticalAlignment))
+ {
+ ao.SetValue(Layoutable.VerticalAlignmentProperty, VerticalAlignment);
+ }
}
}
@@ -171,15 +196,15 @@ namespace Avalonia.Diagnostics.ViewModels
if (e.Property == Layoutable.MarginProperty)
{
MarginThickness = ao.GetValue(Layoutable.MarginProperty);
- }
+ }
else if (e.Property == Decorator.PaddingProperty)
{
PaddingThickness = ao.GetValue(Decorator.PaddingProperty);
- }
+ }
else if (e.Property == Border.BorderThicknessProperty)
{
BorderThickness = ao.GetValue(Border.BorderThicknessProperty);
- }
+ }
else if (e.Property == Layoutable.MinWidthProperty ||
e.Property == Layoutable.MaxWidthProperty ||
e.Property == Layoutable.MinHeightProperty ||
@@ -187,6 +212,14 @@ namespace Avalonia.Diagnostics.ViewModels
{
UpdateSizeConstraints();
}
+ else if (e.Property == Layoutable.HorizontalAlignmentProperty)
+ {
+ HorizontalAlignment = ao.GetValue(Layoutable.HorizontalAlignmentProperty);
+ }
+ else if (e.Property == Layoutable.VerticalAlignmentProperty)
+ {
+ VerticalAlignment = ao.GetValue(Layoutable.VerticalAlignmentProperty);
+ }
}
}
}
diff --git a/src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml b/src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml
index 50534e77b8..ab651b2a06 100644
--- a/src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml
+++ b/src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml
@@ -7,88 +7,10 @@
x:Name="Main">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -130,184 +52,133 @@
-
-
+
-
-
-
-
-
+
+
+
+
-
+
-
-
-
+
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
- (
-
-
- )
+
+
+
+
-
-
-
+
-
-
-
-
-
-
-
-
+
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (
+
+
+ )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml.cs b/src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml.cs
index c9568509f6..c6bd5a18aa 100644
--- a/src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml.cs
+++ b/src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml.cs
@@ -1,24 +1,10 @@
-using System;
using Avalonia.Controls;
-using Avalonia.Controls.Shapes;
using Avalonia.Markup.Xaml;
-using Avalonia.VisualTree;
namespace Avalonia.Diagnostics.Views
{
internal class ControlDetailsView : UserControl
{
- private ThicknessEditor _borderArea;
- private ThicknessEditor _paddingArea;
- private Rectangle _horizontalSizeBegin;
- private Rectangle _horizontalSizeEnd;
- private Rectangle _verticalSizeBegin;
- private Rectangle _verticalSizeEnd;
- private Grid _layoutRoot;
- private Border _horizontalSize;
- private Border _verticalSize;
- private Border _contentArea;
-
public ControlDetailsView()
{
InitializeComponent();
@@ -27,101 +13,6 @@ namespace Avalonia.Diagnostics.Views
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
-
- _borderArea = this.FindControl("BorderArea");
- _paddingArea = this.FindControl("PaddingArea");
-
- _horizontalSizeBegin = this.FindControl("HorizontalSizeBegin");
- _horizontalSizeEnd = this.FindControl("HorizontalSizeEnd");
- _verticalSizeBegin = this.FindControl("VerticalSizeBegin");
- _verticalSizeEnd = this.FindControl("VerticalSizeEnd");
-
- _horizontalSize = this.FindControl("HorizontalSize");
- _verticalSize = this.FindControl("VerticalSize");
-
- _contentArea = this.FindControl("ContentArea");
-
- _layoutRoot = this.FindControl("LayoutRoot");
-
- void SubscribeToBounds(Visual visual)
- {
- visual.GetPropertyChangedObservable(TransformedBoundsProperty)
- .Subscribe(UpdateSizeGuidelines);
- }
-
- SubscribeToBounds(_borderArea);
- SubscribeToBounds(_paddingArea);
- SubscribeToBounds(_contentArea);
- }
-
- private void UpdateSizeGuidelines(AvaloniaPropertyChangedEventArgs e)
- {
- void UpdateGuidelines(Visual area)
- {
- if (area.TransformedBounds is TransformedBounds bounds)
- {
- // Horizontal guideline
- {
- var sizeArea = TranslateToRoot((_horizontalSize.TransformedBounds ?? default).Bounds.BottomLeft,
- _horizontalSize);
-
- var start = TranslateToRoot(bounds.Bounds.BottomLeft, area);
-
- SetPosition(_horizontalSizeBegin, start);
-
- var end = TranslateToRoot(bounds.Bounds.BottomRight, area);
-
- SetPosition(_horizontalSizeEnd, end.WithX(end.X - 1));
-
- var height = sizeArea.Y - start.Y + 2;
-
- _horizontalSizeBegin.Height = height;
- _horizontalSizeEnd.Height = height;
- }
-
- // Vertical guideline
- {
- var sizeArea = TranslateToRoot((_verticalSize.TransformedBounds ?? default).Bounds.TopRight, _verticalSize);
-
- var start = TranslateToRoot(bounds.Bounds.TopRight, area);
-
- SetPosition(_verticalSizeBegin, start);
-
- var end = TranslateToRoot(bounds.Bounds.BottomRight, area);
-
- SetPosition(_verticalSizeEnd, end.WithY(end.Y - 1));
-
- var width = sizeArea.X - start.X + 2;
-
- _verticalSizeBegin.Width = width;
- _verticalSizeEnd.Width = width;
- }
- }
- }
-
- Point TranslateToRoot(Point point, IVisual from)
- {
- return from.TranslatePoint(point, _layoutRoot) ?? default;
- }
-
- static void SetPosition(Rectangle rect, Point start)
- {
- Canvas.SetLeft(rect, start.X);
- Canvas.SetTop(rect, start.Y);
- }
-
- if (_borderArea.IsPresent)
- {
- UpdateGuidelines(_borderArea);
- }
- else if (_paddingArea.IsPresent)
- {
- UpdateGuidelines(_paddingArea);
- }
- else
- {
- UpdateGuidelines(_contentArea);
- }
}
}
}
diff --git a/src/Avalonia.Diagnostics/Diagnostics/Views/LayoutExplorerView.axaml b/src/Avalonia.Diagnostics/Diagnostics/Views/LayoutExplorerView.axaml
new file mode 100644
index 0000000000..af6c84a76a
--- /dev/null
+++ b/src/Avalonia.Diagnostics/Diagnostics/Views/LayoutExplorerView.axaml
@@ -0,0 +1,210 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Avalonia.Diagnostics/Diagnostics/Views/LayoutExplorerView.axaml.cs b/src/Avalonia.Diagnostics/Diagnostics/Views/LayoutExplorerView.axaml.cs
new file mode 100644
index 0000000000..d4a09f7296
--- /dev/null
+++ b/src/Avalonia.Diagnostics/Diagnostics/Views/LayoutExplorerView.axaml.cs
@@ -0,0 +1,128 @@
+using System;
+using Avalonia.Controls;
+using Avalonia.Controls.Shapes;
+using Avalonia.Diagnostics.Controls;
+using Avalonia.Markup.Xaml;
+using Avalonia.VisualTree;
+
+namespace Avalonia.Diagnostics.Views
+{
+ internal class LayoutExplorerView : UserControl
+ {
+ private readonly ThicknessEditor _borderArea;
+ private readonly ThicknessEditor _paddingArea;
+ private readonly Rectangle _horizontalSizeBegin;
+ private readonly Rectangle _horizontalSizeEnd;
+ private readonly Rectangle _verticalSizeBegin;
+ private readonly Rectangle _verticalSizeEnd;
+ private readonly Grid _layoutRoot;
+ private readonly Border _horizontalSize;
+ private readonly Border _verticalSize;
+ private readonly Border _contentArea;
+
+ public LayoutExplorerView()
+ {
+ InitializeComponent();
+
+ _borderArea = this.FindControl("BorderArea");
+ _paddingArea = this.FindControl("PaddingArea");
+
+ _horizontalSizeBegin = this.FindControl("HorizontalSizeBegin");
+ _horizontalSizeEnd = this.FindControl("HorizontalSizeEnd");
+ _verticalSizeBegin = this.FindControl("VerticalSizeBegin");
+ _verticalSizeEnd = this.FindControl("VerticalSizeEnd");
+
+ _horizontalSize = this.FindControl("HorizontalSize");
+ _verticalSize = this.FindControl("VerticalSize");
+
+ _contentArea = this.FindControl("ContentArea");
+
+ _layoutRoot = this.FindControl("LayoutRoot");
+
+ void SubscribeToBounds(Visual visual)
+ {
+ visual.GetPropertyChangedObservable(TransformedBoundsProperty)
+ .Subscribe(UpdateSizeGuidelines);
+ }
+
+ SubscribeToBounds(_borderArea);
+ SubscribeToBounds(_paddingArea);
+ SubscribeToBounds(_contentArea);
+ }
+
+ private void InitializeComponent()
+ {
+ AvaloniaXamlLoader.Load(this);
+ }
+
+ private void UpdateSizeGuidelines(AvaloniaPropertyChangedEventArgs e)
+ {
+ void UpdateGuidelines(Visual area)
+ {
+ if (area.TransformedBounds is TransformedBounds bounds)
+ {
+ // Horizontal guideline
+ {
+ var sizeArea = TranslateToRoot((_horizontalSize.TransformedBounds ?? default).Bounds.BottomLeft,
+ _horizontalSize);
+
+ var start = TranslateToRoot(bounds.Bounds.BottomLeft, area);
+
+ SetPosition(_horizontalSizeBegin, start);
+
+ var end = TranslateToRoot(bounds.Bounds.BottomRight, area);
+
+ SetPosition(_horizontalSizeEnd, end.WithX(end.X - 1));
+
+ var height = sizeArea.Y - start.Y + 2;
+
+ _horizontalSizeBegin.Height = height;
+ _horizontalSizeEnd.Height = height;
+ }
+
+ // Vertical guideline
+ {
+ var sizeArea = TranslateToRoot((_verticalSize.TransformedBounds ?? default).Bounds.TopRight, _verticalSize);
+
+ var start = TranslateToRoot(bounds.Bounds.TopRight, area);
+
+ SetPosition(_verticalSizeBegin, start);
+
+ var end = TranslateToRoot(bounds.Bounds.BottomRight, area);
+
+ SetPosition(_verticalSizeEnd, end.WithY(end.Y - 1));
+
+ var width = sizeArea.X - start.X + 2;
+
+ _verticalSizeBegin.Width = width;
+ _verticalSizeEnd.Width = width;
+ }
+ }
+ }
+
+ Point TranslateToRoot(Point point, IVisual from)
+ {
+ return from.TranslatePoint(point, _layoutRoot) ?? default;
+ }
+
+ static void SetPosition(Rectangle rect, Point start)
+ {
+ Canvas.SetLeft(rect, start.X);
+ Canvas.SetTop(rect, start.Y);
+ }
+
+ if (_borderArea.IsPresent)
+ {
+ UpdateGuidelines(_borderArea);
+ }
+ else if (_paddingArea.IsPresent)
+ {
+ UpdateGuidelines(_paddingArea);
+ }
+ else
+ {
+ UpdateGuidelines(_contentArea);
+ }
+ }
+ }
+}
diff --git a/src/Avalonia.Diagnostics/Diagnostics/Views/MainWindow.xaml b/src/Avalonia.Diagnostics/Diagnostics/Views/MainWindow.xaml
index 7dd4ed0832..7628ee2d8c 100644
--- a/src/Avalonia.Diagnostics/Diagnostics/Views/MainWindow.xaml
+++ b/src/Avalonia.Diagnostics/Diagnostics/Views/MainWindow.xaml
@@ -15,6 +15,7 @@
+
diff --git a/src/Avalonia.Diagnostics/Diagnostics/Views/TreePageView.xaml b/src/Avalonia.Diagnostics/Diagnostics/Views/TreePageView.xaml
index fd631f0dff..a5328716fc 100644
--- a/src/Avalonia.Diagnostics/Diagnostics/Views/TreePageView.xaml
+++ b/src/Avalonia.Diagnostics/Diagnostics/Views/TreePageView.xaml
@@ -2,7 +2,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:Avalonia.Diagnostics.ViewModels"
x:Class="Avalonia.Diagnostics.Views.TreePageView">
-
+