luat_lib_easylvgl_textarea.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. /*
  2. @module easylvgl.textarea
  3. @summary EasyLVGL Textarea 组件 Lua 绑定
  4. @version 0.3.0
  5. @date 2025.12.15
  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 "luat_malloc.h"
  16. #define LUAT_LOG_TAG "easylvgl.textarea"
  17. #include "luat_log.h"
  18. /************************************************************************
  19. * Lua 接口定义
  20. ************************************************************************/
  21. /**
  22. * 创建 Textarea 组件
  23. * @api easylvgl.textarea(config)
  24. * @table config 配置表
  25. * @int config.x X 坐标,默认 0
  26. * @int config.y Y 坐标,默认 0
  27. * @int config.w 宽度,默认 ctx->width - x 或 200
  28. * @int config.h 高度,默认 120
  29. * @int config.max_len 最大字符数,默认 256
  30. * @string config.text 初始文本
  31. * @string config.placeholder 占位提示
  32. * @function config.on_text_change 文本变更回调
  33. * @table config.keyboard 内嵌 Keyboard 配置(table)
  34. * @userdata config.parent 父对象,可选
  35. * @return userdata Textarea 对象,失败返回 nil
  36. */
  37. static int l_easylvgl_textarea(lua_State *L) {
  38. easylvgl_ctx_t *ctx = NULL;
  39. lua_getfield(L, LUA_REGISTRYINDEX, "easylvgl_ctx");
  40. if (lua_type(L, -1) == LUA_TLIGHTUSERDATA) {
  41. ctx = (easylvgl_ctx_t *)lua_touserdata(L, -1);
  42. }
  43. lua_pop(L, 1);
  44. if (ctx == NULL) {
  45. luaL_error(L, "easylvgl not initialized, call easylvgl.init() first");
  46. return 0;
  47. }
  48. luaL_checktype(L, 1, LUA_TTABLE);
  49. lv_obj_t *textarea = easylvgl_textarea_create_from_config(L, 1);
  50. if (textarea == NULL) {
  51. lua_pushnil(L);
  52. return 1;
  53. }
  54. easylvgl_push_component_userdata(L, textarea, EASYLVGL_TEXTAREA_MT);
  55. return 1;
  56. }
  57. /**
  58. * Textarea:set_text(text)
  59. * @api textarea:set_text(text)
  60. * @string text 文本内容
  61. * @return nil
  62. */
  63. static int l_textarea_set_text(lua_State *L) {
  64. lv_obj_t *textarea = easylvgl_check_component(L, 1, EASYLVGL_TEXTAREA_MT);
  65. const char *text = luaL_checkstring(L, 2);
  66. easylvgl_textarea_set_text(textarea, text);
  67. return 0;
  68. }
  69. /**
  70. * Textarea:get_text()
  71. * @api textarea:get_text()
  72. * @return string 当前文本
  73. */
  74. static int l_textarea_get_text(lua_State *L) {
  75. lv_obj_t *textarea = easylvgl_check_component(L, 1, EASYLVGL_TEXTAREA_MT);
  76. const char *text = easylvgl_textarea_get_text(textarea);
  77. lua_pushstring(L, text ? text : "");
  78. return 1;
  79. }
  80. /**
  81. * Textarea:set_cursor(pos)
  82. * @api textarea:set_cursor(pos)
  83. * @int pos 光标位置
  84. * @return nil
  85. */
  86. static int l_textarea_set_cursor(lua_State *L) {
  87. lv_obj_t *textarea = easylvgl_check_component(L, 1, EASYLVGL_TEXTAREA_MT);
  88. uint32_t pos = (uint32_t)luaL_checkinteger(L, 2);
  89. easylvgl_textarea_set_cursor(textarea, pos);
  90. return 0;
  91. }
  92. /**
  93. * Textarea:set_on_text_change(callback)
  94. * @api textarea:set_on_text_change(callback)
  95. * @function callback 文本变化回调
  96. * @return nil
  97. */
  98. static int l_textarea_set_on_change(lua_State *L) {
  99. lv_obj_t *textarea = easylvgl_check_component(L, 1, EASYLVGL_TEXTAREA_MT);
  100. luaL_checktype(L, 2, LUA_TFUNCTION);
  101. lua_pushvalue(L, 2);
  102. int ref = luaL_ref(L, LUA_REGISTRYINDEX);
  103. easylvgl_textarea_set_on_text_change(textarea, ref);
  104. return 0;
  105. }
  106. /**
  107. * Textarea:attach_keyboard(keyboard)
  108. * @api textarea:attach_keyboard(keyboard)
  109. * @userdata keyboard Keyboard 对象
  110. * @return nil
  111. */
  112. static int l_textarea_attach_keyboard(lua_State *L) {
  113. lv_obj_t *textarea = easylvgl_check_component(L, 1, EASYLVGL_TEXTAREA_MT);
  114. lv_obj_t *keyboard = easylvgl_check_component(L, 2, EASYLVGL_KEYBOARD_MT);
  115. easylvgl_textarea_attach_keyboard(textarea, keyboard);
  116. return 0;
  117. }
  118. /**
  119. * Textarea:get_keyboard()
  120. * @api textarea:get_keyboard()
  121. * @return userdata|null 当前绑定的 Keyboard
  122. */
  123. static int l_textarea_get_keyboard(lua_State *L) {
  124. lv_obj_t *textarea = easylvgl_check_component(L, 1, EASYLVGL_TEXTAREA_MT);
  125. lv_obj_t *keyboard = easylvgl_textarea_get_keyboard(textarea);
  126. if (keyboard == NULL) {
  127. lua_pushnil(L);
  128. return 1;
  129. }
  130. easylvgl_push_component_userdata(L, keyboard, EASYLVGL_KEYBOARD_MT);
  131. return 1;
  132. }
  133. /**
  134. * Textarea GC(销毁组件)
  135. */
  136. static int l_textarea_gc(lua_State *L) {
  137. easylvgl_component_ud_t *ud = (easylvgl_component_ud_t *)luaL_checkudata(L, 1, EASYLVGL_TEXTAREA_MT);
  138. if (ud != NULL && ud->obj != NULL) {
  139. easylvgl_component_meta_t *meta = easylvgl_component_meta_get(ud->obj);
  140. if (meta != NULL) {
  141. if (meta->user_data != NULL) {
  142. luat_heap_free(meta->user_data);
  143. meta->user_data = NULL;
  144. }
  145. easylvgl_component_meta_free(meta);
  146. }
  147. lv_obj_delete(ud->obj);
  148. ud->obj = NULL;
  149. }
  150. return 0;
  151. }
  152. /**
  153. * 注册 Textarea 元表
  154. * @param L Lua 状态
  155. */
  156. void easylvgl_register_textarea_meta(lua_State *L) {
  157. luaL_newmetatable(L, EASYLVGL_TEXTAREA_MT);
  158. lua_pushcfunction(L, l_textarea_gc);
  159. lua_setfield(L, -2, "__gc");
  160. static const luaL_Reg functions[] = {
  161. {"set_text", l_textarea_set_text},
  162. {"get_text", l_textarea_get_text},
  163. {"set_cursor", l_textarea_set_cursor},
  164. {"set_on_text_change", l_textarea_set_on_change},
  165. {"attach_keyboard", l_textarea_attach_keyboard},
  166. {"get_keyboard", l_textarea_get_keyboard},
  167. {NULL, NULL}
  168. };
  169. luaL_newlib(L, functions);
  170. lua_setfield(L, -2, "__index");
  171. lua_pop(L, 1);
  172. }
  173. /**
  174. * Textarea 创建函数(供主模块注册)
  175. */
  176. int easylvgl_textarea_create(lua_State *L) {
  177. return l_easylvgl_textarea(L);
  178. }