Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add OnPlatformExtension. #7812

Merged
merged 44 commits into from
Nov 11, 2022
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
6d3ce0a
Add service for runtime platform information.
danwalmsley Mar 15, 2022
3d53bd6
Merge branch 'master' into feature/onplatform-xaml-compiler-support
maxkatz6 Jun 1, 2022
9479baa
Add object-based OnPlatformExtension impl
maxkatz6 Jun 1, 2022
30447ac
Add tests for OnPlatform extensions
maxkatz6 Jun 1, 2022
f39fa92
Merge branch 'master' into feature/onplatform-xaml-compiler-support
maxkatz6 Oct 15, 2022
0dfc280
WIP
maxkatz6 Oct 18, 2022
12608c5
redirect submodule
maxkatz6 Oct 18, 2022
8f9c08d
Merge remote-tracking branch 'origin/master' into feature/onplatform-…
danwalmsley Oct 18, 2022
a8ac68b
skip failing test for now.
danwalmsley Oct 18, 2022
be4a669
implement BrowserRuntimePlatform that can distinguish between desktop…
danwalmsley Oct 19, 2022
aa09803
add a platform info page to control catalog that tells user where ava…
danwalmsley Oct 19, 2022
288cfed
Merge remote-tracking branch 'origin/master' into feature/onplatform-…
danwalmsley Oct 19, 2022
81dca34
tmp
danwalmsley Oct 19, 2022
59e12e4
add OnFormFactor extension.
danwalmsley Oct 19, 2022
0966f63
fix onplatform extension bug.
danwalmsley Oct 19, 2022
4d48f9e
Merge branch 'master' into feature/onplatform-xaml-compiler-support
Oct 20, 2022
9e41a88
Reimplement OnPlatform to inject IL code instead of markup extension
maxkatz6 Oct 21, 2022
725105f
Merge branch 'master' into feature/onplatform-xaml-compiler-support
Oct 22, 2022
06a6875
Move IsOnPlatform method to the xaml helpers class
maxkatz6 Oct 23, 2022
caf2b30
Update xamlx
maxkatz6 Oct 23, 2022
8172173
Extract code into a AvaloniaXamlIlConditionalNode
maxkatz6 Oct 23, 2022
3d4b0ae
Reenable form factor markup extension with some tests
maxkatz6 Oct 23, 2022
b50e187
Merge branch 'master' into feature/onplatform-xaml-compiler-support
Oct 23, 2022
9b4fc3d
Fix tests
maxkatz6 Oct 23, 2022
8daf6d0
Switch back to original XamlX repo
maxkatz6 Oct 24, 2022
be0b414
Merge branch 'master' into feature/onplatform-xaml-compiler-support
Oct 24, 2022
94049a1
Merge branch 'master' into feature/onplatform-xaml-compiler-support
Oct 26, 2022
1e3556b
update xamlx
danwalmsley Oct 27, 2022
5a64c84
Merge branch 'master' into feature/onplatform-xaml-compiler-support
Oct 27, 2022
9c60fe8
Merge branch 'master' into feature/onplatform-xaml-compiler-support
maxkatz6 Oct 29, 2022
12921c1
Refactor extension to use a custom xaml method
maxkatz6 Nov 10, 2022
5484bf4
Merge remote-tracking branch 'origin/master' into feature/onplatform-…
maxkatz6 Nov 10, 2022
523c87d
Browser: use JS side mobile checks
maxkatz6 Nov 10, 2022
a2b939a
Merge remote-tracking branch 'origin/master' into feature/onplatform-…
maxkatz6 Nov 10, 2022
bfc349e
Update XamlX and remove unused methods
maxkatz6 Nov 10, 2022
f8ace85
Merge remote-tracking branch 'origin/master' into feature/onplatform-…
danwalmsley Nov 10, 2022
3593803
browser runtime platform is much simpler.
danwalmsley Nov 10, 2022
60ef705
move constant.
danwalmsley Nov 10, 2022
9be00c0
Merge branch 'master' into feature/onplatform-xaml-compiler-support
Nov 10, 2022
8a6bb0f
Move OnExtensionType and fix netstandard error
maxkatz6 Nov 10, 2022
f489a33
Fix onplatform generics crash on macOS
maxkatz6 Nov 10, 2022
769a51b
Merge branch 'master' into feature/onplatform-xaml-compiler-support
Nov 10, 2022
6bd6e9f
Reuse PlatformFact on some onplatform tests
maxkatz6 Nov 10, 2022
9883a96
Merge branch 'feature/onplatform-xaml-compiler-support' of https://gi…
maxkatz6 Nov 10, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,6 @@
}
},
"profiles": {
"ControlCatalog.Web - IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"ControlCatalog.Web": {
"commandName": "Project",
"dotnetRunMessages": "true",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<TargetFramework>net6.0</TargetFramework>
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<RuntimeFrameworkVersion>6.0.9</RuntimeFrameworkVersion>
<RuntimeFrameworkVersion>6.0.8</RuntimeFrameworkVersion>
</PropertyGroup>

<PropertyGroup Condition="'$(RunNativeAotCompilation)' == 'true'">
Expand Down
11 changes: 7 additions & 4 deletions samples/ControlCatalog/MainView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@
<Setter Property="HorizontalAlignment" Value="Left" />
</Style>
</Grid.Styles>
<controls:HamburgerMenu Name="Sidebar">
<TabItem Header="Composition">
<controls:HamburgerMenu Name="Sidebar">
<TabItem Header="Platform Information">
<pages:PlatformInfoPage />
</TabItem>
<TabItem Header="Composition">
<pages:CompositionPage/>
</TabItem>
<TabItem Header="Acrylic">
Expand Down Expand Up @@ -118,7 +121,7 @@
<TabItem Header="OpenGL">
<pages:OpenGlPage />
</TabItem>
<TabItem Header="Pointers">
<TabItem Header="Pointers">
<pages:PointersPage />
</TabItem>
<TabItem Header="ProgressBar">
Expand All @@ -130,7 +133,7 @@
<TabItem Header="RelativePanel">
<pages:RelativePanelPage />
</TabItem>
<TabItem Header="ScrollViewer">
<TabItem Header="ScrollViewer">
<pages:ScrollViewerPage />
</TabItem>
<TabItem Header="Slider">
Expand Down
43 changes: 43 additions & 0 deletions samples/ControlCatalog/Pages/PlatformInfoPage.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<UserControl x:Class="ControlCatalog.Pages.PlatformInfoPage"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DesignHeight="800"
d:DesignWidth="400"
mc:Ignorable="d">
<StackPanel Spacing="20">
<TextBlock Text="{Binding PlatformInfo}" />

<StackPanel TextElement.Foreground="White">
<StackPanel Orientation="Horizontal">
<Border Height="100" Width="100" Background="{OnFormFactor Gray, Desktop=Green}">
<TextBlock Text="Desktop" />
</Border>
<Border Height="100" Width="100" Background="{OnFormFactor Gray, Mobile=Green}">
<TextBlock Text="Mobile" />
</Border>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Border Height="100" Width="100" Background="{OnPlatform Gray, Windows=Green}">
<TextBlock Text="Windows" />
</Border>
<Border Height="100" Width="100" Background="{OnPlatform Gray, macOS=Green}">
<TextBlock Text="macOS" />
</Border>
<Border Height="100" Width="100" Background="{OnPlatform Gray, Linux=Green}">
<TextBlock Text="Linux" />
</Border>
<Border Height="100" Width="100" Background="{OnPlatform Gray, Browser=Green}">
<TextBlock Text="Browser" />
</Border>
<Border Height="100" Width="100" Background="{OnPlatform Gray, iOS=Green}">
<TextBlock Text="iOS" />
</Border>
<Border Height="100" Width="100" Background="{OnPlatform Gray, Android=Green}">
<TextBlock Text="Android" />
</Border>
</StackPanel>
</StackPanel>
</StackPanel>
</UserControl>
20 changes: 20 additions & 0 deletions samples/ControlCatalog/Pages/PlatformInfoPage.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using ControlCatalog.ViewModels;

namespace ControlCatalog.Pages
{
public class PlatformInfoPage : UserControl
{
public PlatformInfoPage()
{
this.InitializeComponent();
DataContext = new PlatformInformationViewModel();
}

private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
}
}
54 changes: 54 additions & 0 deletions samples/ControlCatalog/ViewModels/PlatformInformationViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using Avalonia;
using Avalonia.Platform;
using MiniMvvm;

namespace ControlCatalog.ViewModels;
#nullable enable

public class PlatformInformationViewModel : ViewModelBase
{
public PlatformInformationViewModel()
{
var runtimeInfo = AvaloniaLocator.Current.GetService<IRuntimePlatform>()?.GetRuntimeInfo();

if (runtimeInfo is { } info)
{
if (info.IsBrowser)
{
if (info.IsDesktop)
{
PlatformInfo = "Platform: Desktop (browser)";
}
else if (info.IsMobile)
{
PlatformInfo = "Platform: Mobile (browser)";
}
else
{
PlatformInfo = "Platform: Unknown (browser) - please report";
}
}
else
{
if (info.IsDesktop)
{
PlatformInfo = "Platform: Desktop (native)";
}
else if (info.IsMobile)
{
PlatformInfo = "Platform: Mobile (native)";
}
else
{
PlatformInfo = "Platform: Unknown (native) - please report";
}
}
}
else
{

}
}

public string PlatformInfo { get; }
}
13 changes: 12 additions & 1 deletion src/Avalonia.Base/Platform/IRuntimePlatform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,16 @@ public interface IUnmanagedBlob : IDisposable
IntPtr Address { get; }
int Size { get; }
bool IsDisposed { get; }

}

