53 changed files with 425 additions and 1033 deletions
@ -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); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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<IAndroidActivity>().ContentView = this; |
|
||||
//this.Visibility = ViewStates.Visible;
|
|
||||
} |
|
||||
|
|
||||
void ITopLevelImpl.SetInputRoot(IInputRoot inputRoot) |
|
||||
{ |
|
||||
base.SetInputRoot(inputRoot); |
|
||||
_keyboardHelper.UpdateKeyboardState(inputRoot); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -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<IAndroidActivity>().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); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -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; } |
|
||||
} |
|
||||
} |
|
||||
@ -1,58 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Linq; |
|
||||
using System.Text; |
|
||||
using System.Threading.Tasks; |
|
||||
using Avalonia.Controls.Platform.Surfaces; |
|
||||
using Avalonia.Platform; |
|
||||
using Gdk; |
|
||||
|
|
||||
namespace Avalonia.Gtk |
|
||||
{ |
|
||||
class PixbufFramebuffer : ILockedFramebuffer |
|
||||
{ |
|
||||
private Pixbuf _pixbuf; |
|
||||
private Drawable _drawable; |
|
||||
|
|
||||
public PixbufFramebuffer(int width, int height) |
|
||||
{ |
|
||||
_pixbuf = new Pixbuf(Gdk.Colorspace.Rgb, false, 8, width, height); |
|
||||
} |
|
||||
|
|
||||
public void SetDrawable(Drawable drawable) |
|
||||
{ |
|
||||
_drawable = drawable; |
|
||||
} |
|
||||
|
|
||||
public void Deallocate() |
|
||||
{ |
|
||||
_pixbuf.Dispose(); |
|
||||
_pixbuf = null; |
|
||||
} |
|
||||
|
|
||||
public void Dispose() |
|
||||
{ |
|
||||
using (var gc = new Gdk.GC(_drawable)) |
|
||||
_drawable.DrawPixbuf(gc, _pixbuf, 0, 0, 0, 0, Width, Height, RgbDither.None, 0, 0); |
|
||||
_drawable = null; |
|
||||
} |
|
||||
|
|
||||
public IntPtr Address => _pixbuf.Pixels; |
|
||||
public int Width => _pixbuf.Width; |
|
||||
public int Height => _pixbuf.Height; |
|
||||
public int RowBytes => _pixbuf.Rowstride; |
|
||||
//TODO: Proper DPI detect
|
|
||||
public Size Dpi => new Size(96, 96); |
|
||||
public PixelFormat Format |
|
||||
{ |
|
||||
get |
|
||||
{ |
|
||||
if (AvaloniaLocator.Current.GetService<IRuntimePlatform>().GetRuntimeInfo().OperatingSystem == |
|
||||
OperatingSystemType.WinNT) |
|
||||
return PixelFormat.Bgra8888; |
|
||||
return PixelFormat.Rgba8888; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
@ -0,0 +1,55 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Text; |
||||
|
using System.Threading.Tasks; |
||||
|
using Avalonia.Controls.Platform.Surfaces; |
||||
|
using Avalonia.Platform; |
||||
|
using Cairo; |
||||
|
using Gdk; |
||||
|
|
||||
|
namespace Avalonia.Gtk |
||||
|
{ |
||||
|
class SurfaceFramebuffer : ILockedFramebuffer |
||||
|
{ |
||||
|
private Drawable _drawable; |
||||
|
private ImageSurface _surface; |
||||
|
|
||||
|
public SurfaceFramebuffer(int width, int height) |
||||
|
{ |
||||
|
_surface = new ImageSurface(Cairo.Format.RGB24, width, height); |
||||
|
} |
||||
|
|
||||
|
public void SetDrawable(Drawable drawable) |
||||
|
{ |
||||
|
_drawable = drawable; |
||||
|
_surface.Flush(); |
||||
|
} |
||||
|
|
||||
|
public void Deallocate() |
||||
|
{ |
||||
|
_surface.Dispose(); |
||||
|
_surface = null; |
||||
|
} |
||||
|
|
||||
|
public void Dispose() |
||||
|
{ |
||||
|
using (var ctx = CairoHelper.Create(_drawable)) |
||||
|
{ |
||||
|
_surface.MarkDirty(); |
||||
|
ctx.SetSourceSurface(_surface, 0, 0); |
||||
|
ctx.Paint(); |
||||
|
} |
||||
|
_drawable = null; |
||||
|
} |
||||
|
|
||||
|
public IntPtr Address => _surface.DataPtr; |
||||
|
public int Width => _surface.Width; |
||||
|
public int Height => _surface.Height; |
||||
|
public int RowBytes => _surface.Stride; |
||||
|
//TODO: Proper DPI detect
|
||||
|
public Size Dpi => new Size(96, 96); |
||||
|
public PixelFormat Format => PixelFormat.Bgra8888; |
||||
|
} |
||||
|
} |
||||
|
|
||||
@ -1,7 +0,0 @@ |
|||||
|
|
||||
namespace Avalonia.Skia.Android.TestApp |
|
||||
{ |
|
||||
public class App : Application |
|
||||
{ |
|
||||
} |
|
||||
} |
|
||||
@ -1,138 +0,0 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|
||||
<PropertyGroup> |
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
|
||||
<ProductVersion>8.0.30703</ProductVersion> |
|
||||
<SchemaVersion>2.0</SchemaVersion> |
|
||||
<ProjectGuid>{F92E55A5-ED73-4CCB-AB4B-0541B6757F31}</ProjectGuid> |
|
||||
<ProjectTypeGuids>{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> |
|
||||
<OutputType>Library</OutputType> |
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder> |
|
||||
<RootNamespace>Avalonia.Skia.Android.TestApp</RootNamespace> |
|
||||
<AssemblyName>Avalonia.Skia.Android.TestApp</AssemblyName> |
|
||||
<FileAlignment>512</FileAlignment> |
|
||||
<AndroidApplication>true</AndroidApplication> |
|
||||
<AndroidResgenFile>Resources\Resource.Designer.cs</AndroidResgenFile> |
|
||||
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies> |
|
||||
<AndroidUseLatestPlatformSdk>False</AndroidUseLatestPlatformSdk> |
|
||||
<TargetFrameworkVersion>v4.4</TargetFrameworkVersion> |
|
||||
<AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest> |
|
||||
</PropertyGroup> |
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> |
|
||||
<DebugSymbols>True</DebugSymbols> |
|
||||
<DebugType>full</DebugType> |
|
||||
<Optimize>false</Optimize> |
|
||||
<OutputPath>bin\Debug\</OutputPath> |
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants> |
|
||||
<ErrorReport>prompt</ErrorReport> |
|
||||
<WarningLevel>4</WarningLevel> |
|
||||
<AndroidUseSharedRuntime>True</AndroidUseSharedRuntime> |
|
||||
<AndroidLinkMode>None</AndroidLinkMode> |
|
||||
<EmbedAssembliesIntoApk>False</EmbedAssembliesIntoApk> |
|
||||
<BundleAssemblies>False</BundleAssemblies> |
|
||||
<AndroidCreatePackagePerAbi>False</AndroidCreatePackagePerAbi> |
|
||||
<AndroidSupportedAbis>armeabi;armeabi-v7a;x86</AndroidSupportedAbis> |
|
||||
<Debugger>Xamarin</Debugger> |
|
||||
<AndroidEnableMultiDex>False</AndroidEnableMultiDex> |
|
||||
<DevInstrumentationEnabled>True</DevInstrumentationEnabled> |
|
||||
</PropertyGroup> |
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> |
|
||||
<DebugType>pdbonly</DebugType> |
|
||||
<Optimize>true</Optimize> |
|
||||
<OutputPath>bin\Release\</OutputPath> |
|
||||
<DefineConstants>TRACE</DefineConstants> |
|
||||
<ErrorReport>prompt</ErrorReport> |
|
||||
<WarningLevel>4</WarningLevel> |
|
||||
<AndroidUseSharedRuntime>False</AndroidUseSharedRuntime> |
|
||||
<AndroidLinkMode>Full</AndroidLinkMode> |
|
||||
<EmbedAssembliesIntoApk>True</EmbedAssembliesIntoApk> |
|
||||
<BundleAssemblies>False</BundleAssemblies> |
|
||||
<AndroidCreatePackagePerAbi>False</AndroidCreatePackagePerAbi> |
|
||||
<Debugger>Xamarin</Debugger> |
|
||||
<AotAssemblies>False</AotAssemblies> |
|
||||
<EnableLLVM>False</EnableLLVM> |
|
||||
<AndroidEnableMultiDex>False</AndroidEnableMultiDex> |
|
||||
<EnableProguard>False</EnableProguard> |
|
||||
<DebugSymbols>False</DebugSymbols> |
|
||||
<AndroidSupportedAbis>armeabi;armeabi-v7a;x86</AndroidSupportedAbis> |
|
||||
</PropertyGroup> |
|
||||
<ItemGroup> |
|
||||
<Reference Include="Mono.Android" /> |
|
||||
<Reference Include="mscorlib" /> |
|
||||
<Reference Include="System" /> |
|
||||
<Reference Include="System.Collections" /> |
|
||||
<Reference Include="System.Core" /> |
|
||||
<Reference Include="System.Runtime" /> |
|
||||
<Reference Include="System.Xml.Linq" /> |
|
||||
<Reference Include="System.Xml" /> |
|
||||
</ItemGroup> |
|
||||
<ItemGroup> |
|
||||
<Compile Include="App.cs" /> |
|
||||
<Compile Include="MainActivity.cs" /> |
|
||||
<Compile Include="Properties\AssemblyInfo.cs" /> |
|
||||
<Compile Include="Resources\Resource.Designer.cs" /> |
|
||||
</ItemGroup> |
|
||||
<ItemGroup> |
|
||||
<None Include="Properties\AndroidManifest.xml" /> |
|
||||
<AndroidResource Include="Resources\layout\Main.axml" /> |
|
||||
</ItemGroup> |
|
||||
<ItemGroup> |
|
||||
<ProjectReference Include="..\..\Android\Avalonia.Android\Avalonia.Android.csproj"> |
|
||||
<Project>{7b92af71-6287-4693-9dcb-bd5b6e927e23}</Project> |
|
||||
<Name>Avalonia.Android</Name> |
|
||||
</ProjectReference> |
|
||||
<ProjectReference Include="..\..\Avalonia.Animation\Avalonia.Animation.csproj"> |
|
||||
<Project>{d211e587-d8bc-45b9-95a4-f297c8fa5200}</Project> |
|
||||
<Name>Avalonia.Animation</Name> |
|
||||
</ProjectReference> |
|
||||
<ProjectReference Include="..\..\Avalonia.Base\Avalonia.Base.csproj"> |
|
||||
<Project>{b09b78d8-9b26-48b0-9149-d64a2f120f3f}</Project> |
|
||||
<Name>Avalonia.Base</Name> |
|
||||
</ProjectReference> |
|
||||
<ProjectReference Include="..\..\Avalonia.Controls\Avalonia.Controls.csproj"> |
|
||||
<Project>{d2221c82-4a25-4583-9b43-d791e3f6820c}</Project> |
|
||||
<Name>Avalonia.Controls</Name> |
|
||||
</ProjectReference> |
|
||||
<ProjectReference Include="..\..\Avalonia.DotNetFrameworkRuntime\Avalonia.DotNetFrameworkRuntime.csproj"> |
|
||||
<Project>{4a1abb09-9047-4bd5-a4ad-a055e52c5ee0}</Project> |
|
||||
<Name>Avalonia.DotNetFrameworkRuntime</Name> |
|
||||
</ProjectReference> |
|
||||
<ProjectReference Include="..\..\Avalonia.Input\Avalonia.Input.csproj"> |
|
||||
<Project>{62024b2d-53eb-4638-b26b-85eeaa54866e}</Project> |
|
||||
<Name>Avalonia.Input</Name> |
|
||||
</ProjectReference> |
|
||||
<ProjectReference Include="..\..\Avalonia.Interactivity\Avalonia.Interactivity.csproj"> |
|
||||
<Project>{6b0ed19d-a08b-461c-a9d9-a9ee40b0c06b}</Project> |
|
||||
<Name>Avalonia.Interactivity</Name> |
|
||||
</ProjectReference> |
|
||||
<ProjectReference Include="..\..\Avalonia.Layout\Avalonia.Layout.csproj"> |
|
||||
<Project>{42472427-4774-4c81-8aff-9f27b8e31721}</Project> |
|
||||
<Name>Avalonia.Layout</Name> |
|
||||
</ProjectReference> |
|
||||
<ProjectReference Include="..\..\Avalonia.Visuals\Avalonia.Visuals.csproj"> |
|
||||
<Project>{eb582467-6abb-43a1-b052-e981ba910e3a}</Project> |
|
||||
<Name>Avalonia.Visuals</Name> |
|
||||
</ProjectReference> |
|
||||
<ProjectReference Include="..\..\Avalonia.Styling\Avalonia.Styling.csproj"> |
|
||||
<Project>{f1baa01a-f176-4c6a-b39d-5b40bb1b148f}</Project> |
|
||||
<Name>Avalonia.Styling</Name> |
|
||||
</ProjectReference> |
|
||||
<ProjectReference Include="..\Avalonia.Skia.Android\Avalonia.Skia.Android.csproj"> |
|
||||
<Project>{bd43f7c0-396b-4aa1-bad9-dfde54d51298}</Project> |
|
||||
<Name>Avalonia.Skia.Android</Name> |
|
||||
</ProjectReference> |
|
||||
</ItemGroup> |
|
||||
<ItemGroup> |
|
||||
<AndroidResource Include="Resources\drawable\Icon.png" /> |
|
||||
<AndroidResource Include="Resources\values\Strings.xml" /> |
|
||||
</ItemGroup> |
|
||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" /> |
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. |
|
||||
Other similar extension points exist, see Microsoft.Common.targets. |
|
||||
<Target Name="BeforeBuild"> |
|
||||
</Target> |
|
||||
<Target Name="AfterBuild"> |
|
||||
</Target> |
|
||||
--> |
|
||||
</Project> |
|
||||
@ -1,26 +0,0 @@ |
|||||
<ProjectConfiguration> |
|
||||
<AutoDetectNugetBuildDependencies>true</AutoDetectNugetBuildDependencies> |
|
||||
<BuildPriority>1000</BuildPriority> |
|
||||
<CopyReferencedAssembliesToWorkspace>false</CopyReferencedAssembliesToWorkspace> |
|
||||
<ConsiderInconclusiveTestsAsPassing>false</ConsiderInconclusiveTestsAsPassing> |
|
||||
<PreloadReferencedAssemblies>false</PreloadReferencedAssemblies> |
|
||||
<AllowDynamicCodeContractChecking>true</AllowDynamicCodeContractChecking> |
|
||||
<AllowStaticCodeContractChecking>false</AllowStaticCodeContractChecking> |
|
||||
<AllowCodeAnalysis>false</AllowCodeAnalysis> |
|
||||
<IgnoreThisComponentCompletely>true</IgnoreThisComponentCompletely> |
|
||||
<RunPreBuildEvents>false</RunPreBuildEvents> |
|
||||
<RunPostBuildEvents>false</RunPostBuildEvents> |
|
||||
<PreviouslyBuiltSuccessfully>false</PreviouslyBuiltSuccessfully> |
|
||||
<InstrumentAssembly>true</InstrumentAssembly> |
|
||||
<PreventSigningOfAssembly>false</PreventSigningOfAssembly> |
|
||||
<AnalyseExecutionTimes>true</AnalyseExecutionTimes> |
|
||||
<DetectStackOverflow>true</DetectStackOverflow> |
|
||||
<IncludeStaticReferencesInWorkspace>true</IncludeStaticReferencesInWorkspace> |
|
||||
<DefaultTestTimeout>60000</DefaultTestTimeout> |
|
||||
<UseBuildConfiguration /> |
|
||||
<UseBuildPlatform /> |
|
||||
<ProxyProcessPath /> |
|
||||
<UseCPUArchitecture>AutoDetect</UseCPUArchitecture> |
|
||||
<MSTestThreadApartmentState>STA</MSTestThreadApartmentState> |
|
||||
<BuildProcessArchitecture>x86</BuildProcessArchitecture> |
|
||||
</ProjectConfiguration> |
|
||||
@ -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); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
@ -1,5 +0,0 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="Avalonia.Skia.Android.TestApp" android:versionCode="1" android:versionName="1.0"> |
|
||||
<uses-sdk /> |
|
||||
<application android:label="Avalonia.Skia.Android.TestApp" android:icon="@drawable/Icon"></application> |
|
||||
</manifest> |
|
||||
@ -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")] |
|
||||
@ -1,114 +0,0 @@ |
|||||
#pragma warning disable 1591
|
|
||||
//------------------------------------------------------------------------------
|
|
||||
// <auto-generated>
|
|
||||
// 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.
|
|
||||
// </auto-generated>
|
|
||||
//------------------------------------------------------------------------------
|
|
||||
|
|
||||
[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
|
|
||||
|
Before Width: | Height: | Size: 4.0 KiB |
@ -1,13 +0,0 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
|
||||
android:orientation="vertical" |
|
||||
android:layout_width="fill_parent" |
|
||||
android:layout_height="fill_parent" |
|
||||
> |
|
||||
<Button |
|
||||
android:id="@+id/MyButton" |
|
||||
android:layout_width="fill_parent" |
|
||||
android:layout_height="wrap_content" |
|
||||
android:text="@string/Hello" |
|
||||
/> |
|
||||
</LinearLayout> |
|
||||
@ -1,5 +0,0 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
<resources> |
|
||||
<string name="Hello">Hello World, Click Me!</string> |
|
||||
<string name="ApplicationName">Avalonia.Skia.Android.TestApp</string> |
|
||||
</resources> |
|
||||
@ -1,24 +0,0 @@ |
|||||
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.Media; |
|
||||
using Avalonia.Platform; |
|
||||
|
|
||||
namespace Avalonia.Skia |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// We will likely need platform specific pieces to support HW acceleration
|
|
||||
/// so leaving this class here for now as placeholder.
|
|
||||
/// </summary>
|
|
||||
internal partial class RenderTarget : IRenderTarget |
|
||||
{ |
|
||||
} |
|
||||
} |
|
||||
@ -1,106 +0,0 @@ |
|||||
using System; |
|
||||
using Avalonia.Media; |
|
||||
using Avalonia.Platform; |
|
||||
using SkiaSharp; |
|
||||
using Android.Graphics; |
|
||||
using Android.Views; |
|
||||
|
|
||||
namespace Avalonia.Skia |
|
||||
{ |
|
||||
internal partial class RenderTarget : IRenderTarget |
|
||||
{ |
|
||||
public SKSurface Surface { get; protected set; } |
|
||||
|
|
||||
public virtual DrawingContext CreateDrawingContext() |
|
||||
{ |
|
||||
return |
|
||||
new DrawingContext( |
|
||||
new DrawingContextImpl(Surface.Canvas)); |
|
||||
} |
|
||||
|
|
||||
public void Dispose() |
|
||||
{ |
|
||||
// Nothing to do here.
|
|
||||
} |
|
||||
} |
|
||||
|
|
||||
internal class WindowRenderTarget : RenderTarget |
|
||||
{ |
|
||||
private readonly SurfaceView _surfaceView; |
|
||||
Bitmap _bitmap; |
|
||||
int Width { get; set; } |
|
||||
int Height { get; set; } |
|
||||
|
|
||||
public WindowRenderTarget(SurfaceView surfaceView) |
|
||||
{ |
|
||||
_surfaceView = surfaceView; |
|
||||
FixSize(); |
|
||||
} |
|
||||
|
|
||||
private void FixSize() |
|
||||
{ |
|
||||
int width, height; |
|
||||
GetPlatformWindowSize(out width, out height); |
|
||||
if (Width == width && Height == height) |
|
||||
return; |
|
||||
|
|
||||
Width = width; |
|
||||
Height = height; |
|
||||
|
|
||||
if (Surface != null) |
|
||||
{ |
|
||||
Surface.Dispose(); |
|
||||
} |
|
||||
|
|
||||
if (_bitmap != null) |
|
||||
{ |
|
||||
_bitmap.Dispose(); |
|
||||
} |
|
||||
|
|
||||
_bitmap = Bitmap.CreateBitmap(width, height, Bitmap.Config.Argb8888); |
|
||||
Surface = SKSurface.Create(width, height, SKImageInfo.PlatformColorType, SKAlphaType.Premul, _bitmap.LockPixels(), width * 4); |
|
||||
} |
|
||||
|
|
||||
private void GetPlatformWindowSize(out int w, out int h) |
|
||||
{ |
|
||||
w = _surfaceView.Width; |
|
||||
h = _surfaceView.Height; |
|
||||
} |
|
||||
|
|
||||
public override DrawingContext CreateDrawingContext() |
|
||||
{ |
|
||||
FixSize(); |
|
||||
|
|
||||
var canvas = Surface.Canvas; |
|
||||
canvas.RestoreToCount(0); |
|
||||
canvas.Save(); |
|
||||
canvas.Clear(SKColors.Red); |
|
||||
canvas.ResetMatrix(); |
|
||||
|
|
||||
return |
|
||||
new DrawingContext( |
|
||||
new WindowDrawingContextImpl(this)); |
|
||||
} |
|
||||
|
|
||||
public void Present() |
|
||||
{ |
|
||||
Canvas canvas = null; |
|
||||
try |
|
||||
{ |
|
||||
canvas = _surfaceView.Holder.LockCanvas(null); |
|
||||
_bitmap.UnlockPixels(); |
|
||||
canvas.DrawBitmap(_bitmap, 0, 0, null); |
|
||||
} |
|
||||
catch (Exception) |
|
||||
{ |
|
||||
} |
|
||||
finally |
|
||||
{ |
|
||||
if (canvas != null) |
|
||||
_surfaceView.Holder.UnlockCanvasAndPost(canvas); |
|
||||
} |
|
||||
|
|
||||
_bitmap.UnlockPixels(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,39 +0,0 @@ |
|||||
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.Media; |
|
||||
using Avalonia.Platform; |
|
||||
|
|
||||
namespace Avalonia.Skia.Android |
|
||||
{ |
|
||||
public abstract class SkiaRenderView : SkiaView |
|
||||
{ |
|
||||
private IRenderTarget _renderTarget; |
|
||||
|
|
||||
public SkiaRenderView(Activity context) : base(context) |
|
||||
{ |
|
||||
_renderTarget = |
|
||||
AvaloniaLocator.Current.GetService<IPlatformRenderInterface>() |
|
||||
.CreateRenderTarget(new object[]{this}); |
|
||||
} |
|
||||
|
|
||||
protected override void Draw() |
|
||||
{ |
|
||||
if (_renderTarget == null) |
|
||||
return; |
|
||||
using (var ctx = _renderTarget.CreateDrawingContext()) |
|
||||
OnRender(ctx); |
|
||||
} |
|
||||
|
|
||||
protected abstract void OnRender(DrawingContext ctx); |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
Loading…
Reference in new issue