2011-07-28 14:24:24 +08:00
|
|
|
/****************************************************************************
|
|
|
|
Copyright (c) 2008-2010 Ricardo Quesada
|
2014-01-07 11:25:07 +08:00
|
|
|
Copyright (c) 2010-2012 cocos2d-x.org
|
2018-01-29 16:25:32 +08:00
|
|
|
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
|
|
|
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
2011-07-28 14:24:24 +08:00
|
|
|
|
|
|
|
http://www.cocos2d-x.org
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
|
|
in the Software without restriction, including without limitation the rights
|
|
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
|
|
all copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
THE SOFTWARE.
|
|
|
|
****************************************************************************/
|
2014-04-27 01:11:22 +08:00
|
|
|
#include "2d/CCMenu.h"
|
2015-06-18 10:23:52 +08:00
|
|
|
#include "2d/CCCamera.h"
|
2014-04-30 08:37:36 +08:00
|
|
|
#include "base/CCDirector.h"
|
|
|
|
#include "base/CCTouch.h"
|
|
|
|
#include "base/CCEventListenerTouch.h"
|
2014-08-26 18:19:28 +08:00
|
|
|
#include "base/CCEventDispatcher.h"
|
2016-06-15 15:01:26 +08:00
|
|
|
#include "base/ccUTF8.h"
|
2014-09-10 07:50:02 +08:00
|
|
|
#include "platform/CCStdC.h"
|
2013-09-03 18:22:03 +08:00
|
|
|
|
2011-07-28 14:24:24 +08:00
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
2012-03-22 14:22:06 +08:00
|
|
|
NS_CC_BEGIN
|
2011-07-28 14:24:24 +08:00
|
|
|
|
2012-03-22 14:22:06 +08:00
|
|
|
enum
|
|
|
|
{
|
2012-04-19 14:35:52 +08:00
|
|
|
kDefaultPadding = 5,
|
2012-03-22 14:22:06 +08:00
|
|
|
};
|
2011-07-28 14:24:24 +08:00
|
|
|
|
2012-03-22 14:22:06 +08:00
|
|
|
//
|
|
|
|
//CCMenu
|
|
|
|
//
|
2011-07-28 14:24:24 +08:00
|
|
|
|
2013-09-03 18:22:03 +08:00
|
|
|
Menu::~Menu()
|
|
|
|
{
|
2013-09-16 22:23:07 +08:00
|
|
|
CCLOGINFO("In the destructor of Menu. %p", this);
|
2013-09-03 18:22:03 +08:00
|
|
|
}
|
|
|
|
|
2014-03-22 21:04:36 +08:00
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
Menu* Menu::create()
|
2012-03-22 14:22:06 +08:00
|
|
|
{
|
2014-03-25 06:09:24 +08:00
|
|
|
return Menu::create(nullptr, nullptr);
|
2012-03-22 14:22:06 +08:00
|
|
|
}
|
2011-07-28 14:24:24 +08:00
|
|
|
|
2015-05-09 00:19:13 +08:00
|
|
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
|
2014-03-25 06:09:24 +08:00
|
|
|
Menu * Menu::variadicCreate(MenuItem* item, ...)
|
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
va_start(args,item);
|
|
|
|
|
|
|
|
Menu *ret = Menu::createWithItems(item, args);
|
|
|
|
|
|
|
|
va_end(args);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
|
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
Menu * Menu::create(MenuItem* item, ...)
|
2012-03-22 14:22:06 +08:00
|
|
|
{
|
2012-04-19 14:35:52 +08:00
|
|
|
va_list args;
|
|
|
|
va_start(args,item);
|
2012-11-14 18:05:15 +08:00
|
|
|
|
2013-12-18 17:47:20 +08:00
|
|
|
Menu *ret = Menu::createWithItems(item, args);
|
2012-11-14 18:05:15 +08:00
|
|
|
|
2012-04-19 14:35:52 +08:00
|
|
|
va_end(args);
|
2012-12-06 18:51:33 +08:00
|
|
|
|
2013-12-18 17:47:20 +08:00
|
|
|
return ret;
|
2012-03-22 14:22:06 +08:00
|
|
|
}
|
2014-03-25 06:09:24 +08:00
|
|
|
#endif
|
|
|
|
|
2011-07-28 14:24:24 +08:00
|
|
|
|
2013-11-28 16:02:03 +08:00
|
|
|
Menu* Menu::createWithArray(const Vector<MenuItem*>& arrayOfItems)
|
2012-03-22 14:22:06 +08:00
|
|
|
{
|
2014-08-28 07:31:57 +08:00
|
|
|
auto ret = new (std::nothrow) Menu();
|
2013-11-28 16:02:03 +08:00
|
|
|
if (ret && ret->initWithArray(arrayOfItems))
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-11-28 16:02:03 +08:00
|
|
|
ret->autorelease();
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-11-28 16:02:03 +08:00
|
|
|
CC_SAFE_DELETE(ret);
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
|
|
|
|
2013-11-28 16:02:03 +08:00
|
|
|
return ret;
|
2012-03-22 14:22:06 +08:00
|
|
|
}
|
2011-07-28 14:24:24 +08:00
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
Menu* Menu::createWithItems(MenuItem* item, va_list args)
|
2012-03-22 14:22:06 +08:00
|
|
|
{
|
2013-11-28 16:02:03 +08:00
|
|
|
Vector<MenuItem*> items;
|
2012-11-14 18:05:15 +08:00
|
|
|
if( item )
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-12-05 10:35:10 +08:00
|
|
|
items.pushBack(item);
|
2013-06-20 14:13:12 +08:00
|
|
|
MenuItem *i = va_arg(args, MenuItem*);
|
2012-11-14 18:05:15 +08:00
|
|
|
while(i)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-12-05 10:35:10 +08:00
|
|
|
items.pushBack(i);
|
2013-06-20 14:13:12 +08:00
|
|
|
i = va_arg(args, MenuItem*);
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
|
|
|
}
|
2012-11-14 18:05:15 +08:00
|
|
|
|
2013-11-28 16:02:03 +08:00
|
|
|
return Menu::createWithArray(items);
|
2012-11-14 18:05:15 +08:00
|
|
|
}
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
Menu* Menu::createWithItem(MenuItem* item)
|
2012-11-14 18:05:15 +08:00
|
|
|
{
|
2014-03-25 06:09:24 +08:00
|
|
|
return Menu::create(item, nullptr);
|
2012-11-14 18:05:15 +08:00
|
|
|
}
|
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
bool Menu::init()
|
2012-11-14 18:05:15 +08:00
|
|
|
{
|
2013-11-28 16:02:03 +08:00
|
|
|
return initWithArray(Vector<MenuItem*>());
|
2012-03-22 14:22:06 +08:00
|
|
|
}
|
2011-07-28 14:24:24 +08:00
|
|
|
|
2013-11-28 16:02:03 +08:00
|
|
|
bool Menu::initWithArray(const Vector<MenuItem*>& arrayOfItems)
|
2012-03-22 14:22:06 +08:00
|
|
|
{
|
2013-06-20 14:13:12 +08:00
|
|
|
if (Layer::init())
|
2012-03-22 14:22:06 +08:00
|
|
|
{
|
2013-06-15 14:03:30 +08:00
|
|
|
_enabled = true;
|
2012-03-22 14:22:06 +08:00
|
|
|
// menu in the center of the screen
|
2013-07-12 06:24:23 +08:00
|
|
|
Size s = Director::getInstance()->getWinSize();
|
2012-03-22 14:22:06 +08:00
|
|
|
|
2016-04-22 20:36:02 +08:00
|
|
|
this->setIgnoreAnchorPointForPosition(true);
|
2014-05-15 01:07:09 +08:00
|
|
|
setAnchorPoint(Vec2(0.5f, 0.5f));
|
2012-03-22 14:22:06 +08:00
|
|
|
this->setContentSize(s);
|
|
|
|
|
2014-08-28 11:41:18 +08:00
|
|
|
setPosition(s.width/2, s.height/2);
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2013-11-28 16:02:03 +08:00
|
|
|
int z=0;
|
|
|
|
|
|
|
|
for (auto& item : arrayOfItems)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-11-28 16:02:03 +08:00
|
|
|
this->addChild(item, z);
|
|
|
|
z++;
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
|
|
|
|
2013-12-18 17:47:20 +08:00
|
|
|
_selectedItem = nullptr;
|
2013-07-26 08:47:42 +08:00
|
|
|
_state = Menu::State::WAITING;
|
2013-02-28 10:15:09 +08:00
|
|
|
|
|
|
|
// enable cascade color and opacity on menus
|
|
|
|
setCascadeColorEnabled(true);
|
|
|
|
setCascadeOpacityEnabled(true);
|
|
|
|
|
2013-11-01 20:53:51 +08:00
|
|
|
|
|
|
|
auto touchListener = EventListenerTouchOneByOne::create();
|
|
|
|
touchListener->setSwallowTouches(true);
|
|
|
|
|
|
|
|
touchListener->onTouchBegan = CC_CALLBACK_2(Menu::onTouchBegan, this);
|
|
|
|
touchListener->onTouchMoved = CC_CALLBACK_2(Menu::onTouchMoved, this);
|
|
|
|
touchListener->onTouchEnded = CC_CALLBACK_2(Menu::onTouchEnded, this);
|
|
|
|
touchListener->onTouchCancelled = CC_CALLBACK_2(Menu::onTouchCancelled, this);
|
|
|
|
|
|
|
|
_eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this);
|
|
|
|
|
2012-03-22 14:22:06 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2011-07-28 14:24:24 +08:00
|
|
|
|
2012-03-22 14:22:06 +08:00
|
|
|
/*
|
|
|
|
* override add:
|
|
|
|
*/
|
2013-06-20 14:13:12 +08:00
|
|
|
void Menu::addChild(Node * child)
|
2012-03-22 14:22:06 +08:00
|
|
|
{
|
2013-06-20 14:13:12 +08:00
|
|
|
Layer::addChild(child);
|
2012-03-22 14:22:06 +08:00
|
|
|
}
|
2011-07-28 14:24:24 +08:00
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
void Menu::addChild(Node * child, int zOrder)
|
2012-03-22 14:22:06 +08:00
|
|
|
{
|
2013-06-20 14:13:12 +08:00
|
|
|
Layer::addChild(child, zOrder);
|
2012-03-22 14:22:06 +08:00
|
|
|
}
|
2011-07-28 14:24:24 +08:00
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
void Menu::addChild(Node * child, int zOrder, int tag)
|
2012-03-22 14:22:06 +08:00
|
|
|
{
|
2013-12-18 17:47:20 +08:00
|
|
|
CCASSERT( dynamic_cast<MenuItem*>(child) != nullptr, "Menu only supports MenuItem objects as children");
|
2013-06-20 14:13:12 +08:00
|
|
|
Layer::addChild(child, zOrder, tag);
|
2012-03-22 14:22:06 +08:00
|
|
|
}
|
2011-07-28 14:24:24 +08:00
|
|
|
|
2014-06-25 11:27:48 +08:00
|
|
|
void Menu::addChild(Node * child, int zOrder, const std::string &name)
|
|
|
|
{
|
|
|
|
CCASSERT( dynamic_cast<MenuItem*>(child) != nullptr, "Menu only supports MenuItem objects as children");
|
|
|
|
Layer::addChild(child, zOrder, name);
|
|
|
|
}
|
|
|
|
|
2013-09-03 18:22:03 +08:00
|
|
|
void Menu::onEnter()
|
|
|
|
{
|
2015-07-28 16:07:14 +08:00
|
|
|
#if CC_ENABLE_SCRIPT_BINDING
|
|
|
|
if (_scriptType == kScriptTypeJavascript)
|
|
|
|
{
|
2015-07-28 18:24:03 +08:00
|
|
|
if (ScriptEngineManager::sendNodeEventToJSExtended(this, kNodeOnEnter))
|
2015-07-28 16:07:14 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2013-09-03 18:22:03 +08:00
|
|
|
Layer::onEnter();
|
|
|
|
}
|
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
void Menu::onExit()
|
2012-03-22 14:22:06 +08:00
|
|
|
{
|
2015-07-28 16:07:14 +08:00
|
|
|
#if CC_ENABLE_SCRIPT_BINDING
|
|
|
|
if (_scriptType == kScriptTypeJavascript)
|
|
|
|
{
|
2015-07-28 18:24:03 +08:00
|
|
|
if (ScriptEngineManager::sendNodeEventToJSExtended(this, kNodeOnExit))
|
2015-07-28 16:07:14 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2013-07-26 08:47:42 +08:00
|
|
|
if (_state == Menu::State::TRACKING_TOUCH)
|
2011-07-28 14:24:24 +08:00
|
|
|
{
|
2013-06-15 14:03:30 +08:00
|
|
|
if (_selectedItem)
|
2013-01-17 15:04:48 +08:00
|
|
|
{
|
2013-06-15 14:03:30 +08:00
|
|
|
_selectedItem->unselected();
|
2013-12-18 17:47:20 +08:00
|
|
|
_selectedItem = nullptr;
|
2013-01-17 15:04:48 +08:00
|
|
|
}
|
|
|
|
|
2013-07-26 08:47:42 +08:00
|
|
|
_state = Menu::State::WAITING;
|
2011-07-28 14:24:24 +08:00
|
|
|
}
|
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
Layer::onExit();
|
2012-03-22 14:22:06 +08:00
|
|
|
}
|
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
void Menu::removeChild(Node* child, bool cleanup)
|
2013-01-17 15:04:48 +08:00
|
|
|
{
|
2016-06-22 07:46:27 +08:00
|
|
|
CCASSERT(dynamic_cast<MenuItem*>(child) != nullptr, "Menu only supports MenuItem objects as children");
|
2013-01-17 15:04:48 +08:00
|
|
|
|
2016-06-22 07:46:27 +08:00
|
|
|
if (_selectedItem == child)
|
2013-01-17 15:04:48 +08:00
|
|
|
{
|
2013-12-18 17:47:20 +08:00
|
|
|
_selectedItem = nullptr;
|
2013-01-17 15:04:48 +08:00
|
|
|
}
|
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
Node::removeChild(child, cleanup);
|
2013-01-17 15:04:48 +08:00
|
|
|
}
|
|
|
|
|
2012-03-22 14:22:06 +08:00
|
|
|
//Menu - Events
|
2012-04-13 14:11:35 +08:00
|
|
|
|
2016-11-09 10:34:50 +08:00
|
|
|
bool Menu::onTouchBegan(Touch* touch, Event* /*event*/)
|
2012-03-22 14:22:06 +08:00
|
|
|
{
|
2015-08-07 16:27:25 +08:00
|
|
|
auto camera = Camera::getVisitingCamera();
|
|
|
|
if (_state != Menu::State::WAITING || ! _visible || !_enabled || !camera)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2013-09-03 18:22:03 +08:00
|
|
|
|
2013-12-18 17:47:20 +08:00
|
|
|
for (Node *c = this->_parent; c != nullptr; c = c->getParent())
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2012-06-15 15:10:40 +08:00
|
|
|
if (c->isVisible() == false)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2015-08-07 16:27:25 +08:00
|
|
|
_selectedItem = this->getItemForTouch(touch, camera);
|
2016-06-22 07:46:27 +08:00
|
|
|
|
2013-06-15 14:03:30 +08:00
|
|
|
if (_selectedItem)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-07-26 08:47:42 +08:00
|
|
|
_state = Menu::State::TRACKING_TOUCH;
|
2015-08-07 16:27:25 +08:00
|
|
|
_selectedWithCamera = camera;
|
2013-06-15 14:03:30 +08:00
|
|
|
_selectedItem->selected();
|
2013-09-03 18:22:03 +08:00
|
|
|
|
2012-04-19 14:35:52 +08:00
|
|
|
return true;
|
|
|
|
}
|
2013-09-03 18:22:03 +08:00
|
|
|
|
2012-04-19 14:35:52 +08:00
|
|
|
return false;
|
2012-03-22 14:22:06 +08:00
|
|
|
}
|
2011-08-02 15:45:27 +08:00
|
|
|
|
2016-11-09 10:34:50 +08:00
|
|
|
void Menu::onTouchEnded(Touch* /*touch*/, Event* /*event*/)
|
2012-03-22 14:22:06 +08:00
|
|
|
{
|
2013-07-26 08:47:42 +08:00
|
|
|
CCASSERT(_state == Menu::State::TRACKING_TOUCH, "[Menu ccTouchEnded] -- invalid state");
|
2013-10-24 11:17:29 +08:00
|
|
|
this->retain();
|
2013-06-15 14:03:30 +08:00
|
|
|
if (_selectedItem)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-06-15 14:03:30 +08:00
|
|
|
_selectedItem->unselected();
|
|
|
|
_selectedItem->activate();
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
2013-07-26 08:47:42 +08:00
|
|
|
_state = Menu::State::WAITING;
|
2015-08-07 16:27:25 +08:00
|
|
|
_selectedWithCamera = nullptr;
|
2013-10-24 11:17:29 +08:00
|
|
|
this->release();
|
2012-03-22 14:22:06 +08:00
|
|
|
}
|
2011-07-28 14:24:24 +08:00
|
|
|
|
2016-11-09 10:34:50 +08:00
|
|
|
void Menu::onTouchCancelled(Touch* /*touch*/, Event* /*event*/)
|
2012-03-22 14:22:06 +08:00
|
|
|
{
|
2013-07-26 08:47:42 +08:00
|
|
|
CCASSERT(_state == Menu::State::TRACKING_TOUCH, "[Menu ccTouchCancelled] -- invalid state");
|
2013-10-24 11:17:29 +08:00
|
|
|
this->retain();
|
2013-06-15 14:03:30 +08:00
|
|
|
if (_selectedItem)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-06-15 14:03:30 +08:00
|
|
|
_selectedItem->unselected();
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
2013-07-26 08:47:42 +08:00
|
|
|
_state = Menu::State::WAITING;
|
2013-10-24 11:17:29 +08:00
|
|
|
this->release();
|
2012-03-22 14:22:06 +08:00
|
|
|
}
|
2011-07-28 14:24:24 +08:00
|
|
|
|
2016-11-09 10:34:50 +08:00
|
|
|
void Menu::onTouchMoved(Touch* touch, Event* /*event*/)
|
2012-03-22 14:22:06 +08:00
|
|
|
{
|
2013-07-26 08:47:42 +08:00
|
|
|
CCASSERT(_state == Menu::State::TRACKING_TOUCH, "[Menu ccTouchMoved] -- invalid state");
|
2015-08-07 16:27:25 +08:00
|
|
|
MenuItem *currentItem = this->getItemForTouch(touch, _selectedWithCamera);
|
2013-09-03 18:22:03 +08:00
|
|
|
if (currentItem != _selectedItem)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-06-15 14:03:30 +08:00
|
|
|
if (_selectedItem)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-06-15 14:03:30 +08:00
|
|
|
_selectedItem->unselected();
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
2013-06-15 14:03:30 +08:00
|
|
|
_selectedItem = currentItem;
|
|
|
|
if (_selectedItem)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-06-15 14:03:30 +08:00
|
|
|
_selectedItem->selected();
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
|
|
|
}
|
2012-03-22 14:22:06 +08:00
|
|
|
}
|
2011-07-28 14:24:24 +08:00
|
|
|
|
2012-03-22 14:22:06 +08:00
|
|
|
//Menu - Alignment
|
2013-06-20 14:13:12 +08:00
|
|
|
void Menu::alignItemsVertically()
|
2012-03-22 14:22:06 +08:00
|
|
|
{
|
2012-04-19 14:35:52 +08:00
|
|
|
this->alignItemsVerticallyWithPadding(kDefaultPadding);
|
2012-03-22 14:22:06 +08:00
|
|
|
}
|
2011-07-28 14:24:24 +08:00
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
void Menu::alignItemsVerticallyWithPadding(float padding)
|
2012-03-22 14:22:06 +08:00
|
|
|
{
|
2012-04-19 14:35:52 +08:00
|
|
|
float height = -padding;
|
2013-12-20 05:34:41 +08:00
|
|
|
|
|
|
|
for(const auto &child : _children)
|
|
|
|
height += child->getContentSize().height * child->getScaleY() + padding;
|
2011-07-28 14:24:24 +08:00
|
|
|
|
2012-04-19 14:35:52 +08:00
|
|
|
float y = height / 2.0f;
|
2013-11-28 16:02:03 +08:00
|
|
|
|
2013-12-20 05:34:41 +08:00
|
|
|
for(const auto &child : _children) {
|
2014-08-28 11:41:18 +08:00
|
|
|
child->setPosition(0, y - child->getContentSize().height * child->getScaleY() / 2.0f);
|
2013-12-20 05:34:41 +08:00
|
|
|
y -= child->getContentSize().height * child->getScaleY() + padding;
|
|
|
|
}
|
2012-03-22 14:22:06 +08:00
|
|
|
}
|
2011-07-28 14:24:24 +08:00
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
void Menu::alignItemsHorizontally(void)
|
2012-03-22 14:22:06 +08:00
|
|
|
{
|
2012-04-19 14:35:52 +08:00
|
|
|
this->alignItemsHorizontallyWithPadding(kDefaultPadding);
|
2012-03-22 14:22:06 +08:00
|
|
|
}
|
2011-07-28 14:24:24 +08:00
|
|
|
|
2013-06-20 14:13:12 +08:00
|
|
|
void Menu::alignItemsHorizontallyWithPadding(float padding)
|
2012-03-22 14:22:06 +08:00
|
|
|
{
|
2012-04-19 14:35:52 +08:00
|
|
|
float width = -padding;
|
2013-12-20 05:34:41 +08:00
|
|
|
for(const auto &child : _children)
|
|
|
|
width += child->getContentSize().width * child->getScaleX() + padding;
|
2011-07-28 14:24:24 +08:00
|
|
|
|
2012-04-19 14:35:52 +08:00
|
|
|
float x = -width / 2.0f;
|
2013-11-28 16:02:03 +08:00
|
|
|
|
2013-12-20 05:34:41 +08:00
|
|
|
for(const auto &child : _children) {
|
2014-08-28 11:41:18 +08:00
|
|
|
child->setPosition(x + child->getContentSize().width * child->getScaleX() / 2.0f, 0);
|
2013-12-20 05:34:41 +08:00
|
|
|
x += child->getContentSize().width * child->getScaleX() + padding;
|
|
|
|
}
|
2012-03-22 14:22:06 +08:00
|
|
|
}
|
2011-07-28 14:24:24 +08:00
|
|
|
|
2013-07-20 13:01:27 +08:00
|
|
|
void Menu::alignItemsInColumns(int columns, ...)
|
2012-03-22 14:22:06 +08:00
|
|
|
{
|
2012-04-19 14:35:52 +08:00
|
|
|
va_list args;
|
|
|
|
va_start(args, columns);
|
2011-07-28 14:24:24 +08:00
|
|
|
|
2012-04-19 14:35:52 +08:00
|
|
|
this->alignItemsInColumns(columns, args);
|
2011-07-28 14:24:24 +08:00
|
|
|
|
2012-04-19 14:35:52 +08:00
|
|
|
va_end(args);
|
2012-03-22 14:22:06 +08:00
|
|
|
}
|
2011-07-28 14:24:24 +08:00
|
|
|
|
2013-07-20 13:01:27 +08:00
|
|
|
void Menu::alignItemsInColumns(int columns, va_list args)
|
2012-03-22 14:22:06 +08:00
|
|
|
{
|
2013-07-20 13:01:27 +08:00
|
|
|
CCASSERT(columns >= 0, "Columns must be >= 0");
|
2013-12-04 17:46:57 +08:00
|
|
|
ValueVector rows;
|
2012-04-19 14:35:52 +08:00
|
|
|
while (columns)
|
|
|
|
{
|
2013-12-03 17:15:48 +08:00
|
|
|
rows.push_back(Value(columns));
|
2013-07-20 13:01:27 +08:00
|
|
|
columns = va_arg(args, int);
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
2012-11-30 21:13:25 +08:00
|
|
|
alignItemsInColumnsWithArray(rows);
|
|
|
|
}
|
|
|
|
|
2013-12-04 17:46:57 +08:00
|
|
|
void Menu::alignItemsInColumnsWithArray(const ValueVector& rows)
|
2012-11-30 21:13:25 +08:00
|
|
|
{
|
2012-04-19 14:35:52 +08:00
|
|
|
int height = -5;
|
2013-12-27 15:06:16 +08:00
|
|
|
size_t row = 0;
|
2013-12-03 17:15:48 +08:00
|
|
|
int rowHeight = 0;
|
|
|
|
int columnsOccupied = 0;
|
|
|
|
int rowColumns = 0;
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2013-12-20 05:34:41 +08:00
|
|
|
for(const auto &child : _children) {
|
2015-07-14 15:28:36 +08:00
|
|
|
CCASSERT(row < rows.size(), "row should less than rows.size()!");
|
2013-12-20 05:34:41 +08:00
|
|
|
|
|
|
|
rowColumns = rows[row].asInt();
|
|
|
|
// can not have zero columns on a row
|
2015-07-14 15:28:36 +08:00
|
|
|
CCASSERT(rowColumns, "rowColumns can't be 0.");
|
2013-12-20 05:34:41 +08:00
|
|
|
|
|
|
|
float tmp = child->getContentSize().height;
|
|
|
|
rowHeight = (unsigned int)((rowHeight >= tmp || isnan(tmp)) ? rowHeight : tmp);
|
|
|
|
|
|
|
|
++columnsOccupied;
|
|
|
|
if (columnsOccupied >= rowColumns)
|
2012-03-22 14:22:06 +08:00
|
|
|
{
|
2013-12-20 05:34:41 +08:00
|
|
|
height += rowHeight + 5;
|
2013-11-28 16:02:03 +08:00
|
|
|
|
2013-12-20 05:34:41 +08:00
|
|
|
columnsOccupied = 0;
|
|
|
|
rowHeight = 0;
|
|
|
|
++row;
|
2012-03-22 14:22:06 +08:00
|
|
|
}
|
2013-12-20 05:34:41 +08:00
|
|
|
}
|
2011-07-28 14:24:24 +08:00
|
|
|
|
2012-04-19 14:35:52 +08:00
|
|
|
// check if too many rows/columns for available menu items
|
2015-07-14 15:28:36 +08:00
|
|
|
CCASSERT(! columnsOccupied, "columnsOccupied should be 0.");
|
2011-07-28 14:24:24 +08:00
|
|
|
|
2017-01-03 09:49:22 +08:00
|
|
|
Size winSize = getContentSize();
|
2011-07-28 14:24:24 +08:00
|
|
|
|
2012-04-19 14:35:52 +08:00
|
|
|
row = 0;
|
|
|
|
rowHeight = 0;
|
|
|
|
rowColumns = 0;
|
|
|
|
float w = 0.0;
|
|
|
|
float x = 0.0;
|
|
|
|
float y = (float)(height / 2);
|
2011-07-28 14:24:24 +08:00
|
|
|
|
2013-12-20 05:34:41 +08:00
|
|
|
for(const auto &child : _children) {
|
|
|
|
if (rowColumns == 0)
|
2012-03-22 14:22:06 +08:00
|
|
|
{
|
2013-12-20 05:34:41 +08:00
|
|
|
rowColumns = rows[row].asInt();
|
|
|
|
w = winSize.width / (1 + rowColumns);
|
|
|
|
x = w;
|
|
|
|
}
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2013-12-20 05:34:41 +08:00
|
|
|
float tmp = child->getContentSize().height;
|
|
|
|
rowHeight = (unsigned int)((rowHeight >= tmp || isnan(tmp)) ? rowHeight : tmp);
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2014-08-28 11:41:18 +08:00
|
|
|
child->setPosition(x - winSize.width / 2,
|
|
|
|
y - child->getContentSize().height / 2);
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2013-12-20 05:34:41 +08:00
|
|
|
x += w;
|
|
|
|
++columnsOccupied;
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2013-12-20 05:34:41 +08:00
|
|
|
if (columnsOccupied >= rowColumns)
|
|
|
|
{
|
|
|
|
y -= rowHeight + 5;
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2013-12-20 05:34:41 +08:00
|
|
|
columnsOccupied = 0;
|
|
|
|
rowColumns = 0;
|
|
|
|
rowHeight = 0;
|
|
|
|
++row;
|
2012-03-22 14:22:06 +08:00
|
|
|
}
|
2013-12-20 05:34:41 +08:00
|
|
|
}
|
2012-03-22 14:22:06 +08:00
|
|
|
}
|
2011-07-28 14:24:24 +08:00
|
|
|
|
2013-07-20 13:01:27 +08:00
|
|
|
void Menu::alignItemsInRows(int rows, ...)
|
2012-03-22 14:22:06 +08:00
|
|
|
{
|
2012-04-19 14:35:52 +08:00
|
|
|
va_list args;
|
|
|
|
va_start(args, rows);
|
2011-07-28 14:24:24 +08:00
|
|
|
|
2012-04-19 14:35:52 +08:00
|
|
|
this->alignItemsInRows(rows, args);
|
2011-07-28 14:24:24 +08:00
|
|
|
|
2012-04-19 14:35:52 +08:00
|
|
|
va_end(args);
|
2012-03-22 14:22:06 +08:00
|
|
|
}
|
2011-07-28 14:24:24 +08:00
|
|
|
|
2013-07-20 13:01:27 +08:00
|
|
|
void Menu::alignItemsInRows(int rows, va_list args)
|
2012-03-22 14:22:06 +08:00
|
|
|
{
|
2013-12-04 17:46:57 +08:00
|
|
|
ValueVector array;
|
2012-04-19 14:35:52 +08:00
|
|
|
while (rows)
|
|
|
|
{
|
2013-12-03 17:15:48 +08:00
|
|
|
array.push_back(Value(rows));
|
2013-07-20 13:01:27 +08:00
|
|
|
rows = va_arg(args, int);
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
2013-12-03 17:15:48 +08:00
|
|
|
alignItemsInRowsWithArray(array);
|
2012-11-30 21:13:25 +08:00
|
|
|
}
|
|
|
|
|
2013-12-04 17:46:57 +08:00
|
|
|
void Menu::alignItemsInRowsWithArray(const ValueVector& columns)
|
2012-11-30 21:13:25 +08:00
|
|
|
{
|
2013-12-03 17:15:48 +08:00
|
|
|
vector<int> columnWidths;
|
|
|
|
vector<int> columnHeights;
|
2012-04-19 14:35:52 +08:00
|
|
|
|
|
|
|
int width = -10;
|
|
|
|
int columnHeight = -5;
|
2013-12-27 15:06:16 +08:00
|
|
|
size_t column = 0;
|
2013-12-03 17:15:48 +08:00
|
|
|
int columnWidth = 0;
|
|
|
|
int rowsOccupied = 0;
|
|
|
|
int columnRows;
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2013-12-20 05:34:41 +08:00
|
|
|
for(const auto &child : _children) {
|
|
|
|
// check if too many menu items for the amount of rows/columns
|
2015-07-14 15:28:36 +08:00
|
|
|
CCASSERT(column < columns.size(), "column should be less than columns.size().");
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2013-12-20 05:34:41 +08:00
|
|
|
columnRows = columns[column].asInt();
|
|
|
|
// can't have zero rows on a column
|
2015-07-14 15:28:36 +08:00
|
|
|
CCASSERT(columnRows, "columnRows can't be 0.");
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2013-12-20 05:34:41 +08:00
|
|
|
// columnWidth = fmaxf(columnWidth, [item contentSize].width);
|
|
|
|
float tmp = child->getContentSize().width;
|
|
|
|
columnWidth = (unsigned int)((columnWidth >= tmp || isnan(tmp)) ? columnWidth : tmp);
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2013-12-20 05:34:41 +08:00
|
|
|
columnHeight += (int)(child->getContentSize().height + 5);
|
|
|
|
++rowsOccupied;
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2013-12-20 05:34:41 +08:00
|
|
|
if (rowsOccupied >= columnRows)
|
|
|
|
{
|
|
|
|
columnWidths.push_back(columnWidth);
|
|
|
|
columnHeights.push_back(columnHeight);
|
|
|
|
width += columnWidth + 10;
|
|
|
|
|
|
|
|
rowsOccupied = 0;
|
|
|
|
columnWidth = 0;
|
|
|
|
columnHeight = -5;
|
|
|
|
++column;
|
2012-03-22 14:22:06 +08:00
|
|
|
}
|
2013-12-20 05:34:41 +08:00
|
|
|
}
|
2011-07-28 14:24:24 +08:00
|
|
|
|
2012-04-19 14:35:52 +08:00
|
|
|
// check if too many rows/columns for available menu items.
|
2015-07-14 15:28:36 +08:00
|
|
|
CCASSERT(! rowsOccupied, "rowsOccupied should be 0.");
|
2011-07-28 14:24:24 +08:00
|
|
|
|
2017-01-03 09:49:22 +08:00
|
|
|
Size winSize = getContentSize();
|
2011-07-28 14:24:24 +08:00
|
|
|
|
2012-04-19 14:35:52 +08:00
|
|
|
column = 0;
|
|
|
|
columnWidth = 0;
|
|
|
|
columnRows = 0;
|
|
|
|
float x = (float)(-width / 2);
|
|
|
|
float y = 0.0;
|
2011-07-28 14:24:24 +08:00
|
|
|
|
2013-12-20 05:34:41 +08:00
|
|
|
for(const auto &child : _children) {
|
|
|
|
if (columnRows == 0)
|
2012-03-22 14:22:06 +08:00
|
|
|
{
|
2013-12-20 05:34:41 +08:00
|
|
|
columnRows = columns[column].asInt();
|
|
|
|
y = (float) columnHeights[column];
|
|
|
|
}
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2013-12-20 05:34:41 +08:00
|
|
|
// columnWidth = fmaxf(columnWidth, [item contentSize].width);
|
|
|
|
float tmp = child->getContentSize().width;
|
|
|
|
columnWidth = (unsigned int)((columnWidth >= tmp || isnan(tmp)) ? columnWidth : tmp);
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2014-08-28 11:41:18 +08:00
|
|
|
child->setPosition(x + columnWidths[column] / 2,
|
|
|
|
y - winSize.height / 2);
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2013-12-20 05:34:41 +08:00
|
|
|
y -= child->getContentSize().height + 10;
|
|
|
|
++rowsOccupied;
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2013-12-20 05:34:41 +08:00
|
|
|
if (rowsOccupied >= columnRows)
|
|
|
|
{
|
|
|
|
x += columnWidth + 5;
|
|
|
|
rowsOccupied = 0;
|
|
|
|
columnRows = 0;
|
|
|
|
columnWidth = 0;
|
|
|
|
++column;
|
2012-03-22 14:22:06 +08:00
|
|
|
}
|
2013-12-20 05:34:41 +08:00
|
|
|
}
|
2012-03-22 14:22:06 +08:00
|
|
|
}
|
2011-07-28 14:24:24 +08:00
|
|
|
|
2015-08-07 16:27:25 +08:00
|
|
|
MenuItem* Menu::getItemForTouch(Touch *touch, const Camera *camera)
|
2012-03-22 14:22:06 +08:00
|
|
|
{
|
2014-05-15 01:07:09 +08:00
|
|
|
Vec2 touchLocation = touch->getLocation();
|
2016-06-22 07:46:27 +08:00
|
|
|
for (const auto &item: _children)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2016-06-22 07:46:27 +08:00
|
|
|
MenuItem* child = dynamic_cast<MenuItem*>(item);
|
|
|
|
if (nullptr == child || false == child->isVisible() || false == child->isEnabled())
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
Rect rect;
|
|
|
|
rect.size = child->getContentSize();
|
|
|
|
if (isScreenPointInRect(touchLocation, camera, child->getWorldToNodeTransform(), rect, nullptr))
|
2012-03-22 14:22:06 +08:00
|
|
|
{
|
2016-06-22 07:46:27 +08:00
|
|
|
return child;
|
2012-03-22 14:22:06 +08:00
|
|
|
}
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
2013-12-18 17:47:20 +08:00
|
|
|
return nullptr;
|
2011-07-28 14:24:24 +08:00
|
|
|
}
|
2012-03-22 14:22:06 +08:00
|
|
|
|
2016-11-16 09:48:37 +08:00
|
|
|
void Menu::setOpacityModifyRGB(bool /*value*/)
|
|
|
|
{}
|
|
|
|
|
|
|
|
bool Menu::isOpacityModifyRGB() const
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-12-13 06:30:22 +08:00
|
|
|
std::string Menu::getDescription() const
|
|
|
|
{
|
|
|
|
return StringUtils::format("<Menu | Tag = %d>", _tag);
|
|
|
|
}
|
|
|
|
|
2012-03-22 14:22:06 +08:00
|
|
|
NS_CC_END
|