Browse Source

Merge branch 'master' into fixes/DevTools/NRE

pull/7273/head
Max Katz 5 years ago
committed by GitHub
parent
commit
ee2c603c3d
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 24
      src/Avalonia.Diagnostics/Diagnostics/Converters/GetTypeNameConverter.cs
  2. 33
      src/Avalonia.Diagnostics/Diagnostics/TypeExtesnions.cs
  3. 13
      src/Avalonia.Diagnostics/Diagnostics/ViewModels/AvaloniaPropertyViewModel.cs
  4. 12
      src/Avalonia.Diagnostics/Diagnostics/ViewModels/ClrPropertyViewModel.cs
  5. 6
      src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlDetailsViewModel.cs
  6. 12
      src/Avalonia.Diagnostics/Diagnostics/ViewModels/MainViewModel.cs
  7. 13
      src/Avalonia.Diagnostics/Diagnostics/ViewModels/PropertyViewModel.cs
  8. 14
      src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml
  9. 10
      src/Avalonia.Diagnostics/Diagnostics/Views/MainView.xaml

24
src/Avalonia.Diagnostics/Diagnostics/Converters/GetTypeNameConverter.cs

@ -0,0 +1,24 @@
using System;
using System.Globalization;
using Avalonia.Data;
using Avalonia.Data.Converters;
namespace Avalonia.Diagnostics.Converters
{
internal class GetTypeNameConverter : IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is Type type)
{
return type.GetTypeName();
}
return BindingOperations.DoNothing;
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
return BindingOperations.DoNothing;
}
}
}

33
src/Avalonia.Diagnostics/Diagnostics/TypeExtesnions.cs

@ -0,0 +1,33 @@
using System;
using System.Runtime.CompilerServices;
using System.Linq;
namespace Avalonia.Diagnostics
{
internal static class TypeExtesnions
{
private static readonly ConditionalWeakTable<Type, string> s_getTypeNameCache =
new ConditionalWeakTable<Type, string>();
public static string GetTypeName(this Type type)
{
if (!s_getTypeNameCache.TryGetValue(type, out var name))
{
name = type.Name;
if (Nullable.GetUnderlyingType(type) is Type nullable)
{
name = nullable.Name + "?";
}
else if (type.IsGenericType)
{
var definition = type.GetGenericTypeDefinition();
var arguments = type.GetGenericArguments();
name = definition.Name.Substring(0, definition.Name.IndexOf('`'));
name = $"{name}<{string.Join(",", arguments.Select(GetTypeName))}>";
}
s_getTypeNameCache.Add(type, name);
}
return name;
}
}
}

13
src/Avalonia.Diagnostics/Diagnostics/ViewModels/AvaloniaPropertyViewModel.cs

@ -3,10 +3,11 @@ namespace Avalonia.Diagnostics.ViewModels
internal class AvaloniaPropertyViewModel : PropertyViewModel
{
private readonly AvaloniaObject _target;
private System.Type _type;
private System.Type _assignedType;
private object? _value;
private string _priority;
private string _group;
private readonly System.Type _propertyType;
#nullable disable
// Remove "nullable disable" after MemberNotNull will work on our CI.
@ -20,6 +21,7 @@ namespace Avalonia.Diagnostics.ViewModels
$"[{property.OwnerType.Name}.{property.Name}]" :
property.Name;
DeclaringType = property.OwnerType;
_propertyType = property.PropertyType;
Update();
}
@ -32,7 +34,7 @@ namespace Avalonia.Diagnostics.ViewModels
public override string Priority =>
_priority;
public override System.Type Type => _type;
public override System.Type AssignedType => _assignedType;
public override string? Value
{
@ -43,6 +45,7 @@ namespace Avalonia.Diagnostics.ViewModels
{
var convertedValue = ConvertFromString(value, Property.PropertyType);
_target.SetValue(Property, convertedValue);
Update();
}
catch { }
}
@ -51,6 +54,7 @@ namespace Avalonia.Diagnostics.ViewModels
public override string Group => _group;
public override System.Type? DeclaringType { get; }
public override System.Type PropertyType => _propertyType;
// [MemberNotNull(nameof(_type), nameof(_group), nameof(_priority))]
public override void Update()
@ -58,7 +62,7 @@ namespace Avalonia.Diagnostics.ViewModels
if (Property.IsDirect)
{
RaiseAndSetIfChanged(ref _value, _target.GetValue(Property), nameof(Value));
RaiseAndSetIfChanged(ref _type, _value?.GetType() ?? Property.PropertyType, nameof(Type));
RaiseAndSetIfChanged(ref _assignedType,_value?.GetType() ?? Property.PropertyType, nameof(AssignedType));
RaiseAndSetIfChanged(ref _priority, "Direct", nameof(Priority));
_group = "Properties";
@ -68,7 +72,7 @@ namespace Avalonia.Diagnostics.ViewModels
var val = _target.GetDiagnostic(Property);
RaiseAndSetIfChanged(ref _value, val?.Value, nameof(Value));
RaiseAndSetIfChanged(ref _type, _value?.GetType() ?? Property.PropertyType, nameof(Type));
RaiseAndSetIfChanged(ref _assignedType, _value?.GetType() ?? Property.PropertyType, nameof(AssignedType));
if (val != null)
{
@ -81,6 +85,7 @@ namespace Avalonia.Diagnostics.ViewModels
RaiseAndSetIfChanged(ref _group, "Unset", nameof(Group));
}
}
RaisePropertyChanged(nameof(Type));
}
}
}

