From c1140ec6a7d5b8132c50fc6aa1843496ed9307ce Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 28 Nov 2018 22:02:51 +0100 Subject: [PATCH 01/42] begin lv_table --- lv_objx/lv_table.c | 307 +++++++++++++++++++++++++++++++++++++++++++++ lv_objx/lv_table.h | 108 ++++++++++++++++ lvgl.h | 1 + 3 files changed, 416 insertions(+) create mode 100644 lv_objx/lv_table.c create mode 100644 lv_objx/lv_table.h diff --git a/lv_objx/lv_table.c b/lv_objx/lv_table.c new file mode 100644 index 000000000..106c56b25 --- /dev/null +++ b/lv_objx/lv_table.c @@ -0,0 +1,307 @@ +/** + * @file lv_table.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_table.h" +#if USE_LV_TABLE != 0 + +#include "../lv_misc/lv_txt.h" +#include "../lv_misc/lv_math.h" +#include "../lv_draw/lv_draw_label.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ +static bool lv_table_design(lv_obj_t * table, const lv_area_t * mask, lv_design_mode_t mode); +static lv_res_t lv_table_signal(lv_obj_t * table, lv_signal_t sign, void * param); +static lv_coord_t get_row_height(lv_obj_t * table, uint16_t row_id); + +/********************** + * STATIC VARIABLES + **********************/ +static lv_signal_func_t ancestor_signal; +static lv_design_func_t ancestor_scrl_design; + +static const char * cell_data_example[] = {"r1", "rc11", "rc12", + "ro row 2", "rc21", "rc22", + "row3", "rc31", "rc32", + "row4", "rc41", "rc42"}; + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/** + * Create a table object + * @param par pointer to an object, it will be the parent of the new table + * @param copy pointer to a table object, if not NULL then the new object will be copied from it + * @return pointer to the created table + */ +lv_obj_t * lv_table_create(lv_obj_t * par, const lv_obj_t * copy) +{ + LV_LOG_TRACE("table create started"); + + /*Create the ancestor of table*/ + lv_obj_t * new_table = lv_obj_create(par, copy); + lv_mem_assert(new_table); + if(new_table == NULL) return NULL; + + /*Allocate the table type specific extended data*/ + lv_table_ext_t * ext = lv_obj_allocate_ext_attr(new_table, sizeof(lv_table_ext_t)); + lv_mem_assert(ext); + if(ext == NULL) return NULL; + if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_func(new_table); + if(ancestor_scrl_design == NULL) ancestor_scrl_design = lv_obj_get_design_func(new_table); + + /*Initialize the allocated 'ext' */ + ext->cell_data = cell_data_example; + ext->cell_style = &lv_style_pretty; + ext->col_cnt = 3; + ext->row_cnt = 4; + ext->col_w[0] = 50; + ext->col_w[1] = 70; + ext->col_w[2] = 80; + + /*The signal and design functions are not copied so set them here*/ + lv_obj_set_signal_func(new_table, lv_table_signal); + lv_obj_set_design_func(new_table, lv_table_design); + + /*Init the new table table*/ + if(copy == NULL) { + + } + /*Copy an existing table*/ + else { + lv_table_ext_t * copy_ext = lv_obj_get_ext_attr(copy); + + /*Refresh the style with new signal function*/ + lv_obj_refresh_style(new_table); + } + + LV_LOG_INFO("table created"); + + return new_table; +} + +/*====================== + * Add/remove functions + *=====================*/ + +/* + * New object specific "add" or "remove" functions come here + */ + + +/*===================== + * Setter functions + *====================*/ + +/* + * New object specific "set" functions come here + */ + + +/** + * Set a style of a table. + * @param table pointer to table object + * @param type which style should be set + * @param style pointer to a style + */ +void lv_table_set_style(lv_obj_t * table, lv_table_style_t type, lv_style_t * style) +{ + lv_table_ext_t * ext = lv_obj_get_ext_attr(table); + + switch(type) { + case LV_TABLE_STYLE_X: + break; + case LV_TABLE_STYLE_Y: + break; + } +} + +/*===================== + * Getter functions + *====================*/ + +/* + * New object specific "get" functions come here + */ + +/** + * Get style of a table. + * @param table pointer to table object + * @param type which style should be get + * @return style pointer to the style + */ +lv_style_t * lv_table_get_style(const lv_obj_t * table, lv_table_style_t type) +{ + lv_table_ext_t * ext = lv_obj_get_ext_attr(table); + + switch(type) { + case LV_TABLE_STYLE_X: + return NULL; + case LV_TABLE_STYLE_Y: + return NULL; + default: + return NULL; + } + + /*To avoid warning*/ + return NULL; +} + +/*===================== + * Other functions + *====================*/ + +/* + * New object specific "other" functions come here + */ + +/********************** + * STATIC FUNCTIONS + **********************/ + +/** + * Handle the drawing related tasks of the tables + * @param table pointer to an object + * @param mask the object will be drawn only in this area + * @param mode LV_DESIGN_COVER_CHK: only check if the object fully covers the 'mask_p' area + * (return 'true' if yes) + * LV_DESIGN_DRAW: draw the object (always return 'true') + * LV_DESIGN_DRAW_POST: drawing after every children are drawn + * @param return true/false, depends on 'mode' + */ +static bool lv_table_design(lv_obj_t * table, const lv_area_t * mask, lv_design_mode_t mode) +{ + /*Return false if the object is not covers the mask_p area*/ + if(mode == LV_DESIGN_COVER_CHK) { + return false; + } + /*Draw the object*/ + else if(mode == LV_DESIGN_DRAW_MAIN) { + ancestor_scrl_design(table, mask, mode); + + lv_table_ext_t * ext = lv_obj_get_ext_attr(table); + lv_coord_t h_row; + lv_point_t txt_size; + lv_area_t cell_area; + lv_area_t txt_area; + + uint16_t col; + uint16_t row; + uint16_t cell = 0; + + cell_area.y2 = table->coords.y1; + for(row = 0; row < ext->row_cnt; row++) { + h_row = get_row_height(table, row); + + cell_area.y1 = cell_area.y2; + cell_area.y2 = cell_area.y1 + h_row; + + + uint16_t col_x = 0; + for(col = 0; col < ext->col_cnt; col++) { + + cell_area.x1 = table->coords.x1 + col_x; + cell_area.x2 = cell_area.x1 + ext->col_w[col]; + + txt_area.x1 = cell_area.x1 + ext->cell_style->body.padding.hor; + txt_area.x2 = cell_area.x2 - ext->cell_style->body.padding.hor; + txt_area.y1 = cell_area.y1 + ext->cell_style->body.padding.ver; + txt_area.y2 = cell_area.y2 - ext->cell_style->body.padding.ver; + + lv_txt_get_size(&txt_size, ext->cell_data[cell], ext->cell_style->text.font, + ext->cell_style->text.letter_space, ext->cell_style->text.line_space, lv_area_get_width(&txt_area), LV_TXT_FLAG_NONE); + + col_x += ext->col_w[col]; + + lv_draw_rect(&cell_area, mask, ext->cell_style, LV_OPA_COVER); + lv_draw_label(&txt_area, mask, ext->cell_style, LV_OPA_COVER, ext->cell_data[cell], LV_TXT_FLAG_NONE, NULL); + + cell++; + } + } + + + + } + /*Post draw when the children are drawn*/ + else if(mode == LV_DESIGN_DRAW_POST) { + + } + + return true; +} + +/** + * Signal function of the table + * @param table pointer to a table object + * @param sign a signal type from lv_signal_t enum + * @param param pointer to a signal specific variable + * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted + */ +static lv_res_t lv_table_signal(lv_obj_t * table, lv_signal_t sign, void * param) +{ + lv_res_t res; + + /* Include the ancient signal function */ + res = ancestor_signal(table, sign, param); + if(res != LV_RES_OK) return res; + + + if(sign == LV_SIGNAL_CLEANUP) { + /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/ + } else if(sign == LV_SIGNAL_GET_TYPE) { + lv_obj_type_t * buf = param; + uint8_t i; + for(i = 0; i < LV_MAX_ANCESTOR_NUM - 1; i++) { /*Find the last set data*/ + if(buf->type[i] == NULL) break; + } + buf->type[i] = "lv_table"; + } + + return res; +} + +static lv_coord_t get_row_height(lv_obj_t * table, uint16_t row_id) +{ + lv_table_ext_t * ext = lv_obj_get_ext_attr(table); + lv_point_t txt_size; + lv_coord_t txt_w; + + uint16_t row_start = row_id * ext->col_cnt; + uint16_t cell; + uint16_t col; + lv_coord_t h_max = 0; + + for(cell = row_start, col = 0; cell < row_start + ext->col_cnt; cell++, col ++) { + txt_w = ext->col_w[col] - 2 * ext->cell_style->body.padding.hor; + lv_txt_get_size(&txt_size, ext->cell_data[cell], ext->cell_style->text.font, + ext->cell_style->text.letter_space, ext->cell_style->text.line_space, txt_w, LV_TXT_FLAG_NONE); + + h_max = LV_MATH_MAX(txt_size.y, h_max); + } + + printf("row:%d, h:%d\n", row_id, h_max); + + return h_max + 2 * ext->cell_style->body.padding.ver; +} + +#endif diff --git a/lv_objx/lv_table.h b/lv_objx/lv_table.h new file mode 100644 index 000000000..0009685fe --- /dev/null +++ b/lv_objx/lv_table.h @@ -0,0 +1,108 @@ +/** + * @file lv_table.h + * + */ + +#ifndef LV_TABLE_H +#define LV_TABLE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#ifdef LV_CONF_INCLUDE_SIMPLE +#include "lv_conf.h" +#else +#include "../../lv_conf.h" +#endif + +#if USE_LV_TABLE != 0 + +#include "../lv_core/lv_obj.h" + +/********************* + * DEFINES + *********************/ +#define LV_TABLE_COL_MAX 12 + +/********************** + * TYPEDEFS + **********************/ +/*Data of table*/ +typedef struct { + /*New data for this type */ + uint16_t col_cnt; + uint16_t row_cnt; + const char ** cell_data; + lv_style_t * cell_style; + lv_coord_t col_w[LV_TABLE_COL_MAX]; +} lv_table_ext_t; + + +/*Styles*/ +enum { + LV_TABLE_STYLE_X, + LV_TABLE_STYLE_Y, +}; +typedef uint8_t lv_table_style_t; + + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/** + * Create a table objects + * @param par pointer to an object, it will be the parent of the new table + * @param copy pointer to a table object, if not NULL then the new object will be copied from it + * @return pointer to the created table + */ +lv_obj_t * lv_table_create(lv_obj_t * par, const lv_obj_t * copy); + +/*====================== + * Add/remove functions + *=====================*/ + + +/*===================== + * Setter functions + *====================*/ + +/** + * Set a style of a table. + * @param table pointer to table object + * @param type which style should be set + * @param style pointer to a style + */ +void lv_table_set_style(lv_obj_t * table, lv_table_style_t type, lv_style_t *style); + +/*===================== + * Getter functions + *====================*/ + +/** + * Get style of a table. + * @param table pointer to table object + * @param type which style should be get + * @return style pointer to the style + */ +lv_style_t * lv_table_get_style(const lv_obj_t * table, lv_table_style_t type); + +/*===================== + * Other functions + *====================*/ + +/********************** + * MACROS + **********************/ + +#endif /*USE_LV_TABLE*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /*LV_TABLE_H*/ diff --git a/lvgl.h b/lvgl.h index dfaf55a92..7e0792c48 100644 --- a/lvgl.h +++ b/lvgl.h @@ -36,6 +36,7 @@ extern "C" { #include "lv_objx/lv_cont.h" #include "lv_objx/lv_list.h" #include "lv_objx/lv_chart.h" +#include "lv_objx/lv_table.h" #include "lv_objx/lv_cb.h" #include "lv_objx/lv_bar.h" #include "lv_objx/lv_slider.h" From e7058e9135f3db41c1f4ea4017946de9229d1fab Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Thu, 29 Nov 2018 08:52:21 +0100 Subject: [PATCH 02/42] table updates --- lv_objx/lv_table.c | 211 ++++++++++++++++++++++++++++++++++++++------- lv_objx/lv_table.h | 27 +++++- 2 files changed, 207 insertions(+), 31 deletions(-) diff --git a/lv_objx/lv_table.c b/lv_objx/lv_table.c index 106c56b25..6ef9fe78d 100644 --- a/lv_objx/lv_table.c +++ b/lv_objx/lv_table.c @@ -27,6 +27,7 @@ static bool lv_table_design(lv_obj_t * table, const lv_area_t * mask, lv_design_mode_t mode); static lv_res_t lv_table_signal(lv_obj_t * table, lv_signal_t sign, void * param); static lv_coord_t get_row_height(lv_obj_t * table, uint16_t row_id); +static void refr_size(lv_obj_t * table); /********************** * STATIC VARIABLES @@ -34,11 +35,6 @@ static lv_coord_t get_row_height(lv_obj_t * table, uint16_t row_id); static lv_signal_func_t ancestor_signal; static lv_design_func_t ancestor_scrl_design; -static const char * cell_data_example[] = {"r1", "rc11", "rc12", - "ro row 2", "rc21", "rc22", - "row3", "rc31", "rc32", - "row4", "rc41", "rc42"}; - /********************** * MACROS **********************/ @@ -70,10 +66,10 @@ lv_obj_t * lv_table_create(lv_obj_t * par, const lv_obj_t * copy) if(ancestor_scrl_design == NULL) ancestor_scrl_design = lv_obj_get_design_func(new_table); /*Initialize the allocated 'ext' */ - ext->cell_data = cell_data_example; + ext->cell_data = NULL; ext->cell_style = &lv_style_pretty; - ext->col_cnt = 3; - ext->row_cnt = 4; + ext->col_cnt = 0; + ext->row_cnt = 0; ext->col_w[0] = 50; ext->col_w[1] = 70; ext->col_w[2] = 80; @@ -112,9 +108,92 @@ lv_obj_t * lv_table_create(lv_obj_t * par, const lv_obj_t * copy) * Setter functions *====================*/ -/* - * New object specific "set" functions come here - */ +void lv_table_set_cell_value(lv_obj_t * table, uint16_t row, uint16_t col, const char * txt) +{ + lv_table_ext_t * ext = lv_obj_get_ext_attr(table); + if(row >= ext->row_cnt || col >= ext->col_cnt) { + LV_LOG_WARN("lv_table_set_cell_value: invalid row or column"); + return; + } + uint32_t cell = row * ext->col_cnt + col; + ext->cell_data[cell] = lv_mem_realloc(ext->cell_data[cell], strlen(txt) + 2); /*+1: trailing '\0; +1: format byte*/ + strcpy(ext->cell_data[cell] + 1, txt); /*Leave the format byte*/ + refr_size(table); +} + +void lv_table_set_cell_format(lv_obj_t * table, uint16_t row, uint16_t col, lv_table_cell_align_t align) +{ + lv_table_ext_t * ext = lv_obj_get_ext_attr(table); + if(row >= ext->row_cnt || col >= ext->col_cnt) { + LV_LOG_WARN("lv_table_set_cell_format: invalid row or column"); + return; + } + uint32_t cell = row * ext->col_cnt + col; + + if(ext->cell_data[cell] == NULL) { + ext->cell_data[cell] = lv_mem_alloc(2); /*+1: trailing '\0; +1: format byte*/ + ext->cell_data[1] = '\0'; + } + + lv_table_cell_format_t format; + format.format_byte = ext->cell_data[cell][0]; + format.align = align; + ext->cell_data[cell][0] = format.format_byte; +} + +void lv_table_set_cell_merge_right(lv_obj_t * table, uint16_t row, uint16_t col, bool en) +{ + lv_table_ext_t * ext = lv_obj_get_ext_attr(table); + if(row >= ext->row_cnt || col >= ext->col_cnt) { + LV_LOG_WARN("lv_table_set_cell_merge_right: invalid row or column"); + return; + } + + uint32_t cell = row * ext->col_cnt + col; + + if(ext->cell_data[cell] == NULL) { + ext->cell_data[cell] = lv_mem_alloc(2); /*+1: trailing '\0; +1: format byte*/ + ext->cell_data[1] = '\0'; + } + + lv_table_cell_format_t format; + format.format_byte = ext->cell_data[cell][0]; + format.right_merge = en ? 1 : 0; + ext->cell_data[cell][0] = format.format_byte; +} + + + +void lv_table_set_row_cnt(lv_obj_t * table, uint16_t row_cnt) +{ + lv_table_ext_t * ext = lv_obj_get_ext_attr(table); + ext->row_cnt = row_cnt; + + if(ext->row_cnt > 0 && ext->col_cnt > 0) { + ext->cell_data = lv_mem_realloc(ext->cell_data, ext->row_cnt * ext->col_cnt * sizeof(char*)); + } + else { + lv_mem_free(ext->cell_data); + ext->cell_data = NULL; + } + + refr_size(table); +} + +void lv_table_set_col_cnt(lv_obj_t * table, uint16_t col_cnt) +{ + lv_table_ext_t * ext = lv_obj_get_ext_attr(table); + ext->col_cnt = col_cnt; + + if(ext->row_cnt > 0 && ext->col_cnt > 0) { + ext->cell_data = lv_mem_realloc(ext->cell_data, ext->row_cnt * ext->col_cnt * sizeof(char*)); + } + else { + lv_mem_free(ext->cell_data); + ext->cell_data = NULL; + } + refr_size(table); +} /** @@ -199,43 +278,76 @@ static bool lv_table_design(lv_obj_t * table, const lv_area_t * mask, lv_design_ ancestor_scrl_design(table, mask, mode); lv_table_ext_t * ext = lv_obj_get_ext_attr(table); + lv_style_t * bg_style = lv_obj_get_style(table); lv_coord_t h_row; lv_point_t txt_size; lv_area_t cell_area; lv_area_t txt_area; + lv_txt_flag_t txt_flags; uint16_t col; uint16_t row; uint16_t cell = 0; - cell_area.y2 = table->coords.y1; + cell_area.y2 = table->coords.y1 + bg_style->body.padding.ver; for(row = 0; row < ext->row_cnt; row++) { h_row = get_row_height(table, row); cell_area.y1 = cell_area.y2; cell_area.y2 = cell_area.y1 + h_row; + cell_area.x2 = table->coords.x1 + bg_style->body.padding.hor; - uint16_t col_x = 0; for(col = 0; col < ext->col_cnt; col++) { - cell_area.x1 = table->coords.x1 + col_x; + cell_area.x1 = cell_area.x2; cell_area.x2 = cell_area.x1 + ext->col_w[col]; - txt_area.x1 = cell_area.x1 + ext->cell_style->body.padding.hor; - txt_area.x2 = cell_area.x2 - ext->cell_style->body.padding.hor; - txt_area.y1 = cell_area.y1 + ext->cell_style->body.padding.ver; - txt_area.y2 = cell_area.y2 - ext->cell_style->body.padding.ver; + uint16_t col_merge = 0; + for(col_merge = 0; col_merge + col < ext->col_cnt - 1; col_merge ++) { - lv_txt_get_size(&txt_size, ext->cell_data[cell], ext->cell_style->text.font, - ext->cell_style->text.letter_space, ext->cell_style->text.line_space, lv_area_get_width(&txt_area), LV_TXT_FLAG_NONE); + if(ext->cell_data[cell + col_merge] != NULL) { + lv_table_cell_format_t format; + format.format_byte = ext->cell_data[cell + col_merge][0]; + if(format.right_merge) cell_area.x2 += ext->col_w[col + col_merge + 1]; + else break; + } else { + break; + } + } - col_x += ext->col_w[col]; lv_draw_rect(&cell_area, mask, ext->cell_style, LV_OPA_COVER); - lv_draw_label(&txt_area, mask, ext->cell_style, LV_OPA_COVER, ext->cell_data[cell], LV_TXT_FLAG_NONE, NULL); - cell++; + if(ext->cell_data[cell]) { + txt_area.x1 = cell_area.x1 + ext->cell_style->body.padding.hor; + txt_area.x2 = cell_area.x2 - ext->cell_style->body.padding.hor; + txt_area.y1 = cell_area.y1 + ext->cell_style->body.padding.ver; + txt_area.y2 = cell_area.y2 - ext->cell_style->body.padding.ver; + + lv_table_cell_format_t format; + format.format_byte = ext->cell_data[cell][0]; + + switch(format.align) { + case LV_TABLE_CELL_ALIGN_LEFT: + txt_flags = LV_TXT_FLAG_NONE; + break; + case LV_TABLE_CELL_ALIGN_RIGHT: + txt_flags = LV_TXT_FLAG_RIGHT; + break; + case LV_TABLE_CELL_ALIGN_CENTER: + txt_flags = LV_TXT_FLAG_CENTER; + break; + } + + lv_txt_get_size(&txt_size, ext->cell_data[cell] + 1, ext->cell_style->text.font, + ext->cell_style->text.letter_space, ext->cell_style->text.line_space, lv_area_get_width(&txt_area), txt_flags); + + lv_draw_label(&txt_area, mask, ext->cell_style, LV_OPA_COVER, ext->cell_data[cell] + 1, txt_flags, NULL); + } + + cell += col_merge + 1; + col += col_merge; } } @@ -280,6 +392,30 @@ static lv_res_t lv_table_signal(lv_obj_t * table, lv_signal_t sign, void * param return res; } +static void refr_size(lv_obj_t * table) +{ + lv_coord_t h = 0; + lv_coord_t w = 0; + + lv_table_ext_t * ext = lv_obj_get_ext_attr(table); + + uint16_t i; + for(i= 0; i < ext->col_cnt; i++) { + w += ext->col_w[i]; + } + for(i= 0; i < ext->row_cnt; i++) { + h += get_row_height(table, i); + } + + lv_style_t * bg_style = lv_obj_get_style(table); + + w += bg_style->body.padding.hor * 2; + h += bg_style->body.padding.ver * 2; + + lv_obj_set_size(table, w, h); + lv_obj_invalidate(table); +} + static lv_coord_t get_row_height(lv_obj_t * table, uint16_t row_id) { lv_table_ext_t * ext = lv_obj_get_ext_attr(table); @@ -289,18 +425,33 @@ static lv_coord_t get_row_height(lv_obj_t * table, uint16_t row_id) uint16_t row_start = row_id * ext->col_cnt; uint16_t cell; uint16_t col; - lv_coord_t h_max = 0; + lv_coord_t h_max = lv_font_get_height(ext->cell_style->text.font); for(cell = row_start, col = 0; cell < row_start + ext->col_cnt; cell++, col ++) { - txt_w = ext->col_w[col] - 2 * ext->cell_style->body.padding.hor; - lv_txt_get_size(&txt_size, ext->cell_data[cell], ext->cell_style->text.font, - ext->cell_style->text.letter_space, ext->cell_style->text.line_space, txt_w, LV_TXT_FLAG_NONE); + if(ext->cell_data[cell] != NULL) { - h_max = LV_MATH_MAX(txt_size.y, h_max); + txt_w = ext->col_w[col]; + uint16_t col_merge = 0; + for(col_merge = 0; col_merge + col < ext->col_cnt - 1; col_merge ++) { + + if(ext->cell_data[cell + col_merge] != NULL) { + lv_table_cell_format_t format; + format.format_byte = ext->cell_data[cell + col_merge][0]; + if(format.right_merge) txt_w += ext->col_w[col + col_merge + 1]; + else break; + } else { + break; + } + } + + txt_w -= 2 * ext->cell_style->body.padding.hor; + lv_txt_get_size(&txt_size, ext->cell_data[cell] + 1, ext->cell_style->text.font, + ext->cell_style->text.letter_space, ext->cell_style->text.line_space, txt_w, LV_TXT_FLAG_NONE); + + h_max = LV_MATH_MAX(txt_size.y, h_max); + } } - printf("row:%d, h:%d\n", row_id, h_max); - return h_max + 2 * ext->cell_style->body.padding.ver; } diff --git a/lv_objx/lv_table.h b/lv_objx/lv_table.h index 0009685fe..efb17dc55 100644 --- a/lv_objx/lv_table.h +++ b/lv_objx/lv_table.h @@ -31,12 +31,27 @@ extern "C" { /********************** * TYPEDEFS **********************/ + +typedef enum { + LV_TABLE_CELL_ALIGN_LEFT, + LV_TABLE_CELL_ALIGN_RIGHT, + LV_TABLE_CELL_ALIGN_CENTER, +}lv_table_cell_align_t; + +typedef union { + struct { + uint8_t align:2; + uint8_t right_merge:1; + }; + uint8_t format_byte; +}lv_table_cell_format_t; + /*Data of table*/ typedef struct { /*New data for this type */ uint16_t col_cnt; uint16_t row_cnt; - const char ** cell_data; + char ** cell_data; lv_style_t * cell_style; lv_coord_t col_w[LV_TABLE_COL_MAX]; } lv_table_ext_t; @@ -62,6 +77,16 @@ typedef uint8_t lv_table_style_t; */ lv_obj_t * lv_table_create(lv_obj_t * par, const lv_obj_t * copy); +void lv_table_set_cell_value(lv_obj_t * table, uint16_t row, uint16_t col, const char * txt); + +void lv_table_set_cell_format(lv_obj_t * table, uint16_t row, uint16_t col, lv_table_cell_align_t align); + +void lv_table_set_cell_merge_right(lv_obj_t * table, uint16_t row, uint16_t col, bool en); + +void lv_table_set_row_cnt(lv_obj_t * table, uint16_t row_cnt); + +void lv_table_set_col_cnt(lv_obj_t * table, uint16_t col_cnt); + /*====================== * Add/remove functions *=====================*/ From 1e195746458aae5b5d91e1b89a1b7de0a2943161 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Thu, 29 Nov 2018 10:02:34 +0100 Subject: [PATCH 03/42] lv_table: fix --- lv_objx/lv_table.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lv_objx/lv_table.c b/lv_objx/lv_table.c index 6ef9fe78d..ea538009d 100644 --- a/lv_objx/lv_table.c +++ b/lv_objx/lv_table.c @@ -160,6 +160,7 @@ void lv_table_set_cell_merge_right(lv_obj_t * table, uint16_t row, uint16_t col, format.format_byte = ext->cell_data[cell][0]; format.right_merge = en ? 1 : 0; ext->cell_data[cell][0] = format.format_byte; + refr_size(table); } @@ -445,10 +446,14 @@ static lv_coord_t get_row_height(lv_obj_t * table, uint16_t row_id) } txt_w -= 2 * ext->cell_style->body.padding.hor; + printf("r:%d, c:%d, txt_w:%d\n", row_id, col, txt_w); + lv_txt_get_size(&txt_size, ext->cell_data[cell] + 1, ext->cell_style->text.font, ext->cell_style->text.letter_space, ext->cell_style->text.line_space, txt_w, LV_TXT_FLAG_NONE); h_max = LV_MATH_MAX(txt_size.y, h_max); + cell += col_merge; + col += col_merge; } } From 7da01d86836e4108e8fed244265ff4f85af5fb77 Mon Sep 17 00:00:00 2001 From: Samuel Date: Mon, 3 Dec 2018 19:44:58 +0800 Subject: [PATCH 04/42] Update lv_list.c --- lv_objx/lv_list.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/lv_objx/lv_list.c b/lv_objx/lv_list.c index b0f485ec4..63e706ab4 100644 --- a/lv_objx/lv_list.c +++ b/lv_objx/lv_list.c @@ -256,6 +256,29 @@ bool lv_list_remove(const lv_obj_t * list, uint32_t index) * Setter functions *====================*/ +/** + * Make a single button selected in the list, deselect others, should be called in list btns call back. + * @param btn pointer to the currently pressed list btn object + */ +void lv_list_set_btn_single_selected(lv_obj_t *btn) +{ + lv_obj_t *list = lv_obj_get_parent(lv_obj_get_parent(btn)); + + lv_obj_t * e = lv_list_get_next_btn(list, NULL); + do + { + if(e == btn) + { + lv_btn_set_state(e, LV_BTN_STATE_TGL_REL); + } + else + { + lv_btn_set_state(e, LV_BTN_STATE_REL); + } + e = lv_list_get_next_btn(list, e); + } while (e != NULL); +} + #if USE_LV_GROUP /** From cde5f311354c481160adc0e3df57553fca106626 Mon Sep 17 00:00:00 2001 From: Samuel Date: Mon, 3 Dec 2018 19:45:47 +0800 Subject: [PATCH 05/42] Update lv_list.h --- lv_objx/lv_list.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lv_objx/lv_list.h b/lv_objx/lv_list.h index a1ecaf3ce..f6db5d4cb 100644 --- a/lv_objx/lv_list.h +++ b/lv_objx/lv_list.h @@ -119,6 +119,13 @@ bool lv_list_remove(const lv_obj_t * list, uint32_t index); /*===================== * Setter functions *====================*/ + +/** + * Make a single button selected in the list, deselect others, should be called in list btns call back. + * @param btn pointer to the currently pressed list btn object + */ +void lv_list_set_btn_single_selected(lv_obj_t *btn); + #if USE_LV_GROUP /** From 546262df389d02ee2535a64c9a8d81b2342a26d5 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 5 Dec 2018 06:42:37 +0100 Subject: [PATCH 06/42] add PRESS action handling to keypad indev --- lv_core/lv_indev.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lv_core/lv_indev.c b/lv_core/lv_indev.c index b0ccd1d15..69dc29bd0 100644 --- a/lv_core/lv_indev.c +++ b/lv_core/lv_indev.c @@ -368,6 +368,10 @@ static void indev_keypad_proc(lv_indev_t * i, lv_indev_data_t * data) if(data->state == LV_INDEV_STATE_PR && i->proc.last_state == LV_INDEV_STATE_REL) { i->proc.pr_timestamp = lv_tick_get(); + lv_obj_t * focused = lv_group_get_focused(i->group); + if(focused) { + focused->signal_func(focused, LV_SIGNAL_PRESSED, indev_act); + } } /*Pressing*/ else if(data->state == LV_INDEV_STATE_PR && i->proc.last_state == LV_INDEV_STATE_PR) { From 64a2a85077470100f560de621666cfed2a2fbe6e Mon Sep 17 00:00:00 2001 From: Alexander Date: Tue, 4 Dec 2018 18:54:26 +0200 Subject: [PATCH 07/42] Compilation error fixes --- lv_core/lv_refr.c | 1 - lv_objx/lv_chart.c | 2 -- lv_objx/lv_imgbtn.c | 5 +++-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/lv_core/lv_refr.c b/lv_core/lv_refr.c index 766c6e2e9..63c9bdc86 100644 --- a/lv_core/lv_refr.c +++ b/lv_core/lv_refr.c @@ -514,7 +514,6 @@ static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p) if(union_ok != false) { /* Redraw the object */ - lv_style_t * style = lv_obj_get_style(obj); obj->design_func(obj, &obj_ext_mask, LV_DESIGN_DRAW_MAIN); //tick_wait_ms(100); /*DEBUG: Wait after every object draw to see the order of drawing*/ diff --git a/lv_objx/lv_chart.c b/lv_objx/lv_chart.c index b3ac83880..92e09a400 100644 --- a/lv_objx/lv_chart.c +++ b/lv_objx/lv_chart.c @@ -731,7 +731,6 @@ static void lv_chart_draw_cols(lv_obj_t * chart, const lv_area_t * mask) col_a.y2 = chart->coords.y2; lv_coord_t x_act; - printf("\n", y_tmp); /*Go through all points*/ for(i = 0; i < ext->point_cnt; i ++) { @@ -749,7 +748,6 @@ static void lv_chart_draw_cols(lv_obj_t * chart, const lv_area_t * mask) lv_coord_t p_act = (ser->start_point + i) % ext->point_cnt; y_tmp = (int32_t)((int32_t) ser->points[p_act] - ext->ymin) * h; y_tmp = y_tmp / (ext->ymax - ext->ymin); - printf("ytmp:%d\n", y_tmp); col_a.y1 = h - y_tmp + chart->coords.y1; mask_ret = lv_area_intersect(&col_mask, mask, &col_a); diff --git a/lv_objx/lv_imgbtn.c b/lv_objx/lv_imgbtn.c index b7e061fb2..5bec801f1 100644 --- a/lv_objx/lv_imgbtn.c +++ b/lv_objx/lv_imgbtn.c @@ -81,10 +81,11 @@ lv_obj_t * lv_imgbtn_create(lv_obj_t * par, const lv_obj_t * copy) } /*Copy an existing image button*/ else { - lv_imgbtn_ext_t * copy_ext = lv_obj_get_ext_attr(copy); #if LV_IMGBTN_TILED == 0 memset(ext->img_src, 0, sizeof(ext->img_src)); #else + lv_imgbtn_ext_t * copy_ext = lv_obj_get_ext_attr(copy); + memcpy(ext->img_src_left, copy_ext->img_src_left, sizeof(ext->img_src_left)); memcpy(ext->img_src_mid, copy_ext->img_src_mid, sizeof(ext->img_src_mid)); memcpy(ext->img_src_right, copy_ext->img_src_right, sizeof(ext->img_src_right)); @@ -163,7 +164,7 @@ void lv_imgbtn_set_style(lv_obj_t * imgbtn, lv_imgbtn_style_t type, lv_style_t * */ const void * lv_imgbtn_get_src(lv_obj_t * imgbtn, lv_btn_state_t state) { - lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn); +// lv_imgbtn_ext_t * ext = lv_obj_get_ext_attr(imgbtn); return NULL;//ext->img_src[state]; } From 545b97de65d3aee1ce047d177e6deba8f41a2455 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Thu, 6 Dec 2018 22:07:35 +0100 Subject: [PATCH 08/42] Update CONTRIBUTING.md --- docs/CONTRIBUTING.md | 266 +++++++++++++++---------------------------- 1 file changed, 89 insertions(+), 177 deletions(-) diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 51d97fa02..fd04d47a5 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -1,181 +1,93 @@ # Contributing to Littlev Graphics Library -It's glad to see that you are interested in Contributing to LittlevGL! -In this guide you can learn how can you help to develop LittlevGL. - -### Table Of Content -* [Who can contribute?](#who-can-contribute) -* [How to report an issue?](#how-to-report-a-bug) -* [How to suggest a feature?](#how-to-suggest-a-feature) -* [How to implement a feature?](#how-to-implement-a-feature) -* [Styling guide](#styling-guide) - -## Who can contribute? -As graphical interfaces for embedded systems has an increasing relevance today you also might find important to work with a good graphics library. Now - independently from skills, programming level or any personal attributes - you can influence and help the development of Littlev Graphics Library with: -* Report an issue -* Suggest feature -* Fix an issue -* Implement a feature -* Help with testing bugfixes and new features - -Please, take a look at [CODE_OF_CONDUCT](https://github.com/littlevgl/lvgl/blob/master/docs/CODE_OF_CONDUCT.md) - -There are few **general rules** -* We use [GitHub's issue tracker](https://github.com/littlevgl/lvgl/issues) -* Be kind and respectful. Starting with "Hi" is always a good idea :) -* If somebody helped you give a feedback. -* One issue should be about one topic. If you have other questions please open a new issue. -* Always create an issue before creating a [Pull request](https://help.github.com/articles/about-pull-requests/) to discuss the idea first -* Create small, "digestible" Pull requests. -* Tell your remarks in a structured way. Use paragraphs and the [Markdown](https://guides.github.com/features/mastering-markdown/) support of GitHub. -* Be sure you are using the latest version (from `master` branch) -* Keep in mind LittlevGL should be and should remain: - - usable on small MCUs as well (think about memory footprint) - - compilable with "non-standard" tools like Arduino (no gcc specific options) - - C compatible (no C++ specific code and features) - - all configuration should be in `lv_conf.h`. (Instead of modifying the library) - - the API clean and easiy to understand - -## How to report a bug? -If you found a **simple and straightforward bug** like: -* misspelling (in comments function/variable names or grammatical issues in comments) -* not handled error cases (negative array index, overflow etc) -* anything else which can be fixed locally with a few lines of code -* or defective documentation - -then tell: -* where you found the bug (which file/function/variable) -* how can it cause problem -* what is your suggested solution if you have - -If you faced with **something more complex** like: -* might be simple but you don't know its origin -* affects a whole file, module or even the architecture -* needs deeper discussion - -then please -* tell what do you experience -* tell what do you expect to happen -* tell how to reproduce the issue -* provide a simplified code example (better if can be tested with copy-paste) -* attache your lv_conf.h (if you feel it's important) -* logs and long codes should be attached in a file (instead of copying into a comment) - -## How to suggest a feature? -If you have a good and useful idea open issue to tell it! Please note the followings on suggesting new features: -* What the new feature is about? -* Why/Where/In which case is it useful/helpful/relevant? -* Can you mention real life usecases/examples for the use this feature? -* Can you help in implementing it? - -Your suggestion can have 4 possible outcomes: -1. This feature is already exists. In this case you will learn how to achieve your goal. -2. You can simply realize it with the current functionality. -3. Although it's a new feature but it would break LittlevGL's platform independent and/or resource minimalist nature. -4. It's really a new feature which would be good to be in LittlevGL. Hurray! In a discussion we figure out the technical details and implementation options. With the knowledge of how to do it somebody can implement the new feature. - -Keep in mind if you wouldn't like to do the implementation there is no guarantee that it will be ready in the near future. -However, if you would like to force it, take a look at this page: [Feature request service](http://www.gl.littlev.hu/services#feature) - -## How to implement a feature? -In [docs/TODO_MINOR.md](https://github.com/littlevgl/lvgl/blob/master/docs/TODO_MINOR.md) and [docs/TODO_PATCH.md](https://github.com/littlevgl/lvgl/blob/master/docs/TODO_PATCH.md) you can see some ideas which are waiting for somebody to realize them! If want to deal with a feature from these files, please start an issue and discuss the details. - -The new feature should be in a new branch. - -## Styling guide - -### File format -Use [lv_misc/lv_templ.c](https://github.com/littlevgl/lvgl/blob/master/lv_misc/lv_templ.c) and [lv_misc/lv_templ.h](https://github.com/littlevgl/lvgl/blob/master/lv_misc/lv_templ.h) - -### Naming conventions -* Words are separated by '_' -* In variable and function names use only lower case letters (e.g. *height_tmp*) -* In enums and defines use only upper case letters (e.g. *e.g. MAX_LINE_NUM*) -* Global names (API): - * starts with *lv* - * followed by module name: *btn*, *label*, *style* etc. - * followed by the action (for functions): *set*, *get*, *refr* etc. - * closed with the subject: *name*, *size*, *state* etc. -* Typedefs - * prefer `typedef struct` and `typedef enum` instead of `struct name` and `enum name` - * always add a closing *..._t* -* Abbreviations: - * Use abbreviations on public names only if they become longer than 32 characters - * Use only very straightforward (e.g. pos: position) or well-established (e.g. pr: press) abbreviations - -### Coding guide -* Functions: - * Try to write function shorter than is 50 lines - * Always shorter than 100 lines (except very straightforwards) -* Variables: - * One line, one declaration (BAD: char x, y;) - * Use `` (*uint8_t*, *int32_t* etc) - * Declare variables when needed (not all at function start) - * Use the smallest required scope - * Variables in a file (outside functions) are always *static* - * Do not use global variables (use functions to set/get static variables) - -### Comments -Before every function have a comment like this: - -```c -/** - * Return with the screen of an object - * @param obj pointer to an object - * @return pointer to a screen - */ -lv_obj_t * lv_obj_get_scr(lv_obj_t * obj); -``` - -Always use `/* Something */` format and NOT `//Something` - -Write readable code to avoid descriptive comments like: -`x++; /* Add 1 to x */`. -The code should show clearly what you are doing. - -You should write **why** have you done this: -`x++; /*Because of closing '\0' of the string */` - -Short "code summaries" of a few lines are accepted. E.g. `/*Calculate the new coordinates*/` - -In comments use \` \` when referring to a variable. E.g. ``/*Update the value of `x_act`*/`` - -### Formatting -Here is example to show bracket placing and using of white spaces: -```c -/** - * Set a new text for a label. Memory will be allocated to store the text by the label. - * @param label pointer to a label object - * @param text '\0' terminated character string. NULL to refresh with the current text. - */ -void lv_label_set_text(lv_obj_t * label, const char * text) -{ /* Main brackets of functions in new line*/ - - if(label == NULL) return; /*No bracket only if the command is inline with the if statement*/ - - lv_obj_inv(label); - - lv_label_ext_t * ext = lv_obj_get_ext(label); - - /*Comment before a section */ - if(text == ext->txt || text == NULL) { /*Bracket of statements start inline*/ - lv_label_refr_text(label); - return; - } - - ... -} -``` - -Use 4 spaces indentation instead of tab. - -You can use **astyle** to format the code. The required config flies are: `docs/astyle_c` and `docs/astyle_h`. -To format the source files: - `$ find . -type f -name "*.c" | xargs astyle --options=docs/astyle_c` - -To format the header files: - `$ find . -type f -name "*.h" | xargs astyle --options=docs/astyle_h` - -Append `-n` to the end to skip creation of backup file OR use `$ find . -type f -name "*.bak" -delete` (for source file's backups) and `find . -type f -name "*.orig" -delete` (for header file's backups) +**Welcome! It's glad to see that you are interested in contributing to LittlevGL! There are several types of task where you can help to build a better library! Let's see how to get started!** +There are many different possibilities to join the community. If you have some time to work with us I'm sure you will find something that fits you! You can: +- answer other's questions +- report and/or fix bugs +- suggest and/or implement new features +- improve and/or translate the documentation +- write a blog post about your experiences + +But first, start with the most Frequently Asked Questions. + +## FAQ about contributing + +### Where can I write my question and remarks? + +We use [GitHub's issue tracker](https://github.com/littlevgl/lvgl/issues) to ask questions., report bugs and suggest features. But there are some simple rules: +- Be kind and friendly. +- Speak about one thing in one issue. +- Give feedback and close the issue if your question is answered. +- Tell what you experience or expect. _"The button is not working"_ is not enough info to get help. +- If possible send an absolute minimal code example in order to reproduce the issue +- Use [Markdown](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet) to format your post. +- If you don't get any answer in a week write a comment like "Can somebody help?". Maybe your issue wasn't noticed. + +### How can I send fixes and improvements? +Merging new code happens via Pull Requests. If you are still not familiar with the Pull Requests (PR for short) here is a quick guide about them: +1. **Fork** the [lvgl repository](https://github.com/littlevgl/lvgl). To do this click the "Fork" button in the top right corner. It will "copy" the `lvgl` repository to your GitHub account (`https://github.com/your_name?tab=repositories`) +2. **Clone** the forked repository and add your updates +3. **Create a PR** on the GitHub on the page of you `lvgl` repository(`https://github.com/your_name/lvgl`) by hitting the "New pull request" button +4. **Set the base branch**. It means where you want to merge your update. Fixes go to `master`, new features to the actual `dev-x.y` branch. +5. **Describe** what is in the update. An example code is welcome if applicable. + +Some advice: +- If you are not sure about your fix or feature it's better to open an issue first, and discuss the details there. +- Maybe your fix or update won't be perfect at first. Don't be afraid, just improve it and push the new commits. The PR will be updated accordingly. +- If your update needs some extra work it's okay to say: _"I'm busy now and I will improve it soon"_ or _"Sorry, I don't have time to improve it, I hope it helps in this form too"_. So it's better to say don't have time to continue then saying nothing. +- Please read and follow this [guide about the coding style](https://doc.littlevgl.com/#Coding-Style-Guide) + + +### Where is the documentation? + +You can read the documentation here: https://doc.littlevgl.com/ +You can edit the documentation here: https://github.com/littlevgl/doc + +### Where is the blog? + +You can read the blog here: https://blog.littlevgl.com/ +You can edit the blog here: https://github.com/littlevgl/blog + + +## So how and where can I contribute? + +### Answering other's questions + +It's a great way to contribute to the library if you already use it. Just go the [issue tracker](https://github.com/littlevgl/lvgl/issues), read the titles and if you are already familiar with a topic, don't be shy, and write your suggestion. + +### Reporting and/or fixing bugs +For simple bugfixes (typos, missing error handling, fixing a warning) is fine to send a Pull request directly. However, for more complex bugs it's better to open an issue first. In the issue, you should describe how to reproduce the bug and even add the minimal code snippet. + +### Suggesting and/or implementing new features +If you have a good idea don't hesitate to share with us. It's even better if you have time to deal with its implementation. Don't be afraid if you still don't know LittlevGL well enough. We will help you to get started. + +During the implementation don't forget the [Code style guide](https://doc.littlevgl.com/#Coding-Style-Guide). + +### Improving and/or translating the documentation + +The documentation of LittlevGL is written in Markdown and available [here](https://github.com/littlevgl/doc) for editing. If you find some parts of the documentation obscure or insufficient just search the related `.md` file, hit the edit icon and add your updates. This way a new Pull request will be generated automatically. + +If you can devote more time to improve the documentation you can translate it! +1. Just copy the English `.md` files from the root folder to `locale/LANGUAGE_CODE` (language code is e.g. DE, FR, ES etc) +2. Append the language code the end of files (e.g. Welcome_fr.md) +3. Update the filenames in `_Sidebar.md` +4. Translate the page(s) you want +5. Create a Pull request + +### Writing a blog post about your experiences + +Have ported LittlevGL to a new platform? Have you created a fancy GUI? Do you know a great trick? +You can share your knowledge on LittelvGL's blog! It's super easy to add your own post: +- Fork and clone the [blog repository](https://github.com/littlevgl/blog) +- Add your post in Markdown to the `_posts` folder. +- Store the images and other resources in a dedicated folder in `assets` +- Create a Pull Request + +The blog uses [Jekyll](https://jekyllrb.com/) to convert the `.md` files to a webpage. You can easily [run Jekyll offline](https://jekyllrb.com/docs/) to check your post before creating the Pull request + +## Summary + +I hope you have taken a liking to contribute to LittelvGL. A helpful and friendly community is waiting for you! :) + From be8d241e0605db465792cbb5b8222b85f14344d0 Mon Sep 17 00:00:00 2001 From: Samuel Date: Fri, 7 Dec 2018 15:21:35 +0800 Subject: [PATCH 09/42] Update lv_list.h --- lv_objx/lv_list.h | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lv_objx/lv_list.h b/lv_objx/lv_list.h index f6db5d4cb..74026a7e3 100644 --- a/lv_objx/lv_list.h +++ b/lv_objx/lv_list.h @@ -121,10 +121,11 @@ bool lv_list_remove(const lv_obj_t * list, uint32_t index); *====================*/ /** - * Make a single button selected in the list, deselect others, should be called in list btns call back. - * @param btn pointer to the currently pressed list btn object + * Set single button selected mode, only one button will be selected if enabled. + * @param list pointer to the currently pressed list object + * @param mode, enable(true)/disable(false) single selected mode. */ -void lv_list_set_btn_single_selected(lv_obj_t *btn); +void lv_list_set_btn_single_selected_mode(lv_obj_t *list, bool mode); #if USE_LV_GROUP @@ -175,6 +176,12 @@ void lv_list_set_style(lv_obj_t *list, lv_list_style_t type, lv_style_t *style); * Getter functions *====================*/ +/** + * Get single button selected mode. + * @param list pointer to the currently pressed list object. + */ +bool lv_list_get_btn_single_selected_mode(lv_obj_t *list); + /** * Get the text of a list element * @param btn pointer to list element From c7846c827b7f03efc033d049eb9a8018dadbd41f Mon Sep 17 00:00:00 2001 From: Samuel Date: Fri, 7 Dec 2018 15:22:07 +0800 Subject: [PATCH 10/42] Update lv_list.c Use setter function enable/disable single selected mode. --- lv_objx/lv_list.c | 71 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 52 insertions(+), 19 deletions(-) diff --git a/lv_objx/lv_list.c b/lv_objx/lv_list.c index 63e706ab4..3e3e5578d 100644 --- a/lv_objx/lv_list.c +++ b/lv_objx/lv_list.c @@ -38,6 +38,7 @@ static lv_res_t lv_list_signal(lv_obj_t * list, lv_signal_t sign, void * param); static lv_res_t lv_list_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param); static void refr_btn_width(lv_obj_t * list); +static void lv_list_btn_single_selected(lv_obj_t *btn); /********************** * STATIC VARIABLES @@ -89,6 +90,8 @@ lv_obj_t * lv_list_create(lv_obj_t * par, const lv_obj_t * copy) ext->styles_btn[LV_BTN_STATE_TGL_PR] = &lv_style_btn_tgl_pr; ext->styles_btn[LV_BTN_STATE_INA] = &lv_style_btn_ina; ext->anim_time = LV_LIST_FOCUS_TIME; + ext->single_selected_mode = false; + #if USE_LV_GROUP ext->last_sel = NULL; ext->selected_btn = NULL; @@ -257,26 +260,15 @@ bool lv_list_remove(const lv_obj_t * list, uint32_t index) *====================*/ /** - * Make a single button selected in the list, deselect others, should be called in list btns call back. - * @param btn pointer to the currently pressed list btn object + * Set single button selected mode, only one button will be selected if enabled. + * @param list pointer to the currently pressed list object + * @param mode, enable(true)/disable(false) single selected mode. */ -void lv_list_set_btn_single_selected(lv_obj_t *btn) +void lv_list_set_btn_single_selected_mode(lv_obj_t *list, bool mode) { - lv_obj_t *list = lv_obj_get_parent(lv_obj_get_parent(btn)); + lv_list_ext_t * ext = lv_obj_get_ext_attr(list); - lv_obj_t * e = lv_list_get_next_btn(list, NULL); - do - { - if(e == btn) - { - lv_btn_set_state(e, LV_BTN_STATE_TGL_REL); - } - else - { - lv_btn_set_state(e, LV_BTN_STATE_REL); - } - e = lv_list_get_next_btn(list, e); - } while (e != NULL); + ext->single_selected_mode = mode; } #if USE_LV_GROUP @@ -388,6 +380,17 @@ void lv_list_set_style(lv_obj_t * list, lv_list_style_t type, lv_style_t * style * Getter functions *====================*/ +/** + * Get single button selected mode. + * @param list pointer to the currently pressed list object. + */ +bool lv_list_get_btn_single_selected_mode(lv_obj_t *list) +{ + lv_list_ext_t * ext = lv_obj_get_ext_attr(list); + + return (ext->single_selected_mode); +} + /** * Get the text of a list element * @param btn pointer to list element @@ -850,8 +853,9 @@ static lv_res_t lv_list_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * para res = ancestor_btn_signal(btn, sign, param); if(res != LV_RES_OK) return res; -#if USE_LV_GROUP if(sign == LV_SIGNAL_RELEASED) { + +#if USE_LV_GROUP lv_obj_t * list = lv_obj_get_parent(lv_obj_get_parent(btn)); lv_group_t * g = lv_obj_get_group(list); if(lv_group_get_focused(g) == list && lv_indev_is_dragging(lv_indev_get_act()) == false) { @@ -872,8 +876,15 @@ static lv_res_t lv_list_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * para /* If `click_focus == 1` then LV_SIGNAL_FOCUS need to know which button triggered the focus * to mark it as selected (pressed state)*/ last_clicked_btn = btn; - +#endif + lv_list_ext_t * ext = lv_obj_get_ext_attr(list); + if(lv_indev_is_dragging(lv_indev_get_act()) == false && ext->single_selected_mode) + { + lv_list_btn_single_selected(btn); + } } + +#if USE_LV_GROUP if(sign == LV_SIGNAL_CLEANUP) { lv_obj_t * list = lv_obj_get_parent(lv_obj_get_parent(btn)); @@ -907,5 +918,27 @@ static void refr_btn_width(lv_obj_t * list) } } +/** + * Make a single button selected in the list, deselect others, should be called in list btns call back. + * @param btn pointer to the currently pressed list btn object + */ +static void lv_list_btn_single_selected(lv_obj_t *btn) +{ + lv_obj_t *list = lv_obj_get_parent(lv_obj_get_parent(btn)); + + lv_obj_t * e = lv_list_get_next_btn(list, NULL); + do + { + if(e == btn) + { + lv_btn_set_state(e, LV_BTN_STATE_TGL_REL); + } + else + { + lv_btn_set_state(e, LV_BTN_STATE_REL); + } + e = lv_list_get_next_btn(list, e); + } while (e != NULL); +} #endif From 50fe1ba14d079b715584624932e25a5b5a7b3fac Mon Sep 17 00:00:00 2001 From: Alexander Date: Wed, 5 Dec 2018 11:46:37 +0200 Subject: [PATCH 11/42] lv_roller_set_align / lv_roller_get_align funcs (user can align the Options: left, right or center) --- lv_objx/lv_roller.c | 63 ++++++++++++++++++++++++++++++++++++++------- lv_objx/lv_roller.h | 17 ++++++++++-- 2 files changed, 68 insertions(+), 12 deletions(-) diff --git a/lv_objx/lv_roller.c b/lv_objx/lv_roller.c index cc8728eb0..8f70c484d 100644 --- a/lv_objx/lv_roller.c +++ b/lv_objx/lv_roller.c @@ -22,7 +22,7 @@ # endif #else # undef LV_ROLLER_ANIM_TIME -# define LV_ROLLER_ANIM_TIME 0 /*No animation*/ +# define LV_ROLLER_ANIM_TIME 0 /*No animation*/ #endif /********************** @@ -75,7 +75,7 @@ lv_obj_t * lv_roller_create(lv_obj_t * par, const lv_obj_t * copy) lv_mem_assert(ext); if(ext == NULL) return NULL; ext->ddlist.draw_arrow = 0; /*Do not draw arrow by default*/ - + /*The signal and design functions are not copied so set them here*/ lv_obj_set_signal_func(new_roller, lv_roller_signal); lv_obj_set_design_func(new_roller, lv_roller_design); @@ -123,6 +123,19 @@ lv_obj_t * lv_roller_create(lv_obj_t * par, const lv_obj_t * copy) * Setter functions *====================*/ +/** + * Set the align of the roller's options (left or center) + * @param roller - pointer to a roller object + * @param align - one of lv_label_align_t values (left, right, center) + */ +void lv_roller_set_align(lv_obj_t * roller, lv_label_align_t align) +{ + lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller); + lv_mem_assert(ext); + if(ext->ddlist.label == NULL) return; /*Probably the roller is being deleted if the label is NULL.*/ + lv_label_set_align(ext->ddlist.label, align); +} + /** * Set the selected option * @param roller pointer to a roller object @@ -151,8 +164,8 @@ void lv_roller_set_visible_row_count(lv_obj_t * roller, uint8_t row_cnt) lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller); lv_style_t * style_label = lv_obj_get_style(ext->ddlist.label); lv_ddlist_set_fix_height(roller, lv_font_get_height(style_label->text.font) * row_cnt + style_label->text.line_space * (row_cnt)); - } + /** * Set a style of a roller * @param roller pointer to a roller object @@ -175,6 +188,19 @@ void lv_roller_set_style(lv_obj_t * roller, lv_roller_style_t type, lv_style_t * * Getter functions *====================*/ +/** + * Get the align attribute. Default alignment after _create is LV_LABEL_ALIGN_CENTER + * @param roller pointer to a roller object + * @return LV_LABEL_ALIGN_LEFT, LV_LABEL_ALIGN_RIGHT or LV_LABEL_ALIGN_CENTER + */ +lv_label_align_t lv_roller_get_align(const lv_obj_t * roller) +{ + lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller); + lv_mem_assert(ext); + lv_mem_assert(ext->ddlist.label); + return lv_label_get_align(ext->ddlist.label); +} + /** * Get the auto width set attribute * @param roller pointer to a roller object @@ -210,7 +236,6 @@ lv_style_t * lv_roller_get_style(const lv_obj_t * roller, lv_roller_style_t type * STATIC FUNCTIONS **********************/ - /** * Handle the drawing related tasks of the rollers * @param roller pointer to an object @@ -266,11 +291,23 @@ static bool lv_roller_design(lv_obj_t * roller, const lv_area_t * mask, lv_desig if(area_ok) { lv_style_t * sel_style = lv_roller_get_style(roller, LV_ROLLER_STYLE_SEL); lv_style_t new_style; + lv_txt_flag_t txt_align = LV_TXT_FLAG_NONE; + + { + lv_label_align_t label_align = lv_label_get_align(ext->ddlist.label); + + if(LV_LABEL_ALIGN_CENTER == label_align) { + txt_align |= LV_TXT_FLAG_CENTER; + } else if(LV_LABEL_ALIGN_RIGHT == label_align) { + txt_align |= LV_TXT_FLAG_RIGHT; + } + } + lv_style_copy(&new_style, style); new_style.text.color = sel_style->text.color; new_style.text.opa = sel_style->text.opa; lv_draw_label(&ext->ddlist.label->coords, &mask_sel, &new_style, opa_scale, - lv_label_get_text(ext->ddlist.label), LV_TXT_FLAG_CENTER, NULL); + lv_label_get_text(ext->ddlist.label), txt_align, NULL); } } @@ -296,10 +333,19 @@ static lv_res_t lv_roller_signal(lv_obj_t * roller, lv_signal_t sign, void * par } lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller); + lv_align_t obj_align = LV_ALIGN_IN_LEFT_MID; + + { + lv_label_align_t label_align = lv_label_get_align(ext->ddlist.label); + + if(LV_LABEL_ALIGN_CENTER == label_align) obj_align = LV_ALIGN_CENTER; + else if(LV_LABEL_ALIGN_RIGHT == label_align) obj_align = LV_ALIGN_IN_RIGHT_MID; + } + if(sign == LV_SIGNAL_STYLE_CHG) { lv_obj_set_height(lv_page_get_scrl(roller), lv_obj_get_height(ext->ddlist.label) + lv_obj_get_height(roller)); - lv_obj_align(ext->ddlist.label, NULL, LV_ALIGN_CENTER, 0, 0); + lv_obj_align(ext->ddlist.label, NULL, obj_align, 0, 0); lv_ddlist_set_selected(roller, ext->ddlist.sel_opt_id); refr_position(roller, false); } else if(sign == LV_SIGNAL_CORD_CHG) { @@ -311,7 +357,7 @@ static lv_res_t lv_roller_signal(lv_obj_t * roller, lv_signal_t sign, void * par lv_obj_set_height(lv_page_get_scrl(roller), lv_obj_get_height(ext->ddlist.label) + lv_obj_get_height(roller)); - lv_obj_align(ext->ddlist.label, NULL, LV_ALIGN_CENTER, 0, 0); + lv_obj_align(ext->ddlist.label, NULL, obj_align, 0, 0); lv_ddlist_set_selected(roller, ext->ddlist.sel_opt_id); refr_position(roller, false); } @@ -337,14 +383,12 @@ static lv_res_t lv_roller_signal(lv_obj_t * roller, lv_signal_t sign, void * par ext->ddlist.sel_opt_id_ori = ext->ddlist.sel_opt_id; /*Save the current value. Used to revert this state if ENER wont't be pressed*/ } - } else if(sign == LV_SIGNAL_DEFOCUS) { /*Revert the original state*/ if(ext->ddlist.sel_opt_id != ext->ddlist.sel_opt_id_ori) { ext->ddlist.sel_opt_id = ext->ddlist.sel_opt_id_ori; refr_position(roller, true); } - } else if(sign == LV_SIGNAL_CONTROLL) { char c = *((char *)param); if(c == LV_GROUP_KEY_RIGHT || c == LV_GROUP_KEY_DOWN) { @@ -486,7 +530,6 @@ static void draw_bg(lv_obj_t * roller, const lv_area_t * mask) style->body.main_color = main_tmp; style->body.grad_color = grad_tmp; } - } /** diff --git a/lv_objx/lv_roller.h b/lv_objx/lv_roller.h index d0aaed42a..a751cd8c3 100644 --- a/lv_objx/lv_roller.h +++ b/lv_objx/lv_roller.h @@ -28,6 +28,7 @@ extern "C" { #include "../lv_core/lv_obj.h" #include "lv_ddlist.h" +#include "lv_label.h" /********************* * DEFINES @@ -64,6 +65,13 @@ lv_obj_t * lv_roller_create(lv_obj_t * par, const lv_obj_t * copy); * Setter functions *====================*/ +/** + * Set the align of the roller's options (left, right or center[default]) + * @param roller - pointer to a roller object + * @param align - one of lv_label_align_t values (left, right, center) + */ +void lv_roller_set_align(lv_obj_t * roller, lv_label_align_t align); + /** * Set the options on a roller * @param roller pointer to roller object @@ -82,7 +90,6 @@ static inline void lv_roller_set_options(lv_obj_t * roller, const char * options */ void lv_roller_set_selected(lv_obj_t *roller, uint16_t sel_opt, bool anim_en); - /** * Set a function to call when a new option is chosen * @param roller pointer to a roller @@ -120,7 +127,6 @@ static inline void lv_roller_set_anim_time(lv_obj_t *roller, uint16_t anim_time) lv_ddlist_set_anim_time(roller, anim_time); } - /** * Set a style of a roller * @param roller pointer to a roller object @@ -133,6 +139,13 @@ void lv_roller_set_style(lv_obj_t *roller, lv_roller_style_t type, lv_style_t *s * Getter functions *====================*/ +/** + * Get the align attribute. Default alignment after _create is LV_LABEL_ALIGN_CENTER + * @param roller pointer to a roller object + * @return LV_LABEL_ALIGN_LEFT, LV_LABEL_ALIGN_RIGHT or LV_LABEL_ALIGN_CENTER + */ +lv_label_align_t lv_roller_get_align(const lv_obj_t * roller); + /** * Get the options of a roller * @param roller pointer to roller object From 648c3430ef86253518400719739d3132258e8815 Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Sat, 8 Dec 2018 09:22:41 -0500 Subject: [PATCH 12/42] Add `bool single_selected_mode` to `lv_list_ext_t` --- lv_objx/lv_list.h | 1 + 1 file changed, 1 insertion(+) diff --git a/lv_objx/lv_list.h b/lv_objx/lv_list.h index 74026a7e3..b79491b47 100644 --- a/lv_objx/lv_list.h +++ b/lv_objx/lv_list.h @@ -57,6 +57,7 @@ typedef struct lv_style_t *styles_btn[LV_BTN_STATE_NUM]; /*Styles of the list element buttons*/ lv_style_t *style_img; /*Style of the list element images on buttons*/ uint32_t size; /*the number of items(buttons) in the list*/ + bool single_selected_mode; /* whether single selected mode is enabled */ #if USE_LV_GROUP lv_obj_t * last_sel; /* Last btn selected */ lv_obj_t * selected_btn; From 429dca127d3a5a62ac37ba9130c4dc2bb463c6cd Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Sat, 8 Dec 2018 09:59:56 -0500 Subject: [PATCH 13/42] Fix compilation error in lv_chart --- lv_objx/lv_chart.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/lv_objx/lv_chart.c b/lv_objx/lv_chart.c index b3ac83880..92e09a400 100644 --- a/lv_objx/lv_chart.c +++ b/lv_objx/lv_chart.c @@ -731,7 +731,6 @@ static void lv_chart_draw_cols(lv_obj_t * chart, const lv_area_t * mask) col_a.y2 = chart->coords.y2; lv_coord_t x_act; - printf("\n", y_tmp); /*Go through all points*/ for(i = 0; i < ext->point_cnt; i ++) { @@ -749,7 +748,6 @@ static void lv_chart_draw_cols(lv_obj_t * chart, const lv_area_t * mask) lv_coord_t p_act = (ser->start_point + i) % ext->point_cnt; y_tmp = (int32_t)((int32_t) ser->points[p_act] - ext->ymin) * h; y_tmp = y_tmp / (ext->ymax - ext->ymin); - printf("ytmp:%d\n", y_tmp); col_a.y1 = h - y_tmp + chart->coords.y1; mask_ret = lv_area_intersect(&col_mask, mask, &col_a); From e5dabf716aea3307b01e4599e640b2542e071002 Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Sun, 9 Dec 2018 20:30:36 -0500 Subject: [PATCH 14/42] Rename `btn_single_selected_mode` to `single_mode` --- lv_objx/lv_list.c | 12 ++++++------ lv_objx/lv_list.h | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lv_objx/lv_list.c b/lv_objx/lv_list.c index 87a91ea75..62b258503 100644 --- a/lv_objx/lv_list.c +++ b/lv_objx/lv_list.c @@ -90,7 +90,7 @@ lv_obj_t * lv_list_create(lv_obj_t * par, const lv_obj_t * copy) ext->styles_btn[LV_BTN_STATE_TGL_PR] = &lv_style_btn_tgl_pr; ext->styles_btn[LV_BTN_STATE_INA] = &lv_style_btn_ina; ext->anim_time = LV_LIST_FOCUS_TIME; - ext->single_selected_mode = false; + ext->single_mode = false; #if USE_LV_GROUP ext->last_sel = NULL; @@ -264,11 +264,11 @@ bool lv_list_remove(const lv_obj_t * list, uint32_t index) * @param list pointer to the currently pressed list object * @param mode, enable(true)/disable(false) single selected mode. */ -void lv_list_set_btn_single_selected_mode(lv_obj_t *list, bool mode) +void lv_list_set_single_mode(lv_obj_t *list, bool mode) { lv_list_ext_t * ext = lv_obj_get_ext_attr(list); - ext->single_selected_mode = mode; + ext->single_mode = mode; } #if USE_LV_GROUP @@ -387,11 +387,11 @@ void lv_list_set_style(lv_obj_t * list, lv_list_style_t type, lv_style_t * style * Get single button selected mode. * @param list pointer to the currently pressed list object. */ -bool lv_list_get_btn_single_selected_mode(lv_obj_t *list) +bool lv_list_get_single_mode(lv_obj_t *list) { lv_list_ext_t * ext = lv_obj_get_ext_attr(list); - return (ext->single_selected_mode); + return (ext->single_mode); } /** @@ -885,7 +885,7 @@ static lv_res_t lv_list_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * para * to mark it as selected (pressed state)*/ last_clicked_btn = btn; #endif - if(lv_indev_is_dragging(lv_indev_get_act()) == false && ext->single_selected_mode) + if(lv_indev_is_dragging(lv_indev_get_act()) == false && ext->single_mode) { lv_list_btn_single_selected(btn); } diff --git a/lv_objx/lv_list.h b/lv_objx/lv_list.h index 20fa98cc7..572f0189e 100644 --- a/lv_objx/lv_list.h +++ b/lv_objx/lv_list.h @@ -57,7 +57,7 @@ typedef struct lv_style_t *styles_btn[LV_BTN_STATE_NUM]; /*Styles of the list element buttons*/ lv_style_t *style_img; /*Style of the list element images on buttons*/ uint32_t size; /*the number of items(buttons) in the list*/ - bool single_selected_mode; /* whether single selected mode is enabled */ + bool single_mode; /* whether single selected mode is enabled */ #if USE_LV_GROUP lv_obj_t * last_sel; /* Last btn selected */ lv_obj_t * selected_btn; @@ -127,7 +127,7 @@ bool lv_list_remove(const lv_obj_t * list, uint32_t index); * @param list pointer to the currently pressed list object * @param mode, enable(true)/disable(false) single selected mode. */ -void lv_list_set_btn_single_selected_mode(lv_obj_t *list, bool mode); +void lv_list_set_single_mode(lv_obj_t *list, bool mode); #if USE_LV_GROUP @@ -192,7 +192,7 @@ void lv_list_set_style(lv_obj_t *list, lv_list_style_t type, lv_style_t *style); * Get single button selected mode. * @param list pointer to the currently pressed list object. */ -bool lv_list_get_btn_single_selected_mode(lv_obj_t *list); +bool lv_list_get_single_mode(lv_obj_t *list); /** * Get the text of a list element From f504d016444e765a52919565e5eb2f706eede474 Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Sun, 9 Dec 2018 20:51:32 -0500 Subject: [PATCH 15/42] Add lv_ddlist_set_align and lv_ddlist_get_align --- lv_objx/lv_ddlist.c | 40 +++++++++++++++++++++++++++++++++++++++- lv_objx/lv_ddlist.h | 14 ++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/lv_objx/lv_ddlist.c b/lv_objx/lv_ddlist.c index 5ee00fa63..66baf77f8 100644 --- a/lv_objx/lv_ddlist.c +++ b/lv_objx/lv_ddlist.c @@ -287,6 +287,12 @@ void lv_ddlist_set_style(lv_obj_t * ddlist, lv_ddlist_style_t type, lv_style_t * } } +void lv_ddlist_set_align(lv_obj_t *ddlist, lv_label_align_t align) +{ + lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist); + + lv_label_set_align(ext->label, align); +} /*===================== * Getter functions *====================*/ @@ -407,6 +413,14 @@ lv_style_t * lv_ddlist_get_style(const lv_obj_t * ddlist, lv_ddlist_style_t type /*To avoid warning*/ return NULL; } + +lv_label_align_t lv_ddlist_get_align(const lv_obj_t *ddlist) +{ + lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist); + + return lv_label_get_align(ext->label); +} + /*===================== * Other functions *====================*/ @@ -447,6 +461,29 @@ void lv_ddlist_close(lv_obj_t * ddlist, bool anim_en) * STATIC FUNCTIONS **********************/ +/** + * Get the text alignment flag for a drop down list. + * @param ddlist drop down list + * @return text alignment flag + */ +static lv_txt_flag_t lv_ddlist_get_txt_flag(const lv_obj_t *ddlist) +{ + lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist); + + lv_label_align_t align = lv_label_get_align(ext->label); + + switch(align) + { + default: + case LV_LABEL_ALIGN_LEFT: + return LV_TXT_FLAG_NONE; + case LV_LABEL_ALIGN_CENTER: + return LV_TXT_FLAG_CENTER; + case LV_LABEL_ALIGN_RIGHT: + return LV_TXT_FLAG_RIGHT; + } +} + /** * Handle the drawing related tasks of the drop down lists * @param ddlist pointer to an object @@ -517,8 +554,9 @@ static bool lv_ddlist_design(lv_obj_t * ddlist, const lv_area_t * mask, lv_desig lv_style_copy(&new_style, style); new_style.text.color = sel_style->text.color; new_style.text.opa = sel_style->text.opa; + lv_txt_flag_t flag = lv_ddlist_get_txt_flag(ddlist); lv_draw_label(&ext->label->coords, &mask_sel, &new_style, opa_scale, - lv_label_get_text(ext->label), LV_TXT_FLAG_NONE, NULL); + lv_label_get_text(ext->label), flag, NULL); } } diff --git a/lv_objx/lv_ddlist.h b/lv_objx/lv_ddlist.h index d928d6520..4c9207463 100644 --- a/lv_objx/lv_ddlist.h +++ b/lv_objx/lv_ddlist.h @@ -150,6 +150,13 @@ void lv_ddlist_set_anim_time(lv_obj_t * ddlist, uint16_t anim_time); * */ void lv_ddlist_set_style(lv_obj_t *ddlist, lv_ddlist_style_t type, lv_style_t *style); +/** + * Set the alignment of the labels in a drop down list + * @param ddlist pointer to a drop down list object + * @param align alignment of labels + */ +void lv_ddlist_set_align(lv_obj_t *ddlist, lv_label_align_t align); + /*===================== * Getter functions *====================*/ @@ -220,6 +227,13 @@ uint16_t lv_ddlist_get_anim_time(const lv_obj_t * ddlist); */ lv_style_t * lv_ddlist_get_style(const lv_obj_t *ddlist, lv_ddlist_style_t type); +/** + * Get the alignment of the labels in a drop down list + * @param ddlist pointer to a drop down list object + * @return alignment of labels + */ +lv_label_align_t lv_ddlist_get_align(const lv_obj_t *ddlist); + /*===================== * Other functions *====================*/ From 42a8c598862df7c2fc00ad2e1294cdb0177c967d Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Mon, 10 Dec 2018 15:35:57 -0500 Subject: [PATCH 16/42] Handle USE_LV_ANIMATION being disabled in lv_page and lv_sw --- lv_objx/lv_page.c | 3 ++- lv_objx/lv_sw.c | 32 ++++++++++++++++++++++---------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/lv_objx/lv_page.c b/lv_objx/lv_page.c index cd36c3143..38d75fa8f 100644 --- a/lv_objx/lv_page.c +++ b/lv_objx/lv_page.c @@ -571,7 +571,6 @@ void lv_page_scroll_ver(lv_obj_t * page, lv_coord_t dist) #endif } - /** * Not intended to use directly by the user but by other object types internally. * Start an edge flash animation. Exactly one `ext->edge_flash.xxx_ip` should be set @@ -579,6 +578,7 @@ void lv_page_scroll_ver(lv_obj_t * page, lv_coord_t dist) */ void lv_page_start_edge_flash(lv_obj_t * page) { +#if USE_LV_ANIMATION lv_page_ext_t * ext = lv_obj_get_ext_attr(page); if(ext->edge_flash.enabled) { lv_anim_t a; @@ -596,6 +596,7 @@ void lv_page_start_edge_flash(lv_obj_t * page) a.repeat_pause = 0; lv_anim_create(&a); } +#endif } diff --git a/lv_objx/lv_sw.c b/lv_objx/lv_sw.c index 570a6c4f4..8a43c56b2 100644 --- a/lv_objx/lv_sw.c +++ b/lv_objx/lv_sw.c @@ -69,7 +69,9 @@ lv_obj_t * lv_sw_create(lv_obj_t * par, const lv_obj_t * copy) /*Initialize the allocated 'ext' */ ext->changed = 0; +#if USE_LV_ANIMATION ext->anim_time = 0; +#endif ext->style_knob_off = ext->slider.style_knob; ext->style_knob_on = ext->slider.style_knob; @@ -100,7 +102,9 @@ lv_obj_t * lv_sw_create(lv_obj_t * par, const lv_obj_t * copy) lv_sw_ext_t * copy_ext = lv_obj_get_ext_attr(copy); ext->style_knob_off = copy_ext->style_knob_off; ext->style_knob_on = copy_ext->style_knob_on; +#if USE_LV_ANIMATION ext->anim_time = copy_ext->anim_time; +#endif if(lv_sw_get_state(new_sw)) lv_slider_set_style(new_sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_on); else lv_slider_set_style(new_sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_off); @@ -150,9 +154,11 @@ void lv_sw_off(lv_obj_t * sw) void lv_sw_on_anim(lv_obj_t * sw) { lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); - - if(lv_sw_get_anim_time(sw) > 0) lv_sw_anim_to_value(sw, LV_SWITCH_SLIDER_ANIM_MAX); - else lv_slider_set_value(sw, LV_SWITCH_SLIDER_ANIM_MAX); +#if USE_LV_ANIMATION + if(lv_sw_get_anim_time(sw) > 0)lv_sw_anim_to_value(sw, LV_SWITCH_SLIDER_ANIM_MAX); + else +#endif + lv_slider_set_value(sw, LV_SWITCH_SLIDER_ANIM_MAX); lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_on); } @@ -164,8 +170,11 @@ void lv_sw_on_anim(lv_obj_t * sw) void lv_sw_off_anim(lv_obj_t * sw) { lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); +#if USE_LV_ANIMATION if(lv_sw_get_anim_time(sw) > 0) lv_sw_anim_to_value(sw, 0); - else lv_slider_set_value(sw, 0); + else +#endif + lv_slider_set_value(sw, 0); lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_off); } @@ -197,15 +206,13 @@ void lv_sw_set_style(lv_obj_t * sw, lv_sw_style_t type, lv_style_t * style) break; } } - +#if USE_LV_ANIMATION void lv_sw_set_anim_time(lv_obj_t *sw, uint16_t anim_time) { -#if USE_LV_ANIMATION == 0 - anim_time = 0; -#endif - lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); + lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); ext->anim_time = anim_time; } +#endif /*===================== * Getter functions @@ -325,11 +332,15 @@ static lv_res_t lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param) else if(sign == LV_SIGNAL_PRESS_LOST) { if(lv_sw_get_state(sw)) { lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_on); +#if USE_LV_ANIMATION lv_sw_anim_to_value(sw, LV_SWITCH_SLIDER_ANIM_MAX); +#endif } else { lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_off); +#if USE_LV_ANIMATION lv_sw_anim_to_value(sw, 0); +#endif } } else if(sign == LV_SIGNAL_RELEASED) { @@ -380,7 +391,7 @@ static lv_res_t lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param) return res; } - +#if USE_LV_ANIMATION static void lv_sw_anim_to_value(lv_obj_t * sw, int16_t value) { lv_anim_t a; @@ -399,5 +410,6 @@ static void lv_sw_anim_to_value(lv_obj_t * sw, int16_t value) a.repeat_pause = 0; lv_anim_create(&a); } +#endif #endif From e60482ca0e97d9e51d5b5cbcbcfd87fdb3a4d369 Mon Sep 17 00:00:00 2001 From: Martin Herancourt Date: Tue, 11 Dec 2018 10:21:22 +0100 Subject: [PATCH 17/42] minor fixes --- lv_objx/lv_list.c | 15 ++++++++------- lv_themes/lv_theme_alien.c | 2 -- lv_themes/lv_theme_mono.c | 4 +--- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/lv_objx/lv_list.c b/lv_objx/lv_list.c index dc8213e58..a9c4cd84f 100644 --- a/lv_objx/lv_list.c +++ b/lv_objx/lv_list.c @@ -391,10 +391,10 @@ lv_obj_t * lv_list_get_btn_img(const lv_obj_t * btn) } /** - * Get the next button from list. (Starts from the bottom button) + * Get the previous button from list. (Starts from the top button) * @param list pointer to a list object - * @param prev_btn pointer to button. Search the next after it. - * @return pointer to the next button or NULL when no more buttons + * @param prev_btn pointer to button. Search the previous before it. + * @return pointer to the previous button or NULL when no more buttons */ lv_obj_t * lv_list_get_prev_btn(const lv_obj_t * list, lv_obj_t * prev_btn) { @@ -416,11 +416,12 @@ lv_obj_t * lv_list_get_prev_btn(const lv_obj_t * list, lv_obj_t * prev_btn) } -/** - * Get the previous button from list. (Starts from the top button) + + /** + * Get the next button from list. (Starts from the bottom button) * @param list pointer to a list object - * @param prev_btn pointer to button. Search the previous before it. - * @return pointer to the previous button or NULL when no more buttons + * @param prev_btn pointer to button. Search the next after it. + * @return pointer to the next button or NULL when no more buttons */ lv_obj_t * lv_list_get_next_btn(const lv_obj_t * list, lv_obj_t * prev_btn) { diff --git a/lv_themes/lv_theme_alien.c b/lv_themes/lv_theme_alien.c index 386efb61e..d271f8610 100644 --- a/lv_themes/lv_theme_alien.c +++ b/lv_themes/lv_theme_alien.c @@ -28,8 +28,6 @@ static uint16_t _hue; static lv_font_t * _font; -static lv_font_t * _font; -static lv_font_t * _font; static lv_theme_t theme; static lv_style_t def; diff --git a/lv_themes/lv_theme_mono.c b/lv_themes/lv_theme_mono.c index 4fee86a58..f456caec1 100644 --- a/lv_themes/lv_theme_mono.c +++ b/lv_themes/lv_theme_mono.c @@ -36,7 +36,6 @@ static lv_style_t light_frame; static lv_style_t dark_frame; /*Saved input parameters*/ -static uint16_t _hue; static lv_font_t * _font; @@ -421,7 +420,7 @@ static void win_init(void) /** * Initialize the mono theme - * @param hue [0..360] hue value from HSV color space to define the theme's base color + * @param hue [0..360] hue value from HSV color space to define the theme's base color; is not used in lv_theme_mono * @param font pointer to a font (NULL to use the default) * @return pointer to the initialized theme */ @@ -429,7 +428,6 @@ lv_theme_t * lv_theme_mono_init(uint16_t hue, lv_font_t * font) { if(font == NULL) font = LV_FONT_DEFAULT; - _hue = hue; _font = font; /*For backward compatibility initialize all theme elements with a default style */ From e68c3ab725f869a57a3810c9996998b1b84e79c4 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 11 Dec 2018 18:00:32 +0100 Subject: [PATCH 18/42] line draw updates with width = 1 --- lv_draw/lv_draw_line.c | 68 +++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/lv_draw/lv_draw_line.c b/lv_draw/lv_draw_line.c index 9e461f1c9..600cdc986 100644 --- a/lv_draw/lv_draw_line.c +++ b/lv_draw/lv_draw_line.c @@ -73,7 +73,7 @@ static bool line_next_x(line_draw_t * line); * @param opa_scale scale down all opacities by the factor */ void lv_draw_line(const lv_point_t * point1, const lv_point_t * point2, const lv_area_t * mask, - const lv_style_t * style, lv_opa_t opa_scale) + const lv_style_t * style, lv_opa_t opa_scale) { if(style->line.width == 0) return; @@ -279,16 +279,12 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_ width = i; #if LV_ANTIALIAS width--; - #endif break; } line_next(&pattern_line); } - } else { - pattern[0].x = 0; - pattern[0].y = 0; } #if LV_ANTIALIAS @@ -299,12 +295,22 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_ aa_last_corner = 0; #endif + lv_coord_t x_center_ofs = 0; + lv_coord_t y_center_ofs = 0; + if(width != 0) { + x_center_ofs = pattern[width - 1].x / 2; + y_center_ofs = pattern[width - 1].y / 2; + } + else { + if(main_line->hor && main_line->p1.y >= main_line->p2.y + dir_ori) pattern[0].y --; + if(!main_line->hor && main_line->p1.x >= main_line->p2.x + dir_ori) pattern[0].x --; + } /* Make the coordinates relative to the center */ for(i = 0; i < width; i++) { - pattern[i].x -= pattern[width - 1].x / 2; - pattern[i].y -= pattern[width - 1].y / 2; + pattern[i].x -= x_center_ofs; + pattern[i].y -= y_center_ofs; #if LV_ANTIALIAS if(i != 0) { if(main_line->hor) { @@ -312,16 +318,16 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_ lv_coord_t seg_w = pattern[i].y - pattern[aa_last_corner].y; if(main_line->sy < 0) { lv_draw_aa_ver_seg(main_line->p1.x + pattern[aa_last_corner].x - 1, main_line->p1.y + pattern[aa_last_corner].y + seg_w + 1, - seg_w, mask, style->line.color, opa); + seg_w, mask, style->line.color, opa); lv_draw_aa_ver_seg(main_line->p2.x + pattern[aa_last_corner].x + 1, main_line->p2.y + pattern[aa_last_corner].y + seg_w + 1, - -seg_w, mask, style->line.color, opa); + -seg_w, mask, style->line.color, opa); } else { lv_draw_aa_ver_seg(main_line->p1.x + pattern[aa_last_corner].x - 1, main_line->p1.y + pattern[aa_last_corner].y, - seg_w, mask, style->line.color, opa); + seg_w, mask, style->line.color, opa); lv_draw_aa_ver_seg(main_line->p2.x + pattern[aa_last_corner].x + 1, main_line->p2.y + pattern[aa_last_corner].y, - -seg_w, mask, style->line.color, opa); + -seg_w, mask, style->line.color, opa); } aa_last_corner = i; } @@ -330,16 +336,16 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_ lv_coord_t seg_w = pattern[i].x - pattern[aa_last_corner].x; if(main_line->sx < 0) { lv_draw_aa_hor_seg(main_line->p1.x + pattern[aa_last_corner].x + seg_w + 1, main_line->p1.y + pattern[aa_last_corner].y - 1, - seg_w, mask, style->line.color, opa); + seg_w, mask, style->line.color, opa); lv_draw_aa_hor_seg(main_line->p2.x + pattern[aa_last_corner].x + seg_w + 1, main_line->p2.y + pattern[aa_last_corner].y + 1, - -seg_w, mask, style->line.color, opa); + -seg_w, mask, style->line.color, opa); } else { lv_draw_aa_hor_seg(main_line->p1.x + pattern[aa_last_corner].x, main_line->p1.y + pattern[aa_last_corner].y - 1, - seg_w, mask, style->line.color, opa); + seg_w, mask, style->line.color, opa); lv_draw_aa_hor_seg(main_line->p2.x + pattern[aa_last_corner].x, main_line->p2.y + pattern[aa_last_corner].y + 1, - -seg_w, mask, style->line.color, opa); + -seg_w, mask, style->line.color, opa); } aa_last_corner = i; } @@ -358,33 +364,33 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_ lv_coord_t seg_w = pattern[width_safe - 1].y - pattern[aa_last_corner].y; if(main_line->sy < 0) { lv_draw_aa_ver_seg(main_line->p1.x + pattern[aa_last_corner].x - 1, main_line->p1.y + pattern[aa_last_corner].y + seg_w, - seg_w + main_line->sy, mask, style->line.color, opa); + seg_w + main_line->sy, mask, style->line.color, opa); lv_draw_aa_ver_seg(main_line->p2.x + pattern[aa_last_corner].x + 1, main_line->p2.y + pattern[aa_last_corner].y + seg_w, - -(seg_w + main_line->sy), mask, style->line.color, opa); + -(seg_w + main_line->sy), mask, style->line.color, opa); } else { lv_draw_aa_ver_seg(main_line->p1.x + pattern[aa_last_corner].x - 1, main_line->p1.y + pattern[aa_last_corner].y, - seg_w + main_line->sy, mask, style->line.color, opa); + seg_w + main_line->sy, mask, style->line.color, opa); lv_draw_aa_ver_seg(main_line->p2.x + pattern[aa_last_corner].x + 1, main_line->p2.y + pattern[aa_last_corner].y, - -(seg_w + main_line->sy), mask, style->line.color, opa); + -(seg_w + main_line->sy), mask, style->line.color, opa); } } else { lv_coord_t seg_w = pattern[width_safe - 1].x - pattern[aa_last_corner].x; if(main_line->sx < 0) { lv_draw_aa_hor_seg(main_line->p1.x + pattern[aa_last_corner].x + seg_w, main_line->p1.y + pattern[aa_last_corner].y - 1, - seg_w + main_line->sx, mask, style->line.color, opa); + seg_w + main_line->sx, mask, style->line.color, opa); lv_draw_aa_hor_seg(main_line->p2.x + pattern[aa_last_corner].x + seg_w, main_line->p2.y + pattern[aa_last_corner].y + 1, - -(seg_w + main_line->sx), mask, style->line.color, opa); + -(seg_w + main_line->sx), mask, style->line.color, opa); } else { lv_draw_aa_hor_seg(main_line->p1.x + pattern[aa_last_corner].x, main_line->p1.y + pattern[aa_last_corner].y - 1, - seg_w + main_line->sx, mask, style->line.color, opa); + seg_w + main_line->sx, mask, style->line.color, opa); lv_draw_aa_hor_seg(main_line->p2.x + pattern[aa_last_corner].x, main_line->p2.y + pattern[aa_last_corner].y + 1, - -(seg_w + main_line->sx), mask, style->line.color, opa); + -(seg_w + main_line->sx), mask, style->line.color, opa); } } @@ -441,9 +447,9 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_ #if LV_ANTIALIAS lv_draw_aa_hor_seg(prev_p.x + pattern[0].x, prev_p.y + pattern[0].y - aa_shift1, - -(main_line->p_act.x - prev_p.x), mask, style->line.color, opa); + -(main_line->p_act.x - prev_p.x), mask, style->line.color, opa); lv_draw_aa_hor_seg(prev_p.x + pattern[width_safe - 1].x, prev_p.y + pattern[width_safe - 1].y + aa_shift2, - main_line->p_act.x - prev_p.x, mask, style->line.color, opa); + main_line->p_act.x - prev_p.x, mask, style->line.color, opa); #endif first_run = false; @@ -468,9 +474,9 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_ #if LV_ANTIALIAS lv_draw_aa_hor_seg(prev_p.x + pattern[0].x, prev_p.y + pattern[0].y - aa_shift1, - -(main_line->p_act.x - prev_p.x + 1), mask, style->line.color, opa); + -(main_line->p_act.x - prev_p.x + 1), mask, style->line.color, opa); lv_draw_aa_hor_seg(prev_p.x + pattern[width_safe - 1].x, prev_p.y + pattern[width_safe - 1].y + aa_shift2, - main_line->p_act.x - prev_p.x + 1, mask, style->line.color, opa); + main_line->p_act.x - prev_p.x + 1, mask, style->line.color, opa); #endif } /*Rather a vertical line*/ @@ -495,9 +501,9 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_ #if LV_ANTIALIAS lv_draw_aa_ver_seg(prev_p.x + pattern[0].x - aa_shift1, prev_p.y + pattern[0].y, - -(main_line->p_act.y - prev_p.y), mask, style->line.color, opa); + -(main_line->p_act.y - prev_p.y), mask, style->line.color, opa); lv_draw_aa_ver_seg(prev_p.x + pattern[width_safe - 1].x + aa_shift2, prev_p.y + pattern[width_safe - 1].y, - main_line->p_act.y - prev_p.y, mask, style->line.color, opa); + main_line->p_act.y - prev_p.y, mask, style->line.color, opa); #endif first_run = false; @@ -524,9 +530,9 @@ static void line_draw_skew(line_draw_t * main_line, bool dir_ori, const lv_area_ #if LV_ANTIALIAS lv_draw_aa_ver_seg(prev_p.x + pattern[0].x - aa_shift1, prev_p.y + pattern[0].y, - -(main_line->p_act.y - prev_p.y + 1), mask, style->line.color, opa); + -(main_line->p_act.y - prev_p.y + 1), mask, style->line.color, opa); lv_draw_aa_ver_seg(prev_p.x + pattern[width_safe - 1].x + aa_shift2, prev_p.y + pattern[width_safe - 1].y, - main_line->p_act.y - prev_p.y + 1, mask, style->line.color, opa); + main_line->p_act.y - prev_p.y + 1, mask, style->line.color, opa); #endif } } From 49b136191fa43f15a5bab46f212cd26cf5b1e48f Mon Sep 17 00:00:00 2001 From: Samuel Date: Wed, 12 Dec 2018 11:30:17 +0800 Subject: [PATCH 19/42] Update lv_btnm.c Attempt to fix an LV_BORDER_RIGHT drawing issue. --- lv_objx/lv_btnm.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/lv_objx/lv_btnm.c b/lv_objx/lv_btnm.c index 73a96e39d..ac47b9c8c 100644 --- a/lv_objx/lv_btnm.c +++ b/lv_objx/lv_btnm.c @@ -437,7 +437,6 @@ static bool lv_btnm_design(lv_obj_t * btnm, const lv_area_t * mask, lv_design_mo lv_area_t area_tmp; lv_coord_t btn_w; lv_coord_t btn_h; - bool border_mod = false; uint16_t btn_i = 0; uint16_t txt_i = 0; @@ -465,21 +464,8 @@ static bool lv_btnm_design(lv_obj_t * btnm, const lv_area_t * mask, lv_design_mo else if(btn_i == ext->btn_id_pr && btn_i == ext->btn_id_tgl) btn_style = lv_btnm_get_style(btnm, LV_BTNM_STYLE_BTN_TGL_PR); else btn_style = lv_btnm_get_style(btnm, LV_BTNM_STYLE_BTN_REL); /*Not possible option, just to be sure*/ - /*On the right buttons clear the border if only right borders are drawn*/ - if(ext->map_p[txt_i + 1][0] == '\0' || ext->map_p[txt_i + 1][0] == '\n') { - if(btn_style->body.border.part == LV_BORDER_RIGHT) { - btn_style->body.border.part = LV_BORDER_NONE; - border_mod = true; - } - } - lv_draw_rect(&area_tmp, mask, btn_style, opa_scale); - if(border_mod) { - border_mod = false; - btn_style->body.border.part = LV_BORDER_RIGHT; - } - /*Calculate the size of the text*/ if(btn_style->glass) btn_style = bg_style; const lv_font_t * font = btn_style->text.font; @@ -493,7 +479,6 @@ static bool lv_btnm_design(lv_obj_t * btnm, const lv_area_t * mask, lv_design_mo area_tmp.x2 = area_tmp.x1 + txt_size.x; area_tmp.y2 = area_tmp.y1 + txt_size.y; - lv_draw_label(&area_tmp, mask, btn_style, opa_scale, ext->map_p[txt_i], LV_TXT_FLAG_NONE, NULL); } } From a7bc41b528600e489307aa6dc389b42a01264952 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 12 Dec 2018 09:08:10 +0100 Subject: [PATCH 20/42] ddlist and roller delete fix --- lv_objx/lv_ddlist.c | 3 +++ lv_objx/lv_roller.c | 4 +--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lv_objx/lv_ddlist.c b/lv_objx/lv_ddlist.c index 66baf77f8..657d4e5c9 100644 --- a/lv_objx/lv_ddlist.c +++ b/lv_objx/lv_ddlist.c @@ -470,6 +470,9 @@ static lv_txt_flag_t lv_ddlist_get_txt_flag(const lv_obj_t *ddlist) { lv_ddlist_ext_t * ext = lv_obj_get_ext_attr(ddlist); + /*The label might be already deleted so just return with some value*/ + if(!ext->label) return LV_TXT_FLAG_CENTER; + lv_label_align_t align = lv_label_get_align(ext->label); switch(align) diff --git a/lv_objx/lv_roller.c b/lv_objx/lv_roller.c index 8f70c484d..db7d6b04c 100644 --- a/lv_objx/lv_roller.c +++ b/lv_objx/lv_roller.c @@ -334,10 +334,8 @@ static lv_res_t lv_roller_signal(lv_obj_t * roller, lv_signal_t sign, void * par lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller); lv_align_t obj_align = LV_ALIGN_IN_LEFT_MID; - - { + if(ext->ddlist.label) { lv_label_align_t label_align = lv_label_get_align(ext->ddlist.label); - if(LV_LABEL_ALIGN_CENTER == label_align) obj_align = LV_ALIGN_CENTER; else if(LV_LABEL_ALIGN_RIGHT == label_align) obj_align = LV_ALIGN_IN_RIGHT_MID; } From 86de6f5fbc027c05506bb7bd625b46c2b832c372 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 12 Dec 2018 18:55:32 +0100 Subject: [PATCH 21/42] lv_font: fix typo --- lv_misc/lv_font.c | 2 +- lv_misc/lv_font.h | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lv_misc/lv_font.c b/lv_misc/lv_font.c index c9fd008c5..a794be888 100644 --- a/lv_misc/lv_font.c +++ b/lv_misc/lv_font.c @@ -50,7 +50,7 @@ void lv_font_init(void) * Create a pair from font name and font dsc. get function. After it 'font_get' can be used for this font * @param name name of the font * @param dsc_get_fp the font descriptor get function - * @param parent add this font as charter set extension of 'parent' + * @param parent add this font as character set extension of 'parent' */ void lv_font_add(lv_font_t * child, lv_font_t * parent) { diff --git a/lv_misc/lv_font.h b/lv_misc/lv_font.h index bbf56fd57..a26b73a95 100644 --- a/lv_misc/lv_font.h +++ b/lv_misc/lv_font.h @@ -73,8 +73,9 @@ void lv_font_init(void); /** * Create a pair from font name and font dsc. get function. After it 'font_get' can be used for this font - * @param child pointer to a font to join to the 'parent' - * @param parent pointer to a font. 'child' will be joined here + * @param name name of the font + * @param dsc_get_fp the font descriptor get function + * @param parent add this font as character set extension of 'parent' */ void lv_font_add(lv_font_t *child, lv_font_t *parent); From 6c552e8447e249e7fe729dca76409d41dfb4e710 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Wed, 12 Dec 2018 23:45:06 +0100 Subject: [PATCH 22/42] ta: fix cursor draw with LV_TXT_UTF8 == 0 --- lv_objx/lv_ta.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lv_objx/lv_ta.c b/lv_objx/lv_ta.c index f3dd9e7ee..9d3195946 100644 --- a/lv_objx/lv_ta.c +++ b/lv_objx/lv_ta.c @@ -966,11 +966,12 @@ static bool lv_ta_scrollable_design(lv_obj_t * scrl, const lv_area_t * mask, lv_ uint32_t byte_pos; #if LV_TXT_UTF8 != 0 byte_pos = lv_txt_encoded_get_byte_id(txt, cur_pos); + uint32_t letter = lv_txt_encoded_next(&txt[byte_pos], NULL); #else byte_pos = cur_pos; + uint32_t letter = txt[byte_pos]; #endif - uint32_t letter = lv_txt_encoded_next(&txt[byte_pos], NULL); lv_coord_t letter_h = lv_font_get_height(label_style->text.font); /*Set letter_w (set not 0 on non printable but valid chars)*/ lv_coord_t letter_w; @@ -1003,6 +1004,7 @@ static bool lv_ta_scrollable_design(lv_obj_t * scrl, const lv_area_t * mask, lv_ } } + /*Draw he cursor according to the type*/ lv_area_t cur_area; if(ext->cursor.type == LV_CURSOR_LINE) { From 1ccec72f8c44a5cbe8b9314b0d4118afd8509c8c Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Wed, 12 Dec 2018 20:15:09 -0500 Subject: [PATCH 23/42] Move ifdef guard around lv_sw_set_anim_time --- lv_objx/lv_sw.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lv_objx/lv_sw.c b/lv_objx/lv_sw.c index 8a43c56b2..cf88801f7 100644 --- a/lv_objx/lv_sw.c +++ b/lv_objx/lv_sw.c @@ -206,13 +206,15 @@ void lv_sw_set_style(lv_obj_t * sw, lv_sw_style_t type, lv_style_t * style) break; } } -#if USE_LV_ANIMATION + void lv_sw_set_anim_time(lv_obj_t *sw, uint16_t anim_time) { +#if USE_LV_ANIMATION lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); ext->anim_time = anim_time; -} #endif +} + /*===================== * Getter functions From dea81daa79c57a261a7d7e61d5b078e42921d340 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Thu, 13 Dec 2018 15:18:06 +0100 Subject: [PATCH 24/42] add lv_font_remove --- lv_misc/lv_font.c | 25 +++++++++++++++++++++---- lv_misc/lv_font.h | 14 ++++++++++---- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/lv_misc/lv_font.c b/lv_misc/lv_font.c index a794be888..0aa7fe22a 100644 --- a/lv_misc/lv_font.c +++ b/lv_misc/lv_font.c @@ -47,10 +47,9 @@ void lv_font_init(void) } /** - * Create a pair from font name and font dsc. get function. After it 'font_get' can be used for this font - * @param name name of the font - * @param dsc_get_fp the font descriptor get function - * @param parent add this font as character set extension of 'parent' + * Add a font to an other to extend the character set. + * @param child the font to add + * @param parent this font will be extended. Using it later will contain the characters from `child` */ void lv_font_add(lv_font_t * child, lv_font_t * parent) { @@ -64,6 +63,24 @@ void lv_font_add(lv_font_t * child, lv_font_t * parent) } +/** + * Remove a font from a character set. + * @param child the font to remove + * @param parent remove `child` from here + */ +void lv_font_remove(lv_font_t * child, lv_font_t * parent) +{ + if(parent == NULL) return; + if(child == NULL) return; + + while(parent->next_page != child) { + parent = parent->next_page; /*Got to the last page and add the new font there*/ + } + + parent->next_page = child->next_page; +} + + /** * Tells if font which contains `letter` is monospace or not * @param font_p point to font diff --git a/lv_misc/lv_font.h b/lv_misc/lv_font.h index a26b73a95..d1d24f3fe 100644 --- a/lv_misc/lv_font.h +++ b/lv_misc/lv_font.h @@ -72,13 +72,19 @@ typedef struct _lv_font_struct void lv_font_init(void); /** - * Create a pair from font name and font dsc. get function. After it 'font_get' can be used for this font - * @param name name of the font - * @param dsc_get_fp the font descriptor get function - * @param parent add this font as character set extension of 'parent' + * Add a font to an other to extend the character set. + * @param child the font to add + * @param parent this font will be extended. Using it later will contain the characters from `child` */ void lv_font_add(lv_font_t *child, lv_font_t *parent); +/** + * Remove a font from a character set. + * @param child the font to remove + * @param parent remove `child` from here + */ +void lv_font_remove(lv_font_t * child, lv_font_t * parent); + /** * Tells if font which contains `letter` is monospace or not * @param font_p point to font From 1e23df926c73dad57ecbf96d8d6fba76015ce6c1 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Thu, 13 Dec 2018 17:38:27 +0100 Subject: [PATCH 25/42] lv_table updates --- lv_objx/lv_objx_templ.c | 10 +- lv_objx/lv_table.c | 339 ++++++++++++++++++++++++++++++---------- lv_objx/lv_table.h | 130 ++++++++++++--- 3 files changed, 363 insertions(+), 116 deletions(-) diff --git a/lv_objx/lv_objx_templ.c b/lv_objx/lv_objx_templ.c index 0798a70a6..f605450ca 100644 --- a/lv_objx/lv_objx_templ.c +++ b/lv_objx/lv_objx_templ.c @@ -144,18 +144,18 @@ void lv_templ_set_style(lv_obj_t * templ, lv_templ_style_t type, lv_style_t * st lv_style_t * lv_templ_get_style(const lv_obj_t * templ, lv_templ_style_t type) { lv_templ_ext_t * ext = lv_obj_get_ext_attr(templ); + lv_style_t * style = NULL; switch(type) { case LV_TEMPL_STYLE_X: - return NULL; + style = NULL; /*Replace NULL with a pointer to the style*/ case LV_TEMPL_STYLE_Y: - return NULL; + style = NULL; /*Replace NULL with a pointer to the style*/ default: - return NULL; + style = NULL; } - /*To avoid warning*/ - return NULL; + return style; } /*===================== diff --git a/lv_objx/lv_table.c b/lv_objx/lv_table.c index ea538009d..f997beb6c 100644 --- a/lv_objx/lv_table.c +++ b/lv_objx/lv_table.c @@ -67,12 +67,14 @@ lv_obj_t * lv_table_create(lv_obj_t * par, const lv_obj_t * copy) /*Initialize the allocated 'ext' */ ext->cell_data = NULL; - ext->cell_style = &lv_style_pretty; + ext->cell_style = &lv_style_plain; ext->col_cnt = 0; ext->row_cnt = 0; - ext->col_w[0] = 50; - ext->col_w[1] = 70; - ext->col_w[2] = 80; + + uint16_t i; + for(i = 0; i < LV_TABLE_COL_MAX; i++) { + ext->col_w[i] = LV_DPI; + } /*The signal and design functions are not copied so set them here*/ lv_obj_set_signal_func(new_table, lv_table_signal); @@ -80,11 +82,14 @@ lv_obj_t * lv_table_create(lv_obj_t * par, const lv_obj_t * copy) /*Init the new table table*/ if(copy == NULL) { - + lv_table_set_style(new_table, LV_TABLE_STYLE_BG, &lv_style_plain_color); } /*Copy an existing table*/ else { lv_table_ext_t * copy_ext = lv_obj_get_ext_attr(copy); + ext->cell_style = copy_ext->cell_style; + ext->col_cnt = copy_ext->col_cnt; + ext->row_cnt = copy_ext->row_cnt; /*Refresh the style with new signal function*/ lv_obj_refresh_style(new_table); @@ -95,19 +100,17 @@ lv_obj_t * lv_table_create(lv_obj_t * par, const lv_obj_t * copy) return new_table; } -/*====================== - * Add/remove functions - *=====================*/ - -/* - * New object specific "add" or "remove" functions come here - */ - - /*===================== * Setter functions *====================*/ +/** + * Set the value of a cell. + * @param table 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 txt text to display in the cell. It will be copied and saved so this variable is not required after this function call. + */ void lv_table_set_cell_value(lv_obj_t * table, uint16_t row, uint16_t col, const char * txt) { lv_table_ext_t * ext = lv_obj_get_ext_attr(table); @@ -116,55 +119,30 @@ void lv_table_set_cell_value(lv_obj_t * table, uint16_t row, uint16_t col, const return; } uint32_t cell = row * ext->col_cnt + col; + lv_table_cell_format_t format; + + /*Save the format byte*/ + if(ext->cell_data[cell]) { + format.format_byte = ext->cell_data[cell][0]; + } + /*Initialize the format byte*/ + else { + format.align = LV_LABEL_ALIGN_LEFT; + format.right_merge = 0; + } + + ext->cell_data[cell] = lv_mem_realloc(ext->cell_data[cell], strlen(txt) + 2); /*+1: trailing '\0; +1: format byte*/ - strcpy(ext->cell_data[cell] + 1, txt); /*Leave the format byte*/ + strcpy(ext->cell_data[cell] + 1, txt); /*Leave the format byte*/ + ext->cell_data[cell][0] = format.format_byte; refr_size(table); } -void lv_table_set_cell_format(lv_obj_t * table, uint16_t row, uint16_t col, lv_table_cell_align_t align) -{ - lv_table_ext_t * ext = lv_obj_get_ext_attr(table); - if(row >= ext->row_cnt || col >= ext->col_cnt) { - LV_LOG_WARN("lv_table_set_cell_format: invalid row or column"); - return; - } - uint32_t cell = row * ext->col_cnt + col; - - if(ext->cell_data[cell] == NULL) { - ext->cell_data[cell] = lv_mem_alloc(2); /*+1: trailing '\0; +1: format byte*/ - ext->cell_data[1] = '\0'; - } - - lv_table_cell_format_t format; - format.format_byte = ext->cell_data[cell][0]; - format.align = align; - ext->cell_data[cell][0] = format.format_byte; -} - -void lv_table_set_cell_merge_right(lv_obj_t * table, uint16_t row, uint16_t col, bool en) -{ - lv_table_ext_t * ext = lv_obj_get_ext_attr(table); - if(row >= ext->row_cnt || col >= ext->col_cnt) { - LV_LOG_WARN("lv_table_set_cell_merge_right: invalid row or column"); - return; - } - - uint32_t cell = row * ext->col_cnt + col; - - if(ext->cell_data[cell] == NULL) { - ext->cell_data[cell] = lv_mem_alloc(2); /*+1: trailing '\0; +1: format byte*/ - ext->cell_data[1] = '\0'; - } - - lv_table_cell_format_t format; - format.format_byte = ext->cell_data[cell][0]; - format.right_merge = en ? 1 : 0; - ext->cell_data[cell][0] = format.format_byte; - refr_size(table); -} - - - +/** + * Set the number of rows + * @param table table pointer to a Table object + * @param row_cnt number of rows + */ void lv_table_set_row_cnt(lv_obj_t * table, uint16_t row_cnt) { lv_table_ext_t * ext = lv_obj_get_ext_attr(table); @@ -181,8 +159,19 @@ void lv_table_set_row_cnt(lv_obj_t * table, uint16_t row_cnt) refr_size(table); } +/** + * Set the number of columns + * @param table table pointer to a Table object + * @param col_cnt number of columns. Must be < LV_TABLE_COL_MAX + */ void lv_table_set_col_cnt(lv_obj_t * table, uint16_t col_cnt) { + + if(col_cnt >= LV_TABLE_COL_MAX) { + LV_LOG_WARN("lv_table_set_col_cnt: too many columns. Must be < LV_TABLE_COL_MAX."); + return; + } + lv_table_ext_t * ext = lv_obj_get_ext_attr(table); ext->col_cnt = col_cnt; @@ -196,6 +185,79 @@ void lv_table_set_col_cnt(lv_obj_t * table, uint16_t col_cnt) refr_size(table); } +/** + * Set the width of a column + * @param table table pointer to a Table object + * @param col_id id of the column [0 .. LV_TABLE_COL_MAX -1] + * @param w width of the column + */ +void lv_table_set_col_width(lv_obj_t * table, uint16_t col_id, lv_coord_t w) +{ + if(col_id >= LV_TABLE_COL_MAX) { + LV_LOG_WARN("lv_table_set_col_width: too big 'col_id'. Must be < LV_TABLE_COL_MAX."); + return; + } + + lv_table_ext_t * ext = lv_obj_get_ext_attr(table); + ext->col_w[col_id] = w; + refr_size(table); +} + +/** + * Set the text align in a cell + * @param table 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 align LV_LABEL_ALIGN_LEFT or LV_LABEL_ALIGN_CENTER or LV_LABEL_ALIGN_RIGHT + */ +void lv_table_set_cell_align(lv_obj_t * table, uint16_t row, uint16_t col, lv_label_align_t align) +{ + lv_table_ext_t * ext = lv_obj_get_ext_attr(table); + if(row >= ext->row_cnt || col >= ext->col_cnt) { + LV_LOG_WARN("lv_table_set_cell_align: invalid row or column"); + return; + } + uint32_t cell = row * ext->col_cnt + col; + + if(ext->cell_data[cell] == NULL) { + ext->cell_data[cell] = lv_mem_alloc(2); /*+1: trailing '\0; +1: format byte*/ + ext->cell_data[cell][1] = '\0'; + } + + lv_table_cell_format_t format; + format.format_byte = ext->cell_data[cell][0]; + format.align = align; + ext->cell_data[cell][0] = format.format_byte; +} + +/** + * Merge a cell with the right neighbor. The value of the cell to the right won't be displayed. + * @param table table 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 en true: merge right; false: don't merge right + */ +void lv_table_set_cell_merge_right(lv_obj_t * table, uint16_t row, uint16_t col, bool en) +{ + lv_table_ext_t * ext = lv_obj_get_ext_attr(table); + if(row >= ext->row_cnt || col >= ext->col_cnt) { + LV_LOG_WARN("lv_table_set_cell_merge_right: invalid row or column"); + return; + } + + uint32_t cell = row * ext->col_cnt + col; + + if(ext->cell_data[cell] == NULL) { + ext->cell_data[cell] = lv_mem_alloc(2); /*+1: trailing '\0; +1: format byte*/ + ext->cell_data[cell][1] = '\0'; + } + + lv_table_cell_format_t format; + format.format_byte = ext->cell_data[cell][0]; + format.right_merge = en ? 1 : 0; + ext->cell_data[cell][0] = format.format_byte; + refr_size(table); +} /** * Set a style of a table. @@ -208,9 +270,13 @@ void lv_table_set_style(lv_obj_t * table, lv_table_style_t type, lv_style_t * st lv_table_ext_t * ext = lv_obj_get_ext_attr(table); switch(type) { - case LV_TABLE_STYLE_X: + case LV_TABLE_STYLE_BG: + lv_obj_set_style(table, style); + refr_size(table); break; - case LV_TABLE_STYLE_Y: + case LV_TABLE_STYLE_CELL: + ext->cell_style = style; + lv_obj_invalidate(table); break; } } @@ -219,9 +285,114 @@ void lv_table_set_style(lv_obj_t * table, lv_table_style_t type, lv_style_t * st * Getter functions *====================*/ -/* - * New object specific "get" functions come here +/** + * Get the value of a cell. + * @param table 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] + * @return text in the cell */ +const char * lv_table_get_cell_value(lv_obj_t * table, uint16_t row, uint16_t col) +{ + lv_table_ext_t * ext = lv_obj_get_ext_attr(table); + if(row >= ext->row_cnt || col >= ext->col_cnt) { + LV_LOG_WARN("lv_table_set_cell_value: invalid row or column"); + return ""; + } + uint32_t cell = row * ext->col_cnt + col; + + if(ext->cell_data[cell] == NULL) return ""; + + return &ext->cell_data[cell][1]; /*Skip the format byte*/ +} + +/** + * Get the number of rows. + * @param table table pointer to a Table object + * @return number of rows. + */ +uint16_t lv_table_get_row_cnt(lv_obj_t * table) +{ + lv_table_ext_t * ext = lv_obj_get_ext_attr(table); + return ext->row_cnt; +} + +/** + * Get the number of columns. + * @param table table pointer to a Table object + * @return number of columns. + */ +uint16_t lv_table_get_col_cnt(lv_obj_t * table) +{ + lv_table_ext_t * ext = lv_obj_get_ext_attr(table); + return ext->col_cnt; +} + +/** + * Get the width of a column + * @param table table pointer to a Table object + * @param col_id id of the column [0 .. LV_TABLE_COL_MAX -1] + * @return width of the column + */ +lv_coord_t lv_table_get_col_width(lv_obj_t * table, uint16_t col_id) +{ + if(col_id >= LV_TABLE_COL_MAX) { + LV_LOG_WARN("lv_table_set_col_width: too big 'col_id'. Must be < LV_TABLE_COL_MAX."); + return 0; + } + + lv_table_ext_t * ext = lv_obj_get_ext_attr(table); + return ext->col_w[col_id]; +} + +/** + * Get the text align of a cell + * @param table 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] + * @return LV_LABEL_ALIGN_LEFT (default in case of error) or LV_LABEL_ALIGN_CENTER or LV_LABEL_ALIGN_RIGHT + */ +lv_label_align_t lv_table_get_cell_align(lv_obj_t * table, uint16_t row, uint16_t col) +{ + lv_table_ext_t * ext = lv_obj_get_ext_attr(table); + if(row >= ext->row_cnt || col >= ext->col_cnt) { + LV_LOG_WARN("lv_table_set_cell_align: invalid row or column"); + return LV_LABEL_ALIGN_LEFT; /*Just return with something*/ + } + uint32_t cell = row * ext->col_cnt + col; + + if(ext->cell_data[cell] == NULL) return LV_LABEL_ALIGN_LEFT; /*Just return with something*/ + else { + lv_table_cell_format_t format; + format.format_byte = ext->cell_data[cell][0]; + return format.align; + } +} + +/** + * Get the cell merge attribute. + * @param table table 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] + * @return true: merge right; false: don't merge right + */ +bool lv_table_get_cell_merge_right(lv_obj_t * table, uint16_t row, uint16_t col) +{ + lv_table_ext_t * ext = lv_obj_get_ext_attr(table); + if(row >= ext->row_cnt || col >= ext->col_cnt) { + LV_LOG_WARN("lv_table_get_cell_merge_right: invalid row or column"); + return false; + } + + uint32_t cell = row * ext->col_cnt + col; + + if(ext->cell_data[cell] == NULL) return false; + else { + lv_table_cell_format_t format; + format.format_byte = ext->cell_data[cell][0]; + return format.right_merge ? true : false; + } +} /** * Get style of a table. @@ -232,28 +403,22 @@ void lv_table_set_style(lv_obj_t * table, lv_table_style_t type, lv_style_t * st lv_style_t * lv_table_get_style(const lv_obj_t * table, lv_table_style_t type) { lv_table_ext_t * ext = lv_obj_get_ext_attr(table); + lv_style_t * style = NULL; switch(type) { - case LV_TABLE_STYLE_X: - return NULL; - case LV_TABLE_STYLE_Y: - return NULL; + case LV_TABLE_STYLE_BG: + style = lv_obj_get_style(table); + break; + case LV_TABLE_STYLE_CELL: + style = ext->cell_style; + break; default: return NULL; } - /*To avoid warning*/ - return NULL; + return style; } -/*===================== - * Other functions - *====================*/ - -/* - * New object specific "other" functions come here - */ - /********************** * STATIC FUNCTIONS **********************/ @@ -330,13 +495,13 @@ static bool lv_table_design(lv_obj_t * table, const lv_area_t * mask, lv_design_ format.format_byte = ext->cell_data[cell][0]; switch(format.align) { - case LV_TABLE_CELL_ALIGN_LEFT: + case LV_LABEL_ALIGN_LEFT: txt_flags = LV_TXT_FLAG_NONE; break; - case LV_TABLE_CELL_ALIGN_RIGHT: + case LV_LABEL_ALIGN_RIGHT: txt_flags = LV_TXT_FLAG_RIGHT; break; - case LV_TABLE_CELL_ALIGN_CENTER: + case LV_LABEL_ALIGN_CENTER: txt_flags = LV_TXT_FLAG_CENTER; break; } @@ -351,9 +516,6 @@ static bool lv_table_design(lv_obj_t * table, const lv_area_t * mask, lv_design_ col += col_merge; } } - - - } /*Post draw when the children are drawn*/ else if(mode == LV_DESIGN_DRAW_POST) { @@ -380,7 +542,15 @@ static lv_res_t lv_table_signal(lv_obj_t * table, lv_signal_t sign, void * param if(sign == LV_SIGNAL_CLEANUP) { - /*Nothing to cleanup. (No dynamically allocated memory in 'ext')*/ + /*Free the cell texts*/ + lv_table_ext_t * ext = lv_obj_get_ext_attr(table); + uint16_t cell; + for(cell = 0; cell < ext->col_cnt * ext->row_cnt; cell++) { + if(ext->cell_data[cell]) { + lv_mem_free(ext->cell_data[cell]); + ext->cell_data[cell] = NULL; + } + } } else if(sign == LV_SIGNAL_GET_TYPE) { lv_obj_type_t * buf = param; uint8_t i; @@ -446,7 +616,6 @@ static lv_coord_t get_row_height(lv_obj_t * table, uint16_t row_id) } txt_w -= 2 * ext->cell_style->body.padding.hor; - printf("r:%d, c:%d, txt_w:%d\n", row_id, col, txt_w); lv_txt_get_size(&txt_size, ext->cell_data[cell] + 1, ext->cell_style->text.font, ext->cell_style->text.letter_space, ext->cell_style->text.line_space, txt_w, LV_TXT_FLAG_NONE); diff --git a/lv_objx/lv_table.h b/lv_objx/lv_table.h index efb17dc55..0c99dcf6b 100644 --- a/lv_objx/lv_table.h +++ b/lv_objx/lv_table.h @@ -22,6 +22,7 @@ extern "C" { #if USE_LV_TABLE != 0 #include "../lv_core/lv_obj.h" +#include "lv_label.h" /********************* * DEFINES @@ -32,15 +33,9 @@ extern "C" { * TYPEDEFS **********************/ -typedef enum { - LV_TABLE_CELL_ALIGN_LEFT, - LV_TABLE_CELL_ALIGN_RIGHT, - LV_TABLE_CELL_ALIGN_CENTER, -}lv_table_cell_align_t; - typedef union { struct { - uint8_t align:2; + uint8_t align:3; uint8_t right_merge:1; }; uint8_t format_byte; @@ -59,8 +54,8 @@ typedef struct { /*Styles*/ enum { - LV_TABLE_STYLE_X, - LV_TABLE_STYLE_Y, + LV_TABLE_STYLE_BG, + LV_TABLE_STYLE_CELL, }; typedef uint8_t lv_table_style_t; @@ -70,44 +65,127 @@ typedef uint8_t lv_table_style_t; **********************/ /** - * Create a table objects + * Create a table object * @param par pointer to an object, it will be the parent of the new table * @param copy pointer to a table object, if not NULL then the new object will be copied from it * @return pointer to the created table */ lv_obj_t * lv_table_create(lv_obj_t * par, const lv_obj_t * copy); -void lv_table_set_cell_value(lv_obj_t * table, uint16_t row, uint16_t col, const char * txt); - -void lv_table_set_cell_format(lv_obj_t * table, uint16_t row, uint16_t col, lv_table_cell_align_t align); - -void lv_table_set_cell_merge_right(lv_obj_t * table, uint16_t row, uint16_t col, bool en); - -void lv_table_set_row_cnt(lv_obj_t * table, uint16_t row_cnt); - -void lv_table_set_col_cnt(lv_obj_t * table, uint16_t col_cnt); - -/*====================== - * Add/remove functions - *=====================*/ - - /*===================== * Setter functions *====================*/ +/** + * Set the value of a cell. + * @param table 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 txt text to display in the cell. It will be copied and saved so this variable is not required after this function call. + */ +void lv_table_set_cell_value(lv_obj_t * table, uint16_t row, uint16_t col, const char * txt); + +/** + * Set the number of rows + * @param table table pointer to a Table object + * @param row_cnt number of rows + */ +void lv_table_set_row_cnt(lv_obj_t * table, uint16_t row_cnt); + +/** + * Set the number of columns + * @param table table pointer to a Table object + * @param col_cnt number of columns. Must be < LV_TABLE_COL_MAX + */ +void lv_table_set_col_cnt(lv_obj_t * table, uint16_t col_cnt); + +/** + * Set the width of a column + * @param table table pointer to a Table object + * @param col_id id of the column [0 .. LV_TABLE_COL_MAX -1] + * @param w width of the column + */ +void lv_table_set_col_width(lv_obj_t * table, uint16_t col_id, lv_coord_t w); + +/** + * Set the text align in a cell + * @param table 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 align LV_LABEL_ALIGN_LEFT or LV_LABEL_ALIGN_CENTER or LV_LABEL_ALIGN_RIGHT + */ +void lv_table_set_cell_align(lv_obj_t * table, uint16_t row, uint16_t col, lv_label_align_t align); + +/** + * Merge a cell with the right neighbor. The value of the cell to the right won't be displayed. + * @param table table 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 en true: merge right; false: don't merge right + */ +void lv_table_set_cell_merge_right(lv_obj_t * table, uint16_t row, uint16_t col, bool en); + /** * Set a style of a table. * @param table pointer to table object * @param type which style should be set * @param style pointer to a style */ -void lv_table_set_style(lv_obj_t * table, lv_table_style_t type, lv_style_t *style); +void lv_table_set_style(lv_obj_t * table, lv_table_style_t type, lv_style_t * style); /*===================== * Getter functions *====================*/ +/** + * Get the value of a cell. + * @param table 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] + * @return text in the cell + */ +const char * lv_table_get_cell_value(lv_obj_t * table, uint16_t row, uint16_t col); + +/** + * Get the number of rows. + * @param table table pointer to a Table object + * @return number of rows. + */ +uint16_t lv_table_get_row_cnt(lv_obj_t * table); + +/** + * Get the number of columns. + * @param table table pointer to a Table object + * @return number of columns. + */ +uint16_t lv_table_get_col_cnt(lv_obj_t * table); + +/** + * Get the width of a column + * @param table table pointer to a Table object + * @param col_id id of the column [0 .. LV_TABLE_COL_MAX -1] + * @return width of the column + */ +lv_coord_t lv_table_get_col_width(lv_obj_t * table, uint16_t col_id); + +/** + * Get the text align of a cell + * @param table 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] + * @return LV_LABEL_ALIGN_LEFT (default in case of error) or LV_LABEL_ALIGN_CENTER or LV_LABEL_ALIGN_RIGHT + */ +lv_label_align_t lv_table_get_cell_align(lv_obj_t * table, uint16_t row, uint16_t col); + +/** + * Get the cell merge attribute. + * @param table table 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] + * @return true: merge right; false: don't merge right + */ +bool lv_table_get_cell_merge_right(lv_obj_t * table, uint16_t row, uint16_t col); + /** * Get style of a table. * @param table pointer to table object From 4919f24985ce429e66f5f4fce145337eab222904 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Thu, 13 Dec 2018 17:41:59 +0100 Subject: [PATCH 26/42] lv_table updates --- lv_conf_templ.h | 6 ++++++ lv_objx/lv_table.h | 8 +++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lv_conf_templ.h b/lv_conf_templ.h index effc46d26..dd412ea01 100644 --- a/lv_conf_templ.h +++ b/lv_conf_templ.h @@ -247,6 +247,12 @@ /*Chart (dependencies: -)*/ #define USE_LV_CHART 1 +/*Table (dependencies: lv_label)*/ +#define USE_LV_TABLE 1 +#if USE_LV_TABLE +#define LV_TABLE_COL_MAX 12 +#endif + /*LED (dependencies: -)*/ #define USE_LV_LED 1 diff --git a/lv_objx/lv_table.h b/lv_objx/lv_table.h index 0c99dcf6b..b4012299f 100644 --- a/lv_objx/lv_table.h +++ b/lv_objx/lv_table.h @@ -21,14 +21,20 @@ extern "C" { #if USE_LV_TABLE != 0 +/*Testing of dependencies*/ +#if USE_LV_LABEL == 0 +#error "lv_table: lv_label is required. Enable it in lv_conf.h (USE_LV_LABEL 1) " +#endif + #include "../lv_core/lv_obj.h" #include "lv_label.h" /********************* * DEFINES *********************/ +#ifndef LV_TABLE_COL_MAX #define LV_TABLE_COL_MAX 12 - +#endif /********************** * TYPEDEFS **********************/ From 6f1d0ef97b9ee993d16420d94585ba5a1b195bf6 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Fri, 14 Dec 2018 10:33:18 +0100 Subject: [PATCH 27/42] fixes because of sending LV_SIGNAL_PRESSED in LV_GROUP_KEY_ENTER press --- lv_core/lv_indev.c | 2 +- lv_objx/lv_btn.c | 9 +++++---- lv_objx/lv_slider.c | 4 +++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/lv_core/lv_indev.c b/lv_core/lv_indev.c index 69dc29bd0..1955dea44 100644 --- a/lv_core/lv_indev.c +++ b/lv_core/lv_indev.c @@ -369,7 +369,7 @@ static void indev_keypad_proc(lv_indev_t * i, lv_indev_data_t * data) i->proc.last_state == LV_INDEV_STATE_REL) { i->proc.pr_timestamp = lv_tick_get(); lv_obj_t * focused = lv_group_get_focused(i->group); - if(focused) { + if(focused && data->key == LV_GROUP_KEY_ENTER) { focused->signal_func(focused, LV_SIGNAL_PRESSED, indev_act); } } diff --git a/lv_objx/lv_btn.c b/lv_objx/lv_btn.c index 66f94ea78..ab48666ec 100644 --- a/lv_objx/lv_btn.c +++ b/lv_objx/lv_btn.c @@ -674,10 +674,11 @@ static lv_res_t lv_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param) } else if(c == LV_GROUP_KEY_ENTER) { if(!ext->long_pr_action_executed) { if(lv_btn_get_toggle(btn)) { - if(state == LV_BTN_STATE_REL) lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL); - else if(state == LV_BTN_STATE_PR) lv_btn_set_state(btn, LV_BTN_STATE_TGL_PR); - else if(state == LV_BTN_STATE_TGL_REL) lv_btn_set_state(btn, LV_BTN_STATE_REL); - else if(state == LV_BTN_STATE_TGL_PR) lv_btn_set_state(btn, LV_BTN_STATE_PR); + if(state == LV_BTN_STATE_REL || state == LV_BTN_STATE_PR) lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL); + else if(state == LV_BTN_STATE_TGL_REL || state == LV_BTN_STATE_TGL_PR) lv_btn_set_state(btn, LV_BTN_STATE_REL); + } else { + if(state == LV_BTN_STATE_REL || state == LV_BTN_STATE_PR) lv_btn_set_state(btn, LV_BTN_STATE_REL); + else if(state == LV_BTN_STATE_TGL_REL || state == LV_BTN_STATE_TGL_PR) lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL); } if(ext->actions[LV_BTN_ACTION_CLICK] && state != LV_BTN_STATE_INA) { res = ext->actions[LV_BTN_ACTION_CLICK](btn); diff --git a/lv_objx/lv_slider.c b/lv_objx/lv_slider.c index c94220261..bc7dfaa3f 100644 --- a/lv_objx/lv_slider.c +++ b/lv_objx/lv_slider.c @@ -490,11 +490,13 @@ static lv_res_t lv_slider_signal(lv_obj_t * slider, lv_signal_t sign, void * par } } else if(sign == LV_SIGNAL_CONTROLL) { char c = *((char *)param); + + ext->drag_value = LV_SLIDER_NOT_PRESSED; + #if USE_LV_GROUP lv_group_t * g = lv_obj_get_group(slider); bool editing = lv_group_get_editing(g); lv_hal_indev_type_t indev_type = lv_indev_get_type(lv_indev_get_act()); - /*Encoders need special handling*/ if(indev_type == LV_INDEV_TYPE_ENCODER && c == LV_GROUP_KEY_ENTER) { if(editing) lv_group_set_editing(g, false); From 9817e050e088ba96ac15722bcedf57ed4131a0ac Mon Sep 17 00:00:00 2001 From: Josh Date: Fri, 14 Dec 2018 13:05:00 -0800 Subject: [PATCH 28/42] Add wrap enable/disable for lv_group Allows for controlling whether focus next/prev will wrap at the boundaries, or if they will stop at the boundaries. --- lv_core/lv_group.c | 31 +++++++++++++++++++++++++++++-- lv_core/lv_group.h | 14 ++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/lv_core/lv_group.c b/lv_core/lv_group.c index 4a87067e8..17190f428 100644 --- a/lv_core/lv_group.c +++ b/lv_core/lv_group.c @@ -204,7 +204,10 @@ void lv_group_focus_next(lv_group_t * group) if(group->obj_focus == NULL) obj_next = lv_ll_get_head(&group->obj_ll); else obj_next = lv_ll_get_next(&group->obj_ll, group->obj_focus); - if(obj_next == NULL) obj_next = lv_ll_get_head(&group->obj_ll); + if(obj_next == NULL) { + if(group->wrap) obj_next = lv_ll_get_head(&group->obj_ll); + else obj_next = lv_ll_get_tail(&group->obj_ll); + } group->obj_focus = obj_next; if(group->obj_focus) { @@ -232,7 +235,10 @@ void lv_group_focus_prev(lv_group_t * group) if(group->obj_focus == NULL) obj_next = lv_ll_get_tail(&group->obj_ll); else obj_next = lv_ll_get_prev(&group->obj_ll, group->obj_focus); - if(obj_next == NULL) obj_next = lv_ll_get_tail(&group->obj_ll); + if(obj_next == NULL) { + if(group->wrap) obj_next = lv_ll_get_tail(&group->obj_ll); + else obj_next = lv_ll_get_head(&group->obj_ll); + } group->obj_focus = obj_next; if(group->obj_focus != NULL) { @@ -340,6 +346,16 @@ static void lv_group_refocus(lv_group_t *g) { lv_group_focus_prev(g); } +/** + * Set whether focus next/prev will allow wrapping from first->last or last->first. + * @param group pointer to group + * @param en: true: enable `click_focus` + */ +void lv_group_set_wrap(lv_group_t * group, bool en) +{ + group->wrap = en ? 1 : 0; +} + /** * Modify a style with the set 'style_mod' function. The input style remains unchanged. * @param group pointer to group @@ -428,6 +444,17 @@ bool lv_group_get_click_focus(const lv_group_t * group) return group->click_focus ? true : false; } +/** + * Get whether focus next/prev will allow wrapping from first->last or last->first object. + * @param group pointer to group + * @param en: true: wrapping enabled; false: wrapping disabled + */ +bool lv_group_get_wrap(lv_group_t * group) +{ + if(!group) return false; + return group->wrap ? true : false; +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/lv_core/lv_group.h b/lv_core/lv_group.h index 17f9edb93..c7e3ad531 100644 --- a/lv_core/lv_group.h +++ b/lv_core/lv_group.h @@ -58,6 +58,7 @@ typedef struct _lv_group_t uint8_t editing :1; /*1: Edit mode, 0: Navigate mode*/ uint8_t click_focus :1; /*1: If an object in a group is clicked by an indev then it will be focused */ uint8_t refocus_policy :1; /*1: Focus prev if focused on deletion. 0: Focus prev if focused on deletion.*/ + uint8_t wrap :1; /*1: Focus next/prev can wrap at end of list. 0: Focus next/prev stops at end of list.*/ } lv_group_t; typedef enum _lv_group_refocus_policy_t { @@ -168,6 +169,13 @@ void lv_group_set_editing(lv_group_t * group, bool edit); */ void lv_group_set_click_focus(lv_group_t * group, bool en); +/** + * Set whether focus next/prev will allow wrapping from first->last or last->first object. + * @param group pointer to group + * @param en: true: wrapping enabled; false: wrapping disabled + */ +void lv_group_set_wrap(lv_group_t * group, bool en); + /** * Modify a style with the set 'style_mod' function. The input style remains unchanged. * @param group pointer to group @@ -218,6 +226,12 @@ bool lv_group_get_editing(const lv_group_t * group); */ bool lv_group_get_click_focus(const lv_group_t * group); +/** + * Get whether focus next/prev will allow wrapping from first->last or last->first object. + * @param group pointer to group + * @param en: true: wrapping enabled; false: wrapping disabled + */ +bool lv_group_get_wrap(lv_group_t * group); /********************** * MACROS From b1712325a7cfcf9e6f802acf279b002d562ba202 Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Fri, 14 Dec 2018 16:32:22 -0500 Subject: [PATCH 29/42] Fix OK and close button symbols appearing in text area --- lv_objx/lv_kb.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lv_objx/lv_kb.c b/lv_objx/lv_kb.c index 7f1fb003c..d0e3cd5ac 100644 --- a/lv_objx/lv_kb.c +++ b/lv_objx/lv_kb.c @@ -430,6 +430,9 @@ static lv_res_t lv_kb_def_action(lv_obj_t * kb, const char * txt) if(res != LV_RES_OK) return res; /*The keyboard might be deleted in the actions*/ + /*If it's the OK or Close button do nothing */ + if((strcmp(txt, SYMBOL_OK) == 0) || (strcmp(txt, SYMBOL_CLOSE) == 0)) return LV_RES_OK; + /*Add the characters to the text area if set*/ if(ext->ta == NULL) return res; From 47bdf497b6a6eac52a143ca7f1665217f19dbc4f Mon Sep 17 00:00:00 2001 From: Josh Date: Fri, 14 Dec 2018 14:24:47 -0800 Subject: [PATCH 30/42] Fix lv_group wrap behavior when removing head or tail object from group --- lv_core/lv_group.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/lv_core/lv_group.c b/lv_core/lv_group.c index 17190f428..e1d216a75 100644 --- a/lv_core/lv_group.c +++ b/lv_core/lv_group.c @@ -340,10 +340,15 @@ void lv_group_set_refocus_policy(lv_group_t * group, lv_group_refocus_policy_t p } static void lv_group_refocus(lv_group_t *g) { - if(g->refocus_policy == LV_GROUP_REFOCUS_POLICY_NEXT) - lv_group_focus_next(g); - else if(g->refocus_policy == LV_GROUP_REFOCUS_POLICY_PREV) - lv_group_focus_prev(g); + /*Refocus must temporarily allow wrapping to work correctly*/ + uint8_t temp_wrap = g->wrap; + + if(g->refocus_policy == LV_GROUP_REFOCUS_POLICY_NEXT) + lv_group_focus_next(g); + else if(g->refocus_policy == LV_GROUP_REFOCUS_POLICY_PREV) + lv_group_focus_prev(g); + /*Restore wrap property*/ + g->wrap = temp_wrap; } /** From 3b81dc2a557423e5802f13f5cafb6b87745383f1 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Sat, 15 Dec 2018 00:11:28 +0100 Subject: [PATCH 31/42] lv_kb: bugfix update --- lv_objx/lv_kb.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lv_objx/lv_kb.c b/lv_objx/lv_kb.c index d0e3cd5ac..c90ab27ad 100644 --- a/lv_objx/lv_kb.c +++ b/lv_objx/lv_kb.c @@ -419,20 +419,18 @@ static lv_res_t lv_kb_def_action(lv_obj_t * kb, const char * txt) lv_kb_set_ta(kb, NULL); /*De-assign the text area to hide it cursor if needed*/ lv_obj_del(kb); } - return LV_RES_INV; + return res; } else if(strcmp(txt, SYMBOL_OK) == 0) { if(ext->ok_action) res = ext->ok_action(kb); else { lv_kb_set_ta(kb, NULL); /*De-assign the text area to hide it cursor if needed*/ res = lv_obj_del(kb); } + return res; } if(res != LV_RES_OK) return res; /*The keyboard might be deleted in the actions*/ - /*If it's the OK or Close button do nothing */ - if((strcmp(txt, SYMBOL_OK) == 0) || (strcmp(txt, SYMBOL_CLOSE) == 0)) return LV_RES_OK; - /*Add the characters to the text area if set*/ if(ext->ta == NULL) return res; From 92747ec37a19d73402c050e6e4b514254a97e764 Mon Sep 17 00:00:00 2001 From: Josh Date: Fri, 14 Dec 2018 16:02:29 -0800 Subject: [PATCH 32/42] Fix missing temporary setting of wrap to 1 --- lv_core/lv_group.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lv_core/lv_group.c b/lv_core/lv_group.c index e1d216a75..9c1ed4b54 100644 --- a/lv_core/lv_group.c +++ b/lv_core/lv_group.c @@ -342,6 +342,7 @@ void lv_group_set_refocus_policy(lv_group_t * group, lv_group_refocus_policy_t p static void lv_group_refocus(lv_group_t *g) { /*Refocus must temporarily allow wrapping to work correctly*/ uint8_t temp_wrap = g->wrap; + g->wrap = 1; if(g->refocus_policy == LV_GROUP_REFOCUS_POLICY_NEXT) lv_group_focus_next(g); From c74f4656fc500cb362338008e546991763e6e055 Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Fri, 14 Dec 2018 16:32:22 -0500 Subject: [PATCH 33/42] Fix OK and close button symbols appearing in text area --- lv_objx/lv_kb.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lv_objx/lv_kb.c b/lv_objx/lv_kb.c index 7f1fb003c..d0e3cd5ac 100644 --- a/lv_objx/lv_kb.c +++ b/lv_objx/lv_kb.c @@ -430,6 +430,9 @@ static lv_res_t lv_kb_def_action(lv_obj_t * kb, const char * txt) if(res != LV_RES_OK) return res; /*The keyboard might be deleted in the actions*/ + /*If it's the OK or Close button do nothing */ + if((strcmp(txt, SYMBOL_OK) == 0) || (strcmp(txt, SYMBOL_CLOSE) == 0)) return LV_RES_OK; + /*Add the characters to the text area if set*/ if(ext->ta == NULL) return res; From 52ffa29ebe3985bedff16f6afdeed5ff7b4769b1 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Sat, 15 Dec 2018 00:11:28 +0100 Subject: [PATCH 34/42] lv_kb: bugfix update --- lv_objx/lv_kb.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lv_objx/lv_kb.c b/lv_objx/lv_kb.c index d0e3cd5ac..c90ab27ad 100644 --- a/lv_objx/lv_kb.c +++ b/lv_objx/lv_kb.c @@ -419,20 +419,18 @@ static lv_res_t lv_kb_def_action(lv_obj_t * kb, const char * txt) lv_kb_set_ta(kb, NULL); /*De-assign the text area to hide it cursor if needed*/ lv_obj_del(kb); } - return LV_RES_INV; + return res; } else if(strcmp(txt, SYMBOL_OK) == 0) { if(ext->ok_action) res = ext->ok_action(kb); else { lv_kb_set_ta(kb, NULL); /*De-assign the text area to hide it cursor if needed*/ res = lv_obj_del(kb); } + return res; } if(res != LV_RES_OK) return res; /*The keyboard might be deleted in the actions*/ - /*If it's the OK or Close button do nothing */ - if((strcmp(txt, SYMBOL_OK) == 0) || (strcmp(txt, SYMBOL_CLOSE) == 0)) return LV_RES_OK; - /*Add the characters to the text area if set*/ if(ext->ta == NULL) return res; From 37761540d00ac0b45bda62bf758b93d5c43b0703 Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Sat, 15 Dec 2018 21:26:14 -0500 Subject: [PATCH 35/42] Fix warning in lv_table.c --- lv_objx/lv_table.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lv_objx/lv_table.c b/lv_objx/lv_table.c index f997beb6c..e269779cf 100644 --- a/lv_objx/lv_table.c +++ b/lv_objx/lv_table.c @@ -495,6 +495,7 @@ static bool lv_table_design(lv_obj_t * table, const lv_area_t * mask, lv_design_ format.format_byte = ext->cell_data[cell][0]; switch(format.align) { + default: case LV_LABEL_ALIGN_LEFT: txt_flags = LV_TXT_FLAG_NONE; break; From ea224d409e211ff19286c6385691e13ae3c93155 Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Sat, 15 Dec 2018 21:44:44 -0500 Subject: [PATCH 36/42] Add lv_btnm_set_recolor/lv_btnm_get_recolor --- lv_objx/lv_btnm.c | 26 ++++++++++++++++++++++++-- lv_objx/lv_btnm.h | 15 +++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/lv_objx/lv_btnm.c b/lv_objx/lv_btnm.c index 73a96e39d..d2fd6e43d 100644 --- a/lv_objx/lv_btnm.c +++ b/lv_objx/lv_btnm.c @@ -314,6 +314,14 @@ void lv_btnm_set_style(lv_obj_t * btnm, lv_btnm_style_t type, lv_style_t * style } } +void lv_btnm_set_recolor(const lv_obj_t * btnm, bool en) +{ + lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm); + + ext->recolor = en; + lv_obj_invalidate(btnm); +} + /*===================== * Getter functions *====================*/ @@ -402,6 +410,13 @@ lv_style_t * lv_btnm_get_style(const lv_obj_t * btnm, lv_btnm_style_t type) return style; } +bool lv_btnm_get_recolor(const lv_obj_t * btnm) +{ + lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm); + + return ext->recolor; +} + /********************** * STATIC FUNCTIONS **********************/ @@ -424,6 +439,7 @@ static bool lv_btnm_design(lv_obj_t * btnm, const lv_area_t * mask, lv_design_mo } /*Draw the object*/ else if(mode == LV_DESIGN_DRAW_MAIN) { + ancestor_design_f(btnm, mask, mode); lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm); @@ -441,6 +457,12 @@ static bool lv_btnm_design(lv_obj_t * btnm, const lv_area_t * mask, lv_design_mo uint16_t btn_i = 0; uint16_t txt_i = 0; + + lv_txt_flag_t txt_flag = LV_TXT_FLAG_NONE; + + if(ext->recolor) + txt_flag = LV_TXT_FLAG_RECOLOR; + for(btn_i = 0; btn_i < ext->btn_cnt; btn_i ++, txt_i ++) { /*Search the next valid text in the map*/ while(strcmp(ext->map_p[txt_i], "\n") == 0) txt_i ++; @@ -486,7 +508,7 @@ static bool lv_btnm_design(lv_obj_t * btnm, const lv_area_t * mask, lv_design_mo lv_point_t txt_size; lv_txt_get_size(&txt_size, ext->map_p[txt_i], font, btn_style->text.letter_space, btn_style->text.line_space, - lv_area_get_width(&area_btnm), LV_TXT_FLAG_NONE); + lv_area_get_width(&area_btnm), txt_flag); area_tmp.x1 += (btn_w - txt_size.x) / 2; area_tmp.y1 += (btn_h - txt_size.y) / 2; @@ -494,7 +516,7 @@ static bool lv_btnm_design(lv_obj_t * btnm, const lv_area_t * mask, lv_design_mo area_tmp.y2 = area_tmp.y1 + txt_size.y; - lv_draw_label(&area_tmp, mask, btn_style, opa_scale, ext->map_p[txt_i], LV_TXT_FLAG_NONE, NULL); + lv_draw_label(&area_tmp, mask, btn_style, opa_scale, ext->map_p[txt_i], txt_flag, NULL); } } return true; diff --git a/lv_objx/lv_btnm.h b/lv_objx/lv_btnm.h index a1c7c2097..de334b753 100644 --- a/lv_objx/lv_btnm.h +++ b/lv_objx/lv_btnm.h @@ -62,6 +62,7 @@ typedef struct uint16_t btn_id_pr; /*Index of the currently pressed button (in `button_areas`) or LV_BTNM_PR_NONE*/ uint16_t btn_id_tgl; /*Index of the currently toggled button (in `button_areas`) or LV_BTNM_PR_NONE */ uint8_t toggle :1; /*Enable toggling*/ + uint8_t recolor :1; /*Enable button recoloring*/ } lv_btnm_ext_t; enum { @@ -129,6 +130,13 @@ void lv_btnm_set_toggle(lv_obj_t * btnm, bool en, uint16_t id); */ void lv_btnm_set_style(lv_obj_t *btnm, lv_btnm_style_t type, lv_style_t *style); +/** + * Set whether recoloring is enabled + * @param btnm pointer to button matrix object + * @param en whether recoloring is enabled + */ +void lv_btnm_set_recolor(const lv_obj_t * btnm, bool en); + /*===================== * Getter functions *====================*/ @@ -169,6 +177,13 @@ uint16_t lv_btnm_get_toggled(const lv_obj_t * btnm); */ lv_style_t * lv_btnm_get_style(const lv_obj_t *btnm, lv_btnm_style_t type); +/** + * Find whether recoloring is enabled + * @param btnm pointer to button matrix object + * @return whether recoloring is enabled + */ +bool lv_btnm_get_recolor(const lv_obj_t * btnm); + /********************** * MACROS **********************/ From 0fa3fecfe4f30bae0477bcaaa95494243ebe7c63 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Sun, 16 Dec 2018 08:43:35 -0500 Subject: [PATCH 37/42] Fix ifdef guards around lv_sw animation code --- lv_objx/lv_sw.c | 14 ++++---------- lv_objx/lv_sw.h | 2 -- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/lv_objx/lv_sw.c b/lv_objx/lv_sw.c index cf88801f7..e39838795 100644 --- a/lv_objx/lv_sw.c +++ b/lv_objx/lv_sw.c @@ -154,11 +154,8 @@ void lv_sw_off(lv_obj_t * sw) void lv_sw_on_anim(lv_obj_t * sw) { lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); -#if USE_LV_ANIMATION if(lv_sw_get_anim_time(sw) > 0)lv_sw_anim_to_value(sw, LV_SWITCH_SLIDER_ANIM_MAX); - else -#endif - lv_slider_set_value(sw, LV_SWITCH_SLIDER_ANIM_MAX); + else lv_slider_set_value(sw, LV_SWITCH_SLIDER_ANIM_MAX); lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_on); } @@ -170,11 +167,8 @@ void lv_sw_on_anim(lv_obj_t * sw) void lv_sw_off_anim(lv_obj_t * sw) { lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); -#if USE_LV_ANIMATION if(lv_sw_get_anim_time(sw) > 0) lv_sw_anim_to_value(sw, 0); - else -#endif - lv_slider_set_value(sw, 0); + else lv_slider_set_value(sw, 0); lv_slider_set_style(sw, LV_SLIDER_STYLE_KNOB, ext->style_knob_off); } @@ -393,9 +387,9 @@ static lv_res_t lv_sw_signal(lv_obj_t * sw, lv_signal_t sign, void * param) return res; } -#if USE_LV_ANIMATION static void lv_sw_anim_to_value(lv_obj_t * sw, int16_t value) { +#if USE_LV_ANIMATION lv_anim_t a; lv_sw_ext_t * ext = lv_obj_get_ext_attr(sw); a.var = sw; @@ -411,7 +405,7 @@ static void lv_sw_anim_to_value(lv_obj_t * sw, int16_t value) a.repeat = 0; a.repeat_pause = 0; lv_anim_create(&a); -} #endif +} #endif diff --git a/lv_objx/lv_sw.h b/lv_objx/lv_sw.h index 1eee3a50e..9ab27144f 100644 --- a/lv_objx/lv_sw.h +++ b/lv_objx/lv_sw.h @@ -160,14 +160,12 @@ static inline lv_action_t lv_sw_get_action(const lv_obj_t * slider) */ lv_style_t * lv_sw_get_style(const lv_obj_t *sw, lv_sw_style_t type); -#if USE_LV_ANIMATION /** * Get the animation time of the switch * @param sw pointer to a switch object * @return style pointer to a style */ uint16_t lv_sw_get_anim_time(const lv_obj_t *sw); -#endif /********************** * MACROS From 35901db2cdb1fe355fcfe48819c98b1d076679ee Mon Sep 17 00:00:00 2001 From: Themba Dube Date: Sun, 16 Dec 2018 09:33:10 -0500 Subject: [PATCH 38/42] Add mbox recoloring support --- lv_objx/lv_mbox.c | 27 +++++++++++++++++++++++++++ lv_objx/lv_mbox.h | 14 ++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/lv_objx/lv_mbox.c b/lv_objx/lv_mbox.c index 63d17e912..54bf7c2d2 100644 --- a/lv_objx/lv_mbox.c +++ b/lv_objx/lv_mbox.c @@ -280,6 +280,18 @@ void lv_mbox_set_style(lv_obj_t * mbox, lv_mbox_style_t type, lv_style_t * style } +/** + * Set whether recoloring is enabled + * @param btnm pointer to button matrix object + * @param en whether recoloring is enabled + */ +void lv_mbox_set_recolor(lv_obj_t * mbox, bool en) +{ + lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox); + + if(ext->btnm) + lv_btnm_set_recolor(ext->btnm, en); +} /*===================== * Getter functions @@ -362,6 +374,21 @@ lv_style_t * lv_mbox_get_style(const lv_obj_t * mbox, lv_mbox_style_t type) return style; } +/** + * Get whether recoloring is enabled + * @param btnm pointer to button matrix object + * @return whether recoloring is enabled + */ +bool lv_mbox_get_recolor(const lv_obj_t * mbox) +{ + lv_mbox_ext_t * ext = lv_obj_get_ext_attr(mbox); + + if(!ext->btnm) + return false; + + return lv_btnm_get_recolor(ext->btnm); +} + /********************** * STATIC FUNCTIONS diff --git a/lv_objx/lv_mbox.h b/lv_objx/lv_mbox.h index 9ca39b656..9a25a76e3 100644 --- a/lv_objx/lv_mbox.h +++ b/lv_objx/lv_mbox.h @@ -140,6 +140,13 @@ void lv_mbox_stop_auto_close(lv_obj_t * mbox); */ void lv_mbox_set_style(lv_obj_t *mbox, lv_mbox_style_t type, lv_style_t *style); +/** + * Set whether recoloring is enabled. Must be called after `lv_mbox_add_btns`. + * @param btnm pointer to button matrix object + * @param en whether recoloring is enabled + */ +void lv_mbox_set_recolor(lv_obj_t * mbox, bool en); + /*===================== * Getter functions *====================*/ @@ -175,6 +182,13 @@ uint16_t lv_mbox_get_anim_time(const lv_obj_t * mbox); */ lv_style_t * lv_mbox_get_style(const lv_obj_t *mbox, lv_mbox_style_t type); +/** + * Get whether recoloring is enabled + * @param btnm pointer to button matrix object + * @return whether recoloring is enabled + */ +bool lv_mbox_get_recolor(const lv_obj_t * mbox); + /********************** * MACROS **********************/ From 60c07120c7c3a4f21b2881bf9815e8acaa446024 Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Mon, 17 Dec 2018 14:33:29 +0100 Subject: [PATCH 39/42] lv_draw_label: optimization for long texts --- lv_draw/lv_draw_label.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lv_draw/lv_draw_label.c b/lv_draw/lv_draw_label.c index d6235e7d4..134323abc 100644 --- a/lv_draw/lv_draw_label.c +++ b/lv_draw/lv_draw_label.c @@ -115,6 +115,8 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st lv_rletter_set_background(style->body.main_color); #endif + lv_coord_t line_height = lv_font_get_height(font) + style->text.line_space; + /*Write out all lines*/ while(txt[line_start] != '\0') { if(offset != NULL) { @@ -126,6 +128,9 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st uint32_t letter; while(i < line_end) { letter = lv_txt_encoded_next(txt, &i); + +// if(pos.y + line_height < mask->y1) continue; + /*Handle the re-color command*/ if((flag & LV_TXT_FLAG_RECOLOR) != 0) { if(letter == (uint32_t)LV_TXT_COLOR_CMD[0]) { @@ -193,8 +198,9 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st } /*Go the next line position*/ - pos.y += lv_font_get_height(font); - pos.y += style->text.line_space; + pos.y += line_height; + +// if(pos.y > mask->y2) return; } } From 93781909bb799e4fbaeec298fb71659b9984324a Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Mon, 17 Dec 2018 14:34:26 +0100 Subject: [PATCH 40/42] lv_draw_label: optimization for long texts (uncomment some lines) --- lv_draw/lv_draw_label.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lv_draw/lv_draw_label.c b/lv_draw/lv_draw_label.c index 134323abc..d8b0c0e29 100644 --- a/lv_draw/lv_draw_label.c +++ b/lv_draw/lv_draw_label.c @@ -129,7 +129,7 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st while(i < line_end) { letter = lv_txt_encoded_next(txt, &i); -// if(pos.y + line_height < mask->y1) continue; + if(pos.y + line_height < mask->y1) continue; /*Handle the re-color command*/ if((flag & LV_TXT_FLAG_RECOLOR) != 0) { @@ -200,7 +200,7 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st /*Go the next line position*/ pos.y += line_height; -// if(pos.y > mask->y2) return; + if(pos.y > mask->y2) return; } } From e6c4845983250282a94e29c1fddfa0e609d4d67b Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 18 Dec 2018 07:25:34 +0100 Subject: [PATCH 41/42] lv_label: remove space from LV_LABEL_LONG_ROLL/SCROLL anims --- lv_objx/lv_label.c | 8 ++++---- lv_objx/lv_list.c | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/lv_objx/lv_label.c b/lv_objx/lv_label.c index 37af54bf2..0fddfea36 100644 --- a/lv_objx/lv_label.c +++ b/lv_objx/lv_label.c @@ -787,7 +787,7 @@ static void lv_label_refr_text(lv_obj_t * label) anim.var = label; anim.repeat = 1; anim.playback = 1; - anim.start = lv_font_get_width(font, ' '); + anim.start = 0; anim.act_time = 0; anim.end_cb = NULL; anim.path = lv_anim_path_linear; @@ -797,7 +797,7 @@ static void lv_label_refr_text(lv_obj_t * label) anim.repeat_pause = anim.playback_pause; if(lv_obj_get_width(label) > lv_obj_get_width(parent)) { - anim.end = lv_obj_get_width(parent) - lv_obj_get_width(label) - lv_font_get_width(font, ' '); + anim.end = lv_obj_get_width(parent) - lv_obj_get_width(label); anim.fp = (lv_anim_fp_t) lv_obj_set_x; anim.time = lv_anim_speed_to_time(ext->anim_speed, anim.start, anim.end); lv_anim_create(&anim); @@ -817,7 +817,7 @@ static void lv_label_refr_text(lv_obj_t * label) anim.var = label; anim.repeat = 1; anim.playback = 1; - anim.start = lv_font_get_width(font, ' '); + anim.start = 0; anim.act_time = 0; anim.end_cb = NULL; anim.path = lv_anim_path_linear; @@ -826,7 +826,7 @@ static void lv_label_refr_text(lv_obj_t * label) bool hor_anim = false; if(size.x > lv_obj_get_width(label)) { - anim.end = lv_obj_get_width(label) - size.x - lv_font_get_width(font, ' '); + anim.end = lv_obj_get_width(label) - size.x; anim.fp = (lv_anim_fp_t) lv_label_set_offset_x; anim.time = lv_anim_speed_to_time(ext->anim_speed, anim.start, anim.end); lv_anim_create(&anim); diff --git a/lv_objx/lv_list.c b/lv_objx/lv_list.c index 7f367af17..1612c8c59 100644 --- a/lv_objx/lv_list.c +++ b/lv_objx/lv_list.c @@ -220,11 +220,12 @@ lv_obj_t * lv_list_add(lv_obj_t * list, const void * img_src, const char * txt, } #endif if(txt != NULL) { + lv_coord_t btn_hor_pad = ext->styles_btn[LV_BTN_STYLE_REL]->body.padding.hor; lv_obj_t * label = lv_label_create(liste, NULL); lv_label_set_text(label, txt); lv_obj_set_click(label, false); lv_label_set_long_mode(label, LV_LABEL_LONG_ROLL); - lv_obj_set_width(label, liste->coords.x2 - label->coords.x1); + lv_obj_set_width(label, liste->coords.x2 - label->coords.x1 - btn_hor_pad); if(label_signal == NULL) label_signal = lv_obj_get_signal_func(label); } From 61caef8e9475928189b823c69ee2640f2ff8718e Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 18 Dec 2018 07:33:55 +0100 Subject: [PATCH 42/42] lv_indev_set_cursor: don't enable cursor for LV_INDEV_TYPE_BUTTON --- lv_core/lv_indev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lv_core/lv_indev.c b/lv_core/lv_indev.c index 1955dea44..0972e36c6 100644 --- a/lv_core/lv_indev.c +++ b/lv_core/lv_indev.c @@ -136,7 +136,7 @@ void lv_indev_enable(lv_hal_indev_type_t type, bool enable) */ void lv_indev_set_cursor(lv_indev_t * indev, lv_obj_t * cur_obj) { - if(indev->driver.type != LV_INDEV_TYPE_POINTER && indev->driver.type != LV_INDEV_TYPE_BUTTON) return; + if(indev->driver.type != LV_INDEV_TYPE_POINTER) return; indev->cursor = cur_obj; lv_obj_set_parent(indev->cursor, lv_layer_sys());