diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/AndroidManifest.xml b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/AndroidManifest.xml new file mode 100644 index 000000000..3fead98ca --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/AndroidManifest.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/MainActivity.cs b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/MainActivity.cs new file mode 100644 index 000000000..47364e334 --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/MainActivity.cs @@ -0,0 +1,65 @@ +using static Android.Views.ViewGroup.LayoutParams; + +namespace NativeEmbeddingDemo.Droid +{ + [Activity(Label = "@string/app_name", MainLauncher = true, Theme = "@style/AppTheme")] + public class MainActivity : Activity + { + public static readonly Lazy MauiApp = new(() => + { + var mauiApp = MauiProgram.CreateMauiApp(builder => + { + builder.UseMauiEmbedding(); + }); + return mauiApp; + }); + + public static bool UseWindowContext = true; + + MyMauiContent? mauiView; + + protected override void OnCreate(Bundle? savedInstanceState) + { + base.OnCreate(savedInstanceState); + + // Set the view from the "main" layout resource + SetContentView(Resource.Layout.activity_main); + + var rootLayout = FindViewById(Resource.Id.rootLayout)!; + + // Create Android button + var androidButton = new Android.Widget.Button(this); + androidButton.Text = "Android button above .NET MAUI controls"; + androidButton.Click += OnAndroidButtonClicked; + rootLayout.AddView(androidButton, new LinearLayout.LayoutParams(MatchParent, WrapContent)); + + // Ensure .NET MAUI app is built before creating .NET MAUI views + var mauiApp = MainActivity.MauiApp.Value; + + // Create .NET MAUI context + var mauiContext = UseWindowContext + ? mauiApp.CreateEmbeddedWindowContext(this) // Create window context + : new MauiContext(mauiApp.Services, this); // Create app context + + // Create .NET MAUI content + mauiView = new MyMauiContent(); + + // Create native view + var nativeView = mauiView.ToPlatformEmbedded(mauiContext); + + // Add native view to layout + rootLayout.AddView(nativeView, new LinearLayout.LayoutParams(MatchParent, WrapContent)); + } + + async void OnAndroidButtonClicked(object? sender, EventArgs e) + { + if (mauiView?.DotNetBot is not Image bot) + return; + + await bot.RotateTo(360, 1000); + bot.Rotation = 0; + + bot.HeightRequest = 90; + } + } +} \ No newline at end of file diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/NativeEmbeddingDemo.Droid.csproj b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/NativeEmbeddingDemo.Droid.csproj new file mode 100644 index 000000000..d39fc34e9 --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/NativeEmbeddingDemo.Droid.csproj @@ -0,0 +1,29 @@ + + + net8.0-android + 21 + Exe + enable + enable + + true + true + + com.companyname.nativeembeddingdemo + 1 + 1.0 + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/AboutResources.txt b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/AboutResources.txt new file mode 100644 index 000000000..219f42544 --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/AboutResources.txt @@ -0,0 +1,44 @@ +Images, layout descriptions, binary blobs and string dictionaries can be included +in your application as resource files. Various Android APIs are designed to +operate on the resource IDs instead of dealing with images, strings or binary blobs +directly. + +For example, a sample Android app that contains a user interface layout (main.xml), +an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png) +would keep its resources in the "Resources" directory of the application: + +Resources/ + drawable/ + icon.png + + layout/ + main.xml + + values/ + strings.xml + +In order to get the build system to recognize Android resources, set the build action to +"AndroidResource". The native Android APIs do not operate directly with filenames, but +instead operate on resource IDs. When you compile an Android application that uses resources, +the build system will package the resources for distribution and generate a class called "Resource" +(this is an Android convention) that contains the tokens for each one of the resources +included. For example, for the above Resources layout, this is what the Resource class would expose: + +public class Resource { + public class Drawable { + public const int icon = 0x123; + } + + public class Layout { + public const int main = 0x456; + } + + public class Strings { + public const int first_string = 0xabc; + public const int second_string = 0xbcd; + } +} + +You would then use Resource.Drawable.icon to reference the drawable/icon.png file, or +Resource.Layout.main to reference the layout/main.xml file, or Resource.Strings.first_string +to reference the first string in the dictionary file values/strings.xml. \ No newline at end of file diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/layout/activity_main.xml b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/layout/activity_main.xml new file mode 100644 index 000000000..66fe256eb --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/layout/activity_main.xml @@ -0,0 +1,10 @@ + + + \ No newline at end of file diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-anydpi-v26/appicon.xml b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-anydpi-v26/appicon.xml new file mode 100644 index 000000000..7751f6951 --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-anydpi-v26/appicon.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-anydpi-v26/appicon_round.xml b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-anydpi-v26/appicon_round.xml new file mode 100644 index 000000000..7751f6951 --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-anydpi-v26/appicon_round.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-hdpi/appicon.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-hdpi/appicon.png new file mode 100644 index 000000000..0abfc1b58 Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-hdpi/appicon.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-hdpi/appicon_background.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-hdpi/appicon_background.png new file mode 100644 index 000000000..513e69d84 Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-hdpi/appicon_background.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-hdpi/appicon_foreground.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-hdpi/appicon_foreground.png new file mode 100644 index 000000000..99d3a291b Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-hdpi/appicon_foreground.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-mdpi/appicon.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-mdpi/appicon.png new file mode 100644 index 000000000..7b5a2e2bf Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-mdpi/appicon.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-mdpi/appicon_background.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-mdpi/appicon_background.png new file mode 100644 index 000000000..9e2d1e4d8 Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-mdpi/appicon_background.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-mdpi/appicon_foreground.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-mdpi/appicon_foreground.png new file mode 100644 index 000000000..a28d342c1 Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-mdpi/appicon_foreground.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-xhdpi/appicon.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-xhdpi/appicon.png new file mode 100644 index 000000000..b28b73c65 Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-xhdpi/appicon.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-xhdpi/appicon_background.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-xhdpi/appicon_background.png new file mode 100644 index 000000000..658be3fb6 Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-xhdpi/appicon_background.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-xhdpi/appicon_foreground.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-xhdpi/appicon_foreground.png new file mode 100644 index 000000000..70a542ac0 Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-xhdpi/appicon_foreground.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-xxhdpi/appicon.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-xxhdpi/appicon.png new file mode 100644 index 000000000..f9af1173e Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-xxhdpi/appicon.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-xxhdpi/appicon_background.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-xxhdpi/appicon_background.png new file mode 100644 index 000000000..9171c3e40 Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-xxhdpi/appicon_background.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-xxhdpi/appicon_foreground.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-xxhdpi/appicon_foreground.png new file mode 100644 index 000000000..cb63bfb9f Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-xxhdpi/appicon_foreground.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-xxxhdpi/appicon.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-xxxhdpi/appicon.png new file mode 100644 index 000000000..1d948d6b5 Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-xxxhdpi/appicon.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-xxxhdpi/appicon_background.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-xxxhdpi/appicon_background.png new file mode 100644 index 000000000..1232d8c8d Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-xxxhdpi/appicon_background.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-xxxhdpi/appicon_foreground.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-xxxhdpi/appicon_foreground.png new file mode 100644 index 000000000..9f9c9e6d9 Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/mipmap-xxxhdpi/appicon_foreground.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/values/colors.xml b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/values/colors.xml new file mode 100644 index 000000000..b5b50d0ad --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/values/colors.xml @@ -0,0 +1,5 @@ + + #3F51B5 + #303F9F + #FF4081 + diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/values/ic_launcher_background.xml b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/values/ic_launcher_background.xml new file mode 100644 index 000000000..6ec24e641 --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/values/ic_launcher_background.xml @@ -0,0 +1,4 @@ + + + #2C3E50 + \ No newline at end of file diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/values/strings.xml b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/values/strings.xml new file mode 100644 index 000000000..eb1963e24 --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/values/strings.xml @@ -0,0 +1,4 @@ + + NativeEmbeddingDemo.Droid + Hello, Android! + diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/values/styles.xml b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/values/styles.xml new file mode 100644 index 000000000..89aeb9400 --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Droid/Resources/values/styles.xml @@ -0,0 +1,7 @@ + + + diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Library/EmbeddedExtensions.cs b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Library/EmbeddedExtensions.cs new file mode 100644 index 000000000..14c705fa4 --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Library/EmbeddedExtensions.cs @@ -0,0 +1,80 @@ +using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.Maui.Platform; + +#if ANDROID +using PlatformView = Android.Views.View; +using PlatformWindow = Android.App.Activity; +using PlatformApplication = Android.App.Application; +#elif IOS || MACCATALYST +using PlatformView = UIKit.UIView; +using PlatformWindow = UIKit.UIWindow; +using PlatformApplication = UIKit.IUIApplicationDelegate; +#elif WINDOWS +using PlatformView = Microsoft.UI.Xaml.FrameworkElement; +using PlatformWindow = Microsoft.UI.Xaml.Window; +using PlatformApplication = Microsoft.UI.Xaml.Application; +#endif + +namespace Microsoft.Maui.Controls; + +public static class EmbeddedExtensions +{ + public static MauiAppBuilder UseMauiEmbedding(this MauiAppBuilder builder, PlatformApplication? platformApplication = null) + { +#if ANDROID + platformApplication ??= (Android.App.Application)Android.App.Application.Context; +#elif IOS || MACCATALYST + platformApplication ??= UIKit.UIApplication.SharedApplication.Delegate; +#elif WINDOWS + platformApplication ??= Microsoft.UI.Xaml.Application.Current; +#endif + + builder.Services.AddSingleton(platformApplication); + builder.Services.AddSingleton(); + builder.Services.AddScoped(); + + // Returning null is acceptable here as the platform window is optional - but we don't know until we resolve it + builder.Services.AddScoped(svc => svc.GetRequiredService().PlatformWindow!); + builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton()); + builder.ConfigureMauiHandlers(handlers => + { + handlers.AddHandler(typeof(Window), typeof(EmbeddedWindowHandler)); + }); + + return builder; + } + + public static IMauiContext CreateEmbeddedWindowContext(this MauiApp mauiApp, PlatformWindow platformWindow, Window? window = null) + { + var windowScope = mauiApp.Services.CreateScope(); + +#if ANDROID + var windowContext = new MauiContext(windowScope.ServiceProvider, platformWindow); +#else + var windowContext = new MauiContext(windowScope.ServiceProvider); +#endif + + window ??= new Window(); + + var wndProvider = windowContext.Services.GetRequiredService(); + wndProvider.SetWindow(platformWindow, window); + window.ToHandler(windowContext); + + return windowContext; + } + + public static PlatformView ToPlatformEmbedded(this IElement element, IMauiContext context) + { + var wndProvider = context.Services.GetService(); + if (wndProvider is not null && wndProvider.Window is Window wnd && element is VisualElement visual) + wnd.AddLogicalChild(visual); + + return element.ToPlatform(context); + } + + private class EmbeddedInitializeService : IMauiInitializeService + { + public void Initialize(IServiceProvider services) => + services.GetRequiredService(); + } +} \ No newline at end of file diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Library/EmbeddedPlatformApplication.cs b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Library/EmbeddedPlatformApplication.cs new file mode 100644 index 000000000..0b38b9748 --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Library/EmbeddedPlatformApplication.cs @@ -0,0 +1,49 @@ +#if ANDROID +using PlatformApplication = Android.App.Application; +#elif IOS || MACCATALYST +using PlatformApplication = UIKit.IUIApplicationDelegate; +#elif WINDOWS +using PlatformApplication = Microsoft.UI.Xaml.Application; +#endif + +namespace Microsoft.Maui.Controls; + +internal class EmbeddedPlatformApplication : IPlatformApplication +{ + private readonly MauiContext rootContext; + private readonly IMauiContext applicationContext; + + public IServiceProvider Services { get; } + public IApplication Application { get; } + + public EmbeddedPlatformApplication(IServiceProvider services) + { + IPlatformApplication.Current = this; + +#if ANDROID + var platformApp = services.GetRequiredService(); + rootContext = new MauiContext(services, platformApp); +#else + rootContext = new MauiContext(services); +#endif + + applicationContext = MakeApplicationScope(rootContext); + Services = applicationContext.Services; + Application = Services.GetRequiredService(); + } + + private static IMauiContext MakeApplicationScope(IMauiContext rootContext) + { + var scopedContext = new MauiContext(rootContext.Services); + InitializeScopedServices(scopedContext); + return scopedContext; + } + + private static void InitializeScopedServices(IMauiContext scopedContext) + { + var scopedServices = scopedContext.Services.GetServices(); + + foreach (var service in scopedServices) + service.Initialize(scopedContext.Services); + } +} \ No newline at end of file diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Library/EmbeddedWindowHandler.cs b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Library/EmbeddedWindowHandler.cs new file mode 100644 index 000000000..38eee9c0b --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Library/EmbeddedWindowHandler.cs @@ -0,0 +1,32 @@ +using Microsoft.Maui.Handlers; + +#if ANDROID +using PlatformWindow = Android.App.Activity; +#elif IOS || MACCATALYST +using PlatformWindow = UIKit.UIWindow; +#elif WINDOWS +using PlatformWindow = Microsoft.UI.Xaml.Window; +#endif + +namespace Microsoft.Maui.Controls; + +internal class EmbeddedWindowHandler : ElementHandler, IWindowHandler +{ + public static IPropertyMapper Mapper = + new PropertyMapper(ElementHandler.ElementMapper) + { + }; + + public static CommandMapper CommandMapper = + new CommandMapper(ElementHandler.ElementCommandMapper) + { + }; + + public EmbeddedWindowHandler() : base(Mapper) + { + } + + protected override PlatformWindow CreatePlatformElement() => + MauiContext!.Services.GetRequiredService() ?? + throw new InvalidOperationException("EmbeddedWindowHandler could not locate a platform window."); +} \ No newline at end of file diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Library/EmbeddedWindowProvider.cs b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Library/EmbeddedWindowProvider.cs new file mode 100644 index 000000000..aa3e87165 --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Library/EmbeddedWindowProvider.cs @@ -0,0 +1,27 @@ +#if ANDROID +using PlatformWindow = Android.App.Activity; +#elif IOS || MACCATALYST +using PlatformWindow = UIKit.UIWindow; +#elif WINDOWS +using PlatformWindow = Microsoft.UI.Xaml.Window; +#endif + +namespace Microsoft.Maui.Controls; + +public class EmbeddedWindowProvider +{ + WeakReference? platformWindow; + WeakReference? window; + + public PlatformWindow? PlatformWindow => Get(platformWindow); + public Window? Window => Get(window); + + public void SetWindow(PlatformWindow? platformWindow, Window? window) + { + this.platformWindow = new WeakReference(platformWindow); + this.window = new WeakReference(window); + } + + private static T? Get(WeakReference? weak) where T : class => + weak is not null && weak.TryGetTarget(out var target) ? target : null; +} \ No newline at end of file diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Library/NativeEmbeddingDemo.Library.csproj b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Library/NativeEmbeddingDemo.Library.csproj new file mode 100644 index 000000000..524f9d718 --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.Library/NativeEmbeddingDemo.Library.csproj @@ -0,0 +1,26 @@ + + + + net8.0-android;net8.0-ios;net8.0-maccatalyst + $(TargetFrameworks);net8.0-windows10.0.19041.0 + + + true + true + enable + enable + + 11.0 + 13.1 + 21.0 + 10.0.17763.0 + 10.0.17763.0 + 6.5 + + + + + + + + diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/AppDelegate.cs b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/AppDelegate.cs new file mode 100644 index 000000000..68279bda7 --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/AppDelegate.cs @@ -0,0 +1,15 @@ +namespace NativeEmbeddingDemo.MacCatalyst +{ + [Register("AppDelegate")] + public class AppDelegate : UIApplicationDelegate + { + public override UIWindow? Window { get; set; } + + public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions) => true; + + public override UISceneConfiguration GetConfiguration(UIApplication application, UISceneSession connectingSceneSession, UISceneConnectionOptions options) => + Enumerable.FirstOrDefault(options.UserActivities)?.ActivityType == "NewTaskWindow" + ? new UISceneConfiguration("New Task Configuration", UIWindowSceneSessionRole.Application) + : new UISceneConfiguration("Default Configuration", UIWindowSceneSessionRole.Application); + } +} diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Contents.json b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000..98f4d035c --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,117 @@ +{ + "images": [ + { + "scale": "2x", + "size": "20x20", + "idiom": "iphone", + "filename": "Icon40.png" + }, + { + "scale": "3x", + "size": "20x20", + "idiom": "iphone", + "filename": "Icon60.png" + }, + { + "scale": "2x", + "size": "29x29", + "idiom": "iphone", + "filename": "Icon58.png" + }, + { + "scale": "3x", + "size": "29x29", + "idiom": "iphone", + "filename": "Icon87.png" + }, + { + "scale": "2x", + "size": "40x40", + "idiom": "iphone", + "filename": "Icon80.png" + }, + { + "scale": "3x", + "size": "40x40", + "idiom": "iphone", + "filename": "Icon120.png" + }, + { + "scale": "2x", + "size": "60x60", + "idiom": "iphone", + "filename": "Icon120.png" + }, + { + "scale": "3x", + "size": "60x60", + "idiom": "iphone", + "filename": "Icon180.png" + }, + { + "scale": "1x", + "size": "20x20", + "idiom": "ipad", + "filename": "Icon20.png" + }, + { + "scale": "2x", + "size": "20x20", + "idiom": "ipad", + "filename": "Icon40.png" + }, + { + "scale": "1x", + "size": "29x29", + "idiom": "ipad", + "filename": "Icon29.png" + }, + { + "scale": "2x", + "size": "29x29", + "idiom": "ipad", + "filename": "Icon58.png" + }, + { + "scale": "1x", + "size": "40x40", + "idiom": "ipad", + "filename": "Icon40.png" + }, + { + "scale": "2x", + "size": "40x40", + "idiom": "ipad", + "filename": "Icon80.png" + }, + { + "scale": "1x", + "size": "76x76", + "idiom": "ipad", + "filename": "Icon76.png" + }, + { + "scale": "2x", + "size": "76x76", + "idiom": "ipad", + "filename": "Icon152.png" + }, + { + "scale": "2x", + "size": "83.5x83.5", + "idiom": "ipad", + "filename": "Icon167.png" + }, + { + "scale": "1x", + "size": "1024x1024", + "idiom": "ios-marketing", + "filename": "Icon1024.png" + } + ], + "properties": {}, + "info": { + "version": 1, + "author": "xcode" + } +} \ No newline at end of file diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon1024.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon1024.png new file mode 100644 index 000000000..b57320541 Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon1024.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon120.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon120.png new file mode 100644 index 000000000..0b74155a2 Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon120.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon152.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon152.png new file mode 100644 index 000000000..1c1931312 Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon152.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon167.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon167.png new file mode 100644 index 000000000..4e3e8bd8e Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon167.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon180.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon180.png new file mode 100644 index 000000000..40a737125 Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon180.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon20.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon20.png new file mode 100644 index 000000000..8bb138325 Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon20.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon29.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon29.png new file mode 100644 index 000000000..bdd130c35 Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon29.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon40.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon40.png new file mode 100644 index 000000000..75d27899e Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon40.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon58.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon58.png new file mode 100644 index 000000000..06afa6091 Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon58.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon60.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon60.png new file mode 100644 index 000000000..2e0db2a61 Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon60.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon76.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon76.png new file mode 100644 index 000000000..755bc880a Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon76.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon80.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon80.png new file mode 100644 index 000000000..6559bb4da Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon80.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon87.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon87.png new file mode 100644 index 000000000..ca28c8d7a Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Assets.xcassets/AppIcon.appiconset/Icon87.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Entitlements.plist b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Entitlements.plist new file mode 100644 index 000000000..36a870670 --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Entitlements.plist @@ -0,0 +1,6 @@ + + + + + + diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Info.plist b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Info.plist new file mode 100644 index 000000000..4c3967656 --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDisplayName + NativeEmbeddingDemo.MacCatalyst + CFBundleIdentifier + com.companyname.nativeembeddingdemo + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1.0 + UIDeviceFamily + + 2 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + XSAppIconAssets + Assets.xcassets/AppIcon.appiconset + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + New Task Configuration + UISceneDelegateClassName + NewTaskSceneDelegate + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + SceneDelegate + + + + + + diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Main.cs b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Main.cs new file mode 100644 index 000000000..28d78a6ab --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Main.cs @@ -0,0 +1,6 @@ +using NativeEmbeddingDemo.MacCatalyst; + +// This is the main entry point of the application. +// If you want to use a different Application Delegate class from "AppDelegate" +// you can specify it here. +UIApplication.Main(args, null, typeof(AppDelegate)); diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/MainViewController.cs b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/MainViewController.cs new file mode 100644 index 000000000..369ddcf22 --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/MainViewController.cs @@ -0,0 +1,130 @@ +using Microsoft.Maui.Platform; + +namespace NativeEmbeddingDemo.MacCatalyst +{ + public class MainViewController : UIViewController + { + UIWindow GetWindow() => + View?.Window ?? + ParentViewController?.View?.Window ?? + MainViewController.MauiApp.Value.Services.GetRequiredService().GetWindow() ?? + UIApplication.SharedApplication.Delegate.GetWindow(); + + public static readonly Lazy MauiApp = new(() => + { + var mauiApp = MauiProgram.CreateMauiApp(builder => + { + builder.UseMauiEmbedding(); + }); + return mauiApp; + }); + + public static bool UseWindowContext = true; + + MyMauiContent? mauiView; + + public override void ViewDidLoad() + { + base.ViewDidLoad(); + + Title = "Main view controller"; + + View!.BackgroundColor = UIColor.SystemBackground; + + var stackView = new UIStackView + { + Axis = UILayoutConstraintAxis.Vertical, + Alignment = UIStackViewAlignment.Fill, + Distribution = UIStackViewDistribution.Fill, + Spacing = 8, + TranslatesAutoresizingMaskIntoConstraints = false + }; + View.AddSubview(stackView); + + NSLayoutConstraint.ActivateConstraints(new[] + { + stackView.TopAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.TopAnchor, 20), + stackView.LeadingAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.LeadingAnchor, 20), + stackView.TrailingAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.TrailingAnchor, -20), + stackView.BottomAnchor.ConstraintLessThanOrEqualTo(View.SafeAreaLayoutGuide.BottomAnchor, -20) + }); + + // Create UIKit button + var uiButton = new UIButton(UIButtonType.System); + uiButton.SetTitle("UIKit button above .NET MAUI controls", UIControlState.Normal); + uiButton.TouchUpInside += OnUIButtonClicked; + stackView.AddArrangedSubview(uiButton); + + // Ensure .NET MAUI app is built before creating .NET MAUI views + var mauiApp = MainViewController.MauiApp.Value; + + // Create .NET MAUI context + var mauiContext = UseWindowContext + ? mauiApp.CreateEmbeddedWindowContext(GetWindow()) // Create window context + : new MauiContext(mauiApp.Services); // Create app context + + + // Create .NET MAUI content + mauiView = new MyMauiContent(); + + // Create native view + var nativeView = mauiView.ToPlatformEmbedded(mauiContext); + + // Add native view to layout + stackView.AddArrangedSubview(nativeView); + + AddNavBarButtons(); + } + + void AddNavBarButtons() + { + var addNewWindowButton = new UIBarButtonItem( + UIImage.GetSystemImage("macwindow.badge.plus"), + UIBarButtonItemStyle.Plain, + (sender, e) => RequestSession()); + + var addNewTaskButton = new UIBarButtonItem( + UIBarButtonSystemItem.Add, + (sender, e) => RequestSession("NewTaskWindow")); + + NavigationItem.RightBarButtonItems = [addNewTaskButton, addNewWindowButton]; + } + + void RequestSession(string? activityType = null) + { + var activity = activityType is null + ? null + : new NSUserActivity(activityType); + + if (OperatingSystem.IsMacCatalystVersionAtLeast(17)) + { + var request = UISceneSessionActivationRequest.Create(); + request.UserActivity = activity; + + UIApplication.SharedApplication.ActivateSceneSession(request, error => + { + Console.WriteLine(new NSErrorException(error)); + }); + } + else + { + UIApplication.SharedApplication.RequestSceneSessionActivation(null, activity, null, error => + { + Console.WriteLine(new NSErrorException(error)); + }); + } + } + + async void OnUIButtonClicked(object? sender, EventArgs e) + { + if (mauiView?.DotNetBot is not Image bot) + return; + + await bot.RotateTo(360, 1000); + bot.Rotation = 0; + + bot.HeightRequest = 90; + } + } +} + diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/NativeEmbeddingDemo.MacCatalyst.csproj b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/NativeEmbeddingDemo.MacCatalyst.csproj new file mode 100644 index 000000000..fc90824a3 --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/NativeEmbeddingDemo.MacCatalyst.csproj @@ -0,0 +1,23 @@ + + + + net8.0-maccatalyst + Exe + enable + true + + 14.2 + true + true + + + + + + + + + + + + \ No newline at end of file diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/NewTaskSceneDelegate.cs b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/NewTaskSceneDelegate.cs new file mode 100644 index 000000000..8f4c6a871 --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/NewTaskSceneDelegate.cs @@ -0,0 +1,55 @@ +using AppKit; + +namespace NativeEmbeddingDemo.MacCatalyst +{ + [Register(nameof(NewTaskSceneDelegate))] + public class NewTaskSceneDelegate : UIWindowSceneDelegate + { + public override UIWindow? Window { get; set; } + + [Export("scene:willConnectToSession:options:")] + public override void WillConnect(UIScene scene, UISceneSession session, UISceneConnectionOptions connectionOptions) + { + if (scene is not UIWindowScene windowScene) + return; + + var window = new UIWindow(windowScene); + window.RootViewController = new NewTaskViewController(); + window.WindowScene!.Title = "New Task"; + window.MakeKeyAndVisible(); + + Window = window; + + if (OperatingSystem.IsMacCatalyst()) + { + ConfigureMacWindowSize(); + ConfigureToolbar(); + } + } + + void ConfigureMacWindowSize() + { + if (Window?.WindowScene?.SizeRestrictions is null) + return; + + var fixedSize = new CGSize(400, 250); + Window.WindowScene.SizeRestrictions.MinimumSize = fixedSize; + Window.WindowScene.SizeRestrictions.MaximumSize = fixedSize; + } + + void ConfigureToolbar() + { + if (Window?.WindowScene?.Titlebar is null) + return; + + var toolbar = new NSToolbar(); + toolbar.ShowsBaselineSeparator = false; + + var titlebar = Window.WindowScene.Titlebar; + titlebar.Toolbar = toolbar; + titlebar.ToolbarStyle = UITitlebarToolbarStyle.Automatic; + titlebar.TitleVisibility = UITitlebarTitleVisibility.Visible; + } + } +} + diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/NewTaskViewController.cs b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/NewTaskViewController.cs new file mode 100644 index 000000000..faa828a4c --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/NewTaskViewController.cs @@ -0,0 +1,67 @@ +namespace NativeEmbeddingDemo.MacCatalyst +{ + public class NewTaskViewController : UIViewController + { + UITextField taskTitleTextField = null; + UITextField notesTextField = null; + + public override void ViewDidLoad() + { + base.ViewDidLoad(); + + View!.BackgroundColor = UIColor.SystemBackground; + + var stackView = new UIStackView + { + Axis = UILayoutConstraintAxis.Vertical, + Alignment = UIStackViewAlignment.Fill, + Distribution = UIStackViewDistribution.Fill, + Spacing = 8, + TranslatesAutoresizingMaskIntoConstraints = false + }; + View.AddSubview(stackView); + + NSLayoutConstraint.ActivateConstraints(new[] + { + stackView.TopAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.TopAnchor, 20), + stackView.LeadingAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.LeadingAnchor, 20), + stackView.TrailingAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.TrailingAnchor, -20), + stackView.BottomAnchor.ConstraintLessThanOrEqualTo(View.SafeAreaLayoutGuide.BottomAnchor, -20) + }); + + // Title text field + taskTitleTextField = CreateTextField("Title"); + stackView.AddArrangedSubview(taskTitleTextField); + + // Notes text field + notesTextField = CreateTextField("Notes"); + stackView.AddArrangedSubview(notesTextField); + + // Create task button + var createTaskButton = new UIButton(UIButtonType.System); + createTaskButton.SetTitle("Create Task", UIControlState.Normal); + createTaskButton.TouchUpInside += CreateTaskButtonTapped; + stackView.AddArrangedSubview(createTaskButton); + } + + UITextField CreateTextField(string placeholder) + { + var uiTextField = new UITextField + { + Placeholder = placeholder, + BorderStyle = UITextBorderStyle.RoundedRect, + TranslatesAutoresizingMaskIntoConstraints = false + }; + uiTextField.HeightAnchor.ConstraintEqualTo(40).Active = true; + return uiTextField; + } + + void CreateTaskButtonTapped(object? sender, EventArgs e) + { + Console.WriteLine("Create button tapped."); + + // Implement your logic here for creating a task. + } + } +} + diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Resources/LaunchScreen.xib b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Resources/LaunchScreen.xib new file mode 100644 index 000000000..819020174 --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/Resources/LaunchScreen.xib @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/SceneDelegate.cs b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/SceneDelegate.cs new file mode 100644 index 000000000..b24413d9a --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.MacCatalyst/SceneDelegate.cs @@ -0,0 +1,67 @@ +namespace NativeEmbeddingDemo.MacCatalyst +{ + [Register("SceneDelegate")] + public class SceneDelegate : UIResponder, IUIWindowSceneDelegate + { + [Export("window")] + public UIWindow? Window { get; set; } + + [Export("scene:willConnectToSession:options:")] + public void WillConnect(UIScene scene, UISceneSession session, UISceneConnectionOptions connectionOptions) + { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see UIApplicationDelegate `GetConfiguration` instead). + + if (scene is not UIWindowScene windowScene) + return; + + Window = new UIWindow(windowScene); + + var mainVC = new MainViewController(); + var navigationController = new UINavigationController(mainVC); + navigationController.NavigationBar.PrefersLargeTitles = true; + + Window.RootViewController = navigationController; + Window.MakeKeyAndVisible(); + } + + [Export("sceneDidDisconnect:")] + public void DidDisconnect(UIScene scene) + { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see UIApplicationDelegate `DidDiscardSceneSessions` instead). + } + + [Export("sceneDidBecomeActive:")] + public void DidBecomeActive(UIScene scene) + { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + [Export("sceneWillResignActive:")] + public void WillResignActive(UIScene scene) + { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + [Export("sceneWillEnterForeground:")] + public void WillEnterForeground(UIScene scene) + { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + [Export("sceneDidEnterBackground:")] + public void DidEnterBackground(UIScene scene) + { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + } +} diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/App.xaml b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/App.xaml new file mode 100644 index 000000000..202a70f02 --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/App.xaml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/App.xaml.cs b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/App.xaml.cs new file mode 100644 index 000000000..75c7fe352 --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/App.xaml.cs @@ -0,0 +1,34 @@ +using Microsoft.UI.Xaml; + +// To learn more about WinUI, the WinUI project structure, +// and more about our project templates, see: http://aka.ms/winui-project-info. + +namespace NativeEmbeddingDemo.WinUI +{ + /// + /// Provides application-specific behavior to supplement the default Application class. + /// + public partial class App : Microsoft.UI.Xaml.Application + { + /// + /// Initializes the singleton application object. This is the first line of authored code + /// executed, and as such is the logical equivalent of main() or WinMain(). + /// + public App() + { + this.InitializeComponent(); + } + + /// + /// Invoked when the application is launched. + /// + /// Details about the launch request and process. + protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args) + { + m_window = new MainWindow(); + m_window.Activate(); + } + + private Microsoft.UI.Xaml.Window m_window; + } +} diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/Assets/LockScreenLogo.scale-200.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/Assets/LockScreenLogo.scale-200.png new file mode 100644 index 000000000..7440f0d4b Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/Assets/LockScreenLogo.scale-200.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/Assets/SplashScreen.scale-200.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/Assets/SplashScreen.scale-200.png new file mode 100644 index 000000000..32f486a86 Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/Assets/SplashScreen.scale-200.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/Assets/Square150x150Logo.scale-200.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/Assets/Square150x150Logo.scale-200.png new file mode 100644 index 000000000..53ee3777e Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/Assets/Square150x150Logo.scale-200.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/Assets/Square44x44Logo.scale-200.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/Assets/Square44x44Logo.scale-200.png new file mode 100644 index 000000000..f713bba67 Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/Assets/Square44x44Logo.scale-200.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/Assets/Square44x44Logo.targetsize-24_altform-unplated.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/Assets/Square44x44Logo.targetsize-24_altform-unplated.png new file mode 100644 index 000000000..dc9f5bea0 Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/Assets/Square44x44Logo.targetsize-24_altform-unplated.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/Assets/StoreLogo.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/Assets/StoreLogo.png new file mode 100644 index 000000000..a4586f26b Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/Assets/StoreLogo.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/Assets/Wide310x150Logo.scale-200.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/Assets/Wide310x150Logo.scale-200.png new file mode 100644 index 000000000..8b4a5d0dd Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/Assets/Wide310x150Logo.scale-200.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/MainWindow.xaml b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/MainWindow.xaml new file mode 100644 index 000000000..1fd7ac507 --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/MainWindow.xaml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/MainWindow.xaml.cs b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/MainWindow.xaml.cs new file mode 100644 index 000000000..a9eba09b4 --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/MainWindow.xaml.cs @@ -0,0 +1,85 @@ +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Controls; + +// To learn more about WinUI, the WinUI project structure, +// and more about our project templates, see: http://aka.ms/winui-project-info. + +namespace NativeEmbeddingDemo.WinUI +{ + /// + /// An empty window that can be used on its own or navigated to within a Frame. + /// + public sealed partial class MainWindow : Microsoft.UI.Xaml.Window + { + public static readonly Lazy MauiApp = new(() => + { + var mauiApp = MauiProgram.CreateMauiApp(builder => + { + builder.UseMauiEmbedding(); + }); + return mauiApp; + }); + + public static bool UseWindowContext = true; + + MyMauiContent? mauiView; + + public MainWindow() + { + this.InitializeComponent(); + + // Add a StackPanel to the root layout + var stackPanel = new StackPanel + { + Orientation = Orientation.Vertical, + HorizontalAlignment = Microsoft.UI.Xaml.HorizontalAlignment.Stretch, + VerticalAlignment = Microsoft.UI.Xaml.VerticalAlignment.Stretch, + Spacing = 8, + Padding = new Microsoft.UI.Xaml.Thickness(20) + }; + rootLayout.Children.Add(stackPanel); + + // Create WinUI button + var nativeButton = new Microsoft.UI.Xaml.Controls.Button(); + nativeButton.Content = "WinUI button above .NET MAUI controls"; + nativeButton.HorizontalAlignment = Microsoft.UI.Xaml.HorizontalAlignment.Center; + nativeButton.Click += OnWindowsButtonClicked; + stackPanel.Children.Add(nativeButton); + + // Ensure .NET MAUI app is built before creating .NET MAUI views + var mauiApp = MainWindow.MauiApp.Value; + + // Create .NET MAUI context + var mauiContext = UseWindowContext + ? mauiApp.CreateEmbeddedWindowContext(this) // Create window context + : new MauiContext(mauiApp.Services); // Create app context + + // Create .NET MAUI content + mauiView = new MyMauiContent(); + + // Create native view + var nativeView = mauiView.ToPlatformEmbedded(mauiContext); + + // Add native view to layout + stackPanel.Children.Add(nativeView); + } + + private async void OnWindowsButtonClicked(object? sender, RoutedEventArgs e) + { + if (mauiView?.DotNetBot is not Microsoft.Maui.Controls.Image bot) + return; + + await bot.RotateTo(360, 1000); + bot.Rotation = 0; + + bot.HeightRequest = 90; + } + + private void OnNewWindowClicked(object sender, RoutedEventArgs e) + { + var window = new MainWindow(); + window.Activate(); + } + + } +} diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/NativeEmbeddingDemo.WinUI.csproj b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/NativeEmbeddingDemo.WinUI.csproj new file mode 100644 index 000000000..b80c16694 --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/NativeEmbeddingDemo.WinUI.csproj @@ -0,0 +1,63 @@ + + + WinExe + net8.0-windows10.0.19041.0 + 10.0.17763.0 + NativeEmbeddingDemo.WinUI + app.manifest + x86;x64;ARM64 + win10-x86;win10-x64;win10-arm64 + win10-$(Platform).pubxml + true + true + enable + enable + true + + true + true + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/Package.appxmanifest b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/Package.appxmanifest new file mode 100644 index 000000000..9a2e467bd --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/Package.appxmanifest @@ -0,0 +1,51 @@ + + + + + + + + + + NativeEmbeddingDemo.WinUI + dabritch + Assets\StoreLogo.png + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/Properties/launchSettings.json b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/Properties/launchSettings.json new file mode 100644 index 000000000..8e1684848 --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/Properties/launchSettings.json @@ -0,0 +1,10 @@ +{ + "profiles": { + "NativeEmbeddingDemo.WinUI (Package)": { + "commandName": "MsixPackage" + }, + "NativeEmbeddingDemo.WinUI (Unpackaged)": { + "commandName": "Project" + } + } +} \ No newline at end of file diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/app.manifest b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/app.manifest new file mode 100644 index 000000000..23a711688 --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.WinUI/app.manifest @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + PerMonitorV2 + + + \ No newline at end of file diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/AppDelegate.cs b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/AppDelegate.cs new file mode 100644 index 000000000..ba25f30ea --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/AppDelegate.cs @@ -0,0 +1,17 @@ +namespace NativeEmbeddingDemo.iOS +{ + [Register("AppDelegate")] + public class AppDelegate : UIApplicationDelegate + { + public override UIWindow? Window { get; set; } + + public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions) + { + Window = new UIWindow(UIScreen.MainScreen.Bounds); + var vc = new MainViewController(); + Window.RootViewController = vc; + Window.MakeKeyAndVisible(); + return true; + } + } +} diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Contents.json b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000..98f4d035c --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,117 @@ +{ + "images": [ + { + "scale": "2x", + "size": "20x20", + "idiom": "iphone", + "filename": "Icon40.png" + }, + { + "scale": "3x", + "size": "20x20", + "idiom": "iphone", + "filename": "Icon60.png" + }, + { + "scale": "2x", + "size": "29x29", + "idiom": "iphone", + "filename": "Icon58.png" + }, + { + "scale": "3x", + "size": "29x29", + "idiom": "iphone", + "filename": "Icon87.png" + }, + { + "scale": "2x", + "size": "40x40", + "idiom": "iphone", + "filename": "Icon80.png" + }, + { + "scale": "3x", + "size": "40x40", + "idiom": "iphone", + "filename": "Icon120.png" + }, + { + "scale": "2x", + "size": "60x60", + "idiom": "iphone", + "filename": "Icon120.png" + }, + { + "scale": "3x", + "size": "60x60", + "idiom": "iphone", + "filename": "Icon180.png" + }, + { + "scale": "1x", + "size": "20x20", + "idiom": "ipad", + "filename": "Icon20.png" + }, + { + "scale": "2x", + "size": "20x20", + "idiom": "ipad", + "filename": "Icon40.png" + }, + { + "scale": "1x", + "size": "29x29", + "idiom": "ipad", + "filename": "Icon29.png" + }, + { + "scale": "2x", + "size": "29x29", + "idiom": "ipad", + "filename": "Icon58.png" + }, + { + "scale": "1x", + "size": "40x40", + "idiom": "ipad", + "filename": "Icon40.png" + }, + { + "scale": "2x", + "size": "40x40", + "idiom": "ipad", + "filename": "Icon80.png" + }, + { + "scale": "1x", + "size": "76x76", + "idiom": "ipad", + "filename": "Icon76.png" + }, + { + "scale": "2x", + "size": "76x76", + "idiom": "ipad", + "filename": "Icon152.png" + }, + { + "scale": "2x", + "size": "83.5x83.5", + "idiom": "ipad", + "filename": "Icon167.png" + }, + { + "scale": "1x", + "size": "1024x1024", + "idiom": "ios-marketing", + "filename": "Icon1024.png" + } + ], + "properties": {}, + "info": { + "version": 1, + "author": "xcode" + } +} \ No newline at end of file diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon1024.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon1024.png new file mode 100644 index 000000000..b57320541 Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon1024.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon120.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon120.png new file mode 100644 index 000000000..0b74155a2 Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon120.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon152.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon152.png new file mode 100644 index 000000000..1c1931312 Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon152.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon167.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon167.png new file mode 100644 index 000000000..4e3e8bd8e Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon167.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon180.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon180.png new file mode 100644 index 000000000..40a737125 Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon180.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon20.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon20.png new file mode 100644 index 000000000..8bb138325 Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon20.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon29.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon29.png new file mode 100644 index 000000000..bdd130c35 Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon29.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon40.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon40.png new file mode 100644 index 000000000..75d27899e Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon40.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon58.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon58.png new file mode 100644 index 000000000..06afa6091 Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon58.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon60.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon60.png new file mode 100644 index 000000000..2e0db2a61 Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon60.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon76.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon76.png new file mode 100644 index 000000000..755bc880a Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon76.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon80.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon80.png new file mode 100644 index 000000000..6559bb4da Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon80.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon87.png b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon87.png new file mode 100644 index 000000000..ca28c8d7a Binary files /dev/null and b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Assets.xcassets/AppIcon.appiconset/Icon87.png differ diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Entitlements.plist b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Entitlements.plist new file mode 100644 index 000000000..36a870670 --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Entitlements.plist @@ -0,0 +1,6 @@ + + + + + + diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Info.plist b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Info.plist new file mode 100644 index 000000000..f72bacae2 --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Info.plist @@ -0,0 +1,42 @@ + + + + + CFBundleDisplayName + NativeEmbeddingDemo.iOS + CFBundleIdentifier + com.companyname.nativeembeddingdemo + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + UIDeviceFamily + + 1 + 2 + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + XSAppIconAssets + Assets.xcassets/AppIcon.appiconset + + diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Main.cs b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Main.cs new file mode 100644 index 000000000..8f4720b33 --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Main.cs @@ -0,0 +1,6 @@ +using NativeEmbeddingDemo.iOS; + +// This is the main entry point of the application. +// If you want to use a different Application Delegate class from "AppDelegate" +// you can specify it here. +UIApplication.Main(args, null, typeof(AppDelegate)); diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/MainViewController.cs b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/MainViewController.cs new file mode 100644 index 000000000..6f1a8c57e --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/MainViewController.cs @@ -0,0 +1,88 @@ +using Microsoft.Maui.Platform; + +namespace NativeEmbeddingDemo.iOS +{ + public class MainViewController : UIViewController + { + UIWindow GetWindow() => + View?.Window ?? + ParentViewController?.View?.Window ?? + MainViewController.MauiApp.Value.Services.GetRequiredService().GetWindow() ?? + UIApplication.SharedApplication.Delegate.GetWindow(); + + public static readonly Lazy MauiApp = new(() => + { + var mauiApp = MauiProgram.CreateMauiApp(builder => + { + builder.UseMauiEmbedding(); + }); + return mauiApp; + }); + + public static bool UseWindowContext = true; + + MyMauiContent? mauiView; + + public override void ViewDidLoad() + { + base.ViewDidLoad(); + + Title = "Main view controller"; + + View!.BackgroundColor = UIColor.SystemBackground; + + var stackView = new UIStackView + { + Axis = UILayoutConstraintAxis.Vertical, + Alignment = UIStackViewAlignment.Fill, + Distribution = UIStackViewDistribution.Fill, + Spacing = 8, + TranslatesAutoresizingMaskIntoConstraints = false + }; + View.AddSubview(stackView); + + NSLayoutConstraint.ActivateConstraints(new[] + { + stackView.TopAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.TopAnchor, 20), + stackView.LeadingAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.LeadingAnchor, 20), + stackView.TrailingAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.TrailingAnchor, -20), + stackView.BottomAnchor.ConstraintLessThanOrEqualTo(View.SafeAreaLayoutGuide.BottomAnchor, -20) + }); + + // Create UIKit button + var uiButton = new UIButton(UIButtonType.System); + uiButton.SetTitle("UIKit button above .NET MAUI controls", UIControlState.Normal); + uiButton.TouchUpInside += OnUIButtonClicked; + stackView.AddArrangedSubview(uiButton); + + // Ensure .NET MAUI app is built before creating .NET MAUI views + var mauiApp = MainViewController.MauiApp.Value; + + // Create .NET MAUI context + var mauiContext = UseWindowContext + ? mauiApp.CreateEmbeddedWindowContext(GetWindow()) // Create window context + : new MauiContext(mauiApp.Services); // Create app context + + // Create .NET MAUI content + mauiView = new MyMauiContent(); + + // Create native view + var nativeView = mauiView.ToPlatformEmbedded(mauiContext); + + // Add native view to layout + stackView.AddArrangedSubview(nativeView); + } + + async void OnUIButtonClicked(object? sender, EventArgs e) + { + if (mauiView?.DotNetBot is not Image bot) + return; + + await bot.RotateTo(360, 1000); + bot.Rotation = 0; + + bot.HeightRequest = 90; + } + } +} + diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/NativeEmbeddingDemo.iOS.csproj b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/NativeEmbeddingDemo.iOS.csproj new file mode 100644 index 000000000..9100674e4 --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/NativeEmbeddingDemo.iOS.csproj @@ -0,0 +1,22 @@ + + + net8.0-ios + Exe + enable + true + 13.0 + + true + true + + + + + + + + + + + + diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Resources/LaunchScreen.xib b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Resources/LaunchScreen.xib new file mode 100644 index 000000000..819020174 --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.iOS/Resources/LaunchScreen.xib @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.sln b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.sln new file mode 100644 index 000000000..5d7d21ab7 --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo.sln @@ -0,0 +1,173 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.9.34622.214 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NativeEmbeddingDemo", "NativeEmbeddingDemo\NativeEmbeddingDemo.csproj", "{B5348805-A47A-4F1B-99D2-95E2D21A9A51}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NativeEmbeddingDemo.iOS", "NativeEmbeddingDemo.iOS\NativeEmbeddingDemo.iOS.csproj", "{BCDE4985-CC8C-4FE9-A196-18385F0C9B67}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NativeEmbeddingDemo.WinUI", "NativeEmbeddingDemo.WinUI\NativeEmbeddingDemo.WinUI.csproj", "{116EAB9E-EE24-4676-B279-5295D922E07C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NativeEmbeddingDemo.Library", "NativeEmbeddingDemo.Library\NativeEmbeddingDemo.Library.csproj", "{4B4770CF-082D-45AB-86AA-4C7A5ECBC20A}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NativeEmbeddingDemo.Droid", "NativeEmbeddingDemo.Droid\NativeEmbeddingDemo.Droid.csproj", "{76B43FBB-1DEA-4260-8802-7DC0015A916F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NativeEmbeddingDemo.MacCatalyst", "NativeEmbeddingDemo.MacCatalyst\NativeEmbeddingDemo.MacCatalyst.csproj", "{A63220BF-4101-4D60-A75D-CF2693646A6A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|ARM64 = Debug|ARM64 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|ARM64 = Release|ARM64 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B5348805-A47A-4F1B-99D2-95E2D21A9A51}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B5348805-A47A-4F1B-99D2-95E2D21A9A51}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B5348805-A47A-4F1B-99D2-95E2D21A9A51}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {B5348805-A47A-4F1B-99D2-95E2D21A9A51}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {B5348805-A47A-4F1B-99D2-95E2D21A9A51}.Debug|ARM64.Build.0 = Debug|Any CPU + {B5348805-A47A-4F1B-99D2-95E2D21A9A51}.Debug|ARM64.Deploy.0 = Debug|Any CPU + {B5348805-A47A-4F1B-99D2-95E2D21A9A51}.Debug|x64.ActiveCfg = Debug|Any CPU + {B5348805-A47A-4F1B-99D2-95E2D21A9A51}.Debug|x64.Build.0 = Debug|Any CPU + {B5348805-A47A-4F1B-99D2-95E2D21A9A51}.Debug|x64.Deploy.0 = Debug|Any CPU + {B5348805-A47A-4F1B-99D2-95E2D21A9A51}.Debug|x86.ActiveCfg = Debug|Any CPU + {B5348805-A47A-4F1B-99D2-95E2D21A9A51}.Debug|x86.Build.0 = Debug|Any CPU + {B5348805-A47A-4F1B-99D2-95E2D21A9A51}.Debug|x86.Deploy.0 = Debug|Any CPU + {B5348805-A47A-4F1B-99D2-95E2D21A9A51}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B5348805-A47A-4F1B-99D2-95E2D21A9A51}.Release|Any CPU.Build.0 = Release|Any CPU + {B5348805-A47A-4F1B-99D2-95E2D21A9A51}.Release|Any CPU.Deploy.0 = Release|Any CPU + {B5348805-A47A-4F1B-99D2-95E2D21A9A51}.Release|ARM64.ActiveCfg = Release|Any CPU + {B5348805-A47A-4F1B-99D2-95E2D21A9A51}.Release|ARM64.Build.0 = Release|Any CPU + {B5348805-A47A-4F1B-99D2-95E2D21A9A51}.Release|ARM64.Deploy.0 = Release|Any CPU + {B5348805-A47A-4F1B-99D2-95E2D21A9A51}.Release|x64.ActiveCfg = Release|Any CPU + {B5348805-A47A-4F1B-99D2-95E2D21A9A51}.Release|x64.Build.0 = Release|Any CPU + {B5348805-A47A-4F1B-99D2-95E2D21A9A51}.Release|x64.Deploy.0 = Release|Any CPU + {B5348805-A47A-4F1B-99D2-95E2D21A9A51}.Release|x86.ActiveCfg = Release|Any CPU + {B5348805-A47A-4F1B-99D2-95E2D21A9A51}.Release|x86.Build.0 = Release|Any CPU + {B5348805-A47A-4F1B-99D2-95E2D21A9A51}.Release|x86.Deploy.0 = Release|Any CPU + {BCDE4985-CC8C-4FE9-A196-18385F0C9B67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BCDE4985-CC8C-4FE9-A196-18385F0C9B67}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BCDE4985-CC8C-4FE9-A196-18385F0C9B67}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {BCDE4985-CC8C-4FE9-A196-18385F0C9B67}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {BCDE4985-CC8C-4FE9-A196-18385F0C9B67}.Debug|ARM64.Build.0 = Debug|Any CPU + {BCDE4985-CC8C-4FE9-A196-18385F0C9B67}.Debug|ARM64.Deploy.0 = Debug|Any CPU + {BCDE4985-CC8C-4FE9-A196-18385F0C9B67}.Debug|x64.ActiveCfg = Debug|Any CPU + {BCDE4985-CC8C-4FE9-A196-18385F0C9B67}.Debug|x64.Build.0 = Debug|Any CPU + {BCDE4985-CC8C-4FE9-A196-18385F0C9B67}.Debug|x64.Deploy.0 = Debug|Any CPU + {BCDE4985-CC8C-4FE9-A196-18385F0C9B67}.Debug|x86.ActiveCfg = Debug|Any CPU + {BCDE4985-CC8C-4FE9-A196-18385F0C9B67}.Debug|x86.Build.0 = Debug|Any CPU + {BCDE4985-CC8C-4FE9-A196-18385F0C9B67}.Debug|x86.Deploy.0 = Debug|Any CPU + {BCDE4985-CC8C-4FE9-A196-18385F0C9B67}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BCDE4985-CC8C-4FE9-A196-18385F0C9B67}.Release|Any CPU.Build.0 = Release|Any CPU + {BCDE4985-CC8C-4FE9-A196-18385F0C9B67}.Release|Any CPU.Deploy.0 = Release|Any CPU + {BCDE4985-CC8C-4FE9-A196-18385F0C9B67}.Release|ARM64.ActiveCfg = Release|Any CPU + {BCDE4985-CC8C-4FE9-A196-18385F0C9B67}.Release|ARM64.Build.0 = Release|Any CPU + {BCDE4985-CC8C-4FE9-A196-18385F0C9B67}.Release|ARM64.Deploy.0 = Release|Any CPU + {BCDE4985-CC8C-4FE9-A196-18385F0C9B67}.Release|x64.ActiveCfg = Release|Any CPU + {BCDE4985-CC8C-4FE9-A196-18385F0C9B67}.Release|x64.Build.0 = Release|Any CPU + {BCDE4985-CC8C-4FE9-A196-18385F0C9B67}.Release|x64.Deploy.0 = Release|Any CPU + {BCDE4985-CC8C-4FE9-A196-18385F0C9B67}.Release|x86.ActiveCfg = Release|Any CPU + {BCDE4985-CC8C-4FE9-A196-18385F0C9B67}.Release|x86.Build.0 = Release|Any CPU + {BCDE4985-CC8C-4FE9-A196-18385F0C9B67}.Release|x86.Deploy.0 = Release|Any CPU + {116EAB9E-EE24-4676-B279-5295D922E07C}.Debug|Any CPU.ActiveCfg = Debug|x64 + {116EAB9E-EE24-4676-B279-5295D922E07C}.Debug|Any CPU.Build.0 = Debug|x64 + {116EAB9E-EE24-4676-B279-5295D922E07C}.Debug|Any CPU.Deploy.0 = Debug|x64 + {116EAB9E-EE24-4676-B279-5295D922E07C}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {116EAB9E-EE24-4676-B279-5295D922E07C}.Debug|ARM64.Build.0 = Debug|ARM64 + {116EAB9E-EE24-4676-B279-5295D922E07C}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {116EAB9E-EE24-4676-B279-5295D922E07C}.Debug|x64.ActiveCfg = Debug|x64 + {116EAB9E-EE24-4676-B279-5295D922E07C}.Debug|x64.Build.0 = Debug|x64 + {116EAB9E-EE24-4676-B279-5295D922E07C}.Debug|x64.Deploy.0 = Debug|x64 + {116EAB9E-EE24-4676-B279-5295D922E07C}.Debug|x86.ActiveCfg = Debug|x86 + {116EAB9E-EE24-4676-B279-5295D922E07C}.Debug|x86.Build.0 = Debug|x86 + {116EAB9E-EE24-4676-B279-5295D922E07C}.Debug|x86.Deploy.0 = Debug|x86 + {116EAB9E-EE24-4676-B279-5295D922E07C}.Release|Any CPU.ActiveCfg = Release|x64 + {116EAB9E-EE24-4676-B279-5295D922E07C}.Release|Any CPU.Build.0 = Release|x64 + {116EAB9E-EE24-4676-B279-5295D922E07C}.Release|Any CPU.Deploy.0 = Release|x64 + {116EAB9E-EE24-4676-B279-5295D922E07C}.Release|ARM64.ActiveCfg = Release|ARM64 + {116EAB9E-EE24-4676-B279-5295D922E07C}.Release|ARM64.Build.0 = Release|ARM64 + {116EAB9E-EE24-4676-B279-5295D922E07C}.Release|ARM64.Deploy.0 = Release|ARM64 + {116EAB9E-EE24-4676-B279-5295D922E07C}.Release|x64.ActiveCfg = Release|x64 + {116EAB9E-EE24-4676-B279-5295D922E07C}.Release|x64.Build.0 = Release|x64 + {116EAB9E-EE24-4676-B279-5295D922E07C}.Release|x64.Deploy.0 = Release|x64 + {116EAB9E-EE24-4676-B279-5295D922E07C}.Release|x86.ActiveCfg = Release|x86 + {116EAB9E-EE24-4676-B279-5295D922E07C}.Release|x86.Build.0 = Release|x86 + {116EAB9E-EE24-4676-B279-5295D922E07C}.Release|x86.Deploy.0 = Release|x86 + {4B4770CF-082D-45AB-86AA-4C7A5ECBC20A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4B4770CF-082D-45AB-86AA-4C7A5ECBC20A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4B4770CF-082D-45AB-86AA-4C7A5ECBC20A}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {4B4770CF-082D-45AB-86AA-4C7A5ECBC20A}.Debug|ARM64.Build.0 = Debug|Any CPU + {4B4770CF-082D-45AB-86AA-4C7A5ECBC20A}.Debug|x64.ActiveCfg = Debug|Any CPU + {4B4770CF-082D-45AB-86AA-4C7A5ECBC20A}.Debug|x64.Build.0 = Debug|Any CPU + {4B4770CF-082D-45AB-86AA-4C7A5ECBC20A}.Debug|x86.ActiveCfg = Debug|Any CPU + {4B4770CF-082D-45AB-86AA-4C7A5ECBC20A}.Debug|x86.Build.0 = Debug|Any CPU + {4B4770CF-082D-45AB-86AA-4C7A5ECBC20A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4B4770CF-082D-45AB-86AA-4C7A5ECBC20A}.Release|Any CPU.Build.0 = Release|Any CPU + {4B4770CF-082D-45AB-86AA-4C7A5ECBC20A}.Release|ARM64.ActiveCfg = Release|Any CPU + {4B4770CF-082D-45AB-86AA-4C7A5ECBC20A}.Release|ARM64.Build.0 = Release|Any CPU + {4B4770CF-082D-45AB-86AA-4C7A5ECBC20A}.Release|x64.ActiveCfg = Release|Any CPU + {4B4770CF-082D-45AB-86AA-4C7A5ECBC20A}.Release|x64.Build.0 = Release|Any CPU + {4B4770CF-082D-45AB-86AA-4C7A5ECBC20A}.Release|x86.ActiveCfg = Release|Any CPU + {4B4770CF-082D-45AB-86AA-4C7A5ECBC20A}.Release|x86.Build.0 = Release|Any CPU + {76B43FBB-1DEA-4260-8802-7DC0015A916F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {76B43FBB-1DEA-4260-8802-7DC0015A916F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {76B43FBB-1DEA-4260-8802-7DC0015A916F}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {76B43FBB-1DEA-4260-8802-7DC0015A916F}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {76B43FBB-1DEA-4260-8802-7DC0015A916F}.Debug|ARM64.Build.0 = Debug|Any CPU + {76B43FBB-1DEA-4260-8802-7DC0015A916F}.Debug|ARM64.Deploy.0 = Debug|Any CPU + {76B43FBB-1DEA-4260-8802-7DC0015A916F}.Debug|x64.ActiveCfg = Debug|Any CPU + {76B43FBB-1DEA-4260-8802-7DC0015A916F}.Debug|x64.Build.0 = Debug|Any CPU + {76B43FBB-1DEA-4260-8802-7DC0015A916F}.Debug|x64.Deploy.0 = Debug|Any CPU + {76B43FBB-1DEA-4260-8802-7DC0015A916F}.Debug|x86.ActiveCfg = Debug|Any CPU + {76B43FBB-1DEA-4260-8802-7DC0015A916F}.Debug|x86.Build.0 = Debug|Any CPU + {76B43FBB-1DEA-4260-8802-7DC0015A916F}.Debug|x86.Deploy.0 = Debug|Any CPU + {76B43FBB-1DEA-4260-8802-7DC0015A916F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {76B43FBB-1DEA-4260-8802-7DC0015A916F}.Release|Any CPU.Build.0 = Release|Any CPU + {76B43FBB-1DEA-4260-8802-7DC0015A916F}.Release|Any CPU.Deploy.0 = Release|Any CPU + {76B43FBB-1DEA-4260-8802-7DC0015A916F}.Release|ARM64.ActiveCfg = Release|Any CPU + {76B43FBB-1DEA-4260-8802-7DC0015A916F}.Release|ARM64.Build.0 = Release|Any CPU + {76B43FBB-1DEA-4260-8802-7DC0015A916F}.Release|ARM64.Deploy.0 = Release|Any CPU + {76B43FBB-1DEA-4260-8802-7DC0015A916F}.Release|x64.ActiveCfg = Release|Any CPU + {76B43FBB-1DEA-4260-8802-7DC0015A916F}.Release|x64.Build.0 = Release|Any CPU + {76B43FBB-1DEA-4260-8802-7DC0015A916F}.Release|x64.Deploy.0 = Release|Any CPU + {76B43FBB-1DEA-4260-8802-7DC0015A916F}.Release|x86.ActiveCfg = Release|Any CPU + {76B43FBB-1DEA-4260-8802-7DC0015A916F}.Release|x86.Build.0 = Release|Any CPU + {76B43FBB-1DEA-4260-8802-7DC0015A916F}.Release|x86.Deploy.0 = Release|Any CPU + {A63220BF-4101-4D60-A75D-CF2693646A6A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A63220BF-4101-4D60-A75D-CF2693646A6A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A63220BF-4101-4D60-A75D-CF2693646A6A}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {A63220BF-4101-4D60-A75D-CF2693646A6A}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {A63220BF-4101-4D60-A75D-CF2693646A6A}.Debug|ARM64.Build.0 = Debug|Any CPU + {A63220BF-4101-4D60-A75D-CF2693646A6A}.Debug|ARM64.Deploy.0 = Debug|Any CPU + {A63220BF-4101-4D60-A75D-CF2693646A6A}.Debug|x64.ActiveCfg = Debug|Any CPU + {A63220BF-4101-4D60-A75D-CF2693646A6A}.Debug|x64.Build.0 = Debug|Any CPU + {A63220BF-4101-4D60-A75D-CF2693646A6A}.Debug|x64.Deploy.0 = Debug|Any CPU + {A63220BF-4101-4D60-A75D-CF2693646A6A}.Debug|x86.ActiveCfg = Debug|Any CPU + {A63220BF-4101-4D60-A75D-CF2693646A6A}.Debug|x86.Build.0 = Debug|Any CPU + {A63220BF-4101-4D60-A75D-CF2693646A6A}.Debug|x86.Deploy.0 = Debug|Any CPU + {A63220BF-4101-4D60-A75D-CF2693646A6A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A63220BF-4101-4D60-A75D-CF2693646A6A}.Release|Any CPU.Build.0 = Release|Any CPU + {A63220BF-4101-4D60-A75D-CF2693646A6A}.Release|Any CPU.Deploy.0 = Release|Any CPU + {A63220BF-4101-4D60-A75D-CF2693646A6A}.Release|ARM64.ActiveCfg = Release|Any CPU + {A63220BF-4101-4D60-A75D-CF2693646A6A}.Release|ARM64.Build.0 = Release|Any CPU + {A63220BF-4101-4D60-A75D-CF2693646A6A}.Release|ARM64.Deploy.0 = Release|Any CPU + {A63220BF-4101-4D60-A75D-CF2693646A6A}.Release|x64.ActiveCfg = Release|Any CPU + {A63220BF-4101-4D60-A75D-CF2693646A6A}.Release|x64.Build.0 = Release|Any CPU + {A63220BF-4101-4D60-A75D-CF2693646A6A}.Release|x64.Deploy.0 = Release|Any CPU + {A63220BF-4101-4D60-A75D-CF2693646A6A}.Release|x86.ActiveCfg = Release|Any CPU + {A63220BF-4101-4D60-A75D-CF2693646A6A}.Release|x86.Build.0 = Release|Any CPU + {A63220BF-4101-4D60-A75D-CF2693646A6A}.Release|x86.Deploy.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {16ABD2C7-7D6E-4245-A09A-22B4756A0A80} + EndGlobalSection +EndGlobal diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo/App.xaml b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo/App.xaml new file mode 100644 index 000000000..4989854ea --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo/App.xaml @@ -0,0 +1,14 @@ + + + + + + + + + + + diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo/App.xaml.cs b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo/App.xaml.cs new file mode 100644 index 000000000..985a0ba19 --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo/App.xaml.cs @@ -0,0 +1,10 @@ +namespace NativeEmbeddingDemo +{ + public partial class App : Application + { + public App() + { + InitializeComponent(); + } + } +} diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo/MauiProgram.cs b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo/MauiProgram.cs new file mode 100644 index 000000000..833d00224 --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo/MauiProgram.cs @@ -0,0 +1,26 @@ +using Microsoft.Extensions.Logging; + +namespace NativeEmbeddingDemo +{ + public static class MauiProgram + { + public static MauiApp CreateMauiApp(Action? additional = null) + { + var builder = MauiApp.CreateBuilder(); + builder + .UseMauiApp() + .ConfigureFonts(fonts => + { + fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular"); + fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold"); + }); + +#if DEBUG + builder.Logging.AddDebug(); +#endif + additional?.Invoke(builder); + + return builder.Build(); + } + } +} diff --git a/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo/MyMauiContent.xaml b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo/MyMauiContent.xaml new file mode 100644 index 000000000..381bc013e --- /dev/null +++ b/8.0/PlatformIntegration/NativeEmbeddingDemo/NativeEmbeddingDemo/MyMauiContent.xaml @@ -0,0 +1,32 @@ + + + + + + + + + +