7#include "core/lv_global.h"
8#include "core/lv_obj_class_private.h"
12static void *lv_alloc_draw_buf(
size_t size,
bool internal);
13static void *draw_buf_alloc_cb(
size_t size, lv_color_format_t color_format) {
return lv_alloc_draw_buf(size,
false); };
16static const char *
const TAG =
"lvgl";
18static const size_t MIN_BUFFER_FRAC = 8;
19static const size_t MIN_BUFFER_SIZE = 2048;
21static const char *
const EVENT_NAMES[] = {
28 "LONG_PRESSED_REPEAT",
59 "SCREEN_UNLOAD_START",
69static const unsigned LOG_LEVEL_MAP[] = {
70 ESPHOME_LOG_LEVEL_DEBUG, ESPHOME_LOG_LEVEL_INFO, ESPHOME_LOG_LEVEL_WARN,
71 ESPHOME_LOG_LEVEL_ERROR, ESPHOME_LOG_LEVEL_ERROR, ESPHOME_LOG_LEVEL_NONE,
76 auto event_code = lv_event_get_code(event);
77 if (event_code <
sizeof(EVENT_NAMES) /
sizeof(EVENT_NAMES[0])) {
78 return EVENT_NAMES[event_code];
82 snprintf(buf,
sizeof(buf),
"%u", event_code);
88 ESP_LOGW(TAG,
"Display rotation cannot be changed unless rotation was enabled during setup.");
105 if (angle % 90 != 0) {
106 ESP_LOGW(TAG,
"Invalid rotation angle %d; must be a multiple of 90 degrees.", angle);
137static void rounder_cb(lv_event_t *event) {
138 auto *comp =
static_cast<LvglComponent *
>(lv_event_get_user_data(event));
139 auto *area =
static_cast<lv_area_t *
>(lv_event_get_param(event));
145 area->x1 = area->x1 / draw_rounding * draw_rounding;
146 area->y1 = area->y1 / draw_rounding * draw_rounding;
148 area->x2 = (area->x2 + draw_rounding) / draw_rounding * draw_rounding - 1;
149 area->y2 = (area->y2 + draw_rounding) / draw_rounding * draw_rounding - 1;
153 auto *comp =
static_cast<LvglComponent *
>(lv_event_get_user_data(event));
158 ESP_LOGVV(TAG,
"Draw start");
159 auto *comp =
static_cast<LvglComponent *
>(lv_event_get_user_data(event));
167 " Display width/height: %d x %d\n"
168 " Buffer size: %zu%%\n"
170 " Draw rounding: %d",
173 const char *rot_type =
"hardware via display driver";
175#ifdef USE_ESP32_VARIANT_ESP32P4
176 rot_type = this->
ppa_client_ !=
nullptr ?
"software (PPA accelerated)" :
"software";
178 rot_type =
"software";
181 ESP_LOGCONFIG(TAG,
" Rotation type: %s", rot_type);
188 if (!paused && lv_screen_active() !=
nullptr) {
189 lv_display_trigger_activity(this->
disp_);
190 lv_obj_invalidate(lv_screen_active());
201 LV_GLOBAL_DEFAULT()->draw_buf_handlers.buf_malloc_cb = draw_buf_alloc_cb;
202 LV_GLOBAL_DEFAULT()->draw_buf_handlers.buf_free_cb =
lv_free_core;
203 LV_GLOBAL_DEFAULT()->image_cache_draw_buf_handlers.buf_malloc_cb = draw_buf_alloc_cb;
204 LV_GLOBAL_DEFAULT()->image_cache_draw_buf_handlers.buf_free_cb =
lv_free_core;
205 LV_GLOBAL_DEFAULT()->font_draw_buf_handlers.buf_malloc_cb = draw_buf_alloc_cb;
206 LV_GLOBAL_DEFAULT()->font_draw_buf_handlers.buf_free_cb =
lv_free_core;
207 lv_tick_set_cb([] {
return millis(); });
208 lv_update_event =
static_cast<lv_event_code_t
>(lv_event_register_id());
212 lv_obj_add_event_cb(obj, callback, event,
nullptr);
216 lv_event_code_t event2) {
222 lv_event_code_t event2, lv_event_code_t event3) {
229 this->
pages_.push_back(page);
231 lv_display_set_default(this->
disp_);
236 if (index >= this->
pages_.size())
239 if (anim == LV_SCREEN_LOAD_ANIM_NONE) {
247 if (this->
pages_.empty() || (this->current_page_ == this->pages_.size() - 1 && !this->page_wrap_))
259 if (this->
pages_.empty() || (this->current_page_ == 0 && !this->page_wrap_))
273#ifdef USE_ESP32_VARIANT_ESP32P4
276 ppa_srm_rotation_angle_t angle;
277 uint16_t out_w, out_h;
282 angle = PPA_SRM_ROTATION_ANGLE_270;
283 out_w = height_rounded;
287 angle = PPA_SRM_ROTATION_ANGLE_180;
292 angle = PPA_SRM_ROTATION_ANGLE_90;
293 out_w = height_rounded;
303 out_buf_size = LV_ROUND_UP(out_buf_size, LV_DRAW_BUF_ALIGN);
305 ppa_srm_oper_config_t srm_config{};
306 srm_config.in.buffer =
src;
307 srm_config.in.pic_w = width;
308 srm_config.in.pic_h = height;
309 srm_config.in.block_w = width;
310 srm_config.in.block_h = height;
311#if LV_COLOR_DEPTH == 16
312 srm_config.in.srm_cm = PPA_SRM_COLOR_MODE_RGB565;
313#elif LV_COLOR_DEPTH == 32
314 srm_config.in.srm_cm = PPA_SRM_COLOR_MODE_ARGB8888;
316 srm_config.out.buffer = dst;
317 srm_config.out.buffer_size = out_buf_size;
318 srm_config.out.pic_w = out_w;
319 srm_config.out.pic_h = out_h;
320#if LV_COLOR_DEPTH == 16
321 srm_config.out.srm_cm = PPA_SRM_COLOR_MODE_RGB565;
322#elif LV_COLOR_DEPTH == 32
323 srm_config.out.srm_cm = PPA_SRM_COLOR_MODE_ARGB8888;
325 srm_config.rotation_angle = angle;
326 srm_config.scale_x = 1.0f;
327 srm_config.scale_y = 1.0f;
328 srm_config.mode = PPA_TRANS_MODE_BLOCKING;
330 esp_err_t ret = ppa_do_scale_rotate_mirror(this->
ppa_client_, &srm_config);
332 ESP_LOGW(TAG,
"PPA rotation failed: %s", esp_err_to_name(ret));
333 ESP_LOGW(TAG,
"PPA SRM: in=%ux%u src=%p, out=%ux%u dst=%p size=%zu, angle=%d", width, height,
src, out_w, out_h,
334 dst, out_buf_size, (
int) angle);
342 auto width = lv_area_get_width(area);
343 auto height = lv_area_get_height(area);
349#ifdef USE_ESP32_VARIANT_ESP32P4
350 bool ppa_done = this->
ppa_client_ !=
nullptr && this->
ppa_rotate_(ptr, dst, width, height, height_rounded);
356 for (lv_coord_t
x = height;
x-- != 0;) {
357 for (lv_coord_t
y = 0;
y != width;
y++) {
358 dst[
y * height_rounded +
x] = *ptr++;
364 for (lv_coord_t
y = height;
y-- != 0;) {
365 for (lv_coord_t
x = width;
x-- != 0;) {
366 dst[
y * width +
x] = *ptr++;
372 for (lv_coord_t
x = 0;
x != height;
x++) {
373 for (lv_coord_t
y = width;
y-- != 0;) {
374 dst[
y * height_rounded +
x] = *ptr++;
388 x1 = this->
width_ - area->y1 - height;
390 width = height_rounded;
394 x1 = this->
width_ - x1 - width;
395 y1 = this->
height_ - y1 - height;
400 y1 = this->
height_ - area->x1 - width;
402 width = height_rounded;
423 ESP_LOGV(TAG,
"flush_cb, area=%d/%d, %d/%d took %dms", (
int) area->x1, (
int) area->y1,
424 (
int) lv_area_get_width(area), (
int) lv_area_get_height(area), (
int) (
millis() - now));
426 lv_display_flush_ready(disp_drv);
440#ifdef USE_LVGL_TOUCHSCREEN
443 this->
drv_ = lv_indev_create();
444 lv_indev_set_type(this->
drv_, LV_INDEV_TYPE_POINTER);
446 lv_indev_set_long_press_time(this->
drv_, long_press_time);
448 lv_indev_set_user_data(this->
drv_,
this);
449 lv_indev_set_read_cb(this->
drv_, [](lv_indev_t *d, lv_indev_data_t *data) {
451 if (
l->touch_pressed_) {
452 data->point.x =
l->touch_point_.x;
453 data->point.y =
l->touch_point_.y;
454 l->parent_->rotate_coordinates(data->point.x, data->point.y);
455 data->state = LV_INDEV_STATE_PRESSED;
457 data->state = LV_INDEV_STATE_RELEASED;
472 auto *scale = lv_obj_get_parent(obj);
473 auto min_value = lv_scale_get_range_min_value(scale);
474 auto max_value = lv_scale_get_range_max_value(scale);
475 value = clamp(value, min_value, max_value);
476 return ((value - min_value) * lv_scale_get_angle_range(scale) / (max_value - min_value) +
477 lv_scale_get_rotation((scale))) %
483 lv_line_set_points(lv_obj, this->points_, 2);
485 lv_obj_get_parent(
obj),
487 auto *indicator =
static_cast<IndicatorLine *
>(lv_event_get_user_data(e));
488 indicator->update_length_();
489 ESP_LOGV(TAG,
"Updated length, value = %d", indicator->angle_);
491 LV_EVENT_SIZE_CHANGED,
this);
496 if (angle != this->angle_) {
497 this->angle_ = angle;
498 this->update_length_();
502void IndicatorLine::update_length_() {
503 auto cx = lv_obj_get_width(lv_obj_get_parent(this->
obj)) / 2;
504 auto cy = lv_obj_get_height(lv_obj_get_parent(this->
obj)) / 2;
506 auto length = lv_obj_get_style_length(this->
obj, LV_PART_MAIN);
507 auto radial_offset = lv_obj_get_style_radial_offset(this->
obj, LV_PART_MAIN);
508 if (LV_COORD_IS_PCT(radial_offset)) {
509 radial_offset = radius * LV_COORD_GET_PCT(radial_offset) / 100;
511 if (LV_COORD_IS_PCT(
length)) {
516 auto x = lv_trigo_cos(this->angle_) / 32768.0f;
517 auto y = lv_trigo_sin(this->angle_) / 32768.0f;
519 this->points_[0].x = radius + radial_offset *
x;
520 this->points_[0].y = radius + radial_offset *
y;
521 this->points_[1].x = radius +
x * (radial_offset +
length);
522 this->points_[1].y = radius +
y * (radial_offset +
length);
523 lv_obj_refresh_self_size(this->
obj);
524 lv_obj_invalidate(this->
obj);
528#ifdef USE_LVGL_KEY_LISTENER
530 this->
drv_ = lv_indev_create();
531 lv_indev_set_type(this->
drv_, type);
532 lv_indev_set_long_press_time(this->
drv_, long_press_time);
533 lv_indev_set_long_press_repeat_time(this->
drv_, long_press_repeat_time);
534 lv_indev_set_user_data(this->
drv_,
this);
535 lv_indev_set_read_cb(this->
drv_, [](lv_indev_t *d, lv_indev_data_t *data) {
537 data->state =
l->pressed_ ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED;
539 data->enc_diff = (int16_t) (
l->count_ -
l->last_count_);
540 l->last_count_ =
l->count_;
541 data->continue_reading =
false;
546#if defined(USE_LVGL_DROPDOWN) || defined(LV_USE_ROLLER)
549 if (selected >= this->
options_.size())
554static std::string join_string(std::vector<std::string>
options) {
555 return std::accumulate(
557 [](
const std::string &a,
const std::string &b) -> std::string { return a + (!a.empty() ?
"\n" :
"") + b; });
561 auto index = std::find(this->
options_.begin(), this->options_.end(), text);
562 if (index != this->
options_.end()) {
564 lv_obj_send_event(this->
obj, lv_update_event,
nullptr);
574 lv_obj_send_event(this->
obj, LV_EVENT_REFRESH,
nullptr);
579#ifdef USE_LVGL_BUTTONMATRIX
584 [](lv_event_t *event) {
586 if (self->key_callback_.size() == 0)
588 auto key_idx = lv_buttonmatrix_get_selected_button(self->obj);
589 if (key_idx == LV_BUTTONMATRIX_BUTTON_NONE)
591 if (self->key_map_.contains(key_idx)) {
592 self->send_key_(self->key_map_[key_idx]);
595 const auto *str = lv_buttonmatrix_get_button_text(self->obj, key_idx);
596 auto len = strlen(str);
598 self->send_key_(*str++);
600 LV_EVENT_PRESSED,
this);
604#ifdef USE_LVGL_KEYBOARD
605static const char *
const KB_SPECIAL_KEYS[] = {
614 [](lv_event_t *event) {
615 auto *self =
static_cast<LvKeyboardType *
>(lv_event_get_user_data(event));
616 if (self->key_callback_.size() == 0)
619 auto key_idx = lv_buttonmatrix_get_selected_button(self->obj);
620 if (key_idx == LV_BUTTONMATRIX_BUTTON_NONE)
622 const char *txt = lv_buttonmatrix_get_button_text(self->obj, key_idx);
625 for (
const auto *kb_special_key : KB_SPECIAL_KEYS) {
626 if (strcmp(txt, kb_special_key) == 0)
630 self->send_key_(*txt++);
632 LV_EVENT_PRESSED,
this);
651 if (!disp->is_idle())
658 int iterations = 6 - lv_display_get_inactive_time(this->
disp_) / 60000;
661 int16_t width = lv_display_get_horizontal_resolution(this->
disp_);
662 int16_t height = lv_display_get_vertical_resolution(this->
disp_);
663 while (iterations-- != 0) {
669 int32_t
size = (
random_uint32() % 25 + 8) / this->draw_rounding * this->draw_rounding;
670 lv_area_t area{.x1 = col, .y1 = row, .x2 = col +
size - 1, .y2 = row +
size - 1};
672 if (area.x2 >= width)
674 if (area.y2 >= height)
675 area.y2 = height - 1;
678 size_t line_len = lv_area_get_width(&area) * lv_area_get_height(&area) / 2;
679 for (
size_t i = 0; i != line_len; i++) {
708 int draw_rounding,
bool resume_on_input,
bool update_when_display_idle,
710 : draw_rounding(draw_rounding),
711 displays_(
std::move(displays)),
712 buffer_frac_(buffer_frac),
713 full_refresh_(full_refresh),
714 resume_on_input_(resume_on_input),
715 update_when_display_idle_(update_when_display_idle),
716 rotation_type_(rotation_type) {
717 this->
disp_ = lv_display_create(240, 240);
721 int32_t width = this->
width_;
722 int32_t height = this->
height_;
725 std::swap(width, height);
727 ESP_LOGD(TAG,
"Setting resolution to %u x %u (rotation %d)", (
unsigned) width, (
unsigned) height,
731 display->set_rotation(this->rotation_);
733 lv_display_set_resolution(this->
disp_, width, height);
743 if (trigger !=
nullptr)
750 this->
width_ = display->get_native_width();
751 this->
height_ = display->get_native_height();
753 auto width = (this->
width_ + rounding - 1) / rounding * rounding;
754 auto height = (this->
height_ + rounding - 1) / rounding * rounding;
758 auto buf_bytes =
clamp_at_least(width * height / frac * LV_COLOR_DEPTH / 8, MIN_BUFFER_SIZE);
759 void *buffer =
nullptr;
762 buffer = lv_alloc_draw_buf(buf_bytes,
true);
763 if (buffer ==
nullptr)
764 buffer = lv_alloc_draw_buf(buf_bytes,
false);
767 frac = MIN_BUFFER_FRAC;
768 buf_bytes /= MIN_BUFFER_FRAC;
769 buffer = lv_alloc_draw_buf(buf_bytes,
false);
772 if (buffer ==
nullptr) {
777 this->
draw_buf_ =
static_cast<uint8_t *
>(buffer);
779 lv_display_set_color_format(this->
disp_, LV_COLOR_FORMAT_RGB565);
781 lv_display_set_user_data(this->
disp_,
this);
782 lv_display_add_event_cb(this->
disp_, rounder_cb, LV_EVENT_INVALIDATE_AREA,
this);
783 lv_display_set_buffers(this->
disp_, this->
draw_buf_,
nullptr, buf_bytes,
784 this->
full_refresh_ ? LV_DISPLAY_RENDER_MODE_FULL : LV_DISPLAY_RENDER_MODE_PARTIAL);
786 this->
rotate_buf_ =
static_cast<lv_color_t *
>(lv_alloc_draw_buf(buf_bytes,
false));
792#ifdef USE_ESP32_VARIANT_ESP32P4
793 ppa_client_config_t ppa_config{};
794 ppa_config.oper_type = PPA_OPERATION_SRM;
795 ppa_config.max_pending_trans_num = 1;
796 if (ppa_register_client(&ppa_config, &this->
ppa_client_) != ESP_OK) {
797 ESP_LOGW(TAG,
"PPA client registration failed, using software rotation");
811 lv_log_register_print_cb([](lv_log_level_t level,
const char *buf) {
812 auto next = strchr(buf,
')');
815 while (isspace(*buf))
817 if (level >=
sizeof(LOG_LEVEL_MAP) /
sizeof(LOG_LEVEL_MAP[0]))
818 level =
sizeof(LOG_LEVEL_MAP) /
sizeof(LOG_LEVEL_MAP[0]) - 1;
819 esp_log_printf_(LOG_LEVEL_MAP[level], TAG, 0,
"%.*s", (
int) strlen(buf) - 1, buf);
822 this->
show_page(0, LV_SCREEN_LOAD_ANIM_NONE, 0);
823 lv_display_trigger_activity(this->
disp_);
852 lv_timer_set_period(this->
refr_timer_, 5 * 60 * 1000);
864#ifdef USE_LVGL_ANIMIMG
866 int32_t
duration = lv_animimg_get_duration(obj);
867 lv_animimg_set_duration(obj, 0);
868 lv_animimg_start(obj);
869 lv_animimg_set_duration(obj,
duration);
873 reinterpret_cast<LvglComponent *
>(lv_display_get_user_data(disp_drv))->
flush_cb_(disp_drv, area, color_p);
885 lv_color_t color_end,
int width,
bool local) {
886 auto *scale =
static_cast<lv_obj_t *
>(lv_event_get_target(e));
887 lv_draw_task_t *task = lv_event_get_draw_task(e);
889 if (lv_draw_task_get_type(task) == LV_DRAW_TASK_TYPE_LINE) {
890 auto *line_dsc =
static_cast<lv_draw_line_dsc_t *
>(lv_draw_task_get_draw_dsc(task));
891 int tick = line_dsc->base.id2;
892 if (tick >= range_start && tick <= range_end) {
895 int range = range_end - range_start;
897 ratio =
range == 0 ? 0 : (tick * 255) /
range;
900 ratio = (line_dsc->base.id1 * 255) / (lv_scale_get_total_tick_count(scale) - 1);
902 line_dsc->color = lv_color_mix(color_end, color_start, ratio);
903 line_dsc->width += width;
909#ifdef USE_LVGL_GRADIENT
918 if (dsc->stops_count == 0)
919 return lv_color_black();
921 return dsc->stops[0].color;
922 if (
pos >= dsc->stops[dsc->stops_count - 1].frac)
923 return dsc->stops[dsc->stops_count - 1].color;
925 while (i < dsc->stops_count && dsc->stops[i].frac <
pos)
927 auto *stop1 = &dsc->stops[i - 1];
928 auto *stop2 = &dsc->stops[i];
929 int32_t
range = stop2->frac - stop1->frac;
930 int32_t offset =
pos - stop1->frac;
931 return lv_color_mix(stop2->color, stop1->color,
range == 0 ? 0 : (offset * 255) /
range);
936 auto *indev = lv_indev_get_act();
937 if (indev ==
nullptr) {
938 return {INT32_MAX, INT32_MAX};
941 lv_indev_get_point(indev, &point);
943 lv_obj_get_coords(obj, &coords);
944 point.x -= coords.x1;
945 point.y -= coords.y1;
949static void lv_container_constructor(
const lv_obj_class_t *class_p, lv_obj_t *obj) {
950 LV_TRACE_OBJ_CREATE(
"begin");
956 .base_class = &lv_obj_class,
957 .constructor_cb = lv_container_constructor,
958 .name =
"lv_container",
963 lv_obj_class_init_obj(obj);
974#if defined(USE_HOST) || defined(USE_RP2) || defined(USE_ESP8266)
976 auto *ptr = malloc(
size);
977 if (ptr ==
nullptr) {
978 ESP_LOGE(esphome::lvgl::TAG,
"Failed to allocate %zu bytes",
size);
986static void *lv_alloc_draw_buf(
size_t size,
bool internal) {
990#elif defined(USE_ESP32)
991static unsigned cap_bits = MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT;
993static void *lv_alloc_draw_buf(
size_t size,
bool internal) {
995 size = LV_ROUND_UP(
size, LV_DRAW_BUF_ALIGN);
996 buffer = heap_caps_aligned_alloc(LV_DRAW_BUF_ALIGN,
size, internal ? MALLOC_CAP_8BIT : cap_bits);
997 if (buffer ==
nullptr)
998 ESP_LOGW(esphome::lvgl::TAG,
"Failed to allocate %zu bytes for %sdraw buffer",
size, internal ?
"internal " :
"");
1003 multi_heap_info_t heap_info;
1004 heap_caps_get_info(&heap_info, cap_bits);
1005 mon_p->total_size = heap_info.total_allocated_bytes + heap_info.total_free_bytes;
1006 mon_p->free_size = heap_info.total_free_bytes;
1007 mon_p->max_used = heap_info.total_allocated_bytes;
1008 mon_p->free_biggest_size = heap_info.largest_free_block;
1009 mon_p->used_cnt = heap_info.allocated_blocks;
1010 mon_p->free_cnt = heap_info.free_blocks;
1011 mon_p->used_pct = heap_info.allocated_blocks * 100 / (heap_info.allocated_blocks + heap_info.free_blocks);
1012 mon_p->frag_pct = 0;
1017 ptr = heap_caps_malloc(
size, cap_bits);
1018 if (ptr ==
nullptr) {
1019 cap_bits = MALLOC_CAP_8BIT;
1020 ptr = heap_caps_malloc(
size, cap_bits);
1022 if (ptr ==
nullptr) {
1023 ESP_LOGE(esphome::lvgl::TAG,
"Failed to allocate %zu bytes",
size);
1026 ESP_LOGV(esphome::lvgl::TAG,
"allocate %zu - > %p",
size, ptr);
1031 ESP_LOGV(esphome::lvgl::TAG,
"free %p", ptr);
1034 heap_caps_free(ptr);
1038 ESP_LOGV(esphome::lvgl::TAG,
"realloc %p: %zu", ptr,
size);
1039 return heap_caps_realloc(ptr,
size, cap_bits);
void mark_failed()
Mark this component as failed.
void set_parent(T *parent)
Set the parent of this object.
Function-pointer-only templatable storage (4 bytes on 32-bit).
void trigger(const Ts &...x) ESPHOME_ALWAYS_INLINE
Inform the parent automation that the event has triggered.
TemplatableFn< uint32_t > timeout_
IdleTrigger(LvglComponent *parent, TemplatableFn< uint32_t > timeout)
void set_obj(lv_obj_t *lv_obj) override
void set_value(int value)
LVEncoderListener(lv_indev_type_t type, uint16_t long_press_time, uint16_t long_press_repeat_time)
LVTouchListener(uint16_t long_press_time, uint16_t long_press_repeat_time, LvglComponent *parent)
touchscreen::TouchPoint touch_point_
void update(const touchscreen::TouchPoints_t &tpoints) override
virtual void set_obj(lv_obj_t *lv_obj)
void set_obj(lv_obj_t *lv_obj) override
void set_selected_text(const std::string &text, lv_anim_enable_t anim)
void set_options(std::vector< std::string > options)
std::string get_selected_text()
std::vector< std::string > options_
virtual void set_selected_index(size_t index, lv_anim_enable_t anim)=0
virtual size_t get_selected_index()=0
virtual void set_option_string(const char *options)=0
Component for rendering LVGL.
RotationType rotation_type_
void set_paused(bool paused, bool show_snow)
size_t get_current_page() const
display::DisplayRotation rotation_
Trigger * pause_callback_
void rotate_coordinates(int32_t &x, int32_t &y) const
Trigger * resume_callback_
std::vector< LvPageType * > pages_
void set_rotation(display::DisplayRotation rotation)
void set_resolution_() const
static void add_event_cb(lv_obj_t *obj, event_callback_t callback, lv_event_code_t event)
bool ppa_rotate_(const lv_color_data *src, lv_color_data *dst, uint16_t width, uint16_t height, uint32_t height_rounded)
bool update_when_display_idle_
Trigger * landscape_callback_
bool displays_busy_() const
void dump_config() override
CallbackManager< void(uint32_t)> idle_callbacks_
lv_obj_t * get_screen_active()
uint32_t refr_timer_period_
void show_next_page(lv_screen_load_anim_t anim, uint32_t time)
Trigger * draw_start_callback_
Trigger * draw_end_callback_
Trigger * portrait_callback_
uint16_t get_width() const
std::vector< display::Display * > displays_
lv_display_t * get_disp()
static void esphome_lvgl_init()
Initialize the LVGL library and register custom events.
void show_prev_page(lv_screen_load_anim_t anim, uint32_t time)
ppa_client_handle_t ppa_client_
LvglComponent(std::vector< display::Display * > displays, float buffer_frac, bool full_refresh, int draw_rounding, bool resume_on_input, bool update_when_display_idle, RotationType rotation_type)
void update_orientation_()
static void render_start_cb(lv_event_t *event)
static lv_point_t get_touch_relative_to_obj(lv_obj_t *obj)
void add_on_idle_callback(F &&callback)
void add_page(LvPageType *page)
static void static_flush_cb(lv_display_t *disp_drv, const lv_area_t *area, uint8_t *color_p)
static void render_end_cb(lv_event_t *event)
void draw_buffer_(const lv_area_t *area, lv_color_data *ptr)
uint16_t get_height() const
void show_page(size_t index, lv_screen_load_anim_t anim, uint32_t time)
void flush_cb_(lv_display_t *disp_drv, const lv_area_t *area, uint8_t *color_p)
void lv_free_core(void *ptr)
void * lv_malloc_core(size_t size)
void lv_mem_monitor_core(lv_mem_monitor_t *mon_p)
void * lv_realloc_core(void *ptr, size_t size)
lv_result_t lv_mem_test_core()
@ DISPLAY_ROTATION_270_DEGREES
@ DISPLAY_ROTATION_180_DEGREES
@ DISPLAY_ROTATION_90_DEGREES
lv_color_t lv_grad_calculate_color(const lv_grad_dsc_t *dsc, int32_t pos)
void lv_animimg_stop(lv_obj_t *obj)
void(lv_event_t *) event_callback_t
const lv_obj_class_t LV_CONTAINER_CLASS
lv_event_code_t lv_update_event
int16_t lv_get_needle_angle_for_value(lv_obj_t *obj, int32_t value)
lv_obj_t * lv_container_create(lv_obj_t *parent)
std::string lv_event_code_name_for(lv_event_t *event)
void lv_scale_draw_event_cb(lv_event_t *e, int16_t range_start, int16_t range_end, lv_color_t color_start, lv_color_t color_end, int width, bool local)
Function to apply colors to ticks based on position.
std::vector< TouchPoint > TouchPoints_t
T clamp_at_most(T value, U max)
void HOT esp_log_printf_(int level, const char *tag, int line, const char *format,...)
T clamp_at_least(T value, U min)
uint32_t random_uint32()
Return a random 32-bit unsigned integer.
uint32_t IRAM_ATTR HOT millis()