Browse Source

working updating menus inside needsupdate event.

pull/3762/head
Dan Walmsley 6 years ago
parent
commit
24ea90e2ef
  1. 2
      native/Avalonia.Native/inc/avalonia-native.h
  2. 2
      native/Avalonia.Native/src/OSX/menu.h
  3. 10
      native/Avalonia.Native/src/OSX/menu.mm
  4. 7
      src/Avalonia.Controls/NativeMenu.cs
  5. 12
      src/Avalonia.Native/AvaloniaNativeMenuExporter.cs
  6. 42
      src/Avalonia.Native/IAvnMenu.cs
  7. 2
      src/Avalonia.Native/IAvnMenuItem.cs

2
native/Avalonia.Native/inc/avalonia-native.h

@ -416,7 +416,7 @@ AVNCOM(IAvnMenuEvents, 1A) : IUnknown
/**
* NeedsUpdate
*/
virtual bool NeedUpdate () = 0;
virtual void NeedsUpdate () = 0;
};
extern "C" IAvaloniaNativeFactory* CreateAvaloniaNative();

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

@ -67,6 +67,8 @@ public:
AvnMenu* GetNative();
void RaiseNeedsUpdate ();
virtual HRESULT InsertItem (int index, IAvnMenuItem* item) override;
virtual HRESULT RemoveItem (IAvnMenuItem* item) override;

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

@ -167,6 +167,14 @@ AvnMenu* AvnAppMenu::GetNative()
return _native;
}
void AvnAppMenu::RaiseNeedsUpdate()
{
if(_baseEvents != nullptr)
{
_baseEvents->NeedsUpdate();
}
}
HRESULT AvnAppMenu::InsertItem(int index, IAvnMenuItem *item)
{
auto avnMenuItem = dynamic_cast<AvnAppMenuItem*>(item);
@ -231,7 +239,7 @@ HRESULT AvnAppMenu::Clear()
- (void)menuNeedsUpdate:(NSMenu *)menu
{
printf("NEEDSUPDATE\n");
_parent->RaiseNeedsUpdate();
}

7
src/Avalonia.Controls/NativeMenu.cs

@ -15,12 +15,19 @@ namespace Avalonia.Controls
[Content]
public IList<NativeMenuItemBase> Items => _items;
public event EventHandler<EventArgs> NeedsUpdate;
public NativeMenu()
{
_items.Validate = Validator;
_items.CollectionChanged += ItemsChanged;
}
public void RaiseNeedsUpdate ()
{
NeedsUpdate?.Invoke(this, EventArgs.Empty);
}
private void Validator(NativeMenuItemBase obj)
{
if (obj.Parent != null)

12
src/Avalonia.Native/AvaloniaNativeMenuExporter.cs

@ -43,6 +43,14 @@ namespace Avalonia.Native
DoLayoutReset();
}
internal void InvalidateMenu ()
{
if(_resetQueued)
{
DoLayoutReset();
}
}
private static NativeMenu CreateDefaultAppMenu()
{
var result = new NativeMenu();
@ -127,7 +135,7 @@ namespace Avalonia.Native
if (_nativeMenu is null)
{
_nativeMenu = _factory.CreateMenu();
_nativeMenu = IAvnMenu.Create(_factory);
_nativeMenu.Initialise(this, appMenuHolder, "");
@ -151,7 +159,7 @@ namespace Avalonia.Native
if (_nativeMenu is null)
{
_nativeMenu = _factory.CreateMenu();
_nativeMenu = IAvnMenu.Create(_factory);
_nativeMenu.Initialise(this, menu, "");
}

42
src/Avalonia.Native/IAvnMenu.cs

@ -7,15 +7,57 @@ using Avalonia.Platform.Interop;
namespace Avalonia.Native.Interop
{
class MenuEvents : CallbackBase, IAvnMenuEvents
{
private IAvnMenu _parent;
public void Initialise(IAvnMenu parent)
{
_parent = parent;
}
public void NeedsUpdate()
{
_parent?.RaiseNeedsUpdate();
}
}
public partial class IAvnMenu
{
private MenuEvents _events;
private AvaloniaNativeMenuExporter _exporter;
private List<IAvnMenuItem> _menuItems = new List<IAvnMenuItem>();
private Dictionary<NativeMenuItemBase, IAvnMenuItem> _menuItemLookup = new Dictionary<NativeMenuItemBase, IAvnMenuItem>();
private CompositeDisposable _propertyDisposables = new CompositeDisposable();
internal void RaiseNeedsUpdate ()
{
ManagedMenu.RaiseNeedsUpdate();
_exporter.InvalidateMenu();
}
internal NativeMenu ManagedMenu { get; private set; }
public static IAvnMenu Create (IAvaloniaNativeFactory factory)
{
var events = new MenuEvents();
var menu = factory.CreateMenu(events);
events.Initialise(menu);
return menu;
}
protected override void Dispose(bool disposing)
{
if(disposing)
{
_events.Dispose();
}
}
private void RemoveAndDispose(IAvnMenuItem item)
{
_menuItemLookup.Remove(item.ManagedMenuItem);

2
src/Avalonia.Native/IAvnMenuItem.cs

@ -114,7 +114,7 @@ namespace Avalonia.Native.Interop
{
if (_subMenu == null)
{
_subMenu = factory.CreateMenu();
_subMenu = IAvnMenu.Create(factory);
_subMenu.Initialise(exporter, item.Menu, item.Header);

Loading…
Cancel
Save