Example #1
0
void CCScene::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent)
{
    if (!m_touchDispatchingEnabled) return;

    // cleanup
    m_touchingTargets->removeAllObjects();

    // sort touchable nodes
    sortAllTouchableNodes(m_touchableNodes);

    // find touching target
    bool isTouchable = true;
    CCObject *obj = NULL;
    CCNode *node = NULL;
    CCNode *checkTouchableNode = NULL;
    CCTouchTargetNode *touchTarget = NULL;

    CCARRAY_FOREACH(m_touchableNodes, obj)
    {
        checkTouchableNode = node = dynamic_cast<CCNode*>(obj);

        // check node is visible and capturing enabled
        isTouchable = true;
        do
        {
            isTouchable = isTouchable
                    && checkTouchableNode->isRunning()
                    && checkTouchableNode->isVisible()
                    && checkTouchableNode->isTouchCaptureEnabled();
            checkTouchableNode = checkTouchableNode->getParent();
        } while (checkTouchableNode && isTouchable);
        if (!isTouchable) continue;

        // prepare for touch testing
        touchTarget = NULL;
        const CCRect boundingBox = node->getCascadeBoundingBox();

        // set touch target
        CCTouch *touch = NULL;
        for (CCSetIterator it = pTouches->begin(); it != pTouches->end(); ++it)
        {
            touch = (CCTouch*)*it;
            const CCPoint touchPoint = touch->getLocation();

            if (boundingBox.containsPoint(touchPoint))
            {
                if (!touchTarget)
                {
                    touchTarget = CCTouchTargetNode::create(node);
                }

                if (touchTarget->getTouchMode() == kCCTouchesOneByOne)
                {
                    touchTarget->setTouchId(touch->getID());
                    break;
                }
            }
        }

        if (!touchTarget)
        {
            // touch points not in current target, try to next
            continue;
        }

        // try to dispatching event
        CCArray *path = CCArray::createWithCapacity(10);
        node = touchTarget->getNode();
        do
        {
            path->addObject(node);
            node = node->getParent();
        } while (node != NULL && node != this);

        // phase: capturing
        // from parent to child
        bool dispatchingContinue = true;
        int touchMode = touchTarget->getTouchMode();
        for (int i = path->count() - 1; dispatchingContinue && i >= 0; --i)
        {
            node = dynamic_cast<CCNode*>(path->objectAtIndex(i));
            if (touchMode == kCCTouchesAllAtOnce)
            {
                node->ccTouchesCaptureBegan(pTouches, touchTarget->getNode());
            }
            else
            {
                dispatchingContinue = node->ccTouchCaptureBegan(touchTarget->findTouch(pTouches), touchTarget->getNode());
            }
        }

        if (!dispatchingContinue)
        {
            // the target stop dispatching, try to next
            continue;
        }

        // phase: targeting
        node = touchTarget->getNode();
        bool ret = true;
        if (touchMode == kCCTouchesAllAtOnce)
        {
            node->ccTouchesBegan(pTouches, pEvent);
        }
        else
        {
            ret = node->ccTouchBegan(touchTarget->findTouch(pTouches), pEvent);
        }

        if (ret)
        {
            m_touchingTargets->addObject(touchTarget);
//            CCLOG("ADD TOUCH TARGET [%p]", touchTarget);
        }

        if (node->isTouchSwallowEnabled())
        {
            // target swallow touch event, stop dispatching
            break;
        }

        // continue dispatching, try to next
    }