Skip to content

Commit cce7509

Browse files
author
Dan Walmsley
authored
Merge pull request #7812 from AvaloniaUI/feature/onplatform-xaml-compiler-support
Add OnPlatformExtension.
2 parents 9b4a606 + 9883a96 commit cce7509

30 files changed

+1616
-74
lines changed

samples/ControlCatalog.Blazor.Web/Properties/launchSettings.json

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,6 @@
88
}
99
},
1010
"profiles": {
11-
"ControlCatalog.Web - IIS Express": {
12-
"commandName": "IISExpress",
13-
"launchBrowser": true,
14-
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
15-
"environmentVariables": {
16-
"ASPNETCORE_ENVIRONMENT": "Development"
17-
}
18-
},
1911
"ControlCatalog.Web": {
2012
"commandName": "Project",
2113
"dotnetRunMessages": "true",

samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<TargetFramework>net6.0</TargetFramework>
66
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
77
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
8-
<RuntimeFrameworkVersion>6.0.9</RuntimeFrameworkVersion>
8+
<RuntimeFrameworkVersion>6.0.8</RuntimeFrameworkVersion>
99
</PropertyGroup>
1010

1111
<PropertyGroup Condition="'$(RunNativeAotCompilation)' == 'true'">

samples/ControlCatalog/MainView.xaml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
<Setter Property="HorizontalAlignment" Value="Left" />
1313
</Style>
1414
</Grid.Styles>
15-
<controls:HamburgerMenu Name="Sidebar">
16-
<TabItem Header="Composition">
15+
<controls:HamburgerMenu Name="Sidebar">
16+
<TabItem Header="Composition">
1717
<pages:CompositionPage/>
1818
</TabItem>
1919
<TabItem Header="Acrylic">
@@ -118,6 +118,9 @@
118118
<TabItem Header="OpenGL">
119119
<pages:OpenGlPage />
120120
</TabItem>
121+
<TabItem Header="Platform Information">
122+
<pages:PlatformInfoPage />
123+
</TabItem>
121124
<TabItem Header="Pointers">
122125
<pages:PointersPage />
123126
</TabItem>
@@ -130,7 +133,7 @@
130133
<TabItem Header="RelativePanel">
131134
<pages:RelativePanelPage />
132135
</TabItem>
133-
<TabItem Header="ScrollViewer">
136+
<TabItem Header="ScrollViewer">
134137
<pages:ScrollViewerPage />
135138
</TabItem>
136139
<TabItem Header="Slider">
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<UserControl x:Class="ControlCatalog.Pages.PlatformInfoPage"
2+
xmlns="https://github.com/avaloniaui"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
6+
d:DesignHeight="800"
7+
d:DesignWidth="400"
8+
mc:Ignorable="d">
9+
<StackPanel Spacing="20">
10+
<TextBlock Text="{Binding PlatformInfo}" />
11+
12+
<StackPanel TextElement.Foreground="White">
13+
<StackPanel Orientation="Horizontal">
14+
<Border Height="100" Width="100" Background="{OnFormFactor Gray, Desktop=Green}">
15+
<TextBlock Text="Desktop" />
16+
</Border>
17+
<Border Height="100" Width="100" Background="{OnFormFactor Gray, Mobile=Green}">
18+
<TextBlock Text="Mobile" />
19+
</Border>
20+
</StackPanel>
21+
<WrapPanel>
22+
<Border Height="100" Width="100" Background="{OnPlatform Gray, Windows=Green}">
23+
<TextBlock Text="Windows" />
24+
</Border>
25+
<Border Height="100" Width="100" Background="{OnPlatform Gray, macOS=Green}">
26+
<TextBlock Text="macOS" />
27+
</Border>
28+
<Border Height="100" Width="100" Background="{OnPlatform Gray, Linux=Green}">
29+
<TextBlock Text="Linux" />
30+
</Border>
31+
<Border Height="100" Width="100" Background="{OnPlatform Gray, Browser=Green}">
32+
<TextBlock Text="Browser" />
33+
</Border>
34+
<Border Height="100" Width="100" Background="{OnPlatform Gray, iOS=Green}">
35+
<TextBlock Text="iOS" />
36+
</Border>
37+
<Border Height="100" Width="100" Background="{OnPlatform Gray, Android=Green}">
38+
<TextBlock Text="Android" />
39+
</Border>
40+
<Border Height="100" Width="100">
41+
<Border.Background>
42+
<OnPlatform Default="Gray" >
43+
<On Options="macOS, Linux, Windows" Content="Green" />
44+
</OnPlatform>
45+
</Border.Background>
46+
<TextBlock Text="Win, Lin or Mac" />
47+
</Border>
48+
</WrapPanel>
49+
</StackPanel>
50+
</StackPanel>
51+
</UserControl>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using Avalonia.Controls;
2+
using Avalonia.Markup.Xaml;
3+
using ControlCatalog.ViewModels;
4+
5+
namespace ControlCatalog.Pages
6+
{
7+
public class PlatformInfoPage : UserControl
8+
{
9+
public PlatformInfoPage()
10+
{
11+
this.InitializeComponent();
12+
DataContext = new PlatformInformationViewModel();
13+
}
14+
15+
private void InitializeComponent()
16+
{
17+
AvaloniaXamlLoader.Load(this);
18+
}
19+
}
20+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
using Avalonia;
2+
using Avalonia.Platform;
3+
using MiniMvvm;
4+
5+
namespace ControlCatalog.ViewModels;
6+
#nullable enable
7+
8+
public class PlatformInformationViewModel : ViewModelBase
9+
{
10+
public PlatformInformationViewModel()
11+
{
12+
var runtimeInfo = AvaloniaLocator.Current.GetService<IRuntimePlatform>()?.GetRuntimeInfo();
13+
14+
if (runtimeInfo is { } info)
15+
{
16+
if (info.IsBrowser)
17+
{
18+
if (info.IsDesktop)
19+
{
20+
PlatformInfo = "Platform: Desktop (browser)";
21+
}
22+
else if (info.IsMobile)
23+
{
24+
PlatformInfo = "Platform: Mobile (browser)";
25+
}
26+
else
27+
{
28+
PlatformInfo = "Platform: Unknown (browser) - please report";
29+
}
30+
}
31+
else
32+
{
33+
if (info.IsDesktop)
34+
{
35+
PlatformInfo = "Platform: Desktop (native)";
36+
}
37+
else if (info.IsMobile)
38+
{
39+
PlatformInfo = "Platform: Mobile (native)";
40+
}
41+
else
42+
{
43+
PlatformInfo = "Platform: Unknown (native) - please report";
44+
}
45+
}
46+
}
47+
else
48+
{
49+
50+
}
51+
}
52+
53+
public string PlatformInfo { get; }
54+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using System;
2+
3+
namespace Avalonia.Metadata;
4+
5+
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
6+
public sealed class MarkupExtensionOptionAttribute : Attribute
7+
{
8+
public MarkupExtensionOptionAttribute(object value)
9+
{
10+
Value = value;
11+
}
12+
13+
public object Value { get; }
14+
15+
public int Priority { get; set; } = 0;
16+
}
17+
18+
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
19+
public sealed class MarkupExtensionDefaultOptionAttribute : Attribute
20+
{
21+
22+
}

src/Avalonia.Base/Platform/IRuntimePlatform.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,16 @@ public interface IUnmanagedBlob : IDisposable
1717
IntPtr Address { get; }
1818
int Size { get; }
1919
bool IsDisposed { get; }
20-
20+
2121
}
2222

2323
[Unstable]
2424
public struct RuntimePlatformInfo
2525
{
2626
public OperatingSystemType OperatingSystem { get; set; }
27+
28+
public FormFactorType FormFactor => IsDesktop ? FormFactorType.Desktop :
29+
IsMobile ? FormFactorType.Mobile : FormFactorType.Unknown;
2730
public bool IsDesktop { get; set; }
2831
public bool IsMobile { get; set; }
2932
public bool IsBrowser { get; set; }
@@ -44,4 +47,12 @@ public enum OperatingSystemType
4447
iOS,
4548
Browser
4649
}
50+
51+
[Unstable]
52+
public enum FormFactorType
53+
{
54+
Unknown,
55+
Desktop,
56+
Mobile
57+
}
4758
}

src/Markup/Avalonia.Markup.Xaml.Loader/AvaloniaXamlIlRuntimeCompiler.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ static object LoadSreCore(string xaml, Assembly localAssembly, object rootInstan
198198
compiler.ParseAndCompile(xaml, uri?.ToString(), null, _sreTypeSystem.CreateTypeBuilder(tb), overrideType);
199199
var created = tb.CreateTypeInfo();
200200
clrPropertyBuilder.CreateTypeInfo();
201+
indexerClosureType.CreateTypeInfo();
201202
trampolineBuilder.CreateTypeInfo();
202203

203204
return LoadOrPopulate(created, rootInstance);

src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlCompiler.cs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,20 @@ class AvaloniaXamlIlCompiler : XamlILCompiler
2222
private AvaloniaXamlIlCompiler(TransformerConfiguration configuration, XamlLanguageEmitMappings<IXamlILEmitter, XamlILNodeEmitResult> emitMappings)
2323
: base(configuration, emitMappings, true)
2424
{
25-
void InsertAfter<T>(params IXamlAstTransformer[] t)
25+
void InsertAfter<T>(params IXamlAstTransformer[] t)
2626
=> Transformers.InsertRange(Transformers.FindIndex(x => x is T) + 1, t);
2727

28-
void InsertBefore<T>(params IXamlAstTransformer[] t)
28+
void InsertBefore<T>(params IXamlAstTransformer[] t)
2929
=> Transformers.InsertRange(Transformers.FindIndex(x => x is T), t);
3030

3131

3232
// Before everything else
33-
33+
3434
Transformers.Insert(0, new XNameTransformer());
3535
Transformers.Insert(1, new IgnoredDirectivesTransformer());
3636
Transformers.Insert(2, _designTransformer = new AvaloniaXamlIlDesignPropertiesTransformer());
3737
Transformers.Insert(3, _bindingTransformer = new AvaloniaBindingExtensionTransformer());
38-
38+
3939
// Targeted
4040
InsertBefore<PropertyReferenceResolver>(
4141
new AvaloniaXamlIlResolveClassesPropertiesTransformer(),
@@ -49,7 +49,7 @@ void InsertBefore<T>(params IXamlAstTransformer[] t)
4949
InsertBefore<ContentConvertTransformer>(
5050
new AvaloniaXamlIlControlThemeTransformer(),
5151
new AvaloniaXamlIlSelectorTransformer(),
52-
new AvaloniaXamlIlControlTemplateTargetTypeMetadataTransformer(),
52+
new AvaloniaXamlIlControlTemplateTargetTypeMetadataTransformer(),
5353
new AvaloniaXamlIlBindingPathParser(),
5454
new AvaloniaXamlIlPropertyPathTransformer(),
5555
new AvaloniaXamlIlSetterTargetTypeMetadataTransformer(),
@@ -58,6 +58,8 @@ void InsertBefore<T>(params IXamlAstTransformer[] t)
5858
new AvaloniaXamlIlTransitionsTypeMetadataTransformer(),
5959
new AvaloniaXamlIlResolveByNameMarkupExtensionReplacer()
6060
);
61+
InsertBefore<ConvertPropertyValuesToAssignmentsTransformer>(
62+
new AvaloniaXamlIlOptionMarkupExtensionTransformer());
6163

6264
InsertAfter<TypeReferenceResolver>(
6365
new XDataTypeTransformer());
@@ -89,14 +91,14 @@ public AvaloniaXamlIlCompiler(TransformerConfiguration configuration,
8991
_contextType = CreateContextType(contextTypeBuilder);
9092
}
9193

92-
94+
9395
public AvaloniaXamlIlCompiler(TransformerConfiguration configuration,
9496
XamlLanguageEmitMappings<IXamlILEmitter, XamlILNodeEmitResult> emitMappings,
9597
IXamlType contextType) : this(configuration, emitMappings)
9698
{
9799
_contextType = contextType;
98100
}
99-
101+
100102
public const string PopulateName = "__AvaloniaXamlIlPopulate";
101103
public const string BuildName = "__AvaloniaXamlIlBuild";
102104

@@ -118,7 +120,7 @@ public void ParseAndCompile(string xaml, string baseUri, IFileSource fileSource,
118120
{
119121
{XamlNamespaces.Blend2008, XamlNamespaces.Blend2008}
120122
});
121-
123+
122124
var rootObject = (XamlAstObjectNode)parsed.Root;
123125

124126
var classDirective = rootObject.Children
@@ -133,8 +135,8 @@ public void ParseAndCompile(string xaml, string baseUri, IFileSource fileSource,
133135
false) :
134136
TypeReferenceResolver.ResolveType(CreateTransformationContext(parsed, true),
135137
(XamlAstXmlTypeReference)rootObject.Type, true);
136-
137-
138+
139+
138140
if (overrideRootType != null)
139141
{
140142
if (!rootType.Type.IsAssignableFrom(overrideRootType))
@@ -147,7 +149,7 @@ public void ParseAndCompile(string xaml, string baseUri, IFileSource fileSource,
147149

148150
Transform(parsed);
149151
Compile(parsed, tb, _contextType, PopulateName, BuildName, "__AvaloniaXamlIlNsInfo", baseUri, fileSource);
150-
152+
151153
}
152154

153155
public void OverrideRootType(XamlDocument doc, IXamlAstTypeReference newType)

src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguage.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,15 @@ public IXamlCustomAttribute GetCustomAttribute(IXamlProperty property, IXamlType
185185
public static bool CustomValueConverter(AstTransformationContext context,
186186
IXamlAstValueNode node, IXamlType type, out IXamlAstValueNode result)
187187
{
188+
if (node is AvaloniaXamlIlOptionMarkupExtensionTransformer.OptionsMarkupExtensionNode optionsNode)
189+
{
190+
if (optionsNode.ConvertToReturnType(context, type, out var newOptionsNode))
191+
{
192+
result = newOptionsNode;
193+
return true;
194+
}
195+
}
196+
188197
if (!(node is XamlAstTextNode textNode))
189198
{
190199
result = null;

0 commit comments

Comments
 (0)