// Author: Stefan Csomor
// Modified by:
// Created: 1998-01-01
-// RCS-ID: $Id: menuitem.cpp 54129 2008-06-11 19:30:52Z SC $
+// RCS-ID: $Id$
// Copyright: (c) Stefan Csomor
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef WX_PRECOMP
#include "wx/app.h"
+ #include "wx/log.h"
#include "wx/menu.h"
#endif // WX_PRECOMP
#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[] =
+{
+// as we don't have NSUndoManager support we must not use the native actions
+#if 0
+ { wxID_UNDO, @selector(undo:) },
+ { wxID_REDO, @selector(redo:) },
+#endif
+ { 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];
- return self;
+ self = [super initWithTitle:aString action:aSelector keyEquivalent:charCode];
+ return self;
}
- (void) clickedAction: (id) sender
{
+ wxUnusedVar(sender);
if ( impl )
{
- impl->GetWXPeer()->GetMenu()->HandleCommandProcess(impl->GetWXPeer());
+ wxMenuItem* menuitem = impl->GetWXPeer();
+ if ( menuitem->GetMenu()->HandleCommandProcess(menuitem) == false )
+ {
+ }
}
}
+- (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();
+ wxMenuItem* wxmenuitem = impl->GetWXPeer();
+ if ( wxmenuitem )
+ {
+ wxmenuitem->GetMenu()->HandleCommandUpdateStatus(wxmenuitem);
+ return wxmenuitem->IsEnabled();
+ }
}
return YES ;
}
void wxMacCocoaMenuItemSetAccelerator( NSMenuItem* menuItem, wxAcceleratorEntry* entry )
{
+ if ( entry == NULL )
+ {
+ [menuItem setKeyEquivalent:@""];
+ return;
+ }
+
unsigned int modifiers = 0 ;
int key = entry->GetKeyCode() ;
if ( key )
{
- if (entry->GetFlags() & wxACCEL_CTRL);
+ if (entry->GetFlags() & wxACCEL_CTRL)
modifiers |= NSCommandKeyMask;
+ if (entry->GetFlags() & wxACCEL_RAW_CTRL)
+ modifiers |= NSControlKeyMask;
+
if (entry->GetFlags() & wxACCEL_ALT)
modifiers |= NSAlternateKeyMask ;
{
switch ( key )
{
-/*
- // standard function keys from here
- case WXK_TAB :
- modifiers |= NSFunctionKeyMask ;
- shortcut = NSTabCharacter ;
- break ;
-
- case kEnterCharCode :
- modifiers |= NSFunctionKeyMask ;
- cocoaKey = NSTabCharacter ;
- break ;
-
- case WXK_RETURN :
- modifiers |= NSFunctionKeyMask ;
- cocoaKey = NSTabCharacter ;
- break ;
-
- case WXK_ESCAPE :
- modifiers |= NSFunctionKeyMask ;
- cocoaKey = kEscapeCharCode ;
- break ;
-
- case WXK_SPACE :
- shortcut = ' ' ;
- break ;
-
-
case WXK_CLEAR :
- cocoaKey = kClearCharCode ;
+ modifiers |= NSFunctionKeyMask;
+ shortcut = NSDeleteCharacter ;
break ;
case WXK_PAGEUP :
- cocoaKey = kPageUpCharCode ;
+ modifiers |= NSFunctionKeyMask;
+ shortcut = NSPageUpFunctionKey ;
break ;
case WXK_PAGEDOWN :
- cocoaKey = kPageDownCharCode ;
+ modifiers |= NSFunctionKeyMask;
+ shortcut = NSPageDownFunctionKey ;
break ;
case WXK_LEFT :
- cocoaKey = kLeftArrowCharCode ;
+ modifiers |= NSNumericPadKeyMask | NSFunctionKeyMask;
+ shortcut = NSLeftArrowFunctionKey ;
break ;
case WXK_UP :
- cocoaKey = kUpArrowCharCode ;
+ modifiers |= NSNumericPadKeyMask | NSFunctionKeyMask;
+ shortcut = NSUpArrowFunctionKey ;
break ;
case WXK_RIGHT :
- cocoaKey = kRightArrowCharCode ;
+ modifiers |= NSNumericPadKeyMask | NSFunctionKeyMask;
+ shortcut = NSRightArrowFunctionKey ;
break ;
case WXK_DOWN :
- cocoaKey = kDownArrowCharCode ;
+ modifiers |= NSNumericPadKeyMask | NSFunctionKeyMask;
+ shortcut = NSDownArrowFunctionKey ;
break ;
case WXK_HOME :
- cocoaKey = kHomeCharCode ;
+ modifiers |= NSFunctionKeyMask;
+ shortcut = NSHomeFunctionKey ;
break ;
case WXK_END :
- cocoaKey = kEndCharCode ;
+ modifiers |= NSFunctionKeyMask;
+ shortcut = NSEndFunctionKey ;
break ;
-*/
- // TODO Test all above with their function key equiv.
- // from NSEvent.h
+
+ case WXK_NUMPAD_ENTER :
+ shortcut = NSEnterCharacter;
+ break;
+
+ case WXK_BACK :
+ case WXK_RETURN :
+ case WXK_TAB :
+ case WXK_ESCAPE :
default :
if(entry->GetFlags() & wxACCEL_SHIFT)
shortcut = toupper(key);
}
}
-class wxMenuItemCocoaImpl : public wxMenuItemImpl
+@interface NSMenuItem(PossibleMethods)
+- (void)setHidden:(BOOL)hidden;
+@end
+
+class wxMenuItemCocoaImpl : public wxMenuItemImpl
{
public :
wxMenuItemCocoaImpl( wxMenuItem* peer, NSMenuItem* item ) : wxMenuItemImpl(peer), m_osxMenuItem(item)
{
+ if ( ![m_osxMenuItem isSeparatorItem] )
+ [(wxNSMenuItem*)m_osxMenuItem setImplementation:this];
}
-
+
~wxMenuItemCocoaImpl();
-
- void SetBitmap( const wxBitmap& bitmap )
+
+ void SetBitmap( const wxBitmap& bitmap )
{
[m_osxMenuItem setImage:bitmap.GetNSImage()];
}
-
- void Enable( bool enable )
+
+ void Enable( bool enable )
{
[m_osxMenuItem setEnabled:enable];
}
-
- void Check( bool check )
+
+ void Check( bool check )
{
[m_osxMenuItem setState:( check ? NSOnState : NSOffState) ];
}
-
+
void Hide( bool hide )
{
- [m_osxMenuItem setHidden:hide ];
+ // NB: setHidden is new as of 10.5 so we should not call it below there
+ if ([m_osxMenuItem respondsToSelector:@selector(setHidden:)])
+ [m_osxMenuItem setHidden:hide ];
+ else
+ wxLogDebug("wxMenuItemCocoaImpl::Hide not yet supported under OS X < 10.5");
}
-
- void SetLabel( const wxString& text, wxAcceleratorEntry *entry )
+
+ void SetLabel( const wxString& text, wxAcceleratorEntry *entry )
{
wxCFStringRef cfText(text);
[m_osxMenuItem setTitle:cfText.AsNSString()];
-
- if ( entry )
- wxMacCocoaMenuItemSetAccelerator( m_osxMenuItem, entry );
+ wxMacCocoaMenuItemSetAccelerator( m_osxMenuItem, entry );
}
+ bool DoDefault();
+
void * GetHMenuItem() { return m_osxMenuItem; }
protected :
wxMenuItemCocoaImpl::~wxMenuItemCocoaImpl()
{
+ if ( ![m_osxMenuItem isSeparatorItem] )
+ [(wxNSMenuItem*)m_osxMenuItem setImplementation:nil];
+ [m_osxMenuItem release];
}
+bool wxMenuItemCocoaImpl::DoDefault()
+{
+ bool handled=false;
+ int menuid = m_peer->GetId();
+
+ NSApplication *theNSApplication = [NSApplication sharedApplication];
+ if (menuid == wxID_OSX_HIDE)
+ {
+ [theNSApplication hide:nil];
+ handled=true;
+ }
+ else if (menuid == wxID_OSX_HIDEOTHERS)
+ {
+ [theNSApplication hideOtherApplications:nil];
+ handled=true;
+ }
+ else if (menuid == wxID_OSX_SHOWALL)
+ {
+ [theNSApplication unhideAllApplications:nil];
+ handled=true;
+ }
+ else if (menuid == wxApp::s_macExitMenuItemId)
+ {
+ wxTheApp->ExitMainLoop();
+ }
+ return handled;
+}
wxMenuItemImpl* wxMenuItemImpl::Create( wxMenuItem* peer, wxMenu *pParentMenu,
- int id,
+ int menuid,
const wxString& text,
wxAcceleratorEntry *entry,
- const wxString& strHelp,
+ const wxString& WXUNUSED(strHelp),
wxItemKind kind,
wxMenu *pSubMenu )
{
wxMenuItemImpl* c = NULL;
NSMenuItem* item = nil;
-
+
if ( kind == wxITEM_SEPARATOR )
{
item = [[NSMenuItem separatorItem] retain];
else
{
wxCFStringRef cfText(text);
- wxNSMenuItem* temp = [ [ wxNSMenuItem alloc ] init ];
- if ( ! pParentMenu->GetNoEventsMode() )
+ SEL selector = nil;
+ bool targetSelf = false;
+ if ( (pParentMenu == NULL || !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 );
- if ( kind != wxITEM_SEPARATOR )
- {
- [(wxNSMenuItem*)item setImplementation:c];
- }
return c;
}