Helper Macros To Custom Manage Touch Priority

2012-10-10 00:00:00 +0000

Why

touch priority is not same as view depth,manage touch priority in cocos2dx is more difficult.So,here comes an idea ,in every panel use macros to define the touch priority,and container define touch priory of this panel recursively,finally you will have only one touch entrance,each touch event will pass to this children to handle it in predefined priority.

Code

#define CUSTOM_TOUCH_PRIORITY_INIT(_removeChildTouch) \
   __customTouchPriorityInit(_removeChildTouch)
#define CUSTOM_TOUCH_PRIORITY_BEGIN(_priority) \
   CCTouchDelegate *__currentTouchItem;bool __isChildTouchBegin; \
   std::vector<CCTouchDelegate*> __customTouchChildren; \
   virtual void registerWithTouchDispatcher(){ \
       CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, _priority, true);\
   } \
   virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent){ \
       if (!this->isVisible()){return false;} \
       for (CCNode *c = this->m_pParent; c != NULL; c = c->getParent()) \
       if (c->isVisible() == false){return false;} \
       if (__isChildTouchBegin){return false;} \
       std::vector<CCTouchDelegate*>::iterator itr = __customTouchChildren.begin();\
       while (itr!=__customTouchChildren.end()){ \
           if ((*itr)->ccTouchBegan(pTouch,pEvent)){ \
               __currentTouchItem = *itr; \
               __isChildTouchBegin = true; \
               break; \
           } \
           ++itr; \
       } \
       return true; \
   } \
   void __customTouchPriorityInit(bool removeChildTouch){ \
       __currentTouchItem = NULL;__isChildTouchBegin = false;
#define CUSTOM_TOUCH_PRIORITY_ITEM(_item) \
   __customTouchChildren.push_back(_item)
#define CUSTOM_TOUCH_PRIORITY_END() \
   setTouchEnabled(true); \
   if(removeChildTouch){ \
       std::vector<CCTouchDelegate*>::iterator itr = __customTouchChildren.begin(); \
       while(itr!=__customTouchChildren.end()) \
       {((CCLayer*)(*itr))->setTouchEnabled(false);++itr;}} \
   } \
   virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent) \
   { \
       if (__isChildTouchBegin) \
           __currentTouchItem->ccTouchMoved(pTouch, pEvent); \
   } \
   \
   virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent) \
   { \
       if (__isChildTouchBegin) \
       { \
           __currentTouchItem->ccTouchEnded(pTouch, pEvent); \
           __isChildTouchBegin = false; \
       } \
   } \
   \
   virtual void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent) \
   { \
       if (__isChildTouchBegin) \
       { \
           __currentTouchItem->ccTouchCancelled(pTouch, pEvent); \
           __isChildTouchBegin = false; \
       } \
   }

How to use

create a CustomTouchPriority.h copy macros above into it,and include in your class file.

//in class header file add these lines
public:

CUSTOM_TOUCH_PRIORITY_BEGIN(TOUCH_PRIORITY_MODAL_PANEL);//give a very low priory here TOUCH_PRIORITY_MODAL_PANEL = -99999999
CUSTOM_TOUCH_PRIORITY_ITEM(scrollView);//first priority
CUSTOM_TOUCH_PRIORITY_ITEM(menu);//second etc..
CUSTOM_TOUCH_PRIORITY_END();
//in implements file add this line in init function to make it work
CUSTOM_TOUCH_PRIORITY_INIT(true);//true will set children touch = false,so the touch event is managed.

when this panel is non visible remember to setTouchEnabled(false)

Setlocale In Ios Aka Swprintf In Ios Error Eilseq

2012-10-03 00:00:00 +0000

when work with swprintf (or wchar functions),you probably want set locale to en_US.UTF-8,but in ios there is no en_US.UTF-8 locale,this is what you should to

How

  • copy en_US.UTF-8 to your ios project resource path,and add to project
sudo copy -r /usr/share/locale/en_US.UTF-8/ your_ios_resource_path/en_US.UTF-8/
  • set locale in AppController applicationDidFinishLaunchingWithOptions
NSString* resources = [ [ NSBundle mainBundle ] resourcePath ];
setenv("PATH_LOCALE", [resources cStringUsingEncoding:1], 1);
setlocale( LC_CTYPE, "en_US.UTF-8" );
  • when format string use %ls instead

Make Ccscrollview Work With Ccmenuitemimage

2012-09-25 00:00:00 +0000

Why

CCScrollView has a lower priority to handle touch event,if there is a CCMenuItemImage the touch event is handled by CCMenuItemImage and never goes to CCScrollView

How

  • Create a new class called CCScrollViewEx extends CCScrollView
  • set a higher priority of handling touch event
  • detect click event and simulate a click event to others
  • disable ccmenu click outside view rect

Code CCScrollViewEx

//header

class CCScrollViewEx : public CCScrollView
{
public:
    virtual bool init();
    virtual void registerWithTouchDispatcher();
    virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
    virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
    void setMenuContent(CCMenu *menu){menuContent = menu;}
    CREATE_FUNC(CCScrollViewEx);
protected:
    CCPoint pressPoint;
    CCMenu *menuContent;
};
//implements

bool CCScrollViewEx::init(){
bool bRet = false;
do
{
    CC_BREAK_IF(! CCScrollView::init());
        bRet = true;
    }while(0);
    return bRet;
}

void CCScrollViewEx::registerWithTouchDispatcher()
{
    CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, TOUCH_PRIORITY_POPUP_PANEL, true);
}
bool CCScrollViewEx::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)
{
    pressPoint = pTouch->getLocationInView();
    return CCScrollView::ccTouchBegan(pTouch, pEvent);
}
void CCScrollViewEx::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent)
{
    #define MIN_DISTANCE 10
    CCPoint endPoint = pTouch->getLocationInView();
    float distance = sqrtf((endPoint.x - pressPoint.x) * (endPoint.x - pressPoint.x) + (endPoint.y - pressPoint.y) * (endPoint.y - pressPoint.y));

    if(distance < MIN_DISTANCE)
    {
        if (menuContent)
        {
            bool start = menuContent->ccTouchBegan(pTouch, pEvent);//simulate a click
            if (start)
                menuContent->ccTouchEnded(pTouch, pEvent);
        }
    }
    CCScrollView::ccTouchEnded(pTouch, pEvent);
}
//code CCMenuEx

//create a subclass to handle touch outside the scrollView rect
bool CCMenuEx::ccTouchBegan(CCTouch *touch, CCEvent *event)
{
    if (validTouchRectInWorldSpace.size.width && validTouchRectInWorldSpace.size.height)//we have restriction
    {
        CCPoint touchLocation = touch->getLocation();
        if (!validTouchRectInWorldSpace.containsPoint(touchLocation))
            return false;
    }
    return CCMenu::ccTouchBegan(touch, event);
}

remember to call setMenuContent of CCScrollViewEx and set validTouchRectInWorldSpace of CCMenuEx.

« Prev 1 2 3 4 5 6 Next »