Description
Hello Gentlemen. I am looking to make a gui for an ESP32 powered device with a small 240x240 IPS screen with a ST7789 driver without touchscreen, but 3 buttons vertically right next to the screen. A classic configuration that I have hope will work well with what LVGL provides, once I have managed to understand this Library.
Where am I
I have managed to set everything up to compile and run fine on VSCode/PlatformIO. I have basic stuff displayed, input configured but not working as expected. I am chewing myself through the documentation, but feel like I am stuck on a few basics and architectural questions I am hoping to find help in here.
What I’d like to achive
As said earlier I have 3 vertical buttons which would make Sense to be Up/Enter/Down.
I’d like to have a number of different main screens/pages that display information without user input, and there is one more configuration screen that accepts user input to change settings. So when not on the settings screen up/down should scroll through the main pages, and once at the settings page, scroll through the individual settings which can be changed by pressing enter and change value with up/down. After the last setting start again from the first page, or back the other way around. The settings page itself also should have several submenus.
Additionally there needs to be a title bar with battery status, RSSI etc.
What have got so far
I have managed to get LVGL display things on my LCD, I guess that’s a good first step. I also manage to add Items to the screen, I am pretty sure I will manage to configure them, but I am struggling to get input to work the way I’d like to. So far I have the first object on my screen with the orange focus indicator. Up, down and enter keys all set and reset focus of the first element but would not move focus to the next or previous input. I am also not able to change the selected input.
sample code
I have set up and input device as an encoder and added it to a single group:
lv_indev_drv_t indev_ButtonsDriver;
lv_indev_drv_init(&indev_ButtonsDriver);
indev_ButtonsDriver.type = LV_INDEV_TYPE_ENCODER;
indev_ButtonsDriver.read_cb = readButtons;
indev_ButtonsEncoder = lv_indev_drv_register(&indev_ButtonsDriver);
lv_indev_set_group(indev_ButtonsEncoder, displayGroup);
and us the readButtons callback to change the button state:
switch (btnUpState)
{
case BTN_STATE_CLICKED:
data->state = LV_INDEV_STATE_PR;
//data->key = LV_KEY_LEFT;
data->key = LV_KEY_UP;
btnUpState = BTN_STATE_REL;
Serial.println("up clicked");
break;
...
Same code for LV_KEY_DOWN
and LV_KEY_ENTER
as suggested in the docs. As you can Sey I have also tried LV_KEY_LEFT
and LV_KEY_RIGHT
. I am unsure if this is the correct way to do this. Unfortunately I was unable to find any tutorial that does the type of input I am trying to do, only the statements in the manual that it is well possible.
Then I have set up the guy itself like this:
static lv_style_t win_style;
lv_style_copy(&win_style, &lv_style_plain);
guiWindow = lv_win_create(scr, NULL);
lv_win_set_title(guiWindow, "Title Version V0.01a");
lv_win_set_btn_size(guiWindow, 20);
lv_page_set_scrl_layout(lv_win_get_content(guiWindow), LV_LAYOUT_OFF);
lv_win_set_style(guiWindow, LV_WIN_STYLE_BG, &lv_style_plain);
lv_win_set_style(guiWindow, LV_WIN_STYLE_CONTENT, &lv_style_plain);
//lv_group_add_obj(displayGroup, lv_win_get_content(guiWindow)); // with this line uncommented focus is on the window and wont change
// Battery Indicator
lv_obj_t * batteryButton = lv_win_add_btn(guiWindow, LV_SYMBOL_BATTERY_FULL);
lv_obj_set_protect(batteryButton, LV_PROTECT_CLICK_FOCUS);
const lv_style_t * btn_style = lv_btn_get_style(batteryButton, LV_BTN_STYLE_REL);
// A Container
lv_obj_t * cont_A;
cont_A = lv_cont_create(guiWindow, NULL);
lv_obj_set_auto_realign(cont_A, true); // Auto realign when the size changes
lv_obj_align_origo(cont_A, NULL, LV_ALIGN_CENTER, 0, 0); // This parametrs will be sued when realigned
lv_cont_set_fit(cont_A, LV_FIT_TIGHT);
lv_cont_set_layout(cont_A, LV_LAYOUT_COL_M);
lv_cont_set_style(cont_A, LV_CONT_STYLE_MAIN, &lv_style_plain);
// Settings
lv_obj_t *roller1 = lv_roller_create(cont_A, NULL);
lv_roller_set_options(roller1,
"950\n"
"960\n"
"970\n"
"980\n"
"990\n"
"1000\n"
"1010\n"
"1020\n"
"1030\n"
"1040\n"
"1050\n",
LV_ROLLER_MODE_INIFINITE);
lv_roller_set_visible_row_count(roller1, 1);
lv_obj_align(roller1, NULL, LV_ALIGN_CENTER, 0, 0);
lv_obj_set_style(roller1, &lv_style_plain);
lv_group_add_obj(displayGroup, roller1);
//lv_obj_set_event_cb(roller1, event_handler);
lv_obj_t *label;
label = lv_label_create(cont_A, NULL);
lv_label_set_text(label, "Short text");
lv_group_add_obj(displayGroup, label);
label = lv_label_create(cont_A, NULL);
lv_label_set_text(label, "It is a long text");
lv_group_add_obj(displayGroup, label);
lv_obj_t* cb = lv_cb_create(cont_A, NULL); // First check box
lv_cb_set_text(cb, "Red");
lv_group_add_obj(displayGroup, cb);
The Problem summarized
I have set up Input to send KEY_UP/DOWN or LEFT/RIGHT and ENTER. I have created a group, assigned both input and elements to the group. I have the orange focus indicator on the first element. but it would not move to the other elements, also would not change the value of the selected first element. If I press any of the 3 buttons the element would loose and gain the orange focus indicator
I have yet to understand …
how I would lay out the menu structure after I got my input problem fixed. How would I set up 3 or more scrolling pages with no inner focus, plus one last page that contains individual settings to be changed?
I appreciate your guys input!
beef