From 6711a24a68fc1972c641a04253a63dbc30ad730d Mon Sep 17 00:00:00 2001 From: Rdzleo Date: Tue, 24 Mar 2026 18:05:54 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9EScreenChar=E8=A7=92?= =?UTF-8?q?=E8=89=B2=E5=8A=A8=E7=94=BB=E7=95=8C=E9=9D=A2=20+=20=E5=90=AF?= =?UTF-8?q?=E7=94=A8GIF=E8=A7=A3=E7=A0=81=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增ui_ScreenChar:LVGL基元绘制动漫角色(金黄头发/脸/眼/嘴/身体/胳膊) - 序列帧动画:BOOT按键触发眨眼+说话动画,再按停止 - ScreenImg上滑导航至ScreenChar(保留原Home路径可切换) - BOOT按键逻辑:ScreenChar界面切换动画,其他界面返回Home - 启用CONFIG_LV_USE_GIF=y支持GIF动图显示 Co-Authored-By: Claude Opus 4.6 --- main/CMakeLists.txt | 1 + main/main.c | 21 +- main/ui/screens/ui_ScreenChar.c | 381 ++++++++++++++++++++++++++++++++ main/ui/screens/ui_ScreenChar.h | 25 +++ main/ui/screens/ui_ScreenImg.c | 5 +- main/ui/ui.h | 1 + sdkconfig | 2 +- 7 files changed, 432 insertions(+), 4 deletions(-) create mode 100644 main/ui/screens/ui_ScreenChar.c create mode 100644 main/ui/screens/ui_ScreenChar.h diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index c8de5a0..d8692aa 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -15,6 +15,7 @@ idf_component_register( "./ui/screens/ui_ScreenHome.c" "./ui/screens/ui_ScreenSet.c" "./ui/screens/ui_ScreenImg.c" + "./ui/screens/ui_ScreenChar.c" "./ui/ui_helpers.c" "./ui/images/ui_img_s1_png.c" "./ui/images/ui_img_s6_png.c" diff --git a/main/main.c b/main/main.c index 206c7d1..88803dd 100644 --- a/main/main.c +++ b/main/main.c @@ -22,6 +22,7 @@ #include "ui/ui.h" #include "ui/screens/ui_ScreenSet.h" #include "ui/screens/ui_ScreenImg.h" +#include "ui/screens/ui_ScreenChar.h" // #include "axis.h" @@ -71,11 +72,27 @@ void boot_btn_handler(int gpio_num, void *usr_data) { ESP_LOGI("BTN_HANDLER", "BOOT按键:低功耗模式,仅唤醒屏幕"); sleep_mgr_notify_activity(); // 唤醒屏幕,恢复亮度 } else { - // 正常模式下:返回ScreenHome界面 + // 正常模式下的按键处理 + lv_obj_t *current_screen = lv_scr_act(); + + // 在ScreenChar界面:切换角色动画(不返回Home) + if (current_screen == ui_ScreenChar) { + sleep_mgr_notify_activity(); + if (char_anim_is_playing()) { + char_anim_stop(); + ESP_LOGI("BTN_HANDLER", "BOOT按键:停止角色动画"); + } else { + char_anim_start(); + ESP_LOGI("BTN_HANDLER", "BOOT按键:启动角色动画"); + } + return; + } + + + // 其他界面:返回ScreenHome ESP_LOGI("BTN_HANDLER", "BOOT按键:正常模式,返回ScreenHome"); // 检查当前是否在ScreenImg界面,如果是则先隐藏ContainerDle - lv_obj_t *current_screen = lv_scr_act(); if (current_screen == ui_ScreenImg) { ui_ScreenImg_hide_delete_container(); ESP_LOGI("BTN_HANDLER", "从ScreenImg离开,已隐藏ContainerDle"); diff --git a/main/ui/screens/ui_ScreenChar.c b/main/ui/screens/ui_ScreenChar.c new file mode 100644 index 0000000..eabb721 --- /dev/null +++ b/main/ui/screens/ui_ScreenChar.c @@ -0,0 +1,381 @@ +// 动漫角色界面 - LVGL图形基元绘制 + 序列帧动画 +// 默认静态显示,BOOT按键触发眨眼+说话动画 +// 零图片资源,纯代码绘制 + +#include "../ui.h" +#include "ui_ScreenChar.h" +#include "esp_log.h" + +static const char *TAG = "CHAR"; + +lv_obj_t *ui_ScreenChar = NULL; + +// === 角色配色 === +#define COL_SKIN 0xFFD5B8 // 肤色 +#define COL_HAIR 0xFFD54F // 金黄色头发 +#define COL_EYE_WHITE 0xFFFFFF // 眼白 +#define COL_PUPIL 0x1565C0 // 蓝色瞳孔 +#define COL_MOUTH 0xE57373 // 粉红嘴巴 +#define COL_BLUSH 0xFFAB91 // 腮红 +#define COL_SHIRT 0x42A5F5 // 蓝色衣服 +#define COL_COLLAR 0xFFFFFF // 白色衣领 +#define COL_BG 0x1A1A2E // 深蓝背景 + +// === 角色布局坐标(基于360x360屏幕)=== +// 角色居中偏上,留出底部空间给提示文字 +#define CHAR_CX 180 // 角色中心X +#define FACE_CY 120 // 脸部中心Y +#define FACE_R 72 // 脸部半径 + +// 眼睛 +#define EYE_Y 110 // 眼睛Y +#define EYE_L_X 152 // 左眼X +#define EYE_R_X 208 // 右眼X +#define EYE_W 26 // 眼白宽度 +#define EYE_H 26 // 眼白高度(眨眼时变小) +#define PUPIL_R 7 // 瞳孔半径 + +// 嘴巴 +#define MOUTH_Y 155 // 嘴巴Y +#define MOUTH_W 24 // 嘴巴宽度 +#define MOUTH_H_IDLE 6 // 静态嘴巴高度(微笑线) +#define MOUTH_H_TALK 18 // 说话时嘴巴高度 + +// 身体 +#define NECK_Y 185 // 脖子顶部Y +#define NECK_W 28 // 脖子宽度 +#define NECK_H 18 // 脖子高度 +#define BODY_Y 203 // 身体顶部Y +#define BODY_W 160 // 肩宽 +#define BODY_H 160 // 身体高度(延伸到屏幕外) +#define SHOULDER_R 25 // 肩部圆角 + +// 胳膊 +#define ARM_W 28 // 胳膊宽度 +#define ARM_H 100 // 胳膊长度 +#define ARM_Y 215 // 胳膊顶部Y(肩膀下方) +#define ARM_L_X (CHAR_CX - BODY_W / 2 - ARM_W / 2 + 8) // 左胳膊X +#define ARM_R_X (CHAR_CX + BODY_W / 2 + ARM_W / 2 - 8) // 右胳膊X +#define HAND_R 16 // 手掌半径 + +// === 角色控件指针 === +static lv_obj_t *hair_obj = NULL; // 头发 +static lv_obj_t *face_obj = NULL; // 脸 +static lv_obj_t *eye_l_white = NULL; // 左眼白 +static lv_obj_t *eye_r_white = NULL; // 右眼白 +static lv_obj_t *pupil_l = NULL; // 左瞳孔 +static lv_obj_t *pupil_r = NULL; // 右瞳孔 +static lv_obj_t *blush_l = NULL; // 左腮红 +static lv_obj_t *blush_r = NULL; // 右腮红 +static lv_obj_t *mouth_obj = NULL; // 嘴巴 +static lv_obj_t *neck_obj = NULL; // 脖子 +static lv_obj_t *body_obj = NULL; // 身体/衣服 +static lv_obj_t *collar_l = NULL; // 左衣领 +static lv_obj_t *collar_r = NULL; // 右衣领 +static lv_obj_t *arm_l = NULL; // 左胳膊 +static lv_obj_t *arm_r = NULL; // 右胳膊 +static lv_obj_t *hand_l = NULL; // 左手 +static lv_obj_t *hand_r = NULL; // 右手 +static lv_obj_t *hint_label = NULL; // 提示文字 + +// === 动画状态 === +static lv_timer_t *blink_timer = NULL; // 眨眼定时器 +static lv_timer_t *mouth_timer = NULL; // 说话定时器 +static bool anim_playing = false; // 动画是否在播放 + +// 眨眼动画状态 +static uint8_t blink_phase = 0; // 0=睁眼 1=半闭 2=闭眼 3=半闭 +static uint32_t next_blink_ms = 0; // 下次眨眼时间 + +// 说话动画状态 +static uint8_t mouth_phase = 0; // 嘴巴帧索引 +static const lv_coord_t mouth_heights[] = {6, 12, 18, 14, 8, 14, 18, 12}; // 嘴巴高度序列 +#define MOUTH_FRAMES (sizeof(mouth_heights) / sizeof(mouth_heights[0])) + +// === 创建圆形对象的辅助函数 === +static lv_obj_t *create_circle(lv_obj_t *parent, lv_coord_t cx, lv_coord_t cy, + lv_coord_t w, lv_coord_t h, uint32_t color) { + lv_obj_t *obj = lv_obj_create(parent); + lv_obj_remove_style_all(obj); + lv_obj_set_size(obj, w, h); + lv_obj_set_pos(obj, cx - w / 2, cy - h / 2); + lv_obj_set_style_bg_color(obj, lv_color_hex(color), 0); + lv_obj_set_style_bg_opa(obj, LV_OPA_COVER, 0); + lv_obj_set_style_radius(obj, LV_RADIUS_CIRCLE, 0); + lv_obj_set_style_border_width(obj, 0, 0); + lv_obj_clear_flag(obj, LV_OBJ_FLAG_SCROLLABLE | LV_OBJ_FLAG_CLICKABLE); + return obj; +} + +// 创建矩形/圆角矩形 +static lv_obj_t *create_rect(lv_obj_t *parent, lv_coord_t x, lv_coord_t y, + lv_coord_t w, lv_coord_t h, uint32_t color, lv_coord_t radius) { + lv_obj_t *obj = lv_obj_create(parent); + lv_obj_remove_style_all(obj); + lv_obj_set_size(obj, w, h); + lv_obj_set_pos(obj, x, y); + lv_obj_set_style_bg_color(obj, lv_color_hex(color), 0); + lv_obj_set_style_bg_opa(obj, LV_OPA_COVER, 0); + lv_obj_set_style_radius(obj, radius, 0); + lv_obj_set_style_border_width(obj, 0, 0); + lv_obj_clear_flag(obj, LV_OBJ_FLAG_SCROLLABLE | LV_OBJ_FLAG_CLICKABLE); + return obj; +} + +// === 绘制角色 === +static void draw_character(lv_obj_t *screen) { + // 1. 胳膊(最底层,被身体部分遮挡) + // 左胳膊(衣袖) + arm_l = create_rect(screen, ARM_L_X - ARM_W / 2, ARM_Y, + ARM_W, ARM_H, COL_SHIRT, ARM_W / 2); + // 右胳膊(衣袖) + arm_r = create_rect(screen, ARM_R_X - ARM_W / 2, ARM_Y, + ARM_W, ARM_H, COL_SHIRT, ARM_W / 2); + // 左手(肤色圆形) + hand_l = create_circle(screen, ARM_L_X, ARM_Y + ARM_H - 5, + HAND_R * 2, HAND_R * 2, COL_SKIN); + // 右手(肤色圆形) + hand_r = create_circle(screen, ARM_R_X, ARM_Y + ARM_H - 5, + HAND_R * 2, HAND_R * 2, COL_SKIN); + + // 2. 身体/衣服 + body_obj = create_rect(screen, + CHAR_CX - BODY_W / 2, BODY_Y, + BODY_W, BODY_H, COL_SHIRT, SHOULDER_R); + + // 3. 衣领(V形,用两个斜矩形模拟) + collar_l = create_rect(screen, + CHAR_CX - 18, BODY_Y, + 20, 28, COL_COLLAR, 3); + lv_obj_set_style_transform_angle(collar_l, 200, 0); // 旋转20度 + + collar_r = create_rect(screen, + CHAR_CX - 2, BODY_Y, + 20, 28, COL_COLLAR, 3); + lv_obj_set_style_transform_angle(collar_r, -200, 0); // 旋转-20度 + + // 3. 脖子 + neck_obj = create_rect(screen, + CHAR_CX - NECK_W / 2, NECK_Y, + NECK_W, NECK_H, COL_SKIN, 5); + + // 4. 头发(脸后面的半圆,稍大于脸) + hair_obj = create_circle(screen, CHAR_CX, FACE_CY - 5, + FACE_R * 2 + 16, FACE_R * 2 + 16, COL_HAIR); + + // 头发刘海(额头上方的矩形) + create_rect(screen, + CHAR_CX - FACE_R - 2, FACE_CY - FACE_R - 10, + FACE_R * 2 + 4, 35, COL_HAIR, 8); + + // 5. 脸(圆形) + face_obj = create_circle(screen, CHAR_CX, FACE_CY, + FACE_R * 2, FACE_R * 2, COL_SKIN); + + // 6. 腮红 + blush_l = create_circle(screen, EYE_L_X - 5, EYE_Y + 18, 22, 12, COL_BLUSH); + lv_obj_set_style_bg_opa(blush_l, LV_OPA_60, 0); + blush_r = create_circle(screen, EYE_R_X + 5, EYE_Y + 18, 22, 12, COL_BLUSH); + lv_obj_set_style_bg_opa(blush_r, LV_OPA_60, 0); + + // 7. 眼睛(眼白 + 瞳孔) + eye_l_white = create_circle(screen, EYE_L_X, EYE_Y, EYE_W, EYE_H, COL_EYE_WHITE); + eye_r_white = create_circle(screen, EYE_R_X, EYE_Y, EYE_W, EYE_H, COL_EYE_WHITE); + + pupil_l = create_circle(screen, EYE_L_X, EYE_Y + 2, PUPIL_R * 2, PUPIL_R * 2, COL_PUPIL); + pupil_r = create_circle(screen, EYE_R_X, EYE_Y + 2, PUPIL_R * 2, PUPIL_R * 2, COL_PUPIL); + + // 眼睛高光(小白点) + create_circle(screen, EYE_L_X + 3, EYE_Y - 1, 5, 5, COL_EYE_WHITE); + create_circle(screen, EYE_R_X + 3, EYE_Y - 1, 5, 5, COL_EYE_WHITE); + + // 8. 眉毛(深棕色,黄毛配深眉更协调) + lv_obj_t *brow_l = create_rect(screen, EYE_L_X - 14, EYE_Y - 20, 22, 4, 0x5D4037, 2); + lv_obj_set_style_transform_angle(brow_l, -50, 0); // 微微倾斜 + lv_obj_t *brow_r = create_rect(screen, EYE_R_X - 8, EYE_Y - 20, 22, 4, 0x5D4037, 2); + lv_obj_set_style_transform_angle(brow_r, 50, 0); + + // 9. 鼻子(小三角,用一个很小的圆角矩形) + create_circle(screen, CHAR_CX, FACE_CY + 12, 6, 6, 0xFFBCA0); + + // 10. 嘴巴(椭圆形,高度可变实现说话效果) + mouth_obj = create_circle(screen, CHAR_CX, MOUTH_Y, + MOUTH_W, MOUTH_H_IDLE, COL_MOUTH); +} + +// === 眨眼动画回调 === +static void blink_timer_cb(lv_timer_t *t) { + if (!anim_playing || !eye_l_white || !eye_r_white) return; + + uint32_t now = lv_tick_get(); + + if (blink_phase == 0) { + // 睁眼状态,等待下次眨眼 + if (now < next_blink_ms) return; + blink_phase = 1; + } + + // 眨眼帧序列:睁眼26 → 半闭12 → 闭眼3 → 半闭12 → 睁眼26 + static const lv_coord_t eye_h[] = {12, 3, 12, EYE_H}; + lv_coord_t h = eye_h[blink_phase - 1]; + + // 更新眼睛高度(模拟眨眼) + lv_obj_set_height(eye_l_white, h); + lv_obj_set_y(eye_l_white, EYE_Y - h / 2); + lv_obj_set_height(eye_r_white, h); + lv_obj_set_y(eye_r_white, EYE_Y - h / 2); + + // 瞳孔跟随(闭眼时隐藏) + if (h <= 5) { + lv_obj_add_flag(pupil_l, LV_OBJ_FLAG_HIDDEN); + lv_obj_add_flag(pupil_r, LV_OBJ_FLAG_HIDDEN); + } else { + lv_obj_clear_flag(pupil_l, LV_OBJ_FLAG_HIDDEN); + lv_obj_clear_flag(pupil_r, LV_OBJ_FLAG_HIDDEN); + } + + blink_phase++; + if (blink_phase > 4) { + blink_phase = 0; + // 随机间隔2-4秒后下次眨眼 + next_blink_ms = now + 2000 + (lv_tick_get() % 2000); + } +} + +// === 说话动画回调 === +static void mouth_timer_cb(lv_timer_t *t) { + if (!anim_playing || !mouth_obj) return; + + lv_coord_t h = mouth_heights[mouth_phase]; + lv_obj_set_height(mouth_obj, h); + lv_obj_set_y(mouth_obj, MOUTH_Y - h / 2); + + mouth_phase = (mouth_phase + 1) % MOUTH_FRAMES; +} + +// === 手势回调 === +static void ui_event_ScreenChar(lv_event_t *e) { + lv_event_code_t code = lv_event_get_code(e); + if (code == LV_EVENT_GESTURE) { + lv_dir_t dir = lv_indev_get_gesture_dir(lv_indev_get_act()); + // 下滑返回ScreenImg + if (dir == LV_DIR_BOTTOM) { + lv_indev_wait_release(lv_indev_get_act()); + char_anim_stop(); + _ui_screen_change(&ui_ScreenImg, LV_SCR_LOAD_ANIM_NONE, 0, 0, &ui_ScreenImg_screen_init); + } + // 左滑/右滑返回Home + if (dir == LV_DIR_LEFT || dir == LV_DIR_RIGHT) { + lv_indev_wait_release(lv_indev_get_act()); + char_anim_stop(); + _ui_screen_change(&ui_ScreenHome, LV_SCR_LOAD_ANIM_NONE, 0, 0, &ui_ScreenHome_screen_init); + } + } +} + +// === 界面初始化 === +void ui_ScreenChar_screen_init(void) { + ui_ScreenChar = lv_obj_create(NULL); + lv_obj_clear_flag(ui_ScreenChar, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_set_style_bg_color(ui_ScreenChar, lv_color_hex(COL_BG), LV_PART_MAIN); + lv_obj_set_style_bg_opa(ui_ScreenChar, 255, LV_PART_MAIN); + + // 绘制角色 + draw_character(ui_ScreenChar); + + // 提示标签 + hint_label = lv_label_create(ui_ScreenChar); + lv_label_set_text(hint_label, "BOOT: Talk"); + lv_obj_set_align(hint_label, LV_ALIGN_BOTTOM_MID); + lv_obj_set_y(hint_label, -15); + lv_obj_set_style_text_color(hint_label, lv_color_hex(0x666688), LV_PART_MAIN); + lv_obj_set_style_text_font(hint_label, &lv_font_montserrat_14, LV_PART_MAIN); + + // 手势:下滑返回Img,左右滑返回Home + lv_obj_add_flag(ui_ScreenChar, LV_OBJ_FLAG_CLICKABLE); + lv_obj_add_flag(ui_ScreenChar, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_add_event_cb(ui_ScreenChar, ui_event_ScreenChar, LV_EVENT_ALL, NULL); + + ESP_LOGI(TAG, "ScreenChar界面初始化完成"); +} + +void ui_ScreenChar_screen_destroy(void) { + char_anim_stop(); + if (ui_ScreenChar) lv_obj_del(ui_ScreenChar); + ui_ScreenChar = NULL; + // 所有子控件随屏幕一起销毁,只需清空指针 + face_obj = hair_obj = NULL; + eye_l_white = eye_r_white = NULL; + pupil_l = pupil_r = NULL; + blush_l = blush_r = NULL; + mouth_obj = neck_obj = body_obj = NULL; + collar_l = collar_r = NULL; + arm_l = arm_r = hand_l = hand_r = NULL; + hint_label = NULL; +} + +// === 动画控制接口 === + +void char_anim_start(void) { + if (anim_playing) return; + anim_playing = true; + blink_phase = 0; + mouth_phase = 0; + next_blink_ms = lv_tick_get() + 500; // 0.5秒后第一次眨眼 + + // 眨眼定时器:50ms间隔(眨眼帧切换速度) + blink_timer = lv_timer_create(blink_timer_cb, 50, NULL); + // 说话定时器:80ms间隔(嘴巴变化速度) + mouth_timer = lv_timer_create(mouth_timer_cb, 80, NULL); + + // 更新提示 + if (hint_label) { + lv_label_set_text(hint_label, "Speaking..."); + lv_obj_set_style_text_color(hint_label, lv_color_hex(0x42A5F5), LV_PART_MAIN); + } + + ESP_LOGI(TAG, "角色动画启动(序列帧)"); +} + +void char_anim_stop(void) { + if (!anim_playing) return; + anim_playing = false; + + // 删除定时器 + if (blink_timer) { + lv_timer_del(blink_timer); + blink_timer = NULL; + } + if (mouth_timer) { + lv_timer_del(mouth_timer); + mouth_timer = NULL; + } + + // 恢复静态状态 + if (eye_l_white) { + lv_obj_set_height(eye_l_white, EYE_H); + lv_obj_set_y(eye_l_white, EYE_Y - EYE_H / 2); + } + if (eye_r_white) { + lv_obj_set_height(eye_r_white, EYE_H); + lv_obj_set_y(eye_r_white, EYE_Y - EYE_H / 2); + } + if (pupil_l) lv_obj_clear_flag(pupil_l, LV_OBJ_FLAG_HIDDEN); + if (pupil_r) lv_obj_clear_flag(pupil_r, LV_OBJ_FLAG_HIDDEN); + if (mouth_obj) { + lv_obj_set_height(mouth_obj, MOUTH_H_IDLE); + lv_obj_set_y(mouth_obj, MOUTH_Y - MOUTH_H_IDLE / 2); + } + + // 恢复提示 + if (hint_label) { + lv_label_set_text(hint_label, "BOOT: Talk"); + lv_obj_set_style_text_color(hint_label, lv_color_hex(0x666688), LV_PART_MAIN); + } + + ESP_LOGI(TAG, "角色动画停止"); +} + +bool char_anim_is_playing(void) { + return anim_playing; +} diff --git a/main/ui/screens/ui_ScreenChar.h b/main/ui/screens/ui_ScreenChar.h new file mode 100644 index 0000000..b9d9c7f --- /dev/null +++ b/main/ui/screens/ui_ScreenChar.h @@ -0,0 +1,25 @@ +// 动漫角色界面 - LVGL图形基元绘制 + 序列帧动画 +#ifndef UI_SCREENCHAR_H +#define UI_SCREENCHAR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "lvgl.h" + +// SCREEN: ui_ScreenChar +extern void ui_ScreenChar_screen_init(void); +extern void ui_ScreenChar_screen_destroy(void); +extern lv_obj_t *ui_ScreenChar; + +// 角色动画控制(BOOT按键触发) +void char_anim_start(void); // 开始眨眼+说话动画 +void char_anim_stop(void); // 停止动画,恢复静态 +bool char_anim_is_playing(void); // 查询动画是否在播放 + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif diff --git a/main/ui/screens/ui_ScreenImg.c b/main/ui/screens/ui_ScreenImg.c index bf0b872..226ff82 100644 --- a/main/ui/screens/ui_ScreenImg.c +++ b/main/ui/screens/ui_ScreenImg.c @@ -109,7 +109,10 @@ lv_indev_wait_release(lv_indev_get_act()); pages_cleanup_gif(); #endif ui_ScreenImg_hide_delete_container(); - _ui_screen_change( &ui_ScreenHome, LV_SCR_LOAD_ANIM_NONE, 0, 0, &ui_ScreenHome_screen_init); + // 上滑进入角色动画界面 + _ui_screen_change( &ui_ScreenChar, LV_SCR_LOAD_ANIM_NONE, 0, 0, &ui_ScreenChar_screen_init); + // 原有上滑返回Home(如需切换回来,注释上面一行,取消下面一行注释) + // _ui_screen_change( &ui_ScreenHome, LV_SCR_LOAD_ANIM_NONE, 0, 0, &ui_ScreenHome_screen_init); } if ( event_code == LV_EVENT_GESTURE && lv_indev_get_gesture_dir(lv_indev_get_act()) == LV_DIR_BOTTOM ) { lv_indev_wait_release(lv_indev_get_act()); diff --git a/main/ui/ui.h b/main/ui/ui.h index ac1bf46..7b4cf9d 100644 --- a/main/ui/ui.h +++ b/main/ui/ui.h @@ -19,6 +19,7 @@ extern "C" { #include "screens/ui_ScreenHome.h" #include "screens/ui_ScreenSet.h" #include "screens/ui_ScreenImg.h" +#include "screens/ui_ScreenChar.h" ///////////////////// VARIABLES //////////////////// diff --git a/sdkconfig b/sdkconfig index bdfc89f..fc356d0 100644 --- a/sdkconfig +++ b/sdkconfig @@ -2826,7 +2826,7 @@ CONFIG_LV_FS_POSIX_CACHE_SIZE=0 # CONFIG_LV_USE_PNG is not set # CONFIG_LV_USE_BMP is not set # CONFIG_LV_USE_SJPG is not set -# CONFIG_LV_USE_GIF is not set +CONFIG_LV_USE_GIF=y # CONFIG_LV_USE_QRCODE is not set # CONFIG_LV_USE_FREETYPE is not set # CONFIG_LV_USE_TINY_TTF is not set