diff --git a/examples/scroll/lv_example_scroll_2.c b/examples/scroll/lv_example_scroll_2.c index de673c156..8a2c45c91 100644 --- a/examples/scroll/lv_example_scroll_2.c +++ b/examples/scroll/lv_example_scroll_2.c @@ -18,12 +18,13 @@ void lv_example_scroll_2(void) { lv_obj_t * list = lv_obj_create(lv_scr_act(), NULL); lv_obj_set_size(list, 280, 150); - lv_obj_set_scroll_snap_align_x(list, LV_SCROLL_SNAP_ALIGN_CENTER); + lv_obj_set_scroll_snap_x(list, LV_SCROLL_SNAP_CENTER); lv_obj_set_layout(list, &lv_flex_queue); uint32_t i; for(i = 0; i < 10; i++) { lv_obj_t * btn = lv_btn_create(list, NULL); + lv_obj_clear_flag(btn, LV_OBJ_FLAG_SCROLL_ON_FOCUS); /* It does similar thing than snapping so disable it.*/ lv_obj_set_size(btn, 150, 100); lv_obj_t * label = lv_label_create(btn, NULL); diff --git a/examples/widgets/btnmatrix/lv_example_btnmatrix_2.c b/examples/widgets/btnmatrix/lv_example_btnmatrix_2.c index f2cdc9f2c..44db12d84 100644 --- a/examples/widgets/btnmatrix/lv_example_btnmatrix_2.c +++ b/examples/widgets/btnmatrix/lv_example_btnmatrix_2.c @@ -10,7 +10,7 @@ static void event_cb(lv_obj_t * obj, lv_event_t e) /*Change the draw descriptor the 2nd button */ if(dsc->id == 1) { dsc->rect_dsc->radius = 0; - if(lv_btnmatrix_get_pressed_btn(obj) == dsc->id) dsc->rect_dsc->bg_color = lv_color_blue_darken_3(); + if(lv_btnmatrix_get_active_btn(obj) == dsc->id) dsc->rect_dsc->bg_color = lv_color_blue_darken_3(); else dsc->rect_dsc->bg_color = lv_color_blue(); dsc->rect_dsc->shadow_width = 6; @@ -21,7 +21,7 @@ static void event_cb(lv_obj_t * obj, lv_event_t e) /*Change the draw descriptor the 3rd button */ else if(dsc->id == 2) { dsc->rect_dsc->radius = LV_RADIUS_CIRCLE; - if(lv_btnmatrix_get_pressed_btn(obj) == dsc->id) dsc->rect_dsc->bg_color = lv_color_red_darken_3(); + if(lv_btnmatrix_get_active_btn(obj) == dsc->id) dsc->rect_dsc->bg_color = lv_color_red_darken_3(); else dsc->rect_dsc->bg_color = lv_color_red(); dsc->label_dsc->color = lv_color_white(); @@ -50,7 +50,7 @@ static void event_cb(lv_obj_t * obj, lv_event_t e) lv_draw_img_dsc_t img_draw_dsc; lv_draw_img_dsc_init(&img_draw_dsc); img_draw_dsc.recolor = lv_color_black(); - if(lv_btnmatrix_get_pressed_btn(obj) == dsc->id) img_draw_dsc.recolor_opa = LV_OPA_30; + if(lv_btnmatrix_get_active_btn(obj) == dsc->id) img_draw_dsc.recolor_opa = LV_OPA_30; lv_draw_img(&a, dsc->clip_area, &img_star, &img_draw_dsc); } diff --git a/examples/widgets/calendar/lv_example_calendar_1.c b/examples/widgets/calendar/lv_example_calendar_1.c index e39728cfe..731fbed41 100644 --- a/examples/widgets/calendar/lv_example_calendar_1.c +++ b/examples/widgets/calendar/lv_example_calendar_1.c @@ -6,7 +6,7 @@ static void event_handler(lv_obj_t * obj, lv_event_t event) if(event == LV_EVENT_VALUE_CHANGED) { lv_calendar_date_t date; if(lv_calendar_get_pressed_date(obj, &date)) { - LV_LOG_USER("Clicked date: %02d.%02d.%d\n", date.day, date.month, date.year); + LV_LOG_USER("Clicked date: %02d.%02d.%d", date.day, date.month, date.year); } } } @@ -14,8 +14,8 @@ static void event_handler(lv_obj_t * obj, lv_event_t event) void lv_example_calendar_1(void) { lv_obj_t * calendar = lv_calendar_create(lv_scr_act()); - lv_obj_set_size(calendar, 180, 180); - lv_obj_align(calendar, NULL, LV_ALIGN_CENTER, 0, 0); + lv_obj_set_size(calendar, 200, 200); + lv_obj_align(calendar, NULL, LV_ALIGN_CENTER, 0, 20); lv_obj_add_event_cb(calendar, event_handler, NULL); /*Set today's date*/ @@ -29,16 +29,16 @@ void lv_example_calendar_1(void) /*Highlight a few days*/ static lv_calendar_date_t highlighted_days[3]; /*Only its pointer will be saved so should be static*/ - highlighted_days[0].year = 2020; - highlighted_days[0].month = 10; + highlighted_days[0].year = 2021; + highlighted_days[0].month = 02; highlighted_days[0].day = 6; - highlighted_days[1].year = 2020; - highlighted_days[1].month = 10; + highlighted_days[1].year = 2021; + highlighted_days[1].month = 02; highlighted_days[1].day = 11; - highlighted_days[2].year = 2020; - highlighted_days[2].month = 11; + highlighted_days[2].year = 2022; + highlighted_days[2].month = 02; highlighted_days[2].day = 22; lv_calendar_set_highlighted_dates(calendar, highlighted_days, 3); diff --git a/examples/widgets/meter/lv_example_meter_4.c b/examples/widgets/meter/lv_example_meter_4.c index 6f9a67765..6c5bf0aa8 100644 --- a/examples/widgets/meter/lv_example_meter_4.c +++ b/examples/widgets/meter/lv_example_meter_4.c @@ -24,11 +24,11 @@ void lv_example_meter_4(void) lv_meter_set_indicator_start_value(meter, indic1, 0); lv_meter_set_indicator_end_value(meter, indic1, 40); - lv_meter_indicator_t * indic2 = lv_meter_add_arc(meter, scale, indic_w, lv_color_green(), 0); + lv_meter_indicator_t * indic2 = lv_meter_add_arc(meter, scale, indic_w, lv_color_yellow(), 0); lv_meter_set_indicator_start_value(meter, indic2, 40); /*Start from the previous*/ lv_meter_set_indicator_end_value(meter, indic2, 80); - lv_meter_indicator_t * indic3 = lv_meter_add_arc(meter, scale, indic_w, lv_color_blue(), 0); + lv_meter_indicator_t * indic3 = lv_meter_add_arc(meter, scale, indic_w, lv_color_deep_orange(), 0); lv_meter_set_indicator_start_value(meter, indic3, 80); /*Start from the previous*/ lv_meter_set_indicator_end_value(meter, indic3, 100); } diff --git a/examples/widgets/table/lv_example_table_2.c b/examples/widgets/table/lv_example_table_2.c new file mode 100644 index 000000000..8176314d7 --- /dev/null +++ b/examples/widgets/table/lv_example_table_2.c @@ -0,0 +1,74 @@ +#include "../../../lvgl.h" +#if LV_USE_TABLE && LV_BUILD_EXAMPLES + +#define ITEM_CNT 200 + +static void event_cb(lv_obj_t * obj, lv_event_t e) +{ + if(e == LV_EVENT_DRAW_PART_END) { + lv_obj_draw_hook_dsc_t * hook_dsc = lv_event_get_param(); + /*If the cells are drawn...*/ + if(hook_dsc->part == LV_PART_ITEMS) { + uint32_t row = hook_dsc->id; + + /*Make the texts in the first cell center aligned*/ + if(row == 0) { + hook_dsc->label_dsc->align = LV_TEXT_ALIGN_CENTER; + hook_dsc->rect_dsc->bg_color = lv_color_mix(lv_color_blue(), hook_dsc->rect_dsc->bg_color, LV_OPA_20); + hook_dsc->rect_dsc->bg_opa = LV_OPA_COVER; + } + + /*Make every 2nd row grayish*/ + if((row != 0 && row % 2) == 0) { + hook_dsc->rect_dsc->bg_color = lv_color_mix(lv_color_grey(), hook_dsc->rect_dsc->bg_color, LV_OPA_10); + hook_dsc->rect_dsc->bg_opa = LV_OPA_COVER; + } + } + } +} + + +/** + * A very light-weighted list created from table + */ +void lv_example_table_2(void) +{ + /*Measure memory usage*/ + lv_mem_monitor_t mon1; + lv_mem_monitor(&mon1); + + uint32_t t = lv_tick_get(); + + lv_obj_t * table = lv_table_create(lv_scr_act(), NULL); + lv_table_set_row_cnt(table, ITEM_CNT); /*Not required but avoids a lot of memory reallocation lv_table_set_set_value */ + lv_table_set_col_cnt(table, 1); + + uint32_t i; + for(i = 0; i < ITEM_CNT; i++) { + lv_table_set_cell_value_fmt(table, i, 0, "Item %d", i + 1); + } + + /*Set a smaller height to the table. It'll make it scrollable*/ + lv_obj_set_height(table, 200); + lv_obj_align(table, NULL, LV_ALIGN_CENTER, 0, -20); + + /*Add an event callback to to apply some custom drawing*/ +// lv_obj_add_event_cb(table, event_cb, NULL); + + lv_mem_monitor_t mon2; + lv_mem_monitor(&mon2); + + uint32_t mem_used = mon1.free_size - mon2.free_size; + + uint32_t elaps = lv_tick_elaps(t); + + lv_obj_t * label = lv_label_create(lv_scr_act(), NULL); + lv_label_set_text_fmt(label, "%d bytes are used by the table\n" + "and %d items were added in %d ms", + mem_used, ITEM_CNT, elaps); + + lv_obj_align(label, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, -10); + +} + +#endif diff --git a/src/extra/themes/default/lv_theme_default.c b/src/extra/themes/default/lv_theme_default.c index d30203209..613393795 100644 --- a/src/extra/themes/default/lv_theme_default.c +++ b/src/extra/themes/default/lv_theme_default.c @@ -623,9 +623,11 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) } #endif lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card); + lv_obj_add_style(obj, LV_PART_MAIN, LV_STATE_FOCUS_KEY, &styles->focus_outline); lv_obj_add_style(obj, LV_PART_ITEMS, LV_STATE_DEFAULT, &styles->btn); lv_obj_add_style(obj, LV_PART_ITEMS, LV_STATE_PRESSED, &styles->pressed); lv_obj_add_style(obj, LV_PART_ITEMS, LV_STATE_CHECKED, &styles->bg_color_primary); + lv_obj_add_style(obj, LV_PART_ITEMS, LV_STATE_FOCUS_KEY, &styles->focus_outline); } #endif @@ -805,7 +807,7 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) lv_obj_add_style(obj, LV_PART_ITEMS, LV_STATE_DEFAULT, &styles->calendar_day); lv_obj_add_style(obj, LV_PART_ITEMS, LV_STATE_PRESSED, &styles->pressed); lv_obj_add_style(obj, LV_PART_ITEMS, LV_STATE_DISABLED, &styles->disabled); - lv_obj_add_style(obj, LV_PART_ITEMS, LV_STATE_FOCUSED, &styles->focus_outline); + lv_obj_add_style(obj, LV_PART_ITEMS, LV_STATE_FOCUS_KEY, &styles->focus_outline); } #endif diff --git a/src/extra/widgets/calendar/lv_calendar.c b/src/extra/widgets/calendar/lv_calendar.c index aa311b40f..e67c8209f 100644 --- a/src/extra/widgets/calendar/lv_calendar.c +++ b/src/extra/widgets/calendar/lv_calendar.c @@ -273,7 +273,7 @@ static void draw_event_cb(lv_obj_t * obj, lv_event_t e) if(lv_btnmatrix_has_btn_ctrl(obj, hook_dsc->id, LV_CALENDAR_CTRL_HIGHLIGHT)) { hook_dsc->rect_dsc->bg_opa = LV_OPA_40; hook_dsc->rect_dsc->bg_color = lv_theme_get_color_primary(); - if(lv_btnmatrix_get_pressed_btn(obj) == hook_dsc->id) { + if(lv_btnmatrix_get_active_btn(obj) == hook_dsc->id) { hook_dsc->rect_dsc->bg_opa = LV_OPA_70; } } diff --git a/src/extra/widgets/msgbox/lv_msgbox.c b/src/extra/widgets/msgbox/lv_msgbox.c index 968f32d25..870821c79 100644 --- a/src/extra/widgets/msgbox/lv_msgbox.c +++ b/src/extra/widgets/msgbox/lv_msgbox.c @@ -87,6 +87,7 @@ lv_obj_t * lv_msgbox_create(const char * title, const char * txt, const char * b lv_obj_t * btns = lv_btnmatrix_create(mbox, NULL); lv_btnmatrix_set_map(btns, btn_txts); + lv_btnmatrix_set_btn_ctrl_all(btns, LV_BTNMATRIX_CTRL_CLICK_TRIG | LV_BTNMATRIX_CTRL_NO_REPEAT); uint32_t btn_cnt = 0; while(btn_txts[btn_cnt][0] != '\0') { diff --git a/src/lv_widgets/lv_btnmatrix.c b/src/lv_widgets/lv_btnmatrix.c index d48caa7de..9e426ea03 100644 --- a/src/lv_widgets/lv_btnmatrix.c +++ b/src/lv_widgets/lv_btnmatrix.c @@ -181,7 +181,7 @@ void lv_btnmatrix_set_ctrl_map(lv_obj_t * obj, const lv_btnmatrix_ctrl_t ctrl_ma lv_btnmatrix_set_map(obj, btnm->map_p); } -void lv_btnmatrix_set_focused_btn(lv_obj_t * obj, uint16_t id) +void lv_btnmatrix_set_active_btn(lv_obj_t * obj, uint16_t id) { LV_ASSERT_OBJ(obj, MY_CLASS); @@ -189,12 +189,9 @@ void lv_btnmatrix_set_focused_btn(lv_obj_t * obj, uint16_t id) if(id >= btnm->btn_cnt && id != LV_BTNMATRIX_BTN_NONE) return; - if(btnm->btn_id_act == LV_BTNMATRIX_BTN_NONE) btnm->btn_id_act = id; - - if(id == btnm->btn_id_focused) return; - - btnm->btn_id_focused = id; - lv_obj_invalidate(obj); + invalidate_button_area(obj, btnm->btn_id_act); + btnm->btn_id_act = id; + invalidate_button_area(obj, id); } void lv_btnmatrix_set_recolor(const lv_obj_t * obj, bool en) @@ -309,23 +306,6 @@ uint16_t lv_btnmatrix_get_active_btn(const lv_obj_t * obj) return btnm->btn_id_act; } -uint16_t lv_btnmatrix_get_pressed_btn(const lv_obj_t * obj) -{ - LV_ASSERT_OBJ(obj, MY_CLASS); - - lv_btnmatrix_t * btnm = (lv_btnmatrix_t *)obj;; - return btnm->btn_id_pr; -} - - -uint16_t lv_btnmatrix_get_focused_btn(const lv_obj_t * obj) -{ - LV_ASSERT_OBJ(obj, MY_CLASS); - - lv_btnmatrix_t * btnm = (lv_btnmatrix_t *)obj;; - return btnm->btn_id_focused; -} - const char * lv_btnmatrix_get_btn_text(const lv_obj_t * obj, uint16_t btn_id) { LV_ASSERT_OBJ(obj, MY_CLASS); @@ -378,8 +358,6 @@ static void lv_btnmatrix_constructor(lv_obj_t * obj, const lv_obj_t * copy) { lv_btnmatrix_t * btnm = (lv_btnmatrix_t *)obj; btnm->btn_cnt = 0; - btnm->btn_id_pr = LV_BTNMATRIX_BTN_NONE; - btnm->btn_id_focused = LV_BTNMATRIX_BTN_NONE; btnm->btn_id_act = LV_BTNMATRIX_BTN_NONE; btnm->button_areas = NULL; btnm->ctrl_bits = NULL; @@ -437,18 +415,18 @@ static lv_draw_res_t lv_btnmatrix_draw(lv_obj_t * obj, const lv_area_t * clip_ar lv_draw_rect_dsc_t draw_rect_dsc_act; lv_draw_label_dsc_t draw_label_dsc_act; - lv_draw_rect_dsc_t draw_rect_def_default; - lv_draw_label_dsc_t draw_label_def_default; + lv_draw_rect_dsc_t draw_rect_dsc_def; + lv_draw_label_dsc_t draw_label_dsc_def; lv_text_flag_t recolor_flag = btnm->recolor ? LV_TEXT_FLAG_RECOLOR : 0; lv_state_t state_ori = obj->state; obj->state = LV_STATE_DEFAULT; obj->style_list.skip_trans = 1; - lv_draw_rect_dsc_init(&draw_rect_def_default); - lv_draw_label_dsc_init(&draw_label_def_default); - lv_obj_init_draw_rect_dsc(obj, LV_PART_ITEMS, &draw_rect_def_default); - lv_obj_init_draw_label_dsc(obj, LV_PART_ITEMS, &draw_label_def_default); + lv_draw_rect_dsc_init(&draw_rect_dsc_def); + lv_draw_label_dsc_init(&draw_label_dsc_def); + lv_obj_init_draw_rect_dsc(obj, LV_PART_ITEMS, &draw_rect_dsc_def); + lv_obj_init_draw_label_dsc(obj, LV_PART_ITEMS, &draw_label_dsc_def); draw_label_dsc_act.flag |= recolor_flag; obj->style_list.skip_trans = 0; obj->state = state_ori; @@ -482,9 +460,10 @@ static lv_draw_res_t lv_btnmatrix_draw(lv_obj_t * obj, const lv_area_t * clip_ar lv_state_t btn_state = LV_STATE_DEFAULT; if(button_get_checked(btnm->ctrl_bits[btn_i])) btn_state |= LV_STATE_CHECKED; if(button_is_inactive(btnm->ctrl_bits[btn_i])) btn_state |= LV_STATE_DISABLED; - if(btn_i == btnm->btn_id_pr) btn_state |= LV_STATE_PRESSED; - if(btn_i == btnm->btn_id_focused) { - btn_state |= LV_STATE_FOCUSED; + if(btn_i == btnm->btn_id_act) { + if(state_ori & LV_STATE_PRESSED) btn_state |= LV_STATE_PRESSED; + if(state_ori & LV_STATE_FOCUSED) btn_state |= LV_STATE_FOCUSED; + if(state_ori & LV_STATE_FOCUS_KEY) btn_state |= LV_STATE_FOCUS_KEY; if(state_ori & LV_STATE_EDITED) btn_state |= LV_STATE_EDITED; } @@ -497,8 +476,8 @@ static lv_draw_res_t lv_btnmatrix_draw(lv_obj_t * obj, const lv_area_t * clip_ar /*Set up the draw descriptors*/ if(btn_state == LV_STATE_DEFAULT) { - lv_memcpy(&draw_rect_dsc_act, &draw_rect_def_default, sizeof(lv_draw_rect_dsc_t)); - lv_memcpy(&draw_label_dsc_act, &draw_label_def_default, sizeof(lv_draw_label_dsc_t)); + lv_memcpy(&draw_rect_dsc_act, &draw_rect_dsc_def, sizeof(lv_draw_rect_dsc_t)); + lv_memcpy(&draw_label_dsc_act, &draw_label_dsc_def, sizeof(lv_draw_label_dsc_t)); } /*In other cases get the styles directly without caching them*/ else { @@ -593,7 +572,7 @@ static lv_res_t lv_btnmatrix_signal(lv_obj_t * obj, lv_signal_t sign, void * par } } else if(sign == LV_SIGNAL_PRESSED) { - invalidate_button_area(obj, btnm->btn_id_pr); + invalidate_button_area(obj, btnm->btn_id_act); lv_indev_type_t indev_type = lv_indev_get_type(lv_indev_get_act()); if(indev_type == LV_INDEV_TYPE_POINTER || indev_type == LV_INDEV_TYPE_BUTTON) { @@ -605,25 +584,19 @@ static lv_res_t lv_btnmatrix_signal(lv_obj_t * obj, lv_signal_t sign, void * par if(btn_pr != LV_BTNMATRIX_BTN_NONE) { if(button_is_inactive(btnm->ctrl_bits[btn_pr]) == false && button_is_hidden(btnm->ctrl_bits[btn_pr]) == false) { - invalidate_button_area(obj, btnm->btn_id_pr) /*Invalidate the old area*/; - btnm->btn_id_pr = btn_pr; btnm->btn_id_act = btn_pr; - invalidate_button_area(obj, btnm->btn_id_pr); /*Invalidate the new area*/ + invalidate_button_area(obj, btnm->btn_id_act); /*Invalidate the new area*/ } } } - else if(indev_type == LV_INDEV_TYPE_KEYPAD || (indev_type == LV_INDEV_TYPE_ENCODER && - lv_group_get_editing(lv_obj_get_group(obj)))) { - btnm->btn_id_pr = btnm->btn_id_focused; - invalidate_button_area(obj, btnm->btn_id_focused); - } - if(btnm->btn_id_pr != LV_BTNMATRIX_BTN_NONE) { - if(button_is_click_trig(btnm->ctrl_bits[btnm->btn_id_pr]) == false && - button_is_inactive(btnm->ctrl_bits[btnm->btn_id_pr]) == false && - button_is_hidden(btnm->ctrl_bits[btnm->btn_id_pr]) == false) { - uint32_t b = btnm->btn_id_pr; + if(btnm->btn_id_act != LV_BTNMATRIX_BTN_NONE) { + if(button_is_click_trig(btnm->ctrl_bits[btnm->btn_id_act]) == false && + button_is_inactive(btnm->ctrl_bits[btnm->btn_id_act]) == false && + button_is_hidden(btnm->ctrl_bits[btnm->btn_id_act]) == false) { + uint32_t b = btnm->btn_id_act; res = lv_event_send(obj, LV_EVENT_VALUE_CHANGED, &b); + if(res != LV_RES_OK) return res; } } } @@ -637,12 +610,11 @@ static lv_res_t lv_btnmatrix_signal(lv_obj_t * obj, lv_signal_t sign, void * par lv_indev_get_point(indev, &p); btn_pr = get_button_from_point(obj, &p); /*Invalidate to old and the new areas*/ - if(btn_pr != btnm->btn_id_pr) { - if(btnm->btn_id_pr != LV_BTNMATRIX_BTN_NONE) { - invalidate_button_area(obj, btnm->btn_id_pr); + if(btn_pr != btnm->btn_id_act) { + if(btnm->btn_id_act != LV_BTNMATRIX_BTN_NONE) { + invalidate_button_area(obj, btnm->btn_id_act); } - btnm->btn_id_pr = btn_pr; btnm->btn_id_act = btn_pr; lv_indev_reset_long_press(param); /*Start the log press time again on the new button*/ @@ -653,43 +625,43 @@ static lv_res_t lv_btnmatrix_signal(lv_obj_t * obj, lv_signal_t sign, void * par /* Send VALUE_CHANGED for the newly pressed button */ if(button_is_click_trig(btnm->ctrl_bits[btn_pr]) == false) { uint32_t b = btn_pr; - lv_event_send(obj, LV_EVENT_VALUE_CHANGED, &b); + res = lv_event_send(obj, LV_EVENT_VALUE_CHANGED, &b); + if(res != LV_RES_OK) return res; } } } } else if(sign == LV_SIGNAL_RELEASED) { - if(btnm->btn_id_pr != LV_BTNMATRIX_BTN_NONE) { + if(btnm->btn_id_act != LV_BTNMATRIX_BTN_NONE) { /*Toggle the button if enabled*/ - if(button_is_tgl_enabled(btnm->ctrl_bits[btnm->btn_id_pr]) && - !button_is_inactive(btnm->ctrl_bits[btnm->btn_id_pr])) { - if(button_get_checked(btnm->ctrl_bits[btnm->btn_id_pr]) && !btnm->one_check) { - btnm->ctrl_bits[btnm->btn_id_pr] &= (~LV_BTNMATRIX_CTRL_CHECKED); + if(button_is_tgl_enabled(btnm->ctrl_bits[btnm->btn_id_act]) && + !button_is_inactive(btnm->ctrl_bits[btnm->btn_id_act])) { + if(button_get_checked(btnm->ctrl_bits[btnm->btn_id_act]) && !btnm->one_check) { + btnm->ctrl_bits[btnm->btn_id_act] &= (~LV_BTNMATRIX_CTRL_CHECKED); } else { - btnm->ctrl_bits[btnm->btn_id_pr] |= LV_BTNMATRIX_CTRL_CHECKED; + btnm->ctrl_bits[btnm->btn_id_act] |= LV_BTNMATRIX_CTRL_CHECKED; } - if(btnm->one_check) make_one_button_checked(obj, btnm->btn_id_pr); + if(btnm->one_check) make_one_button_checked(obj, btnm->btn_id_act); } - /*Invalidate to old pressed area*/; - invalidate_button_area(obj, btnm->btn_id_pr); - invalidate_button_area(obj, btnm->btn_id_focused); - - lv_indev_type_t indev_type = lv_indev_get_type(lv_indev_get_act()); - if(indev_type == LV_INDEV_TYPE_KEYPAD || indev_type == LV_INDEV_TYPE_ENCODER) { - btnm->btn_id_focused = btnm->btn_id_pr; - } - - btnm->btn_id_pr = LV_BTNMATRIX_BTN_NONE; if(button_is_click_trig(btnm->ctrl_bits[btnm->btn_id_act]) == true && button_is_inactive(btnm->ctrl_bits[btnm->btn_id_act]) == false && button_is_hidden(btnm->ctrl_bits[btnm->btn_id_act]) == false) { uint32_t b = btnm->btn_id_act; res = lv_event_send(obj, LV_EVENT_VALUE_CHANGED, &b); + if(res != LV_RES_OK) return res; } } + + /*Invalidate to old pressed area*/; + invalidate_button_area(obj, btnm->btn_id_act); + + lv_indev_type_t indev_type = lv_indev_get_type(lv_indev_get_act()); + if(indev_type == LV_INDEV_TYPE_POINTER || indev_type == LV_INDEV_TYPE_BUTTON) { + btnm->btn_id_act = LV_BTNMATRIX_BTN_NONE; + } } else if(sign == LV_SIGNAL_LONG_PRESS_REP) { if(btnm->btn_id_act != LV_BTNMATRIX_BTN_NONE) { @@ -698,13 +670,13 @@ static lv_res_t lv_btnmatrix_signal(lv_obj_t * obj, lv_signal_t sign, void * par button_is_hidden(btnm->ctrl_bits[btnm->btn_id_act]) == false) { uint32_t b = btnm->btn_id_act; res = lv_event_send(obj, LV_EVENT_VALUE_CHANGED, &b); + if(res != LV_RES_OK) return res; } } } else if(sign == LV_SIGNAL_PRESS_LOST) { - btnm->btn_id_pr = LV_BTNMATRIX_BTN_NONE; + invalidate_button_area(obj, btnm->btn_id_act); btnm->btn_id_act = LV_BTNMATRIX_BTN_NONE; - lv_obj_invalidate(obj); } else if(sign == LV_SIGNAL_FOCUS) { lv_indev_t * indev = lv_indev_get_act(); @@ -721,11 +693,10 @@ static lv_res_t lv_btnmatrix_signal(lv_obj_t * obj, lv_signal_t sign, void * par if(lv_group_get_editing(lv_obj_get_group(obj))) { uint32_t b = 0; while(button_is_hidden(btnm->ctrl_bits[b]) || button_is_inactive(btnm->ctrl_bits[b])) b++; - btnm->btn_id_focused = b; btnm->btn_id_act = b; } else { - btnm->btn_id_focused = LV_BTNMATRIX_BTN_NONE; + btnm->btn_id_act = LV_BTNMATRIX_BTN_NONE; } } else if(indev_type == LV_INDEV_TYPE_KEYPAD) { @@ -733,57 +704,54 @@ static lv_res_t lv_btnmatrix_signal(lv_obj_t * obj, lv_signal_t sign, void * par while(button_is_hidden(btnm->ctrl_bits[b]) || button_is_inactive(btnm->ctrl_bits[b])) { b++; } - btnm->btn_id_focused = b; btnm->btn_id_act = b; } } else if(sign == LV_SIGNAL_DEFOCUS || sign == LV_SIGNAL_LEAVE) { - if(btnm->btn_id_focused != LV_BTNMATRIX_BTN_NONE) invalidate_button_area(obj, btnm->btn_id_focused); - if(btnm->btn_id_pr != LV_BTNMATRIX_BTN_NONE) invalidate_button_area(obj, btnm->btn_id_pr); - btnm->btn_id_focused = LV_BTNMATRIX_BTN_NONE; - btnm->btn_id_pr = LV_BTNMATRIX_BTN_NONE; + if(btnm->btn_id_act != LV_BTNMATRIX_BTN_NONE) invalidate_button_area(obj, btnm->btn_id_act); btnm->btn_id_act = LV_BTNMATRIX_BTN_NONE; } else if(sign == LV_SIGNAL_CONTROL) { + + invalidate_button_area(obj, btnm->btn_id_act); + char c = *((char *)param); if(c == LV_KEY_RIGHT) { - if(btnm->btn_id_focused == LV_BTNMATRIX_BTN_NONE) btnm->btn_id_focused = 0; - else btnm->btn_id_focused++; - if(btnm->btn_id_focused >= btnm->btn_cnt) btnm->btn_id_focused = 0; + if(btnm->btn_id_act == LV_BTNMATRIX_BTN_NONE) btnm->btn_id_act = 0; + else btnm->btn_id_act++; + if(btnm->btn_id_act >= btnm->btn_cnt) btnm->btn_id_act = 0; - while(button_is_hidden(btnm->ctrl_bits[btnm->btn_id_focused]) || button_is_inactive(btnm->ctrl_bits[btnm->btn_id_focused])) { - btnm->btn_id_focused++; - if(btnm->btn_id_focused >= btnm->btn_cnt) btnm->btn_id_focused = 0; + while(button_is_hidden(btnm->ctrl_bits[btnm->btn_id_act]) || button_is_inactive(btnm->ctrl_bits[btnm->btn_id_act])) { + btnm->btn_id_act++; + if(btnm->btn_id_act >= btnm->btn_cnt) btnm->btn_id_act = 0; } - - btnm->btn_id_act = btnm->btn_id_focused; - lv_obj_invalidate(obj); } else if(c == LV_KEY_LEFT) { - if(btnm->btn_id_focused == LV_BTNMATRIX_BTN_NONE) btnm->btn_id_focused = 0; - if(btnm->btn_id_focused > 0) btnm->btn_id_focused--; + if(btnm->btn_id_act == LV_BTNMATRIX_BTN_NONE) btnm->btn_id_act = 0; + if(btnm->btn_id_act > 0) btnm->btn_id_act--; - while(button_is_hidden(btnm->ctrl_bits[btnm->btn_id_focused]) || button_is_inactive(btnm->ctrl_bits[btnm->btn_id_focused])) { - if(btnm->btn_id_focused > 0) btnm->btn_id_focused--; - else btnm->btn_id_focused = btnm->btn_cnt - 1; + while(button_is_hidden(btnm->ctrl_bits[btnm->btn_id_act]) || button_is_inactive(btnm->ctrl_bits[btnm->btn_id_act])) { + if(btnm->btn_id_act > 0) btnm->btn_id_act--; + else btnm->btn_id_act = btnm->btn_cnt - 1; } - - btnm->btn_id_act = btnm->btn_id_focused; - lv_obj_invalidate(obj); } else if(c == LV_KEY_DOWN) { lv_coord_t col_gap = lv_obj_get_style_pad_column(obj, LV_PART_MAIN); /*Find the area below the the current*/ - if(btnm->btn_id_focused == LV_BTNMATRIX_BTN_NONE) { - btnm->btn_id_focused = 0; + if(btnm->btn_id_act == LV_BTNMATRIX_BTN_NONE) { + btnm->btn_id_act = 0; + while(button_is_hidden(btnm->ctrl_bits[btnm->btn_id_act]) || button_is_inactive(btnm->ctrl_bits[btnm->btn_id_act])) { + btnm->btn_id_act++; + if(btnm->btn_id_act >= btnm->btn_cnt) btnm->btn_id_act = 0; + } } else { uint16_t area_below; lv_coord_t pr_center = - btnm->button_areas[btnm->btn_id_focused].x1 + (lv_area_get_width(&btnm->button_areas[btnm->btn_id_focused]) >> 1); + btnm->button_areas[btnm->btn_id_act].x1 + (lv_area_get_width(&btnm->button_areas[btnm->btn_id_act]) >> 1); - for(area_below = btnm->btn_id_focused; area_below < btnm->btn_cnt; area_below++) { - if(btnm->button_areas[area_below].y1 > btnm->button_areas[btnm->btn_id_focused].y1 && + for(area_below = btnm->btn_id_act; area_below < btnm->btn_cnt; area_below++) { + if(btnm->button_areas[area_below].y1 > btnm->button_areas[btnm->btn_id_act].y1 && pr_center >= btnm->button_areas[area_below].x1 && pr_center <= btnm->button_areas[area_below].x2 + col_gap && button_is_inactive(btnm->ctrl_bits[area_below]) == false && @@ -792,24 +760,26 @@ static lv_res_t lv_btnmatrix_signal(lv_obj_t * obj, lv_signal_t sign, void * par } } - if(area_below < btnm->btn_cnt) btnm->btn_id_focused = area_below; + if(area_below < btnm->btn_cnt) btnm->btn_id_act = area_below; } - btnm->btn_id_act = btnm->btn_id_focused; - lv_obj_invalidate(obj); } else if(c == LV_KEY_UP) { lv_coord_t col_gap = lv_obj_get_style_pad_column(obj, LV_PART_MAIN); /*Find the area below the the current*/ - if(btnm->btn_id_focused == LV_BTNMATRIX_BTN_NONE) { - btnm->btn_id_focused = 0; + if(btnm->btn_id_act == LV_BTNMATRIX_BTN_NONE) { + btnm->btn_id_act = 0; + while(button_is_hidden(btnm->ctrl_bits[btnm->btn_id_act]) || button_is_inactive(btnm->ctrl_bits[btnm->btn_id_act])) { + btnm->btn_id_act++; + if(btnm->btn_id_act >= btnm->btn_cnt) btnm->btn_id_act = 0; + } } else { int16_t area_above; lv_coord_t pr_center = - btnm->button_areas[btnm->btn_id_focused].x1 + (lv_area_get_width(&btnm->button_areas[btnm->btn_id_focused]) >> 1); + btnm->button_areas[btnm->btn_id_act].x1 + (lv_area_get_width(&btnm->button_areas[btnm->btn_id_act]) >> 1); - for(area_above = btnm->btn_id_focused; area_above >= 0; area_above--) { - if(btnm->button_areas[area_above].y1 < btnm->button_areas[btnm->btn_id_focused].y1 && + for(area_above = btnm->btn_id_act; area_above >= 0; area_above--) { + if(btnm->button_areas[area_above].y1 < btnm->button_areas[btnm->btn_id_act].y1 && pr_center >= btnm->button_areas[area_above].x1 - col_gap && pr_center <= btnm->button_areas[area_above].x2 && button_is_inactive(btnm->ctrl_bits[area_above]) == false && @@ -817,11 +787,11 @@ static lv_res_t lv_btnmatrix_signal(lv_obj_t * obj, lv_signal_t sign, void * par break; } } - if(area_above >= 0) btnm->btn_id_focused = area_above; + if(area_above >= 0) btnm->btn_id_act = area_above; } - btnm->btn_id_act = btnm->btn_id_focused; - lv_obj_invalidate(obj); } + + invalidate_button_area(obj, btnm->btn_id_act); } return res; } @@ -979,11 +949,16 @@ static void invalidate_button_area(const lv_obj_t * obj, uint16_t btn_idx) lv_area_copy(&btn_area, &btnm->button_areas[btn_idx]); lv_obj_get_coords(obj, &obj_area); + /* The buttons might have outline and shadow so make the invalidation larger with the gaps between the buttons. + * It assumes that the outline or shadow is smaller then the gaps*/ + lv_coord_t row_gap = lv_obj_get_style_pad_row(obj, LV_PART_MAIN); + lv_coord_t col_gap = lv_obj_get_style_pad_column(obj, LV_PART_MAIN); + /* Convert relative coordinates to absolute */ - btn_area.x1 += obj_area.x1; - btn_area.y1 += obj_area.y1; - btn_area.x2 += obj_area.x1; - btn_area.y2 += obj_area.y1; + btn_area.x1 += obj_area.x1 - row_gap; + btn_area.y1 += obj_area.y1 - col_gap; + btn_area.x2 += obj_area.x1 + row_gap; + btn_area.y2 += obj_area.y1 + col_gap; lv_obj_invalidate_area(obj, &btn_area); } diff --git a/src/lv_widgets/lv_btnmatrix.h b/src/lv_widgets/lv_btnmatrix.h index afa165aa6..089300bc6 100644 --- a/src/lv_widgets/lv_btnmatrix.h +++ b/src/lv_widgets/lv_btnmatrix.h @@ -58,8 +58,6 @@ typedef struct { lv_area_t * button_areas; /*Array of areas of buttons*/ lv_btnmatrix_ctrl_t * ctrl_bits; /*Array of control bytes*/ uint16_t btn_cnt; /*Number of button in 'map_p'(Handled by the library)*/ - uint16_t btn_id_pr; /*Index of the currently pressed button or LV_BTNMATRIX_BTN_NONE*/ - uint16_t btn_id_focused; /*Index of the currently focused button or LV_BTNMATRIX_BTN_NONE*/ uint16_t btn_id_act; /*Index of the active button (being pressed/released etc) or LV_BTNMATRIX_BTN_NONE */ uint8_t recolor : 1; /*Enable button recoloring*/ uint8_t one_check : 1; /*Single button toggled at once*/ @@ -108,13 +106,6 @@ void lv_btnmatrix_set_map(lv_obj_t * obj, const char * map[]); */ void lv_btnmatrix_set_ctrl_map(lv_obj_t * obj, const lv_btnmatrix_ctrl_t ctrl_map[]); -/** - * Set the focused button i.e. visually highlight it. - * @param obj pointer to button matrix object - * @param id index of the button to focus(`LV_BTNMATRIX_BTN_NONE` to remove focus) - */ -void lv_btnmatrix_set_focused_btn(lv_obj_t * obj, uint16_t id); - /** * Enable recoloring of button's texts. E.g. "a #ff0000 red# word" * @param obj pointer to button matrix object @@ -191,33 +182,17 @@ const char ** lv_btnmatrix_get_map(const lv_obj_t * obj); bool lv_btnmatrix_get_recolor(const lv_obj_t * obj); /** - * Get the index of the lastly "activated" button by the user (pressed, released etc) + * Get the index of the lastly "activated" button by the user (pressed, released, focused etc) * Useful in the the `event_cb` to get the text of the button, check if hidden etc. * @param obj pointer to button matrix object * @return index of the last released button (LV_BTNMATRIX_BTN_NONE: if unset) */ uint16_t lv_btnmatrix_get_active_btn(const lv_obj_t * obj); -/** - * Get the index of the button being pressed button. - * Useful in the the `event_cb` to get the text of the button, check if hidden etc. - * @param obj pointer to button matrix object - * @return index of the last released button (LV_BTNMATRIX_BTN_NONE: if unset) - */ -uint16_t lv_btnmatrix_get_pressed_btn(const lv_obj_t * obj); - -/** - * Get the focused button's index. - * @param obj pointer to button matrix object - * @return index of the focused button (LV_BTNMATRIX_BTN_NONE: if unset) - */ -uint16_t lv_btnmatrix_get_focused_btn(const lv_obj_t * obj); - /** * Get the button's text * @param obj pointer to button matrix object * @param btn_id the index a button not counting new line characters. - * (The return value of lv_btnmatrix_get_active/pressed/released) * @return text of btn_index` button */ const char * lv_btnmatrix_get_btn_text(const lv_obj_t * obj, uint16_t btn_id);