Browse Source

initial work for xamlx compiler support for relative panel.

pull/3987/head
Dan Walmsley 6 years ago
parent
commit
2f35630eba
  1. 48
      src/Avalonia.Controls/RelativePanel.AttachedProperties.cs
  2. 9
      src/Avalonia.Controls/ResolveByNameAttribute.cs
  3. 1
      src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj
  4. 35
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/ResolveByNameExtension.cs
  5. 30
      src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlResolveByNameMarkupExtensionReplacer.cs

48
src/Avalonia.Controls/RelativePanel.AttachedProperties.cs

@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using Avalonia.Layout;
using Avalonia.Markup.Xaml.Converters;
namespace Avalonia.Controls
{
@ -20,7 +19,7 @@ namespace Avalonia.Controls
{
AboveProperty.Changed.AddClassHandler<Layoutable>(OnAlignPropertiesChanged);
AlignBottomWithPanelProperty.Changed.AddClassHandler<Layoutable>(OnAlignPropertiesChanged);
AlignBottomWithProperty.Changed.AddClassHandler<Layoutable>(OnAlignPropertiesChanged);
AlignBottomWithProperty.Changed.AddClassHandler<Layoutable>(OnAlignPropertiesChanged);
AlignHorizontalCenterWithPanelProperty.Changed.AddClassHandler<Layoutable>(OnAlignPropertiesChanged);
AlignHorizontalCenterWithProperty.Changed.AddClassHandler<Layoutable>(OnAlignPropertiesChanged);
AlignLeftWithPanelProperty.Changed.AddClassHandler<Layoutable>(OnAlignPropertiesChanged);
@ -43,8 +42,7 @@ namespace Avalonia.Controls
/// <returns>
/// The RelativePanel.Above XAML attached property value of the specified object.
/// (The element to position this element above.)
/// </returns>
[TypeConverter(typeof(NameReferenceConverter))]
/// </returns>
public static object GetAbove(AvaloniaObject obj)
{
return (object)obj.GetValue(AboveProperty);
@ -60,9 +58,11 @@ namespace Avalonia.Controls
obj.SetValue(AboveProperty, value);
}
/// <summary>
/// Identifies the <see cref="RelativePanel.AboveProperty"/> XAML attached property.
/// </summary>
/// </summary>
[ResolveByName]
public static readonly AttachedProperty<object> AboveProperty =
AvaloniaProperty.RegisterAttached<Layoutable, object>("Above", typeof(RelativePanel));
@ -107,8 +107,7 @@ namespace Avalonia.Controls
/// <returns>
/// The RelativePanel.AlignBottomWith XAML attached property value of the specified object.
/// (The element to align this element's bottom edge with.)
/// </returns>
[TypeConverter(typeof(NameReferenceConverter))]
/// </returns>
public static object GetAlignBottomWith(AvaloniaObject obj)
{
return (object)obj.GetValue(AlignBottomWithProperty);
@ -127,6 +126,7 @@ namespace Avalonia.Controls
/// <summary>
/// Identifies the <see cref="RelativePanel.AlignBottomWithProperty"/> XAML attached property.
/// </summary>
[ResolveByName]
public static readonly AttachedProperty<object> AlignBottomWithProperty =
AvaloniaProperty.RegisterAttached<Layoutable, object>("AlignBottomWith", typeof(RelativePanel));
@ -170,8 +170,7 @@ namespace Avalonia.Controls
/// <returns>
/// The RelativePanel.AlignHorizontalCenterWith XAML attached property value of the
/// specified object. (The element to align this element's horizontal center with.)
/// </returns>
[TypeConverter(typeof(NameReferenceConverter))]
/// </returns>
public static object GetAlignHorizontalCenterWith(AvaloniaObject obj)
{
return (object)obj.GetValue(AlignHorizontalCenterWithProperty);
@ -190,6 +189,7 @@ namespace Avalonia.Controls
/// <summary>
/// Identifies the <see cref="RelativePanel.AlignHorizontalCenterWithProperty"/> XAML attached property.
/// </summary>
[ResolveByName]
public static readonly AttachedProperty<object> AlignHorizontalCenterWithProperty =
AvaloniaProperty.RegisterAttached<Layoutable, object>("AlignHorizontalCenterWith", typeof(object), typeof(RelativePanel));
@ -234,8 +234,7 @@ namespace Avalonia.Controls
/// <returns>
/// The RelativePanel.AlignLeftWith XAML attached property value of the specified
/// object. (The element to align this element's left edge with.)
/// </returns>
[TypeConverter(typeof(NameReferenceConverter))]
/// </returns>
public static object GetAlignLeftWith(AvaloniaObject obj)
{
return (object)obj.GetValue(AlignLeftWithProperty);
@ -254,6 +253,7 @@ namespace Avalonia.Controls
/// <summary>
/// Identifies the <see cref="RelativePanel.AlignLeftWithProperty"/> XAML attached property.
/// </summary>
[ResolveByName]
public static readonly AttachedProperty<object> AlignLeftWithProperty =
AvaloniaProperty.RegisterAttached<RelativePanel, Layoutable, object>("AlignLeftWith");
@ -298,8 +298,7 @@ namespace Avalonia.Controls
/// <returns>
/// The RelativePanel.AlignRightWith XAML attached property value of the specified
/// object. (The element to align this element's right edge with.)
/// </returns>
[TypeConverter(typeof(NameReferenceConverter))]
/// </returns>
public static object GetAlignRightWith(AvaloniaObject obj)
{
return (object)obj.GetValue(AlignRightWithProperty);
@ -318,6 +317,7 @@ namespace Avalonia.Controls
/// <summary>
/// Identifies the <see cref="RelativePanel.AlignRightWithProperty"/> XAML attached property.
/// </summary>
[ResolveByName]
public static readonly AttachedProperty<object> AlignRightWithProperty =
AvaloniaProperty.RegisterAttached<RelativePanel, Layoutable, object>("AlignRightWith");
@ -358,8 +358,7 @@ namespace Avalonia.Controls
/// Gets the value of the RelativePanel.AlignTopWith XAML attached property for the target element.
/// </summary>
/// <param name="obj">The object from which the property value is read.</param>
/// <returns>The value to set. (The element to align this element's top edge with.)</returns>
[TypeConverter(typeof(NameReferenceConverter))]
/// <returns>The value to set. (The element to align this element's top edge with.)</returns>
public static object GetAlignTopWith(AvaloniaObject obj)
{
return (object)obj.GetValue(AlignTopWithProperty);
@ -378,6 +377,7 @@ namespace Avalonia.Controls
/// <summary>
/// Identifies the <see cref="RelativePanel.AlignTopWithProperty"/> XAML attached property.
/// </summary>
[ResolveByName]
public static readonly AttachedProperty<object> AlignTopWithProperty =
AvaloniaProperty.RegisterAttached<RelativePanel, Layoutable, object>("AlignTopWith");
@ -418,8 +418,7 @@ namespace Avalonia.Controls
/// Gets the value of the RelativePanel.AlignVerticalCenterWith XAML attached property for the target element.
/// </summary>
/// <param name="obj">The object from which the property value is read.</param>
/// <returns>The value to set. (The element to align this element's vertical center with.)</returns>
[TypeConverter(typeof(NameReferenceConverter))]
/// <returns>The value to set. (The element to align this element's vertical center with.)</returns>
public static object GetAlignVerticalCenterWith(AvaloniaObject obj)
{
return (object)obj.GetValue(AlignVerticalCenterWithProperty);
@ -429,7 +428,8 @@ namespace Avalonia.Controls
/// Sets the value of the RelativePanel.AlignVerticalCenterWith XAML attached property for a target element.
/// </summary>
/// <param name="obj">The object to which the property value is written.</param>
/// <param name="value">The value to set. (The element to align this element's horizontal center with.)</param>
/// <param name="value">The value to set. (The element to align this element's horizontal center with.)</param>
[ResolveByName]
public static void SetAlignVerticalCenterWith(AvaloniaObject obj, object value)
{
obj.SetValue(AlignVerticalCenterWithProperty, value);
@ -448,8 +448,7 @@ namespace Avalonia.Controls
/// <returns>
/// The RelativePanel.Below XAML attached property value of the specified object.
/// (The element to position this element below.)
/// </returns>
[TypeConverter(typeof(NameReferenceConverter))]
/// </returns>
public static object GetBelow(AvaloniaObject obj)
{
return (object)obj.GetValue(BelowProperty);
@ -468,6 +467,7 @@ namespace Avalonia.Controls
/// <summary>
/// Identifies the <see cref="RelativePanel.BelowProperty"/> XAML attached property.
/// </summary>
[ResolveByName]
public static readonly AttachedProperty<object> BelowProperty =
AvaloniaProperty.RegisterAttached<RelativePanel, Layoutable, object>("Below");
@ -478,8 +478,7 @@ namespace Avalonia.Controls
/// <returns>
/// The RelativePanel.LeftOf XAML attached property value of the specified object.
/// (The element to position this element to the left of.)
/// </returns>
[TypeConverter(typeof(NameReferenceConverter))]
/// </returns>
public static object GetLeftOf(AvaloniaObject obj)
{
return (object)obj.GetValue(LeftOfProperty);
@ -498,6 +497,7 @@ namespace Avalonia.Controls
/// <summary>
/// Identifies the <see cref="RelativePanel.LeftOfProperty"/> XAML attached property.
/// </summary>
[ResolveByName]
public static readonly AttachedProperty<object> LeftOfProperty =
AvaloniaProperty.RegisterAttached<RelativePanel, Layoutable, object>("LeftOf");
@ -508,8 +508,7 @@ namespace Avalonia.Controls
/// <returns>
/// The RelativePanel.RightOf XAML attached property value of the specified object.
/// (The element to position this element to the right of.)
/// </returns>
[TypeConverter(typeof(NameReferenceConverter))]
/// </returns>
public static object GetRightOf(AvaloniaObject obj)
{
return (object)obj.GetValue(RightOfProperty);
@ -528,6 +527,7 @@ namespace Avalonia.Controls
/// <summary>
/// Identifies the <see cref="RelativePanel.RightOfProperty"/> XAML attached property.
/// </summary>
[ResolveByName]
public static readonly AttachedProperty<object> RightOfProperty =
AvaloniaProperty.RegisterAttached<RelativePanel, Layoutable, object>("RightOf");
}

9
src/Avalonia.Controls/ResolveByNameAttribute.cs

@ -0,0 +1,9 @@
using System;
namespace Avalonia.Controls
{
public class ResolveByNameAttribute : Attribute
{
}
}

1
src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj

@ -26,6 +26,7 @@
<Compile Include="MarkupExtensions\CompiledBindings\PropertyInfoAccessorPlugin.cs" />
<Compile Include="MarkupExtensions\CompiledBindings\TaskStreamPlugin.cs" />
<Compile Include="MarkupExtensions\DynamicResourceExtension.cs" />
<Compile Include="MarkupExtensions\ResolveByNameExtension.cs" />
<Compile Include="MarkupExtensions\ResourceInclude.cs" />
<Compile Include="MarkupExtensions\StaticResourceExtension.cs" />
<Compile Include="MarkupExtensions\StyleIncludeExtension.cs" />

35
src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/ResolveByNameExtension.cs

@ -0,0 +1,35 @@
using System;
using Avalonia.Controls;
namespace Avalonia.Markup.Xaml.MarkupExtensions
{
public class ResolveByNameExtension
{
public string Name { get; set; }
public object ProvideValue(IServiceProvider serviceProvider)
{
var namescope = serviceProvider.GetService<INameScope>();
var provideValueTarget = serviceProvider.GetService<IProvideValueTarget>();
var value = namescope.FindAsync(Name);
if(value.IsCompleted)
{
return value.GetResult();
}
else
{
value.OnCompleted(() =>
{
if(provideValueTarget is AvaloniaObject ao)
{
ao.SetValue(provideValueTarget.TargetProperty as AvaloniaProperty, value);
}
});
return null;
}
}
}
}

30
src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlResolveByNameMarkupExtensionReplacer.cs

@ -0,0 +1,30 @@
using System.Linq;
using XamlX.Ast;
using XamlX.Transform;
namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
{
class AvaloniaXamlIlResolveByNameMarkupExtensionReplacer : IXamlAstTransformer
{
public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node)
{
if (node is XamlAstXamlPropertyValueNode propertyValueNode)
{
foreach(var attribute in propertyValueNode.Property.GetClrProperty().CustomAttributes)
{
if (attribute.Type.FullName == "Avalonia.Controls.ResolveByNameAttribute")
{
if (propertyValueNode.Values.Count == 1 &&
propertyValueNode.Values.First() is XamlAstTextNode)
{
//propertyValueNode.Values[0] = new XamlMarkupExtensionNode();
}
break;
}
}
}
return node;
}
}
}
Loading…
Cancel
Save