diff --git a/lv_conf_templ.h b/lv_conf_templ.h index afb941080f..bd55d94275 100644 --- a/lv_conf_templ.h +++ b/lv_conf_templ.h @@ -121,6 +121,7 @@ #define USE_LV_GPU 1 /*1: Enable GPU interface*/ #define USE_LV_REAL_DRAW 1 /*1: Enable function which draw directly to the frame buffer instead of VDB (required if LV_VDB_SIZE = 0)*/ #define USE_LV_FILESYSTEM 1 /*1: Enable file system (might be required for images*/ +#define USE_LV_MULTI_LANG 0 /* Number of languages for labels to store (0: to disable this feature)*/ /*Compiler settings*/ #define LV_ATTRIBUTE_TICK_INC /* Define a custom attribute to `lv_tick_inc` function */ diff --git a/lv_core/lv_obj.c b/lv_core/lv_obj.c index 3d4661bf01..6b858f3178 100644 --- a/lv_core/lv_obj.c +++ b/lv_core/lv_obj.c @@ -35,6 +35,7 @@ **********************/ static void refresh_childen_position(lv_obj_t * obj, lv_coord_t x_diff, lv_coord_t y_diff); static void report_style_mod_core(void * style_p, lv_obj_t * obj); +static void lang_set_core(lv_obj_t * obj); static void refresh_childen_style(lv_obj_t * obj); static void delete_children(lv_obj_t * obj); static bool lv_obj_design(lv_obj_t * obj, const lv_area_t * mask_p, lv_design_mode_t mode); @@ -48,6 +49,9 @@ static lv_obj_t * act_scr = NULL; static lv_obj_t * top_layer = NULL; static lv_obj_t * sys_layer = NULL; static lv_ll_t scr_ll; /*Linked list of screens*/ +#if USE_LV_MULTI_LANG +static uint8_t lang_act = 0; +#endif /********************** * MACROS @@ -456,6 +460,33 @@ void lv_scr_load(lv_obj_t * scr) lv_obj_invalidate(act_scr); } +/*-------------- + * Language + *--------------*/ + +/** + * Change the language + * @param lang_id the id of the + */ +void lv_lang_set(uint8_t lang_id) +{ +#if USE_LV_MULTI_LANG + lang_act = lang_id; + + lv_obj_t * i; + LL_READ(scr_ll, i) { + i->signal_func(i, LV_SIGNAL_LANG_CHG, NULL); + + lang_set_core(i); + } +#else + LV_LOG_WARN("lv_lang_act: multiple languages are not enabled. See lv_conf.h USE_LV_MULTI_LANG ") + return 0; +#endif + + +} + /*-------------------- * Parent/children set *--------------------*/ @@ -1287,6 +1318,24 @@ void lv_obj_animate(lv_obj_t * obj, lv_anim_builtin_t type, uint16_t time, uint1 * Getter functions *======================*/ +/*-------------- + * Language + *--------------*/ + +/** + * Return with ID of the currently selected language + * @return pointer to the active screen object (loaded by 'lv_scr_load()') + */ +lv_obj_t * lv_lang_act(void) +{ +#if USE_LV_MULTI_LANG + return lang_act; +#else + LV_LOG_WARN("lv_lang_act: multiple languages are not enabled. See lv_conf.h USE_LV_MULTI_LANG ") + return 0; +#endif +} + /*------------------ * Screen get *-----------------*/ @@ -1891,6 +1940,20 @@ static void report_style_mod_core(void * style_p, lv_obj_t * obj) } +/** + * Change the language of the children. (Called recursively) + * @param obj pointer to an object + */ +static void lang_set_core(lv_obj_t * obj) +{ + lv_obj_t * i; + LL_READ(obj->child_ll, i) { + i->signal_func(i, LV_SIGNAL_LANG_CHG, NULL); + + lang_set_core(i); + } +} + /** * Recursively refresh the style of the children. Go deeper until a not NULL style is found * because the NULL styles are inherited from the parent diff --git a/lv_core/lv_obj.h b/lv_core/lv_obj.h index 1c2f322e4f..b36fc1f386 100644 --- a/lv_core/lv_obj.h +++ b/lv_core/lv_obj.h @@ -90,6 +90,7 @@ enum LV_SIGNAL_CORD_CHG, LV_SIGNAL_STYLE_CHG, LV_SIGNAL_REFR_EXT_SIZE, + LV_SIGNAL_LANG_CHG, LV_SIGNAL_GET_TYPE, _LV_SIGNAL_FEEDBACK_SECTION_START, @@ -550,6 +551,16 @@ void lv_obj_animate(lv_obj_t * obj, lv_anim_builtin_t type, uint16_t time, uint1 * Getter functions *======================*/ +/*-------------- + * Language + *--------------*/ + +/** + * Return with ID of the currently selected language + * @return pointer to the active screen object (loaded by 'lv_scr_load()') + */ +lv_obj_t * lv_lang_act(void); + /*------------------ * Screen get *-----------------*/ diff --git a/lv_objx/lv_label.c b/lv_objx/lv_label.c index 269acf57c5..f892963c63 100644 --- a/lv_objx/lv_label.c +++ b/lv_objx/lv_label.c @@ -175,6 +175,7 @@ void lv_label_set_text(lv_obj_t * label, const char * text) lv_label_refr_text(label); } + /** * Set a new text for a label from a character array. The array don't has to be '\0' terminated. * Memory will be allocated to store the array by the label. @@ -232,6 +233,27 @@ void lv_label_set_static_text(lv_obj_t * label, const char * text) lv_label_refr_text(label); } +/** + * Set the text for the multiple languages + * @param label pointer to a label object + * @param texts '\0' terminated character strings like `const char * txts[] = {"dog", "hund"}`. + * The number of elements must be `USE_LV_MULTI_LANG`. + * Only the pointer is saved so the variable must be global, static, or dynamically allocated. + * NULL to disable multiple language for the label. + */ +void lv_label_set_text_multi(lv_obj_t * label, const char ** texts) +{ +#if USE_LV_MULTI_LANG + lv_label_ext_t * ext = lv_obj_get_ext_attr(label); + ext->multi_lang_texts = texts; + + /*Apply the new language*/ + label->signal_func(label, LV_SIGNAL_LANG_CHG, NULL); +#else + LV_LOG_WARN("lv_label_set_text_multi: multiple languages are not enabled. See lv_conf.h USE_LV_MULTI_LANG ") +#endif +} + /** * Set the behavior of the label with longer text then the object size * @param label pointer to a label object @@ -277,7 +299,6 @@ void lv_label_set_align(lv_obj_t * label, lv_label_align_t align) ext->align = align; lv_obj_invalidate(label); /*Enough to invalidate because alignment is only drawing related (lv_refr_label_text() not required)*/ - } /** @@ -345,6 +366,22 @@ char * lv_label_get_text(const lv_obj_t * label) return ext->text; } +/** + * Get the array which stores the texts for multiple languages + * @param label pointer to a label object + * @return pointer to the array storing the texts. NULL if not specified. + */ +const char ** lv_label_get_text_multi(lv_obj_t * label) +{ +#if USE_LV_MULTI_LANG + lv_label_ext_t * ext = lv_obj_get_ext_attr(label); + return ext->multi_lang_texts; +#else + LV_LOG_WARN("lv_label_get_text_multi: multiple languages are not enabled. See lv_conf.h USE_LV_MULTI_LANG ") + return NULL; +#endif + +} /** * Get the long mode of a label * @param label pointer to a label object @@ -720,6 +757,12 @@ static lv_res_t lv_label_signal(lv_obj_t * label, lv_signal_t sign, void * param label->ext_size = LV_MATH_MAX(label->ext_size, style->body.padding.hor); label->ext_size = LV_MATH_MAX(label->ext_size, style->body.padding.ver); } + } else if(sign == LV_SIGNAL_LANG_CHG) { + if(ext->multi_lang_texts) { + uint8_t lang = lv_lang_act(); + lv_label_set_text(label, ext->multi_lang_texts[lang]); + } + } else if(sign == LV_SIGNAL_GET_TYPE) { lv_obj_type_t * buf = param; uint8_t i; diff --git a/lv_objx/lv_label.h b/lv_objx/lv_label.h index b3b9575e2b..1ae52fbb7d 100644 --- a/lv_objx/lv_label.h +++ b/lv_objx/lv_label.h @@ -61,16 +61,20 @@ typedef struct { /*Inherited from 'base_obj' so no inherited ext.*/ /*Ext. of ancestor*/ /*New data for this type */ - char * text; /*Text of the label*/ - lv_label_long_mode_t long_mode; /*Determinate what to do with the long texts*/ + char * text; /*Text of the label*/ + lv_label_long_mode_t long_mode; /*Determinate what to do with the long texts*/ #if LV_TXT_UTF8 == 0 - char dot_tmp[LV_LABEL_DOT_NUM + 1]; /*Store the character which are replaced by dots (Handled by the library)*/ + char dot_tmp[LV_LABEL_DOT_NUM + 1]; /*Store the character which are replaced by dots (Handled by the library)*/ #else char dot_tmp[LV_LABEL_DOT_NUM * 4 + 1]; /*Store the character which are replaced by dots (Handled by the library)*/ #endif + +#if USE_LV_MULTI_LANG > 0 + const char ** multi_lang_texts; /*Store multiple languages statically (only the pointer is saved)*/ +#endif uint16_t dot_end; /*The text end position in dot mode (Handled by the library)*/ uint16_t anim_speed; /*Speed of scroll and roll animation in px/sec unit*/ - lv_point_t offset; /*Text draw position offset*/ + lv_point_t offset; /*Text draw position offset*/ uint8_t static_txt :1; /*Flag to indicate the text is static*/ uint8_t align :2; /*Align type from 'lv_label_align_t'*/ uint8_t recolor :1; /*Enable in-line letter re-coloring*/ @@ -119,6 +123,17 @@ void lv_label_set_array_text(lv_obj_t * label, const char * array, uint16_t size */ void lv_label_set_static_text(lv_obj_t * label, const char * text); + +/** + * Set the text for the multiple languages + * @param label pointer to a label object + * @param texts '\0' terminated character strings like `const char * txts[] = {"dog", "hund"}`. + * The number of elements must be `USE_LV_MULTI_LANG`. + * Only the pointer is saved so the variable must be global, static, or dynamically allocated. + * NULL to disable multiple language for the label. + */ +void lv_label_set_text_multi(lv_obj_t * label, const char ** texts); + /** * Set the behavior of the label with longer text then the object size * @param label pointer to a label object @@ -175,6 +190,13 @@ static inline void lv_label_set_style(lv_obj_t *label, lv_style_t *style) */ char * lv_label_get_text(const lv_obj_t * label); +/** + * Get the array which stores the texts for multiple languages + * @param label pointer to a label object + * @return pointer to the array storing the texts. NULL if not specified. + */ +const char ** lv_label_get_text_multi(lv_obj_t * label); + /** * Get the long mode of a label * @param label pointer to a label object