#include "CCMenuPassive.h" #include "CCDirector.h" #include "CCPointExtension.h" #include "CCMenuItem.h" #include using namespace std; NS_CC_BEGIN enum { kDefaultPadding = 5, }; // //CCMenu // CCMenuPassive* CCMenuPassive::node() { return menuWithItem(NULL); } CCMenuPassive * CCMenuPassive::menuWithItems(CCNode* item, ...) { va_list args; va_start(args,item); CCMenuPassive *pRet = new CCMenuPassive(); if (pRet && pRet->initWithItems(item, args)) { pRet->autorelease(); va_end(args); return pRet; } va_end(args); CC_SAFE_DELETE(pRet); return NULL; } CCMenuPassive* CCMenuPassive::menuWithItem(CCNode* item) { return menuWithItems(item, NULL); } bool CCMenuPassive::initWithItems(CCNode* item, va_list args) { if (CCLayer::init()) { //this->m_bIsTouchEnabled = false; // menu in the center of the screen CCSize s = CCDirector::sharedDirector()->getWinSize(); // Set the default anchor point setIsRelativeAnchorPoint(false); setAnchorPoint(ccp(0.5f, 0.5f)); this->setContentSize(s); 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*); } } return true; } return false; } //Menu - Alignment void CCMenuPassive::alignItemsVertically() { this->alignItemsVerticallyWithPadding(kDefaultPadding); } void CCMenuPassive::alignItemsVerticallyWithPadding(float padding) { float height = -padding; if (m_pChildren && m_pChildren->count() > 0) { CCObject* pObject = NULL; CCARRAY_FOREACH(m_pChildren, pObject) { CCNode* pChild = dynamic_cast(pObject); if (pChild) { height += pChild->getContentSize().height * pChild->getScaleY() + padding; } } } float width=0; float y = height / 2.0f; if (m_pChildren && m_pChildren->count() > 0) { CCObject* pObject = NULL; CCARRAY_FOREACH(m_pChildren, pObject) { CCNode* pChild = dynamic_cast(pObject); if (pChild) { width=max(width, pChild->getContentSize().width); pChild->setPosition(ccp(0, y - pChild->getContentSize().height * pChild->getScaleY() / 2.0f)); y -= pChild->getContentSize().height * pChild->getScaleY() + padding; } } } setContentSize(CCSizeMake(width, height)); } void CCMenuPassive::alignItemsHorizontally(void) { this->alignItemsHorizontallyWithPadding(kDefaultPadding); } void CCMenuPassive::alignItemsHorizontallyWithPadding(float padding) { float width = -padding; if (m_pChildren && m_pChildren->count() > 0) { CCObject* pObject = NULL; CCARRAY_FOREACH(m_pChildren, pObject) { CCNode* pChild = dynamic_cast(pObject); if (pChild) { width += pChild->getContentSize().width * pChild->getScaleX() + padding; } } } float height=0; float x = -width / 2.0f; if (m_pChildren && m_pChildren->count() > 0) { CCObject* pObject = NULL; CCARRAY_FOREACH(m_pChildren, pObject) { CCNode* pChild = dynamic_cast(pObject); if (pChild) { height=max(height, pChild->getContentSize().height); pChild->setPosition(ccp(x + pChild->getContentSize().width * pChild->getScaleX() / 2.0f, 0)); x += pChild->getContentSize().width * pChild->getScaleX() + padding; } } } setContentSize(CCSizeMake(width, height)); } void CCMenuPassive::alignItemsInColumns(unsigned int columns, ...) { va_list args; va_start(args, columns); this->alignItemsInColumns(columns, args); va_end(args); } void CCMenuPassive::alignItemsInColumns(unsigned int columns, va_list args) { vector 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 = dynamic_cast(pObject); if (pChild) { CCAssert(row < rows.size(), ""); rowColumns = rows[row]; // can not have zero columns on a row CCAssert(rowColumns, ""); float tmp = pChild->getContentSize().height; rowHeight = (unsigned int)((rowHeight >= tmp || isnan(tmp)) ? rowHeight : tmp); ++columnsOccupied; if (columnsOccupied >= rowColumns) { height += rowHeight + 5; columnsOccupied = 0; rowHeight = 0; ++row; } } } } // check if too many rows/columns for available menu items CCAssert(! 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 = dynamic_cast(pObject); if (pChild) { if (rowColumns == 0) { rowColumns = rows[row]; w = winSize.width / (1 + rowColumns); x = w; } float tmp = pChild->getContentSize().height; rowHeight = (unsigned int)((rowHeight >= tmp || isnan(tmp)) ? rowHeight : tmp); pChild->setPosition(ccp(x - winSize.width / 2, y - pChild->getContentSize().height / 2)); x += w; ++columnsOccupied; if (columnsOccupied >= rowColumns) { y -= rowHeight + 5; columnsOccupied = 0; rowColumns = 0; rowHeight = 0; ++row; } } } } } void CCMenuPassive::alignItemsInRows(unsigned int rows, ...) { va_list args; va_start(args, rows); this->alignItemsInRows(rows, args); va_end(args); } void CCMenuPassive::alignItemsInRows(unsigned int rows, va_list args) { vector columns; while (rows) { columns.push_back(rows); rows = va_arg(args, unsigned int); } vector columnWidths; vector 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 = dynamic_cast(pObject); if (pChild) { // check if too many menu items for the amount of rows/columns CCAssert(column < columns.size(), ""); columnRows = columns[column]; // can't have zero rows on a column CCAssert(columnRows, ""); // columnWidth = fmaxf(columnWidth, [item contentSize].width); float tmp = pChild->getContentSize().width; columnWidth = (unsigned int)((columnWidth >= tmp || isnan(tmp)) ? columnWidth : tmp); columnHeight += (int)(pChild->getContentSize().height + 5); ++rowsOccupied; if (rowsOccupied >= columnRows) { columnWidths.push_back(columnWidth); columnHeights.push_back(columnHeight); width += columnWidth + 10; rowsOccupied = 0; columnWidth = 0; columnHeight = -5; ++column; } } } } // check if too many rows/columns for available menu items. CCAssert(! 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 = dynamic_cast(pObject); if (pChild) { if (columnRows == 0) { columnRows = columns[column]; y = (float) columnHeights[column]; } // columnWidth = fmaxf(columnWidth, [item contentSize].width); float tmp = pChild->getContentSize().width; columnWidth = (unsigned int)((columnWidth >= tmp || isnan(tmp)) ? columnWidth : tmp); pChild->setPosition(ccp(x + columnWidths[column] / 2, y - winSize.height / 2)); y -= pChild->getContentSize().height + 10; ++rowsOccupied; if (rowsOccupied >= columnRows) { x += columnWidth + 5; rowsOccupied = 0; columnRows = 0; columnWidth = 0; ++column; } } } } } // Opacity Protocol /** Override synthesized setOpacity to recurse items */ void CCMenuPassive::setOpacity(GLubyte var) { m_cOpacity = var; if (m_pChildren && m_pChildren->count() > 0) { CCObject* pObject = NULL; CCARRAY_FOREACH(m_pChildren, pObject) { CCNode* pChild = dynamic_cast(pObject); if (pChild) { CCRGBAProtocol *pRGBAProtocol = dynamic_cast(pChild); if (pRGBAProtocol) { pRGBAProtocol->setOpacity(m_cOpacity); } } } } } GLubyte CCMenuPassive::getOpacity(void) { return m_cOpacity; } void CCMenuPassive::setColor(const ccColor3B& var) { m_tColor = var; if (m_pChildren && m_pChildren->count() > 0) { CCObject* pObject = NULL; CCARRAY_FOREACH(m_pChildren, pObject) { CCNode* pChild = dynamic_cast(pObject); if (pChild) { CCRGBAProtocol *pRGBAProtocol = dynamic_cast(pChild); if (pRGBAProtocol) { pRGBAProtocol->setColor(m_tColor); } } } } } const ccColor3B& CCMenuPassive::getColor(void) { return m_tColor; } NS_CC_END