[Unstable]
public struct RuntimePlatformInfo
{
public OperatingSystemType OperatingSystem { get; set; }

public FormFactorType FormFactor => IsDesktop ? FormFactorType.Desktop :
IsMobile ? FormFactorType.Mobile : FormFactorType.Unknown;
public bool IsDesktop { get; set; }
public bool IsMobile { get; set; }
public bool IsBrowser { get; set; }
Expand All @@ -44,4 +47,12 @@ public enum OperatingSystemType
iOS,
Browser
}

[Unstable]
public enum FormFactorType
{
Unknown,
Desktop,
Mobile
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
using System.Collections.Generic;
using System.Reflection.Emit;
using XamlX.Ast;
using XamlX.Emit;
using XamlX.IL;

namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers;

internal sealed class AvaloniaXamlIlConditionalNode : XamlAstNode,
maxkatz6 marked this conversation as resolved.
Show resolved Hide resolved
IXamlAstEmitableNode<IXamlILEmitter, XamlILNodeEmitResult>, IXamlAstManipulationNode
{
private readonly AvaloniaXamlIlConditionalDefaultNode? _defaultValue;
private readonly IReadOnlyList<AvaloniaXamlIlConditionalBranchNode> _branches;

public AvaloniaXamlIlConditionalNode(
AvaloniaXamlIlConditionalDefaultNode defaultValue,
IReadOnlyList<AvaloniaXamlIlConditionalBranchNode> values,
IXamlLineInfo info) : base(info)
{
_defaultValue = defaultValue;
_branches = values;
}

public override void VisitChildren(IXamlAstVisitor visitor)
{
_defaultValue?.VisitChildren(visitor);
foreach (var branch in _branches)
{
branch.VisitChildren(visitor);
}
}

public XamlILNodeEmitResult Emit(XamlEmitContext<IXamlILEmitter, XamlILNodeEmitResult> context,
IXamlILEmitter codeGen)
{
var ret = codeGen.DefineLabel();

foreach (var platform in _branches)
{
var next = codeGen.DefineLabel();
platform.EmitCondition(context, codeGen);
codeGen.Brfalse(next);
platform.EmitBody(context, codeGen);
codeGen.Br(ret);
codeGen.MarkLabel(next);
}

if (_defaultValue is not null)
{
codeGen.Emit(OpCodes.Nop);
_defaultValue.EmitBody(context, codeGen);
}
else
{
codeGen.Pop();
}

codeGen.MarkLabel(ret);

return XamlILNodeEmitResult.Void(1);
}
}

internal abstract class AvaloniaXamlIlConditionalBranchNode : XamlAstNode, IXamlAstManipulationNode
{
protected AvaloniaXamlIlConditionalBranchNode(IXamlLineInfo lineInfo) : base(lineInfo)
{
}

public abstract void EmitCondition(XamlEmitContext<IXamlILEmitter, XamlILNodeEmitResult> context, IXamlILEmitter codeGen);

public abstract void EmitBody(XamlEmitContext<IXamlILEmitter, XamlILNodeEmitResult> context, IXamlILEmitter codeGen);
}

internal abstract class AvaloniaXamlIlConditionalDefaultNode : XamlAstNode, IXamlAstManipulationNode
{
protected AvaloniaXamlIlConditionalDefaultNode(IXamlLineInfo lineInfo) : base(lineInfo)
{
}

public abstract void EmitBody(XamlEmitContext<IXamlILEmitter, XamlILNodeEmitResult> context, IXamlILEmitter codeGen);
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,20 @@ class AvaloniaXamlIlCompiler : XamlILCompiler
private AvaloniaXamlIlCompiler(TransformerConfiguration configuration, XamlLanguageEmitMappings<IXamlILEmitter, XamlILNodeEmitResult> emitMappings)
: base(configuration, emitMappings, true)
{
void InsertAfter<T>(params IXamlAstTransformer[] t)
void InsertAfter<T>(params IXamlAstTransformer[] t)
=> Transformers.InsertRange(Transformers.FindIndex(x => x is T) + 1, t);

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


// Before everything else

Transformers.Insert(0, new XNameTransformer());
Transformers.Insert(1, new IgnoredDirectivesTransformer());
Transformers.Insert(2, _designTransformer = new AvaloniaXamlIlDesignPropertiesTransformer());
Transformers.Insert(3, _bindingTransformer = new AvaloniaBindingExtensionTransformer());

// Targeted
InsertBefore<PropertyReferenceResolver>(
new AvaloniaXamlIlResolveClassesPropertiesTransformer(),
Expand All @@ -49,7 +49,7 @@ void InsertBefore<T>(params IXamlAstTransformer[] t)
InsertBefore<ContentConvertTransformer>(
new AvaloniaXamlIlControlThemeTransformer(),
new AvaloniaXamlIlSelectorTransformer(),
new AvaloniaXamlIlControlTemplateTargetTypeMetadataTransformer(),
new AvaloniaXamlIlControlTemplateTargetTypeMetadataTransformer(),
new AvaloniaXamlIlBindingPathParser(),
new AvaloniaXamlIlPropertyPathTransformer(),
new AvaloniaXamlIlSetterTargetTypeMetadataTransformer(),
Expand All @@ -58,6 +58,9 @@ void InsertBefore<T>(params IXamlAstTransformer[] t)
new AvaloniaXamlIlTransitionsTypeMetadataTransformer(),
new AvaloniaXamlIlResolveByNameMarkupExtensionReplacer()
);
InsertAfter<ResolveContentPropertyTransformer>(
new AvaloniaXamlIlOnPlatformTransformer(),
new AvaloniaXamlIlOnFormFactorTransformer());

InsertAfter<TypeReferenceResolver>(
new XDataTypeTransformer());
Expand Down Expand Up @@ -89,14 +92,14 @@ public AvaloniaXamlIlCompiler(TransformerConfiguration configuration,
_contextType = CreateContextType(contextTypeBuilder);
}


public AvaloniaXamlIlCompiler(TransformerConfiguration configuration,
XamlLanguageEmitMappings<IXamlILEmitter, XamlILNodeEmitResult> emitMappings,
IXamlType contextType) : this(configuration, emitMappings)
{
_contextType = contextType;
}

public const string PopulateName = "__AvaloniaXamlIlPopulate";
public const string BuildName = "__AvaloniaXamlIlBuild";

Expand All @@ -118,7 +121,7 @@ public void ParseAndCompile(string xaml, string baseUri, IFileSource fileSource,
{
{XamlNamespaces.Blend2008, XamlNamespaces.Blend2008}
});

var rootObject = (XamlAstObjectNode)parsed.Root;

var classDirective = rootObject.Children
Expand All @@ -133,8 +136,8 @@ public void ParseAndCompile(string xaml, string baseUri, IFileSource fileSource,
false) :
TypeReferenceResolver.ResolveType(CreateTransformationContext(parsed, true),
(XamlAstXmlTypeReference)rootObject.Type, true);


if (overrideRootType != null)
{
if (!rootType.Type.IsAssignableFrom(overrideRootType))
Expand All @@ -147,7 +150,7 @@ public void ParseAndCompile(string xaml, string baseUri, IFileSource fileSource,

Transform(parsed);
Compile(parsed, tb, _contextType, PopulateName, BuildName, "__AvaloniaXamlIlNsInfo", baseUri, fileSource);

}

public void OverrideRootType(XamlDocument doc, IXamlAstTypeReference newType)
Expand Down
Loading