This commit is contained in:
2026-02-13 14:42:07 -08:00
parent 6a485b6ad9
commit deb33eb352
670 changed files with 55968 additions and 51275 deletions

View File

@@ -21,10 +21,6 @@
#define MY_CLASS &lv_arc_class
#define VALUE_UNSET INT16_MIN
#define CLICK_OUTSIDE_BG_ANGLES ((uint32_t) 0x00U)
#define CLICK_INSIDE_BG_ANGLES ((uint32_t) 0x01U)
#define CLICK_CLOSER_TO_MAX_END ((uint32_t) 0x00U)
#define CLICK_CLOSER_TO_MIN_END ((uint32_t) 0x01U)
/**********************
* TYPEDEFS
@@ -44,7 +40,6 @@ static lv_coord_t get_angle(const lv_obj_t * obj);
static void get_knob_area(lv_obj_t * arc, const lv_point_t * center, lv_coord_t r, lv_area_t * knob_area);
static void value_update(lv_obj_t * arc);
static lv_coord_t knob_get_extra_size(lv_obj_t * obj);
static bool lv_arc_angle_within_bg_bounds(lv_obj_t * obj, const uint32_t angle, const uint32_t tolerance_deg);
/**********************
* STATIC VARIABLES
@@ -404,7 +399,6 @@ static void lv_arc_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
arc->chg_rate = 720;
arc->last_tick = lv_tick_get();
arc->last_angle = arc->indic_angle_end;
arc->in_out = CLICK_OUTSIDE_BG_ANGLES;
lv_obj_add_flag(obj, LV_OBJ_FLAG_CLICKABLE);
lv_obj_clear_flag(obj, LV_OBJ_FLAG_SCROLL_CHAIN | LV_OBJ_FLAG_SCROLLABLE);
@@ -484,54 +478,29 @@ static void lv_arc_event(const lv_obj_class_t * class_p, lv_event_t * e)
angle -= arc->rotation;
angle -= arc->bg_angle_start; /*Make the angle relative to the start angle*/
/* If we click near the bg_angle_start the angle will be close to 360° instead of an small angle */
if(angle < 0) angle += 360;
const uint32_t circumference = (uint32_t)((2U * r * 314U) / 100U); /* Equivalent to: 2r * 3.14, avoiding floats */
const uint32_t tolerance_deg = (360U * LV_DPX(50U)) / circumference;
const uint32_t min_close_prev = (uint32_t) arc->min_close;
const bool is_angle_within_bg_bounds = lv_arc_angle_within_bg_bounds(obj, (uint32_t) angle, tolerance_deg);
if(!is_angle_within_bg_bounds) {
return;
}
int16_t deg_range = bg_end - arc->bg_angle_start;
int16_t last_angle_rel = arc->last_angle - arc->bg_angle_start;
int16_t delta_angle = angle - last_angle_rel;
/*Do not allow big jumps (jumps bigger than 280°).
/*Do not allow big jumps.
*It's mainly to avoid jumping to the opposite end if the "dead" range between min. and max. is crossed.
*Check which end was closer on the last valid press (arc->min_close) and prefer that end*/
if(LV_ABS(delta_angle) > 280) {
if(arc->min_close) angle = 0;
else angle = deg_range;
}
/* Check if click was outside the background arc start and end angles */
else if(CLICK_OUTSIDE_BG_ANGLES == arc->in_out) {
if(arc->min_close) angle = -deg_range;
else angle = deg_range;
else {
if(angle < deg_range / 2)arc->min_close = 1;
else arc->min_close = 0;
}
else { /* Keep the angle value */ }
/* Prevent big jumps when the click goes from start to end angle in the invisible
* part of the background arc without being released */
if(((min_close_prev == CLICK_CLOSER_TO_MIN_END) && (arc->min_close == CLICK_CLOSER_TO_MAX_END))
&& ((CLICK_OUTSIDE_BG_ANGLES == arc->in_out) && (LV_ABS(delta_angle) > 280))) {
angle = 0;
}
else if(((min_close_prev == CLICK_CLOSER_TO_MAX_END) && (arc->min_close == CLICK_CLOSER_TO_MIN_END))
&& (CLICK_OUTSIDE_BG_ANGLES == arc->in_out)) {
angle = deg_range;
}
else { /* Keep the angle value */ }
/*Calculate the slew rate limited angle based on change rate (degrees/sec)*/
delta_angle = angle - last_angle_rel;
uint32_t delta_tick = lv_tick_elaps(arc->last_tick);
/* delta_angle_max can never be signed. delta_tick is always signed, same for ch_rate */
const uint16_t delta_angle_max = (arc->chg_rate * delta_tick) / 1000;
int16_t delta_angle_max = (arc->chg_rate * delta_tick) / 1000;
if(delta_angle > delta_angle_max) {
delta_angle = delta_angle_max;
@@ -539,7 +508,6 @@ static void lv_arc_event(const lv_obj_class_t * class_p, lv_event_t * e)
else if(delta_angle < -delta_angle_max) {
delta_angle = -delta_angle_max;
}
else { /* Nothing to do */ }
angle = last_angle_rel + delta_angle; /*Apply the limited angle change*/
@@ -596,7 +564,7 @@ static void lv_arc_event(const lv_obj_class_t * class_p, lv_event_t * e)
}
}
else if(code == LV_EVENT_HIT_TEST) {
lv_hit_test_info_t * info = lv_event_get_param(e);
lv_hit_test_info_t * info = lv_event_get_param(e);;
lv_point_t p;
lv_coord_t r;
@@ -900,121 +868,4 @@ static lv_coord_t knob_get_extra_size(lv_obj_t * obj)
return LV_MAX(knob_shadow_size, knob_outline_size);
}
/**
* Check if angle is within arc background bounds
*
* In order to avoid unexpected value update of the arc value when the user clicks
* outside of the arc background we need to check if the angle (of the clicked point)
* is within the bounds of the background.
*
* A tolerance (extra room) also should be taken into consideration.
*
* E.g. Arc with start angle of 0° and end angle of 90°, the background is only visible in
* that range, from 90° to 360° the background is invisible. Click in 150° should not update
* the arc value, click within the arc angle range should.
*
* IMPORTANT NOTE: angle is always relative to bg_angle_start, e.g. if bg_angle_start is 30
* and we click a bit to the left, angle is 10, not the expected 40.
*
* @param obj Pointer to lv_arc
* @param angle Angle to be checked
* @param tolerance_deg Tolerance
*
* @return true if angle is within arc background bounds, false otherwise
*/
static bool lv_arc_angle_within_bg_bounds(lv_obj_t * obj, const uint32_t angle, const uint32_t tolerance_deg)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_arc_t * arc = (lv_arc_t *)obj;
uint32_t smaller_angle = 0;
uint32_t bigger_angle = 0;
/* Determine which background angle is smaller and bigger */
if(arc->bg_angle_start < arc->bg_angle_end) {
bigger_angle = arc->bg_angle_end;
smaller_angle = arc->bg_angle_start;
}
else {
bigger_angle = (360 - arc->bg_angle_start) + arc->bg_angle_end;
smaller_angle = 0;
}
/* Angle is between both background angles */
if((smaller_angle <= angle) && (angle <= bigger_angle)) {
if(((bigger_angle - smaller_angle) / 2U) >= angle) {
arc->min_close = 1;
}
else {
arc->min_close = 0;
}
arc->in_out = CLICK_INSIDE_BG_ANGLES;
return true;
}
/* Distance between background start and end angles is less than tolerance,
* consider the click inside the arc */
else if(((smaller_angle - tolerance_deg) <= 0U) &&
(360U - (bigger_angle + (smaller_angle - tolerance_deg)))) {
arc->min_close = 1;
arc->in_out = CLICK_INSIDE_BG_ANGLES;
return true;
}
else { /* Case handled below */ }
/* Legends:
* 0° = angle 0
* 360° = angle 360
* T: Tolerance
* A: Angle
* S: Arc background start angle
* E: Arc background end angle
*
* Start angle is bigger or equal to tolerance */
if((smaller_angle >= tolerance_deg)
/* (360° - T) --- A --- 360° */
&& ((angle >= (360U - tolerance_deg)) && (angle <= 360U))) {
arc->min_close = 1;
arc->in_out = CLICK_OUTSIDE_BG_ANGLES;
return true;
}
/* Tolerance is bigger than bg start angle */
else if((smaller_angle < tolerance_deg)
/* (360° - (T - S)) --- A --- 360° */
&& (((360U - (tolerance_deg - smaller_angle)) <= angle)) && (angle <= 360U)) {
arc->min_close = 1;
arc->in_out = CLICK_OUTSIDE_BG_ANGLES;
return true;
}
/* 360° is bigger than background end angle + tolerance */
else if((360U >= (bigger_angle + tolerance_deg))
/* E --- A --- (E + T) */
&& ((bigger_angle <= (angle + smaller_angle)) &&
((angle + smaller_angle) <= (bigger_angle + tolerance_deg)))) {
arc->min_close = 0;
arc->in_out = CLICK_OUTSIDE_BG_ANGLES;
return true;
}
/* Background end angle + tolerance is bigger than 360° and bg_start_angle + tolerance is not near 0° + ((bg_end_angle + tolerance) - 360°)
* Here we can assume background is not near 0° because of the first two initial checks */
else if((360U < (bigger_angle + tolerance_deg))
&& (angle <= 0U + ((bigger_angle + tolerance_deg) - 360U)) && (angle > bigger_angle)) {
arc->min_close = 0;
arc->in_out = CLICK_OUTSIDE_BG_ANGLES;
return true;
}
else {
/* Nothing to do */
}
return false;
}
#endif

