第一次看CCControl

Control中有九种可能的事件,定义在.h文件中,另外还定义四种状态,用来表示控件高亮等。
在初始化控件的时候:

bool Control::init()
{
    if (Layer::init())
    {
        // Initialise instance variables
        //初始化控件的状态
        _state=Control::State::NORMAL;
        //开启控件
        setEnabled(true);
        //不选中
        setSelected(false);
        //不高亮
        setHighlighted(false);
//获取分发器
        auto dispatcher = Director::getInstance()->getEventDispatcher();
        //创建单点触摸监听器
        auto touchListener = EventListenerTouchOneByOne::create();
        //设置触摸吞没,触摸控件时,控件下的其它东西不会接触到触摸事件
        touchListener->setSwallowTouches(true);
		//创建触摸不同阶段的回调函数
        touchListener->onTouchBegan = CC_CALLBACK_2(Control::onTouchBegan, this);
        touchListener->onTouchMoved = CC_CALLBACK_2(Control::onTouchMoved, this);
        touchListener->onTouchEnded = CC_CALLBACK_2(Control::onTouchEnded, this);
        touchListener->onTouchCancelled = CC_CALLBACK_2(Control::onTouchCancelled, this);
        //添加场景图优先级的触摸监听器,也就是说优先级为0
        dispatcher->addEventListenerWithSceneGraphPriority(touchListener, this);
        
        return true;
    }
    else
    {
        return false;
    }
}

添加场景图优先级的触摸监听器

void EventDispatcher::addEventListenerWithSceneGraphPriority(EventListener* listener, Node* node)
{
    CCASSERT(listener && node, "Invalid parameters.");
    CCASSERT(!listener->isRegistered(), "The listener has been registered.");
    
    if (!listener->checkAvailable())
        return;
    //设置监听器的节点参数
    listener->setAssociatedNode(node);
    //设置优先级
    listener->setFixedPriority(0);
    //设置为注册
    listener->setRegistered(true);
    //添加给存储监听器的全局数组添加元素
    addEventListener(listener);
}

添加事件监听器到全局数组中

void EventDispatcher::addEventListener(EventListener* listener)
{
    if (_inDispatch == 0)
    {
    	//直接添加
        forceAddEventListener(listener);
    }
    else
    {
    	//正在使用,延时添加
        _toAddedListeners.push_back(listener);
    }
#if CC_ENABLE_GC_FOR_NATIVE_OBJECTS
    auto sEngine = ScriptEngineManager::getInstance()->getScriptEngine();
    if (sEngine)
    {
        sEngine->retainScriptObject(this, listener);
    }
#endif // CC_ENABLE_GC_FOR_NATIVE_OBJECTS
    listener->retain();
}

直接添加

void EventDispatcher::forceAddEventListener(EventListener* listener)
{
    EventListenerVector* listeners = nullptr;
    //通过listener获取ID
    EventListener::ListenerID listenerID = listener->getListenerID();
    //通过ID查找是否在存储所有listener的map中,这个map是用来存储监听器ID和监听器数组的
    auto itr = _listenerMap.find(listenerID);
    //如果没找到
    if (itr == _listenerMap.end())
    {
        //新建一个监听器数组类型
        listeners = new (std::nothrow) EventListenerVector();
        //和对应的ID一起加入map中
        _listenerMap.emplace(listenerID, listeners);
    }
    else
    {
    	//如果找到了就获取它的second,即存储listener的数组
        listeners = itr->second;
    }
    //添加到对应ID的listeners中
    listeners->push_back(listener);
    //如果优先级是0
    if (listener->getFixedPriority() == 0)
    {
    	//设置场景图的优先级
        setDirty(listenerID, DirtyFlag::SCENE_GRAPH_PRIORITY);
        //获取关联节点
        auto node = listener->getAssociatedNode();
        CCASSERT(node != nullptr, "Invalid scene graph priority!");
        //将节点和监听器放入_nodeListenersMap中
        associateNodeAndEventListener(node, listener);
        
        if (!node->isRunning())
        {
            listener->setPaused(true);
        }
    }
    else
    {
        setDirty(listenerID, DirtyFlag::FIXED_PRIORITY);
    }
}

要注意的地方是,fixedPriority事件是不绑定节点的。
setDirty看的还不是很明白,后补。

posted @ 2019-10-17 23:59  软不隆咚的二更  阅读(149)  评论(0编辑  收藏  举报