X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e75491071dbefcada61175e3eb89ce4edf335983..8290d43d0d43369d007f1c47abf98a45da461a30:/src/mac/menu.cpp diff --git a/src/mac/menu.cpp b/src/mac/menu.cpp index 35589ca6e1..427db90852 100644 --- a/src/mac/menu.cpp +++ b/src/mac/menu.cpp @@ -33,10 +33,8 @@ // ---------------------- #include -#if !USE_SHARED_LIBRARY IMPLEMENT_DYNAMIC_CLASS(wxMenu, wxEvtHandler) IMPLEMENT_DYNAMIC_CLASS(wxMenuBar, wxEvtHandler) -#endif // the (popup) menu title has this special id static const int idMenuTitle = -2; @@ -57,11 +55,23 @@ void wxMacCtoPString(const char* theCString, Str255 thePString); // remove inappropriate characters, if useShortcuts is false, the ampersand will not auto-generate a mac menu-shortcut -static void wxMacBuildMenuString(StringPtr outMacItemText, char *outMacShortcutChar , short *outMacModifiers , const char *inItemName , bool useShortcuts ) +void wxMacBuildMenuString(StringPtr outMacItemText, char *outMacShortcutChar , short *outMacModifiers , const char *inItemText , bool useShortcuts ) { char *p = (char *) &outMacItemText[1] ; short macModifiers = 0 ; char macShortCut = 0 ; + const char *inItemName ; + wxString inItemTextMac ; + + if (wxApp::s_macDefaultEncodingIsPC) + { + inItemTextMac = wxMacMakeMacStringFromPC( inItemText ) ; + inItemName = inItemTextMac ; + } + else + { + inItemName = inItemText ; + } if ( useShortcuts && !wxApp::s_macSupportPCMenuShortcuts ) useShortcuts = false ; @@ -117,18 +127,23 @@ static void wxMacBuildMenuString(StringPtr outMacItemText, char *outMacShortcutC ++inItemName ; while( *inItemName ) { - if (strncmp("Ctrl+", inItemName, 5) == 0) + if (strncmp("Ctrl", inItemName, 4) == 0) { inItemName = inItemName + 5; macShortCut = *inItemName; } - else if (strncmp("Alt+", inItemName, 4) == 0) + else if (strncmp("Cntrl", inItemName, 5) == 0) + { + inItemName = inItemName + 6; + macShortCut = *inItemName; + } + else if (strncmp("Alt", inItemName, 3) == 0) { inItemName = inItemName + 4; macModifiers |= kMenuOptionModifier ; macShortCut = *inItemName ; } - else if (strncmp("Shift+", inItemName, 6) == 0) + else if (strncmp("Shift", inItemName, 5) == 0) { inItemName = inItemName + 6; macModifiers |= kMenuShiftModifier ; @@ -602,21 +617,7 @@ wxWindow *wxMenu::GetWindow() const return NULL; } -/* -bool wxWindow::PopupMenu(wxMenu *menu, int x, int y) -{ - menu->SetInvokingWindow(this); - ClientToScreen( &x , &y ) ; - - ::InsertMenu( menu->m_hMenu , -1 ) ; - long menuResult = ::PopUpMenuSelect(menu->m_hMenu ,y,x, 0) ; - menu->MacMenuSelect( this , TickCount() , HiWord(menuResult) , LoWord(menuResult) ) ; - ::DeleteMenu( menu->m_macMenuId ) ; - menu->SetInvokingWindow(NULL); - return TRUE; -} -*/ // helper functions returning the mac menu position for a certain item, note that this is // mac-wise 1 - based, i.e. the first item has index 1 whereas on MSWin it has pos 0 @@ -682,7 +683,28 @@ bool wxMenu::MacMenuSelect( wxEvtHandler* handler, long when , int macMenuId, in event.m_timeStamp = when; event.SetEventObject(handler); event.SetInt( pItem->GetId() ); - ProcessCommand( event ) ; + { + bool processed = false ; + +#if WXWIN_COMPATIBILITY + // Try a callback + if (m_callback) + { + (void) (*(m_callback)) (*this, event); + processed = TRUE; + } +#endif + // Try the menu's event handler + if ( !processed && handler) + { + processed = handler->ProcessEvent(event); + } + + // Try the window the menu was popped up from (and up + // through the hierarchy) + if ( !processed && GetInvokingWindow()) + processed = GetInvokingWindow()->GetEventHandler()->ProcessEvent(event); + } return true ; } } @@ -708,7 +730,27 @@ bool wxMenu::MacMenuSelect( wxEvtHandler* handler, long when , int macMenuId, in event.m_timeStamp = when; event.SetEventObject(handler); event.SetInt( pItem->GetId() ); - ProcessCommand( event ) ; + { + bool processed = false ; +#if WXWIN_COMPATIBILITY + // Try a callback + if (m_callback) + { + (void) (*(m_callback)) (*this, event); + processed = TRUE; + } +#endif + // Try the menu's event handler + if ( !processed && handler) + { + processed = handler->ProcessEvent(event); + } + + // Try the window the menu was popped up from (and up + // through the hierarchy) + if ( !processed && GetInvokingWindow()) + processed = GetInvokingWindow()->GetEventHandler()->ProcessEvent(event); + } return true ; } } @@ -757,6 +799,16 @@ void wxMenuBar::Init() m_menuBarFrame = NULL; } +wxMenuBar::wxMenuBar() +{ + Init(); +} + +wxMenuBar::wxMenuBar( long WXUNUSED(style) ) +{ + Init(); +} + wxMenuBar::wxMenuBar(int count, wxMenu *menus[], const wxString titles[]) { @@ -790,6 +842,37 @@ void wxMenuBar::Refresh() DrawMenuBar(); } +#if wxUSE_ACCEL + +void wxMenuBar::RebuildAccelTable() +{ + // merge the accelerators of all menus into one accel table + size_t nAccelCount = 0; + size_t i, count = GetMenuCount(); + for ( i = 0; i < count; i++ ) + { + nAccelCount += m_menus[i]->GetAccelCount(); + } + + if ( nAccelCount ) + { + wxAcceleratorEntry *accelEntries = new wxAcceleratorEntry[nAccelCount]; + + nAccelCount = 0; + for ( i = 0; i < count; i++ ) + { + nAccelCount += m_menus[i]->CopyAccels(&accelEntries[nAccelCount]); + } + + m_accelTable = wxAcceleratorTable(nAccelCount, accelEntries); + + delete [] accelEntries; + } +} + +#endif // wxUSE_ACCEL + + void wxMenuBar::MacInstallMenuBar() { Handle menubar = ::GetNewMBar( kwxMacMenuBarResource ) ; @@ -810,7 +893,7 @@ void wxMenuBar::MacInstallMenuBar() wxMenu* menu = m_menus[i] , *subMenu = NULL ; - if( m_titles[i] == "?" || m_titles[i] == wxApp::s_macHelpMenuTitleName ) + if( m_titles[i] == "?" || m_titles[i] == "&?" || m_titles[i] == wxApp::s_macHelpMenuTitleName ) { MenuHandle mh = NULL ; if ( HMGetHelpMenuHandle( &mh ) != noErr ) @@ -833,24 +916,32 @@ void wxMenuBar::MacInstallMenuBar() } else { - Str255 label ; - wxMacBuildMenuString( label , NULL , NULL , item->GetText(), item->GetId() != wxApp::s_macAboutMenuItemId); // no shortcut in about menu - if ( label[0] == 0 ) + if ( item->IsSeparator() ) { - // we cannot add empty menus on mac - label[0] = 1 ; - label[1] = ' ' ; + if ( mh ) + ::AppendMenu(mh, "\p-" ); } - if ( item->GetId() == wxApp::s_macAboutMenuItemId ) - { - ::SetMenuItemText( GetMenuHandle( kwxMacAppleMenuId ) , 1 , label ); - // ::EnableMenuItem( GetMenuHandle( kwxMacAppleMenuId ) , 1 ); - ::EnableItem( GetMenuHandle( kwxMacAppleMenuId ) , 1 ); - } else { - if ( mh ) - ::AppendMenu(mh, label ); + Str255 label ; + wxMacBuildMenuString( label , NULL , NULL , item->GetText(), item->GetId() != wxApp::s_macAboutMenuItemId); // no shortcut in about menu + if ( label[0] == 0 ) + { + // we cannot add empty menus on mac + label[0] = 1 ; + label[1] = ' ' ; + } + if ( item->GetId() == wxApp::s_macAboutMenuItemId ) + { + ::SetMenuItemText( GetMenuHandle( kwxMacAppleMenuId ) , 1 , label ); + // ::EnableMenuItem( GetMenuHandle( kwxMacAppleMenuId ) , 1 ); + ::EnableItem( GetMenuHandle( kwxMacAppleMenuId ) , 1 ); + } + else + { + if ( mh ) + ::AppendMenu(mh, label ); + } } } } @@ -1028,7 +1119,7 @@ void wxMenuBar::MacMenuSelect(wxEvtHandler* handler, long when , int macMenuId, for (int i = 0; i < m_menus.GetCount() ; i++) { if ( m_menus[i]->MacGetMenuId() == macMenuId || - ( macMenuId == kHMHelpMenuID && ( m_titles[i] == "?" || m_titles[i] == wxApp::s_macHelpMenuTitleName ) ) + ( macMenuId == kHMHelpMenuID && ( m_titles[i] == "?" || m_titles[i] == "&?" || m_titles[i] == wxApp::s_macHelpMenuTitleName ) ) ) { if ( m_menus[i]->MacMenuSelect( handler , when , macMenuId , macMenuItemNum ) ) @@ -1047,7 +1138,107 @@ void wxMenuBar::MacMenuSelect(wxEvtHandler* handler, long when , int macMenuId, { break ; } - } + } } } +wxMenu *wxMenuBar::Remove(size_t pos) +{ + wxMenu *menu = wxMenuBarBase::Remove(pos); + if ( !menu ) + return NULL; + + if ( IsAttached() ) + { + if (s_macInstalledMenuBar == this) + { + ::DeleteMenu( menu->MacGetMenuId() /* m_menus[pos]->MacGetMenuId() */ ) ; + } + + menu->Detach(); + +#if wxUSE_ACCEL + if ( menu->HasAccels() ) + { + // need to rebuild accell table + RebuildAccelTable(); + } +#endif // wxUSE_ACCEL + + Refresh(); + } + + m_titles.Remove(pos); + + return menu; +} + +bool wxMenuBar::Append(wxMenu *menu, const wxString& title) +{ + WXHMENU submenu = menu ? menu->GetHMenu() : 0; + wxCHECK_MSG( submenu, FALSE, wxT("can't append invalid menu to menubar") ); + + if ( !wxMenuBarBase::Append(menu, title) ) + return FALSE; + + menu->Attach(this); + + m_titles.Add(title); + + if ( IsAttached() ) + { + if (s_macInstalledMenuBar == this) + { + ::InsertMenu( menu->GetHMenu() , 0 ) ; + } + +#if wxUSE_ACCEL + if ( menu->HasAccels() ) + { + // need to rebuild accell table + RebuildAccelTable(); + } +#endif // wxUSE_ACCEL + + Refresh(); + } + + return TRUE; +} + +// --------------------------------------------------------------------------- +// wxMenuBar searching for menu items +// --------------------------------------------------------------------------- + +// Find the itemString in menuString, and return the item id or wxNOT_FOUND +int wxMenuBar::FindMenuItem(const wxString& menuString, + const wxString& itemString) const +{ + wxString menuLabel = wxStripMenuCodes(menuString); + size_t count = GetMenuCount(); + for ( size_t i = 0; i < count; i++ ) + { + wxString title = wxStripMenuCodes(m_titles[i]); + if ( menuString == title ) + return m_menus[i]->FindItem(itemString); + } + + return wxNOT_FOUND; +} + +wxMenuItem *wxMenuBar::FindItem(int id, wxMenu **itemMenu) const +{ + if ( itemMenu ) + *itemMenu = NULL; + + wxMenuItem *item = NULL; + size_t count = GetMenuCount(); + for ( size_t i = 0; !item && (i < count); i++ ) + { + item = m_menus[i]->FindItem(id, itemMenu); + } + + return item; +} + +