1 #if LV_BUILD_TEST
2 #include "../lvgl.h"
3 
4 #include "unity/unity.h"
5 
6 static lv_obj_t * scr = NULL;
7 static lv_obj_t * table = NULL;
8 
setUp(void)9 void setUp(void)
10 {
11     scr = lv_scr_act();
12     table = lv_table_create(scr);
13 }
14 
tearDown(void)15 void tearDown(void)
16 {
17     lv_obj_clean(lv_scr_act());
18 }
19 
test_table_should_return_assigned_cell_value(void)20 void test_table_should_return_assigned_cell_value(void)
21 {
22     uint16_t row = 0;
23     uint16_t column = 0;
24     const char * value = "LVGL";
25 
26     lv_table_set_cell_value(table, row, column, value);
27 
28     TEST_ASSERT_EQUAL_STRING(value, lv_table_get_cell_value(table, row, column));
29 }
30 
test_table_should_grow_columns_automatically_when_setting_formatted_cell_value(void)31 void test_table_should_grow_columns_automatically_when_setting_formatted_cell_value(void)
32 {
33     /* Newly created tables have 1 column and 1 row */
34     uint16_t original_column_count = lv_table_get_col_cnt(table);
35     TEST_ASSERT_EQUAL_UINT16(1, original_column_count);
36 
37     /* Table currently only has a cell at 0,0 (row, colum) */
38     lv_table_set_cell_value_fmt(table, 0, 1, "LVGL %s", "Rocks!");
39 
40     /* Table now should have cells at 0,0 and 0,1, so 2 columns */
41     uint16_t expected_column_count = original_column_count + 1;
42     TEST_ASSERT_EQUAL_UINT16(expected_column_count, lv_table_get_col_cnt(table));
43 }
44 
test_table_should_identify_cell_with_ctrl(void)45 void test_table_should_identify_cell_with_ctrl(void)
46 {
47     bool has_ctrl = false;
48 
49     has_ctrl = lv_table_has_cell_ctrl(table, 0, 0, LV_TABLE_CELL_CTRL_MERGE_RIGHT);
50 
51     TEST_ASSERT_FALSE(has_ctrl);
52 
53     lv_table_add_cell_ctrl(table, 0, 0, LV_TABLE_CELL_CTRL_MERGE_RIGHT);
54     has_ctrl = lv_table_has_cell_ctrl(table, 0, 0, LV_TABLE_CELL_CTRL_MERGE_RIGHT);
55     TEST_ASSERT_TRUE(has_ctrl);
56 }
57 
test_table_should_clear_selected_cell_ctrl(void)58 void test_table_should_clear_selected_cell_ctrl(void)
59 {
60     bool has_ctrl = false;
61 
62     lv_table_add_cell_ctrl(table, 0, 0, LV_TABLE_CELL_CTRL_MERGE_RIGHT);
63     has_ctrl = lv_table_has_cell_ctrl(table, 0, 0, LV_TABLE_CELL_CTRL_MERGE_RIGHT);
64     TEST_ASSERT_TRUE(has_ctrl);
65 
66     lv_table_clear_cell_ctrl(table, 0, 0, LV_TABLE_CELL_CTRL_MERGE_RIGHT);
67     has_ctrl = lv_table_has_cell_ctrl(table, 0, 0, LV_TABLE_CELL_CTRL_MERGE_RIGHT);
68     TEST_ASSERT_FALSE(has_ctrl);
69 }
70 
test_table_should_keep_not_selected_cell_ctrl(void)71 void test_table_should_keep_not_selected_cell_ctrl(void)
72 {
73     bool has_ctrl = false;
74 
75     lv_table_add_cell_ctrl(table, 0, 0, LV_TABLE_CELL_CTRL_MERGE_RIGHT | LV_TABLE_CELL_CTRL_TEXT_CROP);
76 
77     lv_table_clear_cell_ctrl(table, 0, 0, LV_TABLE_CELL_CTRL_MERGE_RIGHT);
78     has_ctrl = lv_table_has_cell_ctrl(table, 0, 0, LV_TABLE_CELL_CTRL_MERGE_RIGHT);
79     TEST_ASSERT_FALSE(has_ctrl);
80 
81     has_ctrl = lv_table_has_cell_ctrl(table, 0, 0, LV_TABLE_CELL_CTRL_TEXT_CROP);
82     TEST_ASSERT_TRUE(has_ctrl);
83 }
84 
85 /* We're using a newly created table */
test_table_cell_value_should_return_empty_string_when_cell_is_empty(void)86 void test_table_cell_value_should_return_empty_string_when_cell_is_empty(void)
87 {
88     TEST_ASSERT_EQUAL_STRING("", lv_table_get_cell_value(table, 0, 0));
89 }
90 
test_table_row_height_should_increase_with_multiline_cell_value(void)91 void test_table_row_height_should_increase_with_multiline_cell_value(void)
92 {
93     lv_table_t * table_ptr = (lv_table_t *) table;
94     const char * singleline_value = "LVGL";
95     const char * multiline_value = "LVGL\nRocks";
96 
97     lv_table_set_cell_value(table, 0, 0, singleline_value);
98     lv_coord_t singleline_row_height = table_ptr->row_h[0];
99 
100     lv_table_set_cell_value(table, 0, 0, multiline_value);
101     lv_coord_t multiline_row_height = table_ptr->row_h[0];
102 
103     TEST_ASSERT_GREATER_THAN(singleline_row_height, multiline_row_height);
104 }
105 
test_table_should_wrap_long_texts(void)106 void test_table_should_wrap_long_texts(void)
107 {
108     lv_table_t * table_ptr = (lv_table_t *) table;
109     const char * long_text = "Testing automatic text wrap with a very long text";
110     const char * small_text = "Hi";
111 
112     lv_table_set_col_width(table, 0, 50);
113 
114     lv_table_set_cell_value(table, 0, 0, small_text);
115     lv_coord_t row_height = table_ptr->row_h[0];
116 
117     lv_table_set_cell_value(table, 0, 0, long_text);
118     lv_coord_t wrapped_row_height = table_ptr->row_h[0];
119 
120     /* Row height on cells with wrapped text is bigger than cells with small texts */
121     TEST_ASSERT_GREATER_THAN(row_height, wrapped_row_height);
122 }
123 
draw_part_event_cb(lv_event_t * e)124 static void draw_part_event_cb(lv_event_t * e)
125 {
126     lv_obj_t * obj = lv_event_get_target(e);
127     lv_obj_draw_part_dsc_t * dsc = lv_event_get_param(e);
128     /*If the cells are drawn...*/
129     if(dsc->part == LV_PART_ITEMS) {
130         uint32_t row = dsc->id /  lv_table_get_col_cnt(obj);
131         uint32_t col = dsc->id - row * lv_table_get_col_cnt(obj);
132 
133         /*Make the texts in the first cell center aligned*/
134         if(row == 0) {
135             dsc->label_dsc->align = LV_TEXT_ALIGN_CENTER;
136             dsc->rect_dsc->bg_color = lv_color_mix(lv_palette_main(LV_PALETTE_BLUE), dsc->rect_dsc->bg_color, LV_OPA_40);
137             dsc->rect_dsc->bg_opa = LV_OPA_COVER;
138         }
139         /*In the first column align the texts to the right*/
140         else if(col == 0) {
141             dsc->label_dsc->align = LV_TEXT_ALIGN_RIGHT;
142         }
143 
144         /*Make every 2nd row grayish*/
145         if(row != 0 && (row % 2 == 0)) {
146             dsc->rect_dsc->bg_color = lv_color_mix(lv_palette_main(LV_PALETTE_RED), dsc->rect_dsc->bg_color, LV_OPA_30);
147             dsc->rect_dsc->bg_opa = LV_OPA_COVER;
148         }
149     }
150 }
151 
test_table_rendering(void)152 void test_table_rendering(void)
153 {
154     lv_obj_center(table);
155     lv_obj_add_event_cb(table, draw_part_event_cb, LV_EVENT_DRAW_PART_BEGIN, NULL);
156     lv_obj_set_style_border_side(table, LV_BORDER_SIDE_FULL, LV_PART_ITEMS);
157     lv_obj_set_style_pad_all(table, 10, LV_PART_ITEMS);
158     lv_obj_set_style_border_width(table, 5, LV_PART_ITEMS);
159     lv_table_set_col_cnt(table, 5);
160     lv_table_set_row_cnt(table, 5);
161     lv_table_set_col_width(table, 1, 60);
162     lv_table_set_col_width(table, 2, 100);
163 
164     lv_table_add_cell_ctrl(table, 0, 1, LV_TABLE_CELL_CTRL_MERGE_RIGHT);
165     lv_table_set_cell_value(table, 0, 1, "2 cells are merged");
166 
167     lv_table_add_cell_ctrl(table, 1, 0, LV_TABLE_CELL_CTRL_MERGE_RIGHT);
168     lv_table_add_cell_ctrl(table, 1, 1, LV_TABLE_CELL_CTRL_MERGE_RIGHT);
169     lv_table_add_cell_ctrl(table, 1, 2, LV_TABLE_CELL_CTRL_MERGE_RIGHT);
170     lv_table_add_cell_ctrl(table, 1, 3, LV_TABLE_CELL_CTRL_MERGE_RIGHT);
171     lv_table_set_cell_value(table, 1, 0, "5 cells are merged");
172 
173     uint32_t i;
174     for(i = 0; i < 5; i++) {
175         lv_table_set_cell_value_fmt(table, 3, i, "%d", i);
176     }
177 
178     lv_table_set_cell_value_fmt(table, 2, 3, "Multi\nline text");
179     lv_table_set_cell_value_fmt(table, 2, 4, "Very long text wrapped automatically");
180 
181     lv_table_add_cell_ctrl(table, 4, 3, LV_TABLE_CELL_CTRL_TEXT_CROP);
182     lv_table_set_cell_value_fmt(table, 4, 3, "crop crop crop crop crop crop crop crop ");
183 
184     TEST_ASSERT_EQUAL_SCREENSHOT("table_1.png");
185 }
186 
187 /* See #3120 for context */
test_table_should_reduce_cells(void)188 void test_table_should_reduce_cells(void)
189 {
190     const uint16_t initial_col_num = 8;
191     const uint16_t initial_row_num = 1;
192     const uint16_t final_col_num = 4;
193     const uint16_t final_row_num = 1;
194 
195     lv_obj_center(table);
196 
197     lv_table_set_col_cnt(table, initial_col_num);
198     lv_table_set_row_cnt(table, initial_row_num);
199 
200     uint32_t row_idx, col_idx;
201     for(row_idx = 0; row_idx < initial_row_num; row_idx++) {
202         for(col_idx = 0; col_idx < initial_col_num; col_idx++) {
203             lv_table_set_cell_value(table, row_idx, col_idx, "00");
204         }
205     }
206 
207     lv_table_set_col_cnt(table, final_col_num);
208     lv_table_set_row_cnt(table, final_row_num);
209 
210     for(row_idx = 0; row_idx < final_row_num; row_idx++) {
211         for(col_idx = 0; col_idx < final_col_num; col_idx++) {
212             lv_table_set_cell_value(table, row_idx, col_idx, "00");
213         }
214     }
215 }
216 
217 /* See #3120 for context */
test_table_should_reduce_cells_with_more_than_one_row(void)218 void test_table_should_reduce_cells_with_more_than_one_row(void)
219 {
220     const uint16_t initial_col_num = 8;
221     const uint16_t initial_row_num = 2;
222     const uint16_t final_col_num = 4;
223     const uint16_t final_row_num = 1;
224 
225     lv_obj_center(table);
226 
227     lv_table_set_col_cnt(table, initial_col_num);
228     lv_table_set_row_cnt(table, initial_row_num);
229 
230     uint32_t row_idx, col_idx;
231     for(row_idx = 0; row_idx < initial_row_num; row_idx++) {
232         for(col_idx = 0; col_idx < initial_col_num; col_idx++) {
233             lv_table_set_cell_value(table, row_idx, col_idx, "00");
234         }
235     }
236 
237     lv_table_set_col_cnt(table, final_col_num);
238     lv_table_set_row_cnt(table, final_row_num);
239 
240     for(row_idx = 0; row_idx < final_row_num; row_idx++) {
241         for(col_idx = 0; col_idx < final_col_num; col_idx++) {
242             lv_table_set_cell_value(table, row_idx, col_idx, "00");
243         }
244     }
245 }
246 
247 #endif
248