11#include " electron_emoji_display.h"
2- #include " lvgl_theme.h"
32
43#include < esp_log.h>
5- #include < font_awesome.h>
64
7- #include < algorithm>
85#include < cstring>
9- #include < string>
6+
7+ #include " assets/lang_config.h"
8+ #include " display/lvgl_display/emoji_collection.h"
9+ #include " display/lvgl_display/lvgl_image.h"
10+ #include " display/lvgl_display/lvgl_theme.h"
11+ #include " otto_emoji_gif.h"
1012
1113#define TAG " ElectronEmojiDisplay"
14+ ElectronEmojiDisplay::ElectronEmojiDisplay (esp_lcd_panel_io_handle_t panel_io, esp_lcd_panel_handle_t panel, int width, int height, int offset_x, int offset_y, bool mirror_x, bool mirror_y,
15+ bool swap_xy)
16+ : SpiLcdDisplay(panel_io, panel, width, height, offset_x, offset_y, mirror_x, mirror_y, swap_xy) {
17+ InitializeElectronEmojis ();
18+ SetupChatLabel ();
19+ }
20+
21+ void ElectronEmojiDisplay::InitializeElectronEmojis () {
22+ ESP_LOGI (TAG, " 初始化Electron GIF表情" );
23+
24+ auto otto_emoji_collection = std::make_shared<EmojiCollection>();
1225
13- // 表情映射表 - 将多种表情映射到现有6个GIF
14- const ElectronEmojiDisplay::EmotionMap ElectronEmojiDisplay::emotion_maps_[] = {
1526 // 中性/平静类表情 -> staticstate
16- {" neutral" , &staticstate},
17- {" relaxed" , &staticstate},
18- {" sleepy" , &staticstate},
27+ otto_emoji_collection->AddEmoji (" staticstate" , new LvglRawImage ((void *)staticstate.data , staticstate.data_size ));
28+ otto_emoji_collection->AddEmoji (" neutral" , new LvglRawImage ((void *)staticstate.data , staticstate.data_size ));
29+ otto_emoji_collection->AddEmoji (" relaxed" , new LvglRawImage ((void *)staticstate.data , staticstate.data_size ));
30+ otto_emoji_collection->AddEmoji (" sleepy" , new LvglRawImage ((void *)staticstate.data , staticstate.data_size ));
31+ otto_emoji_collection->AddEmoji (" idle" , new LvglRawImage ((void *)staticstate.data , staticstate.data_size ));
1932
2033 // 积极/开心类表情 -> happy
21- { " happy" , & happy},
22- { " laughing" , & happy},
23- { " funny" , & happy},
24- { " loving" , & happy},
25- { " confident" , & happy},
26- { " winking" , & happy},
27- { " cool" , & happy},
28- { " delicious" , & happy},
29- { " kissy" , & happy},
30- { " silly" , & happy},
34+ otto_emoji_collection-> AddEmoji ( " happy" , new LvglRawImage (( void *) happy. data , happy. data_size ));
35+ otto_emoji_collection-> AddEmoji ( " laughing" , new LvglRawImage (( void *) happy. data , happy. data_size ));
36+ otto_emoji_collection-> AddEmoji ( " funny" , new LvglRawImage (( void *) happy. data , happy. data_size ));
37+ otto_emoji_collection-> AddEmoji ( " loving" , new LvglRawImage (( void *) happy. data , happy. data_size ));
38+ otto_emoji_collection-> AddEmoji ( " confident" , new LvglRawImage (( void *) happy. data , happy. data_size ));
39+ otto_emoji_collection-> AddEmoji ( " winking" , new LvglRawImage (( void *) happy. data , happy. data_size ));
40+ otto_emoji_collection-> AddEmoji ( " cool" , new LvglRawImage (( void *) happy. data , happy. data_size ));
41+ otto_emoji_collection-> AddEmoji ( " delicious" , new LvglRawImage (( void *) happy. data , happy. data_size ));
42+ otto_emoji_collection-> AddEmoji ( " kissy" , new LvglRawImage (( void *) happy. data , happy. data_size ));
43+ otto_emoji_collection-> AddEmoji ( " silly" , new LvglRawImage (( void *) happy. data , happy. data_size ));
3144
3245 // 悲伤类表情 -> sad
33- { " sad" , & sad},
34- { " crying" , & sad},
46+ otto_emoji_collection-> AddEmoji ( " sad" , new LvglRawImage (( void *) sad. data , sad. data_size ));
47+ otto_emoji_collection-> AddEmoji ( " crying" , new LvglRawImage (( void *) sad. data , sad. data_size ));
3548
3649 // 愤怒类表情 -> anger
37- {" angry" , &anger},
50+ otto_emoji_collection->AddEmoji (" anger" , new LvglRawImage ((void *)anger.data , anger.data_size ));
51+ otto_emoji_collection->AddEmoji (" angry" , new LvglRawImage ((void *)anger.data , anger.data_size ));
3852
3953 // 惊讶类表情 -> scare
40- {" surprised" , &scare},
41- {" shocked" , &scare},
54+ otto_emoji_collection->AddEmoji (" scare" , new LvglRawImage ((void *)scare.data , scare.data_size ));
55+ otto_emoji_collection->AddEmoji (" surprised" , new LvglRawImage ((void *)scare.data , scare.data_size ));
56+ otto_emoji_collection->AddEmoji (" shocked" , new LvglRawImage ((void *)scare.data , scare.data_size ));
4257
4358 // 思考/困惑类表情 -> buxue
44- {" thinking" , &buxue},
45- {" confused" , &buxue},
46- {" embarrassed" , &buxue},
47-
48- {nullptr , nullptr } // 结束标记
49- };
50-
51- ElectronEmojiDisplay::ElectronEmojiDisplay (esp_lcd_panel_io_handle_t panel_io,
52- esp_lcd_panel_handle_t panel, int width, int height,
53- int offset_x, int offset_y, bool mirror_x, bool mirror_y,
54- bool swap_xy)
55- : SpiLcdDisplay(panel_io, panel, width, height, offset_x, offset_y, mirror_x, mirror_y, swap_xy),
56- emotion_gif_(nullptr ) {
57- SetupGifContainer ();
58- }
59+ otto_emoji_collection->AddEmoji (" buxue" , new LvglRawImage ((void *)buxue.data , buxue.data_size ));
60+ otto_emoji_collection->AddEmoji (" thinking" , new LvglRawImage ((void *)buxue.data , buxue.data_size ));
61+ otto_emoji_collection->AddEmoji (" confused" , new LvglRawImage ((void *)buxue.data , buxue.data_size ));
62+ otto_emoji_collection->AddEmoji (" embarrassed" , new LvglRawImage ((void *)buxue.data , buxue.data_size ));
5963
60- void ElectronEmojiDisplay::SetupGifContainer () {
61- DisplayLockGuard lock (this );
64+ // 将表情集合添加到主题中
65+ auto & theme_manager = LvglThemeManager::GetInstance ();
66+ auto light_theme = theme_manager.GetTheme (" light" );
67+ auto dark_theme = theme_manager.GetTheme (" dark" );
6268
63- if (emoji_label_) {
64- lv_obj_del (emoji_label_);
65- }
66- if (chat_message_label_) {
67- lv_obj_del (chat_message_label_);
69+ if (light_theme != nullptr ) {
70+ light_theme->set_emoji_collection (otto_emoji_collection);
6871 }
69- if (content_ ) {
70- lv_obj_del (content_ );
72+ if (dark_theme != nullptr ) {
73+ dark_theme-> set_emoji_collection (otto_emoji_collection );
7174 }
7275
73- content_ = lv_obj_create (container_);
74- lv_obj_set_scrollbar_mode (content_, LV_SCROLLBAR_MODE_OFF);
75- lv_obj_set_size (content_, LV_HOR_RES, LV_HOR_RES);
76- lv_obj_set_style_bg_opa (content_, LV_OPA_TRANSP, 0 );
77- lv_obj_set_style_border_width (content_, 0 , 0 );
78- lv_obj_set_flex_grow (content_, 1 );
79- lv_obj_center (content_);
80-
81- emoji_label_ = lv_label_create (content_);
82- lv_label_set_text (emoji_label_, " " );
83- lv_obj_set_width (emoji_label_, 0 );
84- lv_obj_set_style_border_width (emoji_label_, 0 , 0 );
85- lv_obj_add_flag (emoji_label_, LV_OBJ_FLAG_HIDDEN);
86-
87- emotion_gif_ = lv_gif_create (content_);
88- int gif_size = LV_HOR_RES;
89- lv_obj_set_size (emotion_gif_, gif_size, gif_size);
90- lv_obj_set_style_border_width (emotion_gif_, 0 , 0 );
91- lv_obj_set_style_bg_opa (emotion_gif_, LV_OPA_TRANSP, 0 );
92- lv_obj_center (emotion_gif_);
93- lv_gif_set_src (emotion_gif_, &staticstate);
94-
95- chat_message_label_ = lv_label_create (content_);
96- lv_label_set_text (chat_message_label_, " " );
97- lv_obj_set_width (chat_message_label_, LV_HOR_RES * 0.9 );
98- lv_label_set_long_mode (chat_message_label_, LV_LABEL_LONG_SCROLL_CIRCULAR);
99- lv_obj_set_style_text_align (chat_message_label_, LV_TEXT_ALIGN_CENTER, 0 );
100- lv_obj_set_style_text_color (chat_message_label_, lv_color_white (), 0 );
101- lv_obj_set_style_border_width (chat_message_label_, 0 , 0 );
76+ // 设置默认表情为staticstate
77+ SetEmotion (" staticstate" );
10278
103- lv_obj_set_style_bg_opa (chat_message_label_, LV_OPA_70, 0 );
104- lv_obj_set_style_bg_color (chat_message_label_, lv_color_black (), 0 );
105- lv_obj_set_style_pad_ver (chat_message_label_, 5 , 0 );
106-
107- lv_obj_align (chat_message_label_, LV_ALIGN_BOTTOM_MID, 0 , 0 );
108-
109- auto & theme_manager = LvglThemeManager::GetInstance ();
110- auto theme = theme_manager.GetTheme (" dark" );
111- if (theme != nullptr ) {
112- LcdDisplay::SetTheme (theme);
113- }
79+ ESP_LOGI (TAG, " Electron GIF表情初始化完成" );
11480}
11581
116- void ElectronEmojiDisplay::SetEmotion (const char * emotion) {
117- if (!emotion || !emotion_gif_) {
118- return ;
119- }
120-
82+ void ElectronEmojiDisplay::SetupChatLabel () {
12183 DisplayLockGuard lock (this );
12284
123- for (const auto & map : emotion_maps_) {
124- if (map.name && strcmp (map.name , emotion) == 0 ) {
125- lv_gif_set_src (emotion_gif_, map.gif );
126- ESP_LOGI (TAG, " 设置表情: %s" , emotion);
127- return ;
128- }
85+ if (chat_message_label_) {
86+ lv_obj_del (chat_message_label_);
12987 }
13088
131- lv_gif_set_src (emotion_gif_, &staticstate);
132- ESP_LOGI (TAG, " 未知表情'%s',使用默认" , emotion);
89+ chat_message_label_ = lv_label_create (container_);
90+ lv_label_set_text (chat_message_label_, " " );
91+ lv_obj_set_width (chat_message_label_, width_ * 0.9 ); // 限制宽度为屏幕宽度的 90%
92+ lv_label_set_long_mode (chat_message_label_, LV_LABEL_LONG_WRAP); // 设置为自动换行模式
93+ lv_obj_set_style_text_align (chat_message_label_, LV_TEXT_ALIGN_CENTER, 0 ); // 设置文本居中对齐
94+ lv_obj_set_style_text_color (chat_message_label_, lv_color_white (), 0 );
95+ SetTheme (LvglThemeManager::GetInstance ().GetTheme (" dark" ));
13396}
13497
135- void ElectronEmojiDisplay::SetChatMessage (const char * role, const char * content) {
98+ LV_FONT_DECLARE (OTTO_ICON_FONT);
99+ void ElectronEmojiDisplay::SetStatus (const char * status) {
100+ auto lvgl_theme = static_cast <LvglTheme*>(current_theme_);
101+ auto text_font = lvgl_theme->text_font ()->font ();
136102 DisplayLockGuard lock (this );
137- if (chat_message_label_ == nullptr ) {
103+ if (!status) {
104+ ESP_LOGE (TAG, " SetStatus: status is nullptr" );
138105 return ;
139106 }
140107
141- if (content == nullptr || strlen (content) == 0 ) {
142- lv_obj_add_flag (chat_message_label_, LV_OBJ_FLAG_HIDDEN);
108+ if (strcmp (status, Lang::Strings::LISTENING) == 0 ) {
109+ lv_obj_set_style_text_font (status_label_, &OTTO_ICON_FONT, 0 );
110+ lv_label_set_text (status_label_, " \xEF\x84\xB0 " ); // U+F130 麦克风图标
111+ lv_obj_clear_flag (status_label_, LV_OBJ_FLAG_HIDDEN);
112+ lv_obj_add_flag (network_label_, LV_OBJ_FLAG_HIDDEN);
113+ lv_obj_add_flag (battery_label_, LV_OBJ_FLAG_HIDDEN);
114+ return ;
115+ } else if (strcmp (status, Lang::Strings::SPEAKING) == 0 ) {
116+ lv_obj_set_style_text_font (status_label_, &OTTO_ICON_FONT, 0 );
117+ lv_label_set_text (status_label_, " \xEF\x80\xA8 " ); // U+F028 说话图标
118+ lv_obj_clear_flag (status_label_, LV_OBJ_FLAG_HIDDEN);
119+ lv_obj_add_flag (network_label_, LV_OBJ_FLAG_HIDDEN);
120+ lv_obj_add_flag (battery_label_, LV_OBJ_FLAG_HIDDEN);
121+ return ;
122+ } else if (strcmp (status, Lang::Strings::CONNECTING) == 0 ) {
123+ lv_obj_set_style_text_font (status_label_, &OTTO_ICON_FONT, 0 );
124+ lv_label_set_text (status_label_, " \xEF\x83\x81 " ); // U+F0c1 连接图标
125+ lv_obj_clear_flag (status_label_, LV_OBJ_FLAG_HIDDEN);
126+ return ;
127+ } else if (strcmp (status, Lang::Strings::STANDBY) == 0 ) {
128+ lv_obj_set_style_text_font (status_label_, text_font, 0 );
129+ lv_label_set_text (status_label_, " " );
130+ lv_obj_clear_flag (status_label_, LV_OBJ_FLAG_HIDDEN);
143131 return ;
144132 }
145133
146- lv_label_set_text (chat_message_label_, content);
147- lv_obj_remove_flag (chat_message_label_, LV_OBJ_FLAG_HIDDEN);
148-
149- ESP_LOGI (TAG, " 设置聊天消息 [%s]: %s" , role, content);
134+ lv_obj_set_style_text_font (status_label_, text_font, 0 );
135+ lv_label_set_text (status_label_, status);
136+ lv_obj_clear_flag (status_label_, LV_OBJ_FLAG_HIDDEN);
137+ lv_obj_clear_flag (network_label_, LV_OBJ_FLAG_HIDDEN);
138+ lv_obj_clear_flag (battery_label_, LV_OBJ_FLAG_HIDDEN);
150139}
0 commit comments