LVGL学习笔记1--buttonmatrix

代码前提:课程 3-7-3
已经实现内容显示

实现功能:在此基础上实现模拟点击功能(相当于外部硬件矩阵矩阵输入,显示同步更新)

问题描述:
通过一下定时器代码实现模拟点击功能

static void my_timer(lv_timer_t *time)
{
    lv_obj_t *butm = lv_timer_get_user_data(time);

    uint8_t value = lv_rand(0, 15);
    // LV_LOG_USER("value %d", value);

    // 2. 模拟点击,手动触发其回调
    lv_buttonmatrix_set_selected_button(butm, value); 
    lv_buttonmatrix_set_button_ctrl(butm, value, LV_BUTTONMATRIX_CTRL_CHECKABLE | LV_BUTTONMATRIX_CTRL_CHECKED);
    lv_obj_send_event(butm, LV_EVENT_VALUE_CHANGED, NULL);
    lv_obj_invalidate(butm);
}

但是,橙色背景的按键无法显示模拟按下状态的更新
如果还是不能理解问题,可以移植一下完整代码,对比最后两个宏定义的现象就明白了

PS:如果是统一颜色的按键背景不会有这个问题,但是目前是背景颜色不是统一的,橙色背景的绘制是通过LV_EVENT_DRAW_TASK_ADDED,修改后绘制的,这个课程里是有讲的,问题症结就在这里。

原因分析:

 if(lv_buttonmatrix_get_selected_button(obj) == base_dsc->id1 && lv_obj_has_state(obj, LV_STATE_PRESSED))

lv_obj_has_state无法进行判断

解决办法:增加用于判断模拟点击的变量,通过模拟点击的变量跳过判断

完整代码

#include "lv_demo_buttonmatrix.h"
static void butm_event_cb(lv_event_t *e);
static void my_timer(lv_timer_t *time);
static void my_timer1(lv_timer_t *time);

static const char *butm_map[] = {"1", "2", "3", "A", "\n",
                                 "4", "5", "6", "B", "\n",
                                 "7", "8", "9", "C", "\n",
                                 "*", "0", "#", "D",
                                 ""};

static int32_t simulated_pressed_btn = -1;//用于模拟点击

