Просмотр исходного кода

add: easylvgl, 新增Container组件

zengeshuai 1 месяц назад
Родитель
Сommit
1e2f8beb56

+ 6 - 0
components/easylvgl/binding/luat_lib_easylvgl.c

@@ -47,6 +47,10 @@ extern int easylvgl_label_create(lua_State *L);
 extern void easylvgl_register_image_meta(lua_State *L);
 extern int easylvgl_image_create(lua_State *L);
 
+// Container 模块声明
+extern void easylvgl_register_container_meta(lua_State *L);
+extern int easylvgl_container_create(lua_State *L);
+
 // Win 模块声明
 extern void easylvgl_register_win_meta(lua_State *L);
 extern int easylvgl_win_create(lua_State *L);
@@ -84,6 +88,7 @@ static const rotable_Reg_t reg_easylvgl[] = {
     {"button", ROREG_FUNC(easylvgl_button_create)},
     {"label", ROREG_FUNC(easylvgl_label_create)},
     {"image", ROREG_FUNC(easylvgl_image_create)},
+    {"container", ROREG_FUNC(easylvgl_container_create)},
     {"win", ROREG_FUNC(easylvgl_win_create)},
     {"dropdown", ROREG_FUNC(easylvgl_dropdown_create)},
     {"switch", ROREG_FUNC(easylvgl_switch_create)},
@@ -103,6 +108,7 @@ LUAMOD_API int luaopen_easylvgl(lua_State *L) {
     easylvgl_register_button_meta(L);
     easylvgl_register_label_meta(L);
     easylvgl_register_image_meta(L);
+    easylvgl_register_container_meta(L);
     easylvgl_register_win_meta(L);
     easylvgl_register_dropdown_meta(L);
     easylvgl_register_switch_meta(L);

+ 99 - 0
components/easylvgl/binding/luat_lib_easylvgl_container.c

@@ -0,0 +1,99 @@
+/*
+@module  easylvgl.container
+@summary EasyLVGL Container 组件 Lua 绑定
+@version 0.1.0
+@date    2025.12.25
+@tag     LUAT_USE_EASYLVGL
+*/
+
+#include "luat_base.h"
+#include "lua.h"
+#include "lauxlib.h"
+#include "../inc/luat_easylvgl.h"
+#include "../inc/luat_easylvgl_component.h"
+#include "../inc/luat_easylvgl_binding.h"
+
+#define EASYLVGL_CONTAINER_MT "easylvgl.container"
+
+/**
+ * 创建 Container 组件
+ * @api easylvgl.container(config)
+ */
+static int l_easylvgl_container(lua_State *L) {
+    easylvgl_ctx_t *ctx = NULL;
+    lua_getfield(L, LUA_REGISTRYINDEX, "easylvgl_ctx");
+    if (lua_type(L, -1) == LUA_TLIGHTUSERDATA) {
+        ctx = (easylvgl_ctx_t *)lua_touserdata(L, -1);
+    }
+    lua_pop(L, 1);
+
+    if (ctx == NULL) {
+        luaL_error(L, "easylvgl not initialized, call easylvgl.init() first");
+        return 0;
+    }
+
+    luaL_checktype(L, 1, LUA_TTABLE);
+
+    lv_obj_t *container = easylvgl_container_create_from_config(L, 1);
+    if (container == NULL) {
+        lua_pushnil(L);
+        return 1;
+    }
+
+    easylvgl_push_component_userdata(L, container, EASYLVGL_CONTAINER_MT);
+    return 1;
+}
+
+/**
+ * Container:set_color(color)
+ * @api container:set_color(color)
+ * @int color 背景色(0xRRGGBB)
+ */
+static int l_container_set_color(lua_State *L) {
+    lv_obj_t *container = easylvgl_check_component(L, 1, EASYLVGL_CONTAINER_MT);
+    uint32_t color = (uint32_t)luaL_checkinteger(L, 2);
+    easylvgl_container_set_color(container, color);
+    return 0;
+}
+
+/**
+ * Container GC
+ */
+static int l_container_gc(lua_State *L) {
+    easylvgl_component_ud_t *ud = (easylvgl_component_ud_t *)luaL_checkudata(L, 1, EASYLVGL_CONTAINER_MT);
+    if (ud != NULL && ud->obj != NULL) {
+        easylvgl_component_meta_t *meta = easylvgl_component_meta_get(ud->obj);
+        if (meta != NULL) {
+            easylvgl_component_meta_free(meta);
+        }
+        lv_obj_delete(ud->obj);
+        ud->obj = NULL;
+    }
+    return 0;
+}
+
+/**
+ * 注册 Container 元表
+ */
+void easylvgl_register_container_meta(lua_State *L) {
+    luaL_newmetatable(L, EASYLVGL_CONTAINER_MT);
+    lua_pushcfunction(L, l_container_gc);
+    lua_setfield(L, -2, "__gc");
+
+    static const luaL_Reg methods[] = {
+        {"set_color", l_container_set_color},
+        {NULL, NULL}
+    };
+
+    luaL_newlib(L, methods);
+    lua_setfield(L, -2, "__index");
+    lua_pop(L, 1);
+}
+
+/**
+ * Container 创建函数(供主模块注册)
+ */
+int easylvgl_container_create(lua_State *L) {
+    return l_easylvgl_container(L);
+}
+

+ 1 - 0
components/easylvgl/inc/luat_easylvgl_binding.h

@@ -13,6 +13,7 @@
 
 #define EASYLVGL_TEXTAREA_MT "easylvgl.textarea"
 #define EASYLVGL_KEYBOARD_MT "easylvgl.keyboard"
+#define EASYLVGL_CONTAINER_MT "easylvgl.container"
 
 #ifdef __cplusplus
 extern "C" {

+ 10 - 0
components/easylvgl/inc/luat_easylvgl_component.h

@@ -26,6 +26,7 @@ typedef enum {
     EASYLVGL_COMPONENT_DROPDOWN,
     EASYLVGL_COMPONENT_SWITCH,
     EASYLVGL_COMPONENT_MSGBOX,
+    EASYLVGL_COMPONENT_CONTAINER,
     EASYLVGL_COMPONENT_TEXTAREA,
     EASYLVGL_COMPONENT_KEYBOARD
 } easylvgl_component_type_t;
@@ -283,6 +284,15 @@ int easylvgl_switch_set_state(lv_obj_t *sw, bool checked);
 bool easylvgl_switch_get_state(lv_obj_t *sw);
 int easylvgl_switch_set_on_change(lv_obj_t *sw, int callback_ref);
 
+/**
+ * Container 组件创建
+ */
+lv_obj_t *easylvgl_container_create_from_config(void *L, int idx);
+/**
+ * Container 组件:设置背景颜色
+ */
+int easylvgl_container_set_color(lv_obj_t *container, uint32_t color);
+
 /**
  * Msgbox 组件创建与控制
  */

+ 87 - 0
components/easylvgl/src/components/widgets/luat_easylvgl_container.c

@@ -0,0 +1,87 @@
+/**
+ * @file luat_easylvgl_container.c
+ * @summary Container 组件实现
+ * @responsible Container 创建、样式控制
+ */
+
+#include "luat_easylvgl_component.h"
+#include "lvgl9/lvgl.h"
+#include "lvgl9/src/core/lv_obj.h"
+#include "lvgl9/src/misc/lv_color.h"
+#include "lua.h"
+#include "lauxlib.h"
+#include <stdint.h>
+
+/**
+ * 从配置表创建 Container 组件
+ */
+lv_obj_t *easylvgl_container_create_from_config(void *L, int idx)
+{
+    if (L == NULL) {
+        return NULL;
+    }
+
+    lua_State *L_state = (lua_State *)L;
+    easylvgl_ctx_t *ctx = NULL;
+    lua_getfield(L_state, LUA_REGISTRYINDEX, "easylvgl_ctx");
+    if (lua_type(L_state, -1) == LUA_TLIGHTUSERDATA) {
+        ctx = (easylvgl_ctx_t *)lua_touserdata(L_state, -1);
+    }
+    lua_pop(L_state, 1);
+
+    if (ctx == NULL) {
+        return NULL;
+    }
+
+    lv_obj_t *parent = easylvgl_marshal_parent(L, idx);
+    int x = easylvgl_marshal_integer(L, idx, "x", 0);
+    int y = easylvgl_marshal_integer(L, idx, "y", 0);
+    int w = easylvgl_marshal_integer(L, idx, "w", 100);
+    int h = easylvgl_marshal_integer(L, idx, "h", 100);
+    int color_value = easylvgl_marshal_integer(L, idx, "color", -1);
+    int radius = easylvgl_marshal_integer(L, idx, "radius", 0);
+
+    lv_obj_t *container = lv_obj_create(parent);
+    if (container == NULL) {
+        return NULL;
+    }
+
+    lv_obj_set_pos(container, x, y);
+    lv_obj_set_size(container, w, h);
+    lv_obj_set_style_border_width(container, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
+    lv_obj_set_style_radius(container, radius, LV_PART_MAIN | LV_STATE_DEFAULT);
+
+    if (color_value >= 0) {
+        lv_color_t bg_color = lv_color_hex((uint32_t)color_value);
+        lv_obj_set_style_bg_color(container, bg_color, LV_PART_MAIN | LV_STATE_DEFAULT);
+        lv_obj_set_style_bg_opa(container, LV_OPA_COVER, LV_PART_MAIN | LV_STATE_DEFAULT);
+    } else {
+        lv_obj_set_style_bg_opa(container, LV_OPA_TRANSP, LV_PART_MAIN | LV_STATE_DEFAULT);
+    }
+
+    easylvgl_component_meta_t *meta = easylvgl_component_meta_alloc(
+        ctx, container, EASYLVGL_COMPONENT_CONTAINER);
+    if (meta == NULL) {
+        lv_obj_delete(container);
+        return NULL;
+    }
+
+    return container;
+}
+
+/**
+ * 设置 Container 背景颜色
+ */
+int easylvgl_container_set_color(lv_obj_t *container, uint32_t color_value)
+{
+    if (container == NULL) {
+        return EASYLVGL_ERR_INVALID_PARAM;
+    }
+
+    lv_color_t bg_color = lv_color_hex(color_value);
+    lv_obj_set_style_bg_color(container, bg_color, LV_PART_MAIN | LV_STATE_DEFAULT);
+    lv_obj_set_style_bg_opa(container, LV_OPA_COVER, LV_PART_MAIN | LV_STATE_DEFAULT);
+
+    return EASYLVGL_OK;
+}
+