char input

Dependencies:   TS_DISCO_F746NG mbed LCD_DISCO_F746NG BSP_DISCO_F746NG lvgl_RB FastPWM millis

Revision:
1:404ee28a0b60
Child:
4:6a3d12663549
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lv_i18n.c	Fri Jan 17 06:03:24 2020 +0000
@@ -0,0 +1,188 @@
+#include "./lv_i18n.h"
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Define plural operands
+// http://unicode.org/reports/tr35/tr35-numbers.html#Operands
+
+// Integer version, simplified
+
+#define UNUSED(x) (void)(x)
+
+static lv_i18n_phrase_t en_gb_texts[] = {
+    {"dog", "This is a dog"},
+    {"cat", "This is a cat"},
+    {NULL, NULL} // End mark
+};
+
+
+static const lv_i18n_lang_t en_gb_lang = {
+    .locale_name = "en-GB",
+    .singulars = en_gb_texts,
+};
+
+static lv_i18n_phrase_t fr_texts[] = {
+    {"dog", "c'est un chien"},
+    {"cat", "Ceci est un chat"},
+    {NULL, NULL} // End mark
+};
+
+static const lv_i18n_lang_t fr_lang = {
+    .locale_name = "fr",
+    .singulars = fr_texts,
+};
+
+const lv_i18n_language_pack_t lv_i18n_language_pack[] = {
+    &en_gb_lang,
+    &fr_lang,
+    NULL // End mark
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+
+// Internal state
+static const lv_i18n_language_pack_t * current_lang_pack;
+static const lv_i18n_lang_t * current_lang;
+
+
+/**
+ * Reset internal state. For testing.
+ */
+void __lv_i18n_reset(void)
+{
+    current_lang_pack = NULL;
+    current_lang = NULL;
+}
+
+/**
+ * Set the languages for internationalization
+ * @param langs pointer to the array of languages. (Last element has to be `NULL`)
+ */
+int lv_i18n_init(const lv_i18n_language_pack_t * langs)
+{
+    if(langs == NULL) return -1;
+    if(langs[0] == NULL) return -1;
+
+    current_lang_pack = langs;
+    current_lang = langs[0];     /*Automatically select the first language*/
+    return 0;
+}
+
+/**
+ * Change the localization (language)
+ * @param l_name name of the translation locale to use. E.g. "en-GB"
+ */
+int lv_i18n_set_locale(const char * l_name)
+{
+    if(current_lang_pack == NULL) return -1;
+
+    uint16_t i;
+
+    for(i = 0; current_lang_pack[i] != NULL; i++) {
+        // Found -> finish
+        if(strcmp(current_lang_pack[i]->locale_name, l_name) == 0) {
+            current_lang = current_lang_pack[i];
+            return 0;
+        }
+    }
+
+    return -1;
+}
+
+
+static const char * __lv_i18n_get_text_core(lv_i18n_phrase_t * trans, const char * msg_id)
+{
+    uint16_t i;
+    for(i = 0; trans[i].msg_id != NULL; i++) {
+        if(strcmp(trans[i].msg_id, msg_id) == 0) {
+            /*The msg_id has found. Check the translation*/
+            if(trans[i].translation) return trans[i].translation;
+        }
+    }
+
+    return NULL;
+}
+
+
+/**
+ * Get the translation from a message ID
+ * @param msg_id message ID
+ * @return the translation of `msg_id` on the set local
+ */
+const char * lv_i18n_get_text(const char * msg_id)
+{
+    if(current_lang == NULL) return msg_id;
+
+    const lv_i18n_lang_t * lang = current_lang;
+    const void * txt;
+
+    // Search in current locale
+    if(lang->singulars != NULL) {
+        txt = __lv_i18n_get_text_core(lang->singulars, msg_id);
+        if (txt != NULL) return txt;
+    }
+
+    // Try to fallback
+    if(lang == current_lang_pack[0]) return msg_id;
+    lang = current_lang_pack[0];
+
+    // Repeat search for default locale
+    if(lang->singulars != NULL) {
+        txt = __lv_i18n_get_text_core(lang->singulars, msg_id);
+        if (txt != NULL) return txt;
+    }
+
+    return msg_id;
+}
+
+/**
+ * Get the translation from a message ID and apply the language's plural rule to get correct form
+ * @param msg_id message ID
+ * @param num an integer to select the correct plural form
+ * @return the translation of `msg_id` on the set local
+ */
+const char * lv_i18n_get_text_plural(const char * msg_id, int32_t num)
+{
+    if(current_lang == NULL) return msg_id;
+
+    const lv_i18n_lang_t * lang = current_lang;
+    const void * txt;
+    lv_i18n_plural_type_t ptype;
+
+    // Search in current locale
+    if(lang->locale_plural_fn != NULL) {
+        ptype = lang->locale_plural_fn(num);
+
+        if(lang->plurals[ptype] != NULL) {
+            txt = __lv_i18n_get_text_core(lang->plurals[ptype], msg_id);
+            if (txt != NULL) return txt;
+        }
+    }
+
+    // Try to fallback
+    if(lang == current_lang_pack[0]) return msg_id;
+    lang = current_lang_pack[0];
+
+    // Repeat search for default locale
+    if(lang->locale_plural_fn != NULL) {
+        ptype = lang->locale_plural_fn(num);
+
+        if(lang->plurals[ptype] != NULL) {
+            txt = __lv_i18n_get_text_core(lang->plurals[ptype], msg_id);
+            if (txt != NULL) return txt;
+        }
+    }
+
+    return msg_id;
+}
+
+/**
+ * Get the name of the currently used locale.
+ * @return name of the currently used locale. E.g. "en-GB"
+ */
+const char * lv_i18n_get_current_locale(void)
+{
+    if(!current_lang) return NULL;
+    return current_lang->locale_name;
+}