Browse Source

Merge pull request #16 from AvaloniaUI/features/window-management

implement window state change events and manipulation.
pull/1977/head
danwalmsley 8 years ago
committed by GitHub
parent
commit
d1b0e06bb5
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      src/Avalonia.Native.OSX/window.h
  2. 137
      src/Avalonia.Native.OSX/window.mm
  3. 4
      src/Avalonia.Native/PopupImpl.cs
  4. 18
      src/Avalonia.Native/WindowImpl.cs
  5. 2
      src/Avalonia.Native/WindowImplBase.cs
  6. 12
      src/headers/avalonia-native.h

5
src/Avalonia.Native.OSX/window.h

@ -28,4 +28,9 @@ struct INSWindowHolder
virtual AvnWindow* GetNSWindow () = 0; virtual AvnWindow* GetNSWindow () = 0;
}; };
struct IWindowStateChanged
{
virtual void WindowStateChanged () = 0;
};
#endif /* window_h */ #endif /* window_h */

137
src/Avalonia.Native.OSX/window.mm

@ -44,6 +44,16 @@ public:
return S_OK; return S_OK;
} }
virtual HRESULT Activate ()
{
if(Window != nullptr)
{
[Window makeKeyWindow];
}
return S_OK;
}
virtual HRESULT SetTopMost (bool value) virtual HRESULT SetTopMost (bool value)
{ {
[Window setLevel: value ? NSFloatingWindowLevel : NSNormalWindowLevel]; [Window setLevel: value ? NSFloatingWindowLevel : NSNormalWindowLevel];
@ -187,6 +197,11 @@ protected:
{ {
[Window setStyleMask:GetStyle()]; [Window setStyleMask:GetStyle()];
} }
virtual void OnResized ()
{
}
}; };
NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEventTrackingRunLoopMode, NSModalPanelRunLoopMode, NSRunLoopCommonModes, NSConnectionReplyMode, nil]; NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEventTrackingRunLoopMode, NSModalPanelRunLoopMode, NSRunLoopCommonModes, NSConnectionReplyMode, nil];
@ -455,7 +470,6 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
[super scrollWheel:event]; [super scrollWheel:event];
} }
- (void)mouseEntered:(NSEvent *)event - (void)mouseEntered:(NSEvent *)event
{ {
_isMouseOver = true; _isMouseOver = true;
@ -541,6 +555,18 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
_parent->GetPosition(&position); _parent->GetPosition(&position);
_parent->BaseEvents->PositionChanged(position); _parent->BaseEvents->PositionChanged(position);
} }
// TODO this breaks resizing.
/*- (void)windowDidResize:(NSNotification *)notification
{
auto parent = dynamic_cast<IWindowStateChanged*>(_parent.operator->());
if(parent != nullptr)
{
parent->WindowStateChanged();
}
}*/
@end @end
class PopupImpl : public WindowBaseImpl, public IAvnPopup class PopupImpl : public WindowBaseImpl, public IAvnPopup
@ -570,11 +596,13 @@ extern IAvnPopup* CreateAvnPopup(IAvnWindowEvents*events)
return ptr; return ptr;
} }
class WindowImpl : public WindowBaseImpl, public IAvnWindow class WindowImpl : public WindowBaseImpl, public IAvnWindow, public IWindowStateChanged
{ {
private: private:
bool _canResize = true; bool _canResize = true;
bool _hasDecorations = true; bool _hasDecorations = true;
CGRect _lastUndecoratedFrame;
AvnWindowState _lastWindowState;
BEGIN_INTERFACE_MAP() BEGIN_INTERFACE_MAP()
INHERIT_INTERFACE_MAP(WindowBaseImpl) INHERIT_INTERFACE_MAP(WindowBaseImpl)
@ -587,6 +615,39 @@ private:
[Window setCanBecomeKeyAndMain]; [Window setCanBecomeKeyAndMain];
} }
void WindowStateChanged ()
{
AvnWindowState state;
GetWindowState(&state);
WindowEvents->WindowStateChanged(state);
}
bool UndecoratedIsMaximized ()
{
return CGRectEqualToRect([Window frame], [Window screen].visibleFrame);
}
bool IsZoomed ()
{
return _hasDecorations ? [Window isZoomed] : UndecoratedIsMaximized();
}
void DoZoom()
{
if (_hasDecorations)
{
[Window performZoom:Window];
}
else
{
if (!UndecoratedIsMaximized())
{
_lastUndecoratedFrame = [Window frame];
}
[Window zoom:Window];
}
}
virtual HRESULT SetCanResize(bool value) virtual HRESULT SetCanResize(bool value)
{ {
@ -602,7 +663,79 @@ private:
return S_OK; return S_OK;
} }
virtual HRESULT GetWindowState (AvnWindowState*ret)
{
if(ret == nullptr)
{
return E_POINTER;
}
if([Window isMiniaturized])
{
*ret = Minimized;
return S_OK;
}
if([Window isZoomed])
{
*ret = Maximized;
return S_OK;
}
*ret = Normal;
return S_OK;
}
virtual HRESULT SetWindowState (AvnWindowState state)
{
switch (state) {
case Maximized:
if([Window isMiniaturized])
{
[Window deminiaturize:Window];
}
if(!IsZoomed())
{
DoZoom();
}
break;
case Minimized:
[Window miniaturize:Window];
break;
default:
if([Window isMiniaturized])
{
[Window deminiaturize:Window];
}
if(IsZoomed())
{
DoZoom();
}
break;
}
return S_OK;
}
protected: protected:
virtual void OnResized ()
{
auto windowState = [Window isMiniaturized] ? Minimized
: (IsZoomed() ? Maximized : Normal);
if (windowState != _lastWindowState)
{
_lastWindowState = windowState;
WindowEvents->WindowStateChanged(windowState);
}
}
virtual NSWindowStyleMask GetStyle() virtual NSWindowStyleMask GetStyle()
{ {
unsigned long s = NSWindowStyleMaskBorderless; unsigned long s = NSWindowStyleMaskBorderless;

4
src/Avalonia.Native/PopupImpl.cs

@ -28,6 +28,10 @@ namespace Avalonia.Native
{ {
_parent = parent; _parent = parent;
} }
void IAvnWindowEvents.WindowStateChanged(AvnWindowState state)
{
}
} }
} }
} }

