瀏覽代碼

[MONOMAC] Implemented system dialogs

Nikita Tsukanov 8 年之前
父節點
當前提交
7cfe495817

+ 17 - 4
samples/ControlCatalog.NetCore/Program.cs

@@ -1,6 +1,8 @@
 using System;
+using System.Diagnostics;
 using System.Linq;
 using System.Runtime.InteropServices;
+using System.Threading;
 using Avalonia;
 
 namespace ControlCatalog.NetCore
@@ -9,11 +11,22 @@ namespace ControlCatalog.NetCore
     {
         static void Main(string[] args)
         {
-            if (args.Contains("--fbdev")) AppBuilder.Configure<App>().InitializeWithLinuxFramebuffer(tl =>
+            if (args.Contains("--wait-for-attach"))
             {
-                tl.Content = new MainView();
-                System.Threading.ThreadPool.QueueUserWorkItem(_ => ConsoleSilencer());
-            });
+                Console.WriteLine("Attach debugger and use 'Set next statement'");
+                while (true)
+                {
+                    Thread.Sleep(100);
+                    if (Debugger.IsAttached)
+                        break;
+                }
+            }
+            if (args.Contains("--fbdev"))
+                AppBuilder.Configure<App>().InitializeWithLinuxFramebuffer(tl =>
+                {
+                    tl.Content = new MainView();
+                    System.Threading.ThreadPool.QueueUserWorkItem(_ => ConsoleSilencer());
+                });
             else
                 AppBuilder.Configure<App>()
                     .CustomPlatformDetect()

+ 1 - 1
src/Avalonia.Controls/SystemDialog.cs

@@ -20,7 +20,7 @@ namespace Avalonia.Controls
     {
         public string DefaultExtension { get; set; }        
 
-        public async Task<string> ShowAsync(Window window = null)
+        public async Task<string> ShowAsync(Window window)
             =>
                 ((await AvaloniaLocator.Current.GetService<ISystemDialogImpl>().ShowFileDialogAsync(this, window?.PlatformImpl)) ??
                  new string[0]).FirstOrDefault();

+ 5 - 3
src/OSX/Avalonia.MonoMac/MonoMacPlatform.cs

@@ -1,5 +1,6 @@
 using System;
 using Avalonia.Controls;
+using Avalonia.Controls.Platform;
 using Avalonia.Input;
 using Avalonia.Platform;
 using Avalonia.Rendering;
@@ -12,7 +13,7 @@ namespace Avalonia.MonoMac
         internal static MonoMacPlatform Instance { get; private set; }
         internal readonly MouseDevice MouseDevice = new MouseDevice();
         readonly KeyboardDevice _keyboardDevice = new KeyboardDevice();
-        NSApplication _app;
+        internal static NSApplication App;
         void DoInitialize()
         {
             AvaloniaLocator.CurrentMutable
@@ -22,6 +23,7 @@ namespace Avalonia.MonoMac
                 .Bind<IMouseDevice>().ToConstant(MouseDevice)
                 .Bind<IPlatformSettings>().ToConstant(this)
                 .Bind<IWindowingPlatform>().ToConstant(this)
+                .Bind<ISystemDialogImpl>().ToSingleton<SystemDialogsImpl>()
                 .Bind<IPlatformThreadingInterface>().ToConstant(PlatformThreadingInterface.Instance);
 
             InitializeCocoaApp();
@@ -37,8 +39,8 @@ namespace Avalonia.MonoMac
         void InitializeCocoaApp()
         {
             NSApplication.Init();
-            _app = NSApplication.SharedApplication;
-            _app.ActivationPolicy = NSApplicationActivationPolicy.Regular;
+            App = NSApplication.SharedApplication;
+            App.ActivationPolicy = NSApplicationActivationPolicy.Regular;
 
         }
 

+ 91 - 0
src/OSX/Avalonia.MonoMac/SystemDialogsImpl.cs

@@ -0,0 +1,91 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Avalonia.Controls;
+using Avalonia.Controls.Platform;
+using Avalonia.Platform;
+using MonoMac.AppKit;
+
+namespace Avalonia.MonoMac
+{
+    class SystemDialogsImpl : ISystemDialogImpl
+    {
+
+        Task<string[]> RunPanel(NSSavePanel panel, IWindowImpl parent)
+        {
+            var keyWindow = MonoMacPlatform.App.KeyWindow;
+            var tcs = new TaskCompletionSource<string[]>();
+            void OnComplete(int result)
+            {
+                if (result == 0)
+                    tcs.SetResult(null);
+                else
+                {
+                    if (panel is NSOpenPanel openPanel)
+                        tcs.SetResult(openPanel.Filenames);
+                    else
+                        tcs.SetResult(new[] { panel.Filename });
+                }
+                panel.OrderOut(panel);
+                keyWindow?.MakeKeyAndOrderFront(keyWindow);
+                MonoMacPlatform.App.ActivateIgnoringOtherApps(true);
+                panel.Dispose();
+            }
+
+            if (parent != null)
+            {
+                var window = (WindowImpl)parent;
+                panel.BeginSheet(window.Window, OnComplete);
+            }
+            else
+                panel.Begin(OnComplete);
+            return tcs.Task;
+        }
+
+        public Task<string[]> ShowFileDialogAsync(FileDialog dialog, IWindowImpl parent)
+        {
+            /* NOTES
+             * DefaultFileExtension is not supported
+             * Named filters are not supported
+            */
+            NSSavePanel panel;
+            if (dialog is OpenFileDialog openDialog)
+            {
+                var openPanel = new NSOpenPanel();
+                panel = openPanel;
+                
+                openPanel.AllowsMultipleSelection = openDialog.AllowMultiple;
+            }
+            else
+                panel = new NSSavePanel();
+            panel.Title = panel.Title;
+            if (dialog.InitialDirectory != null)
+                panel.Directory = dialog.InitialDirectory;
+            if (dialog.InitialFileName != null)
+                panel.NameFieldStringValue = dialog.InitialFileName;
+            if (dialog.Filters?.Count > 0)
+                panel.AllowedFileTypes = dialog.Filters.SelectMany(f => f.Extensions).Distinct().ToArray();
+
+
+            return RunPanel(panel, parent);
+        }
+
+
+
+        public async Task<string> ShowFolderDialogAsync(OpenFolderDialog dialog, IWindowImpl parent)
+        {
+            var panel = new NSOpenPanel
+            {
+                Title = dialog.Title,
+                CanChooseDirectories = true,
+                CanCreateDirectories = true,
+                CanChooseFiles = false
+            };
+            if (dialog.DefaultDirectory != null)
+                panel.Directory = dialog.DefaultDirectory;
+            return (await RunPanel(panel, parent))?.FirstOrDefault();
+        }
+    }
+}