osxmenuitem.cpp
来自「这是VCF框架的代码」· C++ 代码 · 共 574 行
CPP
574 行
//OSXMenuItem.cpp/*Copyright 2000-2004 The VCF Project.Please see License.txt in the top level directorywhere you installed the VCF.*/#include "vcf/ApplicationKit/ApplicationKit.h"#include "vcf/ApplicationKit/ApplicationKitPrivate.h"#include "vcf/ApplicationKit/OSXMenuItem.h"using namespace VCF;uint32 OSXMenuItem::globalMenuItemID = 0;String OSXGenerateCaption( MenuItem* item, OSXMenuItem* peer, String caption ){ String acceleratorText; VCF::AcceleratorKey* accelerator = item->getAccelerator(); //generate accelerator text if we are not owner drawn if ( !item->canPaint() && (NULL != accelerator) ) { if ( accelerator->hasCtrlKey() ) { acceleratorText += "Ctrl"; } if ( accelerator->hasShiftKey() ) { if ( !acceleratorText.empty() ) { acceleratorText += "+"; } acceleratorText += "Shift"; } if ( accelerator->hasAltKey() ) { if ( !acceleratorText.empty() ) { acceleratorText += "+"; } acceleratorText += "Alt"; } if ( !acceleratorText.empty() ) { acceleratorText += "+"; } acceleratorText += StringUtils::translateVKCodeToString( (VirtualKeyCode)accelerator->getKeyCode() ); } if ( !acceleratorText.empty() ) { caption = caption + "\t" + acceleratorText; } UIPolicyManager* pm = UIToolkit::getUIPolicyManager(); caption = pm->transformMnemonicValues( caption ); return caption;}OSXMenuItem::OSXMenuItem( MenuItem* item ): itemID_(0), menuItem_(item), itemHandle_(NULL), itemAdded_(false){ init();}OSXMenuItem::OSXMenuItem(): itemID_(0), menuItem_(NULL), itemHandle_(NULL), itemAdded_(false){ init();}OSXMenuItem::~OSXMenuItem(){ if ( NULL != itemHandle_ ) { DisposeMenu( itemHandle_ ); } }void OSXMenuItem::init(){ OSXMenuItem::globalMenuItemID ++; itemID_ = OSXMenuItem::globalMenuItemID;}bool OSXMenuItem::isMenuItemRoot( MenuItem* item ){ bool result = false; if ( NULL != item ) { MenuItem* parent = item->getParent(); Menu* menuOwner = item->getMenuOwner(); if ( NULL == menuOwner ) { while ( parent != NULL ) { menuOwner = parent->getMenuOwner(); if ( NULL != menuOwner ) { break; } parent = parent->getParent(); } parent = item->getParent(); } if ( NULL != menuOwner ) { result = (menuOwner->getRootMenuItem() == item); } else if ( NULL == parent ) { result = true; } } return result;} bool OSXMenuItem::isParentMenuItemRoot( MenuItem* item ){ bool result = false; if ( NULL != item ) { MenuItem* parent = item->getParent(); Menu* menuOwner = item->getMenuOwner(); if ( NULL == menuOwner ) { while ( parent != NULL ) { menuOwner = parent->getMenuOwner(); if ( NULL != menuOwner ) { break; } parent = parent->getParent(); } parent = item->getParent(); } if ( NULL != menuOwner ) { result = (menuOwner->getRootMenuItem() == parent); } else if ( NULL != parent ) { if ( NULL == parent->getParent() ) { result = true; } } } return result;}bool OSXMenuItem::isMenuItemRoot(){ return OSXMenuItem::isMenuItemRoot( menuItem_ );}bool OSXMenuItem::isParentMenuItemRoot(){ return OSXMenuItem::isParentMenuItemRoot( menuItem_ );}void OSXMenuItem::addChild( MenuItem* child ){ unsigned long index = child->getIndex();// maxVal<unsigned long>( menuItem_->getChildCount()-1, 0 ); insertChild( index, child );}void OSXMenuItem::fixChildren( MenuItem* child ){ if ( child->hasChildren() ) { Enumerator<MenuItem*>* children = child->getChildren(); while ( children->hasMoreElements() ) { MenuItem* item = children->nextElement(); OSXMenuItem* itemPeer = (OSXMenuItem*) item->getPeer(); if ( false == itemPeer->itemAdded_ ) { item->setMenuOwner( child->getMenuOwner() ); OSXMenuItem* peer = (OSXMenuItem*) child->getPeer(); peer->addChild( item ); } } }}void OSXMenuItem::insertChild( const unsigned long& index, MenuItem* child ){ child->setIndex( index ); CFTextString tmp( OSXGenerateCaption( child, (OSXMenuItem*)child->getPeer(), child->getCaption() ) ); //is this child a top level menu item? if ( OSXMenuItem::isParentMenuItemRoot( child ) ) { OSXMenuItem* peer = (OSXMenuItem*)child->getPeer(); MenuRef handle = (MenuRef) peer->getMenuID(); if ( NULL != handle ) { InsertMenu( handle, peer->itemID_ ); SetMenuTitleWithCFString( handle, tmp ); itemAdded_ = true; } else { //we should get picked up later return; } } else { OSXMenuItem* peer = (OSXMenuItem*)child->getPeer(); MenuRef handle = 0; if ( menuItem_->hasChildren() && (!isParentMenuItemRoot()) ) { OSXMenuItem* parentPeer = (OSXMenuItem*)menuItem_->getParent()->getPeer(); MenuRef parentRef = (MenuRef) parentPeer->getMenuID(); int index = menuItem_->getIndex(); GetMenuItemHierarchicalMenu( parentRef, index, &handle ); if ( NULL == handle ) { handle = (MenuRef) getMenuID(); //apparently the menu index is 1 based! Go figure! OSStatus err = SetMenuItemHierarchicalMenu( parentRef, index+1, handle ); if ( err != noErr ) { printf( "Error with SetMenuItemHierarchicalMenu(): %d\n", err ); } } } else { handle = (MenuRef) getMenuID(); } MenuItemIndex childIndex = index; InsertMenuItemTextWithCFString( handle, tmp, childIndex, 0, peer->itemID_ ); itemAdded_ = true; SetMenuCommandProperty( handle, peer->itemID_, VCF_PROPERTY_CREATOR, OSXMenuItem::propertyTag, sizeof(child), &child ); } /** check to see if we have children that have not yet been added */ fixChildren( child );}void OSXMenuItem::deleteChild( MenuItem* child ){ int index = child->getIndex(); OSXMenuItem* peer = (OSXMenuItem*)child->getPeer(); MenuRef handle = (MenuRef) getMenuID(); if ( child->hasChildren() ) { DeleteMenu( peer->itemID_ ); } DeleteMenuItem( handle, index + 1 );}void OSXMenuItem::deleteChild( const unsigned long& index ){ MenuItem* child = menuItem_->getChildAt(index); deleteChild( child );}void OSXMenuItem::clearChildren(){ MenuRef handle = (MenuRef) getMenuID(); int start = 1; DeleteMenuItems( handle, 1, menuItem_->getChildCount() );}bool OSXMenuItem::isChecked(){ bool result = false; MenuItem* parent = menuItem_->getParent(); OSXMenuItem* parentPeer = (OSXMenuItem*)parent->getPeer(); MenuRef parentHandle = (MenuRef)parentPeer->getMenuID(); int index = menuItem_->getIndex()+1; CharParameter markChar = 0; GetItemMark( parentHandle, index, &markChar ); if ( checkMark == markChar ) { result = true; } return result;}void OSXMenuItem::setChecked( const bool& checked ){ if ( menuItem_->hasChildren() ) { return; } MenuItem* parent = menuItem_->getParent(); OSXMenuItem* parentPeer = (OSXMenuItem*)parent->getPeer(); MenuRef parentHandle = (MenuRef)parentPeer->getMenuID(); int index = menuItem_->getIndex()+1; CharParameter markChar = checked ? checkMark : 0; SetItemMark( parentHandle, index, markChar );}bool OSXMenuItem::hasParent(){ return false;}MenuItem* OSXMenuItem::getParent(){ return menuItem_->getParent();}MenuItem* OSXMenuItem::getChildAt( const unsigned long& index ){ return NULL;}bool OSXMenuItem::isEnabled(){ MenuItem* parent = menuItem_->getParent(); OSXMenuItem* parentPeer = (OSXMenuItem*)parent->getPeer(); MenuRef parentHandle = (MenuRef)parentPeer->getMenuID(); int index = menuItem_->getIndex()+1; return IsMenuItemEnabled( parentHandle, index ) ? true : false;}void OSXMenuItem::setEnabled( const bool& enabled ){ if ( true == menuItem_->isSeparator() ){ return; } MenuItem* parent = menuItem_->getParent(); OSXMenuItem* parentPeer = (OSXMenuItem*)parent->getPeer(); MenuRef parentHandle = (MenuRef)parentPeer->getMenuID(); int index = menuItem_->getIndex()+1; if ( enabled ) { EnableMenuItem( parentHandle, index ); } else { DisableMenuItem( parentHandle, index ); } }bool OSXMenuItem::isVisible(){ return true;}void OSXMenuItem::setVisible( const bool& visible ){ int index = menuItem_->getIndex(); if ( visible ){ } else { //RemoveMenu( itemHandle_, index, MF_BYPOSITION ); }}bool OSXMenuItem::getRadioItem(){ bool result = false; MenuItem* parent = menuItem_->getParent(); OSXMenuItem* parentPeer = (OSXMenuItem*)parent->getPeer(); MenuRef parentHandle = (MenuRef)parentPeer->getMenuID(); int index = menuItem_->getIndex()+1; CharParameter markChar = 0; GetItemMark( parentHandle, index, &markChar ); if ( diamondMark == markChar ) { result = true; } return result;}void OSXMenuItem::setRadioItem( const bool& value ){ if ( menuItem_->hasChildren() || menuItem_->isSeparator() ) { return; } MenuItem* parent = menuItem_->getParent(); OSXMenuItem* parentPeer = (OSXMenuItem*)parent->getPeer(); MenuRef parentHandle = (MenuRef)parentPeer->getMenuID(); int index = menuItem_->getIndex()+1; CharParameter markChar = value ? diamondMark : 0; SetItemMark( parentHandle, index, markChar );}void OSXMenuItem::setMenuItem( MenuItem* item ){ menuItem_ = item;}void OSXMenuItem::setCaption( const String& caption ){ if ( true == menuItem_->isSeparator() ){ return; } int index = menuItem_->getIndex(); MenuItem* parent = menuItem_->getParent(); if ( NULL != parent ) { CFTextString tmp( OSXGenerateCaption( menuItem_, this, caption ) ); if ( isParentMenuItemRoot() ) { MenuRef handle = (MenuRef) getMenuID(); if ( NULL != handle ) { SetMenuTitleWithCFString( handle, tmp ); } } else { OSXMenuItem* peer = (OSXMenuItem*)parent->getPeer(); MenuRef ref = (MenuRef) peer->getMenuID(); SetMenuItemTextWithCFString( ref, index + 1, tmp ); } }}/**This returns an "id" (handle would be a better name) to the menu item.Not all menu items will have a handle.If the menuItem_ is the "root" menu item then this is a no-op*/OSHandleID OSXMenuItem::getMenuID(){ if ( isMenuItemRoot() ) { printf( "the menu item is the root item!\n" ); return 0; } if ( NULL != menuItem_ ){ Menu* menuOwner = menuItem_->getMenuOwner(); //find our owner if ( NULL == menuOwner ){ MenuItem* parent = menuItem_->getParent(); while ( parent != NULL ) { menuOwner = parent->getMenuOwner(); if ( NULL != menuOwner ) { break; } parent = parent->getParent(); } } if ( (NULL == itemHandle_) && (NULL != menuOwner) ){ PopupMenu* popupOwner = dynamic_cast<PopupMenu*>( menuOwner ); if ( NULL != popupOwner ){ //itemHandle_ = ::CreatePopupMenu(); //We need to create a popup menu - i.e. a context menu! } else { MenuBar* menuBarOwner = dynamic_cast<MenuBar*>( menuOwner ); /** At this point we either have a menu bar, because we are top level items, or.. We don't, which means we are nested hierarchical menu items */ if ( NULL != menuBarOwner ){ if ( isParentMenuItemRoot() ) { CreateNewMenu( itemID_,0,&itemHandle_); CFTextString tmp( menuItem_->getCaption() ); SetMenuTitleWithCFString( itemHandle_, tmp ); } else { OSStatus err = CreateNewMenu( itemID_,0,&itemHandle_); if ( noErr != err ) { printf( "CreateNewMenu failed. err: %d\n", err ); } CFTextString tmp( menuItem_->getCaption() ); SetMenuTitleWithCFString( itemHandle_, tmp ); } SetMenuCommandProperty( itemHandle_, 0, VCF_PROPERTY_CREATOR, OSXMenuItem::propertyTag, sizeof(menuItem_), &menuItem_ ); } else { throw RuntimeException(MAKE_ERROR_MSG("Unknown or Invalid Menu Item owner"), __LINE__); } } if ( menuItem_->hasChildren() && NULL == itemHandle_ ){ throw RuntimeException(MAKE_ERROR_MSG("Error allocation Resources for Menu Item Peer. CreateNewMenu failed."), __LINE__); } } } return (OSHandleID)itemHandle_;}void OSXMenuItem::setAsSeparator( const bool& isSeperator ){ MenuItem* parent = menuItem_->getParent(); OSXMenuItem* parentPeer = (OSXMenuItem*)parent->getPeer(); MenuRef parentHandle = (MenuRef)parentPeer->getMenuID(); int index = menuItem_->getIndex()+1; if ( isSeperator ) { ChangeMenuItemAttributes( parentHandle, index, kMenuItemAttrSeparator, 0 ); } else{ ChangeMenuItemAttributes( parentHandle, index, 0, kMenuItemAttrSeparator ); }}void OSXMenuItem::setAcceleratorKey( AcceleratorKey* accelerator ){ setCaption( menuItem_->getCaption() );}/***CVS Log info*$Log$*Revision 1.5 2006/04/07 02:35:24 ddiego*initial checkin of merge from 0.6.9 dev branch.**Revision 1.4.2.1 2005/11/27 23:55:44 ddiego*more osx updates.**Revision 1.4 2005/07/09 23:14:54 ddiego*merging in changes from devmain-0-6-7 branch.**Revision 1.3 2005/01/08 20:52:46 ddiego*fixed some glitches in osx impl.*Revision 1.2.2.1 2005/05/08 19:55:31 ddiego*osx updates, not yet functional.**Revision 1.2 2004/12/01 04:31:37 ddiego*merged over devmain-0-6-6 code. Marcello did a kick ass job*of fixing a nasty bug (1074768VCF application slows down modal dialogs.)*that he found. Many, many thanks for this Marcello.**Revision 1.1.2.2 2004/11/15 05:41:28 ddiego*finished almost all the osx menu code except for custom drawing. This completes this releases osx effort.**Revision 1.1.2.1 2004/11/10 06:16:40 ddiego*started adding osx menu code***/
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?