12
src/Avalonia.Diagnostics/Diagnostics/ViewModels/ClrPropertyViewModel.cs

@ -5,8 +5,9 @@ namespace Avalonia.Diagnostics.ViewModels
internal class ClrPropertyViewModel : PropertyViewModel
{
private readonly object _target;
private System.Type _type;
private System.Type _assignedType;
private object? _value;
private readonly System.Type _propertyType;
#nullable disable
// Remove "nullable disable" after MemberNotNull will work on our CI.
@ -25,6 +26,8 @@ namespace Avalonia.Diagnostics.ViewModels
Name = property.DeclaringType.Name + '.' + property.Name;
}
DeclaringType = property.DeclaringType;
_propertyType = property.PropertyType;
Update();
}
@ -33,7 +36,8 @@ namespace Avalonia.Diagnostics.ViewModels
public override string Name { get; }
public override string Group => "CLR Properties";
public override System.Type Type => _type;
public override System.Type AssignedType => _assignedType;
public override System.Type PropertyType => _propertyType;
public override string? Value
{
@ -44,6 +48,7 @@ namespace Avalonia.Diagnostics.ViewModels
{
var convertedValue = ConvertFromString(value, Property.PropertyType);
Property.SetValue(_target, convertedValue);
Update();
}
catch { }
}
@ -62,7 +67,8 @@ namespace Avalonia.Diagnostics.ViewModels
{
var val = Property.GetValue(_target);
RaiseAndSetIfChanged(ref _value, val, nameof(Value));
RaiseAndSetIfChanged(ref _type, _value?.GetType() ?? Property.PropertyType, nameof(Type));
RaiseAndSetIfChanged(ref _assignedType, _value?.GetType() ?? Property.PropertyType, nameof(AssignedType));
RaisePropertyChanged(nameof(Type));
}
}
}

6
src/Avalonia.Diagnostics/Diagnostics/ViewModels/ControlDetailsViewModel.cs

@ -406,8 +406,8 @@ namespace Avalonia.Diagnostics.ViewModels
var selectedEntityName = SelectedEntityName;
if (selectedEntity == null
|| selectedProperty == null
|| selectedProperty.Type == typeof(string)
|| selectedProperty.Type.IsValueType
|| selectedProperty.PropertyType == typeof(string)
|| selectedProperty.PropertyType.IsValueType
)
return;
@ -421,7 +421,7 @@ namespace Avalonia.Diagnostics.ViewModels
property = selectedEntity.GetType().GetProperties()
.FirstOrDefault(pi => pi.Name == selectedProperty.Name
&& pi.DeclaringType == selectedProperty.DeclaringType
&& pi.PropertyType.Name == selectedProperty.Type.Name)
&& pi.PropertyType.Name == selectedProperty.PropertyType.Name)
?.GetValue(selectedEntity);
}
if (property == null) return;

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

