luat_lib_easylvgl_dropdown.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /*
  2. @module easylvgl.dropdown
  3. @summary EasyLVGL Dropdown 组件
  4. @version 0.2.0
  5. @date 2025.12.12
  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 "lvgl9/src/widgets/dropdown/lv_dropdown.h"
  16. #include "luat_malloc.h"
  17. #define LUAT_LOG_TAG "easylvgl.dropdown"
  18. #include "luat_log.h"
  19. #define EASYLVGL_DROPDOWN_MT "easylvgl.dropdown"
  20. /**
  21. * 创建 Dropdown 组件
  22. * @api easylvgl.dropdown(config)
  23. * @table config 配置表
  24. * @int config.x X 坐标,默认 0
  25. * @int config.y Y 坐标,默认 0
  26. * @int config.w 宽度,默认 140
  27. * @int config.h 高度,默认 40
  28. * @table config.options 选项列表(字符串数组)
  29. * @int config.default_index 默认选中项索引,默认 -1
  30. * @function config.on_change 选中项变化回调
  31. * @userdata config.parent 父对象,可覆盖默认屏幕
  32. * @return userdata Dropdown 对象,失败返回 nil
  33. */
  34. static int l_easylvgl_dropdown(lua_State *L)
  35. {
  36. easylvgl_ctx_t *ctx = NULL;
  37. lua_getfield(L, LUA_REGISTRYINDEX, "easylvgl_ctx");
  38. if (lua_type(L, -1) == LUA_TLIGHTUSERDATA) {
  39. ctx = (easylvgl_ctx_t *)lua_touserdata(L, -1);
  40. }
  41. lua_pop(L, 1);
  42. if (ctx == NULL) {
  43. luaL_error(L, "easylvgl not initialized, call easylvgl.init() first");
  44. return 0;
  45. }
  46. luaL_checktype(L, 1, LUA_TTABLE);
  47. lv_obj_t *dropdown = easylvgl_dropdown_create_from_config(L, 1);
  48. if (dropdown == NULL) {
  49. lua_pushnil(L);
  50. return 1;
  51. }
  52. easylvgl_push_component_userdata(L, dropdown, EASYLVGL_DROPDOWN_MT);
  53. return 1;
  54. }
  55. /**
  56. * Dropdown:set_selected(index)
  57. * @api dropdown:set_selected(index)
  58. * @int index 选中项索引,0 起始
  59. * @return nil
  60. */
  61. static int l_dropdown_set_selected(lua_State *L)
  62. {
  63. lv_obj_t *dropdown = easylvgl_check_component(L, 1, EASYLVGL_DROPDOWN_MT);
  64. int index = luaL_checkinteger(L, 2);
  65. easylvgl_dropdown_set_selected(dropdown, index);
  66. return 0;
  67. }
  68. /**
  69. * Dropdown:get_selected()
  70. * @api dropdown:get_selected()
  71. * @return int 当前选中项索引
  72. */
  73. static int l_dropdown_get_selected(lua_State *L)
  74. {
  75. lv_obj_t *dropdown = easylvgl_check_component(L, 1, EASYLVGL_DROPDOWN_MT);
  76. int index = easylvgl_dropdown_get_selected(dropdown);
  77. lua_pushinteger(L, index);
  78. return 1;
  79. }
  80. /**
  81. * Dropdown:set_on_change(callback)
  82. * @api dropdown:set_on_change(callback)
  83. * @function callback 选中项改变回调
  84. * @return nil
  85. */
  86. static int l_dropdown_set_on_change(lua_State *L)
  87. {
  88. lv_obj_t *dropdown = easylvgl_check_component(L, 1, EASYLVGL_DROPDOWN_MT);
  89. luaL_checktype(L, 2, LUA_TFUNCTION);
  90. lua_pushvalue(L, 2);
  91. int ref = luaL_ref(L, LUA_REGISTRYINDEX);
  92. easylvgl_dropdown_set_on_change(dropdown, ref);
  93. return 0;
  94. }
  95. /**
  96. * Dropdown GC(垃圾回收)
  97. */
  98. static int l_dropdown_gc(lua_State *L)
  99. {
  100. easylvgl_component_ud_t *ud = (easylvgl_component_ud_t *)luaL_checkudata(L, 1, EASYLVGL_DROPDOWN_MT);
  101. if (ud != NULL && ud->obj != NULL) {
  102. easylvgl_component_meta_t *meta = easylvgl_component_meta_get(ud->obj);
  103. if (meta != NULL) {
  104. if (meta->user_data != NULL) {
  105. luat_heap_free(meta->user_data);
  106. meta->user_data = NULL;
  107. }
  108. easylvgl_component_meta_free(meta);
  109. }
  110. lv_obj_delete(ud->obj);
  111. ud->obj = NULL;
  112. }
  113. return 0;
  114. }
  115. /**
  116. * 注册 Dropdown 元表
  117. * @param L Lua 状态
  118. */
  119. void easylvgl_register_dropdown_meta(lua_State *L)
  120. {
  121. luaL_newmetatable(L, EASYLVGL_DROPDOWN_MT);
  122. lua_pushcfunction(L, l_dropdown_gc);
  123. lua_setfield(L, -2, "__gc");
  124. static const luaL_Reg methods[] = {
  125. {"set_selected", l_dropdown_set_selected},
  126. {"get_selected", l_dropdown_get_selected},
  127. {"set_on_change", l_dropdown_set_on_change},
  128. {NULL, NULL}
  129. };
  130. luaL_newlib(L, methods);
  131. lua_setfield(L, -2, "__index");
  132. lua_pop(L, 1);
  133. }
  134. /**
  135. * Dropdown 创建函数(供主模块注册)
  136. */
  137. int easylvgl_dropdown_create(lua_State *L)
  138. {
  139. return l_easylvgl_dropdown(L);
  140. }