mirror of
https://github.com/lvgl/lvgl.git
synced 2024-11-24 10:22:53 +08:00
feat(table): add user_data to table cells (#4767)
Co-authored-by: Oleg Belousov <bov@silentwings.ru>
This commit is contained in:
parent
a5f6e2761f
commit
81e498baf4
@ -41,7 +41,7 @@ static void refr_size_form_row(lv_obj_t * obj, uint32_t start_row);
|
||||
static void refr_cell_size(lv_obj_t * obj, uint32_t row, uint32_t col);
|
||||
static lv_result_t get_pressed_cell(lv_obj_t * obj, uint32_t * row, uint32_t * col);
|
||||
static size_t get_cell_txt_len(const char * txt);
|
||||
static void copy_cell_txt(char * dst, const char * txt);
|
||||
static void copy_cell_txt(lv_table_cell_t * dst, const char * txt);
|
||||
static void get_cell_area(lv_obj_t * obj, uint32_t row, uint32_t col, lv_area_t * area);
|
||||
static void scroll_to_selected_cell(lv_obj_t * obj);
|
||||
|
||||
@ -100,7 +100,12 @@ void lv_table_set_cell_value(lv_obj_t * obj, uint32_t row, uint32_t col, const c
|
||||
lv_table_cell_ctrl_t ctrl = 0;
|
||||
|
||||
/*Save the control byte*/
|
||||
if(table->cell_data[cell]) ctrl = table->cell_data[cell][0];
|
||||
if(table->cell_data[cell]) ctrl = table->cell_data[cell]->ctrl;
|
||||
|
||||
void * user_data = NULL;
|
||||
|
||||
/*Save the user data*/
|
||||
if(table->cell_data[cell]) user_data = table->cell_data[cell]->user_data;
|
||||
|
||||
size_t to_allocate = get_cell_txt_len(txt);
|
||||
|
||||
@ -110,7 +115,8 @@ void lv_table_set_cell_value(lv_obj_t * obj, uint32_t row, uint32_t col, const c
|
||||
|
||||
copy_cell_txt(table->cell_data[cell], txt);
|
||||
|
||||
table->cell_data[cell][0] = ctrl;
|
||||
table->cell_data[cell]->ctrl = ctrl;
|
||||
table->cell_data[cell]->user_data = user_data;
|
||||
refr_cell_size(obj, row, col);
|
||||
}
|
||||
|
||||
@ -133,7 +139,12 @@ void lv_table_set_cell_value_fmt(lv_obj_t * obj, uint32_t row, uint32_t col, con
|
||||
lv_table_cell_ctrl_t ctrl = 0;
|
||||
|
||||
/*Save the control byte*/
|
||||
if(table->cell_data[cell]) ctrl = table->cell_data[cell][0];
|
||||
if(table->cell_data[cell]) ctrl = table->cell_data[cell]->ctrl;
|
||||
|
||||
void * user_data = NULL;
|
||||
|
||||
/*Save the user_data*/
|
||||
if(table->cell_data[cell]) user_data = table->cell_data[cell]->user_data;
|
||||
|
||||
va_list ap, ap2;
|
||||
va_start(ap, fmt);
|
||||
@ -156,32 +167,33 @@ void lv_table_set_cell_value_fmt(lv_obj_t * obj, uint32_t row, uint32_t col, con
|
||||
|
||||
/*Get the size of the Arabic text and process it*/
|
||||
size_t len_ap = _lv_text_ap_calc_bytes_cnt(raw_txt);
|
||||
table->cell_data[cell] = lv_realloc(table->cell_data[cell], len_ap + 1);
|
||||
table->cell_data[cell] = lv_realloc(table->cell_data[cell], sizeof(lv_table_cell_t) + len_ap + 1);
|
||||
LV_ASSERT_MALLOC(table->cell_data[cell]);
|
||||
if(table->cell_data[cell] == NULL) {
|
||||
va_end(ap2);
|
||||
return;
|
||||
}
|
||||
_lv_text_ap_proc(raw_txt, &table->cell_data[cell][1]);
|
||||
_lv_text_ap_proc(raw_txt, table->cell_data[cell]->txt);
|
||||
|
||||
lv_free(raw_txt);
|
||||
#else
|
||||
table->cell_data[cell] = lv_realloc(table->cell_data[cell], len + 2); /*+1: trailing '\0; +1: format byte*/
|
||||
table->cell_data[cell] = lv_realloc(table->cell_data[cell],
|
||||
sizeof(lv_table_cell_t) + len + 1); /*+1: trailing '\0; */
|
||||
LV_ASSERT_MALLOC(table->cell_data[cell]);
|
||||
if(table->cell_data[cell] == NULL) {
|
||||
va_end(ap2);
|
||||
return;
|
||||
}
|
||||
|
||||
table->cell_data[cell][len + 1] = 0; /*Ensure NULL termination*/
|
||||
table->cell_data[cell]->txt[len] = 0; /*Ensure NULL termination*/
|
||||
|
||||
lv_vsnprintf(&table->cell_data[cell][1], len + 1, fmt, ap2);
|
||||
lv_vsnprintf(table->cell_data[cell]->txt, len, fmt, ap2);
|
||||
#endif
|
||||
|
||||
va_end(ap2);
|
||||
|
||||
table->cell_data[cell][0] = ctrl;
|
||||
|
||||
table->cell_data[cell]->ctrl = ctrl;
|
||||
table->cell_data[cell]->user_data = user_data;
|
||||
refr_cell_size(obj, row, col);
|
||||
}
|
||||
|
||||
@ -206,11 +218,15 @@ void lv_table_set_row_cnt(lv_obj_t * obj, uint32_t row_cnt)
|
||||
uint32_t new_cell_cnt = table->col_cnt * table->row_cnt;
|
||||
uint32_t i;
|
||||
for(i = new_cell_cnt; i < old_cell_cnt; i++) {
|
||||
if(table->cell_data[i]->user_data) {
|
||||
lv_free(table->cell_data[i]->user_data);
|
||||
table->cell_data[i]->user_data = NULL;
|
||||
}
|
||||
lv_free(table->cell_data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
table->cell_data = lv_realloc(table->cell_data, table->row_cnt * table->col_cnt * sizeof(char *));
|
||||
table->cell_data = lv_realloc(table->cell_data, table->row_cnt * table->col_cnt * sizeof(lv_table_cell_t *));
|
||||
LV_ASSERT_MALLOC(table->cell_data);
|
||||
if(table->cell_data == NULL) return;
|
||||
|
||||
@ -235,7 +251,7 @@ void lv_table_set_col_cnt(lv_obj_t * obj, uint32_t col_cnt)
|
||||
uint32_t old_col_cnt = table->col_cnt;
|
||||
table->col_cnt = col_cnt;
|
||||
|
||||
char ** new_cell_data = lv_malloc(table->row_cnt * table->col_cnt * sizeof(char *));
|
||||
lv_table_cell_t ** new_cell_data = lv_malloc(table->row_cnt * table->col_cnt * sizeof(lv_table_cell_t *));
|
||||
LV_ASSERT_MALLOC(new_cell_data);
|
||||
if(new_cell_data == NULL) return;
|
||||
uint32_t new_cell_cnt = table->col_cnt * table->row_cnt;
|
||||
@ -258,6 +274,10 @@ void lv_table_set_col_cnt(lv_obj_t * obj, uint32_t col_cnt)
|
||||
int32_t i;
|
||||
for(i = 0; i < (int32_t)old_col_cnt - (int32_t)col_cnt; i++) {
|
||||
uint32_t idx = old_col_start + min_col_cnt + i;
|
||||
if(table->cell_data[idx]->user_data) {
|
||||
lv_free(table->cell_data[idx]->user_data);
|
||||
table->cell_data[idx]->user_data = NULL;
|
||||
}
|
||||
lv_free(table->cell_data[idx]);
|
||||
table->cell_data[idx] = NULL;
|
||||
}
|
||||
@ -306,15 +326,16 @@ void lv_table_add_cell_ctrl(lv_obj_t * obj, uint32_t row, uint32_t col, lv_table
|
||||
uint32_t cell = row * table->col_cnt + col;
|
||||
|
||||
if(is_cell_empty(table->cell_data[cell])) {
|
||||
table->cell_data[cell] = lv_malloc(2); /*+1: trailing '\0; +1: format byte*/
|
||||
table->cell_data[cell] = lv_malloc(sizeof(lv_table_cell_t) + 1); /*+1: trailing '\0 */
|
||||
LV_ASSERT_MALLOC(table->cell_data[cell]);
|
||||
if(table->cell_data[cell] == NULL) return;
|
||||
|
||||
table->cell_data[cell][0] = 0;
|
||||
table->cell_data[cell][1] = '\0';
|
||||
table->cell_data[cell]->ctrl = 0;
|
||||
table->cell_data[cell]->user_data = NULL;
|
||||
table->cell_data[cell]->txt[0] = '\0';
|
||||
}
|
||||
|
||||
table->cell_data[cell][0] |= ctrl;
|
||||
table->cell_data[cell]->ctrl |= ctrl;
|
||||
}
|
||||
|
||||
void lv_table_clear_cell_ctrl(lv_obj_t * obj, uint32_t row, uint32_t col, lv_table_cell_ctrl_t ctrl)
|
||||
@ -330,15 +351,45 @@ void lv_table_clear_cell_ctrl(lv_obj_t * obj, uint32_t row, uint32_t col, lv_tab
|
||||
uint32_t cell = row * table->col_cnt + col;
|
||||
|
||||
if(is_cell_empty(table->cell_data[cell])) {
|
||||
table->cell_data[cell] = lv_malloc(2); /*+1: trailing '\0; +1: format byte*/
|
||||
table->cell_data[cell] = lv_malloc(sizeof(lv_table_cell_t) + 1); /*+1: trailing '\0 */
|
||||
LV_ASSERT_MALLOC(table->cell_data[cell]);
|
||||
if(table->cell_data[cell] == NULL) return;
|
||||
|
||||
table->cell_data[cell][0] = 0;
|
||||
table->cell_data[cell][1] = '\0';
|
||||
table->cell_data[cell]->ctrl = 0;
|
||||
table->cell_data[cell]->user_data = NULL;
|
||||
table->cell_data[cell]->txt[0] = '\0';
|
||||
}
|
||||
|
||||
table->cell_data[cell][0] &= (~ctrl);
|
||||
table->cell_data[cell]->ctrl &= (~ctrl);
|
||||
}
|
||||
|
||||
void lv_table_set_user_data(lv_obj_t * obj, uint16_t row, uint16_t col, void * user_data)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
lv_table_t * table = (lv_table_t *)obj;
|
||||
|
||||
/*Auto expand*/
|
||||
if(col >= table->col_cnt) lv_table_set_col_cnt(obj, col + 1);
|
||||
if(row >= table->row_cnt) lv_table_set_row_cnt(obj, row + 1);
|
||||
|
||||
uint32_t cell = row * table->col_cnt + col;
|
||||
|
||||
if(is_cell_empty(table->cell_data[cell])) {
|
||||
table->cell_data[cell] = lv_malloc(sizeof(lv_table_cell_t) + 1); /*+1: trailing '\0 */
|
||||
LV_ASSERT_MALLOC(table->cell_data[cell]);
|
||||
if(table->cell_data[cell] == NULL) return;
|
||||
|
||||
table->cell_data[cell]->ctrl = 0;
|
||||
table->cell_data[cell]->user_data = NULL;
|
||||
table->cell_data[cell]->txt[0] = '\0';
|
||||
}
|
||||
|
||||
if(table->cell_data[cell]->user_data) {
|
||||
lv_free(table->cell_data[cell]->user_data);
|
||||
}
|
||||
|
||||
table->cell_data[cell]->user_data = user_data;
|
||||
}
|
||||
|
||||
/*=====================
|
||||
@ -358,7 +409,7 @@ const char * lv_table_get_cell_value(lv_obj_t * obj, uint32_t row, uint32_t col)
|
||||
|
||||
if(is_cell_empty(table->cell_data[cell])) return "";
|
||||
|
||||
return &table->cell_data[cell][1]; /*Skip the format byte*/
|
||||
return table->cell_data[cell]->txt;
|
||||
}
|
||||
|
||||
uint32_t lv_table_get_row_cnt(lv_obj_t * obj)
|
||||
@ -403,7 +454,7 @@ bool lv_table_has_cell_ctrl(lv_obj_t * obj, uint32_t row, uint32_t col, lv_table
|
||||
uint32_t cell = row * table->col_cnt + col;
|
||||
|
||||
if(is_cell_empty(table->cell_data[cell])) return false;
|
||||
else return (table->cell_data[cell][0] & ctrl) == ctrl;
|
||||
else return (table->cell_data[cell]->ctrl & ctrl) == ctrl;
|
||||
}
|
||||
|
||||
void lv_table_get_selected_cell(lv_obj_t * obj, uint32_t * row, uint32_t * col)
|
||||
@ -413,6 +464,22 @@ void lv_table_get_selected_cell(lv_obj_t * obj, uint32_t * row, uint32_t * col)
|
||||
*col = table->col_act;
|
||||
}
|
||||
|
||||
void * lv_table_get_user_data(lv_obj_t * obj, uint16_t row, uint16_t col)
|
||||
{
|
||||
LV_ASSERT_OBJ(obj, MY_CLASS);
|
||||
|
||||
lv_table_t * table = (lv_table_t *)obj;
|
||||
if(row >= table->row_cnt || col >= table->col_cnt) {
|
||||
LV_LOG_WARN("invalid row or column");
|
||||
return NULL;
|
||||
}
|
||||
uint32_t cell = row * table->col_cnt + col;
|
||||
|
||||
if(is_cell_empty(table->cell_data[cell])) return NULL;
|
||||
|
||||
return table->cell_data[cell]->user_data;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
@ -430,7 +497,7 @@ static void lv_table_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
|
||||
table->row_h = lv_malloc(table->row_cnt * sizeof(table->row_h[0]));
|
||||
table->col_w[0] = LV_DPI_DEF;
|
||||
table->row_h[0] = LV_DPI_DEF;
|
||||
table->cell_data = lv_realloc(table->cell_data, table->row_cnt * table->col_cnt * sizeof(char *));
|
||||
table->cell_data = lv_realloc(table->cell_data, table->row_cnt * table->col_cnt * sizeof(lv_table_cell_t *));
|
||||
table->cell_data[0] = NULL;
|
||||
|
||||
LV_TRACE_OBJ_CREATE("finished");
|
||||
@ -444,6 +511,10 @@ static void lv_table_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
|
||||
uint32_t i;
|
||||
for(i = 0; i < table->col_cnt * table->row_cnt; i++) {
|
||||
if(table->cell_data[i]) {
|
||||
if(table->cell_data[i]->user_data) {
|
||||
lv_free(table->cell_data[i]->user_data);
|
||||
table->cell_data[i]->user_data = NULL;
|
||||
}
|
||||
lv_free(table->cell_data[i]);
|
||||
table->cell_data[i] = NULL;
|
||||
}
|
||||
@ -635,7 +706,7 @@ static void draw_main(lv_event_t * e)
|
||||
|
||||
for(col = 0; col < table->col_cnt; col++) {
|
||||
lv_table_cell_ctrl_t ctrl = 0;
|
||||
if(table->cell_data[cell]) ctrl = table->cell_data[cell][0];
|
||||
if(table->cell_data[cell]) ctrl = table->cell_data[cell]->ctrl;
|
||||
|
||||
if(rtl) {
|
||||
cell_area.x2 = cell_area.x1 - 1;
|
||||
@ -648,11 +719,11 @@ static void draw_main(lv_event_t * e)
|
||||
|
||||
uint32_t col_merge = 0;
|
||||
for(col_merge = 0; col_merge + col < table->col_cnt - 1; col_merge++) {
|
||||
char * next_cell_data = table->cell_data[cell + col_merge];
|
||||
lv_table_cell_t * next_cell_data = table->cell_data[cell + col_merge];
|
||||
|
||||
if(is_cell_empty(next_cell_data)) break;
|
||||
|
||||
lv_table_cell_ctrl_t merge_ctrl = (lv_table_cell_ctrl_t) next_cell_data[0];
|
||||
lv_table_cell_ctrl_t merge_ctrl = (lv_table_cell_ctrl_t) next_cell_data->ctrl;
|
||||
if(merge_ctrl & LV_TABLE_CELL_CTRL_MERGE_RIGHT) {
|
||||
int32_t offset = table->col_w[col + col_merge + 1];
|
||||
|
||||
@ -736,7 +807,7 @@ static void draw_main(lv_event_t * e)
|
||||
bool crop = ctrl & LV_TABLE_CELL_CTRL_TEXT_CROP;
|
||||
if(crop) txt_flags = LV_TEXT_FLAG_EXPAND;
|
||||
|
||||
lv_text_get_size(&txt_size, table->cell_data[cell] + 1, label_dsc_def.font,
|
||||
lv_text_get_size(&txt_size, table->cell_data[cell]->txt, label_dsc_def.font,
|
||||
label_dsc_act.letter_space, label_dsc_act.line_space,
|
||||
lv_area_get_width(&txt_area), txt_flags);
|
||||
|
||||
@ -751,7 +822,7 @@ static void draw_main(lv_event_t * e)
|
||||
label_mask_ok = _lv_area_intersect(&label_clip_area, &clip_area, &cell_area);
|
||||
if(label_mask_ok) {
|
||||
layer->clip_area = label_clip_area;
|
||||
label_dsc_act.text = table->cell_data[cell] + 1;
|
||||
label_dsc_act.text = table->cell_data[cell]->txt;
|
||||
lv_draw_label(layer, &label_dsc_act, &txt_area);
|
||||
layer->clip_area = clip_area;
|
||||
}
|
||||
@ -841,7 +912,7 @@ static int32_t get_row_height(lv_obj_t * obj, uint32_t row_id, const lv_font_t *
|
||||
uint32_t cell;
|
||||
uint32_t col;
|
||||
for(cell = row_start, col = 0; cell < row_start + table->col_cnt; cell++, col++) {
|
||||
char * cell_data = table->cell_data[cell];
|
||||
lv_table_cell_t * cell_data = table->cell_data[cell];
|
||||
|
||||
if(is_cell_empty(cell_data)) {
|
||||
continue;
|
||||
@ -854,11 +925,11 @@ static int32_t get_row_height(lv_obj_t * obj, uint32_t row_id, const lv_font_t *
|
||||
* exit the traversal when the current cell control is not LV_TABLE_CELL_CTRL_MERGE_RIGHT */
|
||||
uint32_t col_merge = 0;
|
||||
for(col_merge = 0; col_merge + col < table->col_cnt - 1; col_merge++) {
|
||||
char * next_cell_data = table->cell_data[cell + col_merge];
|
||||
lv_table_cell_t * next_cell_data = table->cell_data[cell + col_merge];
|
||||
|
||||
if(is_cell_empty(next_cell_data)) break;
|
||||
|
||||
lv_table_cell_ctrl_t ctrl = (lv_table_cell_ctrl_t) next_cell_data[0];
|
||||
lv_table_cell_ctrl_t ctrl = (lv_table_cell_ctrl_t) next_cell_data->ctrl;
|
||||
if(ctrl & LV_TABLE_CELL_CTRL_MERGE_RIGHT) {
|
||||
txt_w += table->col_w[col + col_merge + 1];
|
||||
}
|
||||
@ -867,7 +938,7 @@ static int32_t get_row_height(lv_obj_t * obj, uint32_t row_id, const lv_font_t *
|
||||
}
|
||||
}
|
||||
|
||||
lv_table_cell_ctrl_t ctrl = (lv_table_cell_ctrl_t) cell_data[0];
|
||||
lv_table_cell_ctrl_t ctrl = (lv_table_cell_ctrl_t) cell_data->ctrl;
|
||||
|
||||
/*When cropping the text we can assume the row height is equal to the line height*/
|
||||
if(ctrl & LV_TABLE_CELL_CTRL_TEXT_CROP) {
|
||||
@ -879,7 +950,7 @@ static int32_t get_row_height(lv_obj_t * obj, uint32_t row_id, const lv_font_t *
|
||||
lv_point_t txt_size;
|
||||
txt_w -= cell_left + cell_right;
|
||||
|
||||
lv_text_get_size(&txt_size, table->cell_data[cell] + 1, font,
|
||||
lv_text_get_size(&txt_size, table->cell_data[cell]->txt, font,
|
||||
letter_space, line_space, txt_w, LV_TEXT_FLAG_NONE);
|
||||
|
||||
h_max = LV_MAX(txt_size.y + cell_top + cell_bottom, h_max);
|
||||
@ -949,23 +1020,21 @@ static size_t get_cell_txt_len(const char * txt)
|
||||
size_t retval = 0;
|
||||
|
||||
#if LV_USE_ARABIC_PERSIAN_CHARS
|
||||
retval = _lv_text_ap_calc_bytes_cnt(txt) + 1;
|
||||
retval = sizeof(lv_table_cell_t) + _lv_text_ap_calc_bytes_cnt(txt) + 1;
|
||||
#else
|
||||
/* cell_data layout: [ctrl][txt][trailing '\0' terminator]
|
||||
* +2 because of the trailing '\0' and the ctrl */
|
||||
retval = lv_strlen(txt) + 2;
|
||||
retval = sizeof(lv_table_cell_t) + strlen(txt) + 1;
|
||||
#endif
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Copy txt into dst skipping the format byte */
|
||||
static void copy_cell_txt(char * dst, const char * txt)
|
||||
static void copy_cell_txt(lv_table_cell_t * dst, const char * txt)
|
||||
{
|
||||
#if LV_USE_ARABIC_PERSIAN_CHARS
|
||||
_lv_text_ap_proc(txt, &dst[1]);
|
||||
_lv_text_ap_proc(txt, dst->txt);
|
||||
#else
|
||||
lv_strcpy(&dst[1], txt);
|
||||
strcpy(dst->txt, txt);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -49,12 +49,19 @@ typedef uint32_t lv_table_cell_ctrl_t;
|
||||
#endif /*DOXYGEN*/
|
||||
|
||||
|
||||
/*Data of cell*/
|
||||
typedef struct {
|
||||
lv_table_cell_ctrl_t ctrl;
|
||||
void * user_data; /**< Custom user data*/
|
||||
char txt[];
|
||||
} lv_table_cell_t;
|
||||
|
||||
/*Data of table*/
|
||||
typedef struct {
|
||||
lv_obj_t obj;
|
||||
uint32_t col_cnt;
|
||||
uint32_t row_cnt;
|
||||
char ** cell_data;
|
||||
lv_table_cell_t ** cell_data;
|
||||
int32_t * row_h;
|
||||
int32_t * col_w;
|
||||
uint32_t col_act;
|
||||
@ -140,6 +147,18 @@ void lv_table_add_cell_ctrl(lv_obj_t * obj, uint32_t row, uint32_t col, lv_table
|
||||
*/
|
||||
void lv_table_clear_cell_ctrl(lv_obj_t * obj, uint32_t row, uint32_t col, lv_table_cell_ctrl_t ctrl);
|
||||
|
||||
/**
|
||||
* Add custom user data to the cell.
|
||||
* @param obj pointer to a Table object
|
||||
* @param row id of the row [0 .. row_cnt -1]
|
||||
* @param col id of the column [0 .. col_cnt -1]
|
||||
* @param user_data pointer to the new user_data.
|
||||
* Should be allocated by `lv_malloc`,
|
||||
* and it will be freed automatically when the table is deleted or
|
||||
* when the cell is dropped due to lower row or column count.
|
||||
*/
|
||||
void lv_table_set_user_data(lv_obj_t * obj, uint16_t row, uint16_t col, void * user_data);
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
@ -193,6 +212,14 @@ bool lv_table_has_cell_ctrl(lv_obj_t * obj, uint32_t row, uint32_t col, lv_table
|
||||
*/
|
||||
void lv_table_get_selected_cell(lv_obj_t * obj, uint32_t * row, uint32_t * col);
|
||||
|
||||
/**
|
||||
* Get custom user data to the cell.
|
||||
* @param obj pointer to a Table object
|
||||
* @param row id of the row [0 .. row_cnt -1]
|
||||
* @param col id of the column [0 .. col_cnt -1]
|
||||
*/
|
||||
void * lv_table_get_user_data(lv_obj_t * obj, uint16_t row, uint16_t col);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
Loading…
Reference in New Issue
Block a user