#ifndef DISPLAY_H #define DISPLAY_H #include #include #include "panel.h" #define LVGL_TICK_PERIOD_MS 5 #define LVGL_TASK_STACK_SIZE (4 * 1024) #define LVGL_TASK_PRIORITY 2 class Display { public: explicit Display(IPanelDevice &device); ~Display() = default; [[nodiscard]] inline const lv_display_t *get() const { return lv_display_; } [[nodiscard]] inline lv_display_t *get() { return lv_display_; } [[nodiscard]] inline const lv_display_t *operator*() const { return get(); } [[nodiscard]] inline lv_display_t *operator*() { return get(); } void set_text(const char *text, const char *name, lv_label_long_mode_t long_mode = LV_LABEL_LONG_SCROLL_CIRCULAR, lv_align_t align = LV_ALIGN_TOP_MID); static bool lvgl_flush_ready(esp_lcd_panel_io_handle_t panel, esp_lcd_panel_io_event_data_t *data, void *user_ctx); static void lvgl_flush_cb(lv_display_t *display, const lv_area_t *area, uint8_t *px_map); static void lvgl_increase_tick(void *arg); [[noreturn]] static void lvgl_port_task(void *arg); private: Panel panel_; lv_display_t *lv_display_; // Draw buffer associated with the lv_display_t. void *lv_buf_; // Objects stored in the screen associated with this display. // @sa Display::set_text // @sa lv_display_get_screen_active std::unordered_map lv_objects_; struct ScopedLock { explicit ScopedLock() { _lock_acquire(&lv_lock_); } ~ScopedLock() { _lock_release(&lv_lock_); } // LVGL library is not thread-safe, this example calls LVGL APIs from tasks. // We must use a mutex to protect it. static _lock_t lv_lock_; }; }; #endif // DISPLAY_H