CCControlButton.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743
  1. /*
  2. * Copyright (c) 2012 cocos2d-x.org
  3. * http://www.cocos2d-x.org
  4. *
  5. * Copyright 2011 Yannick Loriot.
  6. * http://yannickloriot.com
  7. *
  8. * Permission is hereby granted, free of charge, to any person obtaining a copy
  9. * of this software and associated documentation files (the "Software"), to deal
  10. * in the Software without restriction, including without limitation the rights
  11. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12. * copies of the Software, and to permit persons to whom the Software is
  13. * furnished to do so, subject to the following conditions:
  14. *
  15. * The above copyright notice and this permission notice shall be included in
  16. * all copies or substantial portions of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24. * THE SOFTWARE.
  25. *
  26. */
  27. #include "CCControlButton.h"
  28. #include "2d/CCLabel.h"
  29. #include "2d/CCAction.h"
  30. #include "2d/CCActionInterval.h"
  31. using namespace std;
  32. NS_CC_EXT_BEGIN
  33. enum
  34. {
  35. kZoomActionTag = 0xCCCB0001,
  36. };
  37. ControlButton::ControlButton()
  38. : _isPushed(false)
  39. , _parentInited(false)
  40. , _doesAdjustBackgroundImage(false)
  41. , _currentTitleColor(Color3B::WHITE)
  42. , _titleLabel(nullptr)
  43. , _backgroundSprite(nullptr)
  44. , _zoomOnTouchDown(false)
  45. , _marginV(ControlButtonMarginTB)
  46. , _marginH(ControlButtonMarginLR)
  47. {
  48. }
  49. ControlButton::~ControlButton()
  50. {
  51. CC_SAFE_RELEASE(_titleLabel);
  52. CC_SAFE_RELEASE(_backgroundSprite);
  53. }
  54. //initialisers
  55. bool ControlButton::init()
  56. {
  57. return this->initWithLabelAndBackgroundSprite(Label::createWithSystemFont("", "Helvetica", 12), cocos2d::ui::Scale9Sprite::create(),true);
  58. }
  59. bool ControlButton::initWithLabelAndBackgroundSprite(Node* node, ui::Scale9Sprite* backgroundSprite, bool adjustBackGroundSize)
  60. {
  61. if (Control::init())
  62. {
  63. CCASSERT(node != nullptr, "node must not be nil.");
  64. LabelProtocol* label = dynamic_cast<LabelProtocol*>(node);
  65. CCASSERT(backgroundSprite != nullptr, "Background sprite must not be nil.");
  66. CCASSERT(label != nullptr, "label must not be nil.");
  67. _parentInited = true;
  68. _isPushed = false;
  69. // Adjust the background image by adjustBackGroundSize
  70. setPreferredSize(Size::ZERO);
  71. setAdjustBackgroundImage(adjustBackGroundSize);
  72. // Zooming button by default
  73. _zoomOnTouchDown = true;
  74. _scaleRatio = 1.1f;
  75. // Set the default anchor point
  76. setIgnoreAnchorPointForPosition(false);
  77. setAnchorPoint(Vec2::ANCHOR_MIDDLE);
  78. // Set the nodes
  79. setTitleLabel(node);
  80. setBackgroundSprite(backgroundSprite);
  81. // Set the default color and opacity
  82. setColor(Color3B::WHITE);
  83. setOpacity(255.0f);
  84. setOpacityModifyRGB(true);
  85. // Initialize the dispatch table
  86. setTitleForState(label->getString(), Control::State::NORMAL);
  87. setTitleColorForState(node->getColor(), Control::State::NORMAL);
  88. setTitleLabelForState(node, Control::State::NORMAL);
  89. setBackgroundSpriteForState(backgroundSprite, Control::State::NORMAL);
  90. setLabelAnchorPoint(Vec2::ANCHOR_MIDDLE);
  91. // Layout update
  92. needsLayout();
  93. return true;
  94. }
  95. //couldn't init the Control
  96. else
  97. {
  98. return false;
  99. }
  100. }
  101. ControlButton* ControlButton::create(Node* label, cocos2d::ui::Scale9Sprite* backgroundSprite)
  102. {
  103. ControlButton *pRet = new (std::nothrow) ControlButton();
  104. pRet->initWithLabelAndBackgroundSprite(label, backgroundSprite, true);
  105. pRet->autorelease();
  106. return pRet;
  107. }
  108. ControlButton* ControlButton::create(Node* label, cocos2d::ui::Scale9Sprite* backgroundSprite, bool adjustBackGroundSize)
  109. {
  110. ControlButton *pRet = new (std::nothrow) ControlButton();
  111. pRet->initWithLabelAndBackgroundSprite(label, backgroundSprite, adjustBackGroundSize);
  112. pRet->autorelease();
  113. return pRet;
  114. }
  115. bool ControlButton::initWithTitleAndFontNameAndFontSize(const std::string& title, const std::string& fontName, float fontSize)
  116. {
  117. return initWithLabelAndBackgroundSprite(Label::createWithSystemFont(title, fontName, fontSize), cocos2d::ui::Scale9Sprite::create(),true);
  118. }
  119. ControlButton* ControlButton::create(const std::string& title, const std::string& fontName, float fontSize)
  120. {
  121. ControlButton *pRet = new (std::nothrow) ControlButton();
  122. pRet->initWithTitleAndFontNameAndFontSize(title, fontName, fontSize);
  123. pRet->autorelease();
  124. return pRet;
  125. }
  126. bool ControlButton::initWithBackgroundSprite(cocos2d::ui::Scale9Sprite* sprite)
  127. {
  128. Label *label = Label::createWithSystemFont("", "Arial", 30);//
  129. return initWithLabelAndBackgroundSprite(label, sprite,false);
  130. }
  131. ControlButton* ControlButton::create(cocos2d::ui::Scale9Sprite* sprite)
  132. {
  133. ControlButton *pRet = new (std::nothrow) ControlButton();
  134. pRet->initWithBackgroundSprite(sprite);
  135. pRet->autorelease();
  136. return pRet;
  137. }
  138. void ControlButton::setMargins(int marginH, int marginV)
  139. {
  140. _marginV = marginV;
  141. _marginH = marginH;
  142. needsLayout();
  143. }
  144. void ControlButton::setEnabled(bool enabled)
  145. {
  146. Control::setEnabled(enabled);
  147. needsLayout();
  148. }
  149. void ControlButton::setSelected(bool enabled)
  150. {
  151. Control::setSelected(enabled);
  152. needsLayout();
  153. }
  154. void ControlButton::setHighlighted(bool enabled)
  155. {
  156. if (enabled == true)
  157. {
  158. _state = Control::State::HIGH_LIGHTED;
  159. }
  160. else
  161. {
  162. _state = Control::State::NORMAL;
  163. }
  164. Control::setHighlighted(enabled);
  165. Action *action = getActionByTag(kZoomActionTag);
  166. if (action)
  167. {
  168. stopAction(action);
  169. }
  170. needsLayout();
  171. if( _zoomOnTouchDown )
  172. {
  173. float scaleValue = (isHighlighted() && isEnabled() && !isSelected()) ? _scaleRatio : 1.0f;
  174. Action *zoomAction = ScaleTo::create(0.05f, scaleValue);
  175. zoomAction->setTag(kZoomActionTag);
  176. runAction(zoomAction);
  177. }
  178. }
  179. void ControlButton::setZoomOnTouchDown(bool zoomOnTouchDown)
  180. {
  181. _zoomOnTouchDown = zoomOnTouchDown;
  182. }
  183. bool ControlButton::getZoomOnTouchDown() const
  184. {
  185. return _zoomOnTouchDown;
  186. }
  187. void ControlButton::setPreferredSize(const Size& size)
  188. {
  189. if(size.width == 0 && size.height == 0)
  190. {
  191. _doesAdjustBackgroundImage = true;
  192. }
  193. else
  194. {
  195. _doesAdjustBackgroundImage = false;
  196. for (auto iter = _backgroundSpriteDispatchTable.begin(); iter != _backgroundSpriteDispatchTable.end(); ++iter)
  197. {
  198. iter->second->setPreferredSize(size);
  199. }
  200. }
  201. _preferredSize = size;
  202. needsLayout();
  203. }
  204. const Size& ControlButton::getPreferredSize() const
  205. {
  206. return _preferredSize;
  207. }
  208. void ControlButton::setAdjustBackgroundImage(bool adjustBackgroundImage)
  209. {
  210. _doesAdjustBackgroundImage=adjustBackgroundImage;
  211. needsLayout();
  212. }
  213. bool ControlButton::doesAdjustBackgroundImage()
  214. {
  215. return _doesAdjustBackgroundImage;
  216. }
  217. const Vec2& ControlButton::getLabelAnchorPoint() const
  218. {
  219. return this->_labelAnchorPoint;
  220. }
  221. void ControlButton::setLabelAnchorPoint(const Vec2& labelAnchorPoint)
  222. {
  223. this->_labelAnchorPoint = labelAnchorPoint;
  224. if (_titleLabel != nullptr)
  225. {
  226. this->_titleLabel->setAnchorPoint(labelAnchorPoint);
  227. }
  228. }
  229. std::string ControlButton::getTitleForState(State state)
  230. {
  231. auto iter = _titleDispatchTable.find((int)state);
  232. if (iter != _titleDispatchTable.end())
  233. {
  234. return iter->second;
  235. }
  236. iter = _titleDispatchTable.find((int)Control::State::NORMAL);
  237. return iter != _titleDispatchTable.end() ? iter->second : "";
  238. }
  239. void ControlButton::setTitleForState(const std::string& title, State state)
  240. {
  241. _titleDispatchTable.erase((int)state);
  242. if (!title.empty())
  243. {
  244. _titleDispatchTable[(int)state] = title;
  245. }
  246. // If the current state if equal to the given state we update the layout
  247. if (getState() == state)
  248. {
  249. needsLayout();
  250. }
  251. }
  252. Color3B ControlButton::getTitleColorForState(State state) const
  253. {
  254. Color3B returnColor = Color3B::WHITE;
  255. auto iter = _titleColorDispatchTable.find((int)state);
  256. if (iter != _titleColorDispatchTable.end())
  257. {
  258. returnColor = iter->second;
  259. }
  260. else
  261. {
  262. iter = _titleColorDispatchTable.find((int)Control::State::NORMAL);
  263. if (iter != _titleColorDispatchTable.end())
  264. {
  265. returnColor = iter->second;
  266. }
  267. }
  268. return returnColor;
  269. }
  270. void ControlButton::setTitleColorForState(const Color3B& color, State state)
  271. {
  272. _titleColorDispatchTable.erase((int)state);
  273. _titleColorDispatchTable[(int)state] = color;
  274. // If the current state if equal to the given state we update the layout
  275. if (getState() == state)
  276. {
  277. needsLayout();
  278. }
  279. }
  280. Node* ControlButton::getTitleLabelForState(State state)
  281. {
  282. Node* titleLabel = _titleLabelDispatchTable.at((int)state);
  283. if (titleLabel)
  284. {
  285. return titleLabel;
  286. }
  287. return _titleLabelDispatchTable.at((int)Control::State::NORMAL);
  288. }
  289. void ControlButton::setTitleLabelForState(Node* titleLabel, State state)
  290. {
  291. Node* previousLabel = _titleLabelDispatchTable.at((int)state);
  292. if (previousLabel)
  293. {
  294. removeChild(previousLabel, true);
  295. _titleLabelDispatchTable.erase((int)state);
  296. }
  297. _titleLabelDispatchTable.insert((int)state, titleLabel);
  298. titleLabel->setVisible(false);
  299. titleLabel->setAnchorPoint(Vec2(0.5f, 0.5f));
  300. addChild(titleLabel, 1);
  301. // If the current state if equal to the given state we update the layout
  302. if (getState() == state)
  303. {
  304. needsLayout();
  305. }
  306. }
  307. void ControlButton::setTitleTTFForState(const std::string& fontName, State state)
  308. {
  309. this->setTitleLabelForState(Label::createWithSystemFont(getTitleForState(state), fontName, 12), state);
  310. }
  311. const std::string& ControlButton::getTitleTTFForState(State state)
  312. {
  313. LabelProtocol* label = dynamic_cast<LabelProtocol*>(this->getTitleLabelForState(state));
  314. Label* labelTTF = dynamic_cast<Label*>(label);
  315. if(labelTTF != 0)
  316. {
  317. return labelTTF->getSystemFontName();
  318. }
  319. static std::string ret("");
  320. return ret;
  321. }
  322. void ControlButton::setTitleTTFSizeForState(float size, State state)
  323. {
  324. LabelProtocol* label = dynamic_cast<LabelProtocol*>(this->getTitleLabelForState(state));
  325. if(label)
  326. {
  327. Label* labelTTF = dynamic_cast<Label*>(label);
  328. if(labelTTF != 0)
  329. {
  330. return labelTTF->setSystemFontSize(size);
  331. }
  332. }
  333. }
  334. float ControlButton::getTitleTTFSizeForState(State state)
  335. {
  336. LabelProtocol* label = dynamic_cast<LabelProtocol*>(this->getTitleLabelForState(state));
  337. Label* labelTTF = dynamic_cast<Label*>(label);
  338. if(labelTTF != 0)
  339. {
  340. return labelTTF->getSystemFontSize();
  341. }
  342. else
  343. {
  344. return 0;
  345. }
  346. }
  347. void ControlButton::setTitleBMFontForState(const std::string& fntFile, State state)
  348. {
  349. std::string title = this->getTitleForState(state);
  350. this->setTitleLabelForState(Label::createWithBMFont(fntFile, title), state);
  351. }
  352. const std::string& ControlButton::getTitleBMFontForState(State state)
  353. {
  354. LabelProtocol* label = dynamic_cast<LabelProtocol*>(this->getTitleLabelForState(state));
  355. auto labelBMFont = dynamic_cast<Label*>(label);
  356. if(labelBMFont != 0)
  357. {
  358. return labelBMFont->getBMFontFilePath();
  359. }
  360. static std::string ret("");
  361. return ret;
  362. }
  363. ui::Scale9Sprite* ControlButton::getBackgroundSpriteForState(State state)
  364. {
  365. auto backgroundSprite = _backgroundSpriteDispatchTable.at((int)state);
  366. if (backgroundSprite)
  367. {
  368. return backgroundSprite;
  369. }
  370. return _backgroundSpriteDispatchTable.at((int)Control::State::NORMAL);
  371. }
  372. void ControlButton::setBackgroundSpriteForState(ui::Scale9Sprite* sprite, State state)
  373. {
  374. Size oldPreferredSize = _preferredSize;
  375. auto previousBackgroundSprite = _backgroundSpriteDispatchTable.at((int)state);
  376. if (previousBackgroundSprite)
  377. {
  378. removeChild(previousBackgroundSprite, true);
  379. _backgroundSpriteDispatchTable.erase((int)state);
  380. }
  381. _backgroundSpriteDispatchTable.insert((int)state, sprite);
  382. sprite->setVisible(false);
  383. sprite->setAnchorPoint(Vec2(0.5f, 0.5f));
  384. addChild(sprite);
  385. if (this->_preferredSize.width != 0 || this->_preferredSize.height != 0)
  386. {
  387. if (oldPreferredSize.equals(_preferredSize))
  388. {
  389. // Force update of preferred size
  390. sprite->setPreferredSize(Size(oldPreferredSize.width+1, oldPreferredSize.height+1));
  391. }
  392. sprite->setPreferredSize(this->_preferredSize);
  393. }
  394. // If the current state if equal to the given state we update the layout
  395. if (getState() == state)
  396. {
  397. needsLayout();
  398. }
  399. }
  400. void ControlButton::setBackgroundSpriteFrameForState(SpriteFrame * spriteFrame, State state)
  401. {
  402. ui::Scale9Sprite * sprite = ui::Scale9Sprite::createWithSpriteFrame(spriteFrame);
  403. this->setBackgroundSpriteForState(sprite, state);
  404. }
  405. void ControlButton::needsLayout()
  406. {
  407. if (!_parentInited) {
  408. return;
  409. }
  410. // Hide the background and the label
  411. if (_titleLabel != nullptr) {
  412. _titleLabel->setVisible(false);
  413. }
  414. if (_backgroundSprite) {
  415. _backgroundSprite->setVisible(false);
  416. }
  417. // Update anchor of all labels
  418. this->setLabelAnchorPoint(this->_labelAnchorPoint);
  419. // Update the label to match with the current state
  420. _currentTitle = getTitleForState(_state);
  421. _currentTitleColor = getTitleColorForState(_state);
  422. this->setTitleLabel(getTitleLabelForState(_state));
  423. LabelProtocol* label = dynamic_cast<LabelProtocol*>(_titleLabel);
  424. if (label && !_currentTitle.empty())
  425. {
  426. label->setString(_currentTitle);
  427. }
  428. if (_titleLabel)
  429. {
  430. _titleLabel->setColor(_currentTitleColor);
  431. }
  432. if (_titleLabel != nullptr)
  433. {
  434. _titleLabel->setPosition(getContentSize().width / 2, getContentSize().height / 2);
  435. }
  436. // Update the background sprite
  437. this->setBackgroundSprite(this->getBackgroundSpriteForState(_state));
  438. if (_backgroundSprite != nullptr)
  439. {
  440. _backgroundSprite->setPosition(getContentSize().width / 2, getContentSize().height / 2);
  441. }
  442. // Get the title label size
  443. Size titleLabelSize;
  444. if (_titleLabel != nullptr)
  445. {
  446. titleLabelSize = _titleLabel->getBoundingBox().size;
  447. }
  448. // Adjust the background image if necessary
  449. if (_doesAdjustBackgroundImage)
  450. {
  451. // Add the margins
  452. if (_backgroundSprite != nullptr)
  453. {
  454. _backgroundSprite->setContentSize(Size(titleLabelSize.width + _marginH * 2, titleLabelSize.height + _marginV * 2));
  455. }
  456. }
  457. else
  458. {
  459. //TODO: should this also have margins if one of the preferred sizes is relaxed?
  460. if (_backgroundSprite != nullptr)
  461. {
  462. Size preferredSize = _backgroundSprite->getPreferredSize();
  463. if (preferredSize.width <= 0)
  464. {
  465. preferredSize.width = titleLabelSize.width;
  466. }
  467. if (preferredSize.height <= 0)
  468. {
  469. preferredSize.height = titleLabelSize.height;
  470. }
  471. _backgroundSprite->setContentSize(preferredSize);
  472. }
  473. }
  474. // Set the content size
  475. Rect rectTitle;
  476. if (_titleLabel != nullptr)
  477. {
  478. rectTitle = _titleLabel->getBoundingBox();
  479. }
  480. Rect rectBackground;
  481. if (_backgroundSprite != nullptr)
  482. {
  483. rectBackground = _backgroundSprite->getBoundingBox();
  484. }
  485. Rect maxRect = ControlUtils::RectUnion(rectTitle, rectBackground);
  486. setContentSize(Size(maxRect.size.width, maxRect.size.height));
  487. if (_titleLabel != nullptr)
  488. {
  489. _titleLabel->setPosition(getContentSize().width/2, getContentSize().height/2);
  490. // Make visible the background and the label
  491. _titleLabel->setVisible(true);
  492. }
  493. if (_backgroundSprite != nullptr)
  494. {
  495. _backgroundSprite->setPosition(getContentSize().width/2, getContentSize().height/2);
  496. _backgroundSprite->setVisible(true);
  497. }
  498. }
  499. bool ControlButton::onTouchBegan(Touch *pTouch, Event* /*pEvent*/)
  500. {
  501. if (!isTouchInside(pTouch) || !isEnabled() || !isVisible() || !hasVisibleParents() )
  502. {
  503. return false;
  504. }
  505. for (Node *c = this->_parent; c != nullptr; c = c->getParent())
  506. {
  507. if (c->isVisible() == false)
  508. {
  509. return false;
  510. }
  511. }
  512. _isPushed = true;
  513. this->setHighlighted(true);
  514. sendActionsForControlEvents(Control::EventType::TOUCH_DOWN);
  515. return true;
  516. }
  517. void ControlButton::onTouchMoved(Touch *pTouch, Event* /*pEvent*/)
  518. {
  519. if (!isEnabled() || !isPushed() || isSelected())
  520. {
  521. if (isHighlighted())
  522. {
  523. setHighlighted(false);
  524. }
  525. return;
  526. }
  527. bool isTouchMoveInside = isTouchInside(pTouch);
  528. if (isTouchMoveInside && !isHighlighted())
  529. {
  530. setHighlighted(true);
  531. sendActionsForControlEvents(Control::EventType::DRAG_ENTER);
  532. }
  533. else if (isTouchMoveInside && isHighlighted())
  534. {
  535. sendActionsForControlEvents(Control::EventType::DRAG_INSIDE);
  536. }
  537. else if (!isTouchMoveInside && isHighlighted())
  538. {
  539. setHighlighted(false);
  540. sendActionsForControlEvents(Control::EventType::DRAG_EXIT);
  541. }
  542. else if (!isTouchMoveInside && !isHighlighted())
  543. {
  544. sendActionsForControlEvents(Control::EventType::DRAG_OUTSIDE);
  545. }
  546. }
  547. void ControlButton::onTouchEnded(Touch *pTouch, Event* /*pEvent*/)
  548. {
  549. _isPushed = false;
  550. setHighlighted(false);
  551. if (isTouchInside(pTouch))
  552. {
  553. sendActionsForControlEvents(Control::EventType::TOUCH_UP_INSIDE);
  554. }
  555. else
  556. {
  557. sendActionsForControlEvents(Control::EventType::TOUCH_UP_OUTSIDE);
  558. }
  559. }
  560. void ControlButton::setOpacity(GLubyte opacity)
  561. {
  562. Control::setOpacity(opacity);
  563. for (auto iter = _backgroundSpriteDispatchTable.begin(); iter != _backgroundSpriteDispatchTable.end(); ++iter)
  564. {
  565. iter->second->setOpacity(opacity);
  566. }
  567. for (auto iter = _titleLabelDispatchTable.begin(); iter != _titleLabelDispatchTable.end(); ++iter)
  568. {
  569. iter->second->setOpacity(opacity);
  570. }
  571. }
  572. void ControlButton::updateDisplayedOpacity(GLubyte parentOpacity)
  573. {
  574. Control::updateDisplayedOpacity(parentOpacity);
  575. for (auto iter = _backgroundSpriteDispatchTable.begin(); iter != _backgroundSpriteDispatchTable.end(); ++iter)
  576. {
  577. iter->second->updateDisplayedOpacity(parentOpacity);
  578. }
  579. for (auto iter = _titleLabelDispatchTable.begin(); iter != _titleLabelDispatchTable.end(); ++iter)
  580. {
  581. iter->second->updateDisplayedOpacity(parentOpacity);
  582. }
  583. }
  584. void ControlButton::setColor(const Color3B & color)
  585. {
  586. Control::setColor(color);
  587. for (auto iter = _backgroundSpriteDispatchTable.begin(); iter != _backgroundSpriteDispatchTable.end(); ++iter)
  588. {
  589. iter->second->setColor(color);
  590. }
  591. for (auto iter = _titleLabelDispatchTable.begin(); iter != _titleLabelDispatchTable.end(); ++iter)
  592. {
  593. iter->second->setColor(color);
  594. }
  595. }
  596. void ControlButton::updateDisplayedColor(const Color3B& parentColor)
  597. {
  598. Control::updateDisplayedColor(parentColor);
  599. for (auto iter = _backgroundSpriteDispatchTable.begin(); iter != _backgroundSpriteDispatchTable.end(); ++iter)
  600. {
  601. iter->second->updateDisplayedColor(parentColor);
  602. }
  603. for (auto iter = _titleLabelDispatchTable.begin(); iter != _titleLabelDispatchTable.end(); ++iter)
  604. {
  605. iter->second->updateDisplayedColor(parentColor);
  606. }
  607. }
  608. void ControlButton::onTouchCancelled(Touch* /*pTouch*/, Event* /*pEvent*/)
  609. {
  610. _isPushed = false;
  611. setHighlighted(false);
  612. sendActionsForControlEvents(Control::EventType::TOUCH_CANCEL);
  613. }
  614. ControlButton* ControlButton::create()
  615. {
  616. ControlButton *pControlButton = new (std::nothrow) ControlButton();
  617. if (pControlButton && pControlButton->init())
  618. {
  619. pControlButton->autorelease();
  620. return pControlButton;
  621. }
  622. CC_SAFE_DELETE(pControlButton);
  623. return nullptr;
  624. }
  625. NS_CC_EXT_END