mirror of
https://github.com/esphome/esphome.git
synced 2026-10-14 02:02:51 +00:00
[display] Build on_page_change with build_callback_automation and compile it out when unused (#20456)
This commit is contained in:
@@ -21,7 +21,6 @@ from esphome.const import (
|
||||
CONF_PAGES,
|
||||
CONF_ROTATION,
|
||||
CONF_TO,
|
||||
CONF_TRIGGER_ID,
|
||||
CONF_UPDATE_INTERVAL,
|
||||
CONF_WIDTH,
|
||||
SCHEDULER_DONT_RUN,
|
||||
@@ -39,14 +38,13 @@ DisplayPage = display_ns.class_("DisplayPage")
|
||||
DisplayPagePtr = DisplayPage.operator("ptr")
|
||||
DisplayRef = Display.operator("ref")
|
||||
DisplayPageShowAction = display_ns.class_("DisplayPageShowAction", automation.Action)
|
||||
DisplayOnPageChangeTrigger = display_ns.class_(
|
||||
"DisplayOnPageChangeTrigger", automation.Trigger
|
||||
)
|
||||
|
||||
CONF_ON_PAGE_CHANGE = "on_page_change"
|
||||
CONF_SHOW_TEST_CARD = "show_test_card"
|
||||
CONF_UNSPECIFIED = "unspecified"
|
||||
|
||||
_request_page_change_slot = cg.slot_counter("DISPLAY_PAGE_CHANGE_CALLBACK_COUNT")
|
||||
|
||||
DISPLAY_ROTATIONS = {
|
||||
0: display_ns.DISPLAY_ROTATION_0_DEGREES,
|
||||
90: display_ns.DISPLAY_ROTATION_90_DEGREES,
|
||||
@@ -99,9 +97,6 @@ FULL_DISPLAY_SCHEMA = BASIC_DISPLAY_SCHEMA.extend(
|
||||
),
|
||||
cv.Optional(CONF_ON_PAGE_CHANGE): automation.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(
|
||||
DisplayOnPageChangeTrigger
|
||||
),
|
||||
cv.Optional(CONF_FROM): cv.use_id(DisplayPage),
|
||||
cv.Optional(CONF_TO): cv.use_id(DisplayPage),
|
||||
}
|
||||
@@ -137,15 +132,18 @@ async def setup_display_core_(var, config):
|
||||
pages.append(page)
|
||||
cg.add(var.set_pages(pages))
|
||||
for conf in config.get(CONF_ON_PAGE_CHANGE, []):
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||
if CONF_FROM in conf:
|
||||
page = await cg.get_variable(conf[CONF_FROM])
|
||||
cg.add(trigger.set_from(page))
|
||||
if CONF_TO in conf:
|
||||
page = await cg.get_variable(conf[CONF_TO])
|
||||
cg.add(trigger.set_to(page))
|
||||
await automation.build_automation(
|
||||
trigger, [(DisplayPagePtr, "from"), (DisplayPagePtr, "to")], conf
|
||||
_request_page_change_slot(str(var))
|
||||
checks = []
|
||||
for key, name in ((CONF_FROM, "from"), (CONF_TO, "to")):
|
||||
if (page_id := conf.get(key)) is not None:
|
||||
page = await cg.get_variable(page_id)
|
||||
checks.append(f"{name} == ::{page}")
|
||||
await automation.build_callback_automation(
|
||||
var,
|
||||
"add_on_page_change_callback",
|
||||
[(DisplayPagePtr, "from"), (DisplayPagePtr, "to")],
|
||||
conf,
|
||||
when=" && ".join(checks) or None,
|
||||
)
|
||||
if config.get(CONF_SHOW_TEST_CARD):
|
||||
cg.add(var.show_test_card())
|
||||
|
||||
@@ -678,12 +678,14 @@ void Display::set_pages(std::vector<DisplayPage *> pages) {
|
||||
}
|
||||
|
||||
void Display::show_page(DisplayPage *page) {
|
||||
this->previous_page_ = this->page_;
|
||||
#ifdef DISPLAY_PAGE_CHANGE_CALLBACK_COUNT
|
||||
DisplayPage *previous = this->page_;
|
||||
this->page_ = page;
|
||||
if (this->previous_page_ != this->page_) {
|
||||
for (auto *t : on_page_change_triggers_)
|
||||
t->process(this->previous_page_, this->page_);
|
||||
}
|
||||
if (previous != page)
|
||||
this->page_change_callback_.call(previous, page);
|
||||
#else
|
||||
this->page_ = page;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Display::do_update_() {
|
||||
@@ -700,11 +702,6 @@ void Display::do_update_() {
|
||||
this->clear_clipping_();
|
||||
}
|
||||
|
||||
void DisplayOnPageChangeTrigger::process(DisplayPage *from, DisplayPage *to) {
|
||||
if ((this->from_ == nullptr || this->from_ == from) && (this->to_ == nullptr || this->to_ == to))
|
||||
this->trigger(from, to);
|
||||
}
|
||||
|
||||
void Display::strftime(int x, int y, BaseFont *font, Color color, Color background, TextAlign align, const char *format,
|
||||
ESPTime time) {
|
||||
char buffer[64];
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#include "esphome/core/color.h"
|
||||
#include "esphome/core/automation.h"
|
||||
#include "esphome/core/defines.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/time.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include "display_color_utils.h"
|
||||
@@ -173,7 +175,6 @@ enum RegularPolygonDrawing {
|
||||
|
||||
class Display;
|
||||
class DisplayPage;
|
||||
class DisplayOnPageChangeTrigger;
|
||||
|
||||
/** Optimized display writer that uses function pointers for stateless lambdas.
|
||||
*
|
||||
@@ -702,7 +703,11 @@ class Display : public PollingComponent {
|
||||
|
||||
const DisplayPage *get_active_page() const { return this->page_; }
|
||||
|
||||
void add_on_page_change_trigger(DisplayOnPageChangeTrigger *t) { this->on_page_change_triggers_.push_back(t); }
|
||||
#ifdef DISPLAY_PAGE_CHANGE_CALLBACK_COUNT
|
||||
template<typename F> void add_on_page_change_callback(F &&callback) {
|
||||
this->page_change_callback_.add(std::forward<F>(callback));
|
||||
}
|
||||
#endif
|
||||
|
||||
/// Internal method to set the display rotation with.
|
||||
virtual void set_rotation(DisplayRotation rotation);
|
||||
@@ -809,8 +814,9 @@ class Display : public PollingComponent {
|
||||
DisplayRotation rotation_{DISPLAY_ROTATION_0_DEGREES};
|
||||
display_writer_t writer_{};
|
||||
DisplayPage *page_{nullptr};
|
||||
DisplayPage *previous_page_{nullptr};
|
||||
std::vector<DisplayOnPageChangeTrigger *> on_page_change_triggers_;
|
||||
#ifdef DISPLAY_PAGE_CHANGE_CALLBACK_COUNT
|
||||
StaticCallbackManager<DISPLAY_PAGE_CHANGE_CALLBACK_COUNT, void(DisplayPage *, DisplayPage *)> page_change_callback_;
|
||||
#endif
|
||||
bool auto_clear_enabled_{true};
|
||||
std::vector<Rect> clipping_rectangle_;
|
||||
uint8_t wdt_pixel_counter_{0};
|
||||
@@ -850,18 +856,6 @@ template<typename... Ts> class DisplayPageShowAction final : public Action<Ts...
|
||||
}
|
||||
};
|
||||
|
||||
class DisplayOnPageChangeTrigger final : public Trigger<DisplayPage *, DisplayPage *> {
|
||||
public:
|
||||
explicit DisplayOnPageChangeTrigger(Display *parent) { parent->add_on_page_change_trigger(this); }
|
||||
void process(DisplayPage *from, DisplayPage *to);
|
||||
void set_from(DisplayPage *p) { this->from_ = p; }
|
||||
void set_to(DisplayPage *p) { this->to_ = p; }
|
||||
|
||||
protected:
|
||||
DisplayPage *from_{nullptr};
|
||||
DisplayPage *to_{nullptr};
|
||||
};
|
||||
|
||||
const LogString *text_align_to_string(TextAlign textalign);
|
||||
|
||||
} // namespace esphome::display
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
#define USE_DEEP_SLEEP_ON_WAKE
|
||||
#define USE_DEVICES
|
||||
#define USE_DISPLAY
|
||||
#define DISPLAY_PAGE_CHANGE_CALLBACK_COUNT 1
|
||||
#define USE_ENTITY_DEVICE_CLASS
|
||||
#define USE_ENTITY_ICON
|
||||
#define USE_ENTITY_UNIT_OF_MEASUREMENT
|
||||
|
||||
Reference in New Issue
Block a user