1
2
3
4
5
6
7
8
9
10
11
12
|
//
add a "close" icon to exit the progress. it's an autorelease object var closeItem
= cc.MenuItemImage.create( "res/CloseNormal.png" , "res/CloseSelected.png" , function ()
{ cc.log( "close
button was clicked." ); }, this ); closeItem.setAnchorPoint(cc.p(0.5,
0.5)); var menu
= cc.Menu.create(closeItem); menu.setPosition(cc.p(0,
0)); this .addChild(menu,
1); closeItem.setPosition(cc.p(size.width
- 20, 20)); |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
//
"create" in JS //
cc.MenuItemImage.create( normalImage, selectedImage, [disabledImage], callback_fn, [this] JSBool
js_cocos2dx_CCMenuItemImage_create(JSContext *cx, uint32_t argc, jsval *vp) { if (argc
>= 2 && argc <= 5) { jsval
*argv = JS_ARGV(cx, vp); JSStringWrapper
arg0(argv[0]); JSStringWrapper
arg1(argv[1]); JSStringWrapper
arg2; bool thirdArgIsString
= true ; jsval
jsCallback = JSVAL_VOID; jsval
jsThis = JSVAL_VOID; int last
= 2; if (argc
>= 3) { thirdArgIsString
= argv[2].isString(); if (thirdArgIsString)
{ arg2.set(argv[2],
cx); last
= 3; } } cocos2d::MenuItemImage*
ret = cocos2d::MenuItemImage::create(arg0.get(), arg1.get(), std::string(arg2.get())); if (argc
>= 3) { if (!thirdArgIsString)
{ //cc.MenuItemImage.create(
normalImage, selectedImage, callback_fn, [this] ) jsCallback
= argv[last++]; if (argc
== 4) { jsThis
= argv[last]; } } else { //cc.MenuItemImage.create(
normalImage, selectedImage, disabledImage, callback_fn, [this] ) if (argc
>= 4) { jsCallback
= argv[last++]; if (argc
== 5) { jsThis
= argv[last]; } } } } JSObject
*obj = bind_menu_item<cocos2d::MenuItemImage>(cx, ret, jsCallback, jsThis); JS_SET_RVAL(cx,
vp, OBJECT_TO_JSVAL(obj)); return JS_TRUE; } JS_ReportError(cx, "Invalid
number of arguments. Expecting: 2 <= args <= 5" ); return JS_FALSE; } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
if (argc
>= 3) { if (!thirdArgIsString)
{ //cc.MenuItemImage.create(
normalImage, selectedImage, callback_fn, [this] ) jsCallback
= argv[last++]; if (argc
== 4) { jsThis
= argv[last]; } } else { //cc.MenuItemImage.create(
normalImage, selectedImage, disabledImage, callback_fn, [this] ) if (argc
>= 4) { jsCallback
= argv[last++]; if (argc
== 5) { jsThis
= argv[last]; } } } } |
1
|
JSObject
*obj = bind_menu_item<cocos2d::MenuItemImage>(cx, ret, jsCallback, jsThis); |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
template < class T> JSObject*
bind_menu_item(JSContext *cx, T* nativeObj, jsval callback, jsval thisObj) { js_proxy_t
*p = jsb_get_native_proxy(nativeObj); if (p)
{ addCallBackAndThis(p->obj,
callback, thisObj); return p->obj; } else { js_type_class_t
*classType = js_get_type_from_native<T>(nativeObj); assert (classType); JSObject
*tmp = JS_NewObject(cx, classType->jsclass, classType->proto, classType->parentProto); //
bind nativeObj <-> JSObject js_proxy_t
*proxy = jsb_new_proxy(nativeObj, tmp); JS_AddNamedObjectRoot(cx,
&proxy->obj, typeid (*nativeObj).name()); addCallBackAndThis(tmp,
callback, thisObj); return tmp; } } |
1
2
3
4
5
6
7
8
9
|
static
void addCallBackAndThis(JSObject *obj, jsval callback, jsval &thisObj) { if (callback
!= JSVAL_VOID) { ScriptingCore::getInstance()->setReservedSpot(0,
obj, callback); } if (thisObj
!= JSVAL_VOID) { ScriptingCore::getInstance()->setReservedSpot(1,
obj, thisObj); } } |
1
2
3
4
|
JSBool
ScriptingCore::setReservedSpot(uint32_t i, JSObject *obj, jsval value) { JS_SetReservedSlot(obj,
i, value); return JS_TRUE; } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
void MenuItem::activate() { if (_enabled) { if (
_callback ) { _callback( this ); } if (kScriptTypeNone
!= _scriptType) { BasicScriptData
data( this ); ScriptEvent
scriptEvent(kMenuClickedEvent,&data); ScriptEngineManager::getInstance()->getScriptEngine()->sendEvent(&scriptEvent); } } } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
int
ScriptingCore::sendEvent(ScriptEvent* evt) { if (NULL
== evt) return 0; JSAutoCompartment
ac(_cx, _global); switch (evt->type) { case kNodeEvent: { return handleNodeEvent(evt->data); } break ; case kMenuClickedEvent: { return handleMenuClickedEvent(evt->data); } break ; case kTouchEvent: { return handleTouchEvent(evt->data); } break ; case kTouchesEvent: { return handleTouchesEvent(evt->data); } break ; case kKeypadEvent: { return handleKeypadEvent(evt->data); } break ; case kAccelerometerEvent: { return handleAccelerometerEvent(evt->data); } break ; default : break ; } return 0; } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
int
ScriptingCore::handleMenuClickedEvent(void* data) { if (NULL
== data) return 0; BasicScriptData*
basicScriptData = static_cast<BasicScriptData*>(data); if (NULL
== basicScriptData->nativeObject) return 0; MenuItem*
menuItem = static_cast<MenuItem*>(basicScriptData->nativeObject); js_proxy_t
* p = jsb_get_native_proxy(menuItem); if (!p) return 0; jsval
retval; jsval
dataVal; js_proxy_t
*proxy = jsb_get_native_proxy(menuItem); dataVal
= (proxy ? OBJECT_TO_JSVAL(proxy->obj) : JSVAL_NULL); executeJSFunctionFromReservedSpot( this ->_cx,
p->obj, dataVal, retval); return 1; } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
static void executeJSFunctionFromReservedSpot(JSContext
*cx, JSObject *obj, jsval
&dataVal, jsval &retval) { jsval
func = JS_GetReservedSlot(obj, 0); if (func
== JSVAL_VOID) { return ;
} jsval
thisObj = JS_GetReservedSlot(obj, 1); JSAutoCompartment
ac(cx, obj); if (thisObj
== JSVAL_VOID) { JS_CallFunctionValue(cx,
obj, func, 1, &dataVal, &retval); } else { assert (!JSVAL_IS_PRIMITIVE(thisObj)); JS_CallFunctionValue(cx,
JSVAL_TO_OBJECT(thisObj), func, 1, &dataVal, &retval); } } |