esphome 2024.10.2__py3-none-any.whl → 2024.11.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- esphome/__main__.py +22 -4
- esphome/automation.py +29 -2
- esphome/components/animation/__init__.py +5 -8
- esphome/components/animation/animation.cpp +1 -1
- esphome/components/audio/__init__.py +9 -0
- esphome/components/audio/audio.h +21 -0
- esphome/components/axs15231/__init__.py +6 -0
- esphome/components/axs15231/touchscreen/__init__.py +36 -0
- esphome/components/axs15231/touchscreen/axs15231_touchscreen.cpp +64 -0
- esphome/components/axs15231/touchscreen/axs15231_touchscreen.h +27 -0
- esphome/components/bme68x_bsec2/__init__.py +1 -1
- esphome/components/bme68x_bsec2/bme68x_bsec2.cpp +50 -47
- esphome/components/bme68x_bsec2/bme68x_bsec2.h +0 -2
- esphome/components/bytebuffer/__init__.py +5 -0
- esphome/components/bytebuffer/bytebuffer.h +421 -0
- esphome/components/climate/__init__.py +14 -13
- esphome/components/datetime/__init__.py +3 -3
- esphome/components/debug/debug_esp32.cpp +16 -8
- esphome/components/dfplayer/dfplayer.cpp +132 -6
- esphome/components/dfplayer/dfplayer.h +19 -53
- esphome/components/display/display.cpp +142 -0
- esphome/components/display/display.h +7 -0
- esphome/components/es8311/__init__.py +0 -0
- esphome/components/es8311/audio_dac.py +70 -0
- esphome/components/es8311/es8311.cpp +227 -0
- esphome/components/es8311/es8311.h +135 -0
- esphome/components/es8311/es8311_const.h +195 -0
- esphome/components/esp32/boards.py +199 -1
- esphome/components/esp32/gpio.py +3 -1
- esphome/components/esp32_ble/const_esp32c6.h +7 -0
- esphome/components/esp32_ble_client/ble_client_base.h +1 -1
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +3 -0
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +2 -1
- esphome/components/esp32_rmt_led_strip/led_strip.cpp +2 -2
- esphome/components/esp32_rmt_led_strip/led_strip.h +2 -0
- esphome/components/esp32_rmt_led_strip/light.py +3 -1
- esphome/components/esp8266/gpio.py +7 -5
- esphome/components/ethernet/__init__.py +55 -1
- esphome/components/ethernet/ethernet_component.cpp +14 -1
- esphome/components/ethernet/ethernet_component.h +7 -1
- esphome/components/font/__init__.py +213 -108
- esphome/components/gp8403/output/__init__.py +1 -1
- esphome/components/host/gpio.py +6 -4
- esphome/components/http_request/__init__.py +12 -0
- esphome/components/http_request/http_request.h +65 -3
- esphome/components/http_request/http_request_arduino.cpp +4 -3
- esphome/components/http_request/http_request_idf.cpp +12 -14
- esphome/components/http_request/ota/ota_http_request.cpp +1 -1
- esphome/components/http_request/update/http_request_update.cpp +1 -1
- esphome/components/i2c_device/__init__.py +26 -0
- esphome/components/i2c_device/i2c_device.cpp +17 -0
- esphome/components/i2c_device/i2c_device.h +18 -0
- esphome/components/i2s_audio/__init__.py +1 -3
- esphome/components/i2s_audio/speaker/__init__.py +12 -4
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +426 -200
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +92 -33
- esphome/components/ili9xxx/display.py +5 -1
- esphome/components/image/__init__.py +5 -8
- esphome/components/image/image.cpp +14 -14
- esphome/components/image/image.h +20 -24
- esphome/components/internal_temperature/internal_temperature.cpp +51 -2
- esphome/components/internal_temperature/internal_temperature.h +1 -0
- esphome/components/ld2420/ld2420.cpp +1 -1
- esphome/components/libretiny/gpio.py +4 -2
- esphome/components/light/__init__.py +32 -1
- esphome/components/light/automation.py +39 -32
- esphome/components/light/effects.py +36 -36
- esphome/components/light/light_state.cpp +6 -16
- esphome/components/light/light_state.h +34 -0
- esphome/components/light/types.py +3 -1
- esphome/components/logger/logger_esp32.cpp +15 -0
- esphome/components/lvgl/__init__.py +202 -95
- esphome/components/lvgl/automation.py +42 -40
- esphome/components/lvgl/binary_sensor/__init__.py +8 -15
- esphome/components/lvgl/defines.py +14 -8
- esphome/components/lvgl/encoders.py +11 -8
- esphome/components/lvgl/keypads.py +77 -0
- esphome/components/lvgl/light/__init__.py +6 -8
- esphome/components/lvgl/lv_validation.py +2 -4
- esphome/components/lvgl/lvcode.py +3 -9
- esphome/components/lvgl/lvgl_esphome.cpp +210 -89
- esphome/components/lvgl/lvgl_esphome.h +113 -30
- esphome/components/lvgl/lvgl_proxy.h +17 -0
- esphome/components/lvgl/number/__init__.py +10 -15
- esphome/components/lvgl/schemas.py +4 -2
- esphome/components/lvgl/select/__init__.py +12 -37
- esphome/components/lvgl/select/lvgl_select.h +27 -33
- esphome/components/lvgl/sensor/__init__.py +8 -14
- esphome/components/lvgl/styles.py +3 -4
- esphome/components/lvgl/switch/__init__.py +8 -13
- esphome/components/lvgl/text/__init__.py +5 -6
- esphome/components/lvgl/text_sensor/__init__.py +15 -15
- esphome/components/lvgl/touchscreens.py +2 -3
- esphome/components/lvgl/trigger.py +7 -9
- esphome/components/lvgl/types.py +9 -3
- esphome/components/lvgl/widgets/__init__.py +32 -21
- esphome/components/lvgl/widgets/animimg.py +4 -3
- esphome/components/lvgl/widgets/dropdown.py +22 -10
- esphome/components/lvgl/widgets/img.py +2 -0
- esphome/components/lvgl/widgets/msgbox.py +6 -5
- esphome/components/lvgl/widgets/obj.py +4 -2
- esphome/components/lvgl/widgets/page.py +3 -2
- esphome/components/lvgl/widgets/qrcode.py +54 -0
- esphome/components/lvgl/widgets/roller.py +21 -14
- esphome/components/lvgl/widgets/tileview.py +2 -1
- esphome/components/max17043/__init__.py +1 -0
- esphome/components/max17043/automation.h +20 -0
- esphome/components/max17043/max17043.cpp +98 -0
- esphome/components/max17043/max17043.h +29 -0
- esphome/components/max17043/sensor.py +77 -0
- esphome/components/media_player/__init__.py +11 -0
- esphome/components/media_player/automation.h +10 -0
- esphome/components/media_player/media_player.cpp +4 -0
- esphome/components/midea/air_conditioner.cpp +17 -1
- esphome/components/mlx90393/sensor.py +1 -1
- esphome/components/modbus/modbus.cpp +24 -12
- esphome/components/modbus_controller/__init__.py +31 -1
- esphome/components/modbus_controller/automation.h +16 -0
- esphome/components/modbus_controller/const.py +2 -0
- esphome/components/modbus_controller/modbus_controller.cpp +14 -2
- esphome/components/modbus_controller/modbus_controller.h +9 -0
- esphome/components/mopeka_pro_check/mopeka_pro_check.cpp +40 -21
- esphome/components/mopeka_pro_check/mopeka_pro_check.h +9 -2
- esphome/components/mopeka_pro_check/sensor.py +41 -0
- esphome/components/mqtt/__init__.py +36 -0
- esphome/components/mqtt/mqtt_client.cpp +27 -3
- esphome/components/mqtt/mqtt_client.h +27 -2
- esphome/components/mqtt/mqtt_climate.cpp +4 -2
- esphome/components/mqtt/mqtt_component.cpp +6 -0
- esphome/components/mqtt/mqtt_component.h +4 -0
- esphome/components/mqtt/mqtt_const.h +6 -0
- esphome/components/online_image/online_image.cpp +2 -8
- esphome/components/online_image/online_image.h +2 -6
- esphome/components/opentherm/__init__.py +35 -9
- esphome/components/opentherm/binary_sensor/__init__.py +33 -0
- esphome/components/opentherm/const.py +11 -0
- esphome/components/opentherm/generate.py +142 -0
- esphome/components/opentherm/hub.cpp +130 -24
- esphome/components/opentherm/hub.h +62 -9
- esphome/components/opentherm/input.h +18 -0
- esphome/components/opentherm/input.py +51 -0
- esphome/components/opentherm/number/__init__.py +74 -0
- esphome/components/opentherm/number/number.cpp +40 -0
- esphome/components/opentherm/number/number.h +31 -0
- esphome/components/opentherm/opentherm.cpp +30 -0
- esphome/components/opentherm/opentherm.h +34 -2
- esphome/components/opentherm/opentherm_macros.h +151 -0
- esphome/components/opentherm/output/__init__.py +47 -0
- esphome/components/opentherm/output/output.cpp +18 -0
- esphome/components/opentherm/output/output.h +33 -0
- esphome/components/opentherm/schema.py +814 -0
- esphome/components/opentherm/sensor/__init__.py +51 -0
- esphome/components/opentherm/switch/__init__.py +43 -0
- esphome/components/opentherm/switch/switch.cpp +28 -0
- esphome/components/opentherm/switch/switch.h +20 -0
- esphome/components/opentherm/validate.py +31 -0
- esphome/components/pcd8544/display.py +8 -4
- esphome/components/prometheus/prometheus_handler.cpp +176 -14
- esphome/components/prometheus/prometheus_handler.h +25 -7
- esphome/components/qspi_amoled/display.py +1 -141
- esphome/components/qspi_dbi/display.py +185 -0
- esphome/components/qspi_dbi/models.py +64 -0
- esphome/components/{qspi_amoled/qspi_amoled.cpp → qspi_dbi/qspi_dbi.cpp} +95 -46
- esphome/components/{qspi_amoled/qspi_amoled.h → qspi_dbi/qspi_dbi.h} +26 -15
- esphome/components/rp2040/__init__.py +6 -3
- esphome/components/rp2040/gpio.py +5 -3
- esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp +20 -0
- esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.h +3 -2
- esphome/components/rtttl/rtttl.cpp +4 -1
- esphome/components/rtttl/rtttl.h +1 -0
- esphome/components/sdl/sdl_esphome.cpp +22 -5
- esphome/components/sdl/sdl_esphome.h +1 -0
- esphome/components/sdm_meter/sdm_meter.cpp +1 -1
- esphome/components/sensor/__init__.py +18 -8
- esphome/components/sensor/filter.cpp +19 -18
- esphome/components/sensor/filter.h +9 -10
- esphome/components/sgp4x/sgp4x.cpp +40 -74
- esphome/components/sgp4x/sgp4x.h +5 -3
- esphome/components/speaker/__init__.py +51 -5
- esphome/components/speaker/automation.h +25 -0
- esphome/components/speaker/speaker.h +72 -1
- esphome/components/spi/__init__.py +15 -14
- esphome/components/spi_device/__init__.py +4 -15
- esphome/components/ssd1306_spi/display.py +6 -2
- esphome/components/ssd1322_spi/display.py +6 -2
- esphome/components/ssd1325_spi/display.py +6 -2
- esphome/components/ssd1327_spi/display.py +6 -2
- esphome/components/ssd1331_spi/display.py +6 -2
- esphome/components/ssd1351_spi/display.py +6 -2
- esphome/components/st7567_spi/display.py +6 -2
- esphome/components/st7701s/display.py +5 -1
- esphome/components/st7735/display.py +10 -5
- esphome/components/st7789v/display.py +12 -7
- esphome/components/statsd/statsd.cpp +2 -0
- esphome/components/statsd/statsd.h +2 -0
- esphome/components/sun/sun.h +3 -0
- esphome/components/tc74/__init__.py +1 -0
- esphome/components/tc74/sensor.py +32 -0
- esphome/components/tc74/tc74.cpp +68 -0
- esphome/components/tc74/tc74.h +28 -0
- esphome/components/touchscreen/__init__.py +41 -50
- esphome/components/touchscreen/touchscreen.h +4 -8
- esphome/components/tuya/fan/tuya_fan.cpp +1 -1
- esphome/components/udp/udp_component.cpp +6 -3
- esphome/components/udp/udp_component.h +4 -2
- esphome/components/waveshare_epaper/display.py +6 -2
- esphome/components/web_server/web_server.cpp +22 -0
- esphome/components/web_server/web_server.h +3 -0
- esphome/components/weikai/weikai.h +2 -2
- esphome/components/wifi/wifi_component.cpp +2 -2
- esphome/components/wifi/wifi_component_esp32_arduino.cpp +4 -4
- esphome/components/wifi/wifi_component_esp8266.cpp +4 -4
- esphome/components/wifi/wifi_component_esp_idf.cpp +2 -2
- esphome/components/xpt2046/touchscreen/__init__.py +7 -32
- esphome/config_validation.py +3 -1
- esphome/const.py +9 -2
- esphome/core/defines.h +8 -2
- esphome/core/helpers.cpp +32 -17
- esphome/core/helpers.h +32 -16
- esphome/core/ring_buffer.cpp +2 -2
- esphome/core/ring_buffer.h +2 -2
- esphome/dashboard/core.py +25 -0
- esphome/dashboard/status/mdns.py +3 -4
- esphome/dashboard/web_server.py +54 -19
- esphome/espota2.py +36 -35
- esphome/helpers.py +68 -16
- esphome/mqtt.py +9 -2
- esphome/storage_json.py +4 -0
- esphome/writer.py +7 -18
- esphome/zeroconf.py +8 -6
- {esphome-2024.10.2.dist-info → esphome-2024.11.0.dist-info}/METADATA +7 -5
- {esphome-2024.10.2.dist-info → esphome-2024.11.0.dist-info}/RECORD +237 -191
- esphome/core/bytebuffer.cpp +0 -167
- esphome/core/bytebuffer.h +0 -144
- /esphome/components/{qspi_amoled → qspi_dbi}/__init__.py +0 -0
- {esphome-2024.10.2.dist-info → esphome-2024.11.0.dist-info}/LICENSE +0 -0
- {esphome-2024.10.2.dist-info → esphome-2024.11.0.dist-info}/WHEEL +0 -0
- {esphome-2024.10.2.dist-info → esphome-2024.11.0.dist-info}/entry_points.txt +0 -0
- {esphome-2024.10.2.dist-info → esphome-2024.11.0.dist-info}/top_level.txt +0 -0
@@ -5,16 +5,12 @@
|
|
5
5
|
#include "lvgl_hal.h"
|
6
6
|
#include "lvgl_esphome.h"
|
7
7
|
|
8
|
+
#include <numeric>
|
9
|
+
|
8
10
|
namespace esphome {
|
9
11
|
namespace lvgl {
|
10
12
|
static const char *const TAG = "lvgl";
|
11
13
|
|
12
|
-
#if LV_USE_LOG
|
13
|
-
static void log_cb(const char *buf) {
|
14
|
-
esp_log_printf_(ESPHOME_LOG_LEVEL_INFO, TAG, 0, "%.*s", (int) strlen(buf) - 1, buf);
|
15
|
-
}
|
16
|
-
#endif // LV_USE_LOG
|
17
|
-
|
18
14
|
static const char *const EVENT_NAMES[] = {
|
19
15
|
"NONE",
|
20
16
|
"PRESSED",
|
@@ -69,43 +65,57 @@ std::string lv_event_code_name_for(uint8_t event_code) {
|
|
69
65
|
}
|
70
66
|
return str_sprintf("%2d", event_code);
|
71
67
|
}
|
68
|
+
|
72
69
|
static void rounder_cb(lv_disp_drv_t *disp_drv, lv_area_t *area) {
|
73
|
-
//
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
70
|
+
// cater for display driver chips with special requirements for bounds of partial
|
71
|
+
// draw areas. Extend the draw area to satisfy:
|
72
|
+
// * Coordinates must be a multiple of draw_rounding
|
73
|
+
auto *comp = static_cast<LvglComponent *>(disp_drv->user_data);
|
74
|
+
auto draw_rounding = comp->draw_rounding;
|
75
|
+
// round down the start coordinates
|
76
|
+
area->x1 = area->x1 / draw_rounding * draw_rounding;
|
77
|
+
area->y1 = area->y1 / draw_rounding * draw_rounding;
|
78
|
+
// round up the end coordinates
|
79
|
+
area->x2 = (area->x2 + draw_rounding) / draw_rounding * draw_rounding - 1;
|
80
|
+
area->y2 = (area->y2 + draw_rounding) / draw_rounding * draw_rounding - 1;
|
82
81
|
}
|
83
82
|
|
84
83
|
lv_event_code_t lv_api_event; // NOLINT
|
85
84
|
lv_event_code_t lv_update_event; // NOLINT
|
86
|
-
void LvglComponent::dump_config() {
|
85
|
+
void LvglComponent::dump_config() {
|
86
|
+
ESP_LOGCONFIG(TAG, "LVGL:");
|
87
|
+
ESP_LOGCONFIG(TAG, " Display width/height: %d x %d", this->disp_drv_.hor_res, this->disp_drv_.ver_res);
|
88
|
+
ESP_LOGCONFIG(TAG, " Rotation: %d", this->rotation);
|
89
|
+
ESP_LOGCONFIG(TAG, " Draw rounding: %d", (int) this->draw_rounding);
|
90
|
+
}
|
87
91
|
void LvglComponent::set_paused(bool paused, bool show_snow) {
|
88
92
|
this->paused_ = paused;
|
89
93
|
this->show_snow_ = show_snow;
|
90
|
-
this->snow_line_ = 0;
|
91
94
|
if (!paused && lv_scr_act() != nullptr) {
|
92
95
|
lv_disp_trig_activity(this->disp_); // resets the inactivity time
|
93
96
|
lv_obj_invalidate(lv_scr_act());
|
94
97
|
}
|
98
|
+
this->pause_callbacks_.call(paused);
|
99
|
+
}
|
100
|
+
|
101
|
+
void LvglComponent::esphome_lvgl_init() {
|
102
|
+
lv_init();
|
103
|
+
lv_update_event = static_cast<lv_event_code_t>(lv_event_register_id());
|
104
|
+
lv_api_event = static_cast<lv_event_code_t>(lv_event_register_id());
|
95
105
|
}
|
96
106
|
void LvglComponent::add_event_cb(lv_obj_t *obj, event_callback_t callback, lv_event_code_t event) {
|
97
|
-
lv_obj_add_event_cb(obj, callback, event,
|
107
|
+
lv_obj_add_event_cb(obj, callback, event, nullptr);
|
98
108
|
}
|
99
109
|
void LvglComponent::add_event_cb(lv_obj_t *obj, event_callback_t callback, lv_event_code_t event1,
|
100
110
|
lv_event_code_t event2) {
|
101
|
-
|
102
|
-
|
111
|
+
add_event_cb(obj, callback, event1);
|
112
|
+
add_event_cb(obj, callback, event2);
|
103
113
|
}
|
104
114
|
void LvglComponent::add_event_cb(lv_obj_t *obj, event_callback_t callback, lv_event_code_t event1,
|
105
115
|
lv_event_code_t event2, lv_event_code_t event3) {
|
106
|
-
|
107
|
-
|
108
|
-
|
116
|
+
add_event_cb(obj, callback, event1);
|
117
|
+
add_event_cb(obj, callback, event2);
|
118
|
+
add_event_cb(obj, callback, event3);
|
109
119
|
}
|
110
120
|
void LvglComponent::add_page(LvPageType *page) {
|
111
121
|
this->pages_.push_back(page);
|
@@ -133,19 +143,64 @@ void LvglComponent::show_prev_page(lv_scr_load_anim_t anim, uint32_t time) {
|
|
133
143
|
} while (this->pages_[this->current_page_]->skip); // skip empty pages()
|
134
144
|
this->show_page(this->current_page_, anim, time);
|
135
145
|
}
|
136
|
-
void LvglComponent::draw_buffer_(const lv_area_t *area,
|
146
|
+
void LvglComponent::draw_buffer_(const lv_area_t *area, lv_color_t *ptr) {
|
147
|
+
auto width = lv_area_get_width(area);
|
148
|
+
auto height = lv_area_get_height(area);
|
149
|
+
auto x1 = area->x1;
|
150
|
+
auto y1 = area->y1;
|
151
|
+
lv_color_t *dst = this->rotate_buf_;
|
152
|
+
switch (this->rotation) {
|
153
|
+
case display::DISPLAY_ROTATION_90_DEGREES:
|
154
|
+
for (lv_coord_t x = height; x-- != 0;) {
|
155
|
+
for (lv_coord_t y = 0; y != width; y++) {
|
156
|
+
dst[y * height + x] = *ptr++;
|
157
|
+
}
|
158
|
+
}
|
159
|
+
y1 = x1;
|
160
|
+
x1 = this->disp_drv_.ver_res - area->y1 - height;
|
161
|
+
width = height;
|
162
|
+
height = lv_area_get_width(area);
|
163
|
+
break;
|
164
|
+
|
165
|
+
case display::DISPLAY_ROTATION_180_DEGREES:
|
166
|
+
for (lv_coord_t y = height; y-- != 0;) {
|
167
|
+
for (lv_coord_t x = width; x-- != 0;) {
|
168
|
+
dst[y * width + x] = *ptr++;
|
169
|
+
}
|
170
|
+
}
|
171
|
+
x1 = this->disp_drv_.hor_res - x1 - width;
|
172
|
+
y1 = this->disp_drv_.ver_res - y1 - height;
|
173
|
+
break;
|
174
|
+
|
175
|
+
case display::DISPLAY_ROTATION_270_DEGREES:
|
176
|
+
for (lv_coord_t x = 0; x != height; x++) {
|
177
|
+
for (lv_coord_t y = width; y-- != 0;) {
|
178
|
+
dst[y * height + x] = *ptr++;
|
179
|
+
}
|
180
|
+
}
|
181
|
+
x1 = y1;
|
182
|
+
y1 = this->disp_drv_.hor_res - area->x1 - width;
|
183
|
+
width = height;
|
184
|
+
height = lv_area_get_width(area);
|
185
|
+
break;
|
186
|
+
|
187
|
+
default:
|
188
|
+
dst = ptr;
|
189
|
+
break;
|
190
|
+
}
|
137
191
|
for (auto *display : this->displays_) {
|
138
|
-
|
139
|
-
|
192
|
+
ESP_LOGV(TAG, "draw buffer x1=%d, y1=%d, width=%d, height=%d", x1, y1, width, height);
|
193
|
+
display->draw_pixels_at(x1, y1, width, height, (const uint8_t *) dst, display::COLOR_ORDER_RGB, LV_BITNESS,
|
194
|
+
LV_COLOR_16_SWAP);
|
140
195
|
}
|
141
196
|
}
|
142
197
|
|
143
198
|
void LvglComponent::flush_cb_(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p) {
|
144
199
|
if (!this->paused_) {
|
145
200
|
auto now = millis();
|
146
|
-
this->draw_buffer_(area,
|
147
|
-
|
148
|
-
|
201
|
+
this->draw_buffer_(area, color_p);
|
202
|
+
ESP_LOGVV(TAG, "flush_cb, area=%d/%d, %d/%d took %dms", area->x1, area->y1, lv_area_get_width(area),
|
203
|
+
lv_area_get_height(area), (int) (millis() - now));
|
149
204
|
}
|
150
205
|
lv_disp_flush_ready(disp_drv);
|
151
206
|
}
|
@@ -160,9 +215,18 @@ IdleTrigger::IdleTrigger(LvglComponent *parent, TemplatableValue<uint32_t> timeo
|
|
160
215
|
});
|
161
216
|
}
|
162
217
|
|
218
|
+
PauseTrigger::PauseTrigger(LvglComponent *parent, TemplatableValue<bool> paused) : paused_(std::move(paused)) {
|
219
|
+
parent->add_on_pause_callback([this](bool pausing) {
|
220
|
+
if (this->paused_.value() == pausing)
|
221
|
+
this->trigger();
|
222
|
+
});
|
223
|
+
}
|
224
|
+
|
163
225
|
#ifdef USE_LVGL_TOUCHSCREEN
|
164
|
-
LVTouchListener::LVTouchListener(uint16_t long_press_time, uint16_t long_press_repeat_time) {
|
226
|
+
LVTouchListener::LVTouchListener(uint16_t long_press_time, uint16_t long_press_repeat_time, LvglComponent *parent) {
|
227
|
+
this->set_parent(parent);
|
165
228
|
lv_indev_drv_init(&this->drv_);
|
229
|
+
this->drv_.disp = parent->get_disp();
|
166
230
|
this->drv_.long_press_repeat_time = long_press_repeat_time;
|
167
231
|
this->drv_.long_press_time = long_press_time;
|
168
232
|
this->drv_.type = LV_INDEV_TYPE_POINTER;
|
@@ -178,6 +242,7 @@ LVTouchListener::LVTouchListener(uint16_t long_press_time, uint16_t long_press_r
|
|
178
242
|
}
|
179
243
|
};
|
180
244
|
}
|
245
|
+
|
181
246
|
void LVTouchListener::update(const touchscreen::TouchPoints_t &tpoints) {
|
182
247
|
this->touch_pressed_ = !this->parent_->is_paused() && !tpoints.empty();
|
183
248
|
if (this->touch_pressed_)
|
@@ -203,6 +268,39 @@ LVEncoderListener::LVEncoderListener(lv_indev_type_t type, uint16_t lpt, uint16_
|
|
203
268
|
}
|
204
269
|
#endif // USE_LVGL_KEY_LISTENER
|
205
270
|
|
271
|
+
#if defined(USE_LVGL_DROPDOWN) || defined(LV_USE_ROLLER)
|
272
|
+
std::string LvSelectable::get_selected_text() {
|
273
|
+
auto selected = this->get_selected_index();
|
274
|
+
if (selected >= this->options_.size())
|
275
|
+
return "";
|
276
|
+
return this->options_[selected];
|
277
|
+
}
|
278
|
+
|
279
|
+
static std::string join_string(std::vector<std::string> options) {
|
280
|
+
return std::accumulate(
|
281
|
+
options.begin(), options.end(), std::string(),
|
282
|
+
[](const std::string &a, const std::string &b) -> std::string { return a + (a.length() > 0 ? "\n" : "") + b; });
|
283
|
+
}
|
284
|
+
|
285
|
+
void LvSelectable::set_selected_text(const std::string &text, lv_anim_enable_t anim) {
|
286
|
+
auto index = std::find(this->options_.begin(), this->options_.end(), text);
|
287
|
+
if (index != this->options_.end()) {
|
288
|
+
this->set_selected_index(index - this->options_.begin(), anim);
|
289
|
+
lv_event_send(this->obj, lv_api_event, nullptr);
|
290
|
+
}
|
291
|
+
}
|
292
|
+
|
293
|
+
void LvSelectable::set_options(std::vector<std::string> options) {
|
294
|
+
auto index = this->get_selected_index();
|
295
|
+
if (index >= options.size())
|
296
|
+
index = options.size() - 1;
|
297
|
+
this->options_ = std::move(options);
|
298
|
+
this->set_option_string(join_string(this->options_).c_str());
|
299
|
+
lv_event_send(this->obj, LV_EVENT_REFRESH, nullptr);
|
300
|
+
this->set_selected_index(index, LV_ANIM_OFF);
|
301
|
+
}
|
302
|
+
#endif // USE_LVGL_DROPDOWN || LV_USE_ROLLER
|
303
|
+
|
206
304
|
#ifdef USE_LVGL_BUTTONMATRIX
|
207
305
|
void LvButtonMatrixType::set_obj(lv_obj_t *lv_obj) {
|
208
306
|
LvCompound::set_obj(lv_obj);
|
@@ -261,45 +359,72 @@ void LvKeyboardType::set_obj(lv_obj_t *lv_obj) {
|
|
261
359
|
#endif // USE_LVGL_KEYBOARD
|
262
360
|
|
263
361
|
void LvglComponent::write_random_() {
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
area.
|
275
|
-
|
276
|
-
area.
|
362
|
+
int iterations = 6 - lv_disp_get_inactive_time(this->disp_) / 60000;
|
363
|
+
if (iterations <= 0)
|
364
|
+
iterations = 1;
|
365
|
+
while (iterations-- != 0) {
|
366
|
+
auto col = random_uint32() % this->disp_drv_.hor_res;
|
367
|
+
col = col / this->draw_rounding * this->draw_rounding;
|
368
|
+
auto row = random_uint32() % this->disp_drv_.ver_res;
|
369
|
+
row = row / this->draw_rounding * this->draw_rounding;
|
370
|
+
auto size = (random_uint32() % 32) / this->draw_rounding * this->draw_rounding - 1;
|
371
|
+
lv_area_t area;
|
372
|
+
area.x1 = col;
|
373
|
+
area.y1 = row;
|
374
|
+
area.x2 = col + size;
|
375
|
+
area.y2 = row + size;
|
376
|
+
if (area.x2 >= this->disp_drv_.hor_res)
|
377
|
+
area.x2 = this->disp_drv_.hor_res - 1;
|
378
|
+
if (area.y2 >= this->disp_drv_.ver_res)
|
379
|
+
area.y2 = this->disp_drv_.ver_res - 1;
|
380
|
+
|
381
|
+
size_t line_len = lv_area_get_width(&area) * lv_area_get_height(&area) / 2;
|
382
|
+
for (size_t i = 0; i != line_len; i++) {
|
383
|
+
((uint32_t *) (this->draw_buf_.buf1))[i] = random_uint32();
|
384
|
+
}
|
385
|
+
this->draw_buffer_(&area, (lv_color_t *) this->draw_buf_.buf1);
|
277
386
|
}
|
278
|
-
// write 2 lines
|
279
|
-
area.y2 = area.y1 + 1;
|
280
|
-
this->draw_buffer_(&area, (const uint8_t *) this->draw_buf_.buf1);
|
281
387
|
}
|
282
388
|
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
389
|
+
/**
|
390
|
+
* @class LvglComponent
|
391
|
+
* @brief Component for rendering LVGL.
|
392
|
+
*
|
393
|
+
* This component renders LVGL widgets on a display. Some initialisation must be done in the constructor
|
394
|
+
* since LVGL needs to be initialised before any widgets can be created.
|
395
|
+
*
|
396
|
+
* @param displays a list of displays to render onto. All displays must have the same
|
397
|
+
* resolution.
|
398
|
+
* @param buffer_frac the fraction of the display resolution to use for the LVGL
|
399
|
+
* draw buffer. A higher value will make animations smoother but
|
400
|
+
* also increase memory usage.
|
401
|
+
* @param full_refresh if true, the display will be fully refreshed on every frame.
|
402
|
+
* If false, only changed areas will be updated.
|
403
|
+
* @param draw_rounding the rounding to use when drawing. A value of 1 will draw
|
404
|
+
* without any rounding, a value of 2 will round to the nearest
|
405
|
+
* multiple of 2, and so on.
|
406
|
+
* @param resume_on_input if true, this component will resume rendering when the user
|
407
|
+
* presses a key or clicks on the screen.
|
408
|
+
*/
|
409
|
+
LvglComponent::LvglComponent(std::vector<display::Display *> displays, float buffer_frac, bool full_refresh,
|
410
|
+
int draw_rounding, bool resume_on_input)
|
411
|
+
: draw_rounding(draw_rounding),
|
412
|
+
displays_(std::move(displays)),
|
413
|
+
buffer_frac_(buffer_frac),
|
414
|
+
full_refresh_(full_refresh),
|
415
|
+
resume_on_input_(resume_on_input) {
|
291
416
|
auto *display = this->displays_[0];
|
292
417
|
size_t buffer_pixels = display->get_width() * display->get_height() / this->buffer_frac_;
|
293
418
|
auto buf_bytes = buffer_pixels * LV_COLOR_DEPTH / 8;
|
294
|
-
|
295
|
-
if (
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
this->mark_failed();
|
300
|
-
this->status_set_error("Memory allocation failure");
|
301
|
-
return;
|
419
|
+
this->rotation = display->get_rotation();
|
420
|
+
if (this->rotation != display::DISPLAY_ROTATION_0_DEGREES) {
|
421
|
+
this->rotate_buf_ = static_cast<lv_color_t *>(lv_custom_mem_alloc(buf_bytes)); // NOLINT
|
422
|
+
if (this->rotate_buf_ == nullptr)
|
423
|
+
return;
|
302
424
|
}
|
425
|
+
auto *buf = lv_custom_mem_alloc(buf_bytes); // NOLINT
|
426
|
+
if (buf == nullptr)
|
427
|
+
return;
|
303
428
|
lv_disp_draw_buf_init(&this->draw_buf_, buf, nullptr, buffer_pixels);
|
304
429
|
lv_disp_drv_init(&this->disp_drv_);
|
305
430
|
this->disp_drv_.draw_buf = &this->draw_buf_;
|
@@ -307,33 +432,36 @@ void LvglComponent::setup() {
|
|
307
432
|
this->disp_drv_.full_refresh = this->full_refresh_;
|
308
433
|
this->disp_drv_.flush_cb = static_flush_cb;
|
309
434
|
this->disp_drv_.rounder_cb = rounder_cb;
|
310
|
-
switch (display->get_rotation()) {
|
311
|
-
case display::DISPLAY_ROTATION_0_DEGREES:
|
312
|
-
break;
|
313
|
-
case display::DISPLAY_ROTATION_90_DEGREES:
|
314
|
-
this->disp_drv_.sw_rotate = true;
|
315
|
-
this->disp_drv_.rotated = LV_DISP_ROT_90;
|
316
|
-
break;
|
317
|
-
case display::DISPLAY_ROTATION_180_DEGREES:
|
318
|
-
this->disp_drv_.sw_rotate = true;
|
319
|
-
this->disp_drv_.rotated = LV_DISP_ROT_180;
|
320
|
-
break;
|
321
|
-
case display::DISPLAY_ROTATION_270_DEGREES:
|
322
|
-
this->disp_drv_.sw_rotate = true;
|
323
|
-
this->disp_drv_.rotated = LV_DISP_ROT_270;
|
324
|
-
break;
|
325
|
-
}
|
326
|
-
display->set_rotation(display::DISPLAY_ROTATION_0_DEGREES);
|
327
435
|
this->disp_drv_.hor_res = (lv_coord_t) display->get_width();
|
328
436
|
this->disp_drv_.ver_res = (lv_coord_t) display->get_height();
|
329
|
-
ESP_LOGV(TAG, "sw_rotate = %d, rotated=%d", this->disp_drv_.sw_rotate, this->disp_drv_.rotated);
|
330
437
|
this->disp_ = lv_disp_drv_register(&this->disp_drv_);
|
331
|
-
|
332
|
-
|
438
|
+
}
|
439
|
+
|
440
|
+
void LvglComponent::setup() {
|
441
|
+
if (this->draw_buf_.buf1 == nullptr) {
|
442
|
+
this->mark_failed();
|
443
|
+
this->status_set_error("Memory allocation failure");
|
444
|
+
return;
|
445
|
+
}
|
446
|
+
ESP_LOGCONFIG(TAG, "LVGL Setup starts");
|
447
|
+
#if LV_USE_LOG
|
448
|
+
lv_log_register_print_cb([](const char *buf) {
|
449
|
+
auto next = strchr(buf, ')');
|
450
|
+
if (next != nullptr)
|
451
|
+
buf = next + 1;
|
452
|
+
while (isspace(*buf))
|
453
|
+
buf++;
|
454
|
+
esp_log_printf_(LVGL_LOG_LEVEL, TAG, 0, "%.*s", (int) strlen(buf) - 1, buf);
|
455
|
+
});
|
456
|
+
#endif
|
457
|
+
// Rotation will be handled by our drawing function, so reset the display rotation.
|
458
|
+
for (auto *display : this->displays_)
|
459
|
+
display->set_rotation(display::DISPLAY_ROTATION_0_DEGREES);
|
333
460
|
this->show_page(0, LV_SCR_LOAD_ANIM_NONE, 0);
|
334
461
|
lv_disp_trig_activity(this->disp_);
|
335
462
|
ESP_LOGCONFIG(TAG, "LVGL Setup complete");
|
336
463
|
}
|
464
|
+
|
337
465
|
void LvglComponent::update() {
|
338
466
|
// update indicators
|
339
467
|
if (this->paused_) {
|
@@ -348,13 +476,6 @@ void LvglComponent::loop() {
|
|
348
476
|
}
|
349
477
|
lv_timer_handler_run_in_period(5);
|
350
478
|
}
|
351
|
-
bool lv_is_pre_initialise() {
|
352
|
-
if (!lv_is_initialized()) {
|
353
|
-
ESP_LOGE(TAG, "LVGL call before component is initialised");
|
354
|
-
return true;
|
355
|
-
}
|
356
|
-
return false;
|
357
|
-
}
|
358
479
|
|
359
480
|
#ifdef USE_LVGL_ANIMIMG
|
360
481
|
void lv_animimg_stop(lv_obj_t *obj) {
|
@@ -4,6 +4,9 @@
|
|
4
4
|
#ifdef USE_BINARY_SENSOR
|
5
5
|
#include "esphome/components/binary_sensor/binary_sensor.h"
|
6
6
|
#endif // USE_BINARY_SENSOR
|
7
|
+
#ifdef USE_LVGL_IMAGE
|
8
|
+
#include "esphome/components/image/image.h"
|
9
|
+
#endif // USE_LVGL_IMAGE
|
7
10
|
#ifdef USE_LVGL_ROTARY_ENCODER
|
8
11
|
#include "esphome/components/rotary_encoder/rotary_encoder.h"
|
9
12
|
#endif // USE_LVGL_ROTARY_ENCODER
|
@@ -18,11 +21,9 @@
|
|
18
21
|
#include "esphome/core/component.h"
|
19
22
|
#include "esphome/core/log.h"
|
20
23
|
#include <lvgl.h>
|
21
|
-
#include <vector>
|
22
24
|
#include <map>
|
23
|
-
#
|
24
|
-
#include
|
25
|
-
#endif // USE_LVGL_IMAGE
|
25
|
+
#include <utility>
|
26
|
+
#include <vector>
|
26
27
|
|
27
28
|
#ifdef USE_LVGL_FONT
|
28
29
|
#include "esphome/components/font/font.h"
|
@@ -41,7 +42,6 @@ namespace lvgl {
|
|
41
42
|
extern lv_event_code_t lv_api_event; // NOLINT
|
42
43
|
extern lv_event_code_t lv_update_event; // NOLINT
|
43
44
|
extern std::string lv_event_code_name_for(uint8_t event_code);
|
44
|
-
extern bool lv_is_pre_initialise();
|
45
45
|
#if LV_COLOR_DEPTH == 16
|
46
46
|
static const display::ColorBitness LV_BITNESS = display::ColorBitness::COLOR_BITNESS_565;
|
47
47
|
#elif LV_COLOR_DEPTH == 32
|
@@ -50,6 +50,14 @@ static const display::ColorBitness LV_BITNESS = display::ColorBitness::COLOR_BIT
|
|
50
50
|
static const display::ColorBitness LV_BITNESS = display::ColorBitness::COLOR_BITNESS_332;
|
51
51
|
#endif // LV_COLOR_DEPTH
|
52
52
|
|
53
|
+
#ifdef USE_LVGL_IMAGE
|
54
|
+
// Shortcut / overload, so that the source of an image can easily be updated
|
55
|
+
// from within a lambda.
|
56
|
+
inline void lv_img_set_src(lv_obj_t *obj, esphome::image::Image *image) {
|
57
|
+
lv_img_set_src(obj, image->get_lv_img_dsc());
|
58
|
+
}
|
59
|
+
#endif // USE_LVGL_IMAGE
|
60
|
+
|
53
61
|
// Parent class for things that wrap an LVGL object
|
54
62
|
class LvCompound {
|
55
63
|
public:
|
@@ -110,6 +118,8 @@ class LvglComponent : public PollingComponent {
|
|
110
118
|
constexpr static const char *const TAG = "lvgl";
|
111
119
|
|
112
120
|
public:
|
121
|
+
LvglComponent(std::vector<display::Display *> displays, float buffer_frac, bool full_refresh, int draw_rounding,
|
122
|
+
bool resume_on_input);
|
113
123
|
static void static_flush_cb(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p);
|
114
124
|
|
115
125
|
float get_setup_priority() const override { return setup_priority::PROCESSOR; }
|
@@ -119,19 +129,31 @@ class LvglComponent : public PollingComponent {
|
|
119
129
|
void add_on_idle_callback(std::function<void(uint32_t)> &&callback) {
|
120
130
|
this->idle_callbacks_.add(std::move(callback));
|
121
131
|
}
|
122
|
-
void
|
123
|
-
void add_init_lambda(const std::function<void(LvglComponent *)> &lamb) { this->init_lambdas_.push_back(lamb); }
|
132
|
+
void add_on_pause_callback(std::function<void(bool)> &&callback) { this->pause_callbacks_.add(std::move(callback)); }
|
124
133
|
void dump_config() override;
|
125
|
-
void set_full_refresh(bool full_refresh) { this->full_refresh_ = full_refresh; }
|
126
134
|
bool is_idle(uint32_t idle_ms) { return lv_disp_get_inactive_time(this->disp_) > idle_ms; }
|
127
|
-
void set_buffer_frac(size_t frac) { this->buffer_frac_ = frac; }
|
128
135
|
lv_disp_t *get_disp() { return this->disp_; }
|
136
|
+
lv_obj_t *get_scr_act() { return lv_disp_get_scr_act(this->disp_); }
|
137
|
+
// Pause or resume the display.
|
138
|
+
// @param paused If true, pause the display. If false, resume the display.
|
139
|
+
// @param show_snow If true, show the snow effect when paused.
|
129
140
|
void set_paused(bool paused, bool show_snow);
|
130
|
-
void add_event_cb(lv_obj_t *obj, event_callback_t callback, lv_event_code_t event);
|
131
|
-
void add_event_cb(lv_obj_t *obj, event_callback_t callback, lv_event_code_t event1, lv_event_code_t event2);
|
132
|
-
void add_event_cb(lv_obj_t *obj, event_callback_t callback, lv_event_code_t event1, lv_event_code_t event2,
|
133
|
-
lv_event_code_t event3);
|
134
141
|
bool is_paused() const { return this->paused_; }
|
142
|
+
// If the display is paused and we have resume_on_input_ set to true, resume the display.
|
143
|
+
void maybe_wakeup() {
|
144
|
+
if (this->paused_ && this->resume_on_input_) {
|
145
|
+
this->set_paused(false, false);
|
146
|
+
}
|
147
|
+
}
|
148
|
+
|
149
|
+
/**
|
150
|
+
* Initialize the LVGL library and register custom events.
|
151
|
+
*/
|
152
|
+
static void esphome_lvgl_init();
|
153
|
+
static void add_event_cb(lv_obj_t *obj, event_callback_t callback, lv_event_code_t event);
|
154
|
+
static void add_event_cb(lv_obj_t *obj, event_callback_t callback, lv_event_code_t event1, lv_event_code_t event2);
|
155
|
+
static void add_event_cb(lv_obj_t *obj, event_callback_t callback, lv_event_code_t event1, lv_event_code_t event2,
|
156
|
+
lv_event_code_t event3);
|
135
157
|
void add_page(LvPageType *page);
|
136
158
|
void show_page(size_t index, lv_scr_load_anim_t anim, uint32_t time);
|
137
159
|
void show_next_page(lv_scr_load_anim_t anim, uint32_t time);
|
@@ -144,12 +166,21 @@ class LvglComponent : public PollingComponent {
|
|
144
166
|
lv_group_focus_obj(mark);
|
145
167
|
}
|
146
168
|
}
|
169
|
+
// rounding factor to align bounds of update area when drawing
|
170
|
+
size_t draw_rounding{2};
|
171
|
+
|
172
|
+
display::DisplayRotation rotation{display::DISPLAY_ROTATION_0_DEGREES};
|
147
173
|
|
148
174
|
protected:
|
149
175
|
void write_random_();
|
150
|
-
void draw_buffer_(const lv_area_t *area,
|
176
|
+
void draw_buffer_(const lv_area_t *area, lv_color_t *ptr);
|
151
177
|
void flush_cb_(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p);
|
178
|
+
|
152
179
|
std::vector<display::Display *> displays_{};
|
180
|
+
size_t buffer_frac_{1};
|
181
|
+
bool full_refresh_{};
|
182
|
+
bool resume_on_input_{};
|
183
|
+
|
153
184
|
lv_disp_draw_buf_t draw_buf_{};
|
154
185
|
lv_disp_drv_t disp_drv_{};
|
155
186
|
lv_disp_t *disp_{};
|
@@ -157,14 +188,12 @@ class LvglComponent : public PollingComponent {
|
|
157
188
|
std::vector<LvPageType *> pages_{};
|
158
189
|
size_t current_page_{0};
|
159
190
|
bool show_snow_{};
|
160
|
-
lv_coord_t snow_line_{};
|
161
191
|
bool page_wrap_{true};
|
162
192
|
std::map<lv_group_t *, lv_obj_t *> focus_marks_{};
|
163
193
|
|
164
|
-
std::vector<std::function<void(LvglComponent *lv_component)>> init_lambdas_;
|
165
194
|
CallbackManager<void(uint32_t)> idle_callbacks_{};
|
166
|
-
|
167
|
-
|
195
|
+
CallbackManager<void(bool)> pause_callbacks_{};
|
196
|
+
lv_color_t *rotate_buf_{};
|
168
197
|
};
|
169
198
|
|
170
199
|
class IdleTrigger : public Trigger<> {
|
@@ -176,6 +205,14 @@ class IdleTrigger : public Trigger<> {
|
|
176
205
|
bool is_idle_{};
|
177
206
|
};
|
178
207
|
|
208
|
+
class PauseTrigger : public Trigger<> {
|
209
|
+
public:
|
210
|
+
explicit PauseTrigger(LvglComponent *parent, TemplatableValue<bool> paused);
|
211
|
+
|
212
|
+
protected:
|
213
|
+
TemplatableValue<bool> paused_;
|
214
|
+
};
|
215
|
+
|
179
216
|
template<typename... Ts> class LvglAction : public Action<Ts...>, public Parented<LvglComponent> {
|
180
217
|
public:
|
181
218
|
explicit LvglAction(std::function<void(LvglComponent *)> &&lamb) : action_(std::move(lamb)) {}
|
@@ -198,9 +235,12 @@ template<typename... Ts> class LvglCondition : public Condition<Ts...>, public P
|
|
198
235
|
#ifdef USE_LVGL_TOUCHSCREEN
|
199
236
|
class LVTouchListener : public touchscreen::TouchListener, public Parented<LvglComponent> {
|
200
237
|
public:
|
201
|
-
LVTouchListener(uint16_t long_press_time, uint16_t long_press_repeat_time);
|
238
|
+
LVTouchListener(uint16_t long_press_time, uint16_t long_press_repeat_time, LvglComponent *parent);
|
202
239
|
void update(const touchscreen::TouchPoints_t &tpoints) override;
|
203
|
-
void release() override {
|
240
|
+
void release() override {
|
241
|
+
touch_pressed_ = false;
|
242
|
+
this->parent_->maybe_wakeup();
|
243
|
+
}
|
204
244
|
lv_indev_drv_t *get_drv() { return &this->drv_; }
|
205
245
|
|
206
246
|
protected:
|
@@ -215,16 +255,11 @@ class LVEncoderListener : public Parented<LvglComponent> {
|
|
215
255
|
public:
|
216
256
|
LVEncoderListener(lv_indev_type_t type, uint16_t lpt, uint16_t lprt);
|
217
257
|
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
void set_right_button(binary_sensor::BinarySensor *right_button) {
|
222
|
-
right_button->add_on_state_callback([this](bool state) { this->event(LV_KEY_RIGHT, state); });
|
223
|
-
}
|
224
|
-
|
225
|
-
void set_enter_button(binary_sensor::BinarySensor *enter_button) {
|
226
|
-
enter_button->add_on_state_callback([this](bool state) { this->event(LV_KEY_ENTER, state); });
|
258
|
+
#ifdef USE_BINARY_SENSOR
|
259
|
+
void add_button(binary_sensor::BinarySensor *button, lv_key_t key) {
|
260
|
+
button->add_on_state_callback([this, key](bool state) { this->event(key, state); });
|
227
261
|
}
|
262
|
+
#endif
|
228
263
|
|
229
264
|
#ifdef USE_LVGL_ROTARY_ENCODER
|
230
265
|
void set_sensor(rotary_encoder::RotaryEncoderSensor *sensor) {
|
@@ -236,12 +271,18 @@ class LVEncoderListener : public Parented<LvglComponent> {
|
|
236
271
|
if (!this->parent_->is_paused()) {
|
237
272
|
this->pressed_ = pressed;
|
238
273
|
this->key_ = key;
|
274
|
+
} else if (!pressed) {
|
275
|
+
// maybe wakeup on release if paused
|
276
|
+
this->parent_->maybe_wakeup();
|
239
277
|
}
|
240
278
|
}
|
241
279
|
|
242
280
|
void set_count(int32_t count) {
|
243
|
-
if (!this->parent_->is_paused())
|
281
|
+
if (!this->parent_->is_paused()) {
|
244
282
|
this->count_ = count;
|
283
|
+
} else {
|
284
|
+
this->parent_->maybe_wakeup();
|
285
|
+
}
|
245
286
|
}
|
246
287
|
|
247
288
|
lv_indev_drv_t *get_drv() { return &this->drv_; }
|
@@ -255,6 +296,48 @@ class LVEncoderListener : public Parented<LvglComponent> {
|
|
255
296
|
};
|
256
297
|
#endif // USE_LVGL_KEY_LISTENER
|
257
298
|
|
299
|
+
#if defined(USE_LVGL_DROPDOWN) || defined(LV_USE_ROLLER)
|
300
|
+
class LvSelectable : public LvCompound {
|
301
|
+
public:
|
302
|
+
virtual size_t get_selected_index() = 0;
|
303
|
+
virtual void set_selected_index(size_t index, lv_anim_enable_t anim) = 0;
|
304
|
+
void set_selected_text(const std::string &text, lv_anim_enable_t anim);
|
305
|
+
std::string get_selected_text();
|
306
|
+
std::vector<std::string> get_options() { return this->options_; }
|
307
|
+
void set_options(std::vector<std::string> options);
|
308
|
+
|
309
|
+
protected:
|
310
|
+
virtual void set_option_string(const char *options) = 0;
|
311
|
+
std::vector<std::string> options_{};
|
312
|
+
};
|
313
|
+
|
314
|
+
#ifdef USE_LVGL_DROPDOWN
|
315
|
+
class LvDropdownType : public LvSelectable {
|
316
|
+
public:
|
317
|
+
size_t get_selected_index() override { return lv_dropdown_get_selected(this->obj); }
|
318
|
+
void set_selected_index(size_t index, lv_anim_enable_t anim) override { lv_dropdown_set_selected(this->obj, index); }
|
319
|
+
|
320
|
+
protected:
|
321
|
+
void set_option_string(const char *options) override { lv_dropdown_set_options(this->obj, options); }
|
322
|
+
};
|
323
|
+
#endif // USE_LVGL_DROPDOWN
|
324
|
+
|
325
|
+
#ifdef USE_LVGL_ROLLER
|
326
|
+
class LvRollerType : public LvSelectable {
|
327
|
+
public:
|
328
|
+
size_t get_selected_index() override { return lv_roller_get_selected(this->obj); }
|
329
|
+
void set_selected_index(size_t index, lv_anim_enable_t anim) override {
|
330
|
+
lv_roller_set_selected(this->obj, index, anim);
|
331
|
+
}
|
332
|
+
void set_mode(lv_roller_mode_t mode) { this->mode_ = mode; }
|
333
|
+
|
334
|
+
protected:
|
335
|
+
void set_option_string(const char *options) override { lv_roller_set_options(this->obj, options, this->mode_); }
|
336
|
+
lv_roller_mode_t mode_{LV_ROLLER_MODE_NORMAL};
|
337
|
+
};
|
338
|
+
#endif
|
339
|
+
#endif // defined(USE_LVGL_DROPDOWN) || defined(LV_USE_ROLLER)
|
340
|
+
|
258
341
|
#ifdef USE_LVGL_BUTTONMATRIX
|
259
342
|
class LvButtonMatrixType : public key_provider::KeyProvider, public LvCompound {
|
260
343
|
public:
|
@@ -0,0 +1,17 @@
|
|
1
|
+
#pragma once
|
2
|
+
/**
|
3
|
+
* This header is for use in components that might or might not use LVGL. There is a platformio bug where
|
4
|
+
the mere mention of a header file, even if ifdefed, causes the build to fail. This is a workaround, since if this
|
5
|
+
file is included in the build, LVGL is always included.
|
6
|
+
*/
|
7
|
+
#ifdef USE_LVGL
|
8
|
+
// required for clang-tidy
|
9
|
+
#ifndef LV_CONF_H
|
10
|
+
#define LV_CONF_SKIP 1 // NOLINT
|
11
|
+
#endif // LV_CONF_H
|
12
|
+
|
13
|
+
#include <lvgl.h>
|
14
|
+
namespace esphome {
|
15
|
+
namespace lvgl {} // namespace lvgl
|
16
|
+
} // namespace esphome
|
17
|
+
#endif // USE_LVGL
|