Преглед изворни кода

Merge pull request #20 from AvaloniaUI/features/show-dialog

Features/show dialog
danwalmsley пре 7 година
родитељ
комит
9234d6ed9d

+ 1 - 0
samples/ControlCatalog/Pages/DialogsPage.xaml

@@ -8,5 +8,6 @@
           <TextBlock>Modal to window</TextBlock>
       </StackPanel>
       <Button Name="DecoratedWindow">Decorated window</Button>
+      <Button Name="ChildWindow">Child window</Button>
   </StackPanel>
 </UserControl>

+ 13 - 0
samples/ControlCatalog/Pages/DialogsPage.xaml.cs

@@ -34,6 +34,19 @@ namespace ControlCatalog.Pages
             {
                 new DecoratedWindow().Show();
             };
+            this.FindControl<Button>("ChildWindow").Click += delegate
+            {
+
+                var window = new Window
+                {
+                    Height = 200,
+                    Width = 200,
+                    Content = new Button{ Content = "Test"}
+                };
+
+                window.ShowDialog();
+
+            };
         }
 
         Window GetWindow() => this.FindControl<CheckBox>("IsModal").IsChecked.Value ? (Window)this.VisualRoot : null;

+ 1 - 0
src/Avalonia.Native.OSX/window.h

@@ -21,6 +21,7 @@ class WindowBaseImpl;
 @interface AvnWindow : NSWindow <NSWindowDelegate>
 -(AvnWindow*) initWithParent: (WindowBaseImpl*) parent;
 -(void) setCanBecomeKeyAndMain;
+-(void) pollModalSession: (nonnull NSModalSession) session;
 @end
 
 struct INSWindowHolder

+ 63 - 0
src/Avalonia.Native.OSX/window.mm

@@ -610,6 +610,23 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
     bool _canBecomeKeyAndMain;
 }
 
+- (void)pollModalSession:(nonnull NSModalSession)session
+{
+    auto response = [NSApp runModalSession:session];
+    
+    if(response == NSModalResponseContinue)
+    {
+        dispatch_async(dispatch_get_main_queue(), ^{
+            [self pollModalSession:session];
+        });
+    }
+    else
+    {
+        [self orderOut:self];
+        [NSApp endModalSession:session];
+    }
+}
+
 -(void) setCanBecomeKeyAndMain
 {
     _canBecomeKeyAndMain = true;
@@ -697,6 +714,30 @@ extern IAvnPopup* CreateAvnPopup(IAvnWindowEvents*events)
     return ptr;
 }
 
+class ModalDisposable : public ComUnknownObject
+{
+    NSModalSession _session;
+    AvnWindow* _window;
+    
+    void Dispose ()
+    {
+        [_window orderOut:_window];
+        [NSApp endModalSession:_session];
+    }
+    
+public:
+    ModalDisposable(AvnWindow* window, NSModalSession session)
+    {
+        _session = session;
+        _window = window;
+    }
+    
+    virtual ~ModalDisposable()
+    {
+        Dispose();
+    }
+};
+
 class WindowImpl : public WindowBaseImpl, public IAvnWindow, public IWindowStateChanged
 {
 private:
@@ -716,6 +757,28 @@ private:
         [Window setCanBecomeKeyAndMain];
     }
     
+    virtual HRESULT ShowDialog (IUnknown**ppv)
+    {
+        @autoreleasepool
+        {
+            if(ppv == nullptr)
+            {
+                return E_POINTER;
+            }
+            
+            auto session = [NSApp beginModalSessionForWindow:Window];
+            auto disposable = new ModalDisposable(Window, session);
+            *ppv = disposable;
+            
+            SetPosition(lastPositionSet);
+            UpdateStyle();
+            
+            [Window pollModalSession:session];
+            
+            return S_OK;
+        }
+    }
+    
     void WindowStateChanged ()
     {
         AvnWindowState state;

+ 1 - 1
src/Avalonia.Native/Avalonia.Native.csproj

@@ -21,7 +21,7 @@
       <Compile Remove="Generated\Structures.cs" />
     </ItemGroup>
 
-    <ItemGroup>
+    <ItemGroup Condition="'$(Configuration)' == 'Release'">
       <Content Include="../../Build/Products/Release/libAvalonia.Native.OSX.dylib">
         <PackagePath>runtimes/osx/native/libAvaloniaNative.dylib</PackagePath>
         <Pack>true</Pack>

+ 1 - 1
src/Avalonia.Native/WindowImpl.cs

@@ -33,7 +33,7 @@ namespace Avalonia.Native
 
         public IDisposable ShowDialog()
         {
-            return null;
+            return _native.ShowDialog();
         }
 
 

+ 1 - 1
src/headers/avalonia-native.h

@@ -136,6 +136,7 @@ AVNCOM(IAvnPopup, 03) : virtual IAvnWindowBase
 
 AVNCOM(IAvnWindow, 04) : virtual IAvnWindowBase
 {
+    virtual HRESULT ShowDialog (IUnknown**ppv) = 0;
     virtual HRESULT SetCanResize(bool value) = 0;
     virtual HRESULT SetHasDecorations(bool value) = 0;
     virtual HRESULT SetWindowState(AvnWindowState state) = 0;
@@ -182,7 +183,6 @@ AVNCOM(IAvnSignaledCallback, 09) : IUnknown
     virtual void Signaled(int priority, bool priorityContainsMeaningfulValue) = 0;
 };
 
-
 AVNCOM(IAvnLoopCancellation, 0a) : virtual IUnknown
 {
     virtual void Cancel() = 0;