Cocostudio中TouchGroup类

TouchGroupj继承自CCLayer,重写了CCTouchDelegate的四个方法

virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent);

cocostudio编辑器中的控件都是继承自Widget,这些控件都被添加到TouchGroup层中。所有的控件事件的接收都是依靠TouchGroup传递。

bool TouchGroup::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)
{
    return checkEventWidget(pTouch, pEvent);
}
bool TouchGroup::checkEventWidget(CCTouch* touch, CCEvent *pEvent)
{
    checkTouchEvent(m_pRootWidget,touch, pEvent);
    return (m_pSelectedWidgets->count() > 0);
}
bool TouchGroup::checkTouchEvent(Widget *root, CCTouch* touch, CCEvent* pEvent)
{
    ccArray* arrayRootChildren = root->getChildren()->data;
    int length = arrayRootChildren->num;
    for (int i=length-1; i >= 0; i--)
    {
        Widget* widget = (Widget*)(arrayRootChildren->arr[i]);
        if (checkTouchEvent(widget, touch, pEvent))
        {
            return true;
        }
    }
    bool pass = root->onTouchBegan(touch, pEvent);
    if (root->_hitted)
    {
        m_pSelectedWidgets->addObject(root);
        return true;
    }
    return pass;
}

其中ccTouchBegan方法调用了checkEventWidget,checkEventWidget调用了checkTouchEvent。 checkTouchEvent是一个递归函数。会递归检查TouchGroup中m_pRootWidget的子节点。m_pRootWidget继承自Widget,代表当前父控件,所有子控件加在它之上。
这里有一点值得要提的是往TouchGroup里加控件不要用addChild,要用addWidget,因为触摸事件检查的节点是m_pRootWidget为根的树,所有直接加到TouchGroup中是接收不到触摸事件的。
void TouchGroup::addWidget(Widget* widget)
{
    m_pRootWidget->addChild(widget);
}
当控件没有子节点,会调用Widget父函数中的onTouchBegan方法,检查控件的Enable,TouchEnable和hitTest。 所以Cocostudio的控件隐藏用setEnbale(false),不要用setVisible(false).setVisible只是不渲染,但是还是 会接收到事件的,setEnbale的话在渲染和事件的接收都会做判断的。
bool Widget::onTouchBegan(CCTouch *touch, CCEvent *unused_event)
{
    _hitted = false;
    if (isEnabled() && isTouchEnabled())
    {
        _touchStartPos = touch->getLocation();
        if(hitTest(_touchStartPos) && clippingParentAreaContainPoint(_touchStartPos))
        {
            _hitted = true;
        }
    }
    if (!_hitted)
    {
        return false;
    }
    setFocused(true);
    Widget* widgetParent = getWidgetParent();
    if (widgetParent)
    {
        widgetParent->checkChildInfo(0,this,_touchStartPos);
    }
    pushDownEvent();
    return !_touchPassedEnabled;
}

void Widget::setEnabled(bool enabled)
{
    _enabled = enabled;
    if(_widgetChildren && _widgetChildren->count() > 0)
    {
        CCObject* child;
        CCARRAY_FOREACH(_widgetChildren, child)
        {
            ((Widget*)child)->setEnabled(enabled);
        }
    }
}

这其中还有一个机制,就是当一个控件接收到事件之后,会先传递给父节点处理. 其中checkChildInfo是个虚函数.控件可以重写这个方法,来接收处理子节点穿过来的事件。
  virtual void checkChildInfo(int handleState,Widget* sender,const CCPoint &touchPoint);
其中handleState的值0为begin.1为move,2为end,3为cancel。 这个方法,一般的控件是没有重写的,也就是继续往父节点传,而不做处理。
只有ScrollView,PageView重写这个函数。







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值