void lv_demo_buttonmatrix_create(lv_obj_t *parent)
{
#if 0
    static lv_style_t lv_style_butm_main;
    static lv_style_t lv_style_butm_itme;

    lv_style_init(&lv_style_butm_main);
    lv_style_init(&lv_style_butm_itme);
    lv_style_set_bg_color(&lv_style_butm_main, lv_color_hex(0x222222));

    lv_style_set_bg_color(&lv_style_butm_itme, lv_color_hex(0x61AFEF));
    lv_style_set_text_font(&lv_style_butm_itme, &lv_font_montserrat_40);
    lv_style_set_text_color(&lv_style_butm_itme, lv_color_hex(0xffffff));


    lv_obj_t *cont = lv_obj_create(parent);
    lv_obj_set_size(cont, 440, 440);
    lv_obj_set_scrollbar_mode(cont, LV_SCROLLBAR_MODE_OFF);
    lv_obj_clear_flag(cont,LV_OBJ_FLAG_SCROLLABLE);
    lv_obj_set_style_border_width(cont,0,LV_PART_MAIN);
    lv_obj_set_style_bg_color(cont,lv_color_hex(0x222222),LV_PART_MAIN);

    lv_obj_center(cont);

    lv_obj_t *butm = lv_buttonmatrix_create(cont);
    lv_obj_set_size(butm, 400, 400);
    lv_obj_add_style(butm, &lv_style_butm_main, LV_PART_MAIN);
    lv_obj_add_style(butm, &lv_style_butm_itme, LV_PART_ITEMS);

    lv_obj_add_event_cb(butm, butm_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
    lv_obj_add_event_cb(butm, butm_event_cb, LV_EVENT_DRAW_TASK_ADDED, NULL);
    lv_obj_add_flag(butm, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS);

    lv_buttonmatrix_set_map(butm, butm_map);
    lv_buttonmatrix_set_one_checked(butm, true);

    lv_obj_center(butm);
#elif 0
    static lv_style_t lv_style_butm_main;
    static lv_style_t lv_style_butm_itme;

    lv_style_init(&lv_style_butm_main);
    lv_style_init(&lv_style_butm_itme);
    lv_style_set_bg_color(&lv_style_butm_main, lv_color_hex(0x222222));

    lv_style_set_bg_color(&lv_style_butm_itme, lv_color_hex(0x61AFEF));
    lv_style_set_text_font(&lv_style_butm_itme, &lv_font_montserrat_40);
    lv_style_set_text_color(&lv_style_butm_itme, lv_color_hex(0xffffff));

    lv_obj_t *cont = lv_obj_create(parent);
    lv_obj_set_size(cont, 440, 440);
    lv_obj_set_scrollbar_mode(cont, LV_SCROLLBAR_MODE_OFF);
    lv_obj_clear_flag(cont, LV_OBJ_FLAG_SCROLLABLE);
    lv_obj_set_style_border_width(cont, 0, LV_PART_MAIN);
    lv_obj_set_style_bg_color(cont, lv_color_hex(0x222222), LV_PART_MAIN);

    lv_obj_center(cont);

    lv_obj_t *butm = lv_buttonmatrix_create(cont);
    lv_obj_set_size(butm, 400, 400);
    lv_obj_add_style(butm, &lv_style_butm_main, LV_PART_MAIN);
    lv_obj_add_style(butm, &lv_style_butm_itme, LV_PART_ITEMS);

    lv_obj_add_event_cb(butm, butm_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
    lv_obj_add_event_cb(butm, butm_event_cb, LV_EVENT_DRAW_TASK_ADDED, NULL);
    lv_obj_add_flag(butm, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS);

    lv_buttonmatrix_set_map(butm, butm_map);
    lv_buttonmatrix_set_one_checked(butm, true);

    lv_obj_center(butm);

    lv_timer_create(my_timer, 1000, butm);
#elif 1
    static lv_style_t lv_style_butm_main;
    static lv_style_t lv_style_butm_itme;

    lv_style_init(&lv_style_butm_main);
    lv_style_init(&lv_style_butm_itme);
    lv_style_set_bg_color(&lv_style_butm_main, lv_color_hex(0x222222));

    lv_style_set_bg_color(&lv_style_butm_itme, lv_color_hex(0x61AFEF));
    lv_style_set_text_font(&lv_style_butm_itme, &lv_font_montserrat_40);
    lv_style_set_text_color(&lv_style_butm_itme, lv_color_hex(0xffffff));

    lv_obj_t *cont = lv_obj_create(parent);
    lv_obj_set_size(cont, 440, 440);
    lv_obj_set_scrollbar_mode(cont, LV_SCROLLBAR_MODE_OFF);
    lv_obj_clear_flag(cont, LV_OBJ_FLAG_SCROLLABLE);
    lv_obj_set_style_border_width(cont, 0, LV_PART_MAIN);
    lv_obj_set_style_bg_color(cont, lv_color_hex(0x222222), LV_PART_MAIN);

    lv_obj_center(cont);

    lv_obj_t *butm = lv_buttonmatrix_create(cont);
    lv_obj_set_size(butm, 400, 400);
    lv_obj_add_style(butm, &lv_style_butm_main, LV_PART_MAIN);
    lv_obj_add_style(butm, &lv_style_butm_itme, LV_PART_ITEMS);

    lv_obj_add_event_cb(butm, butm_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
    lv_obj_add_event_cb(butm, butm_event_cb, LV_EVENT_DRAW_TASK_ADDED, NULL);
    lv_obj_add_flag(butm, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS);

    lv_buttonmatrix_set_map(butm, butm_map);
    lv_buttonmatrix_set_one_checked(butm, true);

    lv_obj_center(butm);

    lv_timer_create(my_timer1, 1000, butm);
#endif
}

static void butm_event_cb(lv_event_t *e)
{
    lv_event_code_t code = lv_event_get_code(e);
    if (code == LV_EVENT_VALUE_CHANGED)
    {
        lv_obj_t *butm = lv_event_get_target(e);
        uint32_t but_index = lv_buttonmatrix_get_selected_button(butm);
        const char *text = lv_buttonmatrix_get_button_text(butm, but_index);
        lv_buttonmatrix_set_button_ctrl(butm, but_index, LV_BUTTONMATRIX_CTRL_CHECKED);
        LV_LOG_USER("but_index=%d", but_index);
        LV_LOG_USER("text=%s", text);
    }

    if (code == LV_EVENT_DRAW_TASK_ADDED)
    {
        lv_obj_t *obj = lv_event_get_target(e);
        lv_draw_task_t *draw_task = lv_event_get_draw_task(e);
        lv_draw_dsc_base_t *base_dsc = lv_draw_task_get_draw_dsc(draw_task);

        if (base_dsc->part == LV_PART_ITEMS)
        {
            bool pressed = false;
            if (simulated_pressed_btn == base_dsc->id1)
            {
                pressed = true;
                // 可选:使用后立即清除,避免影响下一次重绘(如果有连续重绘)
                // simulated_pressed_btn = -1;
            }
            else if(lv_buttonmatrix_get_selected_button(obj) == base_dsc->id1 && lv_obj_has_state(obj, LV_STATE_PRESSED))
            {
                pressed = true;
                LV_LOG_USER("base_dsc->id1%d", base_dsc->id1);
                LV_LOG_USER("pressed %d", pressed);
            }

            if ((base_dsc->id1 == 3) ||
                (base_dsc->id1 == 7) ||
                (base_dsc->id1 == 11) ||
                (base_dsc->id1 == 12) ||
                (base_dsc->id1 == 14) ||
                (base_dsc->id1 == 15))
            {
                lv_draw_fill_dsc_t *fill_draw_dsc = lv_draw_task_get_fill_dsc(draw_task);
                if (fill_draw_dsc)
                {
                    // fill_draw_dsc->radius = LV_RADIUS_CIRCLE;
                    if (pressed)
                    {
                        fill_draw_dsc->color = lv_palette_darken(LV_PALETTE_ORANGE, 3);
                    }
                    else
                    {
                        fill_draw_dsc->color = lv_palette_main(LV_PALETTE_ORANGE);
                    }
                }
            }
        }
    }
}



static void my_timer(lv_timer_t *time)
{
    lv_obj_t *butm = lv_timer_get_user_data(time);

    uint8_t value = lv_rand(0, 15);
    // LV_LOG_USER("value %d", value);

    // 2. 模拟点击,手动触发其回调
    lv_buttonmatrix_set_selected_button(butm, value); 
    lv_buttonmatrix_set_button_ctrl(butm, value, LV_BUTTONMATRIX_CTRL_CHECKABLE | LV_BUTTONMATRIX_CTRL_CHECKED);
    lv_obj_send_event(butm, LV_EVENT_VALUE_CHANGED, NULL);
    lv_obj_invalidate(butm);
}



static void my_timer1(lv_timer_t *time)
{
    lv_obj_t *butm = lv_timer_get_user_data(time);

    uint8_t value = lv_rand(0, 15);
    // LV_LOG_USER("value %d", value);
    simulated_pressed_btn = value;

    // 2. 模拟点击,手动触发其回调
    lv_buttonmatrix_set_selected_button(butm, value); 
    lv_buttonmatrix_set_button_ctrl(butm, value, LV_BUTTONMATRIX_CTRL_CHECKABLE | LV_BUTTONMATRIX_CTRL_CHECKED);
    lv_obj_send_event(butm, LV_EVENT_VALUE_CHANGED, NULL);
    lv_obj_invalidate(butm);
}