mirror of
https://github.com/esphome/esphome.git
synced 2025-11-18 15:55:46 +00:00
[lvgl] Revise code generation to allow early widget creation (#7611)
This commit is contained in:
@@ -11,12 +11,6 @@ namespace esphome {
|
||||
namespace lvgl {
|
||||
static const char *const TAG = "lvgl";
|
||||
|
||||
#if LV_USE_LOG
|
||||
static void log_cb(const char *buf) {
|
||||
esp_log_printf_(ESPHOME_LOG_LEVEL_INFO, TAG, 0, "%.*s", (int) strlen(buf) - 1, buf);
|
||||
}
|
||||
#endif // LV_USE_LOG
|
||||
|
||||
static const char *const EVENT_NAMES[] = {
|
||||
"NONE",
|
||||
"PRESSED",
|
||||
@@ -383,26 +377,48 @@ void LvglComponent::write_random_() {
|
||||
}
|
||||
}
|
||||
|
||||
void LvglComponent::setup() {
|
||||
ESP_LOGCONFIG(TAG, "LVGL Setup starts");
|
||||
#if LV_USE_LOG
|
||||
lv_log_register_print_cb(log_cb);
|
||||
#endif
|
||||
/**
|
||||
* @class LvglComponent
|
||||
* @brief Component for rendering LVGL.
|
||||
*
|
||||
* This component renders LVGL widgets on a display. Some initialisation must be done in the constructor
|
||||
* since LVGL needs to be initialised before any widgets can be created.
|
||||
*
|
||||
* @param displays a list of displays to render onto. All displays must have the same
|
||||
* resolution.
|
||||
* @param buffer_frac the fraction of the display resolution to use for the LVGL
|
||||
* draw buffer. A higher value will make animations smoother but
|
||||
* also increase memory usage.
|
||||
* @param full_refresh if true, the display will be fully refreshed on every frame.
|
||||
* If false, only changed areas will be updated.
|
||||
* @param draw_rounding the rounding to use when drawing. A value of 1 will draw
|
||||
* without any rounding, a value of 2 will round to the nearest
|
||||
* multiple of 2, and so on.
|
||||
* @param resume_on_input if true, this component will resume rendering when the user
|
||||
* presses a key or clicks on the screen.
|
||||
*/
|
||||
LvglComponent::LvglComponent(std::vector<display::Display *> displays, float buffer_frac, bool full_refresh,
|
||||
int draw_rounding, bool resume_on_input)
|
||||
: draw_rounding(draw_rounding),
|
||||
displays_(std::move(displays)),
|
||||
buffer_frac_(buffer_frac),
|
||||
full_refresh_(full_refresh),
|
||||
resume_on_input_(resume_on_input) {
|
||||
lv_init();
|
||||
lv_update_event = static_cast<lv_event_code_t>(lv_event_register_id());
|
||||
lv_api_event = static_cast<lv_event_code_t>(lv_event_register_id());
|
||||
auto *display = this->displays_[0];
|
||||
size_t buffer_pixels = display->get_width() * display->get_height() / this->buffer_frac_;
|
||||
auto buf_bytes = buffer_pixels * LV_COLOR_DEPTH / 8;
|
||||
auto *buf = lv_custom_mem_alloc(buf_bytes); // NOLINT
|
||||
if (buf == nullptr) {
|
||||
#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_ERROR
|
||||
ESP_LOGE(TAG, "Malloc failed to allocate %zu bytes", buf_bytes);
|
||||
#endif
|
||||
this->mark_failed();
|
||||
this->status_set_error("Memory allocation failure");
|
||||
return;
|
||||
this->rotation = display->get_rotation();
|
||||
if (this->rotation != display::DISPLAY_ROTATION_0_DEGREES) {
|
||||
this->rotate_buf_ = static_cast<lv_color_t *>(lv_custom_mem_alloc(buf_bytes)); // NOLINT
|
||||
if (this->rotate_buf_ == nullptr)
|
||||
return;
|
||||
}
|
||||
auto *buf = lv_custom_mem_alloc(buf_bytes); // NOLINT
|
||||
if (buf == nullptr)
|
||||
return;
|
||||
lv_disp_draw_buf_init(&this->draw_buf_, buf, nullptr, buffer_pixels);
|
||||
lv_disp_drv_init(&this->disp_drv_);
|
||||
this->disp_drv_.draw_buf = &this->draw_buf_;
|
||||
@@ -410,18 +426,7 @@ void LvglComponent::setup() {
|
||||
this->disp_drv_.full_refresh = this->full_refresh_;
|
||||
this->disp_drv_.flush_cb = static_flush_cb;
|
||||
this->disp_drv_.rounder_cb = rounder_cb;
|
||||
this->rotation = display->get_rotation();
|
||||
if (this->rotation != display::DISPLAY_ROTATION_0_DEGREES) {
|
||||
this->rotate_buf_ = static_cast<lv_color_t *>(lv_custom_mem_alloc(buf_bytes)); // NOLINT
|
||||
if (this->rotate_buf_ == nullptr) {
|
||||
#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_ERROR
|
||||
ESP_LOGE(TAG, "Malloc failed to allocate %zu bytes", buf_bytes);
|
||||
#endif
|
||||
this->mark_failed();
|
||||
this->status_set_error("Memory allocation failure");
|
||||
return;
|
||||
}
|
||||
}
|
||||
// reset the display rotation since we will handle all rotations
|
||||
display->set_rotation(display::DISPLAY_ROTATION_0_DEGREES);
|
||||
switch (this->rotation) {
|
||||
default:
|
||||
@@ -435,12 +440,30 @@ void LvglComponent::setup() {
|
||||
break;
|
||||
}
|
||||
this->disp_ = lv_disp_drv_register(&this->disp_drv_);
|
||||
for (const auto &v : this->init_lambdas_)
|
||||
v(this);
|
||||
}
|
||||
|
||||
void LvglComponent::setup() {
|
||||
if (this->draw_buf_.buf1 == nullptr) {
|
||||
this->mark_failed();
|
||||
this->status_set_error("Memory allocation failure");
|
||||
return;
|
||||
}
|
||||
ESP_LOGCONFIG(TAG, "LVGL Setup starts");
|
||||
#if LV_USE_LOG
|
||||
lv_log_register_print_cb([](const char *buf) {
|
||||
auto next = strchr(buf, ')');
|
||||
if (next != nullptr)
|
||||
buf = next + 1;
|
||||
while (isspace(*buf))
|
||||
buf++;
|
||||
esp_log_printf_(LVGL_LOG_LEVEL, TAG, 0, "%.*s", (int) strlen(buf) - 1, buf);
|
||||
});
|
||||
#endif
|
||||
this->show_page(0, LV_SCR_LOAD_ANIM_NONE, 0);
|
||||
lv_disp_trig_activity(this->disp_);
|
||||
ESP_LOGCONFIG(TAG, "LVGL Setup complete");
|
||||
}
|
||||
|
||||
void LvglComponent::update() {
|
||||
// update indicators
|
||||
if (this->paused_) {
|
||||
@@ -455,13 +478,6 @@ void LvglComponent::loop() {
|
||||
}
|
||||
lv_timer_handler_run_in_period(5);
|
||||
}
|
||||
bool lv_is_pre_initialise() {
|
||||
if (!lv_is_initialized()) {
|
||||
ESP_LOGE(TAG, "LVGL call before component is initialised");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef USE_LVGL_ANIMIMG
|
||||
void lv_animimg_stop(lv_obj_t *obj) {
|
||||
|
||||
Reference in New Issue
Block a user