Description
Hi there, I have quite a nice menu system up and running, with no touch screen and only an encoder.
I have used buttons and lists with some success, but I am having an issue with the behaviour of base objects.
Initially I wanted to have a table with 2 columns, but when I wanted to navigate it, I couldn’t get the whole row to focus at a time. I’m guessing this could be simulated by implementing it in the table draw callback, but I rather opted for a different route.
I now have a bunch of objects which are my “rows”, within them, I have two labels, simulating my columns.
When I click on one of the rows, I have a callback that changes the value in column two. This works quite well, the only issue is, I need to click twice (first to go into edit mode, then to change the value).
Making matters worse, once I have entered edit mode on the object, I cant seem to exit is. I can manually disable edit mode in the click callback to make my “table” scrollable again, but this will mean I have to click everything twice to change a value.
How can I change the behaviour of the base object (my “rows”) to act like a button? i.e. when navigating, I click once, it executes the callback and I can resume scrolling?
What MCU/Processor/Board and compiler are you using?
A custom board, STM32F769 and STM Cube IDE.
What LVGL version are you using?
Version 8+.
What do you want to achieve?
I want to change the behaviour of a “container”-like object to that of a button.
What have you tried so far?
I tried making the object clickable, I tried changing the edit/navigate mode manually, I also tried exiting the edit mode with a long press, all without success.
Code to reproduce
Here is me creating the “rows” (showing only the relevant bits)
//Clear of all objects
lv_group_remove_all_objs(TestmenuGroup);
//Create the array of setting items
for(uint8_t i = 0; i < Settings_Count; i++)
{
//Create an object
Display_SettingsObjects[i] = lv_obj_create(ParentWindow);
//Set the object size / align
lv_obj_set_width(Display_SettingsObjects[i], LV_PCT(100));
lv_obj_set_height(Display_SettingsObjects[i], 30);
lv_obj_align(Display_SettingsObjects[i], LV_ALIGN_CENTER, 0, 0);
//Reduce padding
lv_obj_set_style_pad_all(Display_SettingsObjects[i], 2, 0);
//Add the first label
lv_obj_t * child1 = lv_label_create(Display_SettingsObjects[i]);
lv_label_set_text(child1, TestJigSettings[i].Name);
//set the width
lv_obj_set_width(child1, LV_PCT(65));
lv_obj_align(child1, LV_ALIGN_LEFT_MID, 0, 0);
//Convert settings value to text
char tempSettingText[MAX_SETTING_TEXT_LENGTH];
Display_getSettingText(Settings[i].Type, Settings[i].Current, Settings[i].Options, Settings[i].OptionCount, SettingText);
//Add the second label
lv_obj_t * child2 = lv_label_create(Display_SettingsObjects[i]);
lv_label_set_text(child2, tempSettingText);
//Add the object to the group
lv_group_add_obj(TestmenuGroup, Display_SettingsObjects[i]);
//set the width
lv_obj_set_width(child2, LV_PCT(30));
lv_obj_align(child2, LV_ALIGN_RIGHT_MID, 0, 0);
//Enable scrolling
lv_obj_add_flag(Display_SettingsObjects[i], LV_OBJ_FLAG_SCROLL_ON_FOCUS);
//Make clickable
lv_obj_add_flag(Display_SettingsObjects[i], LV_OBJ_FLAG_CLICKABLE);
//Add the callback for the menu item
lv_obj_add_event_cb(Display_SettingsObjects[i], Display_EditSetting, LV_EVENT_CLICKED, &Settings[i]);
}
//Set indevices
lv_indev_set_group(MyInputDevice, TestmenuGroup);
lv_indev_set_group(MyInputDevice2, TestmenuGroup);
Here is my click callback:
//get pointer to setting object
Settings_t* Settingtemp = lv_event_get_user_data(e);
//Get pointer to the "value" lable. It is the second child of the object
lv_obj_t * tempObject = lv_event_get_target(e);
lv_obj_t * tempValueLable = lv_obj_get_child(tempObject, 1);
switch(Settingtemp->Type)
{
case MultiSelect:
break;
case Checkbox:
//This is a true/false, we can just toggle it
if(Settingtemp->Current)
{
Settingtemp->Current = 0;
}
else
{
Settingtemp->Current = 1;
}
break;
case Integer:
break;
case Decimal:
break;
case String:
break;
default:
break;
}
//Update the value label
char tempSettingText[MAX_SETTING_TEXT_LENGTH];
Display_getSettingText(Settingtemp->Type, Settingtemp->Current, Settingtemp->Options, Settingtemp->OptionCount, tempSettingText);
lv_label_set_text(tempValueLable, tempSettingText);
//Update the setting in NVRAM
Settings_WriteNewValue(Settingtemp->Current, Settingtemp->Index);