cross platform gui lib for lua
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

617 lines
18 KiB

  1. /* lui.c
  2. *
  3. * lua binding to libui (https://github.com/andlabs/libui)
  4. *
  5. * Gunnar Zötl <gz@tset.de>, 2016
  6. * Released under MIT/X11 license. See file LICENSE for details.
  7. *
  8. * This file is included by lui.c
  9. */
  10. #ifdef uiAreaHandler
  11. #error "uiAreaHandler() is defined now"
  12. #endif
  13. #define uiAreaHandler(this) ((uiAreaHandler*)(this))
  14. /* area control ***********************************************************/
  15. /*** Object
  16. * Name: area
  17. * a rendering area for graphics or extended text rendering. Note that all
  18. * handlers are currently experiments, their arguments may change.
  19. */
  20. #define LUI_AREA "lui_area"
  21. #define lui_pushArea(L) lui_pushObject(L, LUI_AREA, 1)
  22. #define lui_checkArea(L, pos) ((lui_object*)luaL_checkudata(L, pos, LUI_AREA))
  23. /*** Property
  24. * Object: area
  25. * Name: ondraw
  26. * a function <code>ondraw(area, context, x, y, w, h, areaw, areah)</code> that is
  27. * called when the area needs redrawing. area is the area this handler is
  28. * called for. context is a draw.context object for this area. x, y, w, h are
  29. * the position and size of the rectangle within the area to redraw. areaw,
  30. * areah are the full width and height of the area.
  31. *** Property
  32. * Object: area
  33. * Name: onmouse
  34. * a function <code>onmouse(area, which, button, x, y, count, modifiers, areaw, areah)</code>
  35. * that is called when there is mouse action in the area. which is the type
  36. * of action that occurred, and can be "down", "up", "move", "enter" and "leave".
  37. * The arguments after which are empty for the events "enter" and leave". For
  38. * the other events: button is the number of th button that was pressed. It
  39. * is 0 for the "move" event. x, y is the position within the area, where the
  40. * event occurred. count is a counter for mouse clicks. It can be used to
  41. * determine whether a click is a double click. modifiers are the modifier
  42. * keys. areaw, areah are the full width and height of the area.
  43. *** Property
  44. * Object: area
  45. * Name: onkey
  46. * a function <code>bool onkey(area, key, extkey, modifiers, up)</code>
  47. * that is called when there is a key event for the area. key is the code
  48. * of the key pressed, if it is none of the special keys. extkey is the name
  49. * of the key if it is a special key. modifiers is an or'ed mask of the
  50. * currently active modifiers, the names of which can be found in
  51. * lui.enum.keymod. So, in order to determine of a modifier is active, you
  52. * check for it using for example <code>modifier | lui.enum.keymod.shift</code>.
  53. *** Property_undocumented
  54. * Object: area
  55. * Name: ondragbroken
  56. * a function <code>ondragbroken()</code>
  57. * no idea what this is for
  58. */
  59. static int lui_area__index(lua_State *L)
  60. {
  61. (void) lui_checkArea(L, 1);
  62. const char *what = luaL_checkstring(L, 2);
  63. if (strcmp(what, "ondraw") == 0) {
  64. lui_objectGetHandler(L, "ondraw");
  65. } else if (strcmp(what, "onmouse") == 0) {
  66. lui_objectGetHandler(L, "onmouse");
  67. } else if (strcmp(what, "onkey") == 0) {
  68. lui_objectGetHandler(L, "onkey");
  69. } else if (strcmp(what, "ondragbroken") == 0) {
  70. lui_objectGetHandler(L, "ondragbroken");
  71. } else {
  72. return lui_control__index(L);
  73. }
  74. return 1;
  75. }
  76. static int lui_area__newindex(lua_State *L)
  77. {
  78. (void) lui_checkArea(L, 1);
  79. const char *what = luaL_checkstring(L, 2);
  80. if (strcmp(what, "ondraw") == 0) {
  81. lui_objectSetHandler(L, "ondraw", 3);
  82. } else if (strcmp(what, "onmouse") == 0) {
  83. lui_objectSetHandler(L, "onmouse", 3);
  84. } else if (strcmp(what, "onkey") == 0) {
  85. lui_objectSetHandler(L, "onkey", 3);
  86. } else if (strcmp(what, "ondragbroken") == 0) {
  87. lui_objectSetHandler(L, "ondragbroken", 3);
  88. } else {
  89. return lui_control__newindex(L);
  90. }
  91. return 0;
  92. }
  93. typedef struct {
  94. uiAreaHandler H;
  95. lua_State *L;
  96. } lui_areaHandler;
  97. #define lui_areaHandler(this) ((lui_areaHandler *)(this))
  98. static void lui_areaDrawCallback(uiAreaHandler *ah, uiArea *area, uiAreaDrawParams *params)
  99. {
  100. lua_State *L = lui_areaHandler(ah)->L;
  101. int top = lua_gettop(L);
  102. lui_wrapDrawcontext(L, params->Context);
  103. lua_pushnumber(L, params->ClipX);
  104. lua_pushnumber(L, params->ClipY);
  105. lua_pushnumber(L, params->ClipWidth);
  106. lua_pushnumber(L, params->ClipHeight);
  107. lua_pushnumber(L, params->AreaWidth);
  108. lua_pushnumber(L, params->AreaHeight);
  109. lui_objectHandlerCallback(L, uiControl(area), "ondraw", top + 1, 7, 0);
  110. lua_settop(L, top);
  111. }
  112. static void lui_areaMouseEventCallback(uiAreaHandler *ah, uiArea *area, uiAreaMouseEvent *evt)
  113. {
  114. lua_State *L = lui_areaHandler(ah)->L;
  115. int top = lua_gettop(L);
  116. if (evt->Down) {
  117. lua_pushstring(L, "down");
  118. lua_pushinteger(L, evt->Down);
  119. } else if (evt->Up) {
  120. lua_pushstring(L, "up");
  121. lua_pushinteger(L, evt->Up);
  122. } else {
  123. lua_pushstring(L, "move");
  124. lua_pushinteger(L, 0);
  125. }
  126. lua_pushnumber(L, evt->X);
  127. lua_pushnumber(L, evt->Y);
  128. lua_pushinteger(L, evt->Count);
  129. lua_pushinteger(L, evt->Modifiers);
  130. lua_pushnumber(L, evt->AreaWidth);
  131. lua_pushnumber(L, evt->AreaHeight);
  132. lui_objectHandlerCallback(L, uiControl(area), "onmouse", top + 1, 8, 0);
  133. lua_settop(L, top);
  134. }
  135. static void lui_areaMouseCrossedCallback(uiAreaHandler *ah, uiArea *area, int left)
  136. {
  137. lua_State *L = lui_areaHandler(ah)->L;
  138. int top = lua_gettop(L);
  139. lua_pushstring(L, left ? "leave" : "enter");
  140. lui_objectHandlerCallback(L, uiControl(area), "onmouse", top + 1, 1, 0);
  141. lua_settop(L, top);
  142. }
  143. // what is this for???
  144. static void lui_areaDragBrokenCallback(uiAreaHandler *ah, uiArea *area)
  145. {
  146. lua_State *L = lui_areaHandler(ah)->L;
  147. int top = lua_gettop(L);
  148. lui_objectHandlerCallback(L, uiControl(area), "ondragbroken", top + 1, 0, 0);
  149. lua_settop(L, top);
  150. }
  151. static int lui_areaPushExtKeyName(lua_State *L, int ext, int mod)
  152. {
  153. if (ext) {
  154. lui_aux_pushNameOrValue(L, ext, "lui_enumkeyext");
  155. } else if (mod) {
  156. lui_aux_pushNameOrValue(L, mod, "lui_enumkeymod");
  157. }
  158. return 1;
  159. }
  160. static int lui_areaKeyEventCallback(uiAreaHandler *ah, uiArea *area, uiAreaKeyEvent *evt)
  161. {
  162. lua_State *L = lui_areaHandler(ah)->L;
  163. int top = lua_gettop(L);
  164. if (evt->Key > 0) {
  165. lua_pushinteger(L, evt->Key);
  166. } else {
  167. lua_pushnil(L);
  168. }
  169. if (evt->ExtKey > 0 || evt->Modifier > 0) {
  170. lui_areaPushExtKeyName(L, evt->ExtKey, evt->Modifier);
  171. } else {
  172. lua_pushnil(L);
  173. }
  174. if (evt->Modifiers > 0) {
  175. lua_pushinteger(L, evt->Modifiers);
  176. } else {
  177. lua_pushnil(L);
  178. }
  179. lua_pushboolean(L, evt->Up);
  180. lui_objectHandlerCallback(L, uiControl(area), "onkey", top + 1, 4, 1);
  181. int ok = lua_toboolean(L, -1);
  182. lua_settop(L, top);
  183. return ok;
  184. }
  185. static int lui_makeAreaKeyModifierEnum(lua_State *L)
  186. {
  187. lua_newtable(L);
  188. lui_enumItem("ctrl", uiModifierCtrl);
  189. lui_enumItem("alt", uiModifierAlt);
  190. lui_enumItem("shift", uiModifierShift);
  191. lui_enumItem("super", uiModifierSuper);
  192. return 1;
  193. }
  194. static int lui_makeAreaKeyExtEnum(lua_State *L)
  195. {
  196. lua_newtable(L);
  197. lui_enumItem("escape", uiExtKeyEscape);
  198. lui_enumItem("insert", uiExtKeyInsert);
  199. lui_enumItem("delete", uiExtKeyDelete);
  200. lui_enumItem("home", uiExtKeyHome);
  201. lui_enumItem("end", uiExtKeyEnd);
  202. lui_enumItem("pageup", uiExtKeyPageUp);
  203. lui_enumItem("pagedown", uiExtKeyPageDown);
  204. lui_enumItem("up", uiExtKeyUp);
  205. lui_enumItem("down", uiExtKeyDown);
  206. lui_enumItem("left", uiExtKeyLeft);
  207. lui_enumItem("right", uiExtKeyRight);
  208. lui_enumItem("f1", uiExtKeyF1);
  209. lui_enumItem("f2", uiExtKeyF2);
  210. lui_enumItem("f3", uiExtKeyF3);
  211. lui_enumItem("f4", uiExtKeyF4);
  212. lui_enumItem("f5", uiExtKeyF5);
  213. lui_enumItem("f6", uiExtKeyF6);
  214. lui_enumItem("f7", uiExtKeyF7);
  215. lui_enumItem("f8", uiExtKeyF8);
  216. lui_enumItem("f9", uiExtKeyF9);
  217. lui_enumItem("f10", uiExtKeyF10);
  218. lui_enumItem("f11", uiExtKeyF11);
  219. lui_enumItem("f12", uiExtKeyF12);
  220. lui_enumItem("n0", uiExtKeyN0);
  221. lui_enumItem("n1", uiExtKeyN1);
  222. lui_enumItem("n2", uiExtKeyN2);
  223. lui_enumItem("n3", uiExtKeyN3);
  224. lui_enumItem("n4", uiExtKeyN4);
  225. lui_enumItem("n5", uiExtKeyN5);
  226. lui_enumItem("n6", uiExtKeyN6);
  227. lui_enumItem("n7", uiExtKeyN7);
  228. lui_enumItem("n8", uiExtKeyN8);
  229. lui_enumItem("n9", uiExtKeyN9);
  230. lui_enumItem("ndot", uiExtKeyNDot);
  231. lui_enumItem("nenter", uiExtKeyNEnter);
  232. lui_enumItem("nadd", uiExtKeyNAdd);
  233. lui_enumItem("nsubtract", uiExtKeyNSubtract);
  234. lui_enumItem("nmultiply", uiExtKeyNMultiply);
  235. lui_enumItem("ndivide", uiExtKeyNDivide);
  236. return 1;
  237. };
  238. static int luiMakeWindowEdgeEnum(lua_State *L)
  239. {
  240. lua_newtable(L);
  241. lui_enumItem("left", uiWindowResizeEdgeLeft);
  242. lui_enumItem("top", uiWindowResizeEdgeTop);
  243. lui_enumItem("right", uiWindowResizeEdgeRight);
  244. lui_enumItem("bottom", uiWindowResizeEdgeBottom);
  245. lui_enumItem("topleft", uiWindowResizeEdgeTopLeft);
  246. lui_enumItem("topright", uiWindowResizeEdgeTopRight);
  247. lui_enumItem("bottomleft", uiWindowResizeEdgeBottomLeft);
  248. lui_enumItem("bottomright", uiWindowResizeEdgeBottomRight);
  249. return 1;
  250. }
  251. /* L will be filled when the commonAreaHandler is first used. */
  252. static lui_areaHandler lui_commonAreaHandler = {
  253. .H.Draw = lui_areaDrawCallback,
  254. .H.MouseEvent = lui_areaMouseEventCallback,
  255. .H.MouseCrossed = lui_areaMouseCrossedCallback,
  256. .H.DragBroken = lui_areaDragBrokenCallback,
  257. .H.KeyEvent = lui_areaKeyEventCallback,
  258. .L = 0
  259. };
  260. /*** Method
  261. * Object: area
  262. * Name: setsize
  263. * Signature: area:setsize(width, height)
  264. * change the size of an area.
  265. */
  266. static int lui_areaSetSize(lua_State *L)
  267. {
  268. lui_object *lobj = lui_checkArea(L, 1);
  269. int width = luaL_checkinteger(L, 2);
  270. int height = luaL_checkinteger(L, 3);
  271. uiAreaSetSize(uiArea(lobj->object), width, height);
  272. return 0;
  273. }
  274. /*** Method
  275. * Object: area
  276. * Name: forceredraw
  277. * Signature: area:forceredraw()
  278. * force a redraw of the entire area.
  279. */
  280. static int lui_areaForceRedraw(lua_State *L)
  281. {
  282. lui_object *lobj = lui_checkArea(L, 1);
  283. uiAreaQueueRedrawAll(uiArea(lobj->object));
  284. return 0;
  285. }
  286. /*** Method
  287. * Object: area
  288. * Name: scrollto
  289. * Signature: area:scrollto(x, y, w, h)
  290. * make x, y, w, h the currently visible portion of the area.
  291. */
  292. static int lui_areaScrollTo(lua_State *L)
  293. {
  294. lui_object *lobj = lui_checkArea(L, 1);
  295. double x = luaL_checknumber(L, 2);
  296. double y = luaL_checknumber(L, 3);
  297. double width = luaL_checknumber(L, 4);
  298. double height = luaL_checknumber(L, 5);
  299. uiAreaScrollTo(uiArea(lobj->object), x, y, width, height);
  300. return 0;
  301. }
  302. /*** Method
  303. * Object: area
  304. * Name: beginuserwindowmove
  305. * Signature: area:beginuserwindowmove()
  306. * only usable within mouse events
  307. */
  308. static int lui_areaBeginUserWindowMove(lua_State *L)
  309. {
  310. lui_object *lobj = lui_checkArea(L, 1);
  311. uiAreaBeginUserWindowMove(uiArea(lobj->object));
  312. return 0;
  313. }
  314. /*** Method
  315. * Object: area
  316. * Name: beginuserwindowresize
  317. * Signature: area:beginuserwindowresize(edge)
  318. * only usable within mouse events. An enumeration of the edges can be found
  319. * in lui.enum.edge, or you may enter the name directly.
  320. */
  321. static int lui_areaBeginUserWindowResize(lua_State *L)
  322. {
  323. lui_object *lobj = lui_checkArea(L, 1);
  324. int edge = lui_aux_getNumberOrValue(L, 2, "lui_enumwinedge");
  325. uiAreaBeginUserWindowResize(uiArea(lobj->object), edge);
  326. return 0;
  327. }
  328. /*** Constructor
  329. * Object: area
  330. * Name: area
  331. * Signature: area = lui.area(width = 0, height = 0, properties = nil)
  332. * create a new area. Setting width and height to a value other than 0 makes
  333. * the area a scrolling area.
  334. */
  335. static int lui_newArea(lua_State *L)
  336. {
  337. lui_commonAreaHandler.L = L;
  338. int width = luaL_optinteger(L, 1, 0);
  339. int height = luaL_optinteger(L, 2, 0);
  340. int hastable = lui_aux_istable(L, 3);
  341. lui_object *lobj = lui_pushArea(L);
  342. if (width == 0 && height == 0) {
  343. lobj->object = uiNewArea(uiAreaHandler(&lui_commonAreaHandler));
  344. } else {
  345. lobj->object = uiNewScrollingArea(uiAreaHandler(&lui_commonAreaHandler), width, height);
  346. }
  347. if (hastable) { lui_aux_setFieldsFromTable(L, lua_gettop(L), 3); }
  348. lui_registerObject(L, lua_gettop(L));
  349. return 1;
  350. }
  351. /* metamethods for areas */
  352. static const luaL_Reg lui_area_meta[] = {
  353. {"__index", lui_area__index},
  354. {"__newindex", lui_area__newindex},
  355. {0, 0}
  356. };
  357. /* methods for areas */
  358. static const struct luaL_Reg lui_area_methods [] = {
  359. {"setsize", lui_areaSetSize},
  360. {"forceredraw", lui_areaForceRedraw},
  361. {"scrollto", lui_areaScrollTo},
  362. {"beginuserwindowmove", lui_areaBeginUserWindowMove},
  363. {"beginuserwindowresize", lui_areaBeginUserWindowResize},
  364. {0, 0}
  365. };
  366. /* fontbutton control ****************************************************/
  367. /*** Object
  368. * Name: fontbutton
  369. * a button to open a font selector.
  370. */
  371. #define LUI_FONTBUTTON "lui_fontbutton"
  372. #define lui_pushFontbutton(L) lui_pushObject(L, LUI_FONTBUTTON, 1)
  373. #define lui_checkFontbutton(L, pos) ((lui_object*)luaL_checkudata(L, pos, LUI_FONTBUTTON))
  374. /*** Property
  375. * Object: fontbutton
  376. * Name: font
  377. * The font that was last selected via the font selector, or nil if none has
  378. * been selected yet. This is a read-only property.
  379. *** Property
  380. * Object: fontbutton
  381. * Name: onchanged
  382. * a function <code>onchanged(fontbutton)</code> that is called when a new
  383. * font was selected.
  384. */
  385. static int lui_fontbutton__index(lua_State *L)
  386. {
  387. lui_object *lobj = lui_checkFontbutton(L, 1);
  388. const char *what = luaL_checkstring(L, 2);
  389. if (strcmp(what, "font") == 0) {
  390. uiFontDescriptor *fnt = malloc(sizeof(uiFontDescriptor));
  391. uiFontButtonFont(uiFontButton(lobj->object), fnt);
  392. if (fnt->Family) {
  393. lui_wrapTextFont(L, fnt);
  394. } else {
  395. free(fnt);
  396. lua_pushnil(L);
  397. }
  398. } else if (strcmp(what, "onchanged") == 0) {
  399. lui_objectGetHandler(L, "onchanged");
  400. } else {
  401. return lui_control__index(L);
  402. }
  403. return 1;
  404. }
  405. static int lui_fontbutton__newindex(lua_State *L)
  406. {
  407. (void) lui_checkFontbutton(L, 1);
  408. const char *what = luaL_checkstring(L, 2);
  409. if (strcmp(what, "onchanged") == 0) {
  410. lui_objectSetHandler(L, "onchanged", 3);
  411. } else {
  412. return lui_control__newindex(L);
  413. }
  414. return 0;
  415. }
  416. static void lui_fontbuttonOnChangedCallback(uiFontButton *btn, void *data)
  417. {
  418. lua_State *L = (lua_State*) data;
  419. int top = lua_gettop(L);
  420. lui_objectHandlerCallback(L, uiControl(btn), "onchanged", top, 0, 0);
  421. lua_settop(L, top);
  422. }
  423. /*** Constructor
  424. * Object: fontbutton
  425. * Name: fontbutton
  426. * Signature: fontbutton = lui.fontbutton(properties = nil)
  427. * create a new fontbutton.
  428. */
  429. static int lui_newFontButton(lua_State *L)
  430. {
  431. int hastable = lui_aux_istable(L, 1);
  432. lui_object *lobj = lui_pushFontbutton(L);
  433. lobj->object = uiNewFontButton();
  434. uiFontButtonOnChanged(uiFontButton(lobj->object), lui_fontbuttonOnChangedCallback, L);
  435. if (hastable) { lui_aux_setFieldsFromTable(L, lua_gettop(L), 1); }
  436. lui_registerObject(L, lua_gettop(L));
  437. return 1;
  438. }
  439. /* metamethods for fontbuttons */
  440. static const luaL_Reg lui_fontbutton_meta[] = {
  441. {"__index", lui_fontbutton__index},
  442. {"__newindex", lui_fontbutton__newindex},
  443. {0, 0}
  444. };
  445. /* colorbutton control ***************************************************/
  446. /*** Object
  447. * Name: colorbutton
  448. * a button to open a color selector.
  449. */
  450. #define LUI_COLORBUTTON "lui_colorbutton"
  451. #define lui_pushColorbutton(L) lui_pushObject(L, LUI_COLORBUTTON, 1)
  452. #define lui_checkColorbutton(L, pos) ((lui_object*)luaL_checkudata(L, pos, LUI_COLORBUTTON))
  453. /*** Property
  454. * Object: colorbutton
  455. * Name: color
  456. * a table with r, g, b, a fields with values set to the currently selected
  457. * color. Defaults to 0 for each of r, g, b, a.
  458. *** Property
  459. * Object: colorbutton
  460. * Name: onchanged
  461. * a function <code>onchanged(colorbutton)</code> that is called when a new
  462. * color was selected.
  463. */
  464. static int lui_colorbutton__index(lua_State *L)
  465. {
  466. lui_object *lobj = lui_checkColorbutton(L, 1);
  467. const char *what = luaL_checkstring(L, 2);
  468. if (strcmp(what, "color") == 0) {
  469. double r, g, b, a;
  470. uiColorButtonColor(uiColorButton(lobj->object), &r, &g, &b, &a);
  471. lui_aux_pushRgbaAsTable(L, r, g, b, a);
  472. } else if (strcmp(what, "onchanged") == 0) {
  473. lui_objectGetHandler(L, "onchanged");
  474. } else {
  475. return lui_control__index(L);
  476. }
  477. return 1;
  478. }
  479. static int lui_colorbutton__newindex(lua_State *L)
  480. {
  481. lui_object *lobj = lui_checkColorbutton(L, 1);
  482. const char *what = luaL_checkstring(L, 2);
  483. if (strcmp(what, "color") == 0) {
  484. double r, g, b, a;
  485. lui_aux_rgbaFromTable(L, 3, &r, &g, &b, &a);
  486. uiColorButtonSetColor(uiColorButton(lobj->object), r, g, b, a);
  487. } else if (strcmp(what, "onchanged") == 0) {
  488. lui_objectSetHandler(L, "onchanged", 3);
  489. } else {
  490. return lui_control__newindex(L);
  491. }
  492. return 0;
  493. }
  494. static void lui_colorbuttonOnChangedCallback(uiColorButton *btn, void *data)
  495. {
  496. lua_State *L = (lua_State*) data;
  497. int top = lua_gettop(L);
  498. lui_objectHandlerCallback(L, uiControl(btn), "onchanged", top, 0, 0);
  499. lua_settop(L, top);
  500. }
  501. /*** Constructor
  502. * Object: colorbutton
  503. * Name: colorbutton
  504. * Signature: colorbutton = lui.colorbutton(properties = nil)
  505. * create a new colorbutton.
  506. */
  507. static int lui_newColorButton(lua_State *L)
  508. {
  509. int hastable = lui_aux_istable(L, 1);
  510. lui_object *lobj = lui_pushColorbutton(L);
  511. lobj->object = uiNewColorButton();
  512. uiColorButtonOnChanged(uiColorButton(lobj->object), lui_colorbuttonOnChangedCallback, L);
  513. if (hastable) { lui_aux_setFieldsFromTable(L, lua_gettop(L), 1); }
  514. lui_registerObject(L, lua_gettop(L));
  515. return 1;
  516. }
  517. /* metamethods for colorbuttons */
  518. static const luaL_Reg lui_colorbutton_meta[] = {
  519. {"__index", lui_colorbutton__index},
  520. {"__newindex", lui_colorbutton__newindex},
  521. {0, 0}
  522. };
  523. static const struct luaL_Reg lui_area_funcs [] ={
  524. {"area", lui_newArea},
  525. {"fontbutton", lui_newFontButton},
  526. {"colorbutton", lui_newColorButton},
  527. {0, 0}
  528. };
  529. static void lui_addAreaEnums(lua_State *L)
  530. {
  531. int top = lua_gettop(L);
  532. if (lua_getfield(L, top, "enum") == LUA_TNIL) {
  533. lua_pop(L, 1);
  534. lua_newtable(L);
  535. }
  536. lui_makeAreaKeyModifierEnum(L);
  537. lua_pushvalue(L, -1);
  538. lua_setfield(L, top + 1, "keymod");
  539. lua_setfield(L, LUA_REGISTRYINDEX, "lui_enumkeymod");
  540. lui_makeAreaKeyExtEnum(L);
  541. lua_pushvalue(L, -1);
  542. lua_setfield(L, top + 1, "keyext");
  543. lua_setfield(L, LUA_REGISTRYINDEX, "lui_enumkeyext");
  544. luiMakeWindowEdgeEnum(L);
  545. lua_pushvalue(L, -1);
  546. lua_setfield(L, top + 1, "edge");
  547. lua_setfield(L, LUA_REGISTRYINDEX, "lui_enumwinedge");
  548. lua_setfield(L, top, "enum");
  549. }
  550. static int lui_init_area(lua_State *L)
  551. {
  552. luaL_setfuncs(L, lui_area_funcs, 0);
  553. lui_add_control_type(L, LUI_AREA, lui_area_methods, lui_area_meta);
  554. lui_add_control_type(L, LUI_FONTBUTTON, 0, lui_fontbutton_meta);
  555. lui_add_control_type(L, LUI_COLORBUTTON, 0, lui_colorbutton_meta);
  556. lui_addAreaEnums(L);
  557. return 1;
  558. }