6 namespace touchscreen {
8 static const char *
const TAG =
"touchscreen";
14 this->store_.init =
true;
15 this->store_.touched =
false;
16 ESP_LOGD(TAG,
"Attach Touch Interupt");
20 if (this->display_ !=
nullptr) {
21 this->display_width_ = this->display_->get_width();
22 this->display_height_ = this->display_->get_height();
28 if (!this->store_.init) {
29 this->store_.touched =
true;
32 ESP_LOGW(TAG,
"Touch Polling Stopped. You can safely remove the 'update_interval:' variable from the YAML file.");
38 if (this->store_.touched) {
39 ESP_LOGVV(TAG,
"<< Do Touch loop >>");
40 this->first_touch_ = this->touches_.empty();
41 this->need_update_ =
false;
42 this->is_touched_ =
false;
43 this->skip_update_ =
false;
44 for (
auto &tp : this->touches_) {
45 if (tp.second.state == STATE_PRESSED || tp.second.state == STATE_UPDATED) {
46 tp.second.state |= STATE_RELEASING;
48 tp.second.state = STATE_RELEASED;
50 tp.second.x_prev = tp.second.x;
51 tp.second.y_prev = tp.second.y;
53 this->update_touches();
54 if (this->skip_update_) {
55 for (
auto &tp : this->touches_) {
56 tp.second.state &= ~STATE_RELEASING;
59 this->store_.touched =
false;
60 this->defer([
this]() { this->send_touches_(); });
61 if (this->touch_timeout_ > 0) {
64 if (this->is_touched_) {
65 this->set_timeout(TAG, this->touch_timeout_, [
this]() { this->store_.touched =
true; });
67 this->cancel_timeout(TAG);
77 if (this->touches_.count(
id) == 0) {
78 tp.
state = STATE_PRESSED;
81 tp = this->touches_[
id];
82 tp.
state = STATE_UPDATED;
89 if (this->x_raw_max_ != this->x_raw_min_ and this->y_raw_max_ != this->y_raw_min_) {
90 x = this->normalize_(x_raw, this->x_raw_min_, this->x_raw_max_, this->invert_x_);
91 y = this->normalize_(y_raw, this->y_raw_min_, this->y_raw_max_, this->invert_y_);
93 if (this->swap_x_y_) {
97 tp.
x = (uint16_t) ((
int) x * this->display_width_ / 0x1000);
98 tp.
y = (uint16_t) ((
int) y * this->display_height_ / 0x1000);
100 tp.
state |= STATE_CALIBRATE;
102 if (tp.
state == STATE_PRESSED) {
107 this->touches_[
id] = tp;
109 this->is_touched_ =
true;
111 this->need_update_ =
true;
117 ESP_LOGV(TAG,
"Touch status: is_touched=%d, was_touched=%d", this->is_touched_, this->was_touched_);
118 for (
auto tp : this->touches_) {
119 ESP_LOGV(TAG,
"Touch status: %d/%d: raw:(%4d,%4d,%4d) calc:(%3d,%4d)", tp.second.id, tp.second.state,
120 tp.second.x_raw, tp.second.y_raw, tp.second.z_raw, tp.second.x, tp.second.y);
121 touches.push_back(tp.second);
123 if (this->need_update_ || (!this->is_touched_ && this->was_touched_)) {
124 this->update_trigger_.trigger(touches);
125 for (
auto *listener : this->touch_listeners_) {
126 listener->update(touches);
129 if (!this->is_touched_) {
130 if (this->was_touched_) {
131 this->release_trigger_.trigger();
132 for (
auto *listener : this->touch_listeners_)
134 this->touches_.clear();
137 if (this->first_touch_) {
138 TouchPoint tp = this->touches_.begin()->second;
139 this->touch_trigger_.trigger(tp, touches);
140 for (
auto *listener : this->touch_listeners_) {
145 this->was_touched_ = this->is_touched_;
151 if (val <= min_val) {
153 }
else if (val >= max_val) {
156 ret = (int16_t) ((
int) 0xfff * (val - min_val) / (max_val - min_val));
159 ret = (inverted) ? 0xfff - ret : ret;
std::vector< TouchPoint > TouchPoints_t
static void gpio_intr(TouchscreenInterrupt *store)
T id(T value)
Helper function to make id(var) known from lambdas work in custom components.
void attach_interrupt_(InternalGPIOPin *irq_pin, esphome::gpio::InterruptType type)
Call this function to send touch points to the on_touch listener and the binary_sensors.
int16_t normalize_(int16_t val, int16_t min_val, int16_t max_val, bool inverted=false)
void call_setup() override
void call_setup() override
void add_raw_touch_position_(uint8_t id, int16_t x_raw, int16_t y_raw, int16_t z_raw=0)
Implementation of SPI Controller mode.
void attach_interrupt(void(*func)(T *), T *arg, gpio::InterruptType type) const
void swap(optional< T > &x, optional< T > &y) noexcept