@ -26,6 +26,7 @@ namespace Avalonia.Diagnostics.ViewModels
private bool _freezePopups;
private string? _pointerOverElementName;
private IInputRoot? _pointerOverRoot;
private bool _showPropertyType;
public MainViewModel(AvaloniaObject root)
{
_root = root;
@ -289,5 +290,16 @@ namespace Avalonia.Diagnostics.ViewModels
{
StartupScreenIndex = options.StartupScreenIndex;
}
public bool ShowDettailsPropertyType
{
get => _showPropertyType;
private set => RaiseAndSetIfChanged(ref _showPropertyType , value);
}
public void ToggleShowDettailsPropertyType(object paramter)
{
ShowDettailsPropertyType = !ShowDettailsPropertyType;
}
}
}

13
src/Avalonia.Diagnostics/Diagnostics/ViewModels/PropertyViewModel.cs

@ -14,12 +14,17 @@ namespace Avalonia.Diagnostics.ViewModels
public abstract object Key { get; }
public abstract string Name { get; }
public abstract string Group { get; }
public abstract Type Type { get; }
public abstract Type AssignedType { get; }
public abstract Type? DeclaringType { get; }
public abstract string? Value { get; set; }
public abstract string Priority { get; }
public abstract bool? IsAttached { get; }
public abstract void Update();
public abstract bool? IsAttached { get; }
public abstract void Update();
public abstract Type PropertyType { get; }
public string Type => PropertyType == AssignedType
? PropertyType.GetTypeName()
: $"{PropertyType.GetTypeName()} {{{AssignedType.GetTypeName()}}}";
protected static string? ConvertToString(object? value)
{
@ -31,7 +36,7 @@ namespace Avalonia.Diagnostics.ViewModels
var converter = TypeDescriptor.GetConverter(value);
//CollectionConverter does not deliver any important information. It just displays "(Collection)".
if (!converter.CanConvertTo(typeof(string)) ||
if (!converter.CanConvertTo(typeof(string)) ||
converter.GetType() == typeof(CollectionConverter))
{
return value.ToString() ?? "(null)";

14
src/Avalonia.Diagnostics/Diagnostics/Views/ControlDetailsView.xaml

@ -10,6 +10,7 @@
<UserControl.Resources>
<conv:BoolToOpacityConverter x:Key="BoolToOpacity" Opacity="0.6"/>
<conv:GetTypeNameConverter x:Key="GetTypeName"/>
</UserControl.Resources>
<Grid>
@ -53,7 +54,18 @@
<DataGrid.Columns>
<DataGridTextColumn Header="Property" Binding="{Binding Name}" IsReadOnly="True" />
<DataGridTextColumn Header="Value" Binding="{Binding Value}" />
<DataGridTextColumn Header="Type" Binding="{Binding Type.Name}" />
<DataGridTextColumn Header="Type" Binding="{Binding Type}"
IsReadOnly="True"
IsVisible="{Binding !$parent[UserControl;2].DataContext.ShowDettailsPropertyType}"
/>
<DataGridTextColumn Header="Assinged Type" Binding="{Binding AssignedType, Converter={StaticResource GetTypeName}}"
IsReadOnly="True"
IsVisible="{Binding $parent[UserControl;2].DataContext.ShowDettailsPropertyType}"
/>
<DataGridTextColumn Header="Property Type" Binding="{Binding PropertyType, Converter={StaticResource GetTypeName}}"
IsReadOnly="True"
IsVisible="{Binding $parent[UserControl;2].DataContext.ShowDettailsPropertyType}"
/>
<DataGridTextColumn Header="Priority" Binding="{Binding Priority}" IsReadOnly="True" />
</DataGrid.Columns>

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

@ -15,6 +15,16 @@
IsEnabled="False" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="_Details">
<MenuItem Header="Split Property Type" Command="{Binding ToggleShowDettailsPropertyType}">
<MenuItem.Icon>
<CheckBox BorderThickness="0"
IsChecked="{Binding ShowDettailsPropertyType}"
IsEnabled="False"/>
</MenuItem.Icon>
</MenuItem>
</MenuItem>
</MenuItem>
<MenuItem Header="_Options">
<MenuItem Header="Visualize margin/padding" Command="{Binding ToggleVisualizeMarginPadding}">

Loading…
Cancel
Save