char input
Dependencies: TS_DISCO_F746NG mbed LCD_DISCO_F746NG BSP_DISCO_F746NG lvgl_RB FastPWM millis
lv_i18n.c@1:404ee28a0b60, 2020-01-17 (annotated)
- Committer:
- kisvegabor
- Date:
- Fri Jan 17 06:03:24 2020 +0000
- Revision:
- 1:404ee28a0b60
- Child:
- 4:6a3d12663549
Gabor added comments
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kisvegabor | 1:404ee28a0b60 | 1 | #include "./lv_i18n.h" |
kisvegabor | 1:404ee28a0b60 | 2 | |
kisvegabor | 1:404ee28a0b60 | 3 | |
kisvegabor | 1:404ee28a0b60 | 4 | //////////////////////////////////////////////////////////////////////////////// |
kisvegabor | 1:404ee28a0b60 | 5 | // Define plural operands |
kisvegabor | 1:404ee28a0b60 | 6 | // http://unicode.org/reports/tr35/tr35-numbers.html#Operands |
kisvegabor | 1:404ee28a0b60 | 7 | |
kisvegabor | 1:404ee28a0b60 | 8 | // Integer version, simplified |
kisvegabor | 1:404ee28a0b60 | 9 | |
kisvegabor | 1:404ee28a0b60 | 10 | #define UNUSED(x) (void)(x) |
kisvegabor | 1:404ee28a0b60 | 11 | |
kisvegabor | 1:404ee28a0b60 | 12 | static lv_i18n_phrase_t en_gb_texts[] = { |
kisvegabor | 1:404ee28a0b60 | 13 | {"dog", "This is a dog"}, |
kisvegabor | 1:404ee28a0b60 | 14 | {"cat", "This is a cat"}, |
kisvegabor | 1:404ee28a0b60 | 15 | {NULL, NULL} // End mark |
kisvegabor | 1:404ee28a0b60 | 16 | }; |
kisvegabor | 1:404ee28a0b60 | 17 | |
kisvegabor | 1:404ee28a0b60 | 18 | |
kisvegabor | 1:404ee28a0b60 | 19 | static const lv_i18n_lang_t en_gb_lang = { |
kisvegabor | 1:404ee28a0b60 | 20 | .locale_name = "en-GB", |
kisvegabor | 1:404ee28a0b60 | 21 | .singulars = en_gb_texts, |
kisvegabor | 1:404ee28a0b60 | 22 | }; |
kisvegabor | 1:404ee28a0b60 | 23 | |
kisvegabor | 1:404ee28a0b60 | 24 | static lv_i18n_phrase_t fr_texts[] = { |
kisvegabor | 1:404ee28a0b60 | 25 | {"dog", "c'est un chien"}, |
kisvegabor | 1:404ee28a0b60 | 26 | {"cat", "Ceci est un chat"}, |
kisvegabor | 1:404ee28a0b60 | 27 | {NULL, NULL} // End mark |
kisvegabor | 1:404ee28a0b60 | 28 | }; |
kisvegabor | 1:404ee28a0b60 | 29 | |
kisvegabor | 1:404ee28a0b60 | 30 | static const lv_i18n_lang_t fr_lang = { |
kisvegabor | 1:404ee28a0b60 | 31 | .locale_name = "fr", |
kisvegabor | 1:404ee28a0b60 | 32 | .singulars = fr_texts, |
kisvegabor | 1:404ee28a0b60 | 33 | }; |
kisvegabor | 1:404ee28a0b60 | 34 | |
kisvegabor | 1:404ee28a0b60 | 35 | const lv_i18n_language_pack_t lv_i18n_language_pack[] = { |
kisvegabor | 1:404ee28a0b60 | 36 | &en_gb_lang, |
kisvegabor | 1:404ee28a0b60 | 37 | &fr_lang, |
kisvegabor | 1:404ee28a0b60 | 38 | NULL // End mark |
kisvegabor | 1:404ee28a0b60 | 39 | }; |
kisvegabor | 1:404ee28a0b60 | 40 | |
kisvegabor | 1:404ee28a0b60 | 41 | //////////////////////////////////////////////////////////////////////////////// |
kisvegabor | 1:404ee28a0b60 | 42 | |
kisvegabor | 1:404ee28a0b60 | 43 | |
kisvegabor | 1:404ee28a0b60 | 44 | // Internal state |
kisvegabor | 1:404ee28a0b60 | 45 | static const lv_i18n_language_pack_t * current_lang_pack; |
kisvegabor | 1:404ee28a0b60 | 46 | static const lv_i18n_lang_t * current_lang; |
kisvegabor | 1:404ee28a0b60 | 47 | |
kisvegabor | 1:404ee28a0b60 | 48 | |
kisvegabor | 1:404ee28a0b60 | 49 | /** |
kisvegabor | 1:404ee28a0b60 | 50 | * Reset internal state. For testing. |
kisvegabor | 1:404ee28a0b60 | 51 | */ |
kisvegabor | 1:404ee28a0b60 | 52 | void __lv_i18n_reset(void) |
kisvegabor | 1:404ee28a0b60 | 53 | { |
kisvegabor | 1:404ee28a0b60 | 54 | current_lang_pack = NULL; |
kisvegabor | 1:404ee28a0b60 | 55 | current_lang = NULL; |
kisvegabor | 1:404ee28a0b60 | 56 | } |
kisvegabor | 1:404ee28a0b60 | 57 | |
kisvegabor | 1:404ee28a0b60 | 58 | /** |
kisvegabor | 1:404ee28a0b60 | 59 | * Set the languages for internationalization |
kisvegabor | 1:404ee28a0b60 | 60 | * @param langs pointer to the array of languages. (Last element has to be `NULL`) |
kisvegabor | 1:404ee28a0b60 | 61 | */ |
kisvegabor | 1:404ee28a0b60 | 62 | int lv_i18n_init(const lv_i18n_language_pack_t * langs) |
kisvegabor | 1:404ee28a0b60 | 63 | { |
kisvegabor | 1:404ee28a0b60 | 64 | if(langs == NULL) return -1; |
kisvegabor | 1:404ee28a0b60 | 65 | if(langs[0] == NULL) return -1; |
kisvegabor | 1:404ee28a0b60 | 66 | |
kisvegabor | 1:404ee28a0b60 | 67 | current_lang_pack = langs; |
kisvegabor | 1:404ee28a0b60 | 68 | current_lang = langs[0]; /*Automatically select the first language*/ |
kisvegabor | 1:404ee28a0b60 | 69 | return 0; |
kisvegabor | 1:404ee28a0b60 | 70 | } |
kisvegabor | 1:404ee28a0b60 | 71 | |
kisvegabor | 1:404ee28a0b60 | 72 | /** |
kisvegabor | 1:404ee28a0b60 | 73 | * Change the localization (language) |
kisvegabor | 1:404ee28a0b60 | 74 | * @param l_name name of the translation locale to use. E.g. "en-GB" |
kisvegabor | 1:404ee28a0b60 | 75 | */ |
kisvegabor | 1:404ee28a0b60 | 76 | int lv_i18n_set_locale(const char * l_name) |
kisvegabor | 1:404ee28a0b60 | 77 | { |
kisvegabor | 1:404ee28a0b60 | 78 | if(current_lang_pack == NULL) return -1; |
kisvegabor | 1:404ee28a0b60 | 79 | |
kisvegabor | 1:404ee28a0b60 | 80 | uint16_t i; |
kisvegabor | 1:404ee28a0b60 | 81 | |
kisvegabor | 1:404ee28a0b60 | 82 | for(i = 0; current_lang_pack[i] != NULL; i++) { |
kisvegabor | 1:404ee28a0b60 | 83 | // Found -> finish |
kisvegabor | 1:404ee28a0b60 | 84 | if(strcmp(current_lang_pack[i]->locale_name, l_name) == 0) { |
kisvegabor | 1:404ee28a0b60 | 85 | current_lang = current_lang_pack[i]; |
kisvegabor | 1:404ee28a0b60 | 86 | return 0; |
kisvegabor | 1:404ee28a0b60 | 87 | } |
kisvegabor | 1:404ee28a0b60 | 88 | } |
kisvegabor | 1:404ee28a0b60 | 89 | |
kisvegabor | 1:404ee28a0b60 | 90 | return -1; |
kisvegabor | 1:404ee28a0b60 | 91 | } |
kisvegabor | 1:404ee28a0b60 | 92 | |
kisvegabor | 1:404ee28a0b60 | 93 | |
kisvegabor | 1:404ee28a0b60 | 94 | static const char * __lv_i18n_get_text_core(lv_i18n_phrase_t * trans, const char * msg_id) |
kisvegabor | 1:404ee28a0b60 | 95 | { |
kisvegabor | 1:404ee28a0b60 | 96 | uint16_t i; |
kisvegabor | 1:404ee28a0b60 | 97 | for(i = 0; trans[i].msg_id != NULL; i++) { |
kisvegabor | 1:404ee28a0b60 | 98 | if(strcmp(trans[i].msg_id, msg_id) == 0) { |
kisvegabor | 1:404ee28a0b60 | 99 | /*The msg_id has found. Check the translation*/ |
kisvegabor | 1:404ee28a0b60 | 100 | if(trans[i].translation) return trans[i].translation; |
kisvegabor | 1:404ee28a0b60 | 101 | } |
kisvegabor | 1:404ee28a0b60 | 102 | } |
kisvegabor | 1:404ee28a0b60 | 103 | |
kisvegabor | 1:404ee28a0b60 | 104 | return NULL; |
kisvegabor | 1:404ee28a0b60 | 105 | } |
kisvegabor | 1:404ee28a0b60 | 106 | |
kisvegabor | 1:404ee28a0b60 | 107 | |
kisvegabor | 1:404ee28a0b60 | 108 | /** |
kisvegabor | 1:404ee28a0b60 | 109 | * Get the translation from a message ID |
kisvegabor | 1:404ee28a0b60 | 110 | * @param msg_id message ID |
kisvegabor | 1:404ee28a0b60 | 111 | * @return the translation of `msg_id` on the set local |
kisvegabor | 1:404ee28a0b60 | 112 | */ |
kisvegabor | 1:404ee28a0b60 | 113 | const char * lv_i18n_get_text(const char * msg_id) |
kisvegabor | 1:404ee28a0b60 | 114 | { |
kisvegabor | 1:404ee28a0b60 | 115 | if(current_lang == NULL) return msg_id; |
kisvegabor | 1:404ee28a0b60 | 116 | |
kisvegabor | 1:404ee28a0b60 | 117 | const lv_i18n_lang_t * lang = current_lang; |
kisvegabor | 1:404ee28a0b60 | 118 | const void * txt; |
kisvegabor | 1:404ee28a0b60 | 119 | |
kisvegabor | 1:404ee28a0b60 | 120 | // Search in current locale |
kisvegabor | 1:404ee28a0b60 | 121 | if(lang->singulars != NULL) { |
kisvegabor | 1:404ee28a0b60 | 122 | txt = __lv_i18n_get_text_core(lang->singulars, msg_id); |
kisvegabor | 1:404ee28a0b60 | 123 | if (txt != NULL) return txt; |
kisvegabor | 1:404ee28a0b60 | 124 | } |
kisvegabor | 1:404ee28a0b60 | 125 | |
kisvegabor | 1:404ee28a0b60 | 126 | // Try to fallback |
kisvegabor | 1:404ee28a0b60 | 127 | if(lang == current_lang_pack[0]) return msg_id; |
kisvegabor | 1:404ee28a0b60 | 128 | lang = current_lang_pack[0]; |
kisvegabor | 1:404ee28a0b60 | 129 | |
kisvegabor | 1:404ee28a0b60 | 130 | // Repeat search for default locale |
kisvegabor | 1:404ee28a0b60 | 131 | if(lang->singulars != NULL) { |
kisvegabor | 1:404ee28a0b60 | 132 | txt = __lv_i18n_get_text_core(lang->singulars, msg_id); |
kisvegabor | 1:404ee28a0b60 | 133 | if (txt != NULL) return txt; |
kisvegabor | 1:404ee28a0b60 | 134 | } |
kisvegabor | 1:404ee28a0b60 | 135 | |
kisvegabor | 1:404ee28a0b60 | 136 | return msg_id; |
kisvegabor | 1:404ee28a0b60 | 137 | } |
kisvegabor | 1:404ee28a0b60 | 138 | |
kisvegabor | 1:404ee28a0b60 | 139 | /** |
kisvegabor | 1:404ee28a0b60 | 140 | * Get the translation from a message ID and apply the language's plural rule to get correct form |
kisvegabor | 1:404ee28a0b60 | 141 | * @param msg_id message ID |
kisvegabor | 1:404ee28a0b60 | 142 | * @param num an integer to select the correct plural form |
kisvegabor | 1:404ee28a0b60 | 143 | * @return the translation of `msg_id` on the set local |
kisvegabor | 1:404ee28a0b60 | 144 | */ |
kisvegabor | 1:404ee28a0b60 | 145 | const char * lv_i18n_get_text_plural(const char * msg_id, int32_t num) |
kisvegabor | 1:404ee28a0b60 | 146 | { |
kisvegabor | 1:404ee28a0b60 | 147 | if(current_lang == NULL) return msg_id; |
kisvegabor | 1:404ee28a0b60 | 148 | |
kisvegabor | 1:404ee28a0b60 | 149 | const lv_i18n_lang_t * lang = current_lang; |
kisvegabor | 1:404ee28a0b60 | 150 | const void * txt; |
kisvegabor | 1:404ee28a0b60 | 151 | lv_i18n_plural_type_t ptype; |
kisvegabor | 1:404ee28a0b60 | 152 | |
kisvegabor | 1:404ee28a0b60 | 153 | // Search in current locale |
kisvegabor | 1:404ee28a0b60 | 154 | if(lang->locale_plural_fn != NULL) { |
kisvegabor | 1:404ee28a0b60 | 155 | ptype = lang->locale_plural_fn(num); |
kisvegabor | 1:404ee28a0b60 | 156 | |
kisvegabor | 1:404ee28a0b60 | 157 | if(lang->plurals[ptype] != NULL) { |
kisvegabor | 1:404ee28a0b60 | 158 | txt = __lv_i18n_get_text_core(lang->plurals[ptype], msg_id); |
kisvegabor | 1:404ee28a0b60 | 159 | if (txt != NULL) return txt; |
kisvegabor | 1:404ee28a0b60 | 160 | } |
kisvegabor | 1:404ee28a0b60 | 161 | } |
kisvegabor | 1:404ee28a0b60 | 162 | |
kisvegabor | 1:404ee28a0b60 | 163 | // Try to fallback |
kisvegabor | 1:404ee28a0b60 | 164 | if(lang == current_lang_pack[0]) return msg_id; |
kisvegabor | 1:404ee28a0b60 | 165 | lang = current_lang_pack[0]; |
kisvegabor | 1:404ee28a0b60 | 166 | |
kisvegabor | 1:404ee28a0b60 | 167 | // Repeat search for default locale |
kisvegabor | 1:404ee28a0b60 | 168 | if(lang->locale_plural_fn != NULL) { |
kisvegabor | 1:404ee28a0b60 | 169 | ptype = lang->locale_plural_fn(num); |
kisvegabor | 1:404ee28a0b60 | 170 | |
kisvegabor | 1:404ee28a0b60 | 171 | if(lang->plurals[ptype] != NULL) { |
kisvegabor | 1:404ee28a0b60 | 172 | txt = __lv_i18n_get_text_core(lang->plurals[ptype], msg_id); |
kisvegabor | 1:404ee28a0b60 | 173 | if (txt != NULL) return txt; |
kisvegabor | 1:404ee28a0b60 | 174 | } |
kisvegabor | 1:404ee28a0b60 | 175 | } |
kisvegabor | 1:404ee28a0b60 | 176 | |
kisvegabor | 1:404ee28a0b60 | 177 | return msg_id; |
kisvegabor | 1:404ee28a0b60 | 178 | } |
kisvegabor | 1:404ee28a0b60 | 179 | |
kisvegabor | 1:404ee28a0b60 | 180 | /** |
kisvegabor | 1:404ee28a0b60 | 181 | * Get the name of the currently used locale. |
kisvegabor | 1:404ee28a0b60 | 182 | * @return name of the currently used locale. E.g. "en-GB" |
kisvegabor | 1:404ee28a0b60 | 183 | */ |
kisvegabor | 1:404ee28a0b60 | 184 | const char * lv_i18n_get_current_locale(void) |
kisvegabor | 1:404ee28a0b60 | 185 | { |
kisvegabor | 1:404ee28a0b60 | 186 | if(!current_lang) return NULL; |
kisvegabor | 1:404ee28a0b60 | 187 | return current_lang->locale_name; |
kisvegabor | 1:404ee28a0b60 | 188 | } |