18
src/Avalonia.Native/WindowImpl.cs

@ -22,6 +22,11 @@ namespace Avalonia.Native
{ {
_parent = parent; _parent = parent;
} }
void IAvnWindowEvents.WindowStateChanged(AvnWindowState state)
{
_parent.WindowStateChanged?.Invoke((WindowState)state);
}
} }
public IAvnWindow Native => _native; public IAvnWindow Native => _native;
@ -46,7 +51,18 @@ namespace Avalonia.Native
{ {
} }
public WindowState WindowState { get; set; } = WindowState.Normal; public WindowState WindowState
{
get
{
return (WindowState)_native.GetWindowState();
}
set
{
_native.SetWindowState((AvnWindowState)value);
}
}
public Action<WindowState> WindowStateChanged { get; set; } public Action<WindowState> WindowStateChanged { get; set; }
public void ShowTaskbarIcon(bool value) public void ShowTaskbarIcon(bool value)

2
src/Avalonia.Native/WindowImplBase.cs

@ -162,7 +162,7 @@ namespace Avalonia.Native
public void Activate() public void Activate()
{ {
_native.Activate();
} }
public void RawMouseEvent(AvnRawMouseEventType type, uint timeStamp, AvnInputModifiers modifiers, AvnPoint point, AvnVector delta) public void RawMouseEvent(AvnRawMouseEventType type, uint timeStamp, AvnInputModifiers modifiers, AvnPoint point, AvnVector delta)

12
src/headers/avalonia-native.h

@ -82,6 +82,13 @@ enum AvnInputModifiers
MiddleMouseButton = 64 MiddleMouseButton = 64
}; };
enum AvnWindowState
{
Normal,
Minimized,
Maximized,
};
AVNCOM(IAvaloniaNativeFactory, 01) : virtual IUnknown AVNCOM(IAvaloniaNativeFactory, 01) : virtual IUnknown
{ {
public: public:
@ -100,6 +107,7 @@ AVNCOM(IAvnWindowBase, 02) : virtual IUnknown
virtual HRESULT Show() = 0; virtual HRESULT Show() = 0;
virtual HRESULT Hide () = 0; virtual HRESULT Hide () = 0;
virtual HRESULT Close() = 0; virtual HRESULT Close() = 0;
virtual HRESULT Activate () = 0;
virtual HRESULT GetClientSize(AvnSize*ret) = 0; virtual HRESULT GetClientSize(AvnSize*ret) = 0;
virtual HRESULT GetMaxClientSize(AvnSize* ret) = 0; virtual HRESULT GetMaxClientSize(AvnSize* ret) = 0;
virtual HRESULT GetScaling(double*ret)=0; virtual HRESULT GetScaling(double*ret)=0;
@ -123,6 +131,8 @@ AVNCOM(IAvnWindow, 04) : virtual IAvnWindowBase
{ {
virtual HRESULT SetCanResize(bool value) = 0; virtual HRESULT SetCanResize(bool value) = 0;
virtual HRESULT SetHasDecorations(bool value) = 0; virtual HRESULT SetHasDecorations(bool value) = 0;
virtual HRESULT SetWindowState(AvnWindowState state) = 0;
virtual HRESULT GetWindowState(AvnWindowState*ret) = 0;
}; };
AVNCOM(IAvnWindowBaseEvents, 05) : IUnknown AVNCOM(IAvnWindowBaseEvents, 05) : IUnknown
@ -145,7 +155,7 @@ AVNCOM(IAvnWindowBaseEvents, 05) : IUnknown
AVNCOM(IAvnWindowEvents, 06) : IAvnWindowBaseEvents AVNCOM(IAvnWindowEvents, 06) : IAvnWindowBaseEvents
{ {
virtual void WindowStateChanged (AvnWindowState state) = 0;
}; };
AVNCOM(IAvnMacOptions, 07) : virtual IUnknown AVNCOM(IAvnMacOptions, 07) : virtual IUnknown

Loading…
Cancel
Save