diff --git a/Kconfig b/Kconfig
index 4023a3814b..76e86c597b 100644
--- a/Kconfig
+++ b/Kconfig
@@ -1030,14 +1030,22 @@ menu "LVGL configuration"
config LV_USE_IME_PINYIN
bool "Enable Pinyin input method"
default n
+ config LV_IME_PINYIN_USE_K9_MODE
+ bool "Enable Pinyin input method 9 key input mode"
+ depends on LV_USE_IME_PINYIN
+ default n
+ config LV_IME_PINYIN_K9_CAND_TEXT_NUM
+ int "Maximum number of candidate panels for 9-key input mode"
+ depends on LV_IME_PINYIN_USE_K9_MODE
+ default 3
config LV_IME_PINYIN_USE_DEFAULT_DICT
bool "Use built-in Thesaurus"
depends on LV_USE_IME_PINYIN
default y
help
- If you do not use the default thesaurus, be sure to use `lv_ime_pinyin` after setting the thesauruss
+ If you do not use the default thesaurus, be sure to use lv_ime_pinyin after setting the thesauruss
config LV_IME_PINYIN_CAND_TEXT_NUM
- int "maximum number of candidate panels"
+ int "Maximum number of candidate panels"
depends on LV_USE_IME_PINYIN
default 6
help
diff --git a/docs/others/ime_pinyin.md b/docs/others/ime_pinyin.md
index c660d02c4a..82747fff89 100644
--- a/docs/others/ime_pinyin.md
+++ b/docs/others/ime_pinyin.md
@@ -1,6 +1,6 @@
# Pinyin IME
-Pinyin IME provides API to provide Chinese Pinyin input method (Chinese input) for keyboard object. You can think of `lv_ime_pinyin` as a Pinyin input method plug-in for keyboard objects.
+Pinyin IME provides API to provide Chinese Pinyin input method (Chinese input) for keyboard object, which supports 26 key and 9 key input modes. You can think of `lv_ime_pinyin` as a Pinyin input method plug-in for keyboard objects.
Normally, an environment where [lv_keyboard](/widgets/extra/keyboard) can run can also run `lv_ime_pinyin`. There are two main influencing factors: the size of the font file and the size of the dictionary.
@@ -8,7 +8,7 @@ Normally, an environment where [lv_keyboard](/widgets/extra/keyboard) can run ca
中文
-`lv_ime_pinyin`为[键盘](/widgets/extra/keyboard)组件提供汉语拼音输入法(中文输入)的功能(后文简称为拼音输入法)。您可以将 `lv_ime_pinyin` 看成是键盘组件的汉语拼音输入法插件。
+`lv_ime_pinyin`为[键盘](/widgets/extra/keyboard)组件提供汉语拼音输入法(中文输入)的功能(后文简称为拼音输入法),支持26键和9键输入模式。您可以将 `lv_ime_pinyin` 看成是键盘组件的汉语拼音输入法插件。
一般情况下,只要是[键盘](/widgets/extra/keyboard)组件能运行的环境 `lv_ime_pinyin` 也能运行。有两个影响因素:字库的大小和词库的大小。
@@ -118,6 +118,20 @@ After writing a dictionary according to the above dictionary format, you only ne
lv_100ask_pinyin_ime_set_dict(pinyin_ime, your_pinyin_dict);
```
+## Input modes
+
+`lv_ime_pinyin` supports 26 key and 9 key input modes. The mode switching is very simple, just call the function `lv_ime_pinyin_set_mode`. If the second parameter of function `lv_ime_pinyin_set_mode` is' 1 ', switch to 26 key input mode; if it is' 0', switch to 9 key input mode, and the default is' 1 '.
+
+
+中文
+
+
+`lv_ime_pinyin` 支持26键和9键输入模式。模式的切换非常简单,只需调用函数 `lv_ime_pinyin_set_mode` 即可。如果函数 `lv_ime_pinyin_set_mode` 的第2个参数为 `1` 则切换到 26 键输入模式,如果为 `0` 则切换到 9 键输入法模式,默认为 `1` 。
+
+
+
+
+
## Example
```eval_rst
diff --git a/examples/others/ime/index.rst b/examples/others/ime/index.rst
index 2633da5ef0..e7cc1fb9a3 100644
--- a/examples/others/ime/index.rst
+++ b/examples/others/ime/index.rst
@@ -1,8 +1,12 @@
-Simple Pinyin IME example
-"""""""""""""""""""
+Pinyin IME 26 key input
+"""""""""""""""""""""""""
.. lv_example:: others/ime/lv_example_ime_pinyin_1
:language: c
+Pinyin IME 9 key input
+"""""""""""""""""""""""""
+.. lv_example:: others/ime/lv_example_ime_pinyin_2
+ :language: c
diff --git a/examples/others/ime/lv_example_ime_pinyin.h b/examples/others/ime/lv_example_ime_pinyin.h
index b43bfeaee1..96991e3a32 100644
--- a/examples/others/ime/lv_example_ime_pinyin.h
+++ b/examples/others/ime/lv_example_ime_pinyin.h
@@ -26,6 +26,7 @@ extern "C" {
* GLOBAL PROTOTYPES
**********************/
void lv_example_ime_pinyin_1(void);
+void lv_example_ime_pinyin_2(void);
/**********************
* MACROS
diff --git a/examples/others/ime/lv_example_ime_pinyin_1.c b/examples/others/ime/lv_example_ime_pinyin_1.c
index eb6101ac69..b609ee6141 100644
--- a/examples/others/ime/lv_example_ime_pinyin_1.c
+++ b/examples/others/ime/lv_example_ime_pinyin_1.c
@@ -1,5 +1,5 @@
#include "../../lv_examples.h"
-#if LV_USE_LABEL && LV_USE_TEXTAREA && LV_FONT_SIMSUN_16_CJK && LV_USE_IME_PINYIN && LV_BUILD_EXAMPLES
+#if LV_USE_LABEL && LV_USE_TEXTAREA && LV_FONT_SIMSUN_16_CJK && LV_USE_IME_PINYIN && LV_BUILD_EXAMPLES
static void ta_event_cb(lv_event_t * e)
{
@@ -13,7 +13,7 @@ static void ta_event_cb(lv_event_t * e)
lv_obj_clear_flag(kb, LV_OBJ_FLAG_HIDDEN);
}
}
- else if(code == LV_EVENT_READY || code == LV_EVENT_CANCEL) {
+ else if(code == LV_EVENT_CANCEL) {
lv_obj_add_flag(kb, LV_OBJ_FLAG_HIDDEN);
lv_obj_clear_state(ta, LV_STATE_FOCUSED);
lv_indev_reset(NULL, ta); /*To forget the last clicked object to make it focusable again*/
@@ -24,7 +24,7 @@ void lv_example_ime_pinyin_1(void)
{
lv_obj_t * pinyin_ime = lv_ime_pinyin_create(lv_scr_act());
lv_obj_set_style_text_font(pinyin_ime, &lv_font_simsun_16_cjk, 0);
- //lv_ime_pinyin_set_dict(pinyin_ime, your_dict); // Use a custom dictionary. If it is not set, the built-in thesaurus will be used.
+ //lv_ime_pinyin_set_dict(pinyin_ime, your_dict); // Use a custom dictionary. If it is not set, the built-in dictionary will be used.
/* ta1 */
lv_obj_t * ta1 = lv_textarea_create(lv_scr_act());
diff --git a/examples/others/ime/lv_example_ime_pinyin_2.c b/examples/others/ime/lv_example_ime_pinyin_2.c
new file mode 100644
index 0000000000..af5a0589d0
--- /dev/null
+++ b/examples/others/ime/lv_example_ime_pinyin_2.c
@@ -0,0 +1,58 @@
+#include "../../lv_examples.h"
+#if LV_USE_LABEL && LV_USE_TEXTAREA && LV_FONT_SIMSUN_16_CJK && LV_USE_IME_PINYIN && LV_IME_PINYIN_USE_K9_MODE && LV_BUILD_EXAMPLES
+
+static void ta_event_cb(lv_event_t * e)
+{
+ lv_event_code_t code = lv_event_get_code(e);
+ lv_obj_t * ta = lv_event_get_target(e);
+ lv_obj_t * kb = lv_event_get_user_data(e);
+
+ if(code == LV_EVENT_FOCUSED) {
+ if(lv_indev_get_type(lv_indev_get_act()) != LV_INDEV_TYPE_KEYPAD) {
+ lv_keyboard_set_textarea(kb, ta);
+ lv_obj_clear_flag(kb, LV_OBJ_FLAG_HIDDEN);
+ }
+ }
+ else if(code == LV_EVENT_READY) {
+ lv_obj_add_flag(kb, LV_OBJ_FLAG_HIDDEN);
+ lv_obj_clear_state(ta, LV_STATE_FOCUSED);
+ lv_indev_reset(NULL, ta); /*To forget the last clicked object to make it focusable again*/
+ }
+}
+
+void lv_example_ime_pinyin_2(void)
+{
+ lv_obj_t * pinyin_ime = lv_ime_pinyin_create(lv_scr_act());
+ lv_obj_set_style_text_font(pinyin_ime, &lv_font_simsun_16_cjk, 0);
+ //lv_ime_pinyin_set_dict(pinyin_ime, your_dict); // Use a custom dictionary. If it is not set, the built-in dictionary will be used.
+
+ /* ta1 */
+ lv_obj_t * ta1 = lv_textarea_create(lv_scr_act());
+ lv_textarea_set_one_line(ta1, true);
+ lv_obj_set_style_text_font(ta1, &lv_font_simsun_16_cjk, 0);
+ lv_obj_align(ta1, LV_ALIGN_TOP_LEFT, 0, 0);
+
+ /*Create a keyboard and add it to ime_pinyin*/
+ lv_obj_t * kb = lv_keyboard_create(lv_scr_act());
+ lv_keyboard_set_textarea(kb, ta1);
+
+ lv_ime_pinyin_set_keyboard(pinyin_ime, kb);
+ lv_ime_pinyin_set_mode(pinyin_ime,
+ LV_IME_PINYIN_MODE_K9); // Set to 9-key input mode. Default: 26-key input(k26) mode.
+ lv_obj_add_event_cb(ta1, ta_event_cb, LV_EVENT_ALL, kb);
+
+ /*Get the cand_panel, and adjust its size and position*/
+ lv_obj_t * cand_panel = lv_ime_pinyin_get_cand_panel(pinyin_ime);
+ lv_obj_set_size(cand_panel, LV_PCT(100), LV_PCT(10));
+ lv_obj_align_to(cand_panel, kb, LV_ALIGN_OUT_TOP_MID, 0, 0);
+
+ /*Try using ime_pinyin to output the Chinese below in the ta1 above*/
+ lv_obj_t * cz_label = lv_label_create(lv_scr_act());
+ lv_label_set_text(cz_label,
+ "嵌入式系统(Embedded System),\n是一种嵌入机械或电气系统内部、具有专一功能和实时计算性能的计算机系统。");
+ lv_obj_set_style_text_font(cz_label, &lv_font_simsun_16_cjk, 0);
+ lv_obj_set_width(cz_label, 310);
+ lv_obj_align_to(cz_label, ta1, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 0);
+}
+
+#endif
diff --git a/lv_conf_template.h b/lv_conf_template.h
index b4a1600ced..fcbaf73f72 100644
--- a/lv_conf_template.h
+++ b/lv_conf_template.h
@@ -704,6 +704,12 @@
/*Set the maximum number of candidate panels that can be displayed*/
/*This needs to be adjusted according to the size of the screen*/
#define LV_IME_PINYIN_CAND_TEXT_NUM 6
+
+ /*Use 9 key input(k9)*/
+ #define LV_IME_PINYIN_USE_K9_MODE 1
+ #if LV_IME_PINYIN_USE_K9_MODE == 1
+ #define LV_IME_PINYIN_K9_CAND_TEXT_NUM 3
+ #endif // LV_IME_PINYIN_USE_K9_MODE
#endif
/*==================
diff --git a/src/extra/others/ime/lv_ime_pinyin.c b/src/extra/others/ime/lv_ime_pinyin.c
index ab0bfc6e05..b1661e4f71 100644
--- a/src/extra/others/ime/lv_ime_pinyin.c
+++ b/src/extra/others/ime/lv_ime_pinyin.c
@@ -32,7 +32,16 @@ static void lv_ime_pinyin_cand_panel_event(lv_event_t * e);
static void init_pinyin_dict(lv_obj_t * obj, lv_pinyin_dict_t * dict);
static void pinyin_input_proc(lv_obj_t * obj);
static void pinyin_page_proc(lv_obj_t * obj, uint16_t btn);
-static char * pinyin_search_matching(lv_obj_t * obj, char * strInput_py_str, uint16_t * cand_num);
+static char * pinyin_search_matching(lv_obj_t * obj, char * py_str, uint16_t * cand_num);
+static void pinyin_ime_clear_data(lv_obj_t * obj);
+
+#if LV_IME_PINYIN_USE_K9_MODE
+ static void pinyin_k9_init_data(lv_obj_t * obj);
+ static void pinyin_k9_get_legal_py(lv_obj_t * obj, char * k9_input, const char * py9_map[]);
+ static bool pinyin_k9_is_valid_py(lv_obj_t * obj, char * py_str);
+ static void pinyin_k9_fill_cand(lv_obj_t * obj);
+ static void pinyin_k9_cand_page_proc(lv_obj_t * obj, uint16_t dir);
+#endif
/**********************
* STATIC VARIABLES
@@ -47,6 +56,18 @@ const lv_obj_class_t lv_ime_pinyin_class = {
.base_class = &lv_obj_class
};
+#if LV_IME_PINYIN_USE_K9_MODE
+static char * lv_btnm_def_pinyin_k9_map[LV_IME_PINYIN_K9_CAND_TEXT_NUM + 20] = {\
+ ",\0", "1#\0", "abc \0", "def\0", LV_SYMBOL_BACKSPACE"\0", "\n\0",
+ ".\0", "ghi\0", "jkl\0", "mno\0", LV_SYMBOL_KEYBOARD"\0", "\n\0",
+ "?\0", "pqrs\0", "tuv\0", "wxyz\0", LV_SYMBOL_NEW_LINE"\0", "\n\0",
+ LV_SYMBOL_LEFT"\0", "\0"
+ };
+
+static lv_btnmatrix_ctrl_t default_kb_ctrl_k9_map[LV_IME_PINYIN_K9_CAND_TEXT_NUM + 16] = { 1 };
+static char lv_pinyin_k9_cand_str[LV_IME_PINYIN_K9_CAND_TEXT_NUM + 2][LV_IME_PINYIN_K9_MAX_INPUT] = {0};
+#endif
+
static char lv_pinyin_cand_str[LV_IME_PINYIN_CAND_TEXT_NUM][4];
static char * lv_btnm_def_pinyin_sel_map[LV_IME_PINYIN_CAND_TEXT_NUM + 3];
@@ -429,6 +450,30 @@ void lv_ime_pinyin_set_dict(lv_obj_t * obj, lv_pinyin_dict_t * dict)
init_pinyin_dict(obj, dict);
}
+/**
+ * Set mode, 26-key input(k26) or 9-key input(k9).
+ * @param obj pointer to a Pinyin input method object
+ * @param mode the mode from 'lv_keyboard_mode_t'
+ */
+void lv_ime_pinyin_set_mode(lv_obj_t * obj, lv_ime_pinyin_mode_t mode)
+{
+ LV_ASSERT_OBJ(obj, MY_CLASS);
+ lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;
+
+ LV_ASSERT_OBJ(pinyin_ime->kb, &lv_keyboard_class);
+
+ pinyin_ime->mode = mode;
+
+#if LV_IME_PINYIN_USE_K9_MODE
+ if(pinyin_ime->mode == LV_IME_PINYIN_MODE_K9) {
+ pinyin_k9_init_data(obj);
+ lv_keyboard_set_map(pinyin_ime->kb, LV_KEYBOARD_MODE_USER_1, (const char *)lv_btnm_def_pinyin_k9_map,
+ (const)default_kb_ctrl_k9_map);
+ lv_keyboard_set_mode(pinyin_ime->kb, LV_KEYBOARD_MODE_USER_1);
+ }
+#endif
+}
+
/*=====================
* Getter functions
*====================*/
@@ -491,7 +536,8 @@ static void lv_ime_pinyin_constructor(const lv_obj_class_t * class_p, lv_obj_t *
lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;
uint16_t py_str_i = 0;
- for(uint16_t btnm_i = 0; btnm_i < (LV_IME_PINYIN_CAND_TEXT_NUM + 3); btnm_i++) {
+ uint16_t btnm_i = 0;
+ for(btnm_i = 0; btnm_i < (LV_IME_PINYIN_CAND_TEXT_NUM + 3); btnm_i++) {
if(btnm_i == 0) {
lv_btnm_def_pinyin_sel_map[btnm_i] = "<";
}
@@ -508,6 +554,7 @@ static void lv_ime_pinyin_constructor(const lv_obj_class_t * class_p, lv_obj_t *
}
}
+ pinyin_ime->mode = LV_IME_PINYIN_MODE_K26;
pinyin_ime->py_page = 0;
pinyin_ime->ta_count = 0;
pinyin_ime->cand_num = 0;
@@ -553,6 +600,17 @@ static void lv_ime_pinyin_constructor(const lv_obj_class_t * class_p, lv_obj_t *
/* event handler */
lv_obj_add_event_cb(pinyin_ime->cand_panel, lv_ime_pinyin_cand_panel_event, LV_EVENT_VALUE_CHANGED, obj);
lv_obj_add_event_cb(obj, lv_ime_pinyin_style_change_event, LV_EVENT_STYLE_CHANGED, NULL);
+
+#if LV_IME_PINYIN_USE_K9_MODE
+ pinyin_ime->k9_input_str_len = 0;
+ pinyin_ime->k9_py_ll_pos = 0;
+ pinyin_ime->k9_legal_py_count = 0;
+ lv_memset_00(pinyin_ime->k9_input_str, LV_IME_PINYIN_K9_MAX_INPUT);
+
+ pinyin_k9_init_data(obj);
+
+ _lv_ll_init(&(pinyin_ime->k9_legal_py_ll), sizeof(ime_pinyin_k9_py_str_t));
+#endif
}
@@ -578,6 +636,10 @@ static void lv_ime_pinyin_kb_event(lv_event_t * e)
lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;
+#if LV_IME_PINYIN_USE_K9_MODE
+ static const char * k9_py_map[8] = {"abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
+#endif
+
if(code == LV_EVENT_VALUE_CHANGED) {
uint16_t btn_id = lv_btnmatrix_get_selected_btn(kb);
if(btn_id == LV_BTNMATRIX_BTN_NONE) return;
@@ -585,38 +647,111 @@ static void lv_ime_pinyin_kb_event(lv_event_t * e)
const char * txt = lv_btnmatrix_get_btn_text(kb, lv_btnmatrix_get_selected_btn(kb));
if(txt == NULL) return;
+#if LV_IME_PINYIN_USE_K9_MODE
+ if(pinyin_ime->mode == LV_IME_PINYIN_MODE_K9) {
+ lv_obj_t * ta = lv_keyboard_get_textarea(pinyin_ime->kb);
+ uint16_t tmp_btn_str_len = strlen(pinyin_ime->input_char);
+ if((btn_id >= 16) && (tmp_btn_str_len > 0) && (btn_id < (16 + LV_IME_PINYIN_K9_CAND_TEXT_NUM))) {
+ tmp_btn_str_len = strlen(pinyin_ime->input_char);
+ lv_memset_00(pinyin_ime->input_char, sizeof(pinyin_ime->input_char));
+ strcat(pinyin_ime->input_char, txt);
+ pinyin_input_proc(obj);
+
+ for(int index = 0; index < (pinyin_ime->ta_count + tmp_btn_str_len); index++) {
+ lv_textarea_del_char(ta);
+ }
+
+ pinyin_ime->ta_count = tmp_btn_str_len;
+ pinyin_ime->k9_input_str_len = tmp_btn_str_len;
+ lv_textarea_add_text(ta, pinyin_ime->input_char);
+
+ return;
+ }
+ }
+#endif
+
if(strcmp(txt, "Enter") == 0 || strcmp(txt, LV_SYMBOL_NEW_LINE) == 0) {
- lv_memset_00(lv_pinyin_cand_str, (sizeof(lv_pinyin_cand_str)));
- pinyin_ime->ta_count = 0;
- lv_memset_00(pinyin_ime->input_char, sizeof(pinyin_ime->input_char));
+ pinyin_ime_clear_data(obj);
+ lv_obj_add_flag(pinyin_ime->cand_panel, LV_OBJ_FLAG_HIDDEN);
}
else if(strcmp(txt, LV_SYMBOL_BACKSPACE) == 0) {
// del input char
- for(int i = strlen(pinyin_ime->input_char) - 1; i >= 0; i--) {
- if(pinyin_ime->input_char[i] != '\0') {
- pinyin_ime->input_char[i] = '\0';
+ if(pinyin_ime->ta_count > 0) {
+ if(pinyin_ime->mode == LV_IME_PINYIN_MODE_K26)
+ pinyin_ime->input_char[pinyin_ime->ta_count - 1] = '\0';
+#if LV_IME_PINYIN_USE_K9_MODE
+ else
+ pinyin_ime->k9_input_str[pinyin_ime->ta_count - 1] = '\0';
+#endif
+
+ pinyin_ime->ta_count = pinyin_ime->ta_count - 1;
+ if(pinyin_ime->ta_count <= 0) {
lv_obj_add_flag(pinyin_ime->cand_panel, LV_OBJ_FLAG_HIDDEN);
- break;
+#if LV_IME_PINYIN_USE_K9_MODE
+ lv_memset_00(lv_pinyin_k9_cand_str, sizeof(lv_pinyin_k9_cand_str));
+ strcpy(lv_pinyin_k9_cand_str[LV_IME_PINYIN_K9_CAND_TEXT_NUM], LV_SYMBOL_RIGHT"\0");
+ strcpy(lv_pinyin_k9_cand_str[LV_IME_PINYIN_K9_CAND_TEXT_NUM + 1], "\0");
+#endif
}
+ else if(pinyin_ime->mode == LV_IME_PINYIN_MODE_K26) {
+ pinyin_input_proc(obj);
+ }
+#if LV_IME_PINYIN_USE_K9_MODE
+ else if(pinyin_ime->mode == LV_IME_PINYIN_MODE_K9) {
+ pinyin_ime->k9_input_str_len = strlen(pinyin_ime->input_char) - 1;
+ pinyin_k9_get_legal_py(obj, pinyin_ime->k9_input_str, k9_py_map);
+ pinyin_k9_fill_cand(obj);
+ pinyin_input_proc(obj);
+ }
+#endif
}
- pinyin_input_proc(obj);
- pinyin_ime->ta_count--;
}
else if((strcmp(txt, "ABC") == 0) || (strcmp(txt, "abc") == 0) || (strcmp(txt, "1#") == 0)) {
pinyin_ime->ta_count = 0;
lv_memset_00(pinyin_ime->input_char, sizeof(pinyin_ime->input_char));
return;
}
- else if((strcmp(txt, LV_SYMBOL_KEYBOARD) == 0) || (strcmp(txt, LV_SYMBOL_OK) == 0)) {
- pinyin_ime->ta_count = 0;
- lv_memset_00(pinyin_ime->input_char, sizeof(pinyin_ime->input_char));
- lv_obj_add_flag(pinyin_ime->cand_panel, LV_OBJ_FLAG_HIDDEN);
+ else if(strcmp(txt, LV_SYMBOL_KEYBOARD) == 0) {
+ if(pinyin_ime->mode == LV_IME_PINYIN_MODE_K26) {
+ lv_ime_pinyin_set_mode(pinyin_ime, LV_IME_PINYIN_MODE_K9);
+ }
+ else {
+ lv_ime_pinyin_set_mode(pinyin_ime, LV_IME_PINYIN_MODE_K26);
+ lv_keyboard_set_mode(pinyin_ime->kb, LV_KEYBOARD_MODE_TEXT_LOWER);
+ }
+ pinyin_ime_clear_data(obj);
}
- else if((txt[0] >= 'a' && txt[0] <= 'z') || (txt[0] >= 'A' && txt[0] <= 'Z')) {
+ else if(strcmp(txt, LV_SYMBOL_OK) == 0) {
+ pinyin_ime_clear_data(obj);
+ }
+ else if((pinyin_ime->mode == LV_IME_PINYIN_MODE_K26) && ((txt[0] >= 'a' && txt[0] <= 'z') || (txt[0] >= 'A' &&
+ txt[0] <= 'Z'))) {
strcat(pinyin_ime->input_char, txt);
pinyin_input_proc(obj);
pinyin_ime->ta_count++;
}
+#if LV_IME_PINYIN_USE_K9_MODE
+ else if((pinyin_ime->mode == LV_IME_PINYIN_MODE_K9) && (txt[0] >= 'a' && txt[0] <= 'z')) {
+ for(uint16_t i = 0; i < 8; i++) {
+ if((strcmp(txt, k9_py_map[i]) == 0) || (strcmp(txt, "abc ") == 0)) {
+ if(strcmp(txt, "abc ") == 0) pinyin_ime->k9_input_str_len += strlen(k9_py_map[i]) + 1;
+ else pinyin_ime->k9_input_str_len += strlen(k9_py_map[i]);
+ pinyin_ime->k9_input_str[pinyin_ime->ta_count] = 50 + i;
+
+ break;
+ }
+ }
+ pinyin_k9_get_legal_py(obj, pinyin_ime->k9_input_str, k9_py_map);
+ pinyin_k9_fill_cand(obj);
+ pinyin_input_proc(obj);
+ }
+ else if(strcmp(txt, LV_SYMBOL_LEFT) == 0) {
+ pinyin_k9_cand_page_proc(obj, 0);
+ }
+ else if(strcmp(txt, LV_SYMBOL_RIGHT) == 0) {
+ pinyin_k9_cand_page_proc(obj, 1);
+ }
+#endif
}
}
@@ -642,17 +777,13 @@ static void lv_ime_pinyin_cand_panel_event(lv_event_t * e)
const char * txt = lv_btnmatrix_get_btn_text(cand_panel, id);
lv_obj_t * ta = lv_keyboard_get_textarea(pinyin_ime->kb);
-
- for(int i = 0; i < pinyin_ime->ta_count; i++) {
+ uint16_t index = 0;
+ for(index = 0; index < pinyin_ime->ta_count; index++)
lv_textarea_del_char(ta);
- }
lv_textarea_add_text(ta, txt);
- pinyin_ime->ta_count = 0;
- lv_memset_00(lv_pinyin_cand_str, (sizeof(lv_pinyin_cand_str)));
- lv_memset_00(pinyin_ime->input_char, sizeof(pinyin_ime->input_char));
- lv_obj_add_flag(pinyin_ime->cand_panel, LV_OBJ_FLAG_HIDDEN);
+ pinyin_ime_clear_data(obj);
}
}
@@ -772,34 +903,34 @@ static void init_pinyin_dict(lv_obj_t * obj, lv_pinyin_dict_t * dict)
}
-static char * pinyin_search_matching(lv_obj_t * obj, char * strInput_py_str, uint16_t * cand_num)
+static char * pinyin_search_matching(lv_obj_t * obj, char * py_str, uint16_t * cand_num)
{
lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;
lv_pinyin_dict_t * cpHZ;
- uint8_t i, cInputStrLength = 0, offset;
+ uint8_t index, len = 0, offset;
volatile uint8_t count = 0;
- if(*strInput_py_str == '\0') return NULL;
- if(*strInput_py_str == 'i') return NULL;
- if(*strInput_py_str == 'u') return NULL;
- if(*strInput_py_str == 'v') return NULL;
+ if(*py_str == '\0') return NULL;
+ if(*py_str == 'i') return NULL;
+ if(*py_str == 'u') return NULL;
+ if(*py_str == 'v') return NULL;
- offset = strInput_py_str[0] - 'a';
- cInputStrLength = strlen(strInput_py_str);
+ offset = py_str[0] - 'a';
+ len = strlen(py_str);
cpHZ = &pinyin_ime->dict[pinyin_ime->py_pos[offset]];
count = pinyin_ime->py_num[offset];
while(count--) {
- for(i = 0; i < cInputStrLength; i++) {
- if(*(strInput_py_str + i) != *((cpHZ->py) + i)) {
+ for(index = 0; index < len; index++) {
+ if(*(py_str + index) != *((cpHZ->py) + index)) {
break;
}
}
// perfect match
- if(cInputStrLength == 1 || i == cInputStrLength) {
+ if(len == 1 || index == len) {
// The Chinese character in UTF-8 encoding format is 3 bytes
* cand_num = strlen((const char *)(cpHZ->py_mb)) / 3;
return (char *)(cpHZ->py_mb);
@@ -809,5 +940,259 @@ static char * pinyin_search_matching(lv_obj_t * obj, char * strInput_py_str, uin
return NULL;
}
+static void pinyin_ime_clear_data(lv_obj_t * obj)
+{
+ lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;
+
+
+#if LV_IME_PINYIN_USE_K9_MODE
+ if(pinyin_ime->mode == LV_IME_PINYIN_MODE_K9) {
+ pinyin_ime->k9_input_str_len = 0;
+ pinyin_ime->k9_py_ll_pos = 0;
+ pinyin_ime->k9_legal_py_count = 0;
+ lv_memset_00(pinyin_ime->k9_input_str, LV_IME_PINYIN_K9_MAX_INPUT);
+ lv_memset_00(lv_pinyin_k9_cand_str, sizeof(lv_pinyin_k9_cand_str));
+ strcpy(lv_pinyin_k9_cand_str[LV_IME_PINYIN_K9_CAND_TEXT_NUM], LV_SYMBOL_RIGHT"\0");
+ strcpy(lv_pinyin_k9_cand_str[LV_IME_PINYIN_K9_CAND_TEXT_NUM + 1], "\0");
+ }
+#endif
+
+ pinyin_ime->ta_count = 0;
+ lv_memset_00(lv_pinyin_cand_str, (sizeof(lv_pinyin_cand_str)));
+ lv_memset_00(pinyin_ime->input_char, sizeof(pinyin_ime->input_char));
+
+ lv_obj_add_flag(pinyin_ime->cand_panel, LV_OBJ_FLAG_HIDDEN);
+}
+
+
+#if LV_IME_PINYIN_USE_K9_MODE
+static void pinyin_k9_init_data(lv_obj_t * obj)
+{
+ lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;
+
+ uint16_t py_str_i = 0;
+ uint16_t btnm_i = 0;
+ for(btnm_i = 19; btnm_i < (LV_IME_PINYIN_K9_CAND_TEXT_NUM + 21); btnm_i++) {
+ if(py_str_i == LV_IME_PINYIN_K9_CAND_TEXT_NUM) {
+ strcpy(lv_pinyin_k9_cand_str[py_str_i], LV_SYMBOL_RIGHT"\0");
+ }
+ else if(py_str_i == LV_IME_PINYIN_K9_CAND_TEXT_NUM + 1) {
+ strcpy(lv_pinyin_k9_cand_str[py_str_i], "\0");
+ }
+ else {
+ strcpy(lv_pinyin_k9_cand_str[py_str_i], " \0");
+ }
+
+ lv_btnm_def_pinyin_k9_map[btnm_i] = lv_pinyin_k9_cand_str[py_str_i];
+ py_str_i++;
+ }
+
+ default_kb_ctrl_k9_map[0] = LV_KEYBOARD_CTRL_BTN_FLAGS | 1;
+ default_kb_ctrl_k9_map[4] = LV_KEYBOARD_CTRL_BTN_FLAGS | 1;
+ default_kb_ctrl_k9_map[5] = LV_KEYBOARD_CTRL_BTN_FLAGS | 1;
+ default_kb_ctrl_k9_map[9] = LV_KEYBOARD_CTRL_BTN_FLAGS | 1;
+ default_kb_ctrl_k9_map[10] = LV_KEYBOARD_CTRL_BTN_FLAGS | 1;
+ default_kb_ctrl_k9_map[14] = LV_KEYBOARD_CTRL_BTN_FLAGS | 1;
+ default_kb_ctrl_k9_map[15] = LV_KEYBOARD_CTRL_BTN_FLAGS | 1;
+ default_kb_ctrl_k9_map[LV_IME_PINYIN_K9_CAND_TEXT_NUM + 16] = LV_KEYBOARD_CTRL_BTN_FLAGS | 1;
+}
+
+static void pinyin_k9_get_legal_py(lv_obj_t * obj, char * k9_input, const char * py9_map[])
+{
+ lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;
+
+ uint16_t len = strlen(k9_input);
+
+ if((len == 0) || (len >= LV_IME_PINYIN_K9_MAX_INPUT)) {
+ return;
+ }
+
+ char py_comp[LV_IME_PINYIN_K9_MAX_INPUT] = {0};
+ int mark[LV_IME_PINYIN_K9_MAX_INPUT] = {0};
+ int index = 0;
+ int flag = 0;
+ int count = 0;
+
+ uint32_t ll_len = 0;
+ ime_pinyin_k9_py_str_t * ll_index = NULL;
+
+ ll_len = _lv_ll_get_len(&pinyin_ime->k9_legal_py_ll);
+ ll_index = _lv_ll_get_head(&pinyin_ime->k9_legal_py_ll);
+
+ while(index != -1) {
+ if(index == len) {
+ if(pinyin_k9_is_valid_py(obj, py_comp)) {
+ if((count >= ll_len) || (ll_len == 0)) {
+ ll_index = _lv_ll_ins_tail(&pinyin_ime->k9_legal_py_ll);
+ strcpy(ll_index->py_str, py_comp);
+ }
+ else if((count < ll_len)) {
+ strcpy(ll_index->py_str, py_comp);
+ ll_index = _lv_ll_get_next(&pinyin_ime->k9_legal_py_ll, ll_index);
+ }
+ count++;
+ }
+ index--;
+ }
+ else {
+ flag = mark[index];
+ if(flag < strlen(py9_map[k9_input[index] - '2'])) {
+ py_comp[index] = py9_map[k9_input[index] - '2'][flag];
+ mark[index] = mark[index] + 1;
+ index++;
+ }
+ else {
+ mark[index] = 0;
+ index--;
+ }
+ }
+ }
+
+ if(count > 0) {
+ pinyin_ime->ta_count++;
+ pinyin_ime->k9_legal_py_count = count;
+ }
+}
+
+
+/*true: visible; false: not visible*/
+static bool pinyin_k9_is_valid_py(lv_obj_t * obj, char * py_str)
+{
+ lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;
+
+ lv_pinyin_dict_t * cpHZ = NULL;
+ uint8_t index = 0, len = 0, offset = 0;
+ uint16_t ret = 1;
+ volatile uint8_t count = 0;
+
+ if(*py_str == '\0') return false;
+ if(*py_str == 'i') return false;
+ if(*py_str == 'u') return false;
+ if(*py_str == 'v') return false;
+
+ offset = py_str[0] - 'a';
+ len = strlen(py_str);
+
+ cpHZ = &pinyin_ime->dict[pinyin_ime->py_pos[offset]];
+ count = pinyin_ime->py_num[offset];
+
+ while(count--) {
+ for(index = 0; index < len; index++) {
+ if(*(py_str + index) != *((cpHZ->py) + index)) {
+ break;
+ }
+ }
+
+ // perfect match
+ if(len == 1 || index == len) {
+ return true;
+ }
+ cpHZ++;
+ }
+ return false;
+}
+
+
+static void pinyin_k9_fill_cand(lv_obj_t * obj)
+{
+ static uint16_t len = 0;
+ uint16_t index = 0, tmp_len = 0;
+ ime_pinyin_k9_py_str_t * ll_index = NULL;
+
+ lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;
+
+ tmp_len = pinyin_ime->k9_legal_py_count;
+
+ if(tmp_len != len) {
+ lv_memset_00(lv_pinyin_k9_cand_str, sizeof(lv_pinyin_k9_cand_str));
+ strcpy(lv_pinyin_k9_cand_str[LV_IME_PINYIN_K9_CAND_TEXT_NUM], LV_SYMBOL_RIGHT"\0");
+ strcpy(lv_pinyin_k9_cand_str[LV_IME_PINYIN_K9_CAND_TEXT_NUM + 1], "\0");
+ len = tmp_len;
+ }
+
+ ll_index = _lv_ll_get_head(&pinyin_ime->k9_legal_py_ll);
+ strcpy(pinyin_ime->input_char, ll_index->py_str);
+ while(ll_index) {
+ if((index >= LV_IME_PINYIN_K9_CAND_TEXT_NUM) || \
+ (index >= pinyin_ime->k9_legal_py_count))
+ break;
+
+ strcpy(lv_pinyin_k9_cand_str[index], ll_index->py_str);
+ ll_index = _lv_ll_get_next(&pinyin_ime->k9_legal_py_ll, ll_index); /*Find the next list*/
+ index++;
+ }
+ pinyin_ime->k9_py_ll_pos = index;
+
+ lv_obj_t * ta = lv_keyboard_get_textarea(pinyin_ime->kb);
+ for(index = 0; index < pinyin_ime->k9_input_str_len; index++) {
+ lv_textarea_del_char(ta);
+ }
+ pinyin_ime->k9_input_str_len = strlen(pinyin_ime->input_char);
+ lv_textarea_add_text(ta, pinyin_ime->input_char);
+}
+
+
+static void pinyin_k9_cand_page_proc(lv_obj_t * obj, uint16_t dir)
+{
+ lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;
+
+ lv_obj_t * ta = lv_keyboard_get_textarea(pinyin_ime->kb);
+ uint16_t ll_len = _lv_ll_get_len(&pinyin_ime->k9_legal_py_ll);
+
+ if((ll_len > LV_IME_PINYIN_K9_CAND_TEXT_NUM) && (pinyin_ime->k9_legal_py_count > LV_IME_PINYIN_K9_CAND_TEXT_NUM)) {
+ ime_pinyin_k9_py_str_t * ll_index = NULL;
+ uint16_t tmp_btn_str_len = 0;
+ int count = 0;
+
+ ll_index = _lv_ll_get_head(&pinyin_ime->k9_legal_py_ll);
+ while(ll_index) {
+ if(count >= pinyin_ime->k9_py_ll_pos) break;
+
+ ll_index = _lv_ll_get_next(&pinyin_ime->k9_legal_py_ll, ll_index); /*Find the next list*/
+ count++;
+ }
+
+ if((NULL == ll_index) && (dir == 1)) return;
+
+ lv_memset_00(lv_pinyin_k9_cand_str, sizeof(lv_pinyin_k9_cand_str));
+ strcpy(lv_pinyin_k9_cand_str[LV_IME_PINYIN_K9_CAND_TEXT_NUM], LV_SYMBOL_RIGHT"\0");
+ strcpy(lv_pinyin_k9_cand_str[LV_IME_PINYIN_K9_CAND_TEXT_NUM + 1], "\0");
+
+ // next page
+ if(dir == 1) {
+ count = 0;
+ while(ll_index) {
+ if(count >= (LV_IME_PINYIN_K9_CAND_TEXT_NUM - 1))
+ break;
+
+ strcpy(lv_pinyin_k9_cand_str[count], ll_index->py_str);
+ ll_index = _lv_ll_get_next(&pinyin_ime->k9_legal_py_ll, ll_index); /*Find the next list*/
+ count++;
+ }
+ pinyin_ime->k9_py_ll_pos += count - 1;
+
+ }
+ // previous page
+ else {
+ count = LV_IME_PINYIN_K9_CAND_TEXT_NUM - 1;
+ ll_index = _lv_ll_get_prev(&pinyin_ime->k9_legal_py_ll, ll_index);
+ while(ll_index) {
+ if(count < 0) break;
+
+ strcpy(lv_pinyin_k9_cand_str[count], ll_index->py_str);
+ ll_index = _lv_ll_get_prev(&pinyin_ime->k9_legal_py_ll, ll_index); /*Find the previous list*/
+ count--;
+ }
+
+ if(pinyin_ime->k9_py_ll_pos > LV_IME_PINYIN_K9_CAND_TEXT_NUM)
+ pinyin_ime->k9_py_ll_pos -= 1;
+ }
+
+ lv_textarea_set_cursor_pos(ta, LV_TEXTAREA_CURSOR_LAST);
+ }
+}
+
+#endif /*LV_IME_PINYIN_USE_K9_MODE*/
#endif /*LV_USE_IME_PINYIN*/
+
diff --git a/src/extra/others/ime/lv_ime_pinyin.h b/src/extra/others/ime/lv_ime_pinyin.h
index 9d5c2bc66e..3ff7bb9800 100644
--- a/src/extra/others/ime/lv_ime_pinyin.h
+++ b/src/extra/others/ime/lv_ime_pinyin.h
@@ -19,29 +19,49 @@ extern "C" {
/*********************
* DEFINES
*********************/
+#define LV_IME_PINYIN_K9_MAX_INPUT 7
/**********************
* TYPEDEFS
**********************/
+
+typedef enum {
+ LV_IME_PINYIN_MODE_K26,
+ LV_IME_PINYIN_MODE_K9,
+} lv_ime_pinyin_mode_t;
+
+/*Data of pinyin_dict*/
typedef struct {
const char * const py;
const char * const py_mb;
} lv_pinyin_dict_t;
+/*Data of 9-key input(k9) mode*/
+typedef struct {
+ char py_str[7];
+} ime_pinyin_k9_py_str_t;
+
/*Data of lv_ime_pinyin*/
typedef struct {
lv_obj_t obj;
lv_obj_t * kb;
lv_obj_t * cand_panel;
lv_pinyin_dict_t * dict;
+ lv_ll_t k9_legal_py_ll;
char * cand_str; /* Candidate string */
- char * btnm_pinyin_sel[LV_IME_PINYIN_CAND_TEXT_NUM + 3];
- char input_char[16]; /* Input box character */
+ char input_char[16]; /* Input box character */
+#if LV_IME_PINYIN_USE_K9_MODE
+ char k9_input_str[LV_IME_PINYIN_K9_MAX_INPUT]; /* 9-key input(k9) mode input string */
+ uint16_t k9_py_ll_pos; /* Current pinyin map pages(k9) */
+ uint16_t k9_legal_py_count; /* Count of legal Pinyin numbers(k9) */
+ uint16_t k9_input_str_len; /* 9-key input(k9) mode input string max len */
+#endif
uint16_t ta_count; /* The number of characters entered in the text box this time */
uint16_t cand_num; /* Number of candidates */
- uint16_t py_page; /* Current pinyin map pages */
+ uint16_t py_page; /* Current pinyin map pages(k26) */
uint16_t py_num[26]; /* Number and length of Pinyin */
uint16_t py_pos[26]; /* Pinyin position */
+ uint8_t mode : 1; /* Set mode, 1: 26-key input(k26), 0: 9-key input(k9). Default: 1. */
} lv_ime_pinyin_t;
/***********************
@@ -71,6 +91,13 @@ void lv_ime_pinyin_set_keyboard(lv_obj_t * obj, lv_obj_t * kb);
*/
void lv_ime_pinyin_set_dict(lv_obj_t * obj, lv_pinyin_dict_t * dict);
+/**
+ * Set mode, 26-key input(k26) or 9-key input(k9).
+ * @param obj pointer to a Pinyin input method object
+ * @param mode the mode from 'lv_ime_pinyin_mode_t'
+ */
+void lv_ime_pinyin_set_mode(lv_obj_t * obj, lv_ime_pinyin_mode_t mode);
+
/*=====================
* Getter functions
@@ -115,3 +142,4 @@ lv_pinyin_dict_t * lv_ime_pinyin_get_dict(lv_obj_t * obj);
#endif /*LV_USE_IME_PINYIN*/
+
diff --git a/src/lv_conf_internal.h b/src/lv_conf_internal.h
index c2b4ccc561..97807fe378 100644
--- a/src/lv_conf_internal.h
+++ b/src/lv_conf_internal.h
@@ -2288,6 +2288,28 @@
#define LV_IME_PINYIN_CAND_TEXT_NUM 6
#endif
#endif
+
+ /*Use 9 key input(k9)*/
+ #ifndef LV_IME_PINYIN_USE_K9_MODE
+ #ifdef _LV_KCONFIG_PRESENT
+ #ifdef CONFIG_LV_IME_PINYIN_USE_K9_MODE
+ #define LV_IME_PINYIN_USE_K9_MODE CONFIG_LV_IME_PINYIN_USE_K9_MODE
+ #else
+ #define LV_IME_PINYIN_USE_K9_MODE 0
+ #endif
+ #else
+ #define LV_IME_PINYIN_USE_K9_MODE 1
+ #endif
+ #endif
+ #if LV_IME_PINYIN_USE_K9_MODE == 1
+ #ifndef LV_IME_PINYIN_K9_CAND_TEXT_NUM
+ #ifdef CONFIG_LV_IME_PINYIN_K9_CAND_TEXT_NUM
+ #define LV_IME_PINYIN_K9_CAND_TEXT_NUM CONFIG_LV_IME_PINYIN_K9_CAND_TEXT_NUM
+ #else
+ #define LV_IME_PINYIN_K9_CAND_TEXT_NUM 3
+ #endif
+ #endif
+ #endif // LV_IME_PINYIN_USE_K9_MODE
#endif
/*==================