From fbbe829a193ab8a573ccda8dcc85b370df7fc647 Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Wed, 16 Feb 2011 18:32:31 +0000 Subject: [PATCH] support native edit menu handling (cocoa enables menu items in built-in modal dialogs automagically, if they have the proper selectors) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@66907 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/osx/cocoa/menu.mm | 4 +- src/osx/cocoa/menuitem.mm | 89 ++++++++++++++++++++++++++++++------ src/osx/cocoa/nonownedwnd.mm | 68 +++++++++++++++++++++++++++ 3 files changed, 146 insertions(+), 15 deletions(-) diff --git a/src/osx/cocoa/menu.mm b/src/osx/cocoa/menu.mm index ea02cf9f2b..053c120052 100644 --- a/src/osx/cocoa/menu.mm +++ b/src/osx/cocoa/menu.mm @@ -36,9 +36,9 @@ @implementation wxNSMenu -- (id) init +- (id) initWithTitle:(NSString*) title { - [super init]; + [super initWithTitle:title]; impl = NULL; return self; } diff --git a/src/osx/cocoa/menuitem.mm b/src/osx/cocoa/menuitem.mm index c253f75672..2c9a16cdbe 100644 --- a/src/osx/cocoa/menuitem.mm +++ b/src/osx/cocoa/menuitem.mm @@ -22,11 +22,59 @@ #include "wx/osx/private.h" +// a mapping from wx ids to standard osx actions in order to support the native menu item handling +// if a new mapping is added, make sure the wxNonOwnedWindowController has a handler for this action as well + +struct Mapping +{ + int menuid; + SEL action; +}; + +Mapping sActionToWXMapping[] = +{ + wxID_UNDO, @selector(undo:) , + wxID_REDO, @selector(redo:) , + wxID_CUT, @selector(cut:) , + wxID_COPY, @selector(copy:) , + wxID_PASTE, @selector(paste:) , + wxID_CLEAR, @selector(delete:) , + wxID_SELECTALL, @selector(selectAll:) , + 0, NULL +}; + +int wxOSXGetIdFromSelector(SEL action ) +{ + int i = 0 ; + while ( sActionToWXMapping[i].action != nil ) + { + if ( sActionToWXMapping[i].action == action ) + return sActionToWXMapping[i].menuid; + ++i; + } + + return 0; +} + +SEL wxOSXGetSelectorFromID(int menuId ) +{ + int i = 0 ; + while ( sActionToWXMapping[i].action != nil ) + { + if ( sActionToWXMapping[i].menuid == menuId ) + return sActionToWXMapping[i].action; + ++i; + } + + return nil; +} + + @implementation wxNSMenuItem -- (id) init +- (id) initWithTitle:(NSString *)aString action:(SEL)aSelector keyEquivalent:(NSString *)charCode { - [super init]; + [super initWithTitle:aString action:aSelector keyEquivalent:charCode]; return self; } @@ -42,13 +90,18 @@ } } +- (void) setEnabled:(BOOL) flag +{ + [super setEnabled:flag]; +} + - (BOOL)validateMenuItem:(NSMenuItem *) menuItem { wxUnusedVar(menuItem); if( impl ) { - impl->GetWXPeer()->GetMenu()->HandleCommandUpdateStatus(impl->GetWXPeer()); - return impl->GetWXPeer()->IsEnabled(); + if ( impl->GetWXPeer()->GetMenu()->HandleCommandUpdateStatus(impl->GetWXPeer()) ) + return impl->GetWXPeer()->IsEnabled(); } return YES ; } @@ -256,7 +309,7 @@ bool wxMenuItemCocoaImpl::DoDefault() } wxMenuItemImpl* wxMenuItemImpl::Create( wxMenuItem* peer, wxMenu *pParentMenu, - int WXUNUSED(id), + int menuid, const wxString& text, wxAcceleratorEntry *entry, const wxString& WXUNUSED(strHelp), @@ -273,24 +326,34 @@ wxMenuItemImpl* wxMenuItemImpl::Create( wxMenuItem* peer, wxMenu *pParentMenu, else { wxCFStringRef cfText(text); - wxNSMenuItem* temp = [ [ wxNSMenuItem alloc ] init ]; - if ( ! pParentMenu->GetNoEventsMode() ) + SEL selector = nil; + bool targetSelf = false; + if ( ! pParentMenu->GetNoEventsMode() && pSubMenu == NULL ) { - [temp setTarget: temp]; - [temp setAction: @selector(clickedAction:)]; + selector = wxOSXGetSelectorFromID(menuid); + + if ( selector == nil ) + { + selector = @selector(clickedAction:); + targetSelf = true; + } } - [temp setTitle:cfText.AsNSString()]; + + wxNSMenuItem* menuitem = [ [ wxNSMenuItem alloc ] initWithTitle:cfText.AsNSString() action:selector keyEquivalent:@""]; + if ( targetSelf ) + [menuitem setTarget:menuitem]; + if ( pSubMenu ) { pSubMenu->GetPeer()->SetTitle( text ); - [temp setSubmenu:pSubMenu->GetHMenu()]; + [menuitem setSubmenu:pSubMenu->GetHMenu()]; } else { if ( entry ) - wxMacCocoaMenuItemSetAccelerator( temp, entry ); + wxMacCocoaMenuItemSetAccelerator( menuitem, entry ); } - item = temp; + item = menuitem; } c = new wxMenuItemCocoaImpl( peer, item ); return c; diff --git a/src/osx/cocoa/nonownedwnd.mm b/src/osx/cocoa/nonownedwnd.mm index 1c97ba28fc..6adfba6560 100644 --- a/src/osx/cocoa/nonownedwnd.mm +++ b/src/osx/cocoa/nonownedwnd.mm @@ -263,6 +263,8 @@ bool shouldHandleSelector(SEL selector) @end +extern int wxOSXGetIdFromSelector(SEL action ); + @implementation wxNonOwnedWindowController - (id) init @@ -271,6 +273,72 @@ bool shouldHandleSelector(SEL selector) return self; } +- (BOOL) triggerMenu:(SEL) action +{ + wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar(); + if ( mbar ) + { + wxMenu* menu = NULL; + wxMenuItem* menuitem = mbar->FindItem(wxOSXGetIdFromSelector(action), &menu); + if ( menu != NULL && menuitem != NULL) + return menu->HandleCommandProcess(menuitem); + } + return NO; +} + +- (BOOL)validateMenuItem:(NSMenuItem *)menuItem +{ + SEL action = [menuItem action]; + + wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar(); + if ( mbar ) + { + wxMenu* menu = NULL; + wxMenuItem* menuitem = mbar->FindItem(wxOSXGetIdFromSelector(action), &menu); + if ( menu != NULL && menuitem != NULL) + { + if ( menu->HandleCommandUpdateStatus(menuitem) ) + return menuitem->IsEnabled(); + } + } + return YES; +} + +- (void)undo:(id)sender +{ + [self triggerMenu:_cmd]; +} + +- (void)redo:(id)sender +{ + [self triggerMenu:_cmd]; +} + +- (void)cut:(id)sender +{ + [self triggerMenu:_cmd]; +} + +- (void)copy:(id)sender +{ + [self triggerMenu:_cmd]; +} + +- (void)paste:(id)sender +{ + [self triggerMenu:_cmd]; +} + +- (void)delete:(id)sender +{ + [self triggerMenu:_cmd]; +} + +- (void)selectAll:(id)sender +{ + [self triggerMenu:_cmd]; +} + - (BOOL)windowShouldClose:(id)nwindow { wxNonOwnedWindowCocoaImpl* windowimpl = [(NSWindow*) nwindow WX_implementation]; -- 2.47.2