Refactor RootLayout and UIHandler for improved structure and functionality
- 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.
This commit is contained in:
159
main/ui/interaction_handler.cpp
Normal file
159
main/ui/interaction_handler.cpp
Normal file
@@ -0,0 +1,159 @@
|
||||
#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;
|
||||
}
|
||||
Reference in New Issue
Block a user