144 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			144 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #ifndef DISPLAY_H
 | |
| #define DISPLAY_H
 | |
| 
 | |
| 
 | |
| #include <widgets/label/lv_label.h>
 | |
| 
 | |
| #include <unordered_map>
 | |
| 
 | |
| #include "time_keeper.h"
 | |
| #include "panel.h"
 | |
| 
 | |
| #define LVGL_TICK_PERIOD_MS    5
 | |
| #define LVGL_TASK_STACK_SIZE   (4 * 1024)
 | |
| #define LVGL_TASK_PRIORITY     2
 | |
| 
 | |
| /**
 | |
|  * Encapsulates lv_display handle and related LVGL operations.
 | |
|  * Contains helper methods that wrap basic LVGL operations such as drawing text.
 | |
|  * The underlying lv_display can be obtained for manual LVGL operations.
 | |
|  * @sa ScopedLock
 | |
|  * @sa Display::get()
 | |
|  */
 | |
| class Display {
 | |
| public:
 | |
|   /**
 | |
|    * Construct a new Display using an object that implements IPanelDevice.
 | |
|    *
 | |
|    * @param device An object that implements the IPanelDevice interface.
 | |
|    */
 | |
|   explicit Display(IPanelDevice &device);
 | |
| 
 | |
|   ~Display() = default;
 | |
| 
 | |
|   Display(const Display &) = delete;
 | |
| 
 | |
|   Display(Display &) = delete;
 | |
| 
 | |
|   Display &operator=(Display &) = delete;
 | |
| 
 | |
|   //
 | |
|   // GETTERS
 | |
| 
 | |
|   /**
 | |
|    * Getter for accessing LVGL display handle.
 | |
|    *
 | |
|    * @sa ScopedLock for calling custom LVGL API's not implemented by Display.
 | |
|    */
 | |
|   [[nodiscard]] inline const lv_display_t *get() const { return lv_display_; }
 | |
| 
 | |
|   /**
 | |
|    * Getter for accessing LVGL display handle.
 | |
|    *
 | |
|    * @sa ScopedLock for calling custom LVGL API's not implemented by Display.
 | |
|    */
 | |
|   [[nodiscard]] inline lv_display_t *get() { return lv_display_; }
 | |
| 
 | |
|   /// Dereference operator for accessing LVGL display handle.
 | |
|   [[nodiscard]] inline const lv_display_t *operator*() const { return get(); }
 | |
| 
 | |
|   /// Dereference operator for accessing LVGL display handle.
 | |
|   [[nodiscard]] inline lv_display_t *operator*() { return get(); }
 | |
| 
 | |
|   //
 | |
|   // LVGL OPERATIONS
 | |
| 
 | |
|   /**
 | |
|    * Create a LVGL label with some given text on the current display.
 | |
|    * The name of the object can be reused to change text on this label later.
 | |
|    *
 | |
|    * @param text Text to write to the display.
 | |
|    * @param name Name for the LVGL label object associated with this text.
 | |
|    * @param long_mode LVGL long mode for text wider than the current display.
 | |
|    * @param align LVGL alignment to use for placing the label on the display.
 | |
|    */
 | |
|   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);
 | |
| 
 | |
|   //
 | |
|   // TYPE DEFINITIONS
 | |
| 
 | |
|   /**
 | |
|    * Obtains LVGL API mutex lock for the duration of local scope.
 | |
|    *
 | |
|    * LVGL library is not thread-safe, this example calls LVGL APIs from tasks.
 | |
|    */
 | |
|   struct ScopedLock {
 | |
|     explicit ScopedLock() { _lock_acquire(&lv_lock_); }
 | |
| 
 | |
|     ~ScopedLock() { _lock_release(&lv_lock_); }
 | |
| 
 | |
|     /// Mutex used to protect LVGL API calls.
 | |
|     static _lock_t lv_lock_;
 | |
|   };
 | |
| 
 | |
|   //
 | |
|   // PUBLIC STATIC MEMBERS
 | |
| 
 | |
|   /// Public static TimeKeeper for managing ESP timers across all displays.
 | |
|   static TimeKeeper timers_;
 | |
| 
 | |
| private:
 | |
|   /// Registers LVGL draw buffers for this display.
 | |
|   void register_draw_buffer();
 | |
| 
 | |
|   /// Registers LVGL ticker timer callback for rendering this display.
 | |
|   static void register_lvgl_tick_timer();
 | |
| 
 | |
|   static bool lvgl_flush_ready_cb(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_cb(void *arg);
 | |
| 
 | |
|   [[noreturn]] static void lvgl_port_task(void *arg);
 | |
| 
 | |
|   //
 | |
|   // PRIVATE MEMBERS
 | |
| 
 | |
|   /// Panel associated with this Display.
 | |
|   Panel panel_;
 | |
| 
 | |
|   /// LVGL display handle.
 | |
|   lv_display_t *lv_display_;
 | |
| 
 | |
|   /// LVGL draw buffer associated with this Display's lv_display_t.
 | |
|   void *lv_buf_;
 | |
| 
 | |
|   /**
 | |
|    * LVGL object handles stored in the LVGL screen associated with this Display.
 | |
|    *
 | |
|    * @sa Display::set_text
 | |
|    * @sa lv_display_get_screen_active
 | |
|    */
 | |
|   std::unordered_map<const char *, lv_obj_t *> lv_objects_;
 | |
| };
 | |
| 
 | |
| #endif // DISPLAY_H
 |