diff --git a/Avalonia.sln b/Avalonia.sln
index a6fdcbd421..241ba1383c 100644
--- a/Avalonia.sln
+++ b/Avalonia.sln
@@ -99,8 +99,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Skia.Desktop", "sr
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Skia.Android", "src\Skia\Avalonia.Skia.Android\Avalonia.Skia.Android.csproj", "{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Skia.Android.TestApp", "src\Skia\Avalonia.Skia.Android.TestApp\Avalonia.Skia.Android.TestApp.csproj", "{F92E55A5-ED73-4CCB-AB4B-0541B6757F31}"
-EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Skia.iOS.TestApp", "src\Skia\Avalonia.Skia.iOS.TestApp\Avalonia.Skia.iOS.TestApp.csproj", "{DA49C5F3-BE95-461C-B999-072128CCF59E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Skia.iOS", "src\Skia\Avalonia.Skia.iOS\Avalonia.Skia.iOS.csproj", "{47BE08A7-5985-410B-9FFC-2264B8EA595F}"
@@ -1469,38 +1467,6 @@ Global
{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298}.Release|Mono.ActiveCfg = Release|Any CPU
{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298}.Release|x86.ActiveCfg = Release|Any CPU
{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298}.Release|x86.Build.0 = Release|Any CPU
- {F92E55A5-ED73-4CCB-AB4B-0541B6757F31}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
- {F92E55A5-ED73-4CCB-AB4B-0541B6757F31}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
- {F92E55A5-ED73-4CCB-AB4B-0541B6757F31}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
- {F92E55A5-ED73-4CCB-AB4B-0541B6757F31}.Ad-Hoc|Mono.ActiveCfg = Debug|Any CPU
- {F92E55A5-ED73-4CCB-AB4B-0541B6757F31}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
- {F92E55A5-ED73-4CCB-AB4B-0541B6757F31}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
- {F92E55A5-ED73-4CCB-AB4B-0541B6757F31}.Ad-Hoc|x86.Deploy.0 = Debug|Any CPU
- {F92E55A5-ED73-4CCB-AB4B-0541B6757F31}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
- {F92E55A5-ED73-4CCB-AB4B-0541B6757F31}.AppStore|iPhone.ActiveCfg = Release|Any CPU
- {F92E55A5-ED73-4CCB-AB4B-0541B6757F31}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
- {F92E55A5-ED73-4CCB-AB4B-0541B6757F31}.AppStore|Mono.ActiveCfg = Debug|Any CPU
- {F92E55A5-ED73-4CCB-AB4B-0541B6757F31}.AppStore|x86.ActiveCfg = Debug|Any CPU
- {F92E55A5-ED73-4CCB-AB4B-0541B6757F31}.AppStore|x86.Build.0 = Debug|Any CPU
- {F92E55A5-ED73-4CCB-AB4B-0541B6757F31}.AppStore|x86.Deploy.0 = Debug|Any CPU
- {F92E55A5-ED73-4CCB-AB4B-0541B6757F31}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {F92E55A5-ED73-4CCB-AB4B-0541B6757F31}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {F92E55A5-ED73-4CCB-AB4B-0541B6757F31}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
- {F92E55A5-ED73-4CCB-AB4B-0541B6757F31}.Debug|iPhone.ActiveCfg = Debug|Any CPU
- {F92E55A5-ED73-4CCB-AB4B-0541B6757F31}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
- {F92E55A5-ED73-4CCB-AB4B-0541B6757F31}.Debug|Mono.ActiveCfg = Debug|Any CPU
- {F92E55A5-ED73-4CCB-AB4B-0541B6757F31}.Debug|x86.ActiveCfg = Debug|Any CPU
- {F92E55A5-ED73-4CCB-AB4B-0541B6757F31}.Debug|x86.Build.0 = Debug|Any CPU
- {F92E55A5-ED73-4CCB-AB4B-0541B6757F31}.Debug|x86.Deploy.0 = Debug|Any CPU
- {F92E55A5-ED73-4CCB-AB4B-0541B6757F31}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {F92E55A5-ED73-4CCB-AB4B-0541B6757F31}.Release|Any CPU.Build.0 = Release|Any CPU
- {F92E55A5-ED73-4CCB-AB4B-0541B6757F31}.Release|Any CPU.Deploy.0 = Release|Any CPU
- {F92E55A5-ED73-4CCB-AB4B-0541B6757F31}.Release|iPhone.ActiveCfg = Release|Any CPU
- {F92E55A5-ED73-4CCB-AB4B-0541B6757F31}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
- {F92E55A5-ED73-4CCB-AB4B-0541B6757F31}.Release|Mono.ActiveCfg = Release|Any CPU
- {F92E55A5-ED73-4CCB-AB4B-0541B6757F31}.Release|x86.ActiveCfg = Release|Any CPU
- {F92E55A5-ED73-4CCB-AB4B-0541B6757F31}.Release|x86.Build.0 = Release|Any CPU
- {F92E55A5-ED73-4CCB-AB4B-0541B6757F31}.Release|x86.Deploy.0 = Release|Any CPU
{DA49C5F3-BE95-461C-B999-072128CCF59E}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhone
{DA49C5F3-BE95-461C-B999-072128CCF59E}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone
{DA49C5F3-BE95-461C-B999-072128CCF59E}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone
@@ -2359,7 +2325,6 @@ Global
{2F59F3D0-748D-4652-B01E-E0D954756308} = {3743B0F2-CC41-4F14-A8C8-267F579BF91E}
{925DD807-B651-475F-9F7C-CBEB974CE43D} = {3743B0F2-CC41-4F14-A8C8-267F579BF91E}
{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298} = {3743B0F2-CC41-4F14-A8C8-267F579BF91E}
- {F92E55A5-ED73-4CCB-AB4B-0541B6757F31} = {3743B0F2-CC41-4F14-A8C8-267F579BF91E}
{DA49C5F3-BE95-461C-B999-072128CCF59E} = {3743B0F2-CC41-4F14-A8C8-267F579BF91E}
{47BE08A7-5985-410B-9FFC-2264B8EA595F} = {3743B0F2-CC41-4F14-A8C8-267F579BF91E}
{7B92AF71-6287-4693-9DCB-BD5B6E927E23} = {7CF9789C-F1D3-4D0E-90E5-F1DF67A2753F}
diff --git a/samples/ControlCatalog.Android/ControlCatalog.Android.csproj b/samples/ControlCatalog.Android/ControlCatalog.Android.csproj
index 5b39aa3dfb..fa29610b18 100644
--- a/samples/ControlCatalog.Android/ControlCatalog.Android.csproj
+++ b/samples/ControlCatalog.Android/ControlCatalog.Android.csproj
@@ -32,9 +32,12 @@
False
False
False
- armeabi,armeabi-v7a,x86
+ armeabi;armeabi-v7a;x86
Xamarin
False
+ False
+ False
+ False
pdbonly
diff --git a/samples/ControlCatalog.Android/MainActivity.cs b/samples/ControlCatalog.Android/MainActivity.cs
index 3f357b0e70..157609088f 100644
--- a/samples/ControlCatalog.Android/MainActivity.cs
+++ b/samples/ControlCatalog.Android/MainActivity.cs
@@ -1,9 +1,8 @@
using System;
using Android.App;
-
using Android.OS;
using Android.Content.PM;
-using Avalonia.Android.Platform.Specific;
+using Avalonia.Android;
using Avalonia.Controls;
using Avalonia.Controls.Templates;
using Avalonia.Markup.Xaml;
@@ -17,29 +16,16 @@ namespace ControlCatalog.Android
[Activity(Label = "ControlCatalog.Android", MainLauncher = true, Icon = "@drawable/icon", LaunchMode = LaunchMode.SingleInstance)]
public class MainActivity : AvaloniaActivity
{
- public MainActivity() : base(typeof (App))
- {
-
- }
-
protected override void OnCreate(Bundle savedInstanceState)
{
- base.OnCreate(savedInstanceState);
-
- App app;
- if (Avalonia.Application.Current != null)
- app = (App)Avalonia.Application.Current;
- else
+ if (Avalonia.Application.Current == null)
{
- app = new App();
- AppBuilder.Configure(app)
+ AppBuilder.Configure(new App())
.UseAndroid()
- .UseSkia()
.SetupWithoutStarting();
+ Content = new MainView();
}
-
- var mainWindow = new MainWindow();
- app.Run(mainWindow);
+ base.OnCreate(savedInstanceState);
}
}
}
diff --git a/src/Android/Avalonia.Android/AndroidPlatform.cs b/src/Android/Avalonia.Android/AndroidPlatform.cs
index afaa314e6c..5b3170a0c7 100644
--- a/src/Android/Avalonia.Android/AndroidPlatform.cs
+++ b/src/Android/Avalonia.Android/AndroidPlatform.cs
@@ -1,5 +1,8 @@
using System;
using System.IO;
+using System.Linq;
+using Android.Content;
+using Android.Views;
using Avalonia.Android.Platform;
using Avalonia.Android.Platform.Input;
using Avalonia.Android.Platform.SkiaPlatform;
@@ -8,6 +11,7 @@ using Avalonia.Controls.Platform;
using Avalonia.Input;
using Avalonia.Input.Platform;
using Avalonia.Platform;
+using Avalonia.Rendering;
using Avalonia.Shared.PlatformSupport;
using Avalonia.Skia;
@@ -17,7 +21,8 @@ namespace Avalonia
{
public static T UseAndroid(this T builder) where T : AppBuilderBase, new()
{
- builder.UseWindowingSubsystem(Android.AndroidPlatform.Initialize, "Android");
+ builder.UseWindowingSubsystem(() => Android.AndroidPlatform.Initialize(builder.Instance), "Android");
+ builder.UseSkia();
return builder;
}
}
@@ -25,7 +30,7 @@ namespace Avalonia
namespace Avalonia.Android
{
- public class AndroidPlatform : IPlatformSettings, IWindowingPlatform
+ class AndroidPlatform : IPlatformSettings, IWindowingPlatform
{
public static readonly AndroidPlatform Instance = new AndroidPlatform();
public Size DoubleClickSize => new Size(4, 4);
@@ -40,7 +45,7 @@ namespace Avalonia.Android
_scalingFactor = global::Android.App.Application.Context.Resources.DisplayMetrics.ScaledDensity;
}
- public static void Initialize()
+ public static void Initialize(Avalonia.Application app)
{
AvaloniaLocator.CurrentMutable
.Bind().ToTransient()
@@ -51,24 +56,22 @@ namespace Avalonia.Android
.Bind().ToConstant(new AndroidThreadingInterface())
.Bind().ToTransient()
.Bind().ToConstant(Instance)
- .Bind().ToSingleton();
+ .Bind().ToSingleton()
+ .Bind().ToConstant(new DefaultRenderLoop(60))
- SkiaPlatform.Initialize();
- }
+ .Bind().ToConstant(new AssetLoader(app.GetType().Assembly));
- public void Init(Type applicationType)
- {
- StandardRuntimePlatformServices.Register(applicationType.Assembly);
+ SkiaPlatform.Initialize();
}
public IWindowImpl CreateWindow()
{
- return new WindowImpl();
+ throw new NotSupportedException();
}
public IEmbeddableWindowImpl CreateEmbeddableWindow()
{
- throw new NotImplementedException();
+ throw new NotSupportedException();
}
public IPopupImpl CreatePopup()
diff --git a/src/Android/Avalonia.Android/AndroidThreadingInterface.cs b/src/Android/Avalonia.Android/AndroidThreadingInterface.cs
index b4059e3114..6327be12a5 100644
--- a/src/Android/Avalonia.Android/AndroidThreadingInterface.cs
+++ b/src/Android/Avalonia.Android/AndroidThreadingInterface.cs
@@ -51,10 +51,16 @@ namespace Avalonia.Android
scheduled = true;
EnsureInvokeOnMainThread(() =>
{
- tick();
- lock (l)
+ try
{
- scheduled = false;
+ tick();
+ }
+ finally
+ {
+ lock (l)
+ {
+ scheduled = false;
+ }
}
});
}
diff --git a/src/Android/Avalonia.Android/Avalonia.Android.csproj b/src/Android/Avalonia.Android/Avalonia.Android.csproj
index 654cb13678..0dfab3f518 100644
--- a/src/Android/Avalonia.Android/Avalonia.Android.csproj
+++ b/src/Android/Avalonia.Android/Avalonia.Android.csproj
@@ -63,16 +63,17 @@
+
+
-
-
+
+
+
-
-
diff --git a/src/Android/Avalonia.Android/AvaloniaActivity.cs b/src/Android/Avalonia.Android/AvaloniaActivity.cs
new file mode 100644
index 0000000000..a9b04c882b
--- /dev/null
+++ b/src/Android/Avalonia.Android/AvaloniaActivity.cs
@@ -0,0 +1,50 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+using Android.App;
+using Android.Content;
+using Android.OS;
+using Android.Runtime;
+using Android.Views;
+using Android.Widget;
+
+namespace Avalonia.Android
+{
+ public abstract class AvaloniaActivity : Activity
+ {
+ AvaloniaView _view;
+ object _content;
+
+ protected override void OnCreate(Bundle savedInstanceState)
+ {
+ RequestWindowFeature(WindowFeatures.NoTitle);
+ _view = new AvaloniaView(this);
+ if(_content != null)
+ _view.Content = _content;
+ SetContentView(_view);
+ TakeKeyEvents(true);
+ base.OnCreate(savedInstanceState);
+ }
+
+ public object Content
+ {
+ get
+ {
+ return _content;
+ }
+ set
+ {
+ _content = value;
+ if (_view != null)
+ _view.Content = value;
+ }
+ }
+
+ public override bool DispatchKeyEvent(KeyEvent e)
+ {
+ return _view.DispatchKeyEvent(e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Android/Avalonia.Android/AvaloniaView.cs b/src/Android/Avalonia.Android/AvaloniaView.cs
new file mode 100644
index 0000000000..71eea14a1d
--- /dev/null
+++ b/src/Android/Avalonia.Android/AvaloniaView.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+using Android.App;
+using Android.Content;
+using Android.OS;
+using Android.Runtime;
+using Android.Views;
+using Android.Widget;
+using Avalonia.Android.Platform.SkiaPlatform;
+using Avalonia.Controls.Embedding;
+using Avalonia.Platform;
+
+namespace Avalonia.Android
+{
+ public class AvaloniaView : FrameLayout
+ {
+ private readonly EmbeddableControlRoot _root;
+ private readonly ViewImpl _view;
+
+ public AvaloniaView(Context context) : base(context)
+ {
+ _view = new ViewImpl(context);
+ AddView(_view);
+ _root = new EmbeddableControlRoot(_view);
+ _root.Prepare();
+ }
+
+ public object Content
+ {
+ get { return _root.Content; }
+ set { _root.Content = value; }
+ }
+
+ public override bool DispatchKeyEvent(KeyEvent e)
+ {
+ return _view.DispatchKeyEvent(e);
+ }
+
+ class ViewImpl : TopLevelImpl, IEmbeddableWindowImpl
+ {
+ public event Action LostFocus;
+
+ public ViewImpl(Context context) : base(context)
+ {
+ Focusable = true;
+ FocusChange += ViewImpl_FocusChange;
+ }
+
+ private void ViewImpl_FocusChange(object sender, FocusChangeEventArgs e)
+ {
+ if(!e.HasFocus)
+ LostFocus?.Invoke();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Android/Avalonia.Android/Platform/SkiaPlatform/AndroidFramebuffer.cs b/src/Android/Avalonia.Android/Platform/SkiaPlatform/AndroidFramebuffer.cs
new file mode 100644
index 0000000000..982c79560b
--- /dev/null
+++ b/src/Android/Avalonia.Android/Platform/SkiaPlatform/AndroidFramebuffer.cs
@@ -0,0 +1,101 @@
+using System;
+using System.Runtime.InteropServices;
+using Android.Runtime;
+using Android.Views;
+using Avalonia.Controls.Platform.Surfaces;
+
+namespace Avalonia.Android.Platform.SkiaPlatform
+{
+ class AndroidFramebuffer : ILockedFramebuffer
+ {
+ private IntPtr _window;
+
+ public AndroidFramebuffer(Surface surface)
+ {
+ _window = ANativeWindow_fromSurface(JNIEnv.Handle, surface.Handle);
+ ANativeWindow_Buffer buffer;
+ var rc = new ARect()
+ {
+ right = Width = ANativeWindow_getWidth(_window),
+ bottom = Height = ANativeWindow_getHeight(_window)
+ };
+ ANativeWindow_lock(_window, out buffer, ref rc);
+
+ Format = buffer.format == AndroidPixelFormat.WINDOW_FORMAT_RGB_565
+ ? PixelFormat.Rgb565 : PixelFormat.Rgba8888;
+
+ RowBytes = buffer.stride * (Format == PixelFormat.Rgb565 ? 2 : 4);
+ Address = buffer.bits;
+ }
+
+ public void Dispose()
+ {
+ ANativeWindow_unlockAndPost(_window);
+ ANativeWindow_release(_window);
+ _window = IntPtr.Zero;
+ Address = IntPtr.Zero;
+ }
+
+ public IntPtr Address { get; set; }
+ public int Width { get; }
+ public int Height { get; }
+ public int RowBytes { get; }
+ public Size Dpi { get; } = new Size(96, 96);
+ public PixelFormat Format { get; }
+
+ [DllImport("android")]
+ internal static extern IntPtr ANativeWindow_fromSurface(IntPtr jniEnv, IntPtr handle);
+ [DllImport("android")]
+ internal static extern int ANativeWindow_getWidth(IntPtr window);
+ [DllImport("android")]
+ internal static extern int ANativeWindow_getHeight(IntPtr window);
+ [DllImport("android")]
+ internal static extern void ANativeWindow_release(IntPtr window);
+ [DllImport("android")]
+ internal static extern void ANativeWindow_unlockAndPost(IntPtr window);
+
+ [DllImport("android")]
+ internal static extern int ANativeWindow_lock(IntPtr window, out ANativeWindow_Buffer outBuffer, ref ARect inOutDirtyBounds);
+ public enum AndroidPixelFormat
+ {
+ WINDOW_FORMAT_RGBA_8888 = 1,
+ WINDOW_FORMAT_RGBX_8888 = 2,
+ WINDOW_FORMAT_RGB_565 = 4,
+ }
+
+ internal struct ARect
+ {
+ public int left;
+ public int top;
+ public int right;
+ public int bottom;
+ }
+
+ internal struct ANativeWindow_Buffer
+ {
+ // The number of pixels that are show horizontally.
+ public int width;
+
+ // The number of pixels that are shown vertically.
+ public int height;
+
+ // The number of *pixels* that a line in the buffer takes in
+ // memory. This may be >= width.
+ public int stride;
+
+ // The format of the buffer. One of WINDOW_FORMAT_*
+ public AndroidPixelFormat format;
+
+ // The actual bits.
+ public IntPtr bits;
+
+ // Do not touch.
+ uint reserved1;
+ uint reserved2;
+ uint reserved3;
+ uint reserved4;
+ uint reserved5;
+ uint reserved6;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Skia/Avalonia.Skia.Android/SkiaView.cs b/src/Android/Avalonia.Android/Platform/SkiaPlatform/InvalidationAwareSurfaceView.cs
similarity index 88%
rename from src/Skia/Avalonia.Skia.Android/SkiaView.cs
rename to src/Android/Avalonia.Android/Platform/SkiaPlatform/InvalidationAwareSurfaceView.cs
index a45a80cf18..2213ebddcc 100644
--- a/src/Skia/Avalonia.Skia.Android/SkiaView.cs
+++ b/src/Android/Avalonia.Android/Platform/SkiaPlatform/InvalidationAwareSurfaceView.cs
@@ -14,16 +14,16 @@ using Android.Widget;
using Avalonia.Media;
using Avalonia.Platform;
-namespace Avalonia.Skia.Android
+namespace Avalonia.Android
{
- public abstract class SkiaView : SurfaceView, ISurfaceHolderCallback, IPlatformHandle
+ public abstract class InvalidationAwareSurfaceView : SurfaceView, ISurfaceHolderCallback, IPlatformHandle
{
- private readonly Activity _context;
+ private readonly Context _context;
bool _invalidateQueued;
readonly object _lock = new object();
private readonly Handler _handler;
- public SkiaView(Activity context) : base(context)
+ public InvalidationAwareSurfaceView(Context context) : base(context)
{
_context = context;
Holder.AddCallback(this);
diff --git a/src/Android/Avalonia.Android/Platform/SkiaPlatform/MainWindowImpl.cs b/src/Android/Avalonia.Android/Platform/SkiaPlatform/MainWindowImpl.cs
deleted file mode 100644
index 690c509b53..0000000000
--- a/src/Android/Avalonia.Android/Platform/SkiaPlatform/MainWindowImpl.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-using Android.Views;
-using Avalonia.Android.Platform.Specific;
-using Avalonia.Controls;
-using Avalonia.Input;
-using Avalonia.Platform;
-
-namespace Avalonia.Android.Platform.SkiaPlatform
-{
- public class MainWindowImpl :
- WindowImpl
- , IWindowImpl
- {
- public MainWindowImpl()
- {
- }
-
- public new WindowState WindowState
- {
- get { return WindowState.Normal; }
- set { }
- }
-
- protected override void Init()
- {
- base.Init();
-
- HandleEvents = true;
- _keyboardHelper.ActivateAutoShowKeybord();
- }
-
- void ITopLevelImpl.Show()
- {
- (Parent as ViewGroup)?.RemoveAllViews();
- AvaloniaLocator.Current.GetService().ContentView = this;
- //this.Visibility = ViewStates.Visible;
- }
-
- void ITopLevelImpl.SetInputRoot(IInputRoot inputRoot)
- {
- base.SetInputRoot(inputRoot);
- _keyboardHelper.UpdateKeyboardState(inputRoot);
- }
- }
-}
\ No newline at end of file
diff --git a/src/Android/Avalonia.Android/Platform/SkiaPlatform/WindowImpl.cs b/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs
similarity index 85%
rename from src/Android/Avalonia.Android/Platform/SkiaPlatform/WindowImpl.cs
rename to src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs
index 17b1cfba0a..26d2b0aad9 100644
--- a/src/Android/Avalonia.Android/Platform/SkiaPlatform/WindowImpl.cs
+++ b/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs
@@ -7,32 +7,30 @@ using Avalonia.Android.Platform.Specific.Helpers;
using Avalonia.Input;
using Avalonia.Input.Raw;
using Avalonia.Platform;
-using Avalonia.Skia.Android;
using System;
using System.Collections.Generic;
using Avalonia.Controls;
+using Avalonia.Controls.Platform.Surfaces;
namespace Avalonia.Android.Platform.SkiaPlatform
{
- public class WindowImpl : SkiaView, IAndroidView, IWindowImpl, ISurfaceHolderCallback
+ class TopLevelImpl : InvalidationAwareSurfaceView, IAndroidView, ITopLevelImpl,
+ ISurfaceHolderCallback, IFramebufferPlatformSurface
+
{
- protected AndroidKeyboardEventsHelper _keyboardHelper;
+ protected AndroidKeyboardEventsHelper _keyboardHelper;
- private AndroidTouchEventsHelper _touchHelper;
+ private AndroidTouchEventsHelper _touchHelper;
- public WindowImpl(Context context) : base((Activity)context)
+ public TopLevelImpl(Context context) : base(context)
{
- _keyboardHelper = new AndroidKeyboardEventsHelper(this);
- _touchHelper = new AndroidTouchEventsHelper(this, () => InputRoot, p => GetAvaloniaPointFromEvent(p));
+ _keyboardHelper = new AndroidKeyboardEventsHelper(this);
+ _touchHelper = new AndroidTouchEventsHelper(this, () => InputRoot, p => GetAvaloniaPointFromEvent(p));
MaxClientSize = new Size(Resources.DisplayMetrics.WidthPixels, Resources.DisplayMetrics.HeightPixels);
ClientSize = MaxClientSize;
- Init();
- }
-
- public WindowImpl() : this(AvaloniaLocator.Current.GetService().Activity)
- {
}
+
void ISurfaceHolderCallback.SurfaceChanged(ISurfaceHolder holder, Format format, int width, int height)
{
@@ -46,11 +44,7 @@ namespace Avalonia.Android.Platform.SkiaPlatform
base.SurfaceChanged(holder, format, width, height);
}
-
- protected virtual void Init()
- {
- }
-
+
private bool _handleEvents;
public bool HandleEvents
@@ -191,5 +185,7 @@ namespace Avalonia.Android.Platform.SkiaPlatform
{
// No window icons for mobile platforms
}
- }
+
+ ILockedFramebuffer IFramebufferPlatformSurface.Lock()=>new AndroidFramebuffer(Holder.Surface);
+ }
}
\ No newline at end of file
diff --git a/src/Android/Avalonia.Android/Platform/Specific/AvaloniaActivity.cs b/src/Android/Avalonia.Android/Platform/Specific/AvaloniaActivity.cs
deleted file mode 100644
index 4ccff10455..0000000000
--- a/src/Android/Avalonia.Android/Platform/Specific/AvaloniaActivity.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-using System;
-using Android.App;
-using Android.OS;
-using Android.Views;
-using Android.Widget;
-
-namespace Avalonia.Android.Platform.Specific
-{
- public class AvaloniaActivity : Activity, IAndroidActivity
- {
- private IAndroidView _contentView;
-
- public AvaloniaActivity(Type applicationType)
- {
- AndroidPlatform.Instance.Init(applicationType);
- }
-
- public Activity Activity => this;
-
- public IAndroidView ContentView
- {
- get
- {
- return this._contentView;
- }
-
- set
- {
- this._contentView = value;
- var fl = new FrameLayout(this);
- fl.AddView(this._contentView.View);
- //this.SetContentView(value.View);
- this.SetContentView(fl);
- }
- }
-
- protected override void OnCreate(Bundle savedInstanceState)
- {
- AvaloniaLocator.CurrentMutable.Bind().ToConstant(this);
- RequestWindowFeature(WindowFeatures.NoTitle);
- base.OnCreate(savedInstanceState);
- }
-
- public override void SetContentView(View view)
- {
- base.SetContentView(view);
- TakeKeyEvents(true);
- }
-
- public override bool DispatchKeyEvent(KeyEvent e)
- {
- if (_contentView != null)
- {
- _contentView.View.DispatchKeyEvent(e);
- }
-
- return base.DispatchKeyEvent(e);
- }
- }
-}
\ No newline at end of file
diff --git a/src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidKeyboardEventsHelper.cs b/src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidKeyboardEventsHelper.cs
index 17e1f62e8c..7bac0ff814 100644
--- a/src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidKeyboardEventsHelper.cs
+++ b/src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidKeyboardEventsHelper.cs
@@ -12,7 +12,7 @@ using System.ComponentModel;
namespace Avalonia.Android.Platform.Specific.Helpers
{
- public class AndroidKeyboardEventsHelper : IDisposable where TView : View, IWindowImpl, IAndroidView
+ public class AndroidKeyboardEventsHelper : IDisposable where TView : View, ITopLevelImpl, IAndroidView
{
private TView _view;
private IInputElement _lastFocusedElement;
diff --git a/src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidTouchEventsHelper.cs b/src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidTouchEventsHelper.cs
index c6d1833d2d..a448044ee6 100644
--- a/src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidTouchEventsHelper.cs
+++ b/src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidTouchEventsHelper.cs
@@ -8,7 +8,7 @@ using System;
namespace Avalonia.Android.Platform.Specific.Helpers
{
- public class AndroidTouchEventsHelper : IDisposable where TView : View, IWindowImpl, IAndroidView
+ public class AndroidTouchEventsHelper : IDisposable where TView : View, ITopLevelImpl, IAndroidView
{
private TView _view;
public bool HandleEvents { get; set; }
diff --git a/src/Android/Avalonia.Android/Platform/Specific/IAndroidActivity.cs b/src/Android/Avalonia.Android/Platform/Specific/IAndroidActivity.cs
deleted file mode 100644
index b2a999d4be..0000000000
--- a/src/Android/Avalonia.Android/Platform/Specific/IAndroidActivity.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using Android.App;
-using Android.Views;
-
-namespace Avalonia.Android.Platform.Specific
-{
- public interface IAndroidActivity
- {
- Activity Activity { get; }
-
- IAndroidView ContentView { get; set; }
- }
-}
\ No newline at end of file
diff --git a/src/Android/Avalonia.AndroidTestApplication/Avalonia.AndroidTestApplication.csproj b/src/Android/Avalonia.AndroidTestApplication/Avalonia.AndroidTestApplication.csproj
index e004121323..ebe268adcf 100644
--- a/src/Android/Avalonia.AndroidTestApplication/Avalonia.AndroidTestApplication.csproj
+++ b/src/Android/Avalonia.AndroidTestApplication/Avalonia.AndroidTestApplication.csproj
@@ -20,7 +20,7 @@
Properties\AndroidManifest.xml
- true
+ True
full
false
bin\Debug\
@@ -29,16 +29,16 @@
4
True
None
-
- False
+ True
False
False
- armeabi,armeabi-v7a,x86
-
-
+ armeabi;armeabi-v7a;x86
Xamarin
False
True
+ False
+ False
+ False
pdbonly
diff --git a/src/Android/Avalonia.AndroidTestApplication/MainActivity.cs b/src/Android/Avalonia.AndroidTestApplication/MainActivity.cs
index ff27e12f6e..7973ad72e5 100644
--- a/src/Android/Avalonia.AndroidTestApplication/MainActivity.cs
+++ b/src/Android/Avalonia.AndroidTestApplication/MainActivity.cs
@@ -2,7 +2,7 @@ using System;
using Android.App;
using Android.Content.PM;
using Android.OS;
-using Avalonia.Android.Platform.Specific;
+using Avalonia.Android;
using Avalonia.Controls;
using Avalonia.Controls.Templates;
using Avalonia.Markup.Xaml;
@@ -17,36 +17,24 @@ namespace Avalonia.AndroidTestApplication
Icon = "@drawable/icon",
LaunchMode = LaunchMode.SingleInstance/*,
ScreenOrientation = ScreenOrientation.Landscape*/)]
- public class MainBaseActivity : AvaloniaActivity
+ public class MainBaseActivity : Activity
{
- public MainBaseActivity() : base(typeof (App))
- {
-
- }
-
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
-
- App app;
- if (Avalonia.Application.Current != null)
- app = (App)Avalonia.Application.Current;
- else
+ if (Avalonia.Application.Current == null)
{
- app = new App();
- AppBuilder.Configure(app)
+ AppBuilder.Configure()
.UseAndroid()
- .UseSkia()
.SetupWithoutStarting();
}
-
- app.Run();
+ SetContentView(new AvaloniaView(this) { Content = App.CreateSimpleWindow() });
}
}
public class App : Application
{
- public void Run()
+ public override void Initialize()
{
Styles.Add(new DefaultTheme());
@@ -55,18 +43,14 @@ namespace Avalonia.AndroidTestApplication
new Uri("resm:Avalonia.Themes.Default.Accents.BaseLight.xaml?assembly=Avalonia.Themes.Default"));
Styles.Add(baseLight);
- var wnd = App.CreateSimpleWindow();
- wnd.AttachDevTools();
- Run(wnd);
}
// This provides a simple UI tree for testing input handling, drawing, etc
- public static Window CreateSimpleWindow()
+ public static ContentControl CreateSimpleWindow()
{
- Window window = new Window
+ ContentControl window = new ContentControl()
{
- Title = "Avalonia Test Application",
Background = Brushes.Red,
Content = new StackPanel
{
diff --git a/src/Skia/Avalonia.Skia.Android.TestApp/App.cs b/src/Skia/Avalonia.Skia.Android.TestApp/App.cs
deleted file mode 100644
index ca4d36b820..0000000000
--- a/src/Skia/Avalonia.Skia.Android.TestApp/App.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-
-namespace Avalonia.Skia.Android.TestApp
-{
- public class App : Application
- {
- }
-}
diff --git a/src/Skia/Avalonia.Skia.Android.TestApp/Avalonia.Skia.Android.TestApp.csproj b/src/Skia/Avalonia.Skia.Android.TestApp/Avalonia.Skia.Android.TestApp.csproj
deleted file mode 100644
index 041c8d9ecb..0000000000
--- a/src/Skia/Avalonia.Skia.Android.TestApp/Avalonia.Skia.Android.TestApp.csproj
+++ /dev/null
@@ -1,138 +0,0 @@
-
-
-
- Debug
- AnyCPU
- 8.0.30703
- 2.0
- {F92E55A5-ED73-4CCB-AB4B-0541B6757F31}
- {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- Library
- Properties
- Avalonia.Skia.Android.TestApp
- Avalonia.Skia.Android.TestApp
- 512
- true
- Resources\Resource.Designer.cs
- Off
- False
- v4.4
- Properties\AndroidManifest.xml
-
-
- True
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
- True
- None
- False
- False
- False
- armeabi;armeabi-v7a;x86
- Xamarin
- False
- True
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
- False
- Full
- True
- False
- False
- Xamarin
- False
- False
- False
- False
- False
- armeabi;armeabi-v7a;x86
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {7b92af71-6287-4693-9dcb-bd5b6e927e23}
- Avalonia.Android
-
-
- {d211e587-d8bc-45b9-95a4-f297c8fa5200}
- Avalonia.Animation
-
-
- {b09b78d8-9b26-48b0-9149-d64a2f120f3f}
- Avalonia.Base
-
-
- {d2221c82-4a25-4583-9b43-d791e3f6820c}
- Avalonia.Controls
-
-
- {4a1abb09-9047-4bd5-a4ad-a055e52c5ee0}
- Avalonia.DotNetFrameworkRuntime
-
-
- {62024b2d-53eb-4638-b26b-85eeaa54866e}
- Avalonia.Input
-
-
- {6b0ed19d-a08b-461c-a9d9-a9ee40b0c06b}
- Avalonia.Interactivity
-
-
- {42472427-4774-4c81-8aff-9f27b8e31721}
- Avalonia.Layout
-
-
- {eb582467-6abb-43a1-b052-e981ba910e3a}
- Avalonia.Visuals
-
-
- {f1baa01a-f176-4c6a-b39d-5b40bb1b148f}
- Avalonia.Styling
-
-
- {bd43f7c0-396b-4aa1-bad9-dfde54d51298}
- Avalonia.Skia.Android
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/Skia/Avalonia.Skia.Android.TestApp/Avalonia.Skia.Android.TestApp.v2.ncrunchproject b/src/Skia/Avalonia.Skia.Android.TestApp/Avalonia.Skia.Android.TestApp.v2.ncrunchproject
deleted file mode 100644
index e1b4d7cf28..0000000000
--- a/src/Skia/Avalonia.Skia.Android.TestApp/Avalonia.Skia.Android.TestApp.v2.ncrunchproject
+++ /dev/null
@@ -1,26 +0,0 @@
-
- true
- 1000
- false
- false
- false
- true
- false
- false
- true
- false
- false
- false
- true
- false
- true
- true
- true
- 60000
-
-
-
- AutoDetect
- STA
- x86
-
\ No newline at end of file
diff --git a/src/Skia/Avalonia.Skia.Android.TestApp/MainActivity.cs b/src/Skia/Avalonia.Skia.Android.TestApp/MainActivity.cs
deleted file mode 100644
index 9ac833a559..0000000000
--- a/src/Skia/Avalonia.Skia.Android.TestApp/MainActivity.cs
+++ /dev/null
@@ -1,78 +0,0 @@
-using Android.App;
-using Android.OS;
-using Android.Views;
-using Avalonia;
-using Avalonia.Controls;
-using Avalonia.Media;
-
-namespace Avalonia.Skia.Android.TestApp
-{
- [Activity(Label = "Avalonia.Skia.Android.TestApp", MainLauncher = true, Icon = "@drawable/icon")]
- public class MainActivity : Activity
- {
-
- protected override void OnCreate(Bundle bundle)
- {
- base.OnCreate(bundle);
-
- App app;
- if (Avalonia.Application.Current != null)
- app = (App)Avalonia.Application.Current;
- else
- {
- app = new App();
- AppBuilder.Configure(app)
- .UseAndroid()
- .UseSkia()
- .SetupWithoutStarting();
- }
-
- SetContentView(new MainView(this));
- }
-
- class MainView : SkiaRenderView
- {
- float _radians = 0;
- public MainView(Activity context) : base(context)
- {
- }
-
- protected override void OnRender(DrawingContext ctx)
- {
- ctx.FillRectangle(Brushes.Green, new Rect(0, 0, Width, Height));
-
- var rc = new Rect(0, 0, Width/3, Height/3);
- using (ctx.PushPostTransform(
- Avalonia.Matrix.CreateTranslation(-Width/6, -Width/6)*
- Avalonia.Matrix.CreateRotation(_radians)*
- Avalonia.Matrix.CreateTranslation(Width/2, Height/2)))
- {
- ctx.FillRectangle(new LinearGradientBrush()
- {
- GradientStops =
- {
- new GradientStop() {Color = Colors.Blue},
- new GradientStop(Colors.Red, 1)
- }
- }, rc, 5);
- }
-
-
- }
-
- public override bool OnTouchEvent(MotionEvent e)
- {
- if (e.Action == MotionEventActions.Down)
- return true;
- if (e.Action == MotionEventActions.Move)
- {
- _radians = (e.RawY + e.RawY)/100;
- Invalidate();
- return true;
- }
- return base.OnTouchEvent(e);
- }
- }
- }
-}
-
diff --git a/src/Skia/Avalonia.Skia.Android.TestApp/Properties/AndroidManifest.xml b/src/Skia/Avalonia.Skia.Android.TestApp/Properties/AndroidManifest.xml
deleted file mode 100644
index 5af8811830..0000000000
--- a/src/Skia/Avalonia.Skia.Android.TestApp/Properties/AndroidManifest.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/src/Skia/Avalonia.Skia.Android.TestApp/Properties/AssemblyInfo.cs b/src/Skia/Avalonia.Skia.Android.TestApp/Properties/AssemblyInfo.cs
deleted file mode 100644
index 68efca2668..0000000000
--- a/src/Skia/Avalonia.Skia.Android.TestApp/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using Android.App;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("Avalonia.Skia.Android.TestApp")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("Avalonia.Skia.Android.TestApp")]
-[assembly: AssemblyCopyright("Copyright © 2015")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-[assembly: ComVisible(false)]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/Skia/Avalonia.Skia.Android.TestApp/Resources/Resource.Designer.cs b/src/Skia/Avalonia.Skia.Android.TestApp/Resources/Resource.Designer.cs
deleted file mode 100644
index 7d9036603f..0000000000
--- a/src/Skia/Avalonia.Skia.Android.TestApp/Resources/Resource.Designer.cs
+++ /dev/null
@@ -1,114 +0,0 @@
-#pragma warning disable 1591
-//------------------------------------------------------------------------------
-//
-// This code was generated by a tool.
-// Runtime Version:4.0.30319.42000
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-//
-//------------------------------------------------------------------------------
-
-[assembly: global::Android.Runtime.ResourceDesignerAttribute("Avalonia.Skia.Android.TestApp.Resource", IsApplication=true)]
-
-namespace Avalonia.Skia.Android.TestApp
-{
-
-
- [System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "1.0.0.0")]
- public partial class Resource
- {
-
- static Resource()
- {
- global::Android.Runtime.ResourceIdManager.UpdateIdValues();
- }
-
- public static void UpdateIdValues()
- {
- global::Avalonia.Android.Resource.String.ApplicationName = global::Avalonia.Skia.Android.TestApp.Resource.String.ApplicationName;
- global::Avalonia.Android.Resource.String.Hello = global::Avalonia.Skia.Android.TestApp.Resource.String.Hello;
- }
-
- public partial class Attribute
- {
-
- static Attribute()
- {
- global::Android.Runtime.ResourceIdManager.UpdateIdValues();
- }
-
- private Attribute()
- {
- }
- }
-
- public partial class Drawable
- {
-
- // aapt resource value: 0x7f020000
- public const int Icon = 2130837504;
-
- static Drawable()
- {
- global::Android.Runtime.ResourceIdManager.UpdateIdValues();
- }
-
- private Drawable()
- {
- }
- }
-
- public partial class Id
- {
-
- // aapt resource value: 0x7f050000
- public const int MyButton = 2131034112;
-
- static Id()
- {
- global::Android.Runtime.ResourceIdManager.UpdateIdValues();
- }
-
- private Id()
- {
- }
- }
-
- public partial class Layout
- {
-
- // aapt resource value: 0x7f030000
- public const int Main = 2130903040;
-
- static Layout()
- {
- global::Android.Runtime.ResourceIdManager.UpdateIdValues();
- }
-
- private Layout()
- {
- }
- }
-
- public partial class String
- {
-
- // aapt resource value: 0x7f040001
- public const int ApplicationName = 2130968577;
-
- // aapt resource value: 0x7f040000
- public const int Hello = 2130968576;
-
- static String()
- {
- global::Android.Runtime.ResourceIdManager.UpdateIdValues();
- }
-
- private String()
- {
- }
- }
- }
-}
-#pragma warning restore 1591
diff --git a/src/Skia/Avalonia.Skia.Android.TestApp/Resources/drawable/Icon.png b/src/Skia/Avalonia.Skia.Android.TestApp/Resources/drawable/Icon.png
deleted file mode 100644
index 8074c4c571..0000000000
Binary files a/src/Skia/Avalonia.Skia.Android.TestApp/Resources/drawable/Icon.png and /dev/null differ
diff --git a/src/Skia/Avalonia.Skia.Android.TestApp/Resources/layout/Main.axml b/src/Skia/Avalonia.Skia.Android.TestApp/Resources/layout/Main.axml
deleted file mode 100644
index 98be1643ef..0000000000
--- a/src/Skia/Avalonia.Skia.Android.TestApp/Resources/layout/Main.axml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
diff --git a/src/Skia/Avalonia.Skia.Android.TestApp/Resources/values/Strings.xml b/src/Skia/Avalonia.Skia.Android.TestApp/Resources/values/Strings.xml
deleted file mode 100644
index 911585a36d..0000000000
--- a/src/Skia/Avalonia.Skia.Android.TestApp/Resources/values/Strings.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
- Hello World, Click Me!
- Avalonia.Skia.Android.TestApp
-
diff --git a/src/Skia/Avalonia.Skia.Android/AndroidPlatformRenderInterface.cs b/src/Skia/Avalonia.Skia.Android/AndroidPlatformRenderInterface.cs
index 3355839314..be02111cbd 100644
--- a/src/Skia/Avalonia.Skia.Android/AndroidPlatformRenderInterface.cs
+++ b/src/Skia/Avalonia.Skia.Android/AndroidPlatformRenderInterface.cs
@@ -9,6 +9,7 @@ using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
+using Avalonia.Controls.Platform.Surfaces;
using Avalonia.Platform;
namespace Avalonia.Skia
@@ -17,10 +18,10 @@ namespace Avalonia.Skia
{
public IRenderTarget CreateRenderTarget(IEnumerable