From 302dae5b0a80cead1c16fb4cc69afe9fec19c63f Mon Sep 17 00:00:00 2001 From: Matthew Leibowitz Date: Sun, 23 Apr 2017 15:28:32 -0400 Subject: [PATCH] Added the initial mac forms source --- build.cake | 1 + nuget/SkiaSharp.Views.Forms.Mac.nuspec | 6 ++ nuget/SkiaSharp.Views.Forms.nuspec | 6 ++ .../SKCanvasViewRenderer.cs | 18 ++++ .../SKGLViewRenderer.cs | 68 +++++++++++++++ .../SKImageSourceHandler.cs | 49 +++++++++++ .../SkiaSharp.Views.Forms.Mac.csproj | 85 +++++++++++++++++++ .../SkiaSharp.Views.Forms.Mac/packages.config | 4 + .../SKCanvasViewRendererBase.cs | 6 ++ .../SKGLViewRendererBase.cs | 4 + source/SkiaSharpSource.Mac.sln | 7 ++ source/SkiaSharpSource.sln | 7 ++ 12 files changed, 261 insertions(+) create mode 100644 source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Mac/SKCanvasViewRenderer.cs create mode 100644 source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Mac/SKGLViewRenderer.cs create mode 100644 source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Mac/SKImageSourceHandler.cs create mode 100644 source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Mac/SkiaSharp.Views.Forms.Mac.csproj create mode 100644 source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Mac/packages.config diff --git a/build.cake b/build.cake index 99a2594c..03682965 100644 --- a/build.cake +++ b/build.cake @@ -171,6 +171,7 @@ Task ("libs") CopyFileToDirectory ("./source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms/bin/Release/SkiaSharp.Views.Forms.dll", "./output/portable/"); CopyFileToDirectory ("./source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Android/bin/Release/SkiaSharp.Views.Forms.dll", "./output/android/"); CopyFileToDirectory ("./source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.iOS/bin/Release/SkiaSharp.Views.Forms.dll", "./output/ios/"); + CopyFileToDirectory ("./source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Mac/bin/Release/SkiaSharp.Views.Forms.dll", "./output/osx/"); // copy SVG CopyFileToDirectory ("./source/SkiaSharp.Svg/SkiaSharp.Svg/bin/Release/SkiaSharp.Svg.dll", "./output/portable/"); diff --git a/nuget/SkiaSharp.Views.Forms.Mac.nuspec b/nuget/SkiaSharp.Views.Forms.Mac.nuspec index 17f9c196..0a4dea93 100644 --- a/nuget/SkiaSharp.Views.Forms.Mac.nuspec +++ b/nuget/SkiaSharp.Views.Forms.Mac.nuspec @@ -27,11 +27,17 @@ + + + + + + \ No newline at end of file diff --git a/nuget/SkiaSharp.Views.Forms.nuspec b/nuget/SkiaSharp.Views.Forms.nuspec index 78173e4a..2a41bbb8 100644 --- a/nuget/SkiaSharp.Views.Forms.nuspec +++ b/nuget/SkiaSharp.Views.Forms.nuspec @@ -27,6 +27,11 @@ + + + + + @@ -38,6 +43,7 @@ + \ No newline at end of file diff --git a/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Mac/SKCanvasViewRenderer.cs b/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Mac/SKCanvasViewRenderer.cs new file mode 100644 index 00000000..823249da --- /dev/null +++ b/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Mac/SKCanvasViewRenderer.cs @@ -0,0 +1,18 @@ +using Xamarin.Forms; + +using SKFormsView = SkiaSharp.Views.Forms.SKCanvasView; +using SKNativeView = SkiaSharp.Views.Mac.SKCanvasView; + +[assembly: ExportRenderer(typeof(SKFormsView), typeof(SkiaSharp.Views.Forms.SKCanvasViewRenderer))] + +namespace SkiaSharp.Views.Forms +{ + public class SKCanvasViewRenderer : SKCanvasViewRendererBase + { + protected override SKNativeView CreateNativeControl() + { + var view = base.CreateNativeControl(); + return view; + } + } +} diff --git a/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Mac/SKGLViewRenderer.cs b/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Mac/SKGLViewRenderer.cs new file mode 100644 index 00000000..4b6a2d83 --- /dev/null +++ b/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Mac/SKGLViewRenderer.cs @@ -0,0 +1,68 @@ +using CoreVideo; +using Foundation; +using Xamarin.Forms; + +using SKFormsView = SkiaSharp.Views.Forms.SKGLView; +using SKNativeView = SkiaSharp.Views.Mac.SKGLView; + +[assembly: ExportRenderer(typeof(SKFormsView), typeof(SkiaSharp.Views.Forms.SKGLViewRenderer))] + +namespace SkiaSharp.Views.Forms +{ + public class SKGLViewRenderer : SKGLViewRendererBase + { + private CVDisplayLink displayLink; + + protected override SKNativeView CreateNativeControl() + { + var view = base.CreateNativeControl(); + return view; + } + + protected override void Dispose(bool disposing) + { + // stop the render loop + if (displayLink != null) + { + displayLink.Stop(); + displayLink.Dispose(); + displayLink = null; + } + + base.Dispose(disposing); + } + + protected override void SetupRenderLoop(bool oneShot) + { + // only start if we haven't already + if (displayLink != null) + return; + + // bail out if we are requesting something that the view doesn't want to + if (!oneShot && !Element.HasRenderLoop) + return; + + // create the loop + displayLink = new CVDisplayLink(); + displayLink.SetOutputCallback(delegate + { + var formsView = Control; + var nativeView = Element; + + // redraw the view + formsView?.Display(); + + // stop the render loop if this was a one-shot, or the views are disposed + if (formsView == null || nativeView == null || !nativeView.HasRenderLoop) + { + displayLink.Stop(); + displayLink.Dispose(); + displayLink = null; + } + + return CVReturn.Success; + }); + displayLink.Start(); + } + } +} diff --git a/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Mac/SKImageSourceHandler.cs b/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Mac/SKImageSourceHandler.cs new file mode 100644 index 00000000..492d150c --- /dev/null +++ b/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Mac/SKImageSourceHandler.cs @@ -0,0 +1,49 @@ +using System.Threading; +using System.Threading.Tasks; +using AppKit; +using Xamarin.Forms; +using Xamarin.Forms.Platform.MacOS; + +using SkiaSharp.Views.Mac; + +[assembly: ExportImageSourceHandler(typeof(SkiaSharp.Views.Forms.SKImageImageSource), typeof(SkiaSharp.Views.Forms.SKImageSourceHandler))] +[assembly: ExportImageSourceHandler(typeof(SkiaSharp.Views.Forms.SKBitmapImageSource), typeof(SkiaSharp.Views.Forms.SKImageSourceHandler))] +[assembly: ExportImageSourceHandler(typeof(SkiaSharp.Views.Forms.SKPixmapImageSource), typeof(SkiaSharp.Views.Forms.SKImageSourceHandler))] +[assembly: ExportImageSourceHandler(typeof(SkiaSharp.Views.Forms.SKPictureImageSource), typeof(SkiaSharp.Views.Forms.SKImageSourceHandler))] + +namespace SkiaSharp.Views.Forms +{ + public sealed class SKImageSourceHandler : IImageSourceHandler + { + public Task LoadImageAsync(ImageSource imagesource, CancellationToken cancelationToken = default(CancellationToken), float scale = 1f) + { + NSImage image = null; + + var imageImageSource = imagesource as SKImageImageSource; + if (imageImageSource != null) + { + image = imageImageSource.Image?.ToNSImage(); + } + + var bitmapImageSource = imagesource as SKBitmapImageSource; + if (bitmapImageSource != null) + { + image = bitmapImageSource.Bitmap?.ToNSImage(); + } + + var pixmapImageSource = imagesource as SKPixmapImageSource; + if (pixmapImageSource != null) + { + image = pixmapImageSource.Pixmap?.ToNSImage(); + } + + var pictureImageSource = imagesource as SKPictureImageSource; + if (pictureImageSource != null) + { + image = pictureImageSource.Picture?.ToNSImage(pictureImageSource.Dimensions); + } + + return Task.FromResult(image); + } + } +} diff --git a/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Mac/SkiaSharp.Views.Forms.Mac.csproj b/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Mac/SkiaSharp.Views.Forms.Mac.csproj new file mode 100644 index 00000000..117df41d --- /dev/null +++ b/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Mac/SkiaSharp.Views.Forms.Mac.csproj @@ -0,0 +1,85 @@ + + + + Debug + AnyCPU + {DA5DA4D8-4885-4AF2-96BB-AE803C344AB0} + {A3F8F2AB-B479-4A4A-A458-A89E7DC349F1};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + Library + SkiaSharp.Views.Forms + SkiaSharp.Views.Forms + v2.0 + Xamarin.Mac + Resources + + + true + full + false + bin\Debug + DEBUG;__MACOS__ + prompt + 4 + false + false + false + false + None + + + + true + bin\Release + __MACOS__ + prompt + 4 + false + false + false + false + None + + + + + + + + ..\..\packages\Xamarin.Forms.2.3.5.233-pre1\lib\Xamarin.Mac\Xamarin.Forms.Core.dll + + + ..\..\packages\Xamarin.Forms.2.3.5.233-pre1\lib\Xamarin.Mac\Xamarin.Forms.Platform.dll + + + ..\..\packages\Xamarin.Forms.2.3.5.233-pre1\lib\Xamarin.Mac\Xamarin.Forms.Platform.macOS.dll + + + ..\..\packages\Xamarin.Forms.2.3.5.233-pre1\lib\Xamarin.Mac\Xamarin.Forms.Xaml.dll + + + + + + + + + + {809A15DC-E675-4A24-83FA-DF13160F7E4C} + SkiaSharp.Views.Mac + + + {4588A759-3853-49B8-8A68-6C7917BE9220} + SkiaSharp.OSX + + + + + + + + + + + + + \ No newline at end of file diff --git a/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Mac/packages.config b/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Mac/packages.config new file mode 100644 index 00000000..f517c9a1 --- /dev/null +++ b/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Mac/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Native.Shared/SKCanvasViewRendererBase.cs b/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Native.Shared/SKCanvasViewRendererBase.cs index 08337039..077321e8 100644 --- a/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Native.Shared/SKCanvasViewRendererBase.cs +++ b/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Native.Shared/SKCanvasViewRendererBase.cs @@ -15,6 +15,10 @@ using SKNativePaintSurfaceEventArgs = SkiaSharp.Views.iOS.SKPaintSurfaceEventArg using Xamarin.Forms.Platform.UWP; using SKNativeView = SkiaSharp.Views.UWP.SKXamlCanvas; using SKNativePaintSurfaceEventArgs = SkiaSharp.Views.UWP.SKPaintSurfaceEventArgs; +#elif __MACOS__ +using Xamarin.Forms.Platform.MacOS; +using SKNativeView = SkiaSharp.Views.Mac.SKCanvasView; +using SKNativePaintSurfaceEventArgs = SkiaSharp.Views.Mac.SKPaintSurfaceEventArgs; #endif namespace SkiaSharp.Views.Forms @@ -115,6 +119,8 @@ namespace SkiaSharp.Views.Forms // repaint the native control #if __IOS__ Control.SetNeedsDisplay(); +#elif __MACOS__ + Control.NeedsDisplay = true; #else Control.Invalidate(); #endif diff --git a/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Native.Shared/SKGLViewRendererBase.cs b/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Native.Shared/SKGLViewRendererBase.cs index 0019a96b..7c644320 100644 --- a/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Native.Shared/SKGLViewRendererBase.cs +++ b/source/SkiaSharp.Views.Forms/SkiaSharp.Views.Forms.Native.Shared/SKGLViewRendererBase.cs @@ -16,6 +16,10 @@ using SKNativePaintGLSurfaceEventArgs = SkiaSharp.Views.iOS.SKPaintGLSurfaceEven using Xamarin.Forms.Platform.UWP; using SKNativeView = SkiaSharp.Views.UWP.SKSwapChainPanel; using SKNativePaintGLSurfaceEventArgs = SkiaSharp.Views.UWP.SKPaintGLSurfaceEventArgs; +#elif __MACOS__ +using Xamarin.Forms.Platform.MacOS; +using SKNativeView = SkiaSharp.Views.Mac.SKGLView; +using SKNativePaintGLSurfaceEventArgs = SkiaSharp.Views.Mac.SKPaintGLSurfaceEventArgs; #endif namespace SkiaSharp.Views.Forms diff --git a/source/SkiaSharpSource.Mac.sln b/source/SkiaSharpSource.Mac.sln index 8d697d39..89aae552 100644 --- a/source/SkiaSharpSource.Mac.sln +++ b/source/SkiaSharpSource.Mac.sln @@ -57,6 +57,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SkiaSharp.Extended", "SkiaS EndProject Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "SkiaSharp.Views.Forms.Native.Shared", "SkiaSharp.Views.Forms\SkiaSharp.Views.Forms.Native.Shared\SkiaSharp.Views.Forms.Native.Shared.shproj", "{CEBD25FD-DD4F-4D5F-B809-D50D02176F41}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SkiaSharp.Views.Forms.Mac", "SkiaSharp.Views.Forms\SkiaSharp.Views.Forms.Mac\SkiaSharp.Views.Forms.Mac.csproj", "{DA5DA4D8-4885-4AF2-96BB-AE803C344AB0}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution SkiaSharp.Svg\SkiaSharp.Svg.Shared\SkiaSharp.Svg.Shared.projitems*{04c4399a-6740-4733-b6b7-f968232a76c8}*SharedItemsImports = 4 @@ -149,6 +151,10 @@ Global {FEA1FEC9-950C-46C0-9EB0-A515E0AB8F19}.Debug|Any CPU.Build.0 = Debug|Any CPU {FEA1FEC9-950C-46C0-9EB0-A515E0AB8F19}.Release|Any CPU.ActiveCfg = Release|Any CPU {FEA1FEC9-950C-46C0-9EB0-A515E0AB8F19}.Release|Any CPU.Build.0 = Release|Any CPU + {DA5DA4D8-4885-4AF2-96BB-AE803C344AB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DA5DA4D8-4885-4AF2-96BB-AE803C344AB0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DA5DA4D8-4885-4AF2-96BB-AE803C344AB0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DA5DA4D8-4885-4AF2-96BB-AE803C344AB0}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -176,5 +182,6 @@ Global {E3290CE6-0ADA-486B-9BAB-8BCF07F9BE45} = {8570A43F-3AD6-4EC4-8CD1-92EF9AC23916} {FEA1FEC9-950C-46C0-9EB0-A515E0AB8F19} = {8570A43F-3AD6-4EC4-8CD1-92EF9AC23916} {CEBD25FD-DD4F-4D5F-B809-D50D02176F41} = {EB592D4C-48E1-498D-8A9F-3AEA0C7FAB30} + {DA5DA4D8-4885-4AF2-96BB-AE803C344AB0} = {EB592D4C-48E1-498D-8A9F-3AEA0C7FAB30} EndGlobalSection EndGlobal diff --git a/source/SkiaSharpSource.sln b/source/SkiaSharpSource.sln index a89c7940..66895f69 100644 --- a/source/SkiaSharpSource.sln +++ b/source/SkiaSharpSource.sln @@ -75,6 +75,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SkiaSharp.Extended.NetStand EndProject Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "SkiaSharp.Views.Forms.Native.Shared", "SkiaSharp.Views.Forms\SkiaSharp.Views.Forms.Native.Shared\SkiaSharp.Views.Forms.Native.Shared.shproj", "{CEBD25FD-DD4F-4D5F-B809-D50D02176F41}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SkiaSharp.Views.Forms.Mac", "SkiaSharp.Views.Forms\SkiaSharp.Views.Forms.Mac\SkiaSharp.Views.Forms.Mac.csproj", "{DA5DA4D8-4885-4AF2-96BB-AE803C344AB0}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution SkiaSharp.Svg\SkiaSharp.Svg.Shared\SkiaSharp.Svg.Shared.projitems*{04c4399a-6740-4733-b6b7-f968232a76c8}*SharedItemsImports = 4 @@ -212,6 +214,10 @@ Global {36456F7F-388A-49E1-B9C5-CC2DEC82D2C2}.Debug|Any CPU.Build.0 = Debug|Any CPU {36456F7F-388A-49E1-B9C5-CC2DEC82D2C2}.Release|Any CPU.ActiveCfg = Release|Any CPU {36456F7F-388A-49E1-B9C5-CC2DEC82D2C2}.Release|Any CPU.Build.0 = Release|Any CPU + {DA5DA4D8-4885-4AF2-96BB-AE803C344AB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DA5DA4D8-4885-4AF2-96BB-AE803C344AB0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DA5DA4D8-4885-4AF2-96BB-AE803C344AB0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DA5DA4D8-4885-4AF2-96BB-AE803C344AB0}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -248,5 +254,6 @@ Global {FEA1FEC9-950C-46C0-9EB0-A515E0AB8F19} = {06F5DF49-E622-4A4C-8F01-0DB0E04721CE} {36456F7F-388A-49E1-B9C5-CC2DEC82D2C2} = {06F5DF49-E622-4A4C-8F01-0DB0E04721CE} {CEBD25FD-DD4F-4D5F-B809-D50D02176F41} = {DCADA8CC-D50A-4BD9-B2E6-86696A43D819} + {DA5DA4D8-4885-4AF2-96BB-AE803C344AB0} = {DCADA8CC-D50A-4BD9-B2E6-86696A43D819} EndGlobalSection EndGlobal