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; m_titles.Add(title); UMASetMenuTitle( MAC_WXHMENU(menu->GetHMenu()) , title , m_font.GetEncoding() ) ; if ( IsAttached() ) { if (s_macInstalledMenuBar == this) { menu->MacBeforeDisplay( false ) ; ::InsertMenu( MAC_WXHMENU(menu->GetHMenu()) , 0 ) ; } Refresh(); } // m_invokingWindow is set after wxFrame::SetMenuBar(). This call enables // adding menu later on. if (m_invokingWindow) wxMenubarSetInvokingWindow( menu, m_invokingWindow ); return true; }
bool wxMenuBar::Insert(size_t pos, wxMenu *menu, const wxString& title) { if ( !wxMenuBarBase::Insert(pos, menu, title) ) return false; m_titles.Insert(title, pos); UMASetMenuTitle( MAC_WXHMENU(menu->GetHMenu()) , title , m_font.GetEncoding() ) ; if ( IsAttached() && s_macInstalledMenuBar == this ) { if (s_macInstalledMenuBar == this) { menu->MacBeforeDisplay( false ) ; if ( pos == (size_t) -1 || pos + 1 == m_menus.GetCount() ) ::InsertMenu( MAC_WXHMENU(menu->GetHMenu()) , 0 ) ; else ::InsertMenu( MAC_WXHMENU(menu->GetHMenu()) , _wxMenuAt(m_menus, pos+1)->MacGetMenuId() ) ; } Refresh(); } if (m_invokingWindow) wxMenubarSetInvokingWindow( menu, m_invokingWindow ); return true; }
wxMenu *wxMenuBar::Replace(size_t pos, wxMenu *menu, const wxString& title) { wxMenu *menuOld = wxMenuBarBase::Replace(pos, menu, title); if ( !menuOld ) return NULL; m_titles[pos] = title; if ( IsAttached() ) { if (s_macInstalledMenuBar == this) { menuOld->MacAfterDisplay( false ) ; ::DeleteMenu( menuOld->MacGetMenuId() /* m_menus[pos]->MacGetMenuId() */ ) ; menu->MacBeforeDisplay( false ) ; UMASetMenuTitle( MAC_WXHMENU(menu->GetHMenu()) , title , m_font.GetEncoding() ) ; if ( pos == m_menus.GetCount() - 1) ::InsertMenu( MAC_WXHMENU(menu->GetHMenu()) , 0 ) ; else ::InsertMenu( MAC_WXHMENU(menu->GetHMenu()) , _wxMenuAt(m_menus, pos + 1)->MacGetMenuId() ) ; } Refresh(); } if (m_invokingWindow) wxMenubarSetInvokingWindow( menu, m_invokingWindow ); return menuOld; }
void wxMenuItem::UpdateItemBitmap() { if ( !m_parentMenu ) return ; MenuHandle mhandle = MAC_WXHMENU(m_parentMenu->GetHMenu()) ; MenuItemIndex index = m_parentMenu->MacGetIndexFromItem( this ) ; if ( mhandle == NULL || index == 0) return ; if ( m_bitmap.Ok() ) { #if wxUSE_BMPBUTTON ControlButtonContentInfo info ; wxMacCreateBitmapButton( &info , m_bitmap ) ; if ( info.contentType != kControlNoContent ) { if ( info.contentType == kControlContentIconRef ) SetMenuItemIconHandle( mhandle , index , kMenuIconRefType , (Handle) info.u.iconRef ) ; } wxMacReleaseBitmapButton( &info ) ; #endif } }
// ---------------------------------------------------------------------------- // adding/deleting items to/from the list // ---------------------------------------------------------------------------- int wxChoice::DoAppend(const wxString& item) { #if wxUSE_STL wxArrayString::iterator insertPoint; size_t index; if (GetWindowStyle() & wxCB_SORT) { insertPoint = std::lower_bound( m_strings.begin(), m_strings.end(), item ); index = insertPoint - m_strings.begin(); } else { insertPoint = m_strings.end(); index = m_strings.size(); } m_strings.insert( insertPoint, item ); #else size_t index = m_strings.Add( item ) ; #endif m_datas.Insert( NULL , index ) ; UMAInsertMenuItem(MAC_WXHMENU( m_macPopUpMenuHandle ) , item, m_font.GetEncoding() , index ); DoSetItemClientData( index , NULL ) ; m_peer->SetMaximum( GetCount() ) ; return index ; }
wxMenuItem *wxMenu::DoRemove(wxMenuItem *item) { // we need to find the items position in the child list size_t pos; wxMenuItemList::compatibility_iterator node = GetMenuItems().GetFirst(); for ( pos = 0; node; pos++ ) { if ( node->GetData() == item ) break; node = node->GetNext(); } // DoRemove() (unlike Remove) can only be called for existing item! wxCHECK_MSG( node, NULL, wxT("bug in wxMenu::Remove logic") ); ::DeleteMenuItem(MAC_WXHMENU(m_hMenu) , pos + 1); if ( IsAttached() && GetMenuBar()->IsAttached() ) // otherwise, the change won't be visible GetMenuBar()->Refresh(); // and from internal data structures return wxMenuBase::DoRemove(item); }
void wxChoice::SetString(unsigned int n, const wxString& s) { wxCHECK_RET( IsValid(n), wxT("wxChoice::SetString(): invalid index") ); m_strings[n] = s ; // apple menu pos is 1-based UMASetMenuItemText( MAC_WXHMENU(m_macPopUpMenuHandle) , n + 1 , s , wxFont::GetDefaultEncoding() ) ; }
void wxMenuItem::UpdateItemBitmap() { if ( !m_parentMenu ) return ; MenuHandle mhandle = MAC_WXHMENU(m_parentMenu->GetHMenu()) ; MenuItemIndex index = m_parentMenu->MacGetIndexFromItem( this ) ; DoUpdateItemBitmap( mhandle, index ); }
void wxChoice::Clear() { FreeData(); for ( int i = 0 ; i < GetCount() ; i++ ) { ::DeleteMenuItem( MAC_WXHMENU(m_macPopUpMenuHandle) , 1 ) ; } m_strings.Empty() ; m_datas.Empty() ; m_peer->SetMaximum( 0 ) ; }
void wxMacSearchFieldControl::SetSearchMenu( wxMenu* menu ) { if ( menu ) { verify_noerr( HISearchFieldSetSearchMenu( m_controlRef, MAC_WXHMENU(menu->GetHMenu()) ) ); } else { verify_noerr( HISearchFieldSetSearchMenu( m_controlRef, 0 ) ); } }
void wxChoice::Delete(int n) { wxCHECK_RET( n < GetCount(), wxT("invalid item index in wxChoice::Delete") ); if ( HasClientObjectData() ) { delete GetClientObject(n); } ::DeleteMenuItem( MAC_WXHMENU(m_macPopUpMenuHandle) , n + 1) ; m_strings.RemoveAt( n ) ; m_datas.RemoveAt( n ) ; m_peer->SetMaximum( GetCount() ) ; }
void wxChoice::Delete(unsigned int n) { wxCHECK_RET( IsValid(n) , wxT("wxChoice::Delete: invalid index") ); if ( HasClientObjectData() ) delete GetClientObject( n ); ::DeleteMenuItem( MAC_WXHMENU(m_macPopUpMenuHandle) , n + 1 ) ; m_strings.RemoveAt( n ) ; m_datas.RemoveAt( n ) ; m_peer->SetMaximum( GetCount() ) ; }
int wxChoice::DoInsert(const wxString& item, int pos) { wxCHECK_MSG(!(GetWindowStyle() & wxCB_SORT), -1, wxT("can't insert into sorted list")); wxCHECK_MSG((pos>=0) && (pos<=GetCount()), -1, wxT("invalid index")); if (pos == GetCount()) return DoAppend(item); UMAInsertMenuItem(MAC_WXHMENU( m_macPopUpMenuHandle ) , item, m_font.GetEncoding() , pos ); m_strings.Insert( item, pos ) ; m_datas.Insert( NULL, pos ) ; DoSetItemClientData( pos , NULL ) ; m_peer->SetMaximum( GetCount() ) ; return pos ; }
bool wxTaskBarIcon::RemoveIcon() { if(m_pMenu) { delete m_pMenu; m_pMenu = NULL; } //restore old icon to the dock OSStatus err = RestoreApplicationDockTileImage(); wxASSERT(err == 0); //restore the old menu to the dock SetApplicationDockTileMenu(MAC_WXHMENU(m_theLastMenu)); return !(m_iconAdded = !(err == noErr)); }
void wxMenuItem::UpdateItemStatus() { if ( !m_parentMenu ) return ; if ( IsSeparator() ) return ; #if TARGET_CARBON if ( UMAGetSystemVersion() >= 0x1000 && GetId() == wxApp::s_macPreferencesMenuItemId) { if ( !IsEnabled() ) DisableMenuCommand( NULL , kHICommandPreferences ) ; else EnableMenuCommand( NULL , kHICommandPreferences ) ; } if ( UMAGetSystemVersion() >= 0x1000 && GetId() == wxApp::s_macExitMenuItemId) { if ( !IsEnabled() ) DisableMenuCommand( NULL , kHICommandQuit ) ; else EnableMenuCommand( NULL , kHICommandQuit ) ; } #endif { MenuHandle mhandle = MAC_WXHMENU(m_parentMenu->GetHMenu()) ; MenuItemIndex index = m_parentMenu->MacGetIndexFromItem( this ) ; if ( mhandle == NULL || index == 0) return ; UMAEnableMenuItem( mhandle , index , m_isEnabled ) ; if ( IsCheckable() && IsChecked() ) ::SetItemMark( mhandle , index , 0x12 ) ; // checkmark else ::SetItemMark( mhandle , index , 0 ) ; // no mark UMASetMenuItemText( mhandle , index , wxStripMenuCodes(m_text) , wxFont::GetDefaultEncoding() ) ; wxAcceleratorEntry *entry = wxAcceleratorEntry::Create( m_text ) ; UMASetMenuItemShortcut( mhandle , index , entry ) ; delete entry ; } }
void wxMenuItem::Enable(bool bDoEnable) { if (( m_isEnabled != bDoEnable #if TARGET_CARBON // avoid changing menuitem state when menu is disabled // eg. BeginAppModalStateForWindow() will disable menus and ignore this change // which in turn causes m_isEnabled to become out of sync with real menuitem state && !(m_parentMenu && !IsMenuItemEnabled(MAC_WXHMENU(m_parentMenu->GetHMenu()), 0)) ) // always update builtin menuitems || ( GetId() == wxApp::s_macPreferencesMenuItemId || GetId() == wxApp::s_macExitMenuItemId || GetId() == wxApp::s_macAboutMenuItemId #endif )) { wxMenuItemBase::Enable( bDoEnable ) ; UpdateItemStatus() ; } }
void wxMenuItem::UpdateItemText() { if ( !m_parentMenu ) return ; MenuHandle mhandle = MAC_WXHMENU(m_parentMenu->GetHMenu()) ; MenuItemIndex index = m_parentMenu->MacGetIndexFromItem( this ) ; if (mhandle == NULL || index == 0) return ; wxString text = m_text; if (text.IsEmpty() && !IsSeparator()) { wxASSERT_MSG(wxIsStockID(GetId()), wxT("A non-stock menu item with an empty label?")); text = wxGetStockLabel(GetId(), wxSTOCK_WITH_ACCELERATOR|wxSTOCK_WITH_MNEMONIC); } UMASetMenuItemText( mhandle , index , wxStripMenuCodes(text) , wxFont::GetDefaultEncoding() ) ; wxAcceleratorEntry *entry = wxAcceleratorEntry::Create( text ) ; UMASetMenuItemShortcut( mhandle , index , entry ) ; delete entry ; }
//----------------------------------------------------------------------------- // wxDockEventHandler // // This is the global Mac/Carbon event handler for the dock. // We need this for two reasons: // 1) To handle wxTaskBarIcon menu events (see below for why) // 2) To handle events from the dock when it requests a menu //----------------------------------------------------------------------------- pascal OSStatus wxDockEventHandler( EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *pData ) { // Get the parameters we want from the event wxDockTaskBarIcon* pTB = (wxDockTaskBarIcon*) pData; const UInt32 eventClass = GetEventClass(inEvent); const UInt32 eventKind = GetEventKind(inEvent); // Handle wxTaskBar menu events (note that this is a global event handler // so it will actually get called by all commands/menus) if ((eventClass == kEventClassCommand) && (eventKind == kEventCommandProcess)) { // if we have no taskbar menu quickly pass it back to wxApp if (pTB->m_pMenu == NULL) return eventNotHandledErr; // This is the real reason why we need this. Normally menus // get handled in wxMacAppEventHandler // // pascal OSStatus wxMacAppEventHandler(EventHandlerCallRef handler, // EventRef event, void *data) // // However, in the case of a taskbar menu call // command.menu.menuRef IS NULL! // Which causes the wxApp handler just to skip it. MenuRef taskbarMenuRef = MAC_WXHMENU(pTB->m_pMenu->GetHMenu()); OSStatus err; // get the HICommand from the event HICommand command; err = GetEventParameter( inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &command ); if (err == noErr) { // Obtain the REAL menuRef and the menuItemIndex in the real menuRef // // NOTE: menuRef is generally used here for submenus, as // GetMenuItemRefCon could give an incorrect wxMenuItem if we pass // just the top level wxTaskBar menu MenuItemIndex menuItemIndex; MenuRef menuRef; err = GetIndMenuItemWithCommandID( taskbarMenuRef, command.commandID, 1, &menuRef, &menuItemIndex ); if (err == noErr) { MenuCommand id = command.commandID; wxMenuItem *item = NULL; if (id != 0) // get the wxMenuItem reference from the MenuRef GetMenuItemRefCon( menuRef, menuItemIndex, (URefCon*) &item ); if (item) { // Handle items that are checkable // FIXME: Doesn't work (at least on 10.2)! if (item->IsCheckable()) item->Check( !item->IsChecked() ); // send the wxEvent to the wxMenu item->GetMenu()->SendEvent( id, item->IsCheckable() ? item->IsChecked() : -1 ); // successfully handled the event err = noErr; } } } //end if noErr on getting HICommand from event // return whether we handled the event or not return err; } // We better have a kEventClassApplication/kEventAppGetDockTileMenu combo here, // otherwise something is truly funky wxASSERT(eventClass == kEventClassApplication && eventKind == kEventAppGetDockTileMenu); // process the right click events // NB: This may result in double or even triple-creation of the menus // We need to do this for 2.4 compat, however wxTaskBarIconEvent downevt(wxEVT_TASKBAR_RIGHT_DOWN, NULL); pTB->m_parent->ProcessEvent(downevt); wxTaskBarIconEvent upevt(wxEVT_TASKBAR_RIGHT_UP, NULL); pTB->m_parent->ProcessEvent(upevt); // create popup menu wxMenu* menu = pTB->DoCreatePopupMenu(); OSStatus err = eventNotHandledErr; if (menu != NULL) { // note to self - a MenuRef *is* a MenuHandle MenuRef hMenu = MAC_WXHMENU(menu->GetHMenu()); // When SetEventParameter is called it will decrement // the reference count of the menu - we need to make // sure it stays around in the wxMenu class here CFRetain(hMenu); // set the actual dock menu err = SetEventParameter( inEvent, kEventParamMenuRef, typeMenuRef, sizeof(MenuRef), &hMenu ); verify_noerr( err ); } return err; }
void wxChoice::SetString(int n, const wxString& s) { m_strings[n] = s ; // apple menu pos is 1-based UMASetMenuItemText( MAC_WXHMENU(m_macPopUpMenuHandle) , n + 1 , s , wxFont::GetDefaultEncoding() ) ; }
void wxMenu::SetTitle(const wxString& label) { m_title = label ; UMASetMenuTitle(MAC_WXHMENU(m_hMenu) , label , wxFont::GetDefaultEncoding() ) ; }
void wxMenu::MacEnableMenu( bool bDoEnable ) { UMAEnableMenuItem(MAC_WXHMENU(m_hMenu) , 0 , bDoEnable ) ; ::DrawMenuBar() ; }
// MacOS needs to know about submenus somewhere within this menu // before it can be displayed, also hide special menu items // like preferences that are handled by the OS void wxMenu::MacBeforeDisplay( bool isSubMenu ) { wxMenuItem* previousItem = NULL ; size_t pos ; wxMenuItemList::compatibility_iterator node; wxMenuItem *item; for (pos = 0, node = GetMenuItems().GetFirst(); node; node = node->GetNext(), pos++) { item = (wxMenuItem *)node->GetData(); wxMenu* subMenu = item->GetSubMenu() ; if (subMenu) { subMenu->MacBeforeDisplay( true ) ; } else // normal item { #if TARGET_CARBON // what we do here is to hide the special items which are // shown in the application menu anyhow -- it doesn't make // sense to show them in their normal place as well if ( item->GetId() == wxApp::s_macAboutMenuItemId || ( UMAGetSystemVersion() >= 0x1000 && ( item->GetId() == wxApp::s_macPreferencesMenuItemId || item->GetId() == wxApp::s_macExitMenuItemId ) ) ) { ChangeMenuItemAttributes( MAC_WXHMENU( GetHMenu() ), pos + 1, kMenuItemAttrHidden, 0 ); // also check for a separator which was used just to // separate this item from the others, so don't leave // separator at the menu start or end nor 2 consecutive // separators wxMenuItemList::compatibility_iterator nextNode = node->GetNext(); wxMenuItem *next = nextNode ? nextNode->GetData() : NULL; size_t posSeptoHide; if ( !previousItem && next && next->IsSeparator() ) { // next (i.e. second as we must be first) item is // the separator to hide wxASSERT_MSG( pos == 0, _T("should be the menu start") ); posSeptoHide = 2; } else if ( GetMenuItems().GetCount() == pos + 1 && previousItem != NULL && previousItem->IsSeparator() ) { // prev item is a trailing separator we want to hide posSeptoHide = pos; } else if ( previousItem && previousItem->IsSeparator() && next && next->IsSeparator() ) { // two consecutive separators, this is one too many posSeptoHide = pos; } else // no separators to hide { posSeptoHide = 0; } if ( posSeptoHide ) { // hide the separator as well ChangeMenuItemAttributes( MAC_WXHMENU( GetHMenu() ), posSeptoHide, kMenuItemAttrHidden, 0 ); } } #endif // TARGET_CARBON } previousItem = item ; } if ( isSubMenu ) ::InsertMenu(MAC_WXHMENU( GetHMenu()), -1); }
pascal OSStatus wxDockEventHandler( EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void* pData) { wxTaskBarIcon*& pTB = (wxTaskBarIcon*&) pData; const UInt32 eventClass = GetEventClass(inEvent); const UInt32 eventKind = GetEventKind(inEvent); if (eventClass == kEventClassCommand && eventKind == kEventCommandProcess) { //TODO: This is a complete copy of //static pascal OSStatus wxMacAppCommandEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) if (! pTB->GetCurrentMenu() ) { return eventNotHandledErr; } MenuRef hMenu = MAC_WXHMENU(pTB->GetCurrentMenu()->GetHMenu()); OSStatus result = eventNotHandledErr ; HICommand command ; OSErr err; err = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &command); wxASSERT(err == noErr); MenuItemIndex menuItemIndex; err = GetIndMenuItemWithCommandID(hMenu, command.commandID, 1, NULL, &menuItemIndex); wxASSERT(err == noErr); MenuCommand id = command.commandID ; wxMenuItem* item = NULL; // for items we don't really control if ( id == kHICommandPreferences ) { id = wxApp::s_macPreferencesMenuItemId ; wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar() ; if ( mbar ) { wxMenu* menu = NULL ; item = mbar->FindItem( id , &menu ) ; } } else if (id != 0) GetMenuItemRefCon( hMenu , menuItemIndex , (UInt32*) &item ) ; if ( item ) { if (item->IsCheckable()) { item->Check( !item->IsChecked() ) ; } item->GetMenu()->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) ; result = noErr ; } return result ; } wxASSERT(eventClass == kEventClassApplication && eventKind == kEventAppGetDockTileMenu); //process the right click events wxTaskBarIconEvent downevt(wxEVT_TASKBAR_RIGHT_DOWN,NULL); pTB->ProcessEvent(downevt); wxTaskBarIconEvent upevt(wxEVT_TASKBAR_RIGHT_UP,NULL); pTB->ProcessEvent(upevt); //create popup menu wxMenu* menu = pTB->DoCreatePopupMenu(); OSStatus err = noErr; if(menu) { //note to self - a MenuRef IS A MenuHandle MenuRef hMenu = MAC_WXHMENU(menu->GetHMenu()); //When we call SetEventParameter it will decrement //the reference count of the menu - we need to make //sure it stays around in the wxMenu class here RetainMenu(hMenu); //set the actual dock menu err = SetEventParameter((EventRef) inEvent, kEventParamMenuRef, typeMenuRef, sizeof(MenuRef), &hMenu); wxASSERT(err == 0); return err; } else return eventNotHandledErr; }
wxMenu::~wxMenu() { wxRemoveMacMenuAssociation( this ) ; if (MAC_WXHMENU(m_hMenu)) ::DisposeMenu(MAC_WXHMENU(m_hMenu)); }
//----------------------------------------------------------------------------- // wxDockEventHandler // // This is the global Mac/Carbon event handler for the dock. // We need this for two reasons: // 1) To handle wxTaskBarIcon menu events (see below for why) // 2) To handle events from the dock when it requests a menu //----------------------------------------------------------------------------- pascal OSStatus wxDockEventHandler(EventHandlerCallRef WXUNUSED(inHandlerCallRef), EventRef inEvent, void *pData) { // Get the parameters we want from the event wxDockTaskBarIcon* pTB = (wxDockTaskBarIcon*) pData; const UInt32 eventClass = GetEventClass(inEvent); const UInt32 eventKind = GetEventKind(inEvent); OSStatus err = eventNotHandledErr; // Handle wxTaskBar menu events (note that this is a global event handler // so it will actually get called by all commands/menus) if ((eventClass == kEventClassCommand) && (eventKind == kEventCommandProcess || eventKind == kEventCommandUpdateStatus )) { // if we have no taskbar menu quickly pass it back to wxApp if (pTB->m_pMenu != NULL) { // This is the real reason why we need this. Normally menus // get handled in wxMacAppEventHandler // However, in the case of a taskbar menu call // command.menu.menuRef IS NULL! // Which causes the wxApp handler just to skip it. // get the HICommand from the event HICommand command; if (GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL,sizeof(HICommand), NULL, &command ) == noErr) { // Obtain the REAL menuRef and the menuItemIndex in the real menuRef // // NOTE: menuRef is generally used here for submenus, as // GetMenuItemRefCon could give an incorrect wxMenuItem if we pass // just the top level wxTaskBar menu MenuItemIndex menuItemIndex; MenuRef menuRef; MenuRef taskbarMenuRef = MAC_WXHMENU(pTB->m_pMenu->GetHMenu()); // the next command is only successful if it was a command from the taskbar menu // otherwise we pass it on if (GetIndMenuItemWithCommandID(taskbarMenuRef,command.commandID, 1, &menuRef, &menuItemIndex ) == noErr) { wxMenu* itemMenu = wxFindMenuFromMacMenu( menuRef ) ; int id = wxMacCommandToId( command.commandID ) ; wxMenuItem *item = NULL; if (id != 0) // get the wxMenuItem reference from the MenuRef GetMenuItemRefCon( menuRef, menuItemIndex, (URefCon*) &item ); if (item && itemMenu ) { if ( eventKind == kEventCommandProcess ) { if ( itemMenu->HandleCommandProcess( item ) ) err = noErr; } else if ( eventKind == kEventCommandUpdateStatus ) { if ( itemMenu->HandleCommandUpdateStatus( item ) ) err = noErr; } } } } } //end if noErr on getting HICommand from event } else if ((eventClass == kEventClassApplication) && (eventKind == kEventAppGetDockTileMenu )) { // process the right click events // NB: This may result in double or even triple-creation of the menus // We need to do this for 2.4 compat, however wxTaskBarIconEvent downevt(wxEVT_TASKBAR_RIGHT_DOWN, NULL); pTB->m_parent->ProcessEvent(downevt); wxTaskBarIconEvent upevt(wxEVT_TASKBAR_RIGHT_UP, NULL); pTB->m_parent->ProcessEvent(upevt); // create popup menu wxMenu* menu = pTB->DoCreatePopupMenu(); if (menu != NULL) { // note to self - a MenuRef *is* a MenuHandle MenuRef hMenu = MAC_WXHMENU(menu->GetHMenu()); // When SetEventParameter is called it will decrement // the reference count of the menu - we need to make // sure it stays around in the wxMenu class here CFRetain(hMenu); // set the actual dock menu err = SetEventParameter( inEvent, kEventParamMenuRef, typeMenuRef, sizeof(MenuRef), &hMenu ); verify_noerr( err ); } } return err; }
void wxMenuBar::MacInstallMenuBar() { if ( s_macInstalledMenuBar == this ) return ; MenuBarHandle menubar = NULL ; #if TARGET_API_MAC_OSX menubar = NewHandleClear( 6 /* sizeof( MenuBarHeader ) */ ) ; #else menubar = NewHandleClear( 12 ) ; (*menubar)[3] = 0x0a ; #endif ::SetMenuBar( menubar ) ; DisposeMenuBar( menubar ) ; MenuHandle appleMenu = NULL ; verify_noerr( CreateNewMenu( kwxMacAppleMenuId , 0 , &appleMenu ) ) ; verify_noerr( SetMenuTitleWithCFString( appleMenu , CFSTR( "\x14" ) ) ); // Add About/Preferences separator only on OS X // KH/RN: Separator is always present on 10.3 but not on 10.2 // However, the change from 10.2 to 10.3 suggests it is preferred #if TARGET_API_MAC_OSX InsertMenuItemTextWithCFString( appleMenu, CFSTR(""), 0, kMenuItemAttrSeparator, 0); #endif InsertMenuItemTextWithCFString( appleMenu, CFSTR("About..."), 0, 0, 0); MacInsertMenu( appleMenu , 0 ) ; // clean-up the help menu before adding new items static MenuHandle mh = NULL ; if ( mh != NULL ) { MenuItemIndex firstUserHelpMenuItem ; if ( UMAGetHelpMenu( &mh , &firstUserHelpMenuItem) == noErr ) { for ( int i = CountMenuItems( mh ) ; i >= firstUserHelpMenuItem ; --i ) DeleteMenuItem( mh , i ) ; } else { mh = NULL ; } } #if TARGET_CARBON if ( UMAGetSystemVersion() >= 0x1000 && wxApp::s_macPreferencesMenuItemId) { wxMenuItem *item = FindItem( wxApp::s_macPreferencesMenuItemId , NULL ) ; if ( item == NULL || !(item->IsEnabled()) ) DisableMenuCommand( NULL , kHICommandPreferences ) ; else EnableMenuCommand( NULL , kHICommandPreferences ) ; } // Unlike preferences which may or may not exist, the Quit item should be always // enabled unless it is added by the application and then disabled, otherwise // a program would be required to add an item with wxID_EXIT in order to get the // Quit menu item to be enabled, which seems a bit burdensome. if ( UMAGetSystemVersion() >= 0x1000 && wxApp::s_macExitMenuItemId) { wxMenuItem *item = FindItem( wxApp::s_macExitMenuItemId , NULL ) ; if ( item != NULL && !(item->IsEnabled()) ) DisableMenuCommand( NULL , kHICommandQuit ) ; else EnableMenuCommand( NULL , kHICommandQuit ) ; } #endif wxMenuList::compatibility_iterator menuIter = m_menus.GetFirst(); for (size_t i = 0; i < m_menus.GetCount(); i++, menuIter = menuIter->GetNext()) { wxMenuItemList::compatibility_iterator node; wxMenuItem *item; wxMenu* menu = menuIter->GetData() , *subMenu = NULL ; if ( m_titles[i] == wxT("?") || m_titles[i] == wxT("&?") || m_titles[i] == wxApp::s_macHelpMenuTitleName ) { for (node = menu->GetMenuItems().GetFirst(); node; node = node->GetNext()) { item = (wxMenuItem *)node->GetData(); subMenu = item->GetSubMenu() ; if (subMenu) { // we don't support hierarchical menus in the help menu yet } else { if ( item->GetId() != wxApp::s_macAboutMenuItemId ) { if ( mh == NULL ) { MenuItemIndex firstUserHelpMenuItem ; if ( UMAGetHelpMenu( &mh , &firstUserHelpMenuItem) != noErr ) { mh = NULL ; break ; } } } if ( item->IsSeparator() ) { if ( mh ) AppendMenuItemTextWithCFString( mh, CFSTR(""), kMenuItemAttrSeparator, 0,NULL); } else { wxAcceleratorEntry* entry = wxAcceleratorEntry::Create( item->GetText() ) ; if ( item->GetId() == wxApp::s_macAboutMenuItemId ) { // this will be taken care of below } else { if ( mh ) { UMAAppendMenuItem(mh, wxStripMenuCodes(item->GetText()) , wxFont::GetDefaultEncoding(), entry); SetMenuItemCommandID( mh , CountMenuItems(mh) , wxIdToMacCommand ( item->GetId() ) ) ; SetMenuItemRefCon( mh , CountMenuItems(mh) , (URefCon) item ) ; } } delete entry ; } } } } else { UMASetMenuTitle( MAC_WXHMENU(menu->GetHMenu()) , m_titles[i], m_font.GetEncoding() ) ; menu->MacBeforeDisplay(false) ; ::InsertMenu(MAC_WXHMENU(_wxMenuAt(m_menus, i)->GetHMenu()), 0); } } // take care of the about menu item wherever it is { wxMenu* aboutMenu ; wxMenuItem *aboutMenuItem = FindItem(wxApp::s_macAboutMenuItemId , &aboutMenu) ; if ( aboutMenuItem ) { wxAcceleratorEntry* entry = wxAcceleratorEntry::Create( aboutMenuItem->GetText() ) ; UMASetMenuItemText( GetMenuHandle( kwxMacAppleMenuId ) , 1 , wxStripMenuCodes ( aboutMenuItem->GetText() ) , wxFont::GetDefaultEncoding() ); UMAEnableMenuItem( GetMenuHandle( kwxMacAppleMenuId ) , 1 , true ); SetMenuItemCommandID( GetMenuHandle( kwxMacAppleMenuId ) , 1 , kHICommandAbout ) ; SetMenuItemRefCon(GetMenuHandle( kwxMacAppleMenuId ) , 1 , (URefCon)aboutMenuItem ) ; UMASetMenuItemShortcut( GetMenuHandle( kwxMacAppleMenuId ) , 1 , entry ) ; } } if ( GetAutoWindowMenu() ) { if ( MacGetWindowMenuHMenu() == NULL ) CreateStandardWindowMenu( 0 , (MenuHandle*) &s_macWindowMenuHandle ) ; InsertMenu( (MenuHandle) MacGetWindowMenuHMenu() , 0 ) ; } ::DrawMenuBar() ; s_macInstalledMenuBar = this; }
void wxMenuBar::MacInstallMenuBar() { if ( s_macInstalledMenuBar == this ) return ; m_rootMenu->GetPeer()->MakeRoot(); // hide items in the apple menu that don't exist in the wx menubar int menuid = 0; wxMenuItem* appleItem = NULL; wxMenuItem* wxItem = NULL; menuid = wxApp::s_macAboutMenuItemId; appleItem = m_appleMenu->FindItem(menuid); wxItem = FindItem(menuid); if ( appleItem != NULL ) { if ( wxItem == NULL ) appleItem->GetPeer()->Hide(); else appleItem->SetItemLabel(wxItem->GetItemLabel()); } menuid = wxApp::s_macPreferencesMenuItemId; appleItem = m_appleMenu->FindItem(menuid); wxItem = FindItem(menuid); if ( appleItem != NULL ) { if ( wxItem == NULL ) appleItem->GetPeer()->Hide(); else appleItem->SetItemLabel(wxItem->GetItemLabel()); } #if 0 // if we have a mac help menu, clean it up before adding new items MenuHandle helpMenuHandle ; MenuItemIndex firstUserHelpMenuItem ; if ( UMAGetHelpMenuDontCreate( &helpMenuHandle , &firstUserHelpMenuItem) == noErr ) { for ( int i = CountMenuItems( helpMenuHandle ) ; i >= firstUserHelpMenuItem ; --i ) DeleteMenuItem( helpMenuHandle , i ) ; } else { helpMenuHandle = NULL ; } if ( wxApp::s_macPreferencesMenuItemId) { wxMenuItem *item = FindItem( wxApp::s_macPreferencesMenuItemId , NULL ) ; if ( item == NULL || !(item->IsEnabled()) ) DisableMenuCommand( NULL , kHICommandPreferences ) ; else EnableMenuCommand( NULL , kHICommandPreferences ) ; } // Unlike preferences which may or may not exist, the Quit item should be always // enabled unless it is added by the application and then disabled, otherwise // a program would be required to add an item with wxID_EXIT in order to get the // Quit menu item to be enabled, which seems a bit burdensome. if ( wxApp::s_macExitMenuItemId) { wxMenuItem *item = FindItem( wxApp::s_macExitMenuItemId , NULL ) ; if ( item != NULL && !(item->IsEnabled()) ) DisableMenuCommand( NULL , kHICommandQuit ) ; else EnableMenuCommand( NULL , kHICommandQuit ) ; } wxString strippedHelpMenuTitle = wxStripMenuCodes( wxApp::s_macHelpMenuTitleName ) ; wxString strippedTranslatedHelpMenuTitle = wxStripMenuCodes( wxString( _("&Help") ) ) ; wxMenuList::compatibility_iterator menuIter = m_menus.GetFirst(); for (size_t i = 0; i < m_menus.GetCount(); i++, menuIter = menuIter->GetNext()) { wxMenuItemList::compatibility_iterator node; wxMenuItem *item; wxMenu* menu = menuIter->GetData() , *subMenu = NULL ; wxString strippedMenuTitle = wxStripMenuCodes(m_titles[i]); if ( strippedMenuTitle == wxT("?") || strippedMenuTitle == strippedHelpMenuTitle || strippedMenuTitle == strippedTranslatedHelpMenuTitle ) { for (node = menu->GetMenuItems().GetFirst(); node; node = node->GetNext()) { item = (wxMenuItem *)node->GetData(); subMenu = item->GetSubMenu() ; if (subMenu) { UMAAppendMenuItem(mh, wxStripMenuCodes(item->GetText()) , wxFont::GetDefaultEncoding() ); MenuItemIndex position = CountMenuItems(mh); ::SetMenuItemHierarchicalMenu(mh, position, MAC_WXHMENU(subMenu->GetHMenu())); } else { if ( item->GetId() != wxApp::s_macAboutMenuItemId ) { // we have found a user help menu and an item other than the about item, // so we can create the mac help menu now, if we haven't created it yet if ( helpMenuHandle == NULL ) { if ( UMAGetHelpMenu( &helpMenuHandle , &firstUserHelpMenuItem) != noErr ) { helpMenuHandle = NULL ; break ; } } } if ( item->IsSeparator() ) { if ( helpMenuHandle ) AppendMenuItemTextWithCFString( helpMenuHandle, CFSTR(""), kMenuItemAttrSeparator, 0,NULL); } else { wxAcceleratorEntry* entry = wxAcceleratorEntry::Create( item->GetItemLabel() ) ; if ( item->GetId() == wxApp::s_macAboutMenuItemId ) { // this will be taken care of below } else { if ( helpMenuHandle ) { UMAAppendMenuItem(helpMenuHandle, wxStripMenuCodes(item->GetItemLabel()) , wxFont::GetDefaultEncoding(), entry); SetMenuItemCommandID( helpMenuHandle , CountMenuItems(helpMenuHandle) , wxIdToMacCommand ( item->GetId() ) ) ; SetMenuItemRefCon( helpMenuHandle , CountMenuItems(helpMenuHandle) , (URefCon) item ) ; } } delete entry ; } } } } else if ( ( m_titles[i] == wxT("Window") || m_titles[i] == wxT("&Window") ) && GetAutoWindowMenu() ) { if ( MacGetWindowMenuHMenu() == NULL ) { CreateStandardWindowMenu( 0 , (MenuHandle*) &s_macWindowMenuHandle ) ; } MenuRef wm = (MenuRef)MacGetWindowMenuHMenu(); if ( wm == NULL ) break; // get the insertion point in the standard menu MenuItemIndex winListStart; GetIndMenuItemWithCommandID(wm, kHICommandWindowListSeparator, 1, NULL, &winListStart); // add a separator so that the standard items and the custom items // aren't mixed together, but only if this is the first run OSStatus err = GetIndMenuItemWithCommandID(wm, 'WXWM', 1, NULL, NULL); if ( err == menuItemNotFoundErr ) { InsertMenuItemTextWithCFString( wm, CFSTR(""), winListStart-1, kMenuItemAttrSeparator, 'WXWM'); } wxInsertMenuItemsInMenu(menu, wm, winListStart); } else { UMASetMenuTitle( MAC_WXHMENU(menu->GetHMenu()) , m_titles[i], GetFont().GetEncoding() ) ; menu->MacBeforeDisplay(false) ; ::InsertMenu(MAC_WXHMENU(GetMenu(i)->GetHMenu()), 0); } } // take care of the about menu item wherever it is { wxMenu* aboutMenu ; wxMenuItem *aboutMenuItem = FindItem(wxApp::s_macAboutMenuItemId , &aboutMenu) ; if ( aboutMenuItem ) { wxAcceleratorEntry* entry = wxAcceleratorEntry::Create( aboutMenuItem->GetItemLabel() ) ; UMASetMenuItemText( GetMenuHandle( kwxMacAppleMenuId ) , 1 , wxStripMenuCodes ( aboutMenuItem->GetItemLabel() ) , wxFont::GetDefaultEncoding() ); UMAEnableMenuItem( GetMenuHandle( kwxMacAppleMenuId ) , 1 , true ); SetMenuItemCommandID( GetMenuHandle( kwxMacAppleMenuId ) , 1 , kHICommandAbout ) ; SetMenuItemRefCon(GetMenuHandle( kwxMacAppleMenuId ) , 1 , (URefCon)aboutMenuItem ) ; UMASetMenuItemShortcut( GetMenuHandle( kwxMacAppleMenuId ) , 1 , entry ) ; delete entry; } } if ( GetAutoWindowMenu() ) { if ( MacGetWindowMenuHMenu() == NULL ) CreateStandardWindowMenu( 0 , (MenuHandle*) &s_macWindowMenuHandle ) ; InsertMenu( (MenuHandle) MacGetWindowMenuHMenu() , 0 ) ; } ::DrawMenuBar() ; #endif s_macInstalledMenuBar = this; }
// function appends a new item or submenu to the menu // append a new item or submenu to the menu bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos) { wxASSERT_MSG( pItem != NULL, wxT("can't append NULL item to the menu") ); if ( pItem->IsSeparator() ) { if ( pos == (size_t)-1 ) AppendMenuItemTextWithCFString( MAC_WXHMENU(m_hMenu), CFSTR(""), kMenuItemAttrSeparator, 0,NULL); else InsertMenuItemTextWithCFString( MAC_WXHMENU(m_hMenu), CFSTR(""), pos, kMenuItemAttrSeparator, 0); } else { wxMenu *pSubMenu = pItem->GetSubMenu() ; if ( pSubMenu != NULL ) { wxASSERT_MSG( pSubMenu->m_hMenu != NULL , wxT("invalid submenu added")); pSubMenu->m_menuParent = this ; if (wxMenuBar::MacGetInstalledMenuBar() == GetMenuBar()) pSubMenu->MacBeforeDisplay( true ) ; if ( pos == (size_t)-1 ) UMAAppendSubMenuItem(MAC_WXHMENU(m_hMenu), wxStripMenuCodes(pItem->GetText()), wxFont::GetDefaultEncoding(), pSubMenu->m_macMenuId); else UMAInsertSubMenuItem(MAC_WXHMENU(m_hMenu), wxStripMenuCodes(pItem->GetText()), wxFont::GetDefaultEncoding(), pos, pSubMenu->m_macMenuId); pItem->UpdateItemBitmap() ; pItem->UpdateItemStatus() ; } else { if ( pos == (size_t)-1 ) { UMAAppendMenuItem(MAC_WXHMENU(m_hMenu), wxT("a") , wxFont::GetDefaultEncoding() ); pos = CountMenuItems(MAC_WXHMENU(m_hMenu)) ; } else { // MacOS counts menu items from 1 and inserts after, therefore having the // same effect as wx 0 based and inserting before, we must correct pos // after however for updates to be correct UMAInsertMenuItem(MAC_WXHMENU(m_hMenu), wxT("a"), wxFont::GetDefaultEncoding(), pos); pos += 1 ; } SetMenuItemCommandID( MAC_WXHMENU(m_hMenu) , pos , wxIdToMacCommand ( pItem->GetId() ) ) ; SetMenuItemRefCon( MAC_WXHMENU(m_hMenu) , pos , (URefCon) pItem ) ; pItem->UpdateItemText() ; pItem->UpdateItemBitmap() ; pItem->UpdateItemStatus() ; if ( pItem->GetId() == idMenuTitle ) UMAEnableMenuItem(MAC_WXHMENU(m_hMenu) , pos , false ) ; } } // if we're already attached to the menubar, we must update it if ( IsAttached() && GetMenuBar()->IsAttached() ) GetMenuBar()->Refresh(); return true ; }