mirror of
https://github.com/esphome/esphome.git
synced 2024-11-12 18:27:46 +01:00
Add the on_page_change display trigger (#1687)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
parent
cccb1a2c9e
commit
072dce340e
4 changed files with 68 additions and 2 deletions
|
@ -2,7 +2,16 @@ import esphome.codegen as cg
|
|||
import esphome.config_validation as cv
|
||||
from esphome import core, automation
|
||||
from esphome.automation import maybe_simple_id
|
||||
from esphome.const import CONF_ID, CONF_LAMBDA, CONF_PAGES, CONF_PAGE_ID, CONF_ROTATION
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_LAMBDA,
|
||||
CONF_PAGES,
|
||||
CONF_PAGE_ID,
|
||||
CONF_ROTATION,
|
||||
CONF_FROM,
|
||||
CONF_TO,
|
||||
CONF_TRIGGER_ID,
|
||||
)
|
||||
from esphome.core import coroutine_with_priority
|
||||
|
||||
IS_PLATFORM_COMPONENT = True
|
||||
|
@ -22,6 +31,9 @@ DisplayPageShowPrevAction = display_ns.class_(
|
|||
DisplayIsDisplayingPageCondition = display_ns.class_(
|
||||
"DisplayIsDisplayingPageCondition", automation.Condition
|
||||
)
|
||||
DisplayOnPageChangeTrigger = display_ns.class_("DisplayOnPageChangeTrigger")
|
||||
|
||||
CONF_ON_PAGE_CHANGE = "on_page_change"
|
||||
|
||||
DISPLAY_ROTATIONS = {
|
||||
0: display_ns.DISPLAY_ROTATION_0_DEGREES,
|
||||
|
@ -56,6 +68,15 @@ FULL_DISPLAY_SCHEMA = BASIC_DISPLAY_SCHEMA.extend(
|
|||
),
|
||||
cv.Length(min=1),
|
||||
),
|
||||
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),
|
||||
}
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -72,6 +93,17 @@ async def setup_display_core_(var, config):
|
|||
page = cg.new_Pvariable(conf[CONF_ID], lambda_)
|
||||
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
|
||||
)
|
||||
|
||||
|
||||
async def register_display(var, config):
|
||||
|
|
|
@ -315,7 +315,14 @@ void DisplayBuffer::set_pages(std::vector<DisplayPage *> pages) {
|
|||
pages[pages.size() - 1]->set_next(pages[0]);
|
||||
this->show_page(pages[0]);
|
||||
}
|
||||
void DisplayBuffer::show_page(DisplayPage *page) { this->page_ = page; }
|
||||
void DisplayBuffer::show_page(DisplayPage *page) {
|
||||
this->previous_page_ = 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_);
|
||||
}
|
||||
}
|
||||
void DisplayBuffer::show_next_page() { this->page_->show_next(); }
|
||||
void DisplayBuffer::show_prev_page() { this->page_->show_prev(); }
|
||||
void DisplayBuffer::do_update_() {
|
||||
|
@ -326,6 +333,10 @@ void DisplayBuffer::do_update_() {
|
|||
(*this->writer_)(*this);
|
||||
}
|
||||
}
|
||||
void DisplayOnPageChangeTrigger::process(DisplayPage *from, DisplayPage *to) {
|
||||
if ((this->from_ == nullptr || this->from_ == from) && (this->to_ == nullptr || this->to_ == to))
|
||||
this->trigger(from, to);
|
||||
}
|
||||
#ifdef USE_TIME
|
||||
void DisplayBuffer::strftime(int x, int y, Font *font, Color color, TextAlign align, const char *format,
|
||||
time::ESPTime time) {
|
||||
|
|
|
@ -81,6 +81,7 @@ class Font;
|
|||
class Image;
|
||||
class DisplayBuffer;
|
||||
class DisplayPage;
|
||||
class DisplayOnPageChangeTrigger;
|
||||
|
||||
using display_writer_t = std::function<void(DisplayBuffer &)>;
|
||||
|
||||
|
@ -298,6 +299,8 @@ class DisplayBuffer {
|
|||
|
||||
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); }
|
||||
|
||||
/// Internal method to set the display rotation with.
|
||||
void set_rotation(DisplayRotation rotation);
|
||||
|
||||
|
@ -318,6 +321,8 @@ class DisplayBuffer {
|
|||
DisplayRotation rotation_{DISPLAY_ROTATION_0_DEGREES};
|
||||
optional<display_writer_t> writer_{};
|
||||
DisplayPage *page_{nullptr};
|
||||
DisplayPage *previous_page_{nullptr};
|
||||
std::vector<DisplayOnPageChangeTrigger *> on_page_change_triggers_;
|
||||
};
|
||||
|
||||
class DisplayPage {
|
||||
|
@ -465,5 +470,17 @@ template<typename... Ts> class DisplayIsDisplayingPageCondition : public Conditi
|
|||
DisplayPage *page_;
|
||||
};
|
||||
|
||||
class DisplayOnPageChangeTrigger : public Trigger<DisplayPage *, DisplayPage *> {
|
||||
public:
|
||||
explicit DisplayOnPageChangeTrigger(DisplayBuffer *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};
|
||||
};
|
||||
|
||||
} // namespace display
|
||||
} // namespace esphome
|
||||
|
|
|
@ -1874,6 +1874,12 @@ display:
|
|||
- id: page2
|
||||
lambda: |-
|
||||
// Nothing
|
||||
on_page_change:
|
||||
from: page1
|
||||
to: page2
|
||||
then:
|
||||
lambda: |-
|
||||
ESP_LOGD("display", "1 -> 2");
|
||||
- platform: ssd1306_spi
|
||||
model: 'SSD1306 128x64'
|
||||
cs_pin: GPIO23
|
||||
|
|
Loading…
Reference in a new issue