1 #if LV_BUILD_TEST
2 #include "../lvgl.h"
3 
4 #include "unity/unity.h"
5 #include "lv_test_indev.h"
6 
7 static lv_obj_t * g_screen;
8 static lv_group_t * g_group;
9 static struct {
10     bool press_happened;
11     uint32_t key;
12     lv_obj_t * obj;
13 } g_key_data;
14 
setUp(void)15 void setUp(void)
16 {
17     g_screen = lv_screen_active();
18     g_group = lv_group_create();
19     g_key_data.press_happened = false;
20 }
21 
tearDown(void)22 void tearDown(void)
23 {
24     lv_obj_clean(g_screen);
25     lv_group_delete(g_group); /* also removes all indevs set to the group */
26 }
27 
key_event_cb(lv_event_t * e)28 static void key_event_cb(lv_event_t * e)
29 {
30     TEST_ASSERT_FALSE(g_key_data.press_happened);
31     g_key_data.press_happened = true;
32     g_key_data.key = *(uint32_t *)lv_event_get_param(e);
33     g_key_data.obj = lv_event_get_target_obj(e);
34 }
35 
gridnav_one_axis_move_only(uint32_t key_grid_axis_next,uint32_t key_grid_axis_prev,uint32_t key_obj_axis_next,uint32_t key_obj_axis_prev,lv_gridnav_ctrl_t gridnav_ctrl,lv_flex_flow_t flex_flow)36 static void gridnav_one_axis_move_only(uint32_t key_grid_axis_next,
37                                        uint32_t key_grid_axis_prev,
38                                        uint32_t key_obj_axis_next,
39                                        uint32_t key_obj_axis_prev,
40                                        lv_gridnav_ctrl_t gridnav_ctrl,
41                                        lv_flex_flow_t flex_flow)
42 {
43     lv_indev_set_group(lv_test_keypad_indev, g_group);
44 
45     lv_obj_t * cont = lv_obj_create(g_screen);
46     lv_obj_set_flex_flow(cont, flex_flow);
47     lv_obj_set_flex_align(cont, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
48     lv_obj_set_size(cont, lv_pct(100), lv_pct(100));
49     lv_obj_center(cont);
50     lv_gridnav_add(cont, gridnav_ctrl);
51     lv_group_add_obj(g_group, cont);
52     lv_obj_t * objs[3];
53     for(uint32_t i = 0; i < 3; i++) {
54         lv_obj_t * obj = lv_obj_create(cont);
55         lv_obj_create(obj); /* the obj needs a child to be focusable by gridnav */
56         lv_group_remove_obj(obj);
57         lv_obj_add_event_cb(obj, key_event_cb, LV_EVENT_KEY, NULL);
58         objs[i] = obj;
59     }
60 
61     TEST_ASSERT(lv_obj_get_state(objs[0]) & LV_STATE_FOCUSED);
62 
63     /* gridnav direction key moves the focus */
64     lv_test_key_hit(key_grid_axis_next);
65     TEST_ASSERT(lv_obj_get_state(objs[1]) & LV_STATE_FOCUSED);
66     TEST_ASSERT_FALSE(g_key_data.press_happened);
67 
68     /* non gridnav direction key does not move the focus. */
69     /* the key is sent to the object instead */
70     lv_test_key_hit(key_obj_axis_next);
71     TEST_ASSERT(lv_obj_get_state(objs[1]) & LV_STATE_FOCUSED);
72     TEST_ASSERT_TRUE(g_key_data.press_happened);
73     TEST_ASSERT(g_key_data.key == key_obj_axis_next);
74     TEST_ASSERT(g_key_data.obj == objs[1]);
75     g_key_data.press_happened = false;
76 
77     lv_test_key_hit(key_obj_axis_prev);
78     TEST_ASSERT(lv_obj_get_state(objs[1]) & LV_STATE_FOCUSED);
79     TEST_ASSERT_TRUE(g_key_data.press_happened);
80     TEST_ASSERT(g_key_data.key == key_obj_axis_prev);
81     TEST_ASSERT(g_key_data.obj == objs[1]);
82     g_key_data.press_happened = false;
83 
84     /* go back */
85     lv_test_key_hit(key_grid_axis_prev);
86     TEST_ASSERT(lv_obj_get_state(objs[0]) & LV_STATE_FOCUSED);
87     TEST_ASSERT_FALSE(g_key_data.press_happened);
88     /* at the beginning, can't move further back */
89     lv_test_key_hit(key_grid_axis_prev);
90     TEST_ASSERT(lv_obj_get_state(objs[0]) & LV_STATE_FOCUSED);
91     TEST_ASSERT_FALSE(g_key_data.press_happened);
92 }
93 
test_gridnav_vertical_move_only(void)94 void test_gridnav_vertical_move_only(void)
95 {
96     gridnav_one_axis_move_only(LV_KEY_DOWN,
97                                LV_KEY_UP,
98                                LV_KEY_RIGHT,
99                                LV_KEY_LEFT,
100                                LV_GRIDNAV_CTRL_VERTICAL_MOVE_ONLY,
101                                LV_FLEX_FLOW_COLUMN);
102 }
103 
test_gridnav_horizontal_move_only(void)104 void test_gridnav_horizontal_move_only(void)
105 {
106     gridnav_one_axis_move_only(LV_KEY_RIGHT,
107                                LV_KEY_LEFT,
108                                LV_KEY_DOWN,
109                                LV_KEY_UP,
110                                LV_GRIDNAV_CTRL_HORIZONTAL_MOVE_ONLY,
111                                LV_FLEX_FLOW_ROW);
112 }
113 
114 #endif
115