Element.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638
  1. #include "precompiled.h"
  2. #include "Element.h"
  3. #include <ElementStyle.h>
  4. #include "LuaEventListener.h"
  5. namespace Rocket {
  6. namespace Core {
  7. namespace Lua {
  8. typedef ElementDocument Document;
  9. //methods
  10. int ElementAddEventListener(lua_State* L, Element* obj)
  11. {
  12. int top = lua_gettop(L);
  13. bool capture = false;
  14. //default false if they didn't pass it in
  15. if (top > 3)
  16. capture = CHECK_BOOL(L,3);
  17. const char* event = luaL_checkstring(L,1);
  18. LuaEventListener* listener = NULL;
  19. int type = lua_type(L,2);
  20. if(type == LUA_TFUNCTION)
  21. {
  22. listener = new LuaEventListener(L,2,obj);
  23. }
  24. else if(type == LUA_TSTRING)
  25. {
  26. const char* code = luaL_checkstring(L,2);
  27. listener = new LuaEventListener(code,obj);
  28. }
  29. else
  30. {
  31. Log::Message(Log::LT_WARNING, "Lua Context:AddEventLisener's 2nd argument can only be a Lua function or a string, you passed in a %s", lua_typename(L,type));
  32. }
  33. if(listener != NULL)
  34. {
  35. obj->AddEventListener(event,listener,capture);
  36. }
  37. return 0;
  38. }
  39. int ElementAppendChild(lua_State* L, Element* obj)
  40. {
  41. Element* ele = LuaType<Element>::check(L,1);
  42. obj->AppendChild(ele);
  43. return 0;
  44. }
  45. int ElementBlur(lua_State* L, Element* obj)
  46. {
  47. obj->Blur();
  48. return 0;
  49. }
  50. int ElementClick(lua_State* L, Element* obj)
  51. {
  52. obj->Click();
  53. return 0;
  54. }
  55. int ElementDispatchEvent(lua_State* L, Element* obj)
  56. {
  57. const char* event = luaL_checkstring(L,1);
  58. Dictionary params;
  59. lua_pushnil(L); //becauase lua_next pops a key from the stack first, we don't want to pop the table
  60. while(lua_next(L,2) != 0)
  61. {
  62. //[-1] is value, [-2] is key
  63. int type = lua_type(L,-1);
  64. const char* key = luaL_checkstring(L,-2); //key HAS to be a string, or things will go bad
  65. switch(type)
  66. {
  67. case LUA_TNUMBER:
  68. params.Set(key,(float)lua_tonumber(L,-1));
  69. break;
  70. case LUA_TBOOLEAN:
  71. params.Set(key,CHECK_BOOL(L,-1));
  72. break;
  73. case LUA_TSTRING:
  74. params.Set(key,luaL_checkstring(L,-1));
  75. break;
  76. case LUA_TUSERDATA:
  77. case LUA_TLIGHTUSERDATA:
  78. params.Set(key,lua_touserdata(L,-1));
  79. break;
  80. default:
  81. break;
  82. }
  83. }
  84. obj->DispatchEvent(event,params,false);
  85. return 0;
  86. }
  87. int ElementFocus(lua_State* L, Element* obj)
  88. {
  89. obj->Focus();
  90. return 0;
  91. }
  92. int ElementGetAttribute(lua_State* L, Element* obj)
  93. {
  94. const char* name = luaL_checkstring(L,1);
  95. Variant* var = obj->GetAttribute(name);
  96. Variant::Type type = var->GetType();
  97. switch(type)
  98. {
  99. case Variant::BYTE:
  100. case Variant::CHAR:
  101. case Variant::INT:
  102. lua_pushinteger(L,var->Get<int>());
  103. break;
  104. case Variant::FLOAT:
  105. lua_pushnumber(L,var->Get<float>());
  106. break;
  107. case Variant::COLOURB:
  108. LuaType<Colourb>::push(L,&var->Get<Colourb>(),false);
  109. break;
  110. case Variant::COLOURF:
  111. LuaType<Colourf>::push(L,&var->Get<Colourf>(),false);
  112. break;
  113. case Variant::STRING:
  114. lua_pushstring(L,var->Get<String>().CString());
  115. break;
  116. case Variant::VECTOR2:
  117. //according to Variant.inl, it is going to be a Vector2f
  118. LuaType<Vector2f>::push(L,&var->Get<Vector2f>(),false);
  119. break;
  120. case Variant::VOIDPTR:
  121. lua_pushlightuserdata(L,var->Get<void*>());
  122. break;
  123. default:
  124. lua_pushnil(L);
  125. break;
  126. }
  127. return 1;
  128. }
  129. int ElementGetElementById(lua_State* L, Element* obj)
  130. {
  131. const char* id = luaL_checkstring(L,1);
  132. Element* ele = obj->GetElementById(id);
  133. LuaType<Element>::push(L,ele,false);
  134. return 1;
  135. }
  136. int ElementGetElementsByTagName(lua_State* L, Element* obj)
  137. {
  138. const char* tag = luaL_checkstring(L,1);
  139. ElementList list;
  140. obj->GetElementsByTagName(list,tag);
  141. lua_newtable(L);
  142. for(unsigned int i = 0; i < list.size(); i++)
  143. {
  144. lua_pushinteger(L,i);
  145. LuaType<Element>::push(L,list[i],false);
  146. lua_settable(L,-3); //-3 is the table
  147. }
  148. return 1;
  149. }
  150. int ElementHasAttribute(lua_State* L, Element* obj)
  151. {
  152. const char* name = luaL_checkstring(L,1);
  153. lua_pushboolean(L,obj->HasAttribute(name));
  154. return 1;
  155. }
  156. int ElementHasChildNodes(lua_State* L, Element* obj)
  157. {
  158. lua_pushboolean(L,obj->HasChildNodes());
  159. return 1;
  160. }
  161. int ElementInsertBefore(lua_State* L, Element* obj)
  162. {
  163. Element* element = LuaType<Element>::check(L,1);
  164. Element* adjacent = LuaType<Element>::check(L,2);
  165. obj->InsertBefore(element,adjacent);
  166. return 0;
  167. }
  168. int ElementIsClassSet(lua_State* L, Element* obj)
  169. {
  170. const char* name = luaL_checkstring(L,1);
  171. lua_pushboolean(L,obj->IsClassSet(name));
  172. return 1;
  173. }
  174. int ElementRemoveAttribute(lua_State* L, Element* obj)
  175. {
  176. const char* name = luaL_checkstring(L,1);
  177. obj->RemoveAttribute(name);
  178. return 0;
  179. }
  180. int ElementRemoveChild(lua_State* L, Element* obj)
  181. {
  182. Element* element = LuaType<Element>::check(L,1);
  183. lua_pushboolean(L,obj->RemoveChild(element));
  184. return 1;
  185. }
  186. int ElementReplaceChild(lua_State* L, Element* obj)
  187. {
  188. Element* inserted = LuaType<Element>::check(L,1);
  189. Element* replaced = LuaType<Element>::check(L,2);
  190. lua_pushboolean(L,obj->ReplaceChild(inserted,replaced));
  191. return 1;
  192. }
  193. int ElementScrollIntoView(lua_State* L, Element* obj)
  194. {
  195. bool align = CHECK_BOOL(L,1);
  196. obj->ScrollIntoView(align);
  197. return 0;
  198. }
  199. int ElementSetAttribute(lua_State* L, Element* obj)
  200. {
  201. const char* name = luaL_checkstring(L,1);
  202. const char* value = luaL_checkstring(L,2);
  203. obj->SetAttribute(name,String(value));
  204. return 0;
  205. }
  206. int ElementSetClass(lua_State* L, Element* obj)
  207. {
  208. const char* name = luaL_checkstring(L,1);
  209. bool value = CHECK_BOOL(L,2);
  210. obj->SetClass(name,value);
  211. return 0;
  212. }
  213. //getters
  214. int ElementGetAttrattributes(lua_State* L)
  215. {
  216. Element* ele = LuaType<Element>::check(L,1);
  217. LUACHECKOBJ(ele);
  218. int index;
  219. String key;
  220. Variant* var;
  221. Variant::Type type;
  222. lua_newtable(L);
  223. while(ele->IterateAttributes(index,key,var))
  224. {
  225. lua_pushstring(L,key.CString());
  226. type = var->GetType();
  227. switch(type)
  228. {
  229. case Variant::BYTE:
  230. case Variant::CHAR:
  231. case Variant::INT:
  232. lua_pushinteger(L,*(int*)var);
  233. break;
  234. case Variant::FLOAT:
  235. lua_pushnumber(L,*(float*)var);
  236. break;
  237. case Variant::COLOURB:
  238. LuaType<Colourb>::push(L,(Colourb*)var,false);
  239. break;
  240. case Variant::COLOURF:
  241. LuaType<Colourf>::push(L,(Colourf*)var,false);
  242. break;
  243. case Variant::STRING:
  244. lua_pushstring(L,((String*)var)->CString());
  245. break;
  246. case Variant::VECTOR2:
  247. //according to Variant.inl, it is going to be a Vector2f
  248. LuaType<Vector2f>::push(L,((Vector2f*)var),false);
  249. break;
  250. case Variant::VOIDPTR:
  251. lua_pushlightuserdata(L,(void*)var);
  252. break;
  253. default:
  254. lua_pushnil(L);
  255. break;
  256. }
  257. lua_settable(L,-3);
  258. }
  259. return 1;
  260. }
  261. int ElementGetAttrchild_nodes(lua_State* L)
  262. {
  263. Element* ele = LuaType<Element>::check(L,1);
  264. LUACHECKOBJ(ele);
  265. if(!ele->HasChildNodes())
  266. lua_pushnil(L);
  267. else
  268. {
  269. lua_newtable(L);
  270. int index = 0;
  271. int num_of_children = ele->GetNumChildren();
  272. while(index < num_of_children)
  273. {
  274. lua_pushinteger(L,index);
  275. LuaType<Element>::push(L,ele->GetChild(index),false);
  276. lua_settable(L,-3);
  277. ++index;
  278. }
  279. }
  280. return 1;
  281. }
  282. int ElementGetAttrclass_name(lua_State* L)
  283. {
  284. Element* ele = LuaType<Element>::check(L,1);
  285. LUACHECKOBJ(ele);
  286. const char* classnames = ele->GetClassNames().CString();
  287. lua_pushstring(L,classnames);
  288. return 1;
  289. }
  290. int ElementGetAttrclient_left(lua_State* L)
  291. {
  292. Element* ele = LuaType<Element>::check(L,1);
  293. LUACHECKOBJ(ele);
  294. lua_pushnumber(L,ele->GetClientLeft());
  295. return 1;
  296. }
  297. int ElementGetAttrclient_height(lua_State* L)
  298. {
  299. Element* ele = LuaType<Element>::check(L,1);
  300. LUACHECKOBJ(ele);
  301. lua_pushnumber(L,ele->GetClientHeight());
  302. return 1;
  303. }
  304. int ElementGetAttrclient_top(lua_State* L)
  305. {
  306. Element* ele = LuaType<Element>::check(L,1);
  307. LUACHECKOBJ(ele);
  308. lua_pushnumber(L,ele->GetClientTop());
  309. return 1;
  310. }
  311. int ElementGetAttrclient_width(lua_State* L)
  312. {
  313. Element* ele = LuaType<Element>::check(L,1);
  314. LUACHECKOBJ(ele);
  315. lua_pushnumber(L,ele->GetClientWidth());
  316. return 1;
  317. }
  318. int ElementGetAttrfirst_child(lua_State* L)
  319. {
  320. Element* ele = LuaType<Element>::check(L,1);
  321. LUACHECKOBJ(ele);
  322. Element* child = ele->GetFirstChild();
  323. if(child == NULL)
  324. lua_pushnil(L);
  325. else
  326. LuaType<Element>::push(L,child,false);
  327. return 1;
  328. }
  329. int ElementGetAttrid(lua_State* L)
  330. {
  331. Element* ele = LuaType<Element>::check(L,1);
  332. LUACHECKOBJ(ele);
  333. lua_pushstring(L,ele->GetId().CString());
  334. return 1;
  335. }
  336. int ElementGetAttrinner_rml(lua_State* L)
  337. {
  338. Element* ele = LuaType<Element>::check(L,1);
  339. LUACHECKOBJ(ele);
  340. lua_pushstring(L,ele->GetInnerRML().CString());
  341. return 1;
  342. }
  343. int ElementGetAttrlast_child(lua_State* L)
  344. {
  345. Element* ele = LuaType<Element>::check(L,1);
  346. LUACHECKOBJ(ele);
  347. Element* child = ele->GetLastChild();
  348. if(child == NULL)
  349. lua_pushnil(L);
  350. else
  351. LuaType<Element>::push(L,child,false);
  352. return 1;
  353. }
  354. int ElementGetAttrnext_sibling(lua_State* L)
  355. {
  356. Element* ele = LuaType<Element>::check(L,1);
  357. LUACHECKOBJ(ele);
  358. Element* sibling = ele->GetNextSibling();
  359. if(sibling == NULL)
  360. lua_pushnil(L);
  361. else
  362. LuaType<Element>::push(L,sibling,false);
  363. return 1;
  364. }
  365. int ElementGetAttroffset_height(lua_State* L)
  366. {
  367. Element* ele = LuaType<Element>::check(L,1);
  368. LUACHECKOBJ(ele);
  369. lua_pushnumber(L,ele->GetOffsetHeight());
  370. return 1;
  371. }
  372. int ElementGetAttroffset_left(lua_State* L)
  373. {
  374. Element* ele = LuaType<Element>::check(L,1);
  375. LUACHECKOBJ(ele);
  376. lua_pushnumber(L,ele->GetOffsetLeft());
  377. return 1;
  378. }
  379. int ElementGetAttroffset_parent(lua_State* L)
  380. {
  381. Element* ele = LuaType<Element>::check(L,1);
  382. LUACHECKOBJ(ele);
  383. Element* parent = ele->GetOffsetParent();
  384. LuaType<Element>::push(L,parent,false);
  385. return 1;
  386. }
  387. int ElementGetAttroffset_top(lua_State* L)
  388. {
  389. Element* ele = LuaType<Element>::check(L,1);
  390. LUACHECKOBJ(ele);
  391. lua_pushnumber(L, ele->GetOffsetTop());
  392. return 1;
  393. }
  394. int ElementGetAttroffset_width(lua_State* L)
  395. {
  396. Element* ele = LuaType<Element>::check(L,1);
  397. LUACHECKOBJ(ele);
  398. lua_pushnumber(L,ele->GetOffsetWidth());
  399. return 1;
  400. }
  401. int ElementGetAttrowner_document(lua_State* L)
  402. {
  403. Element* ele = LuaType<Element>::check(L,1);
  404. LUACHECKOBJ(ele);
  405. Document* doc = ele->GetOwnerDocument();
  406. LuaType<Document>::push(L,doc,false);
  407. return 1;
  408. }
  409. int ElementGetAttrparent_node(lua_State* L)
  410. {
  411. Element* ele = LuaType<Element>::check(L,1);
  412. Element* parent = ele->GetParentNode();
  413. if(parent == NULL)
  414. lua_pushnil(L);
  415. else
  416. LuaType<Element>::push(L,parent,false);
  417. return 1;
  418. }
  419. int ElementGetAttrprevious_sibling(lua_State* L)
  420. {
  421. Element* ele = LuaType<Element>::check(L,1);
  422. Element* sibling = ele->GetPreviousSibling();
  423. if(sibling == NULL)
  424. lua_pushnil(L);
  425. else
  426. LuaType<Element>::push(L,sibling,false);
  427. return 1;
  428. }
  429. int ElementGetAttrscroll_height(lua_State* L)
  430. {
  431. Element* ele = LuaType<Element>::check(L,1);
  432. lua_pushnumber(L,ele->GetScrollHeight());
  433. return 1;
  434. }
  435. int ElementGetAttrscroll_left(lua_State* L)
  436. {
  437. Element* ele = LuaType<Element>::check(L,1);
  438. lua_pushnumber(L,ele->GetScrollLeft());
  439. return 1;
  440. }
  441. int ElementGetAttrscroll_top(lua_State* L)
  442. {
  443. Element* ele = LuaType<Element>::check(L,1);
  444. lua_pushnumber(L,ele->GetScrollTop());
  445. return 1;
  446. }
  447. int ElementGetAttrscroll_width(lua_State* L)
  448. {
  449. Element* ele = LuaType<Element>::check(L,1);
  450. lua_pushnumber(L,ele->GetScrollWidth());
  451. return 1;
  452. }
  453. int ElementGetAttrstyle(lua_State* L)
  454. {
  455. Element* ele = LuaType<Element>::check(L,1);
  456. LuaType<ElementStyle>::push(L,ele->GetStyle(),false);
  457. return 1;
  458. }
  459. int ElementGetAttrtag_name(lua_State* L)
  460. {
  461. Element* ele = LuaType<Element>::check(L,1);
  462. lua_pushstring(L,ele->GetTagName().CString());
  463. return 0;
  464. }
  465. //setters
  466. int ElementSetAttrclass_name(lua_State* L)
  467. {
  468. Element* ele = LuaType<Element>::check(L,1);
  469. const char* name = luaL_checkstring(L,2);
  470. ele->SetClassNames(name);
  471. return 0;
  472. }
  473. int ElementSetAttrid(lua_State* L)
  474. {
  475. Element* ele = LuaType<Element>::check(L,1);
  476. const char* id = luaL_checkstring(L,2);
  477. ele->SetId(id);
  478. return 0;
  479. }
  480. int ElementSetAttrinner_rml(lua_State* L)
  481. {
  482. Element* ele = LuaType<Element>::check(L,1);
  483. const char* rml = luaL_checkstring(L,2);
  484. ele->SetInnerRML(rml);
  485. return 0;
  486. }
  487. int ElementSetAttrscroll_left(lua_State* L)
  488. {
  489. Element* ele = LuaType<Element>::check(L,1);
  490. float scroll = (float)luaL_checknumber(L,2);
  491. ele->SetScrollLeft(scroll);
  492. return 0;
  493. }
  494. int ElementSetAttrscroll_top(lua_State* L)
  495. {
  496. Element* ele = LuaType<Element>::check(L,1);
  497. float scroll = (float)luaL_checknumber(L,2);
  498. ele->SetScrollTop(scroll);
  499. return 0;
  500. }
  501. RegType<Element> ElementMethods[] =
  502. {
  503. LUAMETHOD(Element,AddEventListener)
  504. LUAMETHOD(Element,AppendChild)
  505. LUAMETHOD(Element,Blur)
  506. LUAMETHOD(Element,Click)
  507. LUAMETHOD(Element,DispatchEvent)
  508. LUAMETHOD(Element,Focus)
  509. LUAMETHOD(Element,GetAttribute)
  510. LUAMETHOD(Element,GetElementById)
  511. LUAMETHOD(Element,GetElementsByTagName)
  512. LUAMETHOD(Element,HasAttribute)
  513. LUAMETHOD(Element,HasChildNodes)
  514. LUAMETHOD(Element,InsertBefore)
  515. LUAMETHOD(Element,IsClassSet)
  516. LUAMETHOD(Element,RemoveAttribute)
  517. LUAMETHOD(Element,RemoveChild)
  518. LUAMETHOD(Element,ReplaceChild)
  519. LUAMETHOD(Element,ScrollIntoView)
  520. LUAMETHOD(Element,SetAttribute)
  521. LUAMETHOD(Element,SetClass)
  522. { NULL, NULL },
  523. };
  524. luaL_reg ElementGetters[] =
  525. {
  526. LUAGETTER(Element,attributes)
  527. LUAGETTER(Element,child_nodes)
  528. LUAGETTER(Element,class_name)
  529. LUAGETTER(Element,client_left)
  530. LUAGETTER(Element,client_height)
  531. LUAGETTER(Element,client_top)
  532. LUAGETTER(Element,client_width)
  533. LUAGETTER(Element,first_child)
  534. LUAGETTER(Element,id)
  535. LUAGETTER(Element,inner_rml)
  536. LUAGETTER(Element,last_child)
  537. LUAGETTER(Element,next_sibling)
  538. LUAGETTER(Element,offset_height)
  539. LUAGETTER(Element,offset_left)
  540. LUAGETTER(Element,offset_parent)
  541. LUAGETTER(Element,offset_top)
  542. LUAGETTER(Element,offset_width)
  543. LUAGETTER(Element,owner_document)
  544. LUAGETTER(Element,parent_node)
  545. LUAGETTER(Element,previous_sibling)
  546. LUAGETTER(Element,scroll_height)
  547. LUAGETTER(Element,scroll_left)
  548. LUAGETTER(Element,scroll_top)
  549. LUAGETTER(Element,scroll_width)
  550. LUAGETTER(Element,style)
  551. LUAGETTER(Element,tag_name)
  552. { NULL, NULL },
  553. };
  554. luaL_reg ElementSetters[] =
  555. {
  556. LUASETTER(Element,class_name)
  557. LUASETTER(Element,id)
  558. LUASETTER(Element,inner_rml)
  559. LUASETTER(Element,scroll_left)
  560. LUASETTER(Element,scroll_top)
  561. { NULL, NULL },
  562. };
  563. /*
  564. template<> const char* GetTClassName<Element>() { return "Element"; }
  565. template<> RegType<Element>* GetMethodTable<Element>() { return ElementMethods; }
  566. template<> luaL_reg* GetAttrTable<Element>() { return ElementGetters; }
  567. template<> luaL_reg* SetAttrTable<Element>() { return ElementSetters; }
  568. */
  569. }
  570. }
  571. }