From 887f8aa7584c3af93f67f1afe838121e7b83834f Mon Sep 17 00:00:00 2001 From: Michael Fink Date: Wed, 15 Apr 2020 18:37:24 +0200 Subject: [PATCH 1/6] added macOS FilePicker implementation --- .../FilePicker/FilePicker.mac.cs | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 Xamarin.Essentials/FilePicker/FilePicker.mac.cs diff --git a/Xamarin.Essentials/FilePicker/FilePicker.mac.cs b/Xamarin.Essentials/FilePicker/FilePicker.mac.cs new file mode 100644 index 000000000..efddcf498 --- /dev/null +++ b/Xamarin.Essentials/FilePicker/FilePicker.mac.cs @@ -0,0 +1,100 @@ +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; +using AppKit; + +namespace Xamarin.Essentials +{ + public static partial class FilePicker + { + static Task PlatformPickFileAsync(PickOptions options) + { + var openPanel = new NSOpenPanel + { + CanChooseFiles = true, + AllowsMultipleSelection = false, + CanChooseDirectories = false + }; + + SetFileTypes(options, openPanel); + + FilePickerResult result = null; + var resultCount = openPanel.RunModal(); + if (resultCount == 1) + { + result = new FilePickerResult(openPanel.Urls[0].Path); + } + + return Task.FromResult(result); + } + + static Task> PlatformPickMultipleFilesAsync(PickOptions options) + { + var openPanel = new NSOpenPanel + { + CanChooseFiles = true, + AllowsMultipleSelection = true, + CanChooseDirectories = false + }; + + SetFileTypes(options, openPanel); + + var resultList = new List(); + var result = openPanel.RunModal(); + if (result != 0) + { + foreach (var url in openPanel.Urls) + { + resultList.Add(new FilePickerResult(url.Path)); + } + } + + return Task.FromResult>(resultList); + } + + static void SetFileTypes(PickOptions options, NSOpenPanel panel) + { + var allowedFileTypes = new List(); + + if (options?.FileTypes?.Value != null) + { + foreach (var type in options.FileTypes.Value) + { + allowedFileTypes.Add(type); + } + } + + if (allowedFileTypes.Count == 0) + allowedFileTypes.Add("*.*"); + + panel.AllowedFileTypes = allowedFileTypes.ToArray(); + } + } + + public partial class FilePickerFileType + { + public static FilePickerFileType PlatformImageFileType() => + new FilePickerFileType(new Dictionary> + { + { DevicePlatform.macOS, new[] { "*.png", "*.jpg", "*.jpeg" } } + }); + + public static FilePickerFileType PlatformPngFileType() => + new FilePickerFileType(new Dictionary> + { + { DevicePlatform.macOS, new[] { "*.png" } } + }); + } + + public partial class FilePickerResult + { + internal FilePickerResult(string filePath) + : base(filePath) + { + FileName = Path.GetFileName(filePath); + } + + Task PlatformOpenReadStreamAsync() + => Task.FromResult(File.OpenRead(FullPath)); + } +} From a21b247545f38292f492e09902235f069508d431 Mon Sep 17 00:00:00 2001 From: Michael Fink Date: Mon, 20 Apr 2020 12:50:40 +0200 Subject: [PATCH 2/6] renamed file to .macos.cs to get picked up by MacOS build --- .../FilePicker/{FilePicker.mac.cs => FilePicker.macos.cs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Xamarin.Essentials/FilePicker/{FilePicker.mac.cs => FilePicker.macos.cs} (100%) diff --git a/Xamarin.Essentials/FilePicker/FilePicker.mac.cs b/Xamarin.Essentials/FilePicker/FilePicker.macos.cs similarity index 100% rename from Xamarin.Essentials/FilePicker/FilePicker.mac.cs rename to Xamarin.Essentials/FilePicker/FilePicker.macos.cs From f42ba864d603bb079c286823838e7d4971cf00d1 Mon Sep 17 00:00:00 2001 From: Michael Fink Date: Mon, 20 Apr 2020 12:51:52 +0200 Subject: [PATCH 3/6] added macOS custom file picker file type to sample --- Samples/Samples/ViewModel/FilePickerViewModel.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Samples/Samples/ViewModel/FilePickerViewModel.cs b/Samples/Samples/ViewModel/FilePickerViewModel.cs index dd3653621..f9fda69d0 100644 --- a/Samples/Samples/ViewModel/FilePickerViewModel.cs +++ b/Samples/Samples/ViewModel/FilePickerViewModel.cs @@ -77,6 +77,7 @@ async void DoPickCustomType() { DevicePlatform.Android, new[] { "application/comics" } }, { DevicePlatform.UWP, new[] { ".cbr", ".cbz" } }, { DevicePlatform.Tizen, new[] { "*/*" } }, + { DevicePlatform.macOS, new[] { "cbr", "cbz" } }, // or general UTType values }); var options = new PickOptions From 8b28a87ad66706e6177e37af4a54c33d82d022d1 Mon Sep 17 00:00:00 2001 From: Michael Fink Date: Mon, 20 Apr 2020 13:23:56 +0200 Subject: [PATCH 4/6] use PickerTitle when set --- Xamarin.Essentials/FilePicker/FilePicker.macos.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Xamarin.Essentials/FilePicker/FilePicker.macos.cs b/Xamarin.Essentials/FilePicker/FilePicker.macos.cs index efddcf498..c787a4d03 100644 --- a/Xamarin.Essentials/FilePicker/FilePicker.macos.cs +++ b/Xamarin.Essentials/FilePicker/FilePicker.macos.cs @@ -16,6 +16,9 @@ static Task PlatformPickFileAsync(PickOptions options) CanChooseDirectories = false }; + if (options.PickerTitle != null) + openPanel.Title = options.PickerTitle; + SetFileTypes(options, openPanel); FilePickerResult result = null; @@ -37,6 +40,9 @@ static Task> PlatformPickMultipleFilesAsync(PickOp CanChooseDirectories = false }; + if (options.PickerTitle != null) + openPanel.Title = options.PickerTitle; + SetFileTypes(options, openPanel); var resultList = new List(); From f2a730da54f7917dddd60a69e149dfcf09302a3e Mon Sep 17 00:00:00 2001 From: Michael Fink Date: Mon, 20 Apr 2020 13:24:56 +0200 Subject: [PATCH 5/6] fixed checking return code from RunModal() --- Xamarin.Essentials/FilePicker/FilePicker.macos.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Xamarin.Essentials/FilePicker/FilePicker.macos.cs b/Xamarin.Essentials/FilePicker/FilePicker.macos.cs index c787a4d03..1710f5c17 100644 --- a/Xamarin.Essentials/FilePicker/FilePicker.macos.cs +++ b/Xamarin.Essentials/FilePicker/FilePicker.macos.cs @@ -2,6 +2,7 @@ using System.IO; using System.Threading.Tasks; using AppKit; +using MobileCoreServices; namespace Xamarin.Essentials { @@ -22,8 +23,8 @@ static Task PlatformPickFileAsync(PickOptions options) SetFileTypes(options, openPanel); FilePickerResult result = null; - var resultCount = openPanel.RunModal(); - if (resultCount == 1) + var panelResult = openPanel.RunModal(); + if (panelResult == (nint)(long)NSModalResponse.OK) { result = new FilePickerResult(openPanel.Urls[0].Path); } @@ -46,8 +47,8 @@ static Task> PlatformPickMultipleFilesAsync(PickOp SetFileTypes(options, openPanel); var resultList = new List(); - var result = openPanel.RunModal(); - if (result != 0) + var panelResult = openPanel.RunModal(); + if (panelResult == (nint)(long)NSModalResponse.OK) { foreach (var url in openPanel.Urls) { From 4f657663ff26a03906bb3850e20e10f5557d80e4 Mon Sep 17 00:00:00 2001 From: Michael Fink Date: Mon, 20 Apr 2020 13:25:27 +0200 Subject: [PATCH 6/6] fixed passing allowed file types to NSOpenPanel --- Xamarin.Essentials/FilePicker/FilePicker.macos.cs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/Xamarin.Essentials/FilePicker/FilePicker.macos.cs b/Xamarin.Essentials/FilePicker/FilePicker.macos.cs index 1710f5c17..2b3fabd64 100644 --- a/Xamarin.Essentials/FilePicker/FilePicker.macos.cs +++ b/Xamarin.Essentials/FilePicker/FilePicker.macos.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.IO; using System.Threading.Tasks; using AppKit; @@ -67,13 +68,10 @@ static void SetFileTypes(PickOptions options, NSOpenPanel panel) { foreach (var type in options.FileTypes.Value) { - allowedFileTypes.Add(type); + allowedFileTypes.Add(type.TrimStart('*', '.')); } } - if (allowedFileTypes.Count == 0) - allowedFileTypes.Add("*.*"); - panel.AllowedFileTypes = allowedFileTypes.ToArray(); } } @@ -83,13 +81,13 @@ public partial class FilePickerFileType public static FilePickerFileType PlatformImageFileType() => new FilePickerFileType(new Dictionary> { - { DevicePlatform.macOS, new[] { "*.png", "*.jpg", "*.jpeg" } } + { DevicePlatform.macOS, new string[] { UTType.PNG, UTType.JPEG, "jpeg" } } }); public static FilePickerFileType PlatformPngFileType() => new FilePickerFileType(new Dictionary> { - { DevicePlatform.macOS, new[] { "*.png" } } + { DevicePlatform.macOS, new string[] { UTType.PNG } } }); }