mirror of
https://github.com/ByteWelder/Tactility.git
synced 2026-02-18 10:53:17 +00:00
Simplify keyboard support (#22)
* simplify keyboard support * removed cleanup code as it wasn't necessary * improved docs
This commit is contained in:
parent
7a7b31e426
commit
618f557a16
@ -4,7 +4,6 @@
|
||||
#include "lvgl.h"
|
||||
#include "services/gui/gui.h"
|
||||
#include "services/wifi/wifi_credentials.h"
|
||||
#include "ui/lvgl_keypad.h"
|
||||
#include "ui/spacer.h"
|
||||
#include "ui/style.h"
|
||||
#include "wifi_connect.h"
|
||||
@ -13,15 +12,6 @@
|
||||
|
||||
#define TAG "wifi_connect"
|
||||
|
||||
static void show_keyboard(lv_event_t* event) {
|
||||
gui_keyboard_show(event->current_target);
|
||||
lv_obj_scroll_to_view(event->current_target, LV_ANIM_ON);
|
||||
}
|
||||
|
||||
static void hide_keyboard(TT_UNUSED lv_event_t* event) {
|
||||
gui_keyboard_hide();
|
||||
}
|
||||
|
||||
static void on_connect(lv_event_t* event) {
|
||||
WifiConnect* wifi = (WifiConnect*)event->user_data;
|
||||
WifiConnectView* view = &wifi->view;
|
||||
@ -104,14 +94,8 @@ void wifi_connect_view_create(App app, void* wifi, lv_obj_t* parent) {
|
||||
|
||||
wifi_connect_view_create_bottom_buttons(wifi, parent);
|
||||
|
||||
if (gui_keyboard_is_enabled()) {
|
||||
lv_obj_add_event_cb(view->ssid_textarea, show_keyboard, LV_EVENT_FOCUSED, NULL);
|
||||
lv_obj_add_event_cb(view->ssid_textarea, hide_keyboard, LV_EVENT_DEFOCUSED, NULL);
|
||||
lv_obj_add_event_cb(view->ssid_textarea, hide_keyboard, LV_EVENT_READY, NULL);
|
||||
lv_obj_add_event_cb(view->password_textarea, show_keyboard, LV_EVENT_FOCUSED, NULL);
|
||||
lv_obj_add_event_cb(view->password_textarea, hide_keyboard, LV_EVENT_DEFOCUSED, NULL);
|
||||
lv_obj_add_event_cb(view->password_textarea, hide_keyboard, LV_EVENT_READY, NULL);
|
||||
}
|
||||
gui_keyboard_add_textarea(view->ssid_textarea);
|
||||
gui_keyboard_add_textarea(view->password_textarea);
|
||||
|
||||
// Init from app parameters
|
||||
Bundle* _Nullable bundle = tt_app_get_parameters(app);
|
||||
@ -126,18 +110,10 @@ void wifi_connect_view_create(App app, void* wifi, lv_obj_t* parent) {
|
||||
lv_textarea_set_text(view->password_textarea, password);
|
||||
}
|
||||
}
|
||||
|
||||
// Hardware keyboard("keypad") requires a group
|
||||
view->group = lv_group_create();
|
||||
lv_group_add_obj(view->group, view->ssid_textarea);
|
||||
lv_group_add_obj(view->group, view->password_textarea);
|
||||
tt_lvgl_keypad_activate(view->group);
|
||||
}
|
||||
|
||||
void wifi_connect_view_destroy(TT_UNUSED WifiConnectView* view) {
|
||||
// Cleanup keypad group
|
||||
tt_lvgl_keypad_deactivate();
|
||||
lv_group_del(view->group);
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
void wifi_connect_view_update(
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
#include "check.h"
|
||||
#include "hardware_i.h"
|
||||
|
||||
#include "check.h"
|
||||
#include "lvgl.h"
|
||||
|
||||
#define TAG "hardware"
|
||||
|
||||
void tt_hardware_init(const HardwareConfig* config) {
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
void gui_redraw(Gui*);
|
||||
static int32_t gui_main(void*);
|
||||
|
||||
static Gui* gui = NULL;
|
||||
Gui* gui = NULL;
|
||||
|
||||
Gui* gui_alloc() {
|
||||
Gui* instance = malloc(sizeof(Gui));
|
||||
@ -32,6 +32,7 @@ Gui* gui_alloc() {
|
||||
instance->keyboard = NULL;
|
||||
|
||||
tt_check(tt_lvgl_lock(1000 / portTICK_PERIOD_MS));
|
||||
instance->keyboard_group = lv_group_create();
|
||||
instance->lvgl_parent = lv_scr_act();
|
||||
tt_lvgl_unlock();
|
||||
|
||||
@ -42,6 +43,11 @@ void gui_free(Gui* instance) {
|
||||
tt_assert(instance != NULL);
|
||||
tt_thread_free(instance->thread);
|
||||
tt_mutex_free(instance->mutex);
|
||||
|
||||
tt_check(tt_lvgl_lock(1000 / portTICK_PERIOD_MS));
|
||||
lv_group_del(instance->keyboard_group);
|
||||
tt_lvgl_unlock();
|
||||
|
||||
free(instance);
|
||||
}
|
||||
|
||||
@ -71,39 +77,6 @@ void gui_show_app(App app, ViewPortShowCallback on_show, ViewPortHideCallback on
|
||||
gui_request_draw();
|
||||
}
|
||||
|
||||
void gui_keyboard_show(lv_obj_t* textarea) {
|
||||
if (gui->keyboard) {
|
||||
gui_lock();
|
||||
|
||||
lv_obj_clear_flag(gui->keyboard, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_keyboard_set_textarea(gui->keyboard, textarea);
|
||||
|
||||
if (gui->toolbar) {
|
||||
lv_obj_add_flag(gui->toolbar, LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
|
||||
gui_unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void gui_keyboard_hide() {
|
||||
if (gui->keyboard) {
|
||||
gui_lock();
|
||||
|
||||
lv_obj_add_flag(gui->keyboard, LV_OBJ_FLAG_HIDDEN);
|
||||
|
||||
if (gui->toolbar) {
|
||||
lv_obj_clear_flag(gui->toolbar, LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
|
||||
gui_unlock();
|
||||
}
|
||||
}
|
||||
|
||||
bool gui_keyboard_is_enabled() {
|
||||
return !tt_lvgl_keypad_is_available() || TT_CONFIG_FORCE_ONSCREEN_KEYBOARD;
|
||||
}
|
||||
|
||||
void gui_hide_app() {
|
||||
gui_lock();
|
||||
ViewPort* view_port = gui->app_view_port;
|
||||
|
||||
@ -40,14 +40,21 @@ void gui_keyboard_show(lv_obj_t* textarea);
|
||||
void gui_keyboard_hide();
|
||||
|
||||
/**
|
||||
* This function is to facilitate hardware keyboards like the one on Lilygo T-Deck.
|
||||
* The software keyboard is only shown when both of these conditions are true:
|
||||
* The on-screen keyboard is only shown when both of these conditions are true:
|
||||
* - there is no hardware keyboard
|
||||
* - TT_CONFIG_FORCE_ONSCREEN_KEYBOARD is set to true in tactility_config.h
|
||||
* @return if we should show a keyboard for text input inside our apps
|
||||
* @return if we should show a on-screen keyboard for text input inside our apps
|
||||
*/
|
||||
bool gui_keyboard_is_enabled();
|
||||
|
||||
/**
|
||||
* Glue code for the on-screen keyboard and the hardware keyboard:
|
||||
* - Attach automatic hide/show parameters for the on-screen keyboard.
|
||||
* - Registers the textarea to the default lv_group_t for hardware keyboards.
|
||||
* @param textarea
|
||||
*/
|
||||
void gui_keyboard_add_textarea(lv_obj_t* textarea);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -49,8 +49,12 @@ static lv_obj_t* create_app_views(Gui* gui, lv_obj_t* parent, App app) {
|
||||
lv_obj_set_width(child_container, LV_PCT(100));
|
||||
lv_obj_set_flex_grow(child_container, 1);
|
||||
|
||||
gui->keyboard = lv_keyboard_create(vertical_container);
|
||||
lv_obj_add_flag(gui->keyboard, LV_OBJ_FLAG_HIDDEN);
|
||||
if (gui_keyboard_is_enabled()) {
|
||||
gui->keyboard = lv_keyboard_create(vertical_container);
|
||||
lv_obj_add_flag(gui->keyboard, LV_OBJ_FLAG_HIDDEN);
|
||||
} else {
|
||||
gui->keyboard = NULL;
|
||||
}
|
||||
|
||||
return child_container;
|
||||
}
|
||||
|
||||
@ -27,16 +27,14 @@ struct Gui {
|
||||
|
||||
lv_obj_t* _Nullable toolbar;
|
||||
lv_obj_t* _Nullable keyboard;
|
||||
lv_group_t* keyboard_group;
|
||||
};
|
||||
|
||||
/** Update GUI, request redraw
|
||||
*/
|
||||
/** Update GUI, request redraw */
|
||||
void gui_request_draw();
|
||||
|
||||
/** Lock GUI
|
||||
*/
|
||||
/** Lock GUI */
|
||||
void gui_lock();
|
||||
|
||||
/** Unlock GUI
|
||||
*/
|
||||
/** Unlock GUI */
|
||||
void gui_unlock();
|
||||
|
||||
70
tactility/src/services/gui/gui_keyboard.c
Normal file
70
tactility/src/services/gui/gui_keyboard.c
Normal file
@ -0,0 +1,70 @@
|
||||
#include "gui_i.h"
|
||||
|
||||
#include "tactility_config.h"
|
||||
#include "ui/lvgl_keypad.h"
|
||||
#include "ui/lvgl_sync.h"
|
||||
|
||||
extern Gui* gui;
|
||||
|
||||
static void show_keyboard(lv_event_t* event) {
|
||||
gui_keyboard_show(event->current_target);
|
||||
lv_obj_scroll_to_view(event->current_target, LV_ANIM_ON);
|
||||
}
|
||||
|
||||
static void hide_keyboard(TT_UNUSED lv_event_t* event) {
|
||||
gui_keyboard_hide();
|
||||
}
|
||||
|
||||
bool gui_keyboard_is_enabled() {
|
||||
return !tt_lvgl_keypad_is_available() || TT_CONFIG_FORCE_ONSCREEN_KEYBOARD;
|
||||
}
|
||||
|
||||
void gui_keyboard_show(lv_obj_t* textarea) {
|
||||
gui_lock();
|
||||
|
||||
if (gui->keyboard) {
|
||||
gui_lock();
|
||||
|
||||
lv_obj_clear_flag(gui->keyboard, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_keyboard_set_textarea(gui->keyboard, textarea);
|
||||
|
||||
if (gui->toolbar) {
|
||||
lv_obj_add_flag(gui->toolbar, LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
gui_unlock();
|
||||
}
|
||||
|
||||
void gui_keyboard_hide() {
|
||||
gui_lock();
|
||||
|
||||
if (gui->keyboard) {
|
||||
lv_obj_add_flag(gui->keyboard, LV_OBJ_FLAG_HIDDEN);
|
||||
if (gui->toolbar) {
|
||||
lv_obj_clear_flag(gui->toolbar, LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
}
|
||||
|
||||
gui_unlock();
|
||||
}
|
||||
|
||||
void gui_keyboard_add_textarea(lv_obj_t* textarea) {
|
||||
gui_lock();
|
||||
tt_check(tt_lvgl_lock(0), "lvgl should already be locked before calling this method");
|
||||
|
||||
if (gui_keyboard_is_enabled()) {
|
||||
lv_obj_add_event_cb(textarea, show_keyboard, LV_EVENT_FOCUSED, NULL);
|
||||
lv_obj_add_event_cb(textarea, hide_keyboard, LV_EVENT_DEFOCUSED, NULL);
|
||||
lv_obj_add_event_cb(textarea, hide_keyboard, LV_EVENT_READY, NULL);
|
||||
}
|
||||
|
||||
// lv_obj_t auto-remove themselves from the group when they are destroyed (last checked in LVGL 8.3)
|
||||
lv_group_add_obj(gui->keyboard_group, textarea);
|
||||
|
||||
tt_lvgl_keypad_activate(gui->keyboard_group);
|
||||
|
||||
tt_lvgl_unlock();
|
||||
gui_unlock();
|
||||
}
|
||||
@ -84,7 +84,7 @@ TT_UNUSED void tt_init(const Config* config) {
|
||||
tt_hardware_init(config->hardware);
|
||||
|
||||
// Note: the order of starting apps and services is critical!
|
||||
// System services are registered first so they can be used by the apps
|
||||
// System services are registered first so the apps below can use them
|
||||
register_and_start_system_services();
|
||||
// Then we register system apps. They are not used/started yet.
|
||||
register_system_apps();
|
||||
|
||||
@ -1,3 +1,6 @@
|
||||
/**
|
||||
* This code relates to the hardware keyboard support also known as "keypads" in LVGL.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "lvgl.h"
|
||||
@ -6,9 +9,28 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @return true if LVGL is configured with a keypad
|
||||
*/
|
||||
bool tt_lvgl_keypad_is_available();
|
||||
|
||||
/**
|
||||
* Set the keypad.
|
||||
* @param device the keypad device
|
||||
*/
|
||||
void tt_lvgl_keypad_set_indev(lv_indev_t* device);
|
||||
|
||||
/**
|
||||
* Activate the keypad for a widget group.
|
||||
* @param group
|
||||
*/
|
||||
void tt_lvgl_keypad_activate(lv_group_t* group);
|
||||
|
||||
/**
|
||||
* Deactivate the keypad for the current widget group (if any).
|
||||
* You don't have to call this after calling _activate() because widget
|
||||
* cleanup automatically removes itself from the group it belongs to.
|
||||
*/
|
||||
void tt_lvgl_keypad_deactivate();
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user