Navigation with encoder - lv_group , disabling enabling things

Description

Navigation with encoder - lv_group , disabling enabling things

What MCU/Processor/Board and compiler are you using?

ESP32, littlevgl 6.1.1

What do you want to achieve?

I have a view with two tabs, each tab has its group, and I switch the active group in the device driver (encoder), so the navigation works as imagined.
This all worked relatively easily and looks pretty. (Thank you for the superb library!)

Now I would like to deactivate (make unclickable / unediatble) Buttons, Text Areas (spinbox) for a specific duration.

What have you tried so far?

I tried

lv_obj_set_protect(obj, LV_PROTECT_CLICK_FOCUS);
lv_btn_set_state(obj,LV_BTN_STATE_INA); // this is style stuff
lv_obj_set_click(obj, 1);

The only workaround i found to achieve what I wanted is to “disabled” items via removing them from their group. If I want to “reactivate” them later on I have to remove all the objects from the group and readd each of them them including the previously deactivated to achive the right order again.
It feels a bit like shooting with a “cannon on a sparrow” (destroying those ll_lists in background and recreating them)

Update: Inbetween I found out that modifying groups after creation sometimes locks up and for some reason I cant change between tabs anymore. If I create the groups once and do not change them in runtime this never happens.

static void group_focus_cb(lv_group_t * group)
{
    lv_obj_t* obj = NULL;
    if (group == t_main_tab_g)
        obj =  main_tab;
    else if (group == t_settings_tab_g )
        obj = settings_tab;
    else
        printf("GROUP FOCUS ERROR");
    if (obj != NULL)
    {
        lv_obj_t * f = lv_group_get_focused(enc_current_group);
        if( ((intptr_t)f != (intptr_t)t_main_tab_g) && ((intptr_t)f != (intptr_t)t_settings_tab_g))
            lv_page_focus(obj, f, LV_ANIM_ON);
    }
}

void init_my_lvgl_view(void)
{
    //lv_coord_t hres = lv_disp_get_hor_res(NULL);
    //lv_coord_t vres = lv_disp_get_ver_res(NULL);

    // groups
    t_main_tab_g = lv_group_create();
    t_settings_tab_g = lv_group_create();
    lv_group_set_focus_cb( t_main_tab_g, group_focus_cb);
    lv_group_set_focus_cb( t_settings_tab_g, group_focus_cb);

    // encoder driver
    lv_indev_drv_init(&enc_drv);
    enc_drv.type = LV_INDEV_TYPE_ENCODER;
    enc_drv.read_cb = lvgl_encoder_read;
    enc_indev = lv_indev_drv_register(&enc_drv);
    lv_indev_set_group(enc_indev, t_main_tab_g);
    enc_current_group = t_main_tab_g;

    // tabs
    t_tabs = lv_tabview_create(lv_disp_get_scr_act(NULL), NULL);
    lv_obj_set_event_cb(t_tabs, tabview_event_handler);
    lv_tabview_set_sliding(t_tabs,true); // small bar below the active tab button

    lv_group_add_obj(t_settings_tab_g, t_tabs);
    lv_group_add_obj(t_main_tab_g, t_tabs); // i think this will be ignored..

    main_tab = lv_tabview_add_tab(t_tabs, T_SYM_SAMPLE);
    settings_tab = lv_tabview_add_tab(t_tabs, T_SYM_SETTINGS);

    init_main_tab(main_tab, t_main_tab_g); // it just adds objects to the group
    init_settings_tab(settings_tab, t_settings_tab_g); // it just adds objects to the group


void gui_set_btns_enabled(uint8_t enabled)
{
        lv_obj_t * focused_obj = lv_group_get_focused(enc_current_group);
        lv_obj_t* tab_obj = NULL;
        if (enc_current_group == t_main_tab_g)
            tab_obj =  main_tab;
        else if (enc_current_group == t_settings_tab_g )
            tab_obj = settings_tab;
        else
            printf("GUI -> Encoder uses an unknown group?! \n");

        if (enabled)
        {
            printf("GUI -> Enable Buttons \n");

            lv_group_remove_all_objs(t_main_tab_g);

            lv_group_add_obj(t_main_tab_g, t_tabs); // i think this will be ignored..
            lv_group_add_obj(t_main_tab_g, t_btn_toast);
            lv_group_add_obj(t_main_tab_g, spinbox_timer);
            lv_group_add_obj(t_main_tab_g, label_humi);
            lv_group_add_obj(t_main_tab_g, label_temp);
            lv_group_add_obj(t_main_tab_g, label_temp1);
            lv_group_add_obj(t_main_tab_g, label_temp2);
            lv_group_add_obj(t_main_tab_g, label_temp3);
            lv_group_add_obj(t_main_tab_g, label_dist_analog);
            lv_group_add_obj(t_main_tab_g, label_smoke);
            lv_group_add_obj(t_main_tab_g, label_scale);
            lv_group_add_obj(t_main_tab_g, label_freq);
            lv_group_add_obj(t_main_tab_g, label_aq);
            lv_group_add_obj(t_main_tab_g, cont_color);

            lv_group_remove_all_objs(t_settings_tab_g);

            lv_group_add_obj(t_settings_tab_g, t_tabs);
            lv_group_add_obj(t_settings_tab_g, t_btn_heater);
            lv_group_add_obj(t_settings_tab_g, t_btn_fan);
            lv_group_add_obj(t_settings_tab_g, t_btn_led);
            lv_group_add_obj(t_settings_tab_g, t_btn_lift);

            if( (focused_obj != t_main_tab_g) && (focused_obj != t_settings_tab_g))
                lv_page_focus(tab_obj, focused_obj, LV_ANIM_OFF);
        }
        else
        {
            lv_group_remove_obj(spinbox_timer);
            lv_group_remove_obj(t_btn_heater);
            lv_group_remove_obj(t_btn_fan);
            lv_group_remove_obj(t_btn_led);
            lv_group_remove_obj(t_btn_lift);

            printf("GUI -> Disable Buttons \n");
        }
}

}

I ended up adding a variable for the button enabledness :slight_smile: and I check it in the event callback. The button is still clickable but I doesnt changes its state at least if I do not want it to. ( so I cant use toggle buttons ).
For the spinbox I’m blocking the increment in the disabled state in lv_spinbox.c.

Is there a simpler way to achive this?
Thank you!

Hi,

In v6 I also can’t imagine a better way than manually hacking this things. However in v7.0 object will have “states”. One the states is LV_STATE_DISABLED which blocks the input devices and also changes the appearance of the object. You acn read more about it here.