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.
 
 
 
 

115 lines
2.9 KiB

  1. /* lui.c
  2. *
  3. * lua binding to libui (https://github.com/andlabs/libui)
  4. *
  5. * Gunnar Zötl <gz@tset.de>, 2016-2018
  6. * Released under MIT/X11 license. See file LICENSE for details.
  7. *
  8. * This file is included by lui.c
  9. */
  10. typedef struct {
  11. int id;
  12. int *status;
  13. } lui_dialogButtonId;
  14. static int lui_dialogOnClosingCallback(uiWindow *win, void *data)
  15. {
  16. int *status = (int*) data;
  17. *status = 0;
  18. return 0;
  19. }
  20. static void lui_dialogButtonOnClickedCallback(uiButton *btn, void *data)
  21. {
  22. lui_dialogButtonId *id = (lui_dialogButtonId*) data;
  23. *(id->status) = id->id;
  24. }
  25. /*** Function
  26. * Name: dialog
  27. * Signature: number = lui.dialog([title], [w, h], control, [button1, ...])
  28. * open a dialog, and wait for it to complete. Returns the number of the
  29. * button that was clicked, starting from 1, or nil if the dialog was just
  30. * aborted. control should be a container, like a box or a form, that contains
  31. * the controls that make up the dialog.
  32. */
  33. // TODO check whether we need to do this more lua-like... (i.e. allocate lua
  34. // objects and use lua methods for stuff)
  35. static int lui_runDialog(lua_State *L)
  36. {
  37. int arg = 1;
  38. int narg = lua_gettop(L);
  39. int status = -1;
  40. const char *title = LUI_DEFAULT_WINDOW_TITLE;
  41. if (lua_isstring(L, arg)) {
  42. title = lua_tostring(L, arg++);
  43. }
  44. int width = LUI_DEFAULT_WINDOW_WIDTH;
  45. int height = LUI_DEFAULT_WINDOW_HEIGHT;
  46. if (lua_isnumber(L, arg)) {
  47. width = luaL_checkinteger(L, arg++);
  48. height = luaL_checkinteger(L, arg++);
  49. }
  50. lui_object *lobj = lui_checkObject(L, arg);
  51. uiBox *vbox = uiNewVerticalBox();
  52. uiBoxAppend(vbox, uiControl(lobj->object), 1);
  53. uiBox *hbox = uiNewHorizontalBox();
  54. uiBoxAppend(vbox, uiControl(hbox), 0);
  55. uiWindow *win = uiNewWindow(title, width, height, 0);
  56. uiWindowOnClosing(win, lui_dialogOnClosingCallback, &status);
  57. uiWindowSetChild(win, uiControl(vbox));
  58. lui_dialogButtonId buttonid[narg + 1];
  59. if (narg == arg) {
  60. uiButton *btn = uiNewButton("OK");
  61. uiButtonOnClicked(btn, lui_dialogButtonOnClickedCallback, &status);
  62. uiBoxAppend(hbox, uiControl(btn), 1);
  63. } else {
  64. ++arg;
  65. for (int i = arg; i <= narg; ++i) {
  66. buttonid[i].id = i + 1 - arg;
  67. buttonid[i].status = &status;
  68. const char *bname = luaL_checkstring(L, i);
  69. uiButton *btn = uiNewButton(bname);
  70. uiButtonOnClicked(btn, lui_dialogButtonOnClickedCallback, &buttonid[i]);
  71. uiBoxAppend(hbox, uiControl(btn), 1);
  72. }
  73. }
  74. uiControlShow(uiControl(win));
  75. while (uiMainStep(1) && status < 0) {
  76. /* nothing */
  77. }
  78. /* destroy everything except for the control we were passed as an argument */
  79. uiWindowSetChild(win, 0);
  80. uiControlDestroy(uiControl(win));
  81. uiBoxDelete(vbox, 0);
  82. uiControlDestroy(uiControl(vbox));
  83. if (status <= 0) {
  84. lua_pushnil(L);
  85. } else {
  86. lua_pushinteger(L, status);
  87. }
  88. return 1;
  89. }
  90. static const struct luaL_Reg lui_dialog_funcs [] ={
  91. {"dialog", lui_runDialog},
  92. {0, 0}
  93. };
  94. static int lui_init_dialog(lua_State *L)
  95. {
  96. luaL_setfuncs(L, lui_dialog_funcs, 0);
  97. return 1;
  98. }