luat_lib_easylvgl_button.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /*
  2. @module easylvgl.button
  3. @summary EasyLVGL Button 组件 Lua 绑定
  4. @version 0.1.0
  5. @date 2025.12.02
  6. @tag LUAT_USE_EASYLVGL
  7. */
  8. #include "luat_base.h"
  9. #include "luat_log.h"
  10. #include "lua.h"
  11. #include "lauxlib.h"
  12. #include "../inc/luat_easylvgl.h"
  13. #include "../inc/luat_easylvgl_component.h"
  14. #include "../inc/luat_easylvgl_binding.h"
  15. #include <string.h>
  16. #define LUAT_LOG_TAG "easylvgl.button"
  17. #include "luat_log.h"
  18. // 元表名称
  19. #define EASYLVGL_BUTTON_MT "easylvgl.button"
  20. /**
  21. * 创建 Button 组件
  22. * @api easylvgl.button(config)
  23. * @table config 配置表
  24. * @int config.x X 坐标,默认 0
  25. * @int config.y Y 坐标,默认 0
  26. * @int config.w 宽度,默认 100
  27. * @int config.h 高度,默认 40
  28. * @string config.text 文本内容,可选
  29. * @function config.on_click 点击回调函数,可选
  30. * @userdata config.parent 父对象,可选,默认当前屏幕
  31. * @return userdata Button 对象
  32. */
  33. static int l_easylvgl_button(lua_State *L) {
  34. // 检查上下文是否已初始化(从注册表获取)
  35. easylvgl_ctx_t *ctx = NULL;
  36. lua_getfield(L, LUA_REGISTRYINDEX, "easylvgl_ctx");
  37. if (lua_type(L, -1) == LUA_TLIGHTUSERDATA) {
  38. ctx = (easylvgl_ctx_t *)lua_touserdata(L, -1);
  39. }
  40. lua_pop(L, 1);
  41. if (ctx == NULL) {
  42. luaL_error(L, "easylvgl not initialized, call easylvgl.init() first");
  43. return 0;
  44. }
  45. luaL_checktype(L, 1, LUA_TTABLE);
  46. lv_obj_t *btn = easylvgl_button_create_from_config(L, 1);
  47. if (btn == NULL) {
  48. lua_pushnil(L);
  49. return 1;
  50. }
  51. easylvgl_push_component_userdata(L, btn, EASYLVGL_BUTTON_MT);
  52. return 1;
  53. }
  54. /**
  55. * Button:set_text(text)
  56. * @api button:set_text(text)
  57. * @string text 文本内容
  58. * @return nil
  59. */
  60. static int l_button_set_text(lua_State *L) {
  61. lv_obj_t *btn = easylvgl_check_component(L, 1, EASYLVGL_BUTTON_MT);
  62. const char *text = luaL_checkstring(L, 2);
  63. easylvgl_button_set_text(btn, text);
  64. return 0;
  65. }
  66. /**
  67. * Button:set_on_click(callback)
  68. * @api button:set_on_click(callback)
  69. * @function callback 回调函数
  70. * @return nil
  71. */
  72. static int l_button_set_on_click(lua_State *L) {
  73. lv_obj_t *btn = easylvgl_check_component(L, 1, EASYLVGL_BUTTON_MT);
  74. luaL_checktype(L, 2, LUA_TFUNCTION);
  75. // 保存回调函数到 registry
  76. lua_pushvalue(L, 2);
  77. int ref = luaL_ref(L, LUA_REGISTRYINDEX);
  78. easylvgl_button_set_on_click(btn, ref);
  79. return 0;
  80. }
  81. /**
  82. * Button GC(垃圾回收)
  83. */
  84. static int l_button_gc(lua_State *L) {
  85. easylvgl_component_ud_t *ud = (easylvgl_component_ud_t *)luaL_checkudata(L, 1, EASYLVGL_BUTTON_MT);
  86. if (ud != NULL && ud->obj != NULL) {
  87. // 获取元数据并释放
  88. easylvgl_component_meta_t *meta = easylvgl_component_meta_get(ud->obj);
  89. if (meta != NULL) {
  90. easylvgl_component_meta_free(meta);
  91. }
  92. // 删除 LVGL 对象
  93. lv_obj_delete(ud->obj);
  94. ud->obj = NULL;
  95. }
  96. return 0;
  97. }
  98. /**
  99. * 注册 Button 元表
  100. * @param L Lua 状态
  101. */
  102. void easylvgl_register_button_meta(lua_State *L) {
  103. luaL_newmetatable(L, EASYLVGL_BUTTON_MT);
  104. // 设置元方法
  105. lua_pushcfunction(L, l_button_gc);
  106. lua_setfield(L, -2, "__gc");
  107. // 设置方法表
  108. static const luaL_Reg methods[] = {
  109. {"set_text", l_button_set_text},
  110. {"set_on_click", l_button_set_on_click},
  111. {NULL, NULL}
  112. };
  113. luaL_newlib(L, methods);
  114. lua_setfield(L, -2, "__index");
  115. lua_pop(L, 1);
  116. }
  117. /**
  118. * Button 创建函数(供主模块注册)
  119. */
  120. int easylvgl_button_create(lua_State *L) {
  121. return l_easylvgl_button(L);
  122. }