Browse Source

add interfaces required for system dialogs

pull/1977/head
Dan Walmsley 7 years ago
parent
commit
7b4275b2d5
  1. 1
      src/Avalonia.Native/AvaloniaNativePlatform.cs
  2. 85
      src/Avalonia.Native/SystemDialogs.cs
  3. 28
      src/headers/avalonia-native.h

1
src/Avalonia.Native/AvaloniaNativePlatform.cs

@ -74,6 +74,7 @@ namespace Avalonia.Native
.Bind<IClipboard>().ToSingleton<ClipboardImpl>()
.Bind<IRenderLoop>().ToConstant(new RenderLoop())
.Bind<IRenderTimer>().ToConstant(new DefaultRenderTimer(60))
.Bind<ISystemDialogImpl>().ToConstant(new SystemDialogs(_factory.CreateSystemDialogs()))
.Bind<IPlatformThreadingInterface>().ToConstant(new PlatformThreadingInterface(_factory.CreatePlatformThreadingInterface()));
}

85
src/Avalonia.Native/SystemDialogs.cs

@ -0,0 +1,85 @@
using System;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Avalonia.Controls;
using Avalonia.Controls.Platform;
using Avalonia.Native.Interop;
using Avalonia.Platform;
namespace Avalonia.Native
{
public class SystemDialogs : ISystemDialogImpl
{
IAvnSystemDialogs _native;
public SystemDialogs(IAvnSystemDialogs native)
{
_native = native;
}
public Task<string[]> ShowFileDialogAsync(FileDialog dialog, IWindowImpl parent)
{
var events = new SystemDialogEvents();
if(dialog is OpenFileDialog ofd)
{
_native.OpenFileDialog(events, ofd.AllowMultiple,
ofd.Title,
ofd.InitialDirectory,
ofd.InitialFileName,
string.Join(";", dialog.Filters.SelectMany(f => f.Extensions)));
}
else
{
_native.SaveFileDialog(events,
dialog.Title,
dialog.InitialDirectory,
dialog.InitialFileName,
string.Join(";", dialog.Filters.SelectMany(f => f.Extensions)));
}
return events.Task;
}
public async Task<string> ShowFolderDialogAsync(OpenFolderDialog dialog, IWindowImpl parent)
{
var events = new SystemDialogEvents();
_native.SelectFolderDialog(events, dialog.Title, dialog.InitialDirectory);
return (await events.Task).FirstOrDefault();
}
}
public class SystemDialogEvents : CallbackBase, IAvnSystemDialogEvents
{
private TaskCompletionSource<string[]> _tcs;
public SystemDialogEvents()
{
_tcs = new TaskCompletionSource<string[]>();
}
public Task<string[]> Task => _tcs.Task;
public void OnCompleted(int numResults, IntPtr trFirstResultRef)
{
string[] results = new string[numResults];
unsafe
{
var ptr = (IntPtr*)trFirstResultRef.ToPointer();
for (int i = 0; i < numResults; i++)
{
results[i] = Marshal.PtrToStringAnsi(*ptr);
ptr++;
}
}
_tcs.SetResult(results);
}
}
}

28
src/headers/avalonia-native.h

@ -7,6 +7,8 @@ struct IAvnWindow;
struct IAvnPopup;
struct IAvnMacOptions;
struct IAvnPlatformThreadingInterface;
struct IAvnSystemDialogEvents;
struct IAvnSystemDialogs;
struct AvnSize
{
@ -62,6 +64,7 @@ public:
virtual HRESULT CreateWindow(IAvnWindowEvents* cb, IAvnWindow** ppv) = 0;
virtual HRESULT CreatePopup (IAvnWindowEvents* cb, IAvnPopup** ppv) = 0;
virtual HRESULT CreatePlatformThreadingInterface(IAvnPlatformThreadingInterface** ppv) = 0;
virtual HRESULT CreateSystemDialogs (IAvnSystemDialogs** ppv) = 0;
};
AVNCOM(IAvnWindowBase, 02) : virtual IUnknown
@ -143,4 +146,29 @@ AVNCOM(IAvnPlatformThreadingInterface, 0b) : virtual IUnknown
virtual IUnknown* StartTimer(int priority, int ms, IAvnActionCallback* callback) = 0;
};
AVNCOM(IAvnSystemDialogEvents, 0c) : virtual IUnknown
{
virtual void OnCompleted (int numResults, void* ptrFirstResult) = 0;
};
AVNCOM(IAvnSystemDialogs, 0d) : virtual IUnknown
{
virtual void SelectFolderDialog (IAvnSystemDialogEvents* events,
const char* title,
const char* initialPath) = 0;
virtual void OpenFileDialog (IAvnSystemDialogEvents* events,
bool allowMultiple,
const char* title,
const char* initialDirectory,
const char* intialFile,
const char* filters) = 0;
virtual void SaveFileDialog (IAvnSystemDialogEvents* events,
const char* title,
const char* initialDirectory,
const char* intialFile,
const char* filters) = 0;
};
extern "C" IAvaloniaNativeFactory* CreateAvaloniaNative();

Loading…
Cancel
Save