#include #include #include #include #include #include "display.h" #include "board.h" #include "application.h" #include "font_awesome_symbols.h" #include "audio_codec.h" #include "settings.h" #include "assets/lang_config.h" #define TAG "Display" Display::Display() { // // Notification timer // esp_timer_create_args_t notification_timer_args = { // .callback = [](void *arg) { // Display *display = static_cast(arg); // DisplayLockGuard lock(display); // lv_obj_add_flag(display->notification_label_, LV_OBJ_FLAG_HIDDEN); // lv_obj_clear_flag(display->status_label_, LV_OBJ_FLAG_HIDDEN); // }, // .arg = this, // .dispatch_method = ESP_TIMER_TASK, // .name = "notification_timer", // .skip_unhandled_events = false, // }; // ESP_ERROR_CHECK(esp_timer_create(¬ification_timer_args, ¬ification_timer_)); // // Create a power management lock // auto ret = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "display_update", &pm_lock_); // if (ret == ESP_ERR_NOT_SUPPORTED) { // ESP_LOGI(TAG, "Power management not supported"); // } else { // ESP_ERROR_CHECK(ret); // } } Display::~Display() { // if (notification_timer_ != nullptr) { // esp_timer_stop(notification_timer_); // esp_timer_delete(notification_timer_); // } // if (network_label_ != nullptr) { // lv_obj_del(network_label_); // lv_obj_del(notification_label_); // lv_obj_del(status_label_); // lv_obj_del(mute_label_); // lv_obj_del(battery_label_); // lv_obj_del(emotion_label_); // } // if( low_battery_popup_ != nullptr ) { // lv_obj_del(low_battery_popup_); // } // if (pm_lock_ != nullptr) { // esp_pm_lock_delete(pm_lock_); // } } void Display::SetStatus(const char* status) { // DisplayLockGuard lock(this); // if (status_label_ == nullptr) { // return; // } // lv_label_set_text(status_label_, status); // lv_obj_clear_flag(status_label_, LV_OBJ_FLAG_HIDDEN); // lv_obj_add_flag(notification_label_, LV_OBJ_FLAG_HIDDEN); // last_status_update_time_ = std::chrono::system_clock::now(); } void Display::ShowNotification(const std::string ¬ification, int duration_ms) { ShowNotification(notification.c_str(), duration_ms); } void Display::ShowNotification(const char* notification, int duration_ms) { // DisplayLockGuard lock(this); // if (notification_label_ == nullptr) { // return; // } // lv_label_set_text(notification_label_, notification); // lv_obj_clear_flag(notification_label_, LV_OBJ_FLAG_HIDDEN); // lv_obj_add_flag(status_label_, LV_OBJ_FLAG_HIDDEN); // esp_timer_stop(notification_timer_); // ESP_ERROR_CHECK(esp_timer_start_once(notification_timer_, duration_ms * 1000)); } void Display::UpdateStatusBar(bool update_all) { // auto& app = Application::GetInstance(); // auto& board = Board::GetInstance(); // auto codec = board.GetAudioCodec(); // // Update mute icon // { // DisplayLockGuard lock(this); // if (mute_label_ == nullptr) { // return; // } // // 如果静音状态改变,则更新图标 // if (codec->output_volume() == 0 && !muted_) { // muted_ = true; // lv_label_set_text(mute_label_, FONT_AWESOME_VOLUME_MUTE); // } else if (codec->output_volume() > 0 && muted_) { // muted_ = false; // lv_label_set_text(mute_label_, ""); // } // } // // Update time // if (app.GetDeviceState() == kDeviceStateIdle) { // if (last_status_update_time_ + std::chrono::seconds(10) < std::chrono::system_clock::now()) { // // Set status to clock "HH:MM" // time_t now = time(NULL); // struct tm* tm = localtime(&now); // // Check if the we have already set the time // if (tm->tm_year >= 2025 - 1900) { // char time_str[16]; // strftime(time_str, sizeof(time_str), "%H:%M ", tm); // SetStatus(time_str); // } else { // ESP_LOGW(TAG, "System time is not set, tm_year: %d", tm->tm_year); // } // } // } // esp_pm_lock_acquire(pm_lock_); // // 更新电池图标 // int battery_level; // bool charging, discharging; // const char* icon = nullptr; // if (board.GetBatteryLevel(battery_level, charging, discharging)) { // if (charging) { // icon = FONT_AWESOME_BATTERY_CHARGING; // } else { // const char* levels[] = { // FONT_AWESOME_BATTERY_EMPTY, // 0-19% // FONT_AWESOME_BATTERY_1, // 20-39% // FONT_AWESOME_BATTERY_2, // 40-59% // FONT_AWESOME_BATTERY_3, // 60-79% // FONT_AWESOME_BATTERY_FULL, // 80-99% // FONT_AWESOME_BATTERY_FULL, // 100% // }; // icon = levels[battery_level / 20]; // } // DisplayLockGuard lock(this); // if (battery_label_ != nullptr && battery_icon_ != icon) { // battery_icon_ = icon; // lv_label_set_text(battery_label_, battery_icon_); // } // if (low_battery_popup_ != nullptr) { // if (strcmp(icon, FONT_AWESOME_BATTERY_EMPTY) == 0 && discharging) { // if (lv_obj_has_flag(low_battery_popup_, LV_OBJ_FLAG_HIDDEN)) { // 如果低电量提示框隐藏,则显示 // lv_obj_clear_flag(low_battery_popup_, LV_OBJ_FLAG_HIDDEN); // app.PlaySound(Lang::Sounds::P3_LOW_BATTERY); // } // } else { // // Hide the low battery popup when the battery is not empty // if (!lv_obj_has_flag(low_battery_popup_, LV_OBJ_FLAG_HIDDEN)) { // 如果低电量提示框显示,则隐藏 // lv_obj_add_flag(low_battery_popup_, LV_OBJ_FLAG_HIDDEN); // } // } // } // } // // 每 10 秒更新一次网络图标 // static int seconds_counter = 0; // if (update_all || seconds_counter++ % 10 == 0) { // // 升级固件时,不读取 4G 网络状态,避免占用 UART 资源 // auto device_state = Application::GetInstance().GetDeviceState(); // static const std::vector allowed_states = { // kDeviceStateIdle, // kDeviceStateStarting, // kDeviceStateWifiConfiguring, // kDeviceStateListening, // kDeviceStateActivating, // }; // if (std::find(allowed_states.begin(), allowed_states.end(), device_state) != allowed_states.end()) { // icon = board.GetNetworkStateIcon(); // if (network_label_ != nullptr && icon != nullptr && network_icon_ != icon) { // DisplayLockGuard lock(this); // network_icon_ = icon; // lv_label_set_text(network_label_, network_icon_); // } // } // } // esp_pm_lock_release(pm_lock_); } void Display::SetEmotion(const char* emotion) { // struct Emotion { // const char* icon; // const char* text; // }; // static const std::vector emotions = { // {FONT_AWESOME_EMOJI_NEUTRAL, "neutral"}, // {FONT_AWESOME_EMOJI_HAPPY, "happy"}, // {FONT_AWESOME_EMOJI_LAUGHING, "laughing"}, // {FONT_AWESOME_EMOJI_FUNNY, "funny"}, // {FONT_AWESOME_EMOJI_SAD, "sad"}, // {FONT_AWESOME_EMOJI_ANGRY, "angry"}, // {FONT_AWESOME_EMOJI_CRYING, "crying"}, // {FONT_AWESOME_EMOJI_LOVING, "loving"}, // {FONT_AWESOME_EMOJI_EMBARRASSED, "embarrassed"}, // {FONT_AWESOME_EMOJI_SURPRISED, "surprised"}, // {FONT_AWESOME_EMOJI_SHOCKED, "shocked"}, // {FONT_AWESOME_EMOJI_THINKING, "thinking"}, // {FONT_AWESOME_EMOJI_WINKING, "winking"}, // {FONT_AWESOME_EMOJI_COOL, "cool"}, // {FONT_AWESOME_EMOJI_RELAXED, "relaxed"}, // {FONT_AWESOME_EMOJI_DELICIOUS, "delicious"}, // {FONT_AWESOME_EMOJI_KISSY, "kissy"}, // {FONT_AWESOME_EMOJI_CONFIDENT, "confident"}, // {FONT_AWESOME_EMOJI_SLEEPY, "sleepy"}, // {FONT_AWESOME_EMOJI_SILLY, "silly"}, // {FONT_AWESOME_EMOJI_CONFUSED, "confused"} // }; // // 查找匹配的表情 // std::string_view emotion_view(emotion); // auto it = std::find_if(emotions.begin(), emotions.end(), // [&emotion_view](const Emotion& e) { return e.text == emotion_view; }); // DisplayLockGuard lock(this); // if (emotion_label_ == nullptr) { // return; // } // // 如果找到匹配的表情就显示对应图标,否则显示默认的neutral表情 // if (it != emotions.end()) { // lv_label_set_text(emotion_label_, it->icon); // } else { // lv_label_set_text(emotion_label_, FONT_AWESOME_EMOJI_NEUTRAL); // } } void Display::SetIcon(const char* icon) { // DisplayLockGuard lock(this); // if (emotion_label_ == nullptr) { // return; // } // lv_label_set_text(emotion_label_, icon); } void Display::SetPreviewImage(const lv_img_dsc_t* image) { // Do nothing } void Display::SetChatMessage(const char* role, const char* content) { // DisplayLockGuard lock(this); // if (chat_message_label_ == nullptr) { // return; // } // lv_label_set_text(chat_message_label_, content); } void Display::SetTheme(const std::string& theme_name) { // current_theme_name_ = theme_name; // Settings settings("display", true); // settings.SetString("theme", theme_name); } void Display::ShowStandbyScreen(bool show) { // if (show) { // SetChatMessage("system", ""); // SetEmotion("sleepy"); // } else { // SetChatMessage("system", ""); // SetEmotion("neutral"); // } }