- Updated RootLayout to manage layout initialization and deinitialization more effectively. - Removed unnecessary dependencies and streamlined event handling for keyboard events. - Enhanced UIHandler to utilize shared pointers for app descriptors, improving memory management. - Added methods for showing and hiding navigation elements in RootLayout. - Introduced textarea widget with instant response by disabling animations. - Improved error handling and logging throughout the UI components.
160 lines
4.0 KiB
C++
160 lines
4.0 KiB
C++
#include "ui/interaction_handler.h"
|
|
#include "ui/events.h"
|
|
#include "esp_err.h"
|
|
#include "esp_log.h"
|
|
|
|
#define TAG "InteractionHandler"
|
|
|
|
InteractionHandler::~InteractionHandler() {
|
|
esp_err_t err = deinit();
|
|
if (err != ESP_OK) {
|
|
ESP_LOGE(TAG, "Error during InteractionHandler deinit: %s", esp_err_to_name(err));
|
|
}
|
|
}
|
|
|
|
esp_err_t InteractionHandler::init(lv_obj_t* app_container) {
|
|
if (!app_container) {
|
|
ESP_LOGE(TAG, "Invalid argument: app_container is nullptr");
|
|
return ESP_ERR_INVALID_ARG;
|
|
}
|
|
app_container_ = app_container;
|
|
keyboard_ = lv_keyboard_create(app_container_);
|
|
lv_obj_add_flag(keyboard_, LV_OBJ_FLAG_HIDDEN); // start hidden
|
|
lv_obj_add_event_cb(
|
|
keyboard_,
|
|
[](lv_event_t* e) {
|
|
InteractionHandler* handler = static_cast<InteractionHandler*>(lv_event_get_user_data(e));
|
|
handler->on_keyboard_event_(e);
|
|
}
|
|
, LV_EVENT_ALL, this);
|
|
|
|
return ESP_OK;
|
|
}
|
|
|
|
esp_err_t InteractionHandler::deinit(void) {
|
|
if (keyboard_) {
|
|
lv_obj_del(keyboard_);
|
|
keyboard_ = nullptr;
|
|
}
|
|
return ESP_OK;
|
|
}
|
|
|
|
esp_err_t InteractionHandler::register_text_area_keyboard_support(lv_obj_t* text_area) {
|
|
if (!text_area) {
|
|
ESP_LOGE(TAG, "Invalid argument: text_area is nullptr");
|
|
return ESP_ERR_INVALID_ARG;
|
|
}
|
|
|
|
lv_obj_add_event_cb(
|
|
text_area,
|
|
[](lv_event_t* e) {
|
|
lv_event_code_t code = lv_event_get_code(e);
|
|
if (code != LV_EVENT_FOCUSED) {
|
|
return;
|
|
}
|
|
InteractionHandler* handler = static_cast<InteractionHandler*>(lv_event_get_user_data(e));
|
|
|
|
esp_err_t err = handler->show_keyboard_for_textarea_(static_cast<lv_obj_t*>(lv_event_get_target(e)));
|
|
if (err != ESP_OK) {
|
|
ESP_LOGE(TAG, "Failed to show keyboard: %s", esp_err_to_name(err));
|
|
}
|
|
}
|
|
, LV_EVENT_FOCUSED, this);
|
|
|
|
lv_obj_add_event_cb(
|
|
text_area,
|
|
[](lv_event_t* e) {
|
|
lv_event_code_t code = lv_event_get_code(e);
|
|
if (code != LV_EVENT_DEFOCUSED) {
|
|
return;
|
|
}
|
|
InteractionHandler* handler = static_cast<InteractionHandler*>(lv_event_get_user_data(e));
|
|
|
|
esp_err_t err = handler->hide_keyboard_();
|
|
if (err != ESP_OK) {
|
|
ESP_LOGE(TAG, "Failed to hide keyboard: %s", esp_err_to_name(err));
|
|
}
|
|
}
|
|
, LV_EVENT_DEFOCUSED, this);
|
|
|
|
return ESP_OK;
|
|
}
|
|
|
|
//
|
|
// Private methods
|
|
//
|
|
|
|
void InteractionHandler::on_keyboard_event_(lv_event_t* e) {
|
|
lv_event_code_t code = lv_event_get_code(e);
|
|
if (code == LV_EVENT_READY || code == LV_EVENT_CANCEL) {
|
|
// Keyboard is cancelled
|
|
esp_err_t err = hide_keyboard_();
|
|
if (err != ESP_OK) {
|
|
ESP_LOGE(TAG, "Failed to hide keyboard: %s", esp_err_to_name(err));
|
|
}
|
|
|
|
if (focused_textarea_) {
|
|
lv_obj_clear_state(focused_textarea_, LV_STATE_FOCUSED);
|
|
lv_keyboard_set_textarea(keyboard_, nullptr);
|
|
focused_textarea_ = nullptr;
|
|
}
|
|
}
|
|
}
|
|
|
|
esp_err_t InteractionHandler::show_keyboard_for_textarea_(lv_obj_t* textarea) {
|
|
if (!keyboard_ || !textarea) {
|
|
ESP_LOGE(TAG, "Invalid state or argument in show_keyboard_for_textarea_");
|
|
return ESP_ERR_INVALID_ARG;
|
|
}
|
|
|
|
focused_textarea_ = textarea;
|
|
lv_keyboard_set_textarea(keyboard_, textarea);
|
|
lv_obj_clear_flag(keyboard_, LV_OBJ_FLAG_HIDDEN);
|
|
// emit keyboard shown event
|
|
KeyboardEventData event_data = {
|
|
.textarea = textarea
|
|
};
|
|
esp_err_t err = esp_event_post_to(
|
|
NULL,
|
|
UI_EVENT_BASE,
|
|
UI_EVENT_KEYBOARD_SHOWN,
|
|
&event_data,
|
|
sizeof(event_data),
|
|
portMAX_DELAY
|
|
);
|
|
|
|
if (err != ESP_OK) {
|
|
ESP_LOGE(TAG, "Failed to post keyboard shown event: %s", esp_err_to_name(err));
|
|
}
|
|
|
|
return ESP_OK;
|
|
}
|
|
|
|
esp_err_t InteractionHandler::hide_keyboard_(void) {
|
|
if (!keyboard_) {
|
|
return ESP_ERR_INVALID_STATE;
|
|
}
|
|
|
|
lv_obj_add_flag(keyboard_, LV_OBJ_FLAG_HIDDEN);
|
|
|
|
// emit keyboard hidden event
|
|
KeyboardEventData event_data = {
|
|
.textarea = nullptr
|
|
};
|
|
|
|
esp_err_t err = esp_event_post_to(
|
|
NULL,
|
|
UI_EVENT_BASE,
|
|
UI_EVENT_KEYBOARD_HIDDEN,
|
|
&event_data,
|
|
sizeof(event_data),
|
|
portMAX_DELAY
|
|
);
|
|
|
|
if (err != ESP_OK) {
|
|
ESP_LOGE(TAG, "Failed to post keyboard hidden event: %s", esp_err_to_name(err));
|
|
}
|
|
|
|
return ESP_OK;
|
|
}
|