/extensions/GUI/CCControlExtension/CCControl.cpp

https://bitbucket.org/Tsiannian/cocos2d-x · C++ · 331 lines · 209 code · 41 blank · 81 comment · 18 complexity · e33ec114e82b447e175a9cfc2ff75401 MD5 · raw file

  1. /*
  2. * CCControl.m
  3. *
  4. * Copyright 2011 Yannick Loriot.
  5. * http://yannickloriot.com
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a copy
  8. * of this software and associated documentation files (the "Software"), to deal
  9. * in the Software without restriction, including without limitation the rights
  10. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. * copies of the Software, and to permit persons to whom the Software is
  12. * furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in
  15. * all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23. * THE SOFTWARE.
  24. *
  25. *
  26. * converted to c++ / cocos2d-x by Angus C
  27. */
  28. #include "CCControl.h"
  29. #include "CCDirector.h"
  30. #include "touch_dispatcher/CCTouchDispatcher.h"
  31. #include "menu_nodes/CCMenu.h"
  32. #include "touch_dispatcher/CCTouch.h"
  33. NS_CC_EXT_BEGIN
  34. CCControl::CCControl()
  35. {
  36. }
  37. bool CCControl::init()
  38. {
  39. if (CCLayer::init())
  40. {
  41. //this->setTouchEnabled(true);
  42. //m_bIsTouchEnabled=true;
  43. // Initialise instance variables
  44. m_nState=CCControlStateNormal;
  45. m_bEnabled=true;
  46. m_bSelected=false;
  47. m_bHighlighted=false;
  48. // Set the touch dispatcher priority by default to 1
  49. m_nDefaultTouchPriority = 1;
  50. this->setDefaultTouchPriority(m_nDefaultTouchPriority);
  51. // Initialise the tables
  52. dispatchTable=new CCDictionary();
  53. //dispatchTable->autorelease();
  54. // dispatchTable_ = [[NSMutableDictionary alloc] initWithCapacity:1];
  55. return true;
  56. }
  57. else
  58. return false;
  59. }
  60. CCControl::~CCControl()
  61. {
  62. CC_SAFE_RELEASE(dispatchTable);
  63. }
  64. //Menu - Events
  65. void CCControl::registerWithTouchDispatcher()
  66. {
  67. CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, kCCMenuHandlerPriority, true);
  68. }
  69. void CCControl::onEnter()
  70. {
  71. //CCTouchDispatcher::sharedDispatcher()->addTargetedDelegate(this, m_nDefaultTouchPriority, true);
  72. CCLayer::onEnter();
  73. }
  74. void CCControl::onExit()
  75. {
  76. //CCTouchDispatcher::sharedDispatcher()->removeDelegate(this);
  77. CCLayer::onExit();
  78. }
  79. void CCControl::sendActionsForControlEvents(CCControlEvent controlEvents)
  80. {
  81. // For each control events
  82. for (int i = 0; i < CONTROL_EVENT_TOTAL_NUMBER; i++)
  83. {
  84. // If the given controlEvents bitmask contains the curent event
  85. if ((controlEvents & (1 << i)))
  86. {
  87. // Call invocations
  88. // <CCInvocation*>
  89. CCArray* invocationList=CCControl::dispatchListforControlEvent(1<<i);
  90. CCObject* pObj = NULL;
  91. CCARRAY_FOREACH(invocationList, pObj)
  92. {
  93. CCInvocation* invocation = (CCInvocation*)pObj;
  94. invocation->invoke(this);
  95. }
  96. }
  97. }
  98. }
  99. void CCControl::addTargetWithActionForControlEvents(CCObject* target, SEL_CCControlHandler action, CCControlEvent controlEvents)
  100. {
  101. // For each control events
  102. for (int i = 0; i < CONTROL_EVENT_TOTAL_NUMBER; i++)
  103. {
  104. // If the given controlEvents bitmask contains the curent event
  105. if ((controlEvents & (1 << i)))
  106. {
  107. CCControl::addTargetWithActionForControlEvent(target, action, 1<<i);
  108. }
  109. }
  110. }
  111. /**
  112. * Adds a target and action for a particular event to an internal dispatch
  113. * table.
  114. * The action message may optionnaly include the sender and the event as
  115. * parameters, in that order.
  116. * When you call this method, target is not retained.
  117. *
  118. * @param target The target object?hat is, the object to which the action
  119. * message is sent. It cannot be nil. The target is not retained.
  120. * @param action A selector identifying an action message. It cannot be NULL.
  121. * @param controlEvent A control event for which the action message is sent.
  122. * See "CCControlEvent" for constants.
  123. */
  124. void CCControl::addTargetWithActionForControlEvent(CCObject* target, SEL_CCControlHandler action, CCControlEvent controlEvent)
  125. {
  126. // Create the invocation object
  127. CCInvocation *invocation=new CCInvocation(target, action, controlEvent);
  128. invocation->autorelease();
  129. // Add the invocation into the dispatch list for the given control event
  130. CCArray* eventInvocationList = dispatchListforControlEvent(controlEvent);
  131. eventInvocationList->addObject(invocation);
  132. }
  133. void CCControl::removeTargetWithActionForControlEvents(CCObject* target, SEL_CCControlHandler action, CCControlEvent controlEvents)
  134. {
  135. // For each control events
  136. for (int i = 0; i < CONTROL_EVENT_TOTAL_NUMBER; i++)
  137. {
  138. // If the given controlEvents bitmask contains the curent event
  139. if ((controlEvents & (1 << i)))
  140. {
  141. removeTargetWithActionForControlEvent(target, action, 1 << i);
  142. }
  143. }
  144. }
  145. /**
  146. * Removes a target and action for a particular event from an internal dispatch
  147. * table.
  148. *
  149. * @param target The target object?hat is, the object to which the action
  150. * message is sent. Pass nil to remove all targets paired with action and the
  151. * specified control events.
  152. * @param action A selector identifying an action message. Pass NULL to remove
  153. * all action messages paired with target.
  154. * @param controlEvent A control event for which the action message is sent.
  155. * See "CCControlEvent" for constants.
  156. */
  157. void CCControl::removeTargetWithActionForControlEvent(CCObject* target, SEL_CCControlHandler action, CCControlEvent controlEvent)
  158. {
  159. // Retrieve all invocations for the given control event
  160. //<CCInvocation*>
  161. CCArray *eventInvocationList=dispatchListforControlEvent(controlEvent);
  162. //remove all invocations if the target and action are null
  163. //TODO: should the invocations be deleted, or just removed from the array? Won't that cause issues if you add a single invocation for multiple events?
  164. bool bDeleteObjects=true;
  165. if (!target && !action)
  166. {
  167. //remove objects
  168. eventInvocationList->removeAllObjects();
  169. }
  170. else
  171. {
  172. //normally we would use a predicate, but this won't work here. Have to do it manually
  173. CCObject* pObj = NULL;
  174. CCARRAY_FOREACH(eventInvocationList, pObj)
  175. {
  176. CCInvocation *invocation = (CCInvocation*)pObj;
  177. bool shouldBeRemoved=true;
  178. if (target)
  179. shouldBeRemoved=(target==invocation->getTarget());
  180. if (action)
  181. shouldBeRemoved=(shouldBeRemoved && (action==invocation->getAction()));
  182. // Remove the corresponding invocation object
  183. if (shouldBeRemoved)
  184. eventInvocationList->removeObject(invocation, bDeleteObjects);
  185. }
  186. }
  187. }
  188. //CRGBA protocol
  189. void CCControl::setColor(const ccColor3B& color)
  190. {
  191. m_tColor=color;
  192. CCObject* child;
  193. CCArray* children=getChildren();
  194. CCARRAY_FOREACH(children, child)
  195. {
  196. CCRGBAProtocol* pNode = dynamic_cast<CCRGBAProtocol*>(child);
  197. if (pNode)
  198. {
  199. pNode->setColor(m_tColor);
  200. }
  201. }
  202. }
  203. const ccColor3B& CCControl::getColor(void)
  204. {
  205. return m_tColor;
  206. }
  207. void CCControl::setOpacity(GLubyte opacity)
  208. {
  209. m_cOpacity = opacity;
  210. CCObject* child;
  211. CCArray* children=getChildren();
  212. CCARRAY_FOREACH(children, child)
  213. {
  214. CCRGBAProtocol* pNode = dynamic_cast<CCRGBAProtocol*>(child);
  215. if (pNode)
  216. {
  217. pNode->setOpacity(opacity);
  218. }
  219. }
  220. }
  221. GLubyte CCControl::getOpacity()
  222. {
  223. return m_cOpacity;
  224. }
  225. void CCControl::setOpacityModifyRGB(bool opacityModifyRGB)
  226. {
  227. m_bIsOpacityModifyRGB=opacityModifyRGB;
  228. CCObject* child;
  229. CCArray* children=getChildren();
  230. CCARRAY_FOREACH(children, child)
  231. {
  232. CCRGBAProtocol* pNode = dynamic_cast<CCRGBAProtocol*>(child);
  233. if (pNode)
  234. {
  235. pNode->setOpacityModifyRGB(opacityModifyRGB);
  236. }
  237. }
  238. }
  239. bool CCControl::isOpacityModifyRGB()
  240. {
  241. return m_bIsOpacityModifyRGB;
  242. }
  243. CCPoint CCControl::getTouchLocation(CCTouch* touch)
  244. {
  245. CCPoint touchLocation = touch->getLocation();; // Get the touch position
  246. touchLocation = this->getParent()->convertToNodeSpace(touchLocation); // Convert to the node space of this class
  247. return touchLocation;
  248. }
  249. bool CCControl::isTouchInside(CCTouch* touch)
  250. {
  251. CCPoint touchLocation=getTouchLocation(touch);
  252. CCRect bBox=boundingBox();
  253. return bBox.containsPoint(touchLocation);
  254. }
  255. CCArray* CCControl::dispatchListforControlEvent(CCControlEvent controlEvent)
  256. {
  257. CCArray* invocationList = (CCArray*)dispatchTable->objectForKey(controlEvent);
  258. // If the invocation list does not exist for the dispatch table, we create it
  259. if (invocationList == NULL)
  260. {
  261. invocationList = CCArray::createWithCapacity(1);
  262. dispatchTable->setObject(invocationList, controlEvent);
  263. }
  264. return invocationList;
  265. }
  266. void CCControl::setEnabled(bool bEnabled)
  267. {
  268. m_bEnabled = bEnabled;
  269. }
  270. bool CCControl::isEnabled()
  271. {
  272. return m_bEnabled;
  273. }
  274. void CCControl::setSelected(bool bSelected)
  275. {
  276. m_bSelected = bSelected;
  277. }
  278. bool CCControl::isSelected()
  279. {
  280. return m_bSelected;
  281. }
  282. void CCControl::setHighlighted(bool bHighlighted)
  283. {
  284. m_bHighlighted = bHighlighted;
  285. }
  286. bool CCControl::isHighlighted()
  287. {
  288. return m_bHighlighted;
  289. }
  290. NS_CC_EXT_END