ESPHome 2025.5.0
Loading...
Searching...
No Matches
lvgl_esphome.cpp
Go to the documentation of this file.
2#include "esphome/core/log.h"
4#include "esphome/core/hal.h"
5#include "lvgl_hal.h"
6#include "lvgl_esphome.h"
7
8#include <numeric>
9
10namespace esphome {
11namespace lvgl {
12static const char *const TAG = "lvgl";
13
14static const char *const EVENT_NAMES[] = {
15 "NONE",
16 "PRESSED",
17 "PRESSING",
18 "PRESS_LOST",
19 "SHORT_CLICKED",
20 "LONG_PRESSED",
21 "LONG_PRESSED_REPEAT",
22 "CLICKED",
23 "RELEASED",
24 "SCROLL_BEGIN",
25 "SCROLL_END",
26 "SCROLL",
27 "GESTURE",
28 "KEY",
29 "FOCUSED",
30 "DEFOCUSED",
31 "LEAVE",
32 "HIT_TEST",
33 "COVER_CHECK",
34 "REFR_EXT_DRAW_SIZE",
35 "DRAW_MAIN_BEGIN",
36 "DRAW_MAIN",
37 "DRAW_MAIN_END",
38 "DRAW_POST_BEGIN",
39 "DRAW_POST",
40 "DRAW_POST_END",
41 "DRAW_PART_BEGIN",
42 "DRAW_PART_END",
43 "VALUE_CHANGED",
44 "INSERT",
45 "REFRESH",
46 "READY",
47 "CANCEL",
48 "DELETE",
49 "CHILD_CHANGED",
50 "CHILD_CREATED",
51 "CHILD_DELETED",
52 "SCREEN_UNLOAD_START",
53 "SCREEN_LOAD_START",
54 "SCREEN_LOADED",
55 "SCREEN_UNLOADED",
56 "SIZE_CHANGED",
57 "STYLE_CHANGED",
58 "LAYOUT_CHANGED",
59 "GET_SELF_SIZE",
60};
61
62std::string lv_event_code_name_for(uint8_t event_code) {
63 if (event_code < sizeof(EVENT_NAMES) / sizeof(EVENT_NAMES[0])) {
64 return EVENT_NAMES[event_code];
65 }
66 return str_sprintf("%2d", event_code);
67}
68
69static void rounder_cb(lv_disp_drv_t *disp_drv, lv_area_t *area) {
70 // cater for display driver chips with special requirements for bounds of partial
71 // draw areas. Extend the draw area to satisfy:
72 // * Coordinates must be a multiple of draw_rounding
73 auto *comp = static_cast<LvglComponent *>(disp_drv->user_data);
74 auto draw_rounding = comp->draw_rounding;
75 // round down the start coordinates
76 area->x1 = area->x1 / draw_rounding * draw_rounding;
77 area->y1 = area->y1 / draw_rounding * draw_rounding;
78 // round up the end coordinates
79 area->x2 = (area->x2 + draw_rounding) / draw_rounding * draw_rounding - 1;
80 area->y2 = (area->y2 + draw_rounding) / draw_rounding * draw_rounding - 1;
81}
82
83lv_event_code_t lv_api_event; // NOLINT
84lv_event_code_t lv_update_event; // NOLINT
86 ESP_LOGCONFIG(TAG, "LVGL:");
87 ESP_LOGCONFIG(TAG, " Display width/height: %d x %d", this->disp_drv_.hor_res, this->disp_drv_.ver_res);
88 ESP_LOGCONFIG(TAG, " Rotation: %d", this->rotation);
89 ESP_LOGCONFIG(TAG, " Draw rounding: %d", (int) this->draw_rounding);
90}
91void LvglComponent::set_paused(bool paused, bool show_snow) {
92 this->paused_ = paused;
93 this->show_snow_ = show_snow;
94 if (!paused && lv_scr_act() != nullptr) {
95 lv_disp_trig_activity(this->disp_); // resets the inactivity time
96 lv_obj_invalidate(lv_scr_act());
97 }
98 this->pause_callbacks_.call(paused);
99}
100
102 lv_init();
103 lv_update_event = static_cast<lv_event_code_t>(lv_event_register_id());
104 lv_api_event = static_cast<lv_event_code_t>(lv_event_register_id());
105}
106void LvglComponent::add_event_cb(lv_obj_t *obj, event_callback_t callback, lv_event_code_t event) {
107 lv_obj_add_event_cb(obj, callback, event, nullptr);
108}
109void LvglComponent::add_event_cb(lv_obj_t *obj, event_callback_t callback, lv_event_code_t event1,
110 lv_event_code_t event2) {
111 add_event_cb(obj, callback, event1);
112 add_event_cb(obj, callback, event2);
113}
114void LvglComponent::add_event_cb(lv_obj_t *obj, event_callback_t callback, lv_event_code_t event1,
115 lv_event_code_t event2, lv_event_code_t event3) {
116 add_event_cb(obj, callback, event1);
117 add_event_cb(obj, callback, event2);
118 add_event_cb(obj, callback, event3);
119}
121 this->pages_.push_back(page);
122 page->set_parent(this);
123 lv_disp_set_default(this->disp_);
124 page->setup(this->pages_.size() - 1);
125}
126void LvglComponent::show_page(size_t index, lv_scr_load_anim_t anim, uint32_t time) {
127 if (index >= this->pages_.size())
128 return;
129 this->current_page_ = index;
130 lv_scr_load_anim(this->pages_[this->current_page_]->obj, anim, time, 0, false);
131}
132void LvglComponent::show_next_page(lv_scr_load_anim_t anim, uint32_t time) {
133 if (this->pages_.empty() || (this->current_page_ == this->pages_.size() - 1 && !this->page_wrap_))
134 return;
135 do {
136 this->current_page_ = (this->current_page_ + 1) % this->pages_.size();
137 } while (this->pages_[this->current_page_]->skip); // skip empty pages()
138 this->show_page(this->current_page_, anim, time);
139}
140void LvglComponent::show_prev_page(lv_scr_load_anim_t anim, uint32_t time) {
141 if (this->pages_.empty() || (this->current_page_ == 0 && !this->page_wrap_))
142 return;
143 do {
144 this->current_page_ = (this->current_page_ + this->pages_.size() - 1) % this->pages_.size();
145 } while (this->pages_[this->current_page_]->skip); // skip empty pages()
146 this->show_page(this->current_page_, anim, time);
147}
148size_t LvglComponent::get_current_page() const { return this->current_page_; }
149bool LvPageType::is_showing() const { return this->parent_->get_current_page() == this->index; }
150void LvglComponent::draw_buffer_(const lv_area_t *area, lv_color_t *ptr) {
151 auto width = lv_area_get_width(area);
152 auto height = lv_area_get_height(area);
153 auto x1 = area->x1;
154 auto y1 = area->y1;
155 lv_color_t *dst = this->rotate_buf_;
156 switch (this->rotation) {
158 for (lv_coord_t x = height; x-- != 0;) {
159 for (lv_coord_t y = 0; y != width; y++) {
160 dst[y * height + x] = *ptr++;
161 }
162 }
163 y1 = x1;
164 x1 = this->disp_drv_.ver_res - area->y1 - height;
165 width = height;
166 height = lv_area_get_width(area);
167 break;
168
170 for (lv_coord_t y = height; y-- != 0;) {
171 for (lv_coord_t x = width; x-- != 0;) {
172 dst[y * width + x] = *ptr++;
173 }
174 }
175 x1 = this->disp_drv_.hor_res - x1 - width;
176 y1 = this->disp_drv_.ver_res - y1 - height;
177 break;
178
180 for (lv_coord_t x = 0; x != height; x++) {
181 for (lv_coord_t y = width; y-- != 0;) {
182 dst[y * height + x] = *ptr++;
183 }
184 }
185 x1 = y1;
186 y1 = this->disp_drv_.hor_res - area->x1 - width;
187 width = height;
188 height = lv_area_get_width(area);
189 break;
190
191 default:
192 dst = ptr;
193 break;
194 }
195 for (auto *display : this->displays_) {
196 ESP_LOGV(TAG, "draw buffer x1=%d, y1=%d, width=%d, height=%d", x1, y1, width, height);
197 display->draw_pixels_at(x1, y1, width, height, (const uint8_t *) dst, display::COLOR_ORDER_RGB, LV_BITNESS,
198 LV_COLOR_16_SWAP);
199 }
200}
201
202void LvglComponent::flush_cb_(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p) {
203 if (!this->paused_) {
204 auto now = millis();
205 this->draw_buffer_(area, color_p);
206 ESP_LOGVV(TAG, "flush_cb, area=%d/%d, %d/%d took %dms", area->x1, area->y1, lv_area_get_width(area),
207 lv_area_get_height(area), (int) (millis() - now));
208 }
209 lv_disp_flush_ready(disp_drv);
210}
211IdleTrigger::IdleTrigger(LvglComponent *parent, TemplatableValue<uint32_t> timeout) : timeout_(std::move(timeout)) {
212 parent->add_on_idle_callback([this](uint32_t idle_time) {
213 if (!this->is_idle_ && idle_time > this->timeout_.value()) {
214 this->is_idle_ = true;
215 this->trigger();
216 } else if (this->is_idle_ && idle_time < this->timeout_.value()) {
217 this->is_idle_ = false;
218 }
219 });
220}
221
222PauseTrigger::PauseTrigger(LvglComponent *parent, TemplatableValue<bool> paused) : paused_(std::move(paused)) {
223 parent->add_on_pause_callback([this](bool pausing) {
224 if (this->paused_.value() == pausing)
225 this->trigger();
226 });
227}
228
229#ifdef USE_LVGL_TOUCHSCREEN
230LVTouchListener::LVTouchListener(uint16_t long_press_time, uint16_t long_press_repeat_time, LvglComponent *parent) {
231 this->set_parent(parent);
232 lv_indev_drv_init(&this->drv_);
233 this->drv_.disp = parent->get_disp();
234 this->drv_.long_press_repeat_time = long_press_repeat_time;
235 this->drv_.long_press_time = long_press_time;
236 this->drv_.type = LV_INDEV_TYPE_POINTER;
237 this->drv_.user_data = this;
238 this->drv_.read_cb = [](lv_indev_drv_t *d, lv_indev_data_t *data) {
239 auto *l = static_cast<LVTouchListener *>(d->user_data);
240 if (l->touch_pressed_) {
241 data->point.x = l->touch_point_.x;
242 data->point.y = l->touch_point_.y;
243 data->state = LV_INDEV_STATE_PRESSED;
244 } else {
245 data->state = LV_INDEV_STATE_RELEASED;
246 }
247 };
248}
249
251 this->touch_pressed_ = !this->parent_->is_paused() && !tpoints.empty();
252 if (this->touch_pressed_)
253 this->touch_point_ = tpoints[0];
254}
255#endif // USE_LVGL_TOUCHSCREEN
256
257#ifdef USE_LVGL_KEY_LISTENER
258LVEncoderListener::LVEncoderListener(lv_indev_type_t type, uint16_t lpt, uint16_t lprt) {
259 lv_indev_drv_init(&this->drv_);
260 this->drv_.type = type;
261 this->drv_.user_data = this;
262 this->drv_.long_press_time = lpt;
263 this->drv_.long_press_repeat_time = lprt;
264 this->drv_.read_cb = [](lv_indev_drv_t *d, lv_indev_data_t *data) {
265 auto *l = static_cast<LVEncoderListener *>(d->user_data);
266 data->state = l->pressed_ ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED;
267 data->key = l->key_;
268 data->enc_diff = (int16_t) (l->count_ - l->last_count_);
269 l->last_count_ = l->count_;
270 data->continue_reading = false;
271 };
272}
273#endif // USE_LVGL_KEY_LISTENER
274
275#if defined(USE_LVGL_DROPDOWN) || defined(LV_USE_ROLLER)
277 auto selected = this->get_selected_index();
278 if (selected >= this->options_.size())
279 return "";
280 return this->options_[selected];
281}
282
283static std::string join_string(std::vector<std::string> options) {
284 return std::accumulate(
285 options.begin(), options.end(), std::string(),
286 [](const std::string &a, const std::string &b) -> std::string { return a + (!a.empty() ? "\n" : "") + b; });
287}
288
289void LvSelectable::set_selected_text(const std::string &text, lv_anim_enable_t anim) {
290 auto index = std::find(this->options_.begin(), this->options_.end(), text);
291 if (index != this->options_.end()) {
292 this->set_selected_index(index - this->options_.begin(), anim);
293 lv_event_send(this->obj, lv_api_event, nullptr);
294 }
295}
296
297void LvSelectable::set_options(std::vector<std::string> options) {
298 auto index = this->get_selected_index();
299 if (index >= options.size())
300 index = options.size() - 1;
301 this->options_ = std::move(options);
302 this->set_option_string(join_string(this->options_).c_str());
303 lv_event_send(this->obj, LV_EVENT_REFRESH, nullptr);
304 this->set_selected_index(index, LV_ANIM_OFF);
305}
306#endif // USE_LVGL_DROPDOWN || LV_USE_ROLLER
307
308#ifdef USE_LVGL_BUTTONMATRIX
309void LvButtonMatrixType::set_obj(lv_obj_t *lv_obj) {
310 LvCompound::set_obj(lv_obj);
311 lv_obj_add_event_cb(
312 lv_obj,
313 [](lv_event_t *event) {
314 auto *self = static_cast<LvButtonMatrixType *>(event->user_data);
315 if (self->key_callback_.size() == 0)
316 return;
317 auto key_idx = lv_btnmatrix_get_selected_btn(self->obj);
318 if (key_idx == LV_BTNMATRIX_BTN_NONE)
319 return;
320 if (self->key_map_.count(key_idx) != 0) {
321 self->send_key_(self->key_map_[key_idx]);
322 return;
323 }
324 const auto *str = lv_btnmatrix_get_btn_text(self->obj, key_idx);
325 auto len = strlen(str);
326 while (len--)
327 self->send_key_(*str++);
328 },
329 LV_EVENT_PRESSED, this);
330}
331#endif // USE_LVGL_BUTTONMATRIX
332
333#ifdef USE_LVGL_KEYBOARD
334static const char *const KB_SPECIAL_KEYS[] = {
335 "abc", "ABC", "1#",
336 // maybe add other special keys here
337};
338
339void LvKeyboardType::set_obj(lv_obj_t *lv_obj) {
340 LvCompound::set_obj(lv_obj);
341 lv_obj_add_event_cb(
342 lv_obj,
343 [](lv_event_t *event) {
344 auto *self = static_cast<LvKeyboardType *>(event->user_data);
345 if (self->key_callback_.size() == 0)
346 return;
347
348 auto key_idx = lv_btnmatrix_get_selected_btn(self->obj);
349 if (key_idx == LV_BTNMATRIX_BTN_NONE)
350 return;
351 const char *txt = lv_btnmatrix_get_btn_text(self->obj, key_idx);
352 if (txt == nullptr)
353 return;
354 for (const auto *kb_special_key : KB_SPECIAL_KEYS) {
355 if (strcmp(txt, kb_special_key) == 0)
356 return;
357 }
358 while (*txt != 0)
359 self->send_key_(*txt++);
360 },
361 LV_EVENT_PRESSED, this);
362}
363#endif // USE_LVGL_KEYBOARD
364
366 int iterations = 6 - lv_disp_get_inactive_time(this->disp_) / 60000;
367 if (iterations <= 0)
368 iterations = 1;
369 while (iterations-- != 0) {
370 auto col = random_uint32() % this->disp_drv_.hor_res;
371 col = col / this->draw_rounding * this->draw_rounding;
372 auto row = random_uint32() % this->disp_drv_.ver_res;
373 row = row / this->draw_rounding * this->draw_rounding;
374 auto size = (random_uint32() % 32) / this->draw_rounding * this->draw_rounding - 1;
375 lv_area_t area;
376 area.x1 = col;
377 area.y1 = row;
378 area.x2 = col + size;
379 area.y2 = row + size;
380 if (area.x2 >= this->disp_drv_.hor_res)
381 area.x2 = this->disp_drv_.hor_res - 1;
382 if (area.y2 >= this->disp_drv_.ver_res)
383 area.y2 = this->disp_drv_.ver_res - 1;
384
385 size_t line_len = lv_area_get_width(&area) * lv_area_get_height(&area) / 2;
386 for (size_t i = 0; i != line_len; i++) {
387 ((uint32_t *) (this->draw_buf_.buf1))[i] = random_uint32();
388 }
389 this->draw_buffer_(&area, (lv_color_t *) this->draw_buf_.buf1);
390 }
391}
392
413LvglComponent::LvglComponent(std::vector<display::Display *> displays, float buffer_frac, bool full_refresh,
414 int draw_rounding, bool resume_on_input)
415 : draw_rounding(draw_rounding),
416 displays_(std::move(displays)),
417 buffer_frac_(buffer_frac),
418 full_refresh_(full_refresh),
419 resume_on_input_(resume_on_input) {
420 lv_disp_draw_buf_init(&this->draw_buf_, nullptr, nullptr, 0);
421 lv_disp_drv_init(&this->disp_drv_);
422 this->disp_drv_.draw_buf = &this->draw_buf_;
423 this->disp_drv_.user_data = this;
424 this->disp_drv_.full_refresh = this->full_refresh_;
425 this->disp_drv_.flush_cb = static_flush_cb;
426 this->disp_drv_.rounder_cb = rounder_cb;
427 this->disp_ = lv_disp_drv_register(&this->disp_drv_);
428}
429
431 ESP_LOGCONFIG(TAG, "LVGL Setup starts");
432 auto *display = this->displays_[0];
433 auto width = display->get_width();
434 auto height = display->get_height();
435 size_t buffer_pixels = width * height / this->buffer_frac_;
436 auto buf_bytes = buffer_pixels * LV_COLOR_DEPTH / 8;
437 void *buffer = nullptr;
438 if (this->buffer_frac_ >= 4)
439 buffer = malloc(buf_bytes); // NOLINT
440 if (buffer == nullptr)
441 buffer = lv_custom_mem_alloc(buf_bytes); // NOLINT
442 if (buffer == nullptr) {
443 this->mark_failed();
444 this->status_set_error("Memory allocation failure");
445 return;
446 }
447 lv_disp_draw_buf_init(&this->draw_buf_, buffer, nullptr, buffer_pixels);
448 this->disp_drv_.hor_res = width;
449 this->disp_drv_.ver_res = height;
450 // this->setup_driver_(display->get_width(), display->get_height());
451 lv_disp_drv_update(this->disp_, &this->disp_drv_);
452 this->rotation = display->get_rotation();
454 this->rotate_buf_ = static_cast<lv_color_t *>(lv_custom_mem_alloc(buf_bytes)); // NOLINT
455 if (this->rotate_buf_ == nullptr) {
456 this->mark_failed();
457 this->status_set_error("Memory allocation failure");
458 return;
459 }
460 }
461#if LV_USE_LOG
462 lv_log_register_print_cb([](const char *buf) {
463 auto next = strchr(buf, ')');
464 if (next != nullptr)
465 buf = next + 1;
466 while (isspace(*buf))
467 buf++;
468 esp_log_printf_(LVGL_LOG_LEVEL, TAG, 0, "%.*s", (int) strlen(buf) - 1, buf);
469 });
470#endif
471 // Rotation will be handled by our drawing function, so reset the display rotation.
472 for (auto *disp : this->displays_)
473 disp->set_rotation(display::DISPLAY_ROTATION_0_DEGREES);
474 this->show_page(0, LV_SCR_LOAD_ANIM_NONE, 0);
475 lv_disp_trig_activity(this->disp_);
476 ESP_LOGCONFIG(TAG, "LVGL Setup complete");
477}
478
480 // update indicators
481 if (this->paused_) {
482 return;
483 }
484 this->idle_callbacks_.call(lv_disp_get_inactive_time(this->disp_));
485}
487 if (this->paused_) {
488 if (this->show_snow_)
489 this->write_random_();
490 }
491 lv_timer_handler_run_in_period(5);
492}
493
494#ifdef USE_LVGL_ANIMIMG
495void lv_animimg_stop(lv_obj_t *obj) {
496 auto *animg = (lv_animimg_t *) obj;
497 int32_t duration = animg->anim.time;
498 lv_animimg_set_duration(obj, 0);
499 lv_animimg_start(obj);
500 lv_animimg_set_duration(obj, duration);
501}
502#endif
503void LvglComponent::static_flush_cb(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p) {
504 reinterpret_cast<LvglComponent *>(disp_drv->user_data)->flush_cb_(disp_drv, area, color_p);
505}
506} // namespace lvgl
507} // namespace esphome
508
509size_t lv_millis(void) { return esphome::millis(); }
510
511#if defined(USE_HOST) || defined(USE_RP2040) || defined(USE_ESP8266)
512void *lv_custom_mem_alloc(size_t size) {
513 auto *ptr = malloc(size); // NOLINT
514 if (ptr == nullptr) {
515 ESP_LOGE(esphome::lvgl::TAG, "Failed to allocate %zu bytes", size);
516 }
517 return ptr;
518}
519void lv_custom_mem_free(void *ptr) { return free(ptr); } // NOLINT
520void *lv_custom_mem_realloc(void *ptr, size_t size) { return realloc(ptr, size); } // NOLINT
521#else
522static unsigned cap_bits = MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT; // NOLINT
523
524void *lv_custom_mem_alloc(size_t size) {
525 void *ptr;
526 ptr = heap_caps_malloc(size, cap_bits);
527 if (ptr == nullptr) {
528 cap_bits = MALLOC_CAP_8BIT;
529 ptr = heap_caps_malloc(size, cap_bits);
530 }
531 if (ptr == nullptr) {
532 ESP_LOGE(esphome::lvgl::TAG, "Failed to allocate %zu bytes", size);
533 return nullptr;
534 }
535 ESP_LOGV(esphome::lvgl::TAG, "allocate %zu - > %p", size, ptr);
536 return ptr;
537}
538
539void lv_custom_mem_free(void *ptr) {
540 ESP_LOGV(esphome::lvgl::TAG, "free %p", ptr);
541 if (ptr == nullptr)
542 return;
543 heap_caps_free(ptr);
544}
545
546void *lv_custom_mem_realloc(void *ptr, size_t size) {
547 ESP_LOGV(esphome::lvgl::TAG, "realloc %p: %zu", ptr, size);
548 return heap_caps_realloc(ptr, size, cap_bits);
549}
550#endif
uint8_t l
Definition bl0906.h:0
virtual void mark_failed()
Mark this component as failed.
void status_set_error(const char *message="unspecified")
void set_parent(T *parent)
Set the parent of this object.
Definition helpers.h:546
void trigger(Ts... x)
Definition automation.h:96
IdleTrigger(LvglComponent *parent, TemplatableValue< uint32_t > timeout)
TemplatableValue< uint32_t > timeout_
LVEncoderListener(lv_indev_type_t type, uint16_t lpt, uint16_t lprt)
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
void set_obj(lv_obj_t *lv_obj) override
virtual void set_obj(lv_obj_t *lv_obj)
void set_obj(lv_obj_t *lv_obj) override
void setup(size_t index)
void set_selected_text(const std::string &text, lv_anim_enable_t anim)
void set_options(std::vector< std::string > options)
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.
void set_paused(bool paused, bool show_snow)
static void static_flush_cb(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
std::vector< LvPageType * > pages_
static void add_event_cb(lv_obj_t *obj, event_callback_t callback, lv_event_code_t event)
void show_next_page(lv_scr_load_anim_t anim, uint32_t time)
CallbackManager< void(uint32_t)> idle_callbacks_
void add_on_idle_callback(std::function< void(uint32_t)> &&callback)
lv_disp_draw_buf_t draw_buf_
display::DisplayRotation rotation
void show_page(size_t index, lv_scr_load_anim_t anim, uint32_t time)
void show_prev_page(lv_scr_load_anim_t anim, uint32_t time)
CallbackManager< void(bool)> pause_callbacks_
std::vector< display::Display * > displays_
static void esphome_lvgl_init()
Initialize the LVGL library and register custom events.
void flush_cb_(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
LvglComponent(std::vector< display::Display * > displays, float buffer_frac, bool full_refresh, int draw_rounding, bool resume_on_input)
void add_page(LvPageType *page)
void add_on_pause_callback(std::function< void(bool)> &&callback)
void draw_buffer_(const lv_area_t *area, lv_color_t *ptr)
PauseTrigger(LvglComponent *parent, TemplatableValue< bool > paused)
TemplatableValue< bool > paused_
uint8_t type
uint8_t options
void * lv_custom_mem_alloc(size_t size)
size_t lv_millis(void)
void lv_custom_mem_free(void *ptr)
void * lv_custom_mem_realloc(void *ptr, size_t size)
uint8_t duration
Definition msa3xx.h:0
@ DISPLAY_ROTATION_0_DEGREES
Definition display.h:135
@ DISPLAY_ROTATION_270_DEGREES
Definition display.h:138
@ DISPLAY_ROTATION_180_DEGREES
Definition display.h:137
@ DISPLAY_ROTATION_90_DEGREES
Definition display.h:136
void lv_animimg_stop(lv_obj_t *obj)
std::string lv_event_code_name_for(uint8_t event_code)
lv_event_code_t lv_update_event
void(_lv_event_t *) event_callback_t
lv_event_code_t lv_api_event
std::vector< TouchPoint > TouchPoints_t
Definition touchscreen.h:30
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
void HOT esp_log_printf_(int level, const char *tag, int line, const char *format,...)
Definition log.cpp:11
std::string size_t len
Definition helpers.h:301
uint32_t random_uint32()
Return a random 32-bit unsigned integer.
Definition helpers.cpp:196
std::string str_sprintf(const char *fmt,...)
Definition helpers.cpp:323
uint32_t IRAM_ATTR HOT millis()
Definition core.cpp:27
uint16_t x
Definition tt21100.cpp:5
uint16_t y
Definition tt21100.cpp:6