Browse Source

add a modal window implementation

pull/1977/head
Dan Walmsley 8 years ago
parent
commit
2758a5839e
  1. 1
      samples/ControlCatalog/Pages/DialogsPage.xaml
  2. 13
      samples/ControlCatalog/Pages/DialogsPage.xaml.cs
  3. 1
      src/Avalonia.Native.OSX/window.h
  4. 63
      src/Avalonia.Native.OSX/window.mm
  5. 2
      src/Avalonia.Native/WindowImpl.cs
  6. 2
      src/headers/avalonia-native.h

1
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
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
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
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;

2
src/Avalonia.Native/WindowImpl.cs

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

2
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;

Loading…
Cancel
Save