Browse Source

Added Opening/Closed for NativeMenu on OSX.

Adds the `Opening` and `Closed` events for OSX to `NativeMenu` which relate to `menuWillOpen` and `menuDidClose`. Note that `NativeMenu` already exposed `NeedsUpdate` as `Opening`; this event has been moved to a separate `NeedsUpdate` event.
pull/5675/head
Steven Kirk 5 years ago
parent
commit
89e5f3888d
  1. 5
      native/Avalonia.Native/src/OSX/menu.h
  2. 26
      native/Avalonia.Native/src/OSX/menu.mm
  3. 2
      src/Avalonia.Controls/INativeMenuExporterEventsImplBridge.cs
  4. 33
      src/Avalonia.Controls/NativeMenu.cs
  5. 22
      src/Avalonia.Native/IAvnMenu.cs
  6. 5
      src/Avalonia.Native/avn.idl

5
native/Avalonia.Native/src/OSX/menu.h

@ -60,7 +60,6 @@ public:
void RaiseOnClicked();
};
class AvnAppMenu : public ComSingleObject<IAvnMenu, &IID_IAvnMenu>
{
private:
@ -71,10 +70,12 @@ public:
FORWARD_IUNKNOWN()
AvnAppMenu(IAvnMenuEvents* events);
AvnMenu* GetNative();
void RaiseNeedsUpdate ();
void RaiseOpening();
void RaiseClosed();
virtual HRESULT InsertItem (int index, IAvnMenuItem* item) override;

26
native/Avalonia.Native/src/OSX/menu.mm

@ -298,6 +298,23 @@ void AvnAppMenu::RaiseNeedsUpdate()
}
}
void AvnAppMenu::RaiseOpening()
{
if(_baseEvents != nullptr)
{
_baseEvents->Opening();
}
}
void AvnAppMenu::RaiseClosed()
{
if(_baseEvents != nullptr)
{
_baseEvents->Closed();
}
}
HRESULT AvnAppMenu::InsertItem(int index, IAvnMenuItem *item)
{
@autoreleasepool
@ -382,6 +399,15 @@ HRESULT AvnAppMenu::Clear()
_parent->RaiseNeedsUpdate();
}
- (void)menuWillOpen:(NSMenu *)menu
{
_parent->RaiseOpening();
}
- (void)menuDidClose:(NSMenu *)menu
{
_parent->RaiseClosed();
}
@end

2
src/Avalonia.Controls/INativeMenuExporterEventsImplBridge.cs

@ -3,5 +3,7 @@ namespace Avalonia.Controls
public interface INativeMenuExporterEventsImplBridge
{
void RaiseNeedsUpdate ();
void RaiseOpening();
void RaiseClosed();
}
}

33
src/Avalonia.Controls/NativeMenu.cs

@ -12,13 +12,34 @@ namespace Avalonia.Controls
private readonly AvaloniaList<NativeMenuItemBase> _items =
new AvaloniaList<NativeMenuItemBase> { ResetBehavior = ResetBehavior.Remove };
private NativeMenuItem _parent;
[Content]
public IList<NativeMenuItemBase> Items => _items;
/// <summary>
/// Raised when the user clicks the menu and before its opened. Use this event to update the menu dynamically.
/// Raised when the menu requests an update.
/// </summary>
/// <remarks>
/// Use this event to add, remove or modify menu items before a menu is
/// shown or a hotkey is pressed.
/// </remarks>
public event EventHandler<EventArgs> NeedsUpdate;
/// <summary>
/// Raised before the menu is opened.
/// </summary>
/// <remarks>
/// Do not update the menu in this event; use <see cref="NeedsUpdate"/>.
/// </remarks>
public event EventHandler<EventArgs> Opening;
/// <summary>
/// Raised after the menu is closed.
/// </summary>
/// <remarks>
/// Do not update the menu in this event; use <see cref="NeedsUpdate"/>.
/// </remarks>
public event EventHandler<EventArgs> Closed;
public NativeMenu()
{
@ -27,10 +48,20 @@ namespace Avalonia.Controls
}
void INativeMenuExporterEventsImplBridge.RaiseNeedsUpdate()
{
NeedsUpdate?.Invoke(this, EventArgs.Empty);
}
void INativeMenuExporterEventsImplBridge.RaiseOpening()
{
Opening?.Invoke(this, EventArgs.Empty);
}
void INativeMenuExporterEventsImplBridge.RaiseClosed()
{
Closed?.Invoke(this, EventArgs.Empty);
}
private void Validator(NativeMenuItemBase obj)
{
if (obj.Parent != null)

22
src/Avalonia.Native/IAvnMenu.cs

@ -20,11 +20,23 @@ namespace Avalonia.Native.Interop
{
_parent?.RaiseNeedsUpdate();
}
public void Opening()
{
_parent?.RaiseOpening();
}
public void Closed()
{
_parent?.RaiseClosed();
}
}
partial interface IAvnMenu
{
void RaiseNeedsUpdate();
void RaiseOpening();
void RaiseClosed();
void Deinitialise();
}
}
@ -45,6 +57,16 @@ namespace Avalonia.Native.Interop.Impl
_exporter.UpdateIfNeeded();
}
public void RaiseOpening()
{
(ManagedMenu as INativeMenuExporterEventsImplBridge).RaiseOpening();
}
public void RaiseClosed()
{
(ManagedMenu as INativeMenuExporterEventsImplBridge).RaiseClosed();
}
internal NativeMenu ManagedMenu { get; private set; }
public static __MicroComIAvnMenuProxy Create(IAvaloniaNativeFactory factory)

5
src/Avalonia.Native/avn.idl

@ -685,10 +685,9 @@ interface IAvnMenuItem : IUnknown
[uuid(0af7df53-7632-42f4-a650-0992c361b477)]
interface IAvnMenuEvents : IUnknown
{
/**
* NeedsUpdate
*/
void NeedsUpdate();
void Opening();
void Closed();
}
[uuid(5142bb41-66ab-49e7-bb37-cd079c000f27)]

Loading…
Cancel
Save