Skip to content

Commit

Permalink
Merge pull request #16 from AvaloniaUI/features/window-management
Browse files Browse the repository at this point in the history
implement window state change events and manipulation.
  • Loading branch information
danwalmsley authored Oct 1, 2018
2 parents d9cbcd5 + 64d439e commit d1b0e06
Show file tree
Hide file tree
Showing 6 changed files with 173 additions and 5 deletions.
5 changes: 5 additions & 0 deletions src/Avalonia.Native.OSX/window.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,9 @@ struct INSWindowHolder
virtual AvnWindow* GetNSWindow () = 0;
};

struct IWindowStateChanged
{
virtual void WindowStateChanged () = 0;
};

#endif /* window_h */
137 changes: 135 additions & 2 deletions src/Avalonia.Native.OSX/window.mm
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,16 @@ virtual HRESULT Hide ()
return S_OK;
}

virtual HRESULT Activate ()
{
if(Window != nullptr)
{
[Window makeKeyWindow];
}

return S_OK;
}

virtual HRESULT SetTopMost (bool value)
{
[Window setLevel: value ? NSFloatingWindowLevel : NSNormalWindowLevel];
Expand Down Expand Up @@ -187,6 +197,11 @@ void UpdateStyle()
{
[Window setStyleMask:GetStyle()];
}

virtual void OnResized ()
{

}
};

NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEventTrackingRunLoopMode, NSModalPanelRunLoopMode, NSRunLoopCommonModes, NSConnectionReplyMode, nil];
Expand Down Expand Up @@ -455,7 +470,6 @@ - (void)scrollWheel:(NSEvent *)event
[super scrollWheel:event];
}


- (void)mouseEntered:(NSEvent *)event
{
_isMouseOver = true;
Expand Down Expand Up @@ -541,6 +555,18 @@ - (void)windowDidMove:(NSNotification *)notification
_parent->GetPosition(&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

class PopupImpl : public WindowBaseImpl, public IAvnPopup
Expand Down Expand Up @@ -570,11 +596,13 @@ virtual NSWindowStyleMask GetStyle()
return ptr;
}

class WindowImpl : public WindowBaseImpl, public IAvnWindow
class WindowImpl : public WindowBaseImpl, public IAvnWindow, public IWindowStateChanged
{
private:
bool _canResize = true;
bool _hasDecorations = true;
CGRect _lastUndecoratedFrame;
AvnWindowState _lastWindowState;

BEGIN_INTERFACE_MAP()
INHERIT_INTERFACE_MAP(WindowBaseImpl)
Expand All @@ -587,6 +615,39 @@ virtual NSWindowStyleMask GetStyle()
[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)
{
Expand All @@ -602,7 +663,79 @@ virtual HRESULT SetHasDecorations(bool value)
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:
virtual void OnResized ()
{
auto windowState = [Window isMiniaturized] ? Minimized
: (IsZoomed() ? Maximized : Normal);

if (windowState != _lastWindowState)
{
_lastWindowState = windowState;

WindowEvents->WindowStateChanged(windowState);
}
}

virtual NSWindowStyleMask GetStyle()
{
unsigned long s = NSWindowStyleMaskBorderless;
Expand Down
4 changes: 4 additions & 0 deletions src/Avalonia.Native/PopupImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ public PopupEvents(PopupImpl parent) : base(parent)
{
_parent = parent;
}

void IAvnWindowEvents.WindowStateChanged(AvnWindowState state)
{
}
}
}
}
18 changes: 17 additions & 1 deletion src/Avalonia.Native/WindowImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ public WindowEvents(WindowImpl parent) : base(parent)
{
_parent = parent;
}

void IAvnWindowEvents.WindowStateChanged(AvnWindowState state)
{
_parent.WindowStateChanged?.Invoke((WindowState)state);
}
}

public IAvnWindow Native => _native;
Expand All @@ -46,7 +51,18 @@ public void SetTitle(string title)
{
}

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 void ShowTaskbarIcon(bool value)
Expand Down
2 changes: 1 addition & 1 deletion src/Avalonia.Native/WindowImplBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ void IAvnWindowBaseEvents.RunRenderPriorityJobs()

public void Activate()
{

_native.Activate();
}

public void RawMouseEvent(AvnRawMouseEventType type, uint timeStamp, AvnInputModifiers modifiers, AvnPoint point, AvnVector delta)
Expand Down
12 changes: 11 additions & 1 deletion src/headers/avalonia-native.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,13 @@ enum AvnInputModifiers
MiddleMouseButton = 64
};

enum AvnWindowState
{
Normal,
Minimized,
Maximized,
};

AVNCOM(IAvaloniaNativeFactory, 01) : virtual IUnknown
{
public:
Expand All @@ -100,6 +107,7 @@ AVNCOM(IAvnWindowBase, 02) : virtual IUnknown
virtual HRESULT Show() = 0;
virtual HRESULT Hide () = 0;
virtual HRESULT Close() = 0;
virtual HRESULT Activate () = 0;
virtual HRESULT GetClientSize(AvnSize*ret) = 0;
virtual HRESULT GetMaxClientSize(AvnSize* ret) = 0;
virtual HRESULT GetScaling(double*ret)=0;
Expand All @@ -123,6 +131,8 @@ AVNCOM(IAvnWindow, 04) : virtual IAvnWindowBase
{
virtual HRESULT SetCanResize(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
Expand All @@ -145,7 +155,7 @@ AVNCOM(IAvnWindowBaseEvents, 05) : IUnknown

AVNCOM(IAvnWindowEvents, 06) : IAvnWindowBaseEvents
{

virtual void WindowStateChanged (AvnWindowState state) = 0;
};

AVNCOM(IAvnMacOptions, 07) : virtual IUnknown
Expand Down

0 comments on commit d1b0e06

Please sign in to comment.