ESPHome  2023.11.6
display.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <cstdarg>
4 #include <vector>
5 
6 #include "rect.h"
7 
8 #include "esphome/core/color.h"
10 #include "esphome/core/time.h"
11 
12 #ifdef USE_GRAPH
14 #endif
15 
16 #ifdef USE_QR_CODE
18 #endif
19 
20 namespace esphome {
21 namespace display {
22 
47 enum class TextAlign {
48  TOP = 0x00,
49  CENTER_VERTICAL = 0x01,
50  BASELINE = 0x02,
51  BOTTOM = 0x04,
52 
53  LEFT = 0x00,
54  CENTER_HORIZONTAL = 0x08,
55  RIGHT = 0x10,
56 
57  TOP_LEFT = TOP | LEFT,
59  TOP_RIGHT = TOP | RIGHT,
60 
64 
68 
72 };
73 
97 enum class ImageAlign {
98  TOP = 0x00,
99  CENTER_VERTICAL = 0x01,
100  BOTTOM = 0x02,
101 
102  LEFT = 0x00,
103  CENTER_HORIZONTAL = 0x04,
104  RIGHT = 0x08,
105 
106  TOP_LEFT = TOP | LEFT,
108  TOP_RIGHT = TOP | RIGHT,
109 
113 
114  BOTTOM_LEFT = BOTTOM | LEFT,
117 
120 };
121 
126 };
127 
133 };
134 
135 class Display;
136 class DisplayPage;
138 
139 using display_writer_t = std::function<void(Display &)>;
140 
141 #define LOG_DISPLAY(prefix, type, obj) \
142  if ((obj) != nullptr) { \
143  ESP_LOGCONFIG(TAG, prefix type); \
144  ESP_LOGCONFIG(TAG, "%s Rotations: %d °", prefix, (obj)->rotation_); \
145  ESP_LOGCONFIG(TAG, "%s Dimensions: %dpx x %dpx", prefix, (obj)->get_width(), (obj)->get_height()); \
146  }
147 
149 extern const Color COLOR_OFF;
151 extern const Color COLOR_ON;
152 
153 class BaseImage {
154  public:
155  virtual void draw(int x, int y, Display *display, Color color_on, Color color_off) = 0;
156  virtual int get_width() const = 0;
157  virtual int get_height() const = 0;
158 };
159 
160 class BaseFont {
161  public:
162  virtual void print(int x, int y, Display *display, Color color, const char *text) = 0;
163  virtual void measure(const char *str, int *width, int *x_offset, int *baseline, int *height) = 0;
164 };
165 
166 class Display {
167  public:
169  virtual void fill(Color color);
171  void clear();
172 
174  virtual int get_width() = 0;
176  virtual int get_height() = 0;
177 
179  inline void draw_pixel_at(int x, int y) { this->draw_pixel_at(x, y, COLOR_ON); }
180 
182  virtual void draw_pixel_at(int x, int y, Color color) = 0;
183 
185  void line(int x1, int y1, int x2, int y2, Color color = COLOR_ON);
186 
188  void horizontal_line(int x, int y, int width, Color color = COLOR_ON);
189 
191  void vertical_line(int x, int y, int height, Color color = COLOR_ON);
192 
195  void rectangle(int x1, int y1, int width, int height, Color color = COLOR_ON);
196 
198  void filled_rectangle(int x1, int y1, int width, int height, Color color = COLOR_ON);
199 
201  void circle(int center_x, int center_xy, int radius, Color color = COLOR_ON);
202 
204  void filled_circle(int center_x, int center_y, int radius, Color color = COLOR_ON);
205 
215  void print(int x, int y, BaseFont *font, Color color, TextAlign align, const char *text);
216 
225  void print(int x, int y, BaseFont *font, Color color, const char *text);
226 
235  void print(int x, int y, BaseFont *font, TextAlign align, const char *text);
236 
244  void print(int x, int y, BaseFont *font, const char *text);
245 
256  void printf(int x, int y, BaseFont *font, Color color, TextAlign align, const char *format, ...)
257  __attribute__((format(printf, 7, 8)));
258 
268  void printf(int x, int y, BaseFont *font, Color color, const char *format, ...) __attribute__((format(printf, 6, 7)));
269 
279  void printf(int x, int y, BaseFont *font, TextAlign align, const char *format, ...)
280  __attribute__((format(printf, 6, 7)));
281 
290  void printf(int x, int y, BaseFont *font, const char *format, ...) __attribute__((format(printf, 5, 6)));
291 
302  void strftime(int x, int y, BaseFont *font, Color color, TextAlign align, const char *format, ESPTime time)
303  __attribute__((format(strftime, 7, 0)));
304 
314  void strftime(int x, int y, BaseFont *font, Color color, const char *format, ESPTime time)
315  __attribute__((format(strftime, 6, 0)));
316 
326  void strftime(int x, int y, BaseFont *font, TextAlign align, const char *format, ESPTime time)
327  __attribute__((format(strftime, 6, 0)));
328 
337  void strftime(int x, int y, BaseFont *font, const char *format, ESPTime time) __attribute__((format(strftime, 5, 0)));
338 
347  void image(int x, int y, BaseImage *image, Color color_on = COLOR_ON, Color color_off = COLOR_OFF);
348 
358  void image(int x, int y, BaseImage *image, ImageAlign align, Color color_on = COLOR_ON, Color color_off = COLOR_OFF);
359 
360 #ifdef USE_GRAPH
361 
368  void graph(int x, int y, graph::Graph *graph, Color color_on = COLOR_ON);
369 
381  void legend(int x, int y, graph::Graph *graph, Color color_on = COLOR_ON);
382 #endif // USE_GRAPH
383 
384 #ifdef USE_QR_CODE
385 
392  void qr_code(int x, int y, qr_code::QrCode *qr_code, Color color_on = COLOR_ON, int scale = 1);
393 #endif
394 
407  void get_text_bounds(int x, int y, const char *text, BaseFont *font, TextAlign align, int *x1, int *y1, int *width,
408  int *height);
409 
411  void set_writer(display_writer_t &&writer);
412 
413  void show_page(DisplayPage *page);
414  void show_next_page();
415  void show_prev_page();
416 
417  void set_pages(std::vector<DisplayPage *> pages);
418 
419  const DisplayPage *get_active_page() const { return this->page_; }
420 
421  void add_on_page_change_trigger(DisplayOnPageChangeTrigger *t) { this->on_page_change_triggers_.push_back(t); }
422 
424  void set_rotation(DisplayRotation rotation);
425 
426  // Internal method to set display auto clearing.
427  void set_auto_clear(bool auto_clear_enabled) { this->auto_clear_enabled_ = auto_clear_enabled; }
428 
429  DisplayRotation get_rotation() const { return this->rotation_; }
430 
434  virtual DisplayType get_display_type() = 0;
435 
442  void start_clipping(Rect rect);
443  void start_clipping(int16_t left, int16_t top, int16_t right, int16_t bottom) {
444  start_clipping(Rect(left, top, right - left, bottom - top));
445  };
446 
452  void extend_clipping(Rect rect);
453  void extend_clipping(int16_t left, int16_t top, int16_t right, int16_t bottom) {
454  this->extend_clipping(Rect(left, top, right - left, bottom - top));
455  };
456 
462  void shrink_clipping(Rect rect);
463  void shrink_clipping(uint16_t left, uint16_t top, uint16_t right, uint16_t bottom) {
464  this->shrink_clipping(Rect(left, top, right - left, bottom - top));
465  };
466 
469  void end_clipping();
470 
475  Rect get_clipping() const;
476 
477  bool is_clipping() const { return !this->clipping_rectangle_.empty(); }
478 
481  bool clip(int x, int y);
482 
483  protected:
484  bool clamp_x_(int x, int w, int &min_x, int &max_x);
485  bool clamp_y_(int y, int h, int &min_y, int &max_y);
486  void vprintf_(int x, int y, BaseFont *font, Color color, TextAlign align, const char *format, va_list arg);
487 
488  void do_update_();
489  void clear_clipping_();
490 
493  DisplayPage *page_{nullptr};
494  DisplayPage *previous_page_{nullptr};
495  std::vector<DisplayOnPageChangeTrigger *> on_page_change_triggers_;
496  bool auto_clear_enabled_{true};
497  std::vector<Rect> clipping_rectangle_;
498 };
499 
500 class DisplayPage {
501  public:
503  void show();
504  void show_next();
505  void show_prev();
506  void set_parent(Display *parent);
507  void set_prev(DisplayPage *prev);
508  void set_next(DisplayPage *next);
509  const display_writer_t &get_writer() const;
510 
511  protected:
514  DisplayPage *prev_{nullptr};
515  DisplayPage *next_{nullptr};
516 };
517 
518 template<typename... Ts> class DisplayPageShowAction : public Action<Ts...> {
519  public:
521 
522  void play(Ts... x) override {
523  auto *page = this->page_.value(x...);
524  if (page != nullptr) {
525  page->show();
526  }
527  }
528 };
529 
530 template<typename... Ts> class DisplayPageShowNextAction : public Action<Ts...> {
531  public:
532  DisplayPageShowNextAction(Display *buffer) : buffer_(buffer) {}
533 
534  void play(Ts... x) override { this->buffer_->show_next_page(); }
535 
537 };
538 
539 template<typename... Ts> class DisplayPageShowPrevAction : public Action<Ts...> {
540  public:
541  DisplayPageShowPrevAction(Display *buffer) : buffer_(buffer) {}
542 
543  void play(Ts... x) override { this->buffer_->show_prev_page(); }
544 
546 };
547 
548 template<typename... Ts> class DisplayIsDisplayingPageCondition : public Condition<Ts...> {
549  public:
550  DisplayIsDisplayingPageCondition(Display *parent) : parent_(parent) {}
551 
552  void set_page(DisplayPage *page) { this->page_ = page; }
553  bool check(Ts... x) override { return this->parent_->get_active_page() == this->page_; }
554 
555  protected:
558 };
559 
560 class DisplayOnPageChangeTrigger : public Trigger<DisplayPage *, DisplayPage *> {
561  public:
562  explicit DisplayOnPageChangeTrigger(Display *parent) { parent->add_on_page_change_trigger(this); }
563  void process(DisplayPage *from, DisplayPage *to);
564  void set_from(DisplayPage *p) { this->from_ = p; }
565  void set_to(DisplayPage *p) { this->to_ = p; }
566 
567  protected:
568  DisplayPage *from_{nullptr};
569  DisplayPage *to_{nullptr};
570 };
571 
572 } // namespace display
573 } // namespace esphome
std::vector< DisplayOnPageChangeTrigger * > on_page_change_triggers_
Definition: display.h:495
DisplayRotation get_rotation() const
Definition: display.h:429
uint16_t x
Definition: tt21100.cpp:17
A more user-friendly version of struct tm from time.h.
Definition: time.h:12
const Color COLOR_OFF(0, 0, 0, 0)
Turn the pixel OFF.
Definition: display.h:149
void extend_clipping(int16_t left, int16_t top, int16_t right, int16_t bottom)
Definition: display.h:453
const DisplayPage * get_active_page() const
Definition: display.h:419
uint16_t y
Definition: tt21100.cpp:18
bool is_clipping() const
Definition: display.h:477
TextAlign
TextAlign is used to tell the display class how to position a piece of text.
Definition: display.h:47
std::function< void(Display &)> display_writer_t
Definition: display.h:139
Base class for all automation conditions.
Definition: automation.h:74
void shrink_clipping(uint16_t left, uint16_t top, uint16_t right, uint16_t bottom)
Definition: display.h:463
ImageAlign
ImageAlign is used to tell the display class how to position a image.
Definition: display.h:97
void start_clipping(int16_t left, int16_t top, int16_t right, int16_t bottom)
Definition: display.h:443
enum esphome::EntityCategory __attribute__
display_writer_t writer_
Definition: display.h:513
const Color COLOR_ON(255, 255, 255, 255)
Turn the pixel ON.
Definition: display.h:151
TEMPLATABLE_VALUE(DisplayPage *, page) void play(Ts... x) override
Definition: display.h:520
uint8_t h
Definition: bl0939.h:21
void draw_pixel_at(int x, int y)
Set a single pixel at the specified coordinates to default color.
Definition: display.h:179
void add_on_page_change_trigger(DisplayOnPageChangeTrigger *t)
Definition: display.h:421
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
void set_auto_clear(bool auto_clear_enabled)
Definition: display.h:427
std::vector< Rect > clipping_rectangle_
Definition: display.h:497