From bd7b3c463b93bc6c14f4386af2e5d28027b15031 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Sun, 16 Sep 2018 12:43:35 +0100 Subject: [PATCH] implement popups. --- src/Avalonia.Native.OSX/common.h | 1 + src/Avalonia.Native.OSX/main.mm | 11 +++++- src/Avalonia.Native.OSX/window.mm | 36 ++++++++++++++++++- src/Avalonia.Native/AvaloniaNativePlatform.cs | 4 +-- src/Avalonia.Native/PopupImpl.cs | 27 ++++++++++++++ src/Avalonia.Native/WindowImplBase.cs | 1 + src/headers/avalonia-native.h | 24 ++++++++----- 7 files changed, 92 insertions(+), 12 deletions(-) create mode 100644 src/Avalonia.Native/PopupImpl.cs diff --git a/src/Avalonia.Native.OSX/common.h b/src/Avalonia.Native.OSX/common.h index 5fd7e57556..303298ba02 100644 --- a/src/Avalonia.Native.OSX/common.h +++ b/src/Avalonia.Native.OSX/common.h @@ -9,4 +9,5 @@ extern IAvnPlatformThreadingInterface* CreatePlatformThreading(); extern IAvnWindow* CreateAvnWindow(IAvnWindowEvents*events); +extern IAvnPopup* CreateAvnPopup(IAvnWindowEvents*events); #endif diff --git a/src/Avalonia.Native.OSX/main.mm b/src/Avalonia.Native.OSX/main.mm index 0d6b2a978d..a04ed11a1e 100644 --- a/src/Avalonia.Native.OSX/main.mm +++ b/src/Avalonia.Native.OSX/main.mm @@ -80,11 +80,20 @@ public: return S_OK; }; + virtual HRESULT CreatePopup(IAvnWindowEvents* cb, IAvnPopup** ppv) + { + if(cb == nullptr || ppv == nullptr) + return E_POINTER; + + *ppv = CreateAvnPopup(cb); + return S_OK; + } + virtual HRESULT CreatePlatformThreadingInterface(IAvnPlatformThreadingInterface** ppv) { *ppv = CreatePlatformThreading(); return S_OK; - }; + } }; extern "C" IAvaloniaNativeFactory* CreateAvaloniaNative() diff --git a/src/Avalonia.Native.OSX/window.mm b/src/Avalonia.Native.OSX/window.mm index f69bec5704..9e2abfead1 100644 --- a/src/Avalonia.Native.OSX/window.mm +++ b/src/Avalonia.Native.OSX/window.mm @@ -35,6 +35,15 @@ public: return S_OK; } + virtual HRESULT Hide () + { + if(Window != nullptr) + { + [Window orderOut:Window]; + } + return S_OK; + } + virtual HRESULT Close() { [Window close]; @@ -368,6 +377,32 @@ protected: @end +class PopupImpl : public WindowBaseImpl, public IAvnPopup +{ +private: + BEGIN_INTERFACE_MAP() + INHERIT_INTERFACE_MAP(WindowBaseImpl) + INTERFACE_MAP_ENTRY(IAvnPopup, IID_IAvnPopup) + END_INTERFACE_MAP() + ComPtr WindowEvents; + PopupImpl(IAvnWindowEvents* events) : WindowBaseImpl(events) + { + WindowEvents = events; + [Window setLevel:NSPopUpMenuWindowLevel]; + } + +protected: + virtual NSWindowStyleMask GetStyle() + { + return NSWindowStyleMaskBorderless; + } +}; + +extern IAvnPopup* CreateAvnPopup(IAvnWindowEvents*events) +{ + IAvnPopup* ptr = dynamic_cast(new PopupImpl(events)); + return ptr; +} class WindowImpl : public WindowBaseImpl, public IAvnWindow { @@ -413,7 +448,6 @@ protected: } }; - extern IAvnWindow* CreateAvnWindow(IAvnWindowEvents*events) { IAvnWindow* ptr = dynamic_cast(new WindowImpl(events)); diff --git a/src/Avalonia.Native/AvaloniaNativePlatform.cs b/src/Avalonia.Native/AvaloniaNativePlatform.cs index ed9acb1d6f..515f56167f 100644 --- a/src/Avalonia.Native/AvaloniaNativePlatform.cs +++ b/src/Avalonia.Native/AvaloniaNativePlatform.cs @@ -88,8 +88,8 @@ namespace Avalonia.Native } public IPopupImpl CreatePopup() - { - throw new NotImplementedException(); + { + return new PopupImpl(_factory); } } diff --git a/src/Avalonia.Native/PopupImpl.cs b/src/Avalonia.Native/PopupImpl.cs new file mode 100644 index 0000000000..bed2b3f929 --- /dev/null +++ b/src/Avalonia.Native/PopupImpl.cs @@ -0,0 +1,27 @@ +using System; +using Avalonia.Native.Interop; +using Avalonia.Platform; + +namespace Avalonia.Native +{ + public class PopupImpl : WindowBaseImpl, IPopupImpl + { + IAvnPopup _native; + + public PopupImpl(IAvaloniaNativeFactory factory) + { + using (var e = new PopupEvents(this)) + Init(_native = factory.CreatePopup(e)); + } + + class PopupEvents : WindowBaseEvents, IAvnWindowEvents + { + readonly PopupImpl _parent; + + public PopupEvents(PopupImpl parent) : base(parent) + { + _parent = parent; + } + } + } +} diff --git a/src/Avalonia.Native/WindowImplBase.cs b/src/Avalonia.Native/WindowImplBase.cs index 9f1a7deedb..b5defeda6a 100644 --- a/src/Avalonia.Native/WindowImplBase.cs +++ b/src/Avalonia.Native/WindowImplBase.cs @@ -197,6 +197,7 @@ namespace Avalonia.Native public void Hide() { + _native.Hide(); } public void BeginMoveDrag() diff --git a/src/headers/avalonia-native.h b/src/headers/avalonia-native.h index 1509f01a57..110dc0f425 100644 --- a/src/headers/avalonia-native.h +++ b/src/headers/avalonia-native.h @@ -4,6 +4,7 @@ struct IAvnWindowEvents; struct IAvnWindow; +struct IAvnPopup; struct IAvnMacOptions; struct IAvnPlatformThreadingInterface; @@ -59,12 +60,14 @@ public: virtual HRESULT Initialize() = 0; virtual IAvnMacOptions* GetMacOptions() = 0; virtual HRESULT CreateWindow(IAvnWindowEvents* cb, IAvnWindow** ppv) = 0; + virtual HRESULT CreatePopup (IAvnWindowEvents* cb, IAvnPopup** ppv) = 0; virtual HRESULT CreatePlatformThreadingInterface(IAvnPlatformThreadingInterface** ppv) = 0; }; AVNCOM(IAvnWindowBase, 02) : virtual IUnknown { virtual HRESULT Show() = 0; + virtual HRESULT Hide () = 0; virtual HRESULT Close() = 0; virtual HRESULT GetClientSize(AvnSize*ret) = 0; virtual HRESULT Resize(double width, double height) = 0; @@ -72,13 +75,18 @@ AVNCOM(IAvnWindowBase, 02) : virtual IUnknown virtual void BeginMoveDrag () = 0; }; -AVNCOM(IAvnWindow, 03) : virtual IAvnWindowBase +AVNCOM(IAvnPopup, 03) : virtual IAvnWindowBase +{ + +}; + +AVNCOM(IAvnWindow, 04) : virtual IAvnWindowBase { virtual HRESULT SetCanResize(bool value) = 0; virtual HRESULT SetHasDecorations(bool value) = 0; }; -AVNCOM(IAvnWindowBaseEvents, 04) : IUnknown +AVNCOM(IAvnWindowBaseEvents, 05) : IUnknown { virtual HRESULT SoftwareDraw(void* ptr, int stride, int pixelWidth, int pixelHeight, const AvnSize& logicalSize) = 0; virtual void Closed() = 0; @@ -93,33 +101,33 @@ AVNCOM(IAvnWindowBaseEvents, 04) : IUnknown }; -AVNCOM(IAvnWindowEvents, 05) : IAvnWindowBaseEvents +AVNCOM(IAvnWindowEvents, 06) : IAvnWindowBaseEvents { }; -AVNCOM(IAvnMacOptions, 06) : virtual IUnknown +AVNCOM(IAvnMacOptions, 07) : virtual IUnknown { virtual HRESULT SetShowInDock(int show) = 0; }; -AVNCOM(IAvnActionCallback, 07) : IUnknown +AVNCOM(IAvnActionCallback, 08) : IUnknown { virtual void Run() = 0; }; -AVNCOM(IAvnSignaledCallback, 08) : IUnknown +AVNCOM(IAvnSignaledCallback, 09) : IUnknown { virtual void Signaled(int priority, bool priorityContainsMeaningfulValue) = 0; }; -AVNCOM(IAvnLoopCancellation, 09) : virtual IUnknown +AVNCOM(IAvnLoopCancellation, 0a) : virtual IUnknown { virtual void Cancel() = 0; }; -AVNCOM(IAvnPlatformThreadingInterface, 0a) : virtual IUnknown +AVNCOM(IAvnPlatformThreadingInterface, 0b) : virtual IUnknown { virtual bool GetCurrentThreadIsLoopThread() = 0; virtual void SetSignaledCallback(IAvnSignaledCallback* cb) = 0;