Disabled/Enable Events similar to the way you'd do for interrupts

Description

Is there anyway to disable events while one is currently happening. Much like you can disable interrupts in an interrupt handler before enabling them at the end.

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

LVGL Simulator via MS Visual Studio 2022

What LVGL version are you using?

8.3.0 (dev)

What do you want to achieve?

I have an event that triggers an animation, I want this animation to finish before allowing other events trigger different animations.

What have you tried so far?

Using lv_obj_remove_event_cb(…) at the start of the event handler on all events I don’t want to trigger. And then using lv_obj_add_event_cb(…) at the end of the handler to re-enable all those event.

Using lv_obj_remove_event_cb(…) at the start of the event handler on all events I don’t want to trigger. And then using lv_anim_set_ready_cb(…) to call a function that re-enables all those events when the animation is completed.

Using lv_obj_clear_flag(…, LV_OBJ_FLAG_CLICKABLE) at the start of the event handler on all buttons I do not want to trigger events. And lv_obj_add_flag(…, LV_OBJ_FLAG_CLICKABLE) at the end of the event handler.

Code to reproduce

If the buttons created by this code are clicked slowly you can observe the intended behaviour. Where things become broken is when you rapidly click buttons, and a buttons animation hasn’t finished before another’s begins.

From source.h

#ifndef SOURCE_H
#define SOURCE_H

#ifdef __cplusplus
extern "C" {
#endif

typdef struct {
    lv_obj_t* screen;
    lv_obj_t* button1;
    lv_obj_t* button2;
    lv_obj_t* button3;
    lv_obj_t* button4;
    lv_obj_t* thing_to_move1;
    lv_obj_t* thing_to_move2;
    lv_obj_t* thing_to_move3;
    lv_obj_t* thing_to_move4;
}lv_ui;

void setup_ui(lv_ui*);

extern lv_ui lcd_ui;

#ifdef __cplusplus
} /* extern "C" */
#endif

#endif /*SOURCE_H*/

From source.c

static void setup_scr_screen(lv_ui*);
static void create_objects_scr_screen(lv_ui*);
static void object_characteristics_scr_screen(lv_ui* ui);
static void enable_events_scr_screen(lv_ui* ui);
static void disable_events_scr_screen(lv_ui* ui);
static void button1_event(lv_event_t*);
static void button2_event(lv_event_t*);
static void button3_event(lv_event_t*);
static void button4_event(lv_event_t*);
static void animation_x_cb(void*, int32_t);
static void animation_selected(lv_obj_t*, int32_t);
static void perform_correct_animation(lv_obj_t*);

void setup_ui(lv_ui* ui)
{
    //init_styles();
    //setup_styles();
    setup_scr_screen(ui);
    lv_scr_load(ui->screen);
}

static void setup_scr_screen(lv_ui* ui)
{
    create_objects_scr_screen(ui);
    object_characteristics_scr_screen(ui);
    enable_events_scr_screen(ui);
}

static void create_objects_scr_screen(lv_ui* ui)
{
    ui->screen = lv_obj_create(NULL);
    ui->container = lv_obj_create(ui->screen);
    ui->button1 = lv_btn_create(ui->container);
    ui->button2 = lv_btn_create(ui->container);
    ui->button3 = lv_btn_create(ui->container);
    ui->button4 = lv_btn_create(ui->container);
    ui->thing_to_move1 = lv_obj_create(ui->container);
    ui->thing_to_move2 = lv_obj_create(ui->container);
    ui->thing_to_move3 = lv_obj_create(ui->container);
    ui->thing_to_move4 = lv_obj_create(ui->container);
}

static void object_characteristics_scr_screen(lv_ui* ui)
{
    lv_obj_set_pos(ui->container, 0, 0);
    lv_obj_set_size(ui->container, 1024, 600); //screen size is 1024*600

    lv_obj_set_pos(ui->button1, 5, 5);
    lv_obj_set_size(ui->button1, 90, 90);

    lv_obj_set_pos(ui->button2, 5, 105);
    lv_obj_set_size(ui->button2, 90, 90);

    lv_obj_set_pos(ui->button3, 5, 205);
    lv_obj_set_size(ui->button3, 90, 90);

    lv_obj_set_pos(ui->button4, 5, 305);
    lv_obj_set_size(ui->button4, 90, 90);

    lv_obj_set_pos(ui->thing_to_move1, 225, 5);
    lv_obj_set_size(ui->thing_to_move1, 25, 90);

    lv_obj_set_pos(ui->thing_to_move2, 225, 105);
    lv_obj_set_size(ui->thing_to_move2, 25, 90);

    lv_obj_set_pos(ui->thing_to_move3, 225, 205);
    lv_obj_set_size(ui->thing_to_move3, 25, 90);

    lv_obj_set_pos(ui->thing_to_move4, 225, 305);
    lv_obj_set_size(ui->thing_to_move4, 25, 90);
}

static void enable_events_scr_screen(lv_ui* ui)
{
    lv_obj_add_event_cb(ui->button1, button1_event, LV_EVENT_RELEASED, NULL);
    lv_obj_add_event_cb(ui->button2, button2_event, LV_EVENT_RELEASED, NULL);
    lv_obj_add_event_cb(ui->button3, button3_event, LV_EVENT_RELEASED, NULL);
    lv_obj_add_event_cb(ui->button4, button4_event, LV_EVENT_RELEASED, NULL);
}

