diff --git a/native/Avalonia.Native/inc/avalonia-native.h b/native/Avalonia.Native/inc/avalonia-native.h index 757c0bc85a..7fde6b3360 100644 --- a/native/Avalonia.Native/inc/avalonia-native.h +++ b/native/Avalonia.Native/inc/avalonia-native.h @@ -176,6 +176,13 @@ enum AvnWindowEdge WindowEdgeSouthEast }; +enum AvnMenuItemToggleType +{ + None, + CheckMark, + Radio +}; + AVNCOM(IAvaloniaNativeFactory, 01) : IUnknown { public: @@ -407,6 +414,7 @@ AVNCOM(IAvnMenuItem, 19) : IUnknown virtual HRESULT SetGesture (void* utf8String, AvnInputModifiers modifiers) = 0; virtual HRESULT SetAction (IAvnPredicateCallback* predicate, IAvnActionCallback* callback) = 0; virtual HRESULT SetIsChecked (bool isChecked) = 0; + virtual HRESULT SetToggleType (AvnMenuItemToggleType toggleType) = 0; }; AVNCOM(IAvnMenuEvents, 1A) : IUnknown diff --git a/native/Avalonia.Native/src/OSX/menu.h b/native/Avalonia.Native/src/OSX/menu.h index 228731cb28..cd464d2169 100644 --- a/native/Avalonia.Native/src/OSX/menu.h +++ b/native/Avalonia.Native/src/OSX/menu.h @@ -32,6 +32,7 @@ private: IAvnActionCallback* _callback; IAvnPredicateCallback* _predicate; bool _isSeperator; + bool _isCheckable; public: FORWARD_IUNKNOWN() @@ -50,6 +51,8 @@ public: virtual HRESULT SetIsChecked (bool isChecked) override; + virtual HRESULT SetToggleType (AvnMenuItemToggleType toggleType) override; + bool EvaluateItemEnabled(); void RaiseOnClicked(); diff --git a/native/Avalonia.Native/src/OSX/menu.mm b/native/Avalonia.Native/src/OSX/menu.mm index 1cd9cb0644..11a8f04ae3 100644 --- a/native/Avalonia.Native/src/OSX/menu.mm +++ b/native/Avalonia.Native/src/OSX/menu.mm @@ -70,6 +70,7 @@ AvnAppMenuItem::AvnAppMenuItem(bool isSeperator) { + _isCheckable = false; _isSeperator = isSeperator; if(isSeperator) @@ -157,7 +158,36 @@ HRESULT AvnAppMenuItem::SetIsChecked (bool isChecked) { @autoreleasepool { - [_native setState:(isChecked ? NSOnState : NSOffState)]; + [_native setState:(isChecked && _isCheckable ? NSOnState : NSOffState)]; + return S_OK; + } +} + +HRESULT AvnAppMenuItem::SetToggleType(AvnMenuItemToggleType toggleType) +{ + @autoreleasepool + { + switch(toggleType) + { + case AvnMenuItemToggleType::None: + [_native setOnStateImage: [NSImage imageNamed:@"NSMenuCheckmark"]]; + + _isCheckable = false; + break; + + case AvnMenuItemToggleType::CheckMark: + [_native setOnStateImage: [NSImage imageNamed:@"NSMenuCheckmark"]]; + + _isCheckable = true; + break; + + case AvnMenuItemToggleType::Radio: + [_native setOnStateImage: [NSImage imageNamed:@"NSMenuItemBullet"]]; + + _isCheckable = true; + break; + } + return S_OK; } } diff --git a/samples/ControlCatalog/MainWindow.xaml b/samples/ControlCatalog/MainWindow.xaml index e75506624a..ca20327e1e 100644 --- a/samples/ControlCatalog/MainWindow.xaml +++ b/samples/ControlCatalog/MainWindow.xaml @@ -39,10 +39,18 @@ - + + diff --git a/src/Avalonia.FreeDesktop/DBusMenuExporter.cs b/src/Avalonia.FreeDesktop/DBusMenuExporter.cs index c60c1d396f..3f64c094ab 100644 --- a/src/Avalonia.FreeDesktop/DBusMenuExporter.cs +++ b/src/Avalonia.FreeDesktop/DBusMenuExporter.cs @@ -240,9 +240,6 @@ namespace Avalonia.FreeDesktop return "checkmark"; if (item.ToggleType == NativeMenuItemToggleType.Radio) return "radio"; - // Someone has forgot to set the style - if (item.IsChecked) - return "checkmark"; } if (name == "toggle-state") diff --git a/src/Avalonia.Native/IAvnMenuItem.cs b/src/Avalonia.Native/IAvnMenuItem.cs index a9730920f1..df82f3955a 100644 --- a/src/Avalonia.Native/IAvnMenuItem.cs +++ b/src/Avalonia.Native/IAvnMenuItem.cs @@ -26,6 +26,11 @@ namespace Avalonia.Native.Interop IsChecked = isChecked; } + private void UpdateToggleType(NativeMenuItemToggleType toggleType) + { + ToggleType = (AvnMenuItemToggleType)toggleType; + } + private void UpdateGesture(Input.KeyGesture gesture) { // todo ensure backend can cope with setting null gesture. @@ -73,6 +78,8 @@ namespace Avalonia.Native.Interop UpdateAction(ManagedMenuItem as NativeMenuItem); + UpdateToggleType(item.ToggleType); + UpdateIsChecked(item.IsChecked); _propertyDisposables.Add(ManagedMenuItem.GetObservable(NativeMenuItem.HeaderProperty) @@ -84,6 +91,9 @@ namespace Avalonia.Native.Interop _propertyDisposables.Add(ManagedMenuItem.GetObservable(NativeMenuItem.CommandProperty) .Subscribe(x => UpdateAction(ManagedMenuItem as NativeMenuItem))); + _propertyDisposables.Add(ManagedMenuItem.GetObservable(NativeMenuItem.ToggleTypeProperty) + .Subscribe(x => UpdateToggleType(x))); + _propertyDisposables.Add(ManagedMenuItem.GetObservable(NativeMenuItem.IsCheckedProperty) .Subscribe(x => UpdateIsChecked(x))); }