1. 简介
control为其子类提供了touch回调函数,当子类触发EventType相关事件时,会调用相关的回调函数。
control对象接收到的事件类型分9类:
- enum class CC_EX_DLL EventType
- {
- TOUCH_DOWN = 1 << 0,
- DRAG_INSIDE = 1 << 1,
- DRAG_OUTSIDE = 1 << 2,
- DRAG_ENTER = 1 << 3,
- DRAG_EXIT = 1 << 4,
- TOUCH_UP_INSIDE = 1 << 5,
- TOUCH_UP_OUTSIDE = 1 << 6,
- TOUCH_CANCEL = 1 << 7,
- VALUE_CHANGED = 1 << 8
- };
用二进制的不同位表示单一的事件类型,说明这些类型可以同时发生。我们用或运算对多个单一事件进行拼接,形成综合的事件。判断事件类型时,对二进制按位与运算检测,得出综合事件包含了哪些单一事件。
control所处的状态分为4种:
- enum class State
- {
- NORMAL = 1 << 0,
- HIGH_LIGHTED = 1 << 1,
- DISABLED = 1 << 2,
- SELECTED = 1 << 3
- };
std::unordered_map<int, Vector<Invocation*>*> _dispatchTable
该哈希表key为EventType的二进制int,value为容器Vector,里面存储了相同EventType的Invocation。
构造函数中未被create修改的变量:
- _hasVisibleParents(false)
- _isOpacityModifyRGB(false)
- _state(State::NORMAL)
2. Invocation
Invocation直接继承Ref,为control而生,存储了control对象在某种EventType下执行的函数action。
create(Ref* target, Control::Handler action, Control::EventType controlEvent)
create方法调用了其构造函数,将三个参数赋给Invocation的_target _action _controlEvent。
3. 成员方法
- Control* create()
create方法调用了父类Layer的init方法,setContentSize为屏幕大小。之后调用init方法,_state设为NORMAL,_enabled为true,_selected _highlighted为false,定义了单点触摸监听器和4种回调函数,并将监听器加到事件分发器进行管理。
control是否启用(enabled),control是否被选中(Selected),control是否高亮(Highlighted)有对应的set get方法:
- virtual void setEnabled(bool bEnabled); //_enabled 会同步修改_state为NORMAL或DISABLED
- virtual bool isEnabled() const;
- virtual void setSelected(bool bSelected); //_selected
- virtual bool isSelected() const;
- virtual void setHighlighted(bool bHighlighted); //_highlighted
- virtual bool isHighlighted() const;
三个set方法结束前都要执行needsLayout(),具体方法是由子类实现。
- Vector<Invocation*>& dispatchListforControlEvent(EventType controlEvent)
简要的说,该方法是通过参数EventType找到所有同EventType的Invocation。
该方法通过参数EventType,即control接收到的触摸类型,在_dispatchTable中根据EventType获取到Vector<Invocation*>*,将该Vector返回。如果没有EventType对应的Vector,则新建Vector,并在_dispatchTable新建项。
- void removeTargetWithActionForControlEvent(Ref* target, Handler action, EventType controlEvent)
简要的说,该方法删除符合参数要求的Invocation,从而删除三者之间的关联关系。
1. 先调用dispatchListforControlEvent,根据EventType获取Vector<Invocation*>。当参数target和action都为空时,对Vector执行clear清空。
2. 接下来,对Vector进行遍历,遍历到的每个Invocation通过参数target和action判断是否符合要求,如果符合要求,加入到容器vector tobeRemovedInvocations。
3. 遍历结束,从Vector中删除tobeRemovedInvocations里的每个Invocation。
- void removeTargetWithActionForControlEvents(Ref* target, Handler action, EventType controlEvents)
kControlEventTotalNumber是EventType类型的数量,Control头文件里定义为9。
1. 对controlEvents的二进制值分别通过9种EventType的二进制值按位与检测,得出“Events”包含了哪些“Event”。
2. 存在的每个EventType作为参数,调用了上面的removeTargetWithActionForControlEvent方法。
- void addTargetWithActionForControlEvent(Ref* target, Handler action, EventType controlEvent)
简要的说,该方法是新建了一个Invocation并存储。
该方法通过三个参数create一个Invocation,再调用dispatchListforControlEvent,通过参数EventType获取Vector<Invocation*>,再把Invocation加到Vector里。
- void addTargetWithActionForControlEvents(Ref* target, Handler action, EventType controlEvents)
通过按位与检测controlEvents包含的EventType, 对每种EventType和参数target action调用addTargetWithActionForControlEvent新建Invocation。
- Vec2 getTouchLocation(Touch* touch) 返回触摸点相对control的坐标。
- bool isTouchInside(Touch* touch) 判断Touch是否在control范围。
- bool hasVisibleParents()
当control的所有父节点都可见,返回true,存在不可见的父节点时返回false。
- void sendActionsForControlEvents(EventType controlEvents)
对controlEvents的每种EventType获得invocation,调用invocation->invoke(this)。