display.cc 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. #include <esp_log.h>
  2. #include <esp_err.h>
  3. #include <string>
  4. #include <cstdlib>
  5. #include <cstring>
  6. #include "display.h"
  7. #include "board.h"
  8. #include "application.h"
  9. #include "font_awesome_symbols.h"
  10. #include "audio_codec.h"
  11. #include "settings.h"
  12. #include "assets/lang_config.h"
  13. #define TAG "Display"
  14. Display::Display() {
  15. // // Notification timer
  16. // esp_timer_create_args_t notification_timer_args = {
  17. // .callback = [](void *arg) {
  18. // Display *display = static_cast<Display*>(arg);
  19. // DisplayLockGuard lock(display);
  20. // lv_obj_add_flag(display->notification_label_, LV_OBJ_FLAG_HIDDEN);
  21. // lv_obj_clear_flag(display->status_label_, LV_OBJ_FLAG_HIDDEN);
  22. // },
  23. // .arg = this,
  24. // .dispatch_method = ESP_TIMER_TASK,
  25. // .name = "notification_timer",
  26. // .skip_unhandled_events = false,
  27. // };
  28. // ESP_ERROR_CHECK(esp_timer_create(&notification_timer_args, &notification_timer_));
  29. // // Create a power management lock
  30. // auto ret = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "display_update", &pm_lock_);
  31. // if (ret == ESP_ERR_NOT_SUPPORTED) {
  32. // ESP_LOGI(TAG, "Power management not supported");
  33. // } else {
  34. // ESP_ERROR_CHECK(ret);
  35. // }
  36. }
  37. Display::~Display() {
  38. // if (notification_timer_ != nullptr) {
  39. // esp_timer_stop(notification_timer_);
  40. // esp_timer_delete(notification_timer_);
  41. // }
  42. // if (network_label_ != nullptr) {
  43. // lv_obj_del(network_label_);
  44. // lv_obj_del(notification_label_);
  45. // lv_obj_del(status_label_);
  46. // lv_obj_del(mute_label_);
  47. // lv_obj_del(battery_label_);
  48. // lv_obj_del(emotion_label_);
  49. // }
  50. // if( low_battery_popup_ != nullptr ) {
  51. // lv_obj_del(low_battery_popup_);
  52. // }
  53. // if (pm_lock_ != nullptr) {
  54. // esp_pm_lock_delete(pm_lock_);
  55. // }
  56. }
  57. void Display::SetStatus(const char* status) {
  58. // DisplayLockGuard lock(this);
  59. // if (status_label_ == nullptr) {
  60. // return;
  61. // }
  62. // lv_label_set_text(status_label_, status);
  63. // lv_obj_clear_flag(status_label_, LV_OBJ_FLAG_HIDDEN);
  64. // lv_obj_add_flag(notification_label_, LV_OBJ_FLAG_HIDDEN);
  65. // last_status_update_time_ = std::chrono::system_clock::now();
  66. }
  67. void Display::ShowNotification(const std::string &notification, int duration_ms) {
  68. ShowNotification(notification.c_str(), duration_ms);
  69. }
  70. void Display::ShowNotification(const char* notification, int duration_ms) {
  71. // DisplayLockGuard lock(this);
  72. // if (notification_label_ == nullptr) {
  73. // return;
  74. // }
  75. // lv_label_set_text(notification_label_, notification);
  76. // lv_obj_clear_flag(notification_label_, LV_OBJ_FLAG_HIDDEN);
  77. // lv_obj_add_flag(status_label_, LV_OBJ_FLAG_HIDDEN);
  78. // esp_timer_stop(notification_timer_);
  79. // ESP_ERROR_CHECK(esp_timer_start_once(notification_timer_, duration_ms * 1000));
  80. }
  81. void Display::UpdateStatusBar(bool update_all) {
  82. // auto& app = Application::GetInstance();
  83. // auto& board = Board::GetInstance();
  84. // auto codec = board.GetAudioCodec();
  85. // // Update mute icon
  86. // {
  87. // DisplayLockGuard lock(this);
  88. // if (mute_label_ == nullptr) {
  89. // return;
  90. // }
  91. // // 如果静音状态改变,则更新图标
  92. // if (codec->output_volume() == 0 && !muted_) {
  93. // muted_ = true;
  94. // lv_label_set_text(mute_label_, FONT_AWESOME_VOLUME_MUTE);
  95. // } else if (codec->output_volume() > 0 && muted_) {
  96. // muted_ = false;
  97. // lv_label_set_text(mute_label_, "");
  98. // }
  99. // }
  100. // // Update time
  101. // if (app.GetDeviceState() == kDeviceStateIdle) {
  102. // if (last_status_update_time_ + std::chrono::seconds(10) < std::chrono::system_clock::now()) {
  103. // // Set status to clock "HH:MM"
  104. // time_t now = time(NULL);
  105. // struct tm* tm = localtime(&now);
  106. // // Check if the we have already set the time
  107. // if (tm->tm_year >= 2025 - 1900) {
  108. // char time_str[16];
  109. // strftime(time_str, sizeof(time_str), "%H:%M ", tm);
  110. // SetStatus(time_str);
  111. // } else {
  112. // ESP_LOGW(TAG, "System time is not set, tm_year: %d", tm->tm_year);
  113. // }
  114. // }
  115. // }
  116. // esp_pm_lock_acquire(pm_lock_);
  117. // // 更新电池图标
  118. // int battery_level;
  119. // bool charging, discharging;
  120. // const char* icon = nullptr;
  121. // if (board.GetBatteryLevel(battery_level, charging, discharging)) {
  122. // if (charging) {
  123. // icon = FONT_AWESOME_BATTERY_CHARGING;
  124. // } else {
  125. // const char* levels[] = {
  126. // FONT_AWESOME_BATTERY_EMPTY, // 0-19%
  127. // FONT_AWESOME_BATTERY_1, // 20-39%
  128. // FONT_AWESOME_BATTERY_2, // 40-59%
  129. // FONT_AWESOME_BATTERY_3, // 60-79%
  130. // FONT_AWESOME_BATTERY_FULL, // 80-99%
  131. // FONT_AWESOME_BATTERY_FULL, // 100%
  132. // };
  133. // icon = levels[battery_level / 20];
  134. // }
  135. // DisplayLockGuard lock(this);
  136. // if (battery_label_ != nullptr && battery_icon_ != icon) {
  137. // battery_icon_ = icon;
  138. // lv_label_set_text(battery_label_, battery_icon_);
  139. // }
  140. // if (low_battery_popup_ != nullptr) {
  141. // if (strcmp(icon, FONT_AWESOME_BATTERY_EMPTY) == 0 && discharging) {
  142. // if (lv_obj_has_flag(low_battery_popup_, LV_OBJ_FLAG_HIDDEN)) { // 如果低电量提示框隐藏,则显示
  143. // lv_obj_clear_flag(low_battery_popup_, LV_OBJ_FLAG_HIDDEN);
  144. // app.PlaySound(Lang::Sounds::P3_LOW_BATTERY);
  145. // }
  146. // } else {
  147. // // Hide the low battery popup when the battery is not empty
  148. // if (!lv_obj_has_flag(low_battery_popup_, LV_OBJ_FLAG_HIDDEN)) { // 如果低电量提示框显示,则隐藏
  149. // lv_obj_add_flag(low_battery_popup_, LV_OBJ_FLAG_HIDDEN);
  150. // }
  151. // }
  152. // }
  153. // }
  154. // // 每 10 秒更新一次网络图标
  155. // static int seconds_counter = 0;
  156. // if (update_all || seconds_counter++ % 10 == 0) {
  157. // // 升级固件时,不读取 4G 网络状态,避免占用 UART 资源
  158. // auto device_state = Application::GetInstance().GetDeviceState();
  159. // static const std::vector<DeviceState> allowed_states = {
  160. // kDeviceStateIdle,
  161. // kDeviceStateStarting,
  162. // kDeviceStateWifiConfiguring,
  163. // kDeviceStateListening,
  164. // kDeviceStateActivating,
  165. // };
  166. // if (std::find(allowed_states.begin(), allowed_states.end(), device_state) != allowed_states.end()) {
  167. // icon = board.GetNetworkStateIcon();
  168. // if (network_label_ != nullptr && icon != nullptr && network_icon_ != icon) {
  169. // DisplayLockGuard lock(this);
  170. // network_icon_ = icon;
  171. // lv_label_set_text(network_label_, network_icon_);
  172. // }
  173. // }
  174. // }
  175. // esp_pm_lock_release(pm_lock_);
  176. }
  177. void Display::SetEmotion(const char* emotion) {
  178. // struct Emotion {
  179. // const char* icon;
  180. // const char* text;
  181. // };
  182. // static const std::vector<Emotion> emotions = {
  183. // {FONT_AWESOME_EMOJI_NEUTRAL, "neutral"},
  184. // {FONT_AWESOME_EMOJI_HAPPY, "happy"},
  185. // {FONT_AWESOME_EMOJI_LAUGHING, "laughing"},
  186. // {FONT_AWESOME_EMOJI_FUNNY, "funny"},
  187. // {FONT_AWESOME_EMOJI_SAD, "sad"},
  188. // {FONT_AWESOME_EMOJI_ANGRY, "angry"},
  189. // {FONT_AWESOME_EMOJI_CRYING, "crying"},
  190. // {FONT_AWESOME_EMOJI_LOVING, "loving"},
  191. // {FONT_AWESOME_EMOJI_EMBARRASSED, "embarrassed"},
  192. // {FONT_AWESOME_EMOJI_SURPRISED, "surprised"},
  193. // {FONT_AWESOME_EMOJI_SHOCKED, "shocked"},
  194. // {FONT_AWESOME_EMOJI_THINKING, "thinking"},
  195. // {FONT_AWESOME_EMOJI_WINKING, "winking"},
  196. // {FONT_AWESOME_EMOJI_COOL, "cool"},
  197. // {FONT_AWESOME_EMOJI_RELAXED, "relaxed"},
  198. // {FONT_AWESOME_EMOJI_DELICIOUS, "delicious"},
  199. // {FONT_AWESOME_EMOJI_KISSY, "kissy"},
  200. // {FONT_AWESOME_EMOJI_CONFIDENT, "confident"},
  201. // {FONT_AWESOME_EMOJI_SLEEPY, "sleepy"},
  202. // {FONT_AWESOME_EMOJI_SILLY, "silly"},
  203. // {FONT_AWESOME_EMOJI_CONFUSED, "confused"}
  204. // };
  205. // // 查找匹配的表情
  206. // std::string_view emotion_view(emotion);
  207. // auto it = std::find_if(emotions.begin(), emotions.end(),
  208. // [&emotion_view](const Emotion& e) { return e.text == emotion_view; });
  209. // DisplayLockGuard lock(this);
  210. // if (emotion_label_ == nullptr) {
  211. // return;
  212. // }
  213. // // 如果找到匹配的表情就显示对应图标,否则显示默认的neutral表情
  214. // if (it != emotions.end()) {
  215. // lv_label_set_text(emotion_label_, it->icon);
  216. // } else {
  217. // lv_label_set_text(emotion_label_, FONT_AWESOME_EMOJI_NEUTRAL);
  218. // }
  219. }
  220. void Display::SetIcon(const char* icon) {
  221. // DisplayLockGuard lock(this);
  222. // if (emotion_label_ == nullptr) {
  223. // return;
  224. // }
  225. // lv_label_set_text(emotion_label_, icon);
  226. }
  227. void Display::SetPreviewImage(const lv_img_dsc_t* image) {
  228. // Do nothing
  229. }
  230. void Display::SetChatMessage(const char* role, const char* content) {
  231. // DisplayLockGuard lock(this);
  232. // if (chat_message_label_ == nullptr) {
  233. // return;
  234. // }
  235. // lv_label_set_text(chat_message_label_, content);
  236. }
  237. void Display::SetTheme(const std::string& theme_name) {
  238. // current_theme_name_ = theme_name;
  239. // Settings settings("display", true);
  240. // settings.SetString("theme", theme_name);
  241. }
  242. void Display::ShowStandbyScreen(bool show) {
  243. // if (show) {
  244. // SetChatMessage("system", "");
  245. // SetEmotion("sleepy");
  246. // } else {
  247. // SetChatMessage("system", "");
  248. // SetEmotion("neutral");
  249. // }
  250. }