wxMenu Review, added Carbon Events and full OSX Support

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@18972 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Stefan Csomor
2003-01-28 07:55:08 +00:00
parent cbf8aca6d4
commit bf918b97ed
4 changed files with 500 additions and 594 deletions

View File

@@ -35,146 +35,6 @@
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// //
// Helper Functions to get Mac Menus the way they should be ;-)
//
void wxMacCtoPString(const char* theCString, Str255 thePString);
// remove inappropriate characters, if useShortcuts is false, the ampersand will not auto-generate a mac menu-shortcut
int wxMenuItem::MacBuildMenuString(StringPtr outMacItemText, SInt16 *outMacShortcutChar , UInt8 *outMacModifiers , const char *inItemText , bool useShortcuts )
{
char *p = (char *) &outMacItemText[1] ;
short macModifiers = 0 ;
SInt16 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 ;
// we have problems with a leading hypen - it will be taken as a separator
while ( *inItemName == '-' )
inItemName++ ;
while( *inItemName )
{
switch ( *inItemName )
{
// shortcuts
case '&' :
{
++inItemName ;
if ( *inItemName )
{
*p++ = *inItemName ;
if ( useShortcuts )
macShortCut = *inItemName ;
}
else
--inItemName ;
}
break ;
// win-like accelerators
case '\t' :
{
++inItemName ;
bool skip = false ;
bool explicitCommandKey = false ;
while( *inItemName && !skip )
{
if (wxStrnicmp("Ctrl", inItemName, 4) == 0)
{
inItemName = inItemName + 5;
explicitCommandKey = true ;
}
else if (wxStrnicmp("Cntrl", inItemName, 5) == 0)
{
inItemName = inItemName + 6;
explicitCommandKey = true ;
}
else if (wxStrnicmp("Alt", inItemName, 3) == 0)
{
inItemName = inItemName + 4;
macModifiers |= kMenuOptionModifier ;
}
else if (wxStrnicmp("Shift", inItemName, 5) == 0)
{
inItemName = inItemName + 6;
macModifiers |= kMenuShiftModifier ;
}
else
{
skip = true ;
}
}
if ( *inItemName )
{
if ( strlen(inItemName) == 1 )
{
macShortCut = *inItemName;
}
else if ( !wxStricmp( inItemName , "Delete" ) || !wxStricmp( inItemName , "Del" ) )
{
macShortCut = WXK_DELETE ;
}
else if ( !wxStricmp( inItemName , "Back" ) || !wxStricmp( inItemName , "Backspace" ) )
{
macShortCut = WXK_BACK ;
}
else if ( !wxStricmp( inItemName , "Return" ) )
{
macShortCut = WXK_RETURN ;
}
else if ( !wxStricmp( inItemName , "Enter" ) )
{
macShortCut = kEnterCharCode ;
}
else if ( *inItemName == 'F' )
{
int fkey = atol(inItemName+1) ;
if (fkey >= 1 && fkey < 15 )
{
macShortCut = WXK_F1 + fkey - 1 ;
}
if ( !explicitCommandKey )
macModifiers |= kMenuNoCommandModifier ;
}
}
inItemName += strlen( inItemName ) ;
if ( *inItemName == 0 )
--inItemName ;
}
break ;
default :
*p++ = *inItemName ;
}
++inItemName ;
}
outMacItemText[0] = (p - (char *)outMacItemText) - 1;
if ( outMacShortcutChar )
*outMacShortcutChar = macShortCut ;
if ( outMacModifiers )
*outMacModifiers = macModifiers ;
return 0 ;
}
// ctor & dtor // ctor & dtor
// ----------- // -----------
@@ -186,115 +46,164 @@ wxMenuItem::wxMenuItem(wxMenu *pParentMenu,
wxMenu *pSubMenu) wxMenu *pSubMenu)
: wxMenuItemBase(pParentMenu, id, text, strHelp, kind, pSubMenu) : wxMenuItemBase(pParentMenu, id, text, strHelp, kind, pSubMenu)
{ {
// VZ: what about translations?? (FIXME) // In other languages there is no difference in naming the Exit/Quit menu item between MacOS and Windows guidelines
if ( m_text == "E&xit" ||m_text == "Exit" ||m_text.Left(5) == "Exit\t" || m_text.Left(6) == "E&xit\t" ) // therefore these item must not be translated
if ( wxStripMenuCodes(m_text).Upper() == "EXIT" )
{ {
m_text = "Quit\tCtrl+Q" ; m_text = "Quit\tCtrl+Q" ;
} }
m_radioGroup.start = -1;
m_isRadioGroupStart = FALSE;
} }
wxMenuItem::~wxMenuItem() wxMenuItem::~wxMenuItem()
{ {
} }
bool wxMenuItem::IsChecked() const
{
return wxMenuItemBase::IsChecked() ;
}
wxString wxMenuItem::GetLabel() const
{
return wxStripMenuCodes(m_text);
}
// accelerators
// ------------
#if wxUSE_ACCEL
wxAcceleratorEntry *wxMenuItem::GetAccel() const
{
return wxGetAccelFromString(GetText());
}
#endif // wxUSE_ACCEL
// misc
// ----
/*
// delete the sub menu
void wxMenuItem::DeleteSubMenu()
{
wxASSERT( m_subMenu != NULL );
delete m_subMenu;
m_subMenu = NULL;
}
*/
// change item state // change item state
// ----------------- // -----------------
void wxMenuItem::SetBitmap(const wxBitmap& bitmap)
{
m_bitmap = bitmap;
UpdateItemBitmap() ;
}
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() )
{
ControlButtonContentInfo info ;
wxMacCreateBitmapButton( &info , m_bitmap , kControlContentCIconHandle ) ;
if ( info.contentType != kControlNoContent )
{
if ( info.contentType == kControlContentCIconHandle )
SetMenuItemIconHandle( mhandle , index ,
kMenuColorIconType , (Handle) info.u.cIconHandle ) ;
}
}
}
void wxMenuItem::UpdateItemStatus()
{
if ( !m_parentMenu )
return ;
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 , m_text ) ;
wxAcceleratorEntry *entry = wxGetAccelFromString( m_text ) ;
UMASetMenuItemShortcut( mhandle , index , entry ) ;
delete entry ;
}
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 ;
UMASetMenuItemText( mhandle , index , m_text ) ;
wxAcceleratorEntry *entry = wxGetAccelFromString( m_text ) ;
UMASetMenuItemShortcut( mhandle , index , entry ) ;
delete entry ;
}
void wxMenuItem::Enable(bool bDoEnable) void wxMenuItem::Enable(bool bDoEnable)
{ {
if ( m_isEnabled != bDoEnable ) { if ( m_isEnabled != bDoEnable )
if ( m_subMenu == NULL ) {
{ wxMenuItemBase::Enable( bDoEnable ) ;
// normal menu item UpdateItemStatus() ;
if ( MAC_WXHMENU(m_parentMenu->GetHMenu()) ) }
{ }
int index = m_parentMenu->MacGetIndexFromItem( this ) ; void wxMenuItem::UncheckRadio()
if ( index >= 1 ) {
{ if ( m_isChecked )
if ( bDoEnable ) {
UMAEnableMenuItem( MAC_WXHMENU(m_parentMenu->GetHMenu()) , index ) ; wxMenuItemBase::Check( false ) ;
else UpdateItemStatus() ;
UMADisableMenuItem( MAC_WXHMENU(m_parentMenu->GetHMenu()) , index ) ; }
}
}
}
else
{
// submenu
if ( MAC_WXHMENU(m_parentMenu->GetHMenu()) )
{
int index = m_parentMenu->MacGetIndexFromItem( this ) ;
if ( index >= 1 )
{
if ( bDoEnable )
UMAEnableMenuItem( MAC_WXHMENU(m_parentMenu->GetHMenu()) , index ) ;
else
UMADisableMenuItem( MAC_WXHMENU(m_parentMenu->GetHMenu()) , index ) ;
}
}
}
m_isEnabled = bDoEnable;
}
} }
void wxMenuItem::Check(bool bDoCheck) void wxMenuItem::Check(bool bDoCheck)
{ {
wxCHECK_RET( IsCheckable(), "only checkable items may be checked" ); wxCHECK_RET( IsCheckable(), "only checkable items may be checked" );
if ( m_isChecked != bDoCheck ) if ( m_isChecked != bDoCheck )
{ {
m_isChecked = bDoCheck; if ( GetKind() == wxITEM_RADIO )
if ( MAC_WXHMENU(m_parentMenu->GetHMenu()) ) {
{ if ( bDoCheck )
int index = m_parentMenu->MacGetIndexFromItem( this ) ; {
if ( index >= 1 ) wxMenuItemBase::Check( bDoCheck ) ;
{ UpdateItemStatus() ;
if ( bDoCheck )
::SetItemMark( MAC_WXHMENU(m_parentMenu->GetHMenu()) , index , 0x12 ) ; // checkmark // get the index of this item in the menu
else const wxMenuItemList& items = m_parentMenu->GetMenuItems();
::SetItemMark( MAC_WXHMENU(m_parentMenu->GetHMenu()) , index , 0 ) ; // no mark int pos = items.IndexOf(this);
} wxCHECK_RET( pos != wxNOT_FOUND,
} _T("menuitem not found in the menu items list?") );
}
// get the radio group range
int start,
end;
if ( m_isRadioGroupStart )
{
// we already have all information we need
start = pos;
end = m_radioGroup.end;
}
else // next radio group item
{
// get the radio group end from the start item
start = m_radioGroup.start;
end = items.Item(start)->GetData()->m_radioGroup.end;
}
// also uncheck all the other items in this radio group
wxMenuItemList::Node *node = items.Item(start);
for ( int n = start; n <= end && node; n++ )
{
if ( n != pos )
{
((wxMenuItem*)node->GetData())->UncheckRadio();
}
node = node->GetNext();
}
}
}
else
{
wxMenuItemBase::Check( bDoCheck ) ;
UpdateItemStatus() ;
}
}
} }
void wxMenuItem::SetText(const wxString& text) void wxMenuItem::SetText(const wxString& text)
@@ -304,29 +213,32 @@ void wxMenuItem::SetText(const wxString& text)
return; return;
wxMenuItemBase::SetText(text); wxMenuItemBase::SetText(text);
// OWNER_DRAWN_ONLY( wxOwnerDrawn::SetName(text) );
UpdateItemText() ;
wxCHECK_RET( m_parentMenu && m_parentMenu->GetHMenu(), wxT("menuitem without menu") );
if ( MAC_WXHMENU(m_parentMenu->GetHMenu()) )
{
int index = m_parentMenu->MacGetIndexFromItem( this ) ;
if ( index >= 1 )
{
Str255 label;
MacBuildMenuString( label , NULL , NULL , text ,false);
::SetMenuItemText( MAC_WXHMENU(m_parentMenu->GetHMenu()) , index , label ) ; // checkmark
}
}
#if wxUSE_ACCEL
m_parentMenu->UpdateAccel(this);
#endif // wxUSE_ACCEL
} }
void wxMenuItem::SetCheckable(bool checkable)
// radio group stuff
// -----------------
void wxMenuItem::SetAsRadioGroupStart()
{ {
wxMenuItemBase::SetCheckable(checkable); m_isRadioGroupStart = TRUE;
// OWNER_DRAWN_ONLY( wxOwnerDrawn::SetCheckable(checkable) ); }
void wxMenuItem::SetRadioGroupStart(int start)
{
wxASSERT_MSG( !m_isRadioGroupStart,
_T("should only be called for the next radio items") );
m_radioGroup.start = start;
}
void wxMenuItem::SetRadioGroupEnd(int end)
{
wxASSERT_MSG( m_isRadioGroupStart,
_T("should only be called for the first radio item") );
m_radioGroup.end = end;
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@@ -180,67 +180,105 @@ bool UMAGetProcessModeDoesActivateOnFGSwitch()
// menu manager // menu manager
void UMASetMenuTitle( MenuRef menu , StringPtr title ) MenuRef UMANewMenu( SInt16 id , const wxString& title )
{ {
/* wxString str = wxStripMenuCodes( title ) ;
#if !TARGET_CARBON MenuRef menu ;
long size = GetHandleSize( (Handle) menu ) ; #if TARGET_CARBON
const long headersize = 14 ; CFStringRef cfs = wxMacCreateCFString( str ) ;
int oldlen = (**menu).menuData[0] + 1; CreateNewMenu( id , 0 , &menu ) ;
int newlen = title[0] + 1 ; SetMenuTitleWithCFString( menu , cfs ) ;
CFRelease( cfs ) ;
if ( oldlen < newlen )
{
// enlarge before adjusting
SetHandleSize( (Handle) menu , size + (newlen - oldlen ) );
}
if ( oldlen != newlen )
memmove( (char*) (**menu).menuData + newlen , (char*) (**menu).menuData + oldlen , size - headersize - oldlen ) ;
memcpy( (char*) (**menu).menuData , title , newlen ) ;
if ( oldlen > newlen )
{
// shrink after
SetHandleSize( (Handle) menu , size + (newlen - oldlen ) ) ;
}
#else #else
*/ Str255 ptitle ;
SetMenuTitle( menu , title ) ; wxMacStringToPascal( str , ptitle ) ;
//#endif menu = ::NewMenu( id , ptitle ) ;
#endif
return menu ;
} }
void UMASetMenuTitle( MenuRef menu , const wxString& title )
{
wxString str = wxStripMenuCodes( title ) ;
#if TARGET_CARBON
CFStringRef cfs = wxMacCreateCFString( str ) ;
SetMenuTitleWithCFString( menu , cfs ) ;
CFRelease( cfs ) ;
#else
Str255 ptitle ;
wxMacStringToPascal( str , ptitle ) ;
SetMenuTitle( menu , ptitle ) ;
#endif
}
void UMASetMenuItemText( MenuRef menu, MenuItemIndex item, const wxString& title )
{
wxString str = wxStripMenuCodes( title ) ;
#if TARGET_CARBON
CFStringRef cfs = wxMacCreateCFString( str ) ;
SetMenuItemTextWithCFString( menu , item , cfs ) ;
CFRelease( cfs ) ;
#else
Str255 ptitle ;
wxMacStringToPascal( str , ptitle ) ;
SetMenuItemText( menu , item , ptitle ) ;
#endif
}
UInt32 UMAMenuEvent( EventRecord *inEvent ) UInt32 UMAMenuEvent( EventRecord *inEvent )
{ {
return MenuEvent( inEvent ) ; return MenuEvent( inEvent ) ;
} }
void UMAEnableMenuItem( MenuRef inMenu , MenuItemIndex inItem ) void UMAEnableMenuItem( MenuRef inMenu , MenuItemIndex inItem , bool enable)
{ {
EnableMenuItem( inMenu , inItem ) ; if ( enable )
EnableMenuItem( inMenu , inItem ) ;
else
DisableMenuItem( inMenu , inItem ) ;
} }
void UMADisableMenuItem( MenuRef inMenu , MenuItemIndex inItem ) void UMAAppendSubMenuItem( MenuRef menu , const wxString& title , SInt16 id )
{ {
DisableMenuItem( inMenu , inItem ) ; MacAppendMenu(menu, "\pA");
} UMASetMenuItemText(menu, (SInt16) ::CountMenuItems(menu), title );
void UMAAppendSubMenuItem( MenuRef menu , StringPtr l , SInt16 id )
{
MacAppendMenu(menu, l);
SetMenuItemHierarchicalID( menu , CountMenuItems( menu ) , id ) ; SetMenuItemHierarchicalID( menu , CountMenuItems( menu ) , id ) ;
} }
void UMAInsertSubMenuItem( MenuRef menu , StringPtr l , MenuItemIndex item , SInt16 id ) void UMAInsertSubMenuItem( MenuRef menu , const wxString& title , MenuItemIndex item , SInt16 id )
{ {
MacInsertMenuItem(menu, l , item); MacInsertMenuItem(menu, "\pA" , item);
UMASetMenuItemText(menu, item , title );
SetMenuItemHierarchicalID( menu , item , id ) ; SetMenuItemHierarchicalID( menu , item , id ) ;
} }
void UMASetMenuItemShortcut( MenuRef menu , MenuItemIndex item , SInt16 key , UInt8 modifiers ) void UMASetMenuItemShortcut( MenuRef menu , MenuItemIndex item , wxAcceleratorEntry *entry )
{ {
if ( !entry )
return ;
UInt8 modifiers = 0 ;
SInt16 key = entry->GetKeyCode() ;
if ( key ) if ( key )
{ {
bool explicitCommandKey = false ;
if ( entry->GetFlags() & wxACCEL_CTRL )
{
explicitCommandKey = true ;
}
if (entry->GetFlags() & wxACCEL_ALT )
{
modifiers |= kMenuOptionModifier ;
}
if (entry->GetFlags() & wxACCEL_SHIFT)
{
modifiers |= kMenuShiftModifier ;
}
SInt16 glyph = 0 ; SInt16 glyph = 0 ;
SInt16 macKey = key ; SInt16 macKey = key ;
if ( key >= WXK_F1 && key <= WXK_F15 ) if ( key >= WXK_F1 && key <= WXK_F15 )
@@ -249,7 +287,10 @@ void UMASetMenuItemShortcut( MenuRef menu , MenuItemIndex item , SInt16 key , UI
glyph = kMenuF1Glyph + ( key - WXK_F1 ) ; glyph = kMenuF1Glyph + ( key - WXK_F1 ) ;
if ( key >= WXK_F13 ) if ( key >= WXK_F13 )
glyph += 13 ; glyph += 13 ;
switch( key ) if ( !explicitCommandKey )
modifiers |= kMenuNoCommandModifier ;
switch( key )
{ {
case WXK_F1 : case WXK_F1 :
macKey += ( 0x7a << 8 ) ; macKey += ( 0x7a << 8 ) ;
@@ -367,7 +408,7 @@ void UMASetMenuItemShortcut( MenuRef menu , MenuItemIndex item , SInt16 key , UI
break ; break ;
} }
} }
SetItemCmd( menu, item , macKey ); SetItemCmd( menu, item , macKey );
SetMenuItemModifiers(menu, item , modifiers ) ; SetMenuItemModifiers(menu, item , modifiers ) ;
@@ -376,18 +417,18 @@ void UMASetMenuItemShortcut( MenuRef menu , MenuItemIndex item , SInt16 key , UI
} }
} }
void UMAAppendMenuItem( MenuRef menu , StringPtr l , SInt16 key, UInt8 modifiers ) void UMAAppendMenuItem( MenuRef menu , const wxString& title , wxAcceleratorEntry *entry )
{ {
MacAppendMenu(menu, "\pA"); MacAppendMenu(menu, "\pA");
SetMenuItemText(menu, (SInt16) ::CountMenuItems(menu), l); UMASetMenuItemText(menu, (SInt16) ::CountMenuItems(menu), title );
UMASetMenuItemShortcut( menu , (SInt16) ::CountMenuItems(menu), key , modifiers ) ; UMASetMenuItemShortcut( menu , (SInt16) ::CountMenuItems(menu), entry ) ;
} }
void UMAInsertMenuItem( MenuRef menu , StringPtr l , MenuItemIndex item , SInt16 key, UInt8 modifiers ) void UMAInsertMenuItem( MenuRef menu , const wxString& title , MenuItemIndex item , wxAcceleratorEntry *entry )
{ {
MacInsertMenuItem( menu , "\p" , item) ; MacInsertMenuItem( menu , "\p" , item) ;
SetMenuItemText(menu, item , l); UMASetMenuItemText(menu, item , title );
UMASetMenuItemShortcut( menu , item , key , modifiers ) ; UMASetMenuItemShortcut( menu , item , entry ) ;
} }
// quickdraw // quickdraw

View File

@@ -35,146 +35,6 @@
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// //
// Helper Functions to get Mac Menus the way they should be ;-)
//
void wxMacCtoPString(const char* theCString, Str255 thePString);
// remove inappropriate characters, if useShortcuts is false, the ampersand will not auto-generate a mac menu-shortcut
int wxMenuItem::MacBuildMenuString(StringPtr outMacItemText, SInt16 *outMacShortcutChar , UInt8 *outMacModifiers , const char *inItemText , bool useShortcuts )
{
char *p = (char *) &outMacItemText[1] ;
short macModifiers = 0 ;
SInt16 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 ;
// we have problems with a leading hypen - it will be taken as a separator
while ( *inItemName == '-' )
inItemName++ ;
while( *inItemName )
{
switch ( *inItemName )
{
// shortcuts
case '&' :
{
++inItemName ;
if ( *inItemName )
{
*p++ = *inItemName ;
if ( useShortcuts )
macShortCut = *inItemName ;
}
else
--inItemName ;
}
break ;
// win-like accelerators
case '\t' :
{
++inItemName ;
bool skip = false ;
bool explicitCommandKey = false ;
while( *inItemName && !skip )
{
if (wxStrnicmp("Ctrl", inItemName, 4) == 0)
{
inItemName = inItemName + 5;
explicitCommandKey = true ;
}
else if (wxStrnicmp("Cntrl", inItemName, 5) == 0)
{
inItemName = inItemName + 6;
explicitCommandKey = true ;
}
else if (wxStrnicmp("Alt", inItemName, 3) == 0)
{
inItemName = inItemName + 4;
macModifiers |= kMenuOptionModifier ;
}
else if (wxStrnicmp("Shift", inItemName, 5) == 0)
{
inItemName = inItemName + 6;
macModifiers |= kMenuShiftModifier ;
}
else
{
skip = true ;
}
}
if ( *inItemName )
{
if ( strlen(inItemName) == 1 )
{
macShortCut = *inItemName;
}
else if ( !wxStricmp( inItemName , "Delete" ) || !wxStricmp( inItemName , "Del" ) )
{
macShortCut = WXK_DELETE ;
}
else if ( !wxStricmp( inItemName , "Back" ) || !wxStricmp( inItemName , "Backspace" ) )
{
macShortCut = WXK_BACK ;
}
else if ( !wxStricmp( inItemName , "Return" ) )
{
macShortCut = WXK_RETURN ;
}
else if ( !wxStricmp( inItemName , "Enter" ) )
{
macShortCut = kEnterCharCode ;
}
else if ( *inItemName == 'F' )
{
int fkey = atol(inItemName+1) ;
if (fkey >= 1 && fkey < 15 )
{
macShortCut = WXK_F1 + fkey - 1 ;
}
if ( !explicitCommandKey )
macModifiers |= kMenuNoCommandModifier ;
}
}
inItemName += strlen( inItemName ) ;
if ( *inItemName == 0 )
--inItemName ;
}
break ;
default :
*p++ = *inItemName ;
}
++inItemName ;
}
outMacItemText[0] = (p - (char *)outMacItemText) - 1;
if ( outMacShortcutChar )
*outMacShortcutChar = macShortCut ;
if ( outMacModifiers )
*outMacModifiers = macModifiers ;
return 0 ;
}
// ctor & dtor // ctor & dtor
// ----------- // -----------
@@ -186,115 +46,164 @@ wxMenuItem::wxMenuItem(wxMenu *pParentMenu,
wxMenu *pSubMenu) wxMenu *pSubMenu)
: wxMenuItemBase(pParentMenu, id, text, strHelp, kind, pSubMenu) : wxMenuItemBase(pParentMenu, id, text, strHelp, kind, pSubMenu)
{ {
// VZ: what about translations?? (FIXME) // In other languages there is no difference in naming the Exit/Quit menu item between MacOS and Windows guidelines
if ( m_text == "E&xit" ||m_text == "Exit" ||m_text.Left(5) == "Exit\t" || m_text.Left(6) == "E&xit\t" ) // therefore these item must not be translated
if ( wxStripMenuCodes(m_text).Upper() == "EXIT" )
{ {
m_text = "Quit\tCtrl+Q" ; m_text = "Quit\tCtrl+Q" ;
} }
m_radioGroup.start = -1;
m_isRadioGroupStart = FALSE;
} }
wxMenuItem::~wxMenuItem() wxMenuItem::~wxMenuItem()
{ {
} }
bool wxMenuItem::IsChecked() const
{
return wxMenuItemBase::IsChecked() ;
}
wxString wxMenuItem::GetLabel() const
{
return wxStripMenuCodes(m_text);
}
// accelerators
// ------------
#if wxUSE_ACCEL
wxAcceleratorEntry *wxMenuItem::GetAccel() const
{
return wxGetAccelFromString(GetText());
}
#endif // wxUSE_ACCEL
// misc
// ----
/*
// delete the sub menu
void wxMenuItem::DeleteSubMenu()
{
wxASSERT( m_subMenu != NULL );
delete m_subMenu;
m_subMenu = NULL;
}
*/
// change item state // change item state
// ----------------- // -----------------
void wxMenuItem::SetBitmap(const wxBitmap& bitmap)
{
m_bitmap = bitmap;
UpdateItemBitmap() ;
}
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() )
{
ControlButtonContentInfo info ;
wxMacCreateBitmapButton( &info , m_bitmap , kControlContentCIconHandle ) ;
if ( info.contentType != kControlNoContent )
{
if ( info.contentType == kControlContentCIconHandle )
SetMenuItemIconHandle( mhandle , index ,
kMenuColorIconType , (Handle) info.u.cIconHandle ) ;
}
}
}
void wxMenuItem::UpdateItemStatus()
{
if ( !m_parentMenu )
return ;
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 , m_text ) ;
wxAcceleratorEntry *entry = wxGetAccelFromString( m_text ) ;
UMASetMenuItemShortcut( mhandle , index , entry ) ;
delete entry ;
}
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 ;
UMASetMenuItemText( mhandle , index , m_text ) ;
wxAcceleratorEntry *entry = wxGetAccelFromString( m_text ) ;
UMASetMenuItemShortcut( mhandle , index , entry ) ;
delete entry ;
}
void wxMenuItem::Enable(bool bDoEnable) void wxMenuItem::Enable(bool bDoEnable)
{ {
if ( m_isEnabled != bDoEnable ) { if ( m_isEnabled != bDoEnable )
if ( m_subMenu == NULL ) {
{ wxMenuItemBase::Enable( bDoEnable ) ;
// normal menu item UpdateItemStatus() ;
if ( MAC_WXHMENU(m_parentMenu->GetHMenu()) ) }
{ }
int index = m_parentMenu->MacGetIndexFromItem( this ) ; void wxMenuItem::UncheckRadio()
if ( index >= 1 ) {
{ if ( m_isChecked )
if ( bDoEnable ) {
UMAEnableMenuItem( MAC_WXHMENU(m_parentMenu->GetHMenu()) , index ) ; wxMenuItemBase::Check( false ) ;
else UpdateItemStatus() ;
UMADisableMenuItem( MAC_WXHMENU(m_parentMenu->GetHMenu()) , index ) ; }
}
}
}
else
{
// submenu
if ( MAC_WXHMENU(m_parentMenu->GetHMenu()) )
{
int index = m_parentMenu->MacGetIndexFromItem( this ) ;
if ( index >= 1 )
{
if ( bDoEnable )
UMAEnableMenuItem( MAC_WXHMENU(m_parentMenu->GetHMenu()) , index ) ;
else
UMADisableMenuItem( MAC_WXHMENU(m_parentMenu->GetHMenu()) , index ) ;
}
}
}
m_isEnabled = bDoEnable;
}
} }
void wxMenuItem::Check(bool bDoCheck) void wxMenuItem::Check(bool bDoCheck)
{ {
wxCHECK_RET( IsCheckable(), "only checkable items may be checked" ); wxCHECK_RET( IsCheckable(), "only checkable items may be checked" );
if ( m_isChecked != bDoCheck ) if ( m_isChecked != bDoCheck )
{ {
m_isChecked = bDoCheck; if ( GetKind() == wxITEM_RADIO )
if ( MAC_WXHMENU(m_parentMenu->GetHMenu()) ) {
{ if ( bDoCheck )
int index = m_parentMenu->MacGetIndexFromItem( this ) ; {
if ( index >= 1 ) wxMenuItemBase::Check( bDoCheck ) ;
{ UpdateItemStatus() ;
if ( bDoCheck )
::SetItemMark( MAC_WXHMENU(m_parentMenu->GetHMenu()) , index , 0x12 ) ; // checkmark // get the index of this item in the menu
else const wxMenuItemList& items = m_parentMenu->GetMenuItems();
::SetItemMark( MAC_WXHMENU(m_parentMenu->GetHMenu()) , index , 0 ) ; // no mark int pos = items.IndexOf(this);
} wxCHECK_RET( pos != wxNOT_FOUND,
} _T("menuitem not found in the menu items list?") );
}
// get the radio group range
int start,
end;
if ( m_isRadioGroupStart )
{
// we already have all information we need
start = pos;
end = m_radioGroup.end;
}
else // next radio group item
{
// get the radio group end from the start item
start = m_radioGroup.start;
end = items.Item(start)->GetData()->m_radioGroup.end;
}
// also uncheck all the other items in this radio group
wxMenuItemList::Node *node = items.Item(start);
for ( int n = start; n <= end && node; n++ )
{
if ( n != pos )
{
((wxMenuItem*)node->GetData())->UncheckRadio();
}
node = node->GetNext();
}
}
}
else
{
wxMenuItemBase::Check( bDoCheck ) ;
UpdateItemStatus() ;
}
}
} }
void wxMenuItem::SetText(const wxString& text) void wxMenuItem::SetText(const wxString& text)
@@ -304,29 +213,32 @@ void wxMenuItem::SetText(const wxString& text)
return; return;
wxMenuItemBase::SetText(text); wxMenuItemBase::SetText(text);
// OWNER_DRAWN_ONLY( wxOwnerDrawn::SetName(text) );
UpdateItemText() ;
wxCHECK_RET( m_parentMenu && m_parentMenu->GetHMenu(), wxT("menuitem without menu") );
if ( MAC_WXHMENU(m_parentMenu->GetHMenu()) )
{
int index = m_parentMenu->MacGetIndexFromItem( this ) ;
if ( index >= 1 )
{
Str255 label;
MacBuildMenuString( label , NULL , NULL , text ,false);
::SetMenuItemText( MAC_WXHMENU(m_parentMenu->GetHMenu()) , index , label ) ; // checkmark
}
}
#if wxUSE_ACCEL
m_parentMenu->UpdateAccel(this);
#endif // wxUSE_ACCEL
} }
void wxMenuItem::SetCheckable(bool checkable)
// radio group stuff
// -----------------
void wxMenuItem::SetAsRadioGroupStart()
{ {
wxMenuItemBase::SetCheckable(checkable); m_isRadioGroupStart = TRUE;
// OWNER_DRAWN_ONLY( wxOwnerDrawn::SetCheckable(checkable) ); }
void wxMenuItem::SetRadioGroupStart(int start)
{
wxASSERT_MSG( !m_isRadioGroupStart,
_T("should only be called for the next radio items") );
m_radioGroup.start = start;
}
void wxMenuItem::SetRadioGroupEnd(int end)
{
wxASSERT_MSG( m_isRadioGroupStart,
_T("should only be called for the first radio item") );
m_radioGroup.end = end;
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@@ -180,67 +180,105 @@ bool UMAGetProcessModeDoesActivateOnFGSwitch()
// menu manager // menu manager
void UMASetMenuTitle( MenuRef menu , StringPtr title ) MenuRef UMANewMenu( SInt16 id , const wxString& title )
{ {
/* wxString str = wxStripMenuCodes( title ) ;
#if !TARGET_CARBON MenuRef menu ;
long size = GetHandleSize( (Handle) menu ) ; #if TARGET_CARBON
const long headersize = 14 ; CFStringRef cfs = wxMacCreateCFString( str ) ;
int oldlen = (**menu).menuData[0] + 1; CreateNewMenu( id , 0 , &menu ) ;
int newlen = title[0] + 1 ; SetMenuTitleWithCFString( menu , cfs ) ;
CFRelease( cfs ) ;
if ( oldlen < newlen )
{
// enlarge before adjusting
SetHandleSize( (Handle) menu , size + (newlen - oldlen ) );
}
if ( oldlen != newlen )
memmove( (char*) (**menu).menuData + newlen , (char*) (**menu).menuData + oldlen , size - headersize - oldlen ) ;
memcpy( (char*) (**menu).menuData , title , newlen ) ;
if ( oldlen > newlen )
{
// shrink after
SetHandleSize( (Handle) menu , size + (newlen - oldlen ) ) ;
}
#else #else
*/ Str255 ptitle ;
SetMenuTitle( menu , title ) ; wxMacStringToPascal( str , ptitle ) ;
//#endif menu = ::NewMenu( id , ptitle ) ;
#endif
return menu ;
} }
void UMASetMenuTitle( MenuRef menu , const wxString& title )
{
wxString str = wxStripMenuCodes( title ) ;
#if TARGET_CARBON
CFStringRef cfs = wxMacCreateCFString( str ) ;
SetMenuTitleWithCFString( menu , cfs ) ;
CFRelease( cfs ) ;
#else
Str255 ptitle ;
wxMacStringToPascal( str , ptitle ) ;
SetMenuTitle( menu , ptitle ) ;
#endif
}
void UMASetMenuItemText( MenuRef menu, MenuItemIndex item, const wxString& title )
{
wxString str = wxStripMenuCodes( title ) ;
#if TARGET_CARBON
CFStringRef cfs = wxMacCreateCFString( str ) ;
SetMenuItemTextWithCFString( menu , item , cfs ) ;
CFRelease( cfs ) ;
#else
Str255 ptitle ;
wxMacStringToPascal( str , ptitle ) ;
SetMenuItemText( menu , item , ptitle ) ;
#endif
}
UInt32 UMAMenuEvent( EventRecord *inEvent ) UInt32 UMAMenuEvent( EventRecord *inEvent )
{ {
return MenuEvent( inEvent ) ; return MenuEvent( inEvent ) ;
} }
void UMAEnableMenuItem( MenuRef inMenu , MenuItemIndex inItem ) void UMAEnableMenuItem( MenuRef inMenu , MenuItemIndex inItem , bool enable)
{ {
EnableMenuItem( inMenu , inItem ) ; if ( enable )
EnableMenuItem( inMenu , inItem ) ;
else
DisableMenuItem( inMenu , inItem ) ;
} }
void UMADisableMenuItem( MenuRef inMenu , MenuItemIndex inItem ) void UMAAppendSubMenuItem( MenuRef menu , const wxString& title , SInt16 id )
{ {
DisableMenuItem( inMenu , inItem ) ; MacAppendMenu(menu, "\pA");
} UMASetMenuItemText(menu, (SInt16) ::CountMenuItems(menu), title );
void UMAAppendSubMenuItem( MenuRef menu , StringPtr l , SInt16 id )
{
MacAppendMenu(menu, l);
SetMenuItemHierarchicalID( menu , CountMenuItems( menu ) , id ) ; SetMenuItemHierarchicalID( menu , CountMenuItems( menu ) , id ) ;
} }
void UMAInsertSubMenuItem( MenuRef menu , StringPtr l , MenuItemIndex item , SInt16 id ) void UMAInsertSubMenuItem( MenuRef menu , const wxString& title , MenuItemIndex item , SInt16 id )
{ {
MacInsertMenuItem(menu, l , item); MacInsertMenuItem(menu, "\pA" , item);
UMASetMenuItemText(menu, item , title );
SetMenuItemHierarchicalID( menu , item , id ) ; SetMenuItemHierarchicalID( menu , item , id ) ;
} }
void UMASetMenuItemShortcut( MenuRef menu , MenuItemIndex item , SInt16 key , UInt8 modifiers ) void UMASetMenuItemShortcut( MenuRef menu , MenuItemIndex item , wxAcceleratorEntry *entry )
{ {
if ( !entry )
return ;
UInt8 modifiers = 0 ;
SInt16 key = entry->GetKeyCode() ;
if ( key ) if ( key )
{ {
bool explicitCommandKey = false ;
if ( entry->GetFlags() & wxACCEL_CTRL )
{
explicitCommandKey = true ;
}
if (entry->GetFlags() & wxACCEL_ALT )
{
modifiers |= kMenuOptionModifier ;
}
if (entry->GetFlags() & wxACCEL_SHIFT)
{
modifiers |= kMenuShiftModifier ;
}
SInt16 glyph = 0 ; SInt16 glyph = 0 ;
SInt16 macKey = key ; SInt16 macKey = key ;
if ( key >= WXK_F1 && key <= WXK_F15 ) if ( key >= WXK_F1 && key <= WXK_F15 )
@@ -249,7 +287,10 @@ void UMASetMenuItemShortcut( MenuRef menu , MenuItemIndex item , SInt16 key , UI
glyph = kMenuF1Glyph + ( key - WXK_F1 ) ; glyph = kMenuF1Glyph + ( key - WXK_F1 ) ;
if ( key >= WXK_F13 ) if ( key >= WXK_F13 )
glyph += 13 ; glyph += 13 ;
switch( key ) if ( !explicitCommandKey )
modifiers |= kMenuNoCommandModifier ;
switch( key )
{ {
case WXK_F1 : case WXK_F1 :
macKey += ( 0x7a << 8 ) ; macKey += ( 0x7a << 8 ) ;
@@ -367,7 +408,7 @@ void UMASetMenuItemShortcut( MenuRef menu , MenuItemIndex item , SInt16 key , UI
break ; break ;
} }
} }
SetItemCmd( menu, item , macKey ); SetItemCmd( menu, item , macKey );
SetMenuItemModifiers(menu, item , modifiers ) ; SetMenuItemModifiers(menu, item , modifiers ) ;
@@ -376,18 +417,18 @@ void UMASetMenuItemShortcut( MenuRef menu , MenuItemIndex item , SInt16 key , UI
} }
} }
void UMAAppendMenuItem( MenuRef menu , StringPtr l , SInt16 key, UInt8 modifiers ) void UMAAppendMenuItem( MenuRef menu , const wxString& title , wxAcceleratorEntry *entry )
{ {
MacAppendMenu(menu, "\pA"); MacAppendMenu(menu, "\pA");
SetMenuItemText(menu, (SInt16) ::CountMenuItems(menu), l); UMASetMenuItemText(menu, (SInt16) ::CountMenuItems(menu), title );
UMASetMenuItemShortcut( menu , (SInt16) ::CountMenuItems(menu), key , modifiers ) ; UMASetMenuItemShortcut( menu , (SInt16) ::CountMenuItems(menu), entry ) ;
} }
void UMAInsertMenuItem( MenuRef menu , StringPtr l , MenuItemIndex item , SInt16 key, UInt8 modifiers ) void UMAInsertMenuItem( MenuRef menu , const wxString& title , MenuItemIndex item , wxAcceleratorEntry *entry )
{ {
MacInsertMenuItem( menu , "\p" , item) ; MacInsertMenuItem( menu , "\p" , item) ;
SetMenuItemText(menu, item , l); UMASetMenuItemText(menu, item , title );
UMASetMenuItemShortcut( menu , item , key , modifiers ) ; UMASetMenuItemShortcut( menu , item , entry ) ;
} }
// quickdraw // quickdraw