Description
In my current project I am working on a menu structure. The menu is based on the complex menu sample.
The idea is that the user gets a pop-up to enter the data in textboxes.
The keyboard should open at the bottom of the screen (similar to the example) but somehow it opens at the top of the submenu.
What MCU/Processor/Board and compiler are you using?
LPC1877 with a custom toolchain
What LVGL version are you using?
8.4.0
What do you want to achieve?
A “normal” working menu. With the constraint that I have to load-unload pages since I don’t have enough RAM in my controller.
What have you tried so far?
multiple options as argument to lv_keyboard_create(). Some produce the keyboard at the top of the sub screen, others a hard crash.
Code to reproduce
static lv_obj_t * create_text(lv_obj_t * parent, const char * icon, const char * txt, lv_menu_builder_variant_t builder_variant);
static lv_obj_t * create_slider(lv_obj_t * parent, const char * icon, const char * txt, int32_t min, int32_t max, int32_t val);
static lv_obj_t * create_switch(lv_obj_t * parent, const char * icon, const char * txt, bool chk);
static lv_obj_t * create_sub_page(lv_obj_t * menu);
static lv_obj_t * create_module_page(lv_obj_t * menu);
lv_obj_t * keyboard = NULL;
lv_obj_t * menu;
lv_obj_t * root_page;
static void ta_event_cb(lv_event_t * e)
{
lv_event_code_t eventCode = lv_event_get_code(e);
lv_obj_t * targetArea = lv_event_get_target(e);
if(eventCode == LV_EVENT_FOCUSED)
{
//Create the keyboard if required
if(keyboard == NULL)
keyboard = lv_keyboard_create(menu);
lv_keyboard_set_textarea(keyboard, targetArea);
}
if(eventCode == LV_EVENT_DEFOCUSED)
{
lv_keyboard_set_textarea(keyboard, NULL);
lv_obj_add_flag(keyboard, LV_OBJ_FLAG_HIDDEN);
}
}
/// @brief Loads the main screen into memory. The screen is only loaded, not shown.
/// @return An object thar represents the full screen.
lv_obj_t* ScreenLoad(void * arg)
{
menu = lv_menu_create(NULL);
lv_color_t bg_color = lv_obj_get_style_bg_color(menu, 0);
if(lv_color_brightness(bg_color) > 127)
{
lv_obj_set_style_bg_color(menu, lv_color_darken(bg_color, 10), 0);
}
else
{
lv_obj_set_style_bg_color(menu, lv_color_darken(bg_color, 50), 0);
}
lv_menu_set_mode_root_back_btn(menu, LV_MENU_ROOT_BACK_BTN_ENABLED);
lv_obj_set_size(menu, lv_disp_get_hor_res(NULL), lv_disp_get_ver_res(NULL));
lv_obj_center(menu);
lv_obj_t * sub_page = create_sub_page(menu);
lv_obj_t * root_page = lv_menu_page_create(menu, "Menu");
lv_obj_set_style_pad_hor(root_page, lv_obj_get_style_pad_left(lv_menu_get_main_header(menu), 0), 0);
lv_obj_t * section = lv_menu_section_create(root_page);
lv_obj_t * cont = create_text(section, LV_SYMBOL_SETTINGS, "sub_page", LV_MENU_ITEM_BUILDER_VARIANT_1);
lv_menu_set_load_page_event(menu, cont, sub_page);
lv_menu_set_sidebar_page(menu, root_page);
lv_event_send(lv_obj_get_child(lv_obj_get_child(lv_menu_get_cur_sidebar_page(menu), 0), 0), LV_EVENT_CLICKED, NULL);
return menu;
}
static lv_obj_t * create_sub_page(lv_obj_t * menu)
{
lv_obj_t * page = lv_menu_page_create(menu, "sub page");
lv_obj_set_style_pad_hor(page, lv_obj_get_style_pad_left(lv_menu_get_main_header(menu), 0), 0);
lv_menu_separator_create(page);
lv_obj_t * section = lv_menu_section_create(page);
lv_obj_t * cont = create_text(section, LV_SYMBOL_AUDIO, "Module", LV_MENU_ITEM_BUILDER_VARIANT_1);
lv_obj_t * module_page = create_module_page(menu);
lv_menu_set_load_page_event(menu, cont, module_page);
return page;
}
static lv_obj_t * create_module_page(lv_obj_t * menu)
{
lv_obj_t * page = lv_menu_page_create(menu, "Module");
lv_obj_set_style_pad_hor(page, lv_obj_get_style_pad_left(lv_menu_get_main_header(menu), 0), 0);
lv_menu_separator_create(page);
lv_obj_t * section = lv_menu_section_create(page);
// Analog input header
lv_obj_t * analog_header = create_text(section, NULL, "Analog input", LV_MENU_ITEM_BUILDER_VARIANT_1);
{
// Channel 1 sub-header
lv_obj_t * channel_header = create_text(section, NULL, "Channel 1", LV_MENU_ITEM_BUILDER_VARIANT_1);
lv_obj_set_style_pad_left(channel_header, 20, 0); // Indent Channel 1
// Name input
lv_obj_t * name_cont = create_text(section, NULL, "Name", LV_MENU_ITEM_BUILDER_VARIANT_1);
lv_obj_set_style_pad_left(name_cont, 40, 0);
lv_obj_t * name_input = lv_textarea_create(name_cont);
lv_textarea_set_one_line(name_input, true);
lv_obj_set_width(name_input, lv_pct(60));
lv_obj_align(name_input, LV_ALIGN_RIGHT_MID, 0, 0);
lv_obj_add_event_cb(name_input, ta_event_cb, LV_EVENT_ALL, NULL);
// Input min
lv_obj_t * input_min_cont = create_text(section, NULL, "Input min", LV_MENU_ITEM_BUILDER_VARIANT_1);
lv_obj_set_style_pad_left(input_min_cont, 40, 0);
lv_obj_t * input_min = lv_textarea_create(input_min_cont);
lv_textarea_set_one_line(input_min, true);
lv_textarea_set_accepted_chars(input_min, "0123456789.-");
lv_obj_set_width(input_min, lv_pct(30));
lv_obj_align(input_min, LV_ALIGN_RIGHT_MID, 0, 0);
lv_obj_add_event_cb(input_min, ta_event_cb, LV_EVENT_ALL, NULL);
// Input max
lv_obj_t * input_max_cont = create_text(section, NULL, "Input max", LV_MENU_ITEM_BUILDER_VARIANT_1);
lv_obj_set_style_pad_left(input_max_cont, 40, 0);
lv_obj_t * input_max = lv_textarea_create(input_max_cont);
lv_textarea_set_one_line(input_max, true);
lv_textarea_set_accepted_chars(input_max, "0123456789.-");
lv_obj_set_width(input_max, lv_pct(30));
lv_obj_align(input_max, LV_ALIGN_RIGHT_MID, 0, 0);
lv_obj_add_event_cb(input_max, ta_event_cb, LV_EVENT_ALL, NULL);
// Output min
lv_obj_t * output_min_cont = create_text(section, NULL, "Output min", LV_MENU_ITEM_BUILDER_VARIANT_1);
lv_obj_set_style_pad_left(output_min_cont, 40, 0);
lv_obj_t * output_min = lv_textarea_create(output_min_cont);
lv_textarea_set_one_line(output_min, true);
lv_textarea_set_accepted_chars(output_min, "0123456789.-");
lv_obj_set_width(output_min, lv_pct(30));
lv_obj_align(output_min, LV_ALIGN_RIGHT_MID, 0, 0);
lv_obj_add_event_cb(output_min, ta_event_cb, LV_EVENT_ALL, NULL);
// Output max
lv_obj_t * output_max_cont = create_text(section, NULL, "Output max", LV_MENU_ITEM_BUILDER_VARIANT_1);
lv_obj_set_style_pad_left(output_max_cont, 40, 0);
lv_obj_t * output_max = lv_textarea_create(output_max_cont);
lv_textarea_set_one_line(output_max, true);
lv_textarea_set_accepted_chars(output_max, "0123456789.-");
lv_obj_set_width(output_max, lv_pct(30));
lv_obj_align(output_max, LV_ALIGN_RIGHT_MID, 0, 0);
lv_obj_add_event_cb(output_max, ta_event_cb, LV_EVENT_ALL, NULL);
}
return page;
}
static void back_event_handler(lv_event_t * e)
{
lv_obj_t * obj = lv_event_get_target(e);
lv_obj_t * menu = lv_event_get_user_data(e);
if(lv_menu_back_btn_is_root(menu, obj)) {
lv_obj_t * mbox1 = lv_msgbox_create(NULL, "Hello", "Root back btn click.", NULL, true);
lv_obj_center(mbox1);
}
}
static lv_obj_t * create_text(lv_obj_t * parent, const char * icon, const char * txt,
lv_menu_builder_variant_t builder_variant)
{
lv_obj_t * obj = lv_menu_cont_create(parent);
lv_obj_t * img = NULL;
lv_obj_t * label = NULL;
if(icon) {
img = lv_img_create(obj);
lv_img_set_src(img, icon);
}
if(txt) {
label = lv_label_create(obj);
lv_label_set_text(label, txt);
lv_label_set_long_mode(label, LV_LABEL_LONG_SCROLL_CIRCULAR);
lv_obj_set_flex_grow(label, 1);
}
if(builder_variant == LV_MENU_ITEM_BUILDER_VARIANT_2 && icon && txt) {
lv_obj_add_flag(img, LV_OBJ_FLAG_FLEX_IN_NEW_TRACK);
lv_obj_swap(img, label);
}
return obj;
}
static lv_obj_t * create_slider(lv_obj_t * parent, const char * icon, const char * txt, int32_t min, int32_t max, int32_t val)
{
lv_obj_t * obj = create_text(parent, icon, txt, LV_MENU_ITEM_BUILDER_VARIANT_2);
lv_obj_t * slider = lv_slider_create(obj);
lv_obj_set_flex_grow(slider, 1);
lv_slider_set_range(slider, min, max);
lv_slider_set_value(slider, val, LV_ANIM_OFF);
if(icon == NULL) {
lv_obj_add_flag(slider, LV_OBJ_FLAG_FLEX_IN_NEW_TRACK);
}
return obj;
}
static lv_obj_t * create_switch(lv_obj_t * parent, const char * icon, const char * txt, bool chk)
{
lv_obj_t * obj = create_text(parent, icon, txt, LV_MENU_ITEM_BUILDER_VARIANT_1);
lv_obj_t * sw = lv_switch_create(obj);
lv_obj_add_state(sw, chk ? LV_STATE_CHECKED : 0);
return obj;
}
This code get’s called from the main()
in the following way:
//Load the graphScreen into RAM and display it
lv_obj_t *configurationScreen = ConfigurationScreenLoad(arg);
lv_scr_load_anim(configurationScreen, LV_SCR_LOAD_ANIM_NONE, 0, 0, true);
Screenshot and/or video
The current state with the strange keyboard (menu entry’s are blacked out).