View File

@@ -44,11 +44,10 @@ typedef struct {
int16_t value; /*Current value of the arc*/
int16_t min_value; /*Minimum value of the arc*/
int16_t max_value; /*Maximum value of the arc*/
uint32_t dragging : 1;
uint32_t type : 2;
uint32_t min_close : 1; /*1: the last pressed angle was closer to minimum end*/
uint32_t in_out : 1; /* 1: The click was within the background arc angles. 0: Click outside */
uint32_t chg_rate; /*Drag angle rate of change of the arc (degrees/sec)*/
uint16_t dragging : 1;
uint16_t type : 2;
uint16_t min_close : 1; /*1: the last pressed angle was closer to minimum end*/
uint16_t chg_rate; /*Drag angle rate of change of the arc (degrees/sec)*/
uint32_t last_tick; /*Last dragging event timestamp of the arc*/
int16_t last_angle; /*Last dragging angle of the arc*/
} lv_arc_t;

View File

@@ -448,9 +448,6 @@ static void lv_btnmatrix_event(const lv_obj_class_t * class_p, lv_event_t * e)
invalidate_button_area(obj, btnm->btn_id_sel); /*Invalidate the new area*/
}
}
else {
btnm->btn_id_sel = LV_BTNMATRIX_BTN_NONE;
}
}
if(btnm->btn_id_sel != LV_BTNMATRIX_BTN_NONE) {

View File

@@ -74,16 +74,14 @@ void lv_checkbox_set_text(lv_obj_t * obj, const char * txt)
size_t len = strlen(txt);
#endif
char * _txt = (char *)cb->txt;
if(!cb->static_txt) _txt = lv_mem_realloc(_txt, len + 1);
else _txt = lv_mem_alloc(len + 1);
if(!cb->static_txt) cb->txt = lv_mem_realloc(cb->txt, len + 1);
else cb->txt = lv_mem_alloc(len + 1);
#if LV_USE_ARABIC_PERSIAN_CHARS
_lv_txt_ap_proc(txt, _txt);
_lv_txt_ap_proc(txt, cb->txt);
#else
strcpy(_txt, txt);
strcpy(cb->txt, txt);
#endif
cb->txt = _txt;
cb->static_txt = 0;
lv_obj_refresh_self_size(obj);
@@ -94,7 +92,7 @@ void lv_checkbox_set_text_static(lv_obj_t * obj, const char * txt)
{
lv_checkbox_t * cb = (lv_checkbox_t *)obj;
if(!cb->static_txt) lv_mem_free((void *)cb->txt);
if(!cb->static_txt) lv_mem_free(cb->txt);
cb->txt = (char *)txt;
cb->static_txt = 1;
@@ -140,7 +138,7 @@ static void lv_checkbox_destructor(const lv_obj_class_t * class_p, lv_obj_t * ob
lv_checkbox_t * cb = (lv_checkbox_t *)obj;
if(!cb->static_txt) {
lv_mem_free((void *)cb->txt);
lv_mem_free(cb->txt);
cb->txt = NULL;
}
LV_TRACE_OBJ_CREATE("finished");

View File

@@ -28,7 +28,7 @@ extern "C" {
typedef struct {
lv_obj_t obj;
const char * txt;
char * txt;
uint32_t static_txt : 1;
} lv_checkbox_t;

View File

@@ -407,19 +407,14 @@ int32_t lv_dropdown_get_option_index(lv_obj_t * obj, const char * option)
const char * opts = lv_dropdown_get_options(obj);
uint32_t char_i = 0;
uint32_t opt_i = 0;
uint32_t option_len = strlen(option);
const char * start = opts;
while(start[char_i] != '\0') {
for(char_i = 0; (start[char_i] != '\n') && (start[char_i] != '\0'); char_i++);
if(option_len == char_i && memcmp(start, option, LV_MIN(option_len, char_i)) == 0) {
return opt_i;
}
if(memcmp(start, option, LV_MIN(strlen(option), char_i)) == 0) return opt_i;
start = &start[char_i];
if(start[0] == '\n') start++;
char_i = 0;
opt_i++;
}

View File

@@ -40,7 +40,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_res_t get_pressed_cell(lv_obj_t * obj, uint16_t * row, uint16_t * col);
static size_t get_cell_txt_len(const char * txt);
static void copy_cell_txt(lv_table_cell_t * dst, const char * txt);
static void copy_cell_txt(char * dst, const char * txt);
static void get_cell_area(lv_obj_t * obj, uint16_t row, uint16_t col, lv_area_t * area);
static void scroll_to_selected_cell(lv_obj_t * obj);
@@ -98,14 +98,7 @@ void lv_table_set_cell_value(lv_obj_t * obj, uint16_t row, uint16_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]->ctrl;
#if LV_USE_USER_DATA
void * user_data = NULL;
/*Save the user data*/
if(table->cell_data[cell]) user_data = table->cell_data[cell]->user_data;
#endif
if(table->cell_data[cell]) ctrl = table->cell_data[cell][0];
size_t to_allocate = get_cell_txt_len(txt);
@@ -115,10 +108,7 @@ void lv_table_set_cell_value(lv_obj_t * obj, uint16_t row, uint16_t col, const c
copy_cell_txt(table->cell_data[cell], txt);
table->cell_data[cell]->ctrl = ctrl;
#if LV_USE_USER_DATA
table->cell_data[cell]->user_data = user_data;
#endif
table->cell_data[cell][0] = ctrl;
refr_cell_size(obj, row, col);
}
@@ -141,14 +131,7 @@ void lv_table_set_cell_value_fmt(lv_obj_t * obj, uint16_t row, uint16_t col, con
lv_table_cell_ctrl_t ctrl = 0;
/*Save the control byte*/
if(table->cell_data[cell]) ctrl = table->cell_data[cell]->ctrl;
#if LV_USE_USER_DATA
void * user_data = NULL;
/*Save the user_data*/
if(table->cell_data[cell]) user_data = table->cell_data[cell]->user_data;
#endif
if(table->cell_data[cell]) ctrl = table->cell_data[cell][0];
va_list ap, ap2;
va_start(ap, fmt);
@@ -171,35 +154,32 @@ void lv_table_set_cell_value_fmt(lv_obj_t * obj, uint16_t row, uint16_t col, con
/*Get the size of the Arabic text and process it*/
size_t len_ap = _lv_txt_ap_calc_bytes_cnt(raw_txt);
table->cell_data[cell] = lv_mem_realloc(table->cell_data[cell], sizeof(lv_table_cell_t) + len_ap + 1);
table->cell_data[cell] = lv_mem_realloc(table->cell_data[cell], len_ap + 1);
LV_ASSERT_MALLOC(table->cell_data[cell]);
if(table->cell_data[cell] == NULL) {
va_end(ap2);
return;
}
_lv_txt_ap_proc(raw_txt, table->cell_data[cell]->txt);
_lv_txt_ap_proc(raw_txt, &table->cell_data[cell][1]);
lv_mem_buf_release(raw_txt);
#else
table->cell_data[cell] = lv_mem_realloc(table->cell_data[cell],
sizeof(lv_table_cell_t) + len + 1); /*+1: trailing '\0; */
table->cell_data[cell] = lv_mem_realloc(table->cell_data[cell], len + 2); /*+1: trailing '\0; +1: format byte*/
LV_ASSERT_MALLOC(table->cell_data[cell]);
if(table->cell_data[cell] == NULL) {
va_end(ap2);
return;
}
table->cell_data[cell]->txt[len] = 0; /*Ensure NULL termination*/
table->cell_data[cell][len + 1] = 0; /*Ensure NULL termination*/
lv_vsnprintf(table->cell_data[cell]->txt, len + 1, fmt, ap2);
lv_vsnprintf(&table->cell_data[cell][1], len + 1, fmt, ap2);
#endif
va_end(ap2);
table->cell_data[cell]->ctrl = ctrl;
#if LV_USE_USER_DATA
table->cell_data[cell]->user_data = user_data;
#endif
table->cell_data[cell][0] = ctrl;
refr_cell_size(obj, row, col);
}
@@ -224,17 +204,11 @@ void lv_table_set_row_cnt(lv_obj_t * obj, uint16_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 LV_USE_USER_DATA
if(table->cell_data[i]->user_data) {
lv_mem_free(table->cell_data[i]->user_data);
table->cell_data[i]->user_data = NULL;
}
#endif
lv_mem_free(table->cell_data[i]);
}
}
table->cell_data = lv_mem_realloc(table->cell_data, table->row_cnt * table->col_cnt * sizeof(lv_table_cell_t *));
table->cell_data = lv_mem_realloc(table->cell_data, table->row_cnt * table->col_cnt * sizeof(char *));
LV_ASSERT_MALLOC(table->cell_data);
if(table->cell_data == NULL) return;
@@ -259,7 +233,7 @@ void lv_table_set_col_cnt(lv_obj_t * obj, uint16_t col_cnt)
uint16_t old_col_cnt = table->col_cnt;
table->col_cnt = col_cnt;
lv_table_cell_t ** new_cell_data = lv_mem_alloc(table->row_cnt * table->col_cnt * sizeof(lv_table_cell_t *));
char ** new_cell_data = lv_mem_alloc(table->row_cnt * table->col_cnt * sizeof(char *));
LV_ASSERT_MALLOC(new_cell_data);
if(new_cell_data == NULL) return;
uint32_t new_cell_cnt = table->col_cnt * table->row_cnt;
@@ -282,12 +256,6 @@ void lv_table_set_col_cnt(lv_obj_t * obj, uint16_t col_cnt)
int32_t i;
for(i = 0; i < (int32_t)old_col_cnt - col_cnt; i++) {
uint32_t idx = old_col_start + min_col_cnt + i;
#if LV_USE_USER_DATA
if(table->cell_data[idx]->user_data) {
lv_mem_free(table->cell_data[idx]->user_data);
table->cell_data[idx]->user_data = NULL;
}
#endif
lv_mem_free(table->cell_data[idx]);
table->cell_data[idx] = NULL;
}
@@ -336,18 +304,15 @@ void lv_table_add_cell_ctrl(lv_obj_t * obj, uint16_t row, uint16_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_mem_alloc(sizeof(lv_table_cell_t) + 1); /*+1: trailing '\0 */
table->cell_data[cell] = lv_mem_alloc(2); /*+1: trailing '\0; +1: format byte*/
LV_ASSERT_MALLOC(table->cell_data[cell]);
if(table->cell_data[cell] == NULL) return;
table->cell_data[cell]->ctrl = 0;
#if LV_USE_USER_DATA
table->cell_data[cell]->user_data = NULL;
#endif
table->cell_data[cell]->txt[0] = '\0';
table->cell_data[cell][0] = 0;
table->cell_data[cell][1] = '\0';
}
table->cell_data[cell]->ctrl |= ctrl;
table->cell_data[cell][0] |= ctrl;
}
void lv_table_clear_cell_ctrl(lv_obj_t * obj, uint16_t row, uint16_t col, lv_table_cell_ctrl_t ctrl)
@@ -363,51 +328,17 @@ void lv_table_clear_cell_ctrl(lv_obj_t * obj, uint16_t row, uint16_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_mem_alloc(sizeof(lv_table_cell_t) + 1); /*+1: trailing '\0 */
table->cell_data[cell] = lv_mem_alloc(2); /*+1: trailing '\0; +1: format byte*/
LV_ASSERT_MALLOC(table->cell_data[cell]);
if(table->cell_data[cell] == NULL) return;
table->cell_data[cell]->ctrl = 0;
#if LV_USE_USER_DATA
table->cell_data[cell]->user_data = NULL;
#endif
table->cell_data[cell]->txt[0] = '\0';
table->cell_data[cell][0] = 0;
table->cell_data[cell][1] = '\0';
}
table->cell_data[cell]->ctrl &= (~ctrl);
table->cell_data[cell][0] &= (~ctrl);
}
#if LV_USE_USER_DATA
void lv_table_set_cell_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_mem_alloc(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_mem_free(table->cell_data[cell]->user_data);
}
table->cell_data[cell]->user_data = user_data;
}
#endif
/*=====================
* Getter functions
*====================*/
@@ -425,7 +356,7 @@ const char * lv_table_get_cell_value(lv_obj_t * obj, uint16_t row, uint16_t col)
if(is_cell_empty(table->cell_data[cell])) return "";
return table->cell_data[cell]->txt;
return &table->cell_data[cell][1]; /*Skip the format byte*/
}
uint16_t lv_table_get_row_cnt(lv_obj_t * obj)
@@ -470,7 +401,7 @@ bool lv_table_has_cell_ctrl(lv_obj_t * obj, uint16_t row, uint16_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]->ctrl & ctrl) == ctrl;
else return (table->cell_data[cell][0] & ctrl) == ctrl;
}
void lv_table_get_selected_cell(lv_obj_t * obj, uint16_t * row, uint16_t * col)
@@ -480,24 +411,6 @@ void lv_table_get_selected_cell(lv_obj_t * obj, uint16_t * row, uint16_t * col)
*col = table->col_act;
}
#if LV_USE_USER_DATA
void * lv_table_get_cell_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;
}
#endif
/**********************
* STATIC FUNCTIONS
**********************/
@@ -515,7 +428,7 @@ static void lv_table_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
table->row_h = lv_mem_alloc(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_mem_realloc(table->cell_data, table->row_cnt * table->col_cnt * sizeof(lv_table_cell_t *));
table->cell_data = lv_mem_realloc(table->cell_data, table->row_cnt * table->col_cnt * sizeof(char *));
table->cell_data[0] = NULL;
LV_TRACE_OBJ_CREATE("finished");
@@ -529,12 +442,6 @@ static void lv_table_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
uint16_t i;
for(i = 0; i < table->col_cnt * table->row_cnt; i++) {
if(table->cell_data[i]) {
#if LV_USE_USER_DATA
if(table->cell_data[i]->user_data) {
lv_mem_free(table->cell_data[i]->user_data);
table->cell_data[i]->user_data = NULL;
}
#endif
lv_mem_free(table->cell_data[i]);
table->cell_data[i] = NULL;
}
@@ -732,7 +639,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]->ctrl;
if(table->cell_data[cell]) ctrl = table->cell_data[cell][0];
if(rtl) {
cell_area.x2 = cell_area.x1 - 1;
@@ -745,11 +652,11 @@ static void draw_main(lv_event_t * e)
uint16_t col_merge = 0;
for(col_merge = 0; col_merge + col < table->col_cnt - 1; col_merge++) {
lv_table_cell_t * next_cell_data = table->cell_data[cell + col_merge];
char * 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->ctrl;
lv_table_cell_ctrl_t merge_ctrl = (lv_table_cell_ctrl_t) next_cell_data[0];
if(merge_ctrl & LV_TABLE_CELL_CTRL_MERGE_RIGHT) {
lv_coord_t offset = table->col_w[col + col_merge + 1];
@@ -832,7 +739,7 @@ static void draw_main(lv_event_t * e)
bool crop = ctrl & LV_TABLE_CELL_CTRL_TEXT_CROP ? true : false;
if(crop) txt_flags = LV_TEXT_FLAG_EXPAND;
lv_txt_get_size(&txt_size, table->cell_data[cell]->txt, label_dsc_def.font,
lv_txt_get_size(&txt_size, table->cell_data[cell] + 1, label_dsc_def.font,
label_dsc_act.letter_space, label_dsc_act.line_space,
lv_area_get_width(&txt_area), txt_flags);
@@ -847,7 +754,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) {
draw_ctx->clip_area = &label_clip_area;
lv_draw_label(draw_ctx, &label_dsc_act, &txt_area, table->cell_data[cell]->txt, NULL);
lv_draw_label(draw_ctx, &label_dsc_act, &txt_area, table->cell_data[cell] + 1, NULL);
draw_ctx->clip_area = &clip_area;
}
}
@@ -938,7 +845,7 @@ static lv_coord_t get_row_height(lv_obj_t * obj, uint16_t row_id, const lv_font_
uint16_t cell;
uint16_t col;
for(cell = row_start, col = 0; cell < row_start + table->col_cnt; cell++, col++) {
lv_table_cell_t * cell_data = table->cell_data[cell];
char * cell_data = table->cell_data[cell];
if(is_cell_empty(cell_data)) {
continue;
@@ -951,11 +858,11 @@ static lv_coord_t get_row_height(lv_obj_t * obj, uint16_t row_id, const lv_font_
* exit the traversal when the current cell control is not LV_TABLE_CELL_CTRL_MERGE_RIGHT */
uint16_t col_merge = 0;
for(col_merge = 0; col_merge + col < table->col_cnt - 1; col_merge++) {
lv_table_cell_t * next_cell_data = table->cell_data[cell + col_merge];
char * 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->ctrl;
lv_table_cell_ctrl_t ctrl = (lv_table_cell_ctrl_t) next_cell_data[0];
if(ctrl & LV_TABLE_CELL_CTRL_MERGE_RIGHT) {
txt_w += table->col_w[col + col_merge + 1];
}
@@ -964,7 +871,7 @@ static lv_coord_t get_row_height(lv_obj_t * obj, uint16_t row_id, const lv_font_
}
}
lv_table_cell_ctrl_t ctrl = (lv_table_cell_ctrl_t) cell_data->ctrl;
lv_table_cell_ctrl_t ctrl = (lv_table_cell_ctrl_t) cell_data[0];
/*When cropping the text we can assume the row height is equal to the line height*/
if(ctrl & LV_TABLE_CELL_CTRL_TEXT_CROP) {
@@ -976,7 +883,7 @@ static lv_coord_t get_row_height(lv_obj_t * obj, uint16_t row_id, const lv_font_
lv_point_t txt_size;
txt_w -= cell_left + cell_right;
lv_txt_get_size(&txt_size, table->cell_data[cell]->txt, font,
lv_txt_get_size(&txt_size, table->cell_data[cell] + 1, font,
letter_space, line_space, txt_w, LV_TEXT_FLAG_NONE);
h_max = LV_MAX(txt_size.y + cell_top + cell_bottom, h_max);
@@ -1046,21 +953,23 @@ static size_t get_cell_txt_len(const char * txt)
size_t retval = 0;
#if LV_USE_ARABIC_PERSIAN_CHARS
retval = sizeof(lv_table_cell_t) + _lv_txt_ap_calc_bytes_cnt(txt) + 1;
retval = _lv_txt_ap_calc_bytes_cnt(txt) + 1;
#else
retval = sizeof(lv_table_cell_t) + strlen(txt) + 1;
/* cell_data layout: [ctrl][txt][trailing '\0' terminator]
* +2 because of the trailing '\0' and the ctrl */
retval = strlen(txt) + 2;
#endif
return retval;
}
/* Copy txt into dst skipping the format byte */
static void copy_cell_txt(lv_table_cell_t * dst, const char * txt)
static void copy_cell_txt(char * dst, const char * txt)
{
#if LV_USE_ARABIC_PERSIAN_CHARS
_lv_txt_ap_proc(txt, dst->txt);
_lv_txt_ap_proc(txt, &dst[1]);
#else
strcpy(dst->txt, txt);
strcpy(&dst[1], txt);
#endif
}

View File

@@ -46,21 +46,12 @@ enum {
typedef uint8_t lv_table_cell_ctrl_t;
/*Data of cell*/
typedef struct {
lv_table_cell_ctrl_t ctrl;
#if LV_USE_USER_DATA
void * user_data; /**< Custom user data*/
#endif
char txt[];
} lv_table_cell_t;
/*Data of table*/
typedef struct {
lv_obj_t obj;
uint16_t col_cnt;
uint16_t row_cnt;
lv_table_cell_t ** cell_data;
char ** cell_data;
lv_coord_t * row_h;
lv_coord_t * col_w;
uint16_t col_act;
@@ -153,17 +144,6 @@ void lv_table_add_cell_ctrl(lv_obj_t * obj, uint16_t row, uint16_t col, lv_table
*/
void lv_table_clear_cell_ctrl(lv_obj_t * obj, uint16_t row, uint16_t col, lv_table_cell_ctrl_t ctrl);
#if LV_USE_USER_DATA
/**
* 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. It must be allocated by user as it will be freed automatically
*/
void lv_table_set_cell_user_data(lv_obj_t * obj, uint16_t row, uint16_t col, void * user_data);
#endif
/*=====================
* Getter functions
*====================*/
@@ -217,16 +197,6 @@ bool lv_table_has_cell_ctrl(lv_obj_t * obj, uint16_t row, uint16_t col, lv_table
*/
void lv_table_get_selected_cell(lv_obj_t * obj, uint16_t * row, uint16_t * col);
#if LV_USE_USER_DATA
/**
* 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_cell_user_data(lv_obj_t * obj, uint16_t row, uint16_t col);
#endif
/**********************
* MACROS
**********************/