1. 新增AI对话LVGL界面(ai_chat_ui),支持emoji图片 + 状态文本 + 聊天消息 2. 新增7个emoji表情资源(64×64 PNG C数组):neutral/happy/sad/angry/crying/funny/laughing 3. 新增阿里巴巴普惠体20px 4bpp中文字体(GB2312字符集) 4. 利用火山RTC会话状态(VOLC_MSG_CONV_STATUS)驱动emoji切换: - LISTENING→happy, THINKING→neutral, ANSWERING→laughing - INTERRUPTED→funny, ANSWER_FINISH→happy 5. 设备状态emoji映射:Listening→happy, Speaking→laughing, Dialog→happy 6. 配网模式显示happy emoji 7. 分区优化:model 3MB→64KB,OTA 5MB→6.5MB 8. 编译优化:-Og→-Os,移除SimSun CJK字体 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
103 lines
3.3 KiB
C
103 lines
3.3 KiB
C
#include "ai_chat_ui.h"
|
||
#include "lvgl.h"
|
||
#include "esp_lvgl_port.h"
|
||
#include <string.h>
|
||
|
||
// 声明阿里巴巴普惠体 20px 4bpp(GB2312 简体中文+ASCII)
|
||
LV_FONT_DECLARE(font_puhui_20_4);
|
||
|
||
// 声明 emoji 图片资源
|
||
LV_IMG_DECLARE(ui_img_neutral_png);
|
||
LV_IMG_DECLARE(ui_img_happy_png);
|
||
LV_IMG_DECLARE(ui_img_sad_png);
|
||
LV_IMG_DECLARE(ui_img_angry_png);
|
||
LV_IMG_DECLARE(ui_img_crying_png);
|
||
LV_IMG_DECLARE(ui_img_funny_png);
|
||
LV_IMG_DECLARE(ui_img_laughing_png);
|
||
|
||
// 屏幕和控件
|
||
static lv_obj_t *ai_screen = NULL;
|
||
static lv_obj_t *emoji_img = NULL;
|
||
static lv_obj_t *status_label = NULL;
|
||
static lv_obj_t *chat_label = NULL;
|
||
|
||
// 背景色
|
||
#define BG_COLOR 0x121212
|
||
|
||
void ai_chat_screen_init(void) {
|
||
// 创建 AI 对话屏幕
|
||
ai_screen = lv_obj_create(NULL);
|
||
lv_obj_set_style_bg_color(ai_screen, lv_color_hex(BG_COLOR), 0);
|
||
lv_obj_set_style_bg_opa(ai_screen, 255, 0);
|
||
lv_obj_clear_flag(ai_screen, LV_OBJ_FLAG_SCROLLABLE);
|
||
|
||
// emoji 表情图片(屏幕中央偏上)
|
||
emoji_img = lv_img_create(ai_screen);
|
||
lv_img_set_src(emoji_img, &ui_img_neutral_png);
|
||
lv_obj_align(emoji_img, LV_ALIGN_CENTER, 0, -55);
|
||
|
||
// 状态文本(表情下方,居中)
|
||
status_label = lv_label_create(ai_screen);
|
||
lv_obj_set_style_text_font(status_label, &font_puhui_20_4, 0);
|
||
lv_obj_set_style_text_color(status_label, lv_color_white(), 0);
|
||
lv_obj_set_width(status_label, 300);
|
||
lv_obj_set_style_text_align(status_label, LV_TEXT_ALIGN_CENTER, 0);
|
||
lv_label_set_text(status_label, "正在初始化...");
|
||
lv_obj_align(status_label, LV_ALIGN_CENTER, 0, 5);
|
||
|
||
// 聊天消息文本(下半部分)
|
||
chat_label = lv_label_create(ai_screen);
|
||
lv_obj_set_style_text_font(chat_label, &font_puhui_20_4, 0);
|
||
lv_obj_set_style_text_color(chat_label, lv_color_hex(0xAAAAAA), 0);
|
||
lv_obj_set_width(chat_label, 300);
|
||
lv_obj_set_style_text_align(chat_label, LV_TEXT_ALIGN_LEFT, 0);
|
||
lv_label_set_text(chat_label, "");
|
||
lv_obj_align(chat_label, LV_ALIGN_CENTER, 0, 50);
|
||
lv_label_set_long_mode(chat_label, LV_LABEL_LONG_WRAP);
|
||
|
||
// 加载屏幕
|
||
lv_disp_load_scr(ai_screen);
|
||
}
|
||
|
||
void ai_chat_set_status(const char* status) {
|
||
if (!status_label) return;
|
||
lvgl_port_lock(50);
|
||
lv_label_set_text(status_label, status);
|
||
lvgl_port_unlock();
|
||
}
|
||
|
||
void ai_chat_set_emotion(const char* emotion) {
|
||
if (!emoji_img) return;
|
||
lvgl_port_lock(50);
|
||
|
||
const lv_img_dsc_t *img = &ui_img_neutral_png;
|
||
|
||
if (strcmp(emotion, "neutral") == 0) {
|
||
img = &ui_img_neutral_png;
|
||
} else if (strcmp(emotion, "happy") == 0) {
|
||
img = &ui_img_happy_png;
|
||
} else if (strcmp(emotion, "sad") == 0) {
|
||
img = &ui_img_sad_png;
|
||
} else if (strcmp(emotion, "angry") == 0) {
|
||
img = &ui_img_angry_png;
|
||
} else if (strcmp(emotion, "surprised") == 0) {
|
||
img = &ui_img_funny_png;
|
||
} else if (strcmp(emotion, "thinking") == 0) {
|
||
img = &ui_img_neutral_png;
|
||
} else if (strcmp(emotion, "crying") == 0) {
|
||
img = &ui_img_crying_png;
|
||
} else if (strcmp(emotion, "laughing") == 0) {
|
||
img = &ui_img_laughing_png;
|
||
}
|
||
|
||
lv_img_set_src(emoji_img, img);
|
||
lvgl_port_unlock();
|
||
}
|
||
|
||
void ai_chat_set_chat_message(const char* role, const char* content) {
|
||
if (!chat_label) return;
|
||
lvgl_port_lock(50);
|
||
lv_label_set_text(chat_label, content ? content : "");
|
||
lvgl_port_unlock();
|
||
}
|