Browse Source
Merge pull request #3838 from AvaloniaUI/feature/osx-native-menu-radiotoggle
Support Radio Toggle on OSX menus.
pull/3840/head
Nikita Tsukanov
7 years ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with
61 additions and
5 deletions
-
native/Avalonia.Native/inc/avalonia-native.h
-
native/Avalonia.Native/src/OSX/menu.h
-
native/Avalonia.Native/src/OSX/menu.mm
-
samples/ControlCatalog/MainWindow.xaml
-
src/Avalonia.FreeDesktop/DBusMenuExporter.cs
-
src/Avalonia.Native/IAvnMenuItem.cs
|
|
|
@ -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 |
|
|
|
|
|
|
|
@ -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(); |
|
|
|
|
|
|
|
@ -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; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -39,10 +39,18 @@ |
|
|
|
<NativeMenuItem Header="Options"> |
|
|
|
<NativeMenuItem.Menu> |
|
|
|
<NativeMenu> |
|
|
|
<NativeMenuItem Header="Check Me Out" |
|
|
|
<NativeMenuItem Header="Check Me (None)" |
|
|
|
Command="{Binding ToggleMenuItemCheckedCommand}" |
|
|
|
ToggleType="None" |
|
|
|
IsChecked="{Binding IsMenuItemChecked}" /> |
|
|
|
<NativeMenuItem Header="Check Me (CheckBox)" |
|
|
|
Command="{Binding ToggleMenuItemCheckedCommand}" |
|
|
|
ToggleType="CheckBox" |
|
|
|
IsChecked="{Binding IsMenuItemChecked}" /> |
|
|
|
<NativeMenuItem Header="Check Me (Radio)" |
|
|
|
Command="{Binding ToggleMenuItemCheckedCommand}" |
|
|
|
ToggleType="Radio" |
|
|
|
IsChecked="{Binding IsMenuItemChecked}" /> |
|
|
|
</NativeMenu> |
|
|
|
</NativeMenuItem.Menu> |
|
|
|
</NativeMenuItem> |
|
|
|
|
|
|
|
@ -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") |
|
|
|
|
|
|
|
@ -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))); |
|
|
|
} |
|
|
|
|