add CCMenu::init() and CCMenu::menu() to create empty menus

This commit is contained in:
Leon 2011-07-28 10:45:32 +08:00
parent c5f7036f7b
commit 4510101e96
2 changed files with 436 additions and 412 deletions

View File

@ -55,8 +55,12 @@ namespace cocos2d{
, m_pSelectedItem(NULL)
{}
virtual ~CCMenu(){}
/** creates a CCMenu with it's items */
static CCMenu* menuWithItems(CCMenuItem* item, ...);
/** creates an empty CCMenu */
static CCMenu* menu();
/** creates a CCMenu with it's items */
static CCMenu* menuWithItems(CCMenuItem* item, ...);
/** creates a CCMenu with it's item, then use addChild() to add
* other items. It is used for script, it can't init with undetermined
@ -64,6 +68,8 @@ namespace cocos2d{
*/
static CCMenu*menuWithItem(CCMenuItem* item);
/** initializes an empty CCMenu */
bool init();
/** initializes a CCMenu with it's items */
bool initWithItems(CCMenuItem* item, va_list args);
@ -129,4 +135,4 @@ namespace cocos2d{
};
}
#endif//__CCMENU_H_
#endif//__CCMENU_H_

View File

@ -35,104 +35,122 @@ THE SOFTWARE.
using namespace std;
namespace cocos2d{
enum
{
kDefaultPadding = 5,
};
//
//CCMenu
//
CCMenu * CCMenu::menuWithItems(CCMenuItem* item, ...)
{
va_list args;
va_start(args,item);
CCMenu *pRet = new CCMenu();
if (pRet && pRet->initWithItems(item, args))
{
pRet->autorelease();
va_end(args);
return pRet;
}
va_end(args);
CC_SAFE_DELETE(pRet)
return NULL;
}
enum
{
kDefaultPadding = 5,
};
//
//CCMenu
//
CCMenu* CCMenu::menu()
{
CCMenu *menu = new CCMenu();
if (menu && menu->init()) {
menu->autorelease();
return menu;
}
CC_SAFE_DELETE(menu)
return 0;
}
CCMenu * CCMenu::menuWithItems(CCMenuItem* item, ...)
{
va_list args;
va_start(args,item);
CCMenu *pRet = new CCMenu();
if (pRet && pRet->initWithItems(item, args))
{
pRet->autorelease();
va_end(args);
return pRet;
}
va_end(args);
CC_SAFE_DELETE(pRet)
return NULL;
}
CCMenu* CCMenu::menuWithItem(CCMenuItem* item)
{
return menuWithItems(item, NULL);
}
bool CCMenu::initWithItems(CCMenuItem* item, va_list args)
{
bool CCMenu::init()
{
va_list args;
return initWithItems(0, args);
}
bool CCMenu::initWithItems(CCMenuItem* item, va_list args)
{
if (CCLayer::init())
{
this->m_bIsTouchEnabled = true;
// menu in the center of the screen
CCSize s = CCDirector::sharedDirector()->getWinSize();
this->m_bIsRelativeAnchorPoint = false;
m_tAnchorPoint = ccp(0.5f, 0.5f);
this->setContentSize(s);
// XXX: in v0.7, winSize should return the visible size
// XXX: so the bar calculation should be done there
CCRect r;
CCApplication::sharedApplication().statusBarFrame(&r);
ccDeviceOrientation orientation = CCDirector::sharedDirector()->getDeviceOrientation();
if (orientation == CCDeviceOrientationLandscapeLeft || orientation == CCDeviceOrientationLandscapeRight)
{
s.height -= r.size.width;
}
else
{
s.height -= r.size.height;
}
setPosition(ccp(s.width/2, s.height/2));
int z=0;
if (item)
{
this->addChild(item, z);
CCMenuItem *i = va_arg(args, CCMenuItem*);
while (i)
{
z++;
this->addChild(i, z);
i = va_arg(args, CCMenuItem*);
}
}
// [self alignItemsVertically];
m_pSelectedItem = NULL;
m_eState = kCCMenuStateWaiting;
return true;
}
return false;
}
/*
* override add:
*/
void CCMenu::addChild(CCNode * child, int zOrder)
{
CCLayer::addChild(child, zOrder);
}
void CCMenu::addChild(CCNode * child, int zOrder, int tag)
{
// we can not use RTTI, so we do not known the type of object
/*CCAssert( dynamic_cast<CCMenuItem*>(child) != NULL, L"Menu only supports MenuItem objects as children");*/
CCLayer::addChild(child, zOrder, tag);
}
void CCMenu::onExit()
{
// menu in the center of the screen
CCSize s = CCDirector::sharedDirector()->getWinSize();
this->m_bIsRelativeAnchorPoint = false;
m_tAnchorPoint = ccp(0.5f, 0.5f);
this->setContentSize(s);
// XXX: in v0.7, winSize should return the visible size
// XXX: so the bar calculation should be done there
CCRect r;
CCApplication::sharedApplication().statusBarFrame(&r);
ccDeviceOrientation orientation = CCDirector::sharedDirector()->getDeviceOrientation();
if (orientation == CCDeviceOrientationLandscapeLeft || orientation == CCDeviceOrientationLandscapeRight)
{
s.height -= r.size.width;
}
else
{
s.height -= r.size.height;
}
setPosition(ccp(s.width/2, s.height/2));
int z=0;
if (item)
{
this->addChild(item, z);
CCMenuItem *i = va_arg(args, CCMenuItem*);
while (i)
{
z++;
this->addChild(i, z);
i = va_arg(args, CCMenuItem*);
}
}
// [self alignItemsVertically];
m_pSelectedItem = NULL;
m_eState = kCCMenuStateWaiting;
return true;
}
return false;
}
/*
* override add:
*/
void CCMenu::addChild(CCNode * child, int zOrder)
{
CCLayer::addChild(child, zOrder);
}
void CCMenu::addChild(CCNode * child, int zOrder, int tag)
{
// we can not use RTTI, so we do not known the type of object
/*CCAssert( dynamic_cast<CCMenuItem*>(child) != NULL, L"Menu only supports MenuItem objects as children");*/
CCLayer::addChild(child, zOrder, tag);
}
void CCMenu::onExit()
{
if (m_eState == kCCMenuStateTrackingTouch)
{
m_pSelectedItem->unselected();
@ -141,194 +159,194 @@ namespace cocos2d{
}
CCLayer::onExit();
}
//Menu - Events
void CCMenu::registerWithTouchDispatcher()
{
CCTouchDispatcher::sharedDispatcher()->addTargetedDelegate(this, kCCMenuTouchPriority, true);
}
bool CCMenu::ccTouchBegan(CCTouch* touch, CCEvent* event)
{
CC_UNUSED_PARAM(event);
if (m_eState != kCCMenuStateWaiting || ! m_bIsVisible)
{
return false;
}
m_pSelectedItem = this->itemForTouch(touch);
if (m_pSelectedItem)
{
m_eState = kCCMenuStateTrackingTouch;
m_pSelectedItem->selected();
return true;
}
return false;
}
void CCMenu::ccTouchEnded(CCTouch *touch, CCEvent* event)
{
CC_UNUSED_PARAM(touch);
CC_UNUSED_PARAM(event);
CCAssert(m_eState == kCCMenuStateTrackingTouch, "[Menu ccTouchEnded] -- invalid state");
}
//Menu - Events
void CCMenu::registerWithTouchDispatcher()
{
CCTouchDispatcher::sharedDispatcher()->addTargetedDelegate(this, kCCMenuTouchPriority, true);
}
bool CCMenu::ccTouchBegan(CCTouch* touch, CCEvent* event)
{
CC_UNUSED_PARAM(event);
if (m_eState != kCCMenuStateWaiting || ! m_bIsVisible)
{
return false;
}
m_pSelectedItem = this->itemForTouch(touch);
if (m_pSelectedItem)
{
m_pSelectedItem->unselected();
m_pSelectedItem->activate();
m_eState = kCCMenuStateTrackingTouch;
m_pSelectedItem->selected();
return true;
}
m_eState = kCCMenuStateWaiting;
}
void CCMenu::ccTouchCancelled(CCTouch *touch, CCEvent* event)
{
CC_UNUSED_PARAM(touch);
CC_UNUSED_PARAM(event);
CCAssert(m_eState == kCCMenuStateTrackingTouch, "[Menu ccTouchCancelled] -- invalid state");
return false;
}
void CCMenu::ccTouchEnded(CCTouch *touch, CCEvent* event)
{
CC_UNUSED_PARAM(touch);
CC_UNUSED_PARAM(event);
CCAssert(m_eState == kCCMenuStateTrackingTouch, "[Menu ccTouchEnded] -- invalid state");
if (m_pSelectedItem)
{
m_pSelectedItem->unselected();
m_pSelectedItem->unselected();
m_pSelectedItem->activate();
}
m_eState = kCCMenuStateWaiting;
}
void CCMenu::ccTouchMoved(CCTouch* touch, CCEvent* event)
{
CC_UNUSED_PARAM(event);
CCAssert(m_eState == kCCMenuStateTrackingTouch, "[Menu ccTouchMoved] -- invalid state");
CCMenuItem *currentItem = this->itemForTouch(touch);
if (currentItem != m_pSelectedItem)
{
m_eState = kCCMenuStateWaiting;
}
void CCMenu::ccTouchCancelled(CCTouch *touch, CCEvent* event)
{
CC_UNUSED_PARAM(touch);
CC_UNUSED_PARAM(event);
CCAssert(m_eState == kCCMenuStateTrackingTouch, "[Menu ccTouchCancelled] -- invalid state");
if (m_pSelectedItem)
{
m_pSelectedItem->unselected();
}
m_eState = kCCMenuStateWaiting;
}
void CCMenu::ccTouchMoved(CCTouch* touch, CCEvent* event)
{
CC_UNUSED_PARAM(event);
CCAssert(m_eState == kCCMenuStateTrackingTouch, "[Menu ccTouchMoved] -- invalid state");
CCMenuItem *currentItem = this->itemForTouch(touch);
if (currentItem != m_pSelectedItem)
{
if (m_pSelectedItem)
{
m_pSelectedItem->unselected();
m_pSelectedItem->unselected();
}
m_pSelectedItem = currentItem;
m_pSelectedItem = currentItem;
if (m_pSelectedItem)
{
m_pSelectedItem->selected();
m_pSelectedItem->selected();
}
}
}
void CCMenu::destroy(void)
{
release();
}
void CCMenu::keep(void)
{
retain();
}
//Menu - Alignment
void CCMenu::alignItemsVertically()
{
this->alignItemsVerticallyWithPadding(kDefaultPadding);
}
void CCMenu::alignItemsVerticallyWithPadding(float padding)
{
float height = -padding;
if (m_pChildren && m_pChildren->count() > 0)
{
CCObject* pObject = NULL;
CCARRAY_FOREACH(m_pChildren, pObject)
{
CCNode* pChild = (CCNode*) pObject;
}
}
void CCMenu::destroy(void)
{
release();
}
void CCMenu::keep(void)
{
retain();
}
//Menu - Alignment
void CCMenu::alignItemsVertically()
{
this->alignItemsVerticallyWithPadding(kDefaultPadding);
}
void CCMenu::alignItemsVerticallyWithPadding(float padding)
{
float height = -padding;
if (m_pChildren && m_pChildren->count() > 0)
{
CCObject* pObject = NULL;
CCARRAY_FOREACH(m_pChildren, pObject)
{
CCNode* pChild = (CCNode*) pObject;
if (pChild)
{
height += pChild->getContentSize().height * pChild->getScaleY() + padding;
}
}
}
float y = height / 2.0f;
if (m_pChildren && m_pChildren->count() > 0)
{
CCObject* pObject = NULL;
CCARRAY_FOREACH(m_pChildren, pObject)
{
CCNode* pChild = (CCNode*) pObject;
}
float y = height / 2.0f;
if (m_pChildren && m_pChildren->count() > 0)
{
CCObject* pObject = NULL;
CCARRAY_FOREACH(m_pChildren, pObject)
{
CCNode* pChild = (CCNode*) pObject;
if (pChild)
{
pChild->setPosition(ccp(0, y - pChild->getContentSize().height * pChild->getScaleY() / 2.0f));
y -= pChild->getContentSize().height * pChild->getScaleY() + padding;
}
}
}
}
void CCMenu::alignItemsHorizontally(void)
{
this->alignItemsHorizontallyWithPadding(kDefaultPadding);
}
void CCMenu::alignItemsHorizontallyWithPadding(float padding)
{
float width = -padding;
if (m_pChildren && m_pChildren->count() > 0)
{
CCObject* pObject = NULL;
CCARRAY_FOREACH(m_pChildren, pObject)
{
CCNode* pChild = (CCNode*) pObject;
{
pChild->setPosition(ccp(0, y - pChild->getContentSize().height * pChild->getScaleY() / 2.0f));
y -= pChild->getContentSize().height * pChild->getScaleY() + padding;
}
}
}
}
void CCMenu::alignItemsHorizontally(void)
{
this->alignItemsHorizontallyWithPadding(kDefaultPadding);
}
void CCMenu::alignItemsHorizontallyWithPadding(float padding)
{
float width = -padding;
if (m_pChildren && m_pChildren->count() > 0)
{
CCObject* pObject = NULL;
CCARRAY_FOREACH(m_pChildren, pObject)
{
CCNode* pChild = (CCNode*) pObject;
if (pChild)
{
width += pChild->getContentSize().width * pChild->getScaleX() + padding;
}
}
}
float x = -width / 2.0f;
if (m_pChildren && m_pChildren->count() > 0)
{
CCObject* pObject = NULL;
CCARRAY_FOREACH(m_pChildren, pObject)
{
CCNode* pChild = (CCNode*) pObject;
{
width += pChild->getContentSize().width * pChild->getScaleX() + padding;
}
}
}
float x = -width / 2.0f;
if (m_pChildren && m_pChildren->count() > 0)
{
CCObject* pObject = NULL;
CCARRAY_FOREACH(m_pChildren, pObject)
{
CCNode* pChild = (CCNode*) pObject;
if (pChild)
{
{
pChild->setPosition(ccp(x + pChild->getContentSize().width * pChild->getScaleX() / 2.0f, 0));
x += pChild->getContentSize().width * pChild->getScaleX() + padding;
}
}
}
}
void CCMenu::alignItemsInColumns(unsigned int columns, ...)
{
va_list args;
va_start(args, columns);
this->alignItemsInColumns(columns, args);
va_end(args);
}
void CCMenu::alignItemsInColumns(unsigned int columns, va_list args)
{
vector<unsigned int> rows;
while (columns)
{
rows.push_back(columns);
columns = va_arg(args, unsigned int);
}
int height = -5;
unsigned int row = 0;
unsigned int rowHeight = 0;
unsigned int columnsOccupied = 0;
unsigned int rowColumns;
if (m_pChildren && m_pChildren->count() > 0)
{
CCObject* pObject = NULL;
CCARRAY_FOREACH(m_pChildren, pObject)
{
CCNode* pChild = (CCNode*) pObject;
x += pChild->getContentSize().width * pChild->getScaleX() + padding;
}
}
}
}
void CCMenu::alignItemsInColumns(unsigned int columns, ...)
{
va_list args;
va_start(args, columns);
this->alignItemsInColumns(columns, args);
va_end(args);
}
void CCMenu::alignItemsInColumns(unsigned int columns, va_list args)
{
vector<unsigned int> rows;
while (columns)
{
rows.push_back(columns);
columns = va_arg(args, unsigned int);
}
int height = -5;
unsigned int row = 0;
unsigned int rowHeight = 0;
unsigned int columnsOccupied = 0;
unsigned int rowColumns;
if (m_pChildren && m_pChildren->count() > 0)
{
CCObject* pObject = NULL;
CCARRAY_FOREACH(m_pChildren, pObject)
{
CCNode* pChild = (CCNode*) pObject;
if (pChild)
{
{
assert(row < rows.size());
rowColumns = rows[row];
@ -346,31 +364,31 @@ namespace cocos2d{
columnsOccupied = 0;
rowHeight = 0;
++row;
}
}
}
}
}
}
// check if too many rows/columns for available menu items
assert(! columnsOccupied);
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
row = 0;
rowHeight = 0;
rowColumns = 0;
float w = 0.0;
float x = 0.0;
float y = (float)(height / 2);
if (m_pChildren && m_pChildren->count() > 0)
{
CCObject* pObject = NULL;
CCARRAY_FOREACH(m_pChildren, pObject)
{
CCNode* pChild = (CCNode*) pObject;
}
// check if too many rows/columns for available menu items
assert(! columnsOccupied);
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
row = 0;
rowHeight = 0;
rowColumns = 0;
float w = 0.0;
float x = 0.0;
float y = (float)(height / 2);
if (m_pChildren && m_pChildren->count() > 0)
{
CCObject* pObject = NULL;
CCARRAY_FOREACH(m_pChildren, pObject)
{
CCNode* pChild = (CCNode*) pObject;
if (pChild)
{
{
if (rowColumns == 0)
{
rowColumns = rows[row];
@ -395,49 +413,49 @@ namespace cocos2d{
rowColumns = 0;
rowHeight = 0;
++row;
}
}
}
}
}
}
}
void CCMenu::alignItemsInRows(unsigned int rows, ...)
{
va_list args;
va_start(args, rows);
this->alignItemsInColumns(rows, args);
va_end(args);
}
void CCMenu::alignItemsInRows(unsigned int rows, va_list args)
{
vector<unsigned int> columns;
while (rows)
{
columns.push_back(rows);
rows = va_arg(args, unsigned int);
}
vector<unsigned int> columnWidths;
vector<unsigned int> columnHeights;
int width = -10;
int columnHeight = -5;
unsigned int column = 0;
unsigned int columnWidth = 0;
unsigned int rowsOccupied = 0;
unsigned int columnRows;
if (m_pChildren && m_pChildren->count() > 0)
{
CCObject* pObject = NULL;
CCARRAY_FOREACH(m_pChildren, pObject)
{
CCNode* pChild = (CCNode*) pObject;
}
}
void CCMenu::alignItemsInRows(unsigned int rows, ...)
{
va_list args;
va_start(args, rows);
this->alignItemsInColumns(rows, args);
va_end(args);
}
void CCMenu::alignItemsInRows(unsigned int rows, va_list args)
{
vector<unsigned int> columns;
while (rows)
{
columns.push_back(rows);
rows = va_arg(args, unsigned int);
}
vector<unsigned int> columnWidths;
vector<unsigned int> columnHeights;
int width = -10;
int columnHeight = -5;
unsigned int column = 0;
unsigned int columnWidth = 0;
unsigned int rowsOccupied = 0;
unsigned int columnRows;
if (m_pChildren && m_pChildren->count() > 0)
{
CCObject* pObject = NULL;
CCARRAY_FOREACH(m_pChildren, pObject)
{
CCNode* pChild = (CCNode*) pObject;
if (pChild)
{
{
// check if too many menu items for the amount of rows/columns
assert(column < columns.size());
@ -462,30 +480,30 @@ namespace cocos2d{
columnWidth = 0;
columnHeight = -5;
++column;
}
}
}
}
}
}
// check if too many rows/columns for available menu items.
assert(! rowsOccupied);
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
column = 0;
columnWidth = 0;
columnRows = 0;
float x = (float)(-width / 2);
float y = 0.0;
if (m_pChildren && m_pChildren->count() > 0)
{
CCObject* pObject = NULL;
CCARRAY_FOREACH(m_pChildren, pObject)
{
CCNode* pChild = (CCNode*) pObject;
}
// check if too many rows/columns for available menu items.
assert(! rowsOccupied);
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
column = 0;
columnWidth = 0;
columnRows = 0;
float x = (float)(-width / 2);
float y = 0.0;
if (m_pChildren && m_pChildren->count() > 0)
{
CCObject* pObject = NULL;
CCARRAY_FOREACH(m_pChildren, pObject)
{
CCNode* pChild = (CCNode*) pObject;
if (pChild)
{
{
if (columnRows == 0)
{
columnRows = columns[column];
@ -509,82 +527,82 @@ namespace cocos2d{
columnRows = 0;
columnWidth = 0;
++column;
}
}
}
}
}
}
}
// Opacity Protocol
/** Override synthesized setOpacity to recurse items */
void CCMenu::setOpacity(GLubyte var)
{
m_cOpacity = var;
if (m_pChildren && m_pChildren->count() > 0)
{
CCObject* pObject = NULL;
CCARRAY_FOREACH(m_pChildren, pObject)
{
CCNode* pChild = (CCNode*) pObject;
}
}
// Opacity Protocol
/** Override synthesized setOpacity to recurse items */
void CCMenu::setOpacity(GLubyte var)
{
m_cOpacity = var;
if (m_pChildren && m_pChildren->count() > 0)
{
CCObject* pObject = NULL;
CCARRAY_FOREACH(m_pChildren, pObject)
{
CCNode* pChild = (CCNode*) pObject;
if (pChild)
{
{
CCRGBAProtocol *pRGBAProtocol = pChild->convertToRGBAProtocol();
if (pRGBAProtocol)
{
pRGBAProtocol->setOpacity(m_cOpacity);
}
}
}
}
}
}
}
GLubyte CCMenu::getOpacity(void)
{
return m_cOpacity;
}
void CCMenu::setColor(cocos2d::ccColor3B var)
{
m_tColor = var;
if (m_pChildren && m_pChildren->count() > 0)
{
CCObject* pObject = NULL;
CCARRAY_FOREACH(m_pChildren, pObject)
{
CCNode* pChild = (CCNode*) pObject;
}
}
GLubyte CCMenu::getOpacity(void)
{
return m_cOpacity;
}
void CCMenu::setColor(cocos2d::ccColor3B var)
{
m_tColor = var;
if (m_pChildren && m_pChildren->count() > 0)
{
CCObject* pObject = NULL;
CCARRAY_FOREACH(m_pChildren, pObject)
{
CCNode* pChild = (CCNode*) pObject;
if (pChild)
{
{
CCRGBAProtocol *pRGBAProtocol = pChild->convertToRGBAProtocol();
if (pRGBAProtocol)
{
pRGBAProtocol->setColor(m_tColor);
}
}
}
}
}
}
}
ccColor3B CCMenu::getColor(void)
{
return m_tColor;
}
CCMenuItem* CCMenu::itemForTouch(cocos2d::CCTouch *touch)
{
CCPoint touchLocation = touch->locationInView(touch->view());
touchLocation = CCDirector::sharedDirector()->convertToGL(touchLocation);
if (m_pChildren && m_pChildren->count() > 0)
{
CCObject* pObject = NULL;
CCARRAY_FOREACH(m_pChildren, pObject)
{
CCNode* pChild = (CCNode*) pObject;
}
}
ccColor3B CCMenu::getColor(void)
{
return m_tColor;
}
CCMenuItem* CCMenu::itemForTouch(cocos2d::CCTouch *touch)
{
CCPoint touchLocation = touch->locationInView(touch->view());
touchLocation = CCDirector::sharedDirector()->convertToGL(touchLocation);
if (m_pChildren && m_pChildren->count() > 0)
{
CCObject* pObject = NULL;
CCARRAY_FOREACH(m_pChildren, pObject)
{
CCNode* pChild = (CCNode*) pObject;
if (pChild && pChild->getIsVisible() && ((CCMenuItem*)pChild)->getIsEnabled())
{
{
CCPoint local = pChild->convertToNodeSpace(touchLocation);
CCRect r = ((CCMenuItem*)pChild)->rect();
r.origin = CCPointZero;
@ -592,13 +610,13 @@ namespace cocos2d{
if (CCRect::CCRectContainsPoint(r, local))
{
return (CCMenuItem*)pChild;
}
}
}
}
}
}
return NULL;
}
}
return NULL;
}
}