static void disable_events_scr_screen(lv_ui* ui)
{
    lv_obj_remove_event_cb(ui->button1, button1_event);
    lv_obj_remove_event_cb(ui->button2, button2_event);
    lv_obj_remove_event_cb(ui->button3, button3_event);
    lv_obj_remove_event_cb(ui->button4, button4_event);
}

// The event handlers might be 4 identical copies, but will have more added in the future to make them different

static void button1_event(lv_event_t* e)
{
    disable_events_scr_screen(&lcd_ui);
    lv_obj_t* obj = lv_event_get_target(e);
    perform_correct_animation(obj);
    enable_events_scr_screen(&lcd_ui);
}

static void button2_event(lv_event_t* e)
{
    disable_events_scr_screen(&lcd_ui);
    lv_obj_t* obj = lv_event_get_target(e);
    perform_correct_animation(obj);
    enable_events_scr_screen(&lcd_ui);
}

static void button3_event(lv_event_t* e)
{
    disable_events_scr_screen(&lcd_ui);
    lv_obj_t* obj = lv_event_get_target(e);
    perform_correct_animation(obj);
    enable_events_scr_screen(&lcd_ui);
}

static void button4_event(lv_event_t* e)
{
    disable_events_scr_screen(&lcd_ui);
    lv_obj_t* obj = lv_event_get_target(e);
    perform_correct_animation(obj);
    enable_events_scr_screen(&lcd_ui);
}

static void animation_x_cb(void* var, int32_t v)
{
    lv_obj_set_x(var, v);
}

static void animation_selected(lv_obj_t* obj, int32_t end)
{
    lv_anim_t a;
    lv_anim_init(&a);
    lv_anim_set_var(&a, obj);
    lv_anim_set_values(&a, lv_obj_get_x(obj), lv_obj_get_x(obj) + end);
    lv_anim_set_time(&a, 350);
    lv_anim_set_exec_cb(&a, animation_x_cb);
    lv_anim_set_path_cb(&a, lv_anim_path_ease_out);
    lv_anim_start(&a);
}

static void perform_correct_animation(lv_obj_t* obj)
{
    if (obj == lcd_ui.button1)
    {
        if (lv_obj_get_x(lcd_ui.thing_to_move2) != 225)
        {
            anim_selected(lcd_ui.thing_to_move2, 25);
        }
        else if (lv_obj_get_x(lcd_ui.thing_to_move3) != 225)
        {
            anim_selected(lcd_ui.thing_to_move3, 25);
        }
        else if (lv_obj_get_x(lcd_ui.thing_to_move4) != 225)
        {
            anim_selected(lcd_ui.thing_to_move4, 25);
        }
        if (lv_obj_get_x(lcd_ui.thing_to_move1) == 225)
        {
            anim_selected(lcd_ui.thing_to_move1, -25);
        }
    }
    else if (obj == lcd_ui.button2)
    {
        if (lv_obj_get_x(lcd_ui.thing_to_move1) != 225)
        {
            anim_selected(lcd_ui.thing_to_move1, 25);
        }
        else if (lv_obj_get_x(lcd_ui.thing_to_move3) != 225)
        {
            anim_selected(lcd_ui.thing_to_move3, 25);
        }
        else if (lv_obj_get_x(lcd_ui.thing_to_move4) != 225)
        {
            anim_selected(lcd_ui.thing_to_move4, 25);
        }
        if (lv_obj_get_x(lcd_ui.thing_to_move2) == 225)
        {
            anim_selected(lcd_ui.thing_to_move2, -25);
        }
    }
    else if (obj == lcd_ui.button3)
    {
        if (lv_obj_get_x(lcd_ui.thing_to_move2) != 225)
        {
            anim_selected(lcd_ui.thing_to_move2, 25);
        }
        else if (lv_obj_get_x(lcd_ui.thing_to_move1) != 225)
        {
            anim_selected(lcd_ui.thing_to_move1, 25);
        }
        else if (lv_obj_get_x(lcd_ui.thing_to_move4) != 225)
        {
            anim_selected(lcd_ui.thing_to_move4, 25);
        }
        if (lv_obj_get_x(lcd_ui.thing_to_move3) == 225)
        {
            anim_selected(lcd_ui.thing_to_move3, -25);
        }
    }
    else if (obj == lcd_ui.button4)
    {
        if (lv_obj_get_x(lcd_ui.thing_to_move2) != 225)
        {
            anim_selected(lcd_ui.thing_to_move2, 25);
        }
        else if (lv_obj_get_x(lcd_ui.thing_to_move3) != 225)
        {
            anim_selected(lcd_ui.thing_to_move3, 25);
        }
        else if (lv_obj_get_x(lcd_ui.thing_to_move1) != 225)
        {
            anim_selected(lcd_ui.thing_to_move1, 25);
        }
        if (lv_obj_get_x(lcd_ui.thing_to_move4) == 225)
        {
            anim_selected(lcd_ui.thing_to_move4, -25);
        }
    }
}

From LVGL.Simulator.cpp

lv_ui lcd_ui;

int main()
{
    lv_init();

    if (!lv_win32_init(
        GetModuleHandleW(NULL),
        SW_SHOW,
        1024,
        600,
        LoadIconW(GetModuleHandleW(NULL), MAKEINTRESOURCE(IDI_LVGL))))
    {
        return -1;
    }

    lv_win32_add_all_input_devices_to_group(NULL);

    setup_ui(&lcd_ui);

// ----------------------------------
// Task handler loop
// ----------------------------------

    while (!lv_win32_quit_signal)
    {
        lv_task_handler();
        Sleep(1);
    }

    return 0;
}

Screenshot and/or video

If possible, add screenshots and/or videos about the current state.