Enable touch keyboard in the geocaching editor

This commit is contained in:
liu weikai
2026-09-28 17:24:19 +08:00
parent a3fc9d73aa
commit c43b372aff
4 changed files with 57 additions and 2 deletions
@@ -4,6 +4,7 @@
#include "ui/page/page_profile.h"
#include "ui/screens/gps/gps_page_runtime.h"
#include "ui/widgets/top_bar.h"
#include "ui_lvgl_ux_packs/common/touch_text_editor.h"
#include <algorithm>
#include <cstdio>
#include <cstring>
@@ -292,6 +293,9 @@ void refreshView()
auto& p = *page;
const auto old_generation = p.snapshot.generation;
auto* focused = p.group ? lv_group_get_focused(p.group) : nullptr;
bool focus_survives = focused != nullptr;
for (auto* object = focused; object; object = lv_obj_get_parent(object))
if (object == p.list) focus_survives = false;
std::array<uint8_t, 32> focused_id{};
bool focused_row = false;
for (size_t i = 0; i < p.row_count; ++i)
@@ -383,7 +387,7 @@ void refreshView()
if (p.row_ids[i] == focused_id) restore = p.rows[i];
lv_group_focus_obj(restore);
}
else if (focused && !lv_obj_has_state(focused, LV_STATE_DISABLED)) lv_group_focus_obj(focused);
else if (focus_survives && !lv_obj_has_state(focused, LV_STATE_DISABLED)) lv_group_focus_obj(focused);
else lv_group_focus_obj(p.tabs[static_cast<size_t>(p.section)]);
}
}
@@ -683,6 +687,7 @@ void openEditor(const ::ui::geocaching::Item* item)
lv_obj_set_height(field, i == 3 || i == 4 ? 64 : 32);
lv_textarea_set_max_length(field, limits[i]);
lv_textarea_set_text(field, i == 5 || i == 6 ? "1.0" : "");
::ui::widgets::attach_touch_text_editor(field);
lv_obj_set_style_bg_color(field, lv_color_hex(styles::kSidePanelBg), 0);
lv_obj_set_style_text_color(field, lv_color_hex(styles::kTextPrimary), 0);
lv_obj_set_style_border_color(field, lv_color_hex(styles::kBorder), 0);
@@ -10,13 +10,22 @@ target_compile_definitions(page_test_lvgl PUBLIC LV_CONF_SKIP=1 LV_USE_STDLIB_MA
LV_MEM_SIZE=1048576 LV_USE_STDLIB_STRING=1 LV_USE_STDLIB_SPRINTF=1
LV_USE_SNAPSHOT=1 LV_FONT_MONTSERRAT_12=1 LV_FONT_MONTSERRAT_16=1 LV_FONT_MONTSERRAT_20=1)
add_executable(geocaching_page_test test_page.cpp
"${REPO_ROOT}/modules/ui_lvgl_ux_packs/tests/touch_editor/test_support.cpp"
"${REPO_ROOT}/modules/ui_lvgl_ux_packs/src/common/touch_text_editor.cpp"
"${REPO_ROOT}/modules/ui_lvgl_ux_packs/src/common/input_layout.cpp"
"${REPO_ROOT}/modules/ui_shared/src/ui/widgets/ime/ime_widget.cpp"
"${REPO_ROOT}/modules/ui_shared/src/ui/widgets/ime/pinyin_ime.cpp"
"${REPO_ROOT}/modules/ui_shared/src/ui/widgets/ime/ime_input_mode_descriptor.cpp"
"${REPO_ROOT}/modules/ui_shared/src/ui/screens/geocaching/geocaching_page_shell.cpp"
"${REPO_ROOT}/modules/ui_shared/src/ui/components/two_pane_styles.cpp"
"${REPO_ROOT}/modules/ui_shared/src/ui/widgets/top_bar.cpp"
"${REPO_ROOT}/modules/ui_shared/src/ui/page/page_profile.cpp")
target_include_directories(geocaching_page_test PRIVATE stubs
"${REPO_ROOT}/modules/ui_lvgl_ux_packs/tests/touch_editor/stubs"
"${REPO_ROOT}/modules/ui_lvgl_ux_packs/include"
"${REPO_ROOT}/modules/ui_shared/include" "${REPO_ROOT}/modules/ui_presentation/include")
target_compile_features(geocaching_page_test PRIVATE cxx_std_17)
target_compile_definitions(geocaching_page_test PRIVATE UI_SHARED_TOUCH_IME_ENABLED=1)
target_link_libraries(geocaching_page_test PRIVATE page_test_lvgl)
if(MSVC)
target_compile_options(geocaching_page_test PRIVATE /utf-8)
@@ -2,6 +2,9 @@
#include "lvgl.h"
namespace ui::fonts
{
inline const lv_font_t* ui_chrome_font() { return &lv_font_montserrat_14; }
inline const lv_font_t* localized_font(const lv_font_t* base) { return base; }
inline const lv_font_t* content_font(const char*, const lv_font_t* base) { return base; }
inline void apply_content_font(lv_obj_t* object, const char*, const lv_font_t* font)
{
lv_obj_set_style_text_font(object, font, 0);
@@ -205,6 +205,14 @@ bool save(const std::string& path, lv_obj_t* screen)
lv_draw_buf_destroy(image);
return out.good();
}
lv_obj_t* findKeyboard(lv_obj_t* root)
{
if (lv_obj_check_type(root, &lv_buttonmatrix_class)) return root;
for (uint32_t i = 0; i < lv_obj_get_child_count(root); ++i)
if (auto* found = findKeyboard(lv_obj_get_child(root, i))) return found;
return nullptr;
}
int main(int argc, char** argv)
{
if (argc != 4) return 1;
@@ -216,7 +224,9 @@ int main(int argc, char** argv)
lv_display_set_buffers(display, pixels.data(), nullptr, pixels.size(), LV_DISPLAY_RENDER_MODE_PARTIAL);
lv_display_set_flush_cb(display, [](lv_display_t* display, const lv_area_t*, uint8_t*)
{ lv_display_flush_ready(display); });
const auto profile = width == 480 ? ui::page_profile::make_pager_profile() : ui::page_profile::make_tdeck_profile();
auto profile = width == 480 ? ui::page_profile::make_pager_profile() : ui::page_profile::make_tdeck_profile();
profile.compact_touch_keyboard = width == 320;
if (profile.compact_touch_keyboard) profile.ime_keyboard_height = 108;
ui::page_profile::set_active_profile(&profile);
auto* screen = lv_screen_active();
auto* old_group = lv_group_create();
@@ -329,6 +339,34 @@ int main(int argc, char** argv)
lv_obj_send_event(lv_obj_get_child(footer, 0), LV_EVENT_CLICKED, nullptr);
list = lv_obj_get_child(root, 3);
auto* name_field = lv_obj_get_child(list, 1);
for (unsigned field = 0; field < 7; ++field)
{
auto* input = lv_obj_get_child(list, 2 * field + 1);
const auto layers = lv_obj_get_child_count(lv_layer_top());
lv_obj_send_event(input, LV_EVENT_CLICKED, nullptr);
if (profile.compact_touch_keyboard)
{
if (lv_obj_get_child_count(lv_layer_top()) != layers + 1) return 40;
auto* modal = lv_obj_get_child(lv_layer_top(), -1);
auto* draft = lv_obj_get_child(modal, 1);
if (!lv_obj_check_type(draft, &lv_textarea_class)) return 41;
auto* keyboard = findKeyboard(modal);
if (!keyboard) return 45;
if (field == 0)
{
lv_buttonmatrix_set_selected_button(keyboard, 0);
lv_obj_send_event(keyboard, LV_EVENT_VALUE_CHANGED, nullptr);
if (std::strcmp(lv_textarea_get_text(draft), "q")) return 46;
}
lv_textarea_set_text(draft, field == 0 ? "Touch input" : "1.5");
if (field == 0 && !save(std::string(argv[3]) + "-keyboard.ppm", modal)) return 42;
auto* actions = lv_obj_get_child(modal, 0);
lv_obj_send_event(lv_obj_get_child(actions, 1), LV_EVENT_CLICKED, nullptr);
if (std::strcmp(lv_textarea_get_text(input), field == 0 ? "Touch input" : "1.5") ||
lv_obj_get_child_count(lv_layer_top()) != layers) return 43;
}
else if (lv_obj_get_child_count(lv_layer_top()) != layers) return 44;
}
lv_textarea_set_text(name_field, "林间宝藏");
lv_textarea_set_text(lv_obj_get_child(list, 3), "30.5");
lv_textarea_set_text(lv_obj_get_child(list, 5), "120.5");