mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-20 21:35:19 +08:00
feat(ime_pinyin): add API to use Pinyin IME(Chinese input) (#3408)
* feat(pinyin_ime): add API to use Pinyin IME(Chinese input) 1.Low resource usage 2.Support custom thesaurus 3.Support custom styles (Candidate panel, keyboard) 4.Support simple spelling * fix(ime_pinyin): fix several problems of ime_pinyin 1. Change lv_pinyin_ime to lv_ime_pinyin 2. Add lv_pinyin_ime_set_keyboard interface 3. Add lv_ime_pinyin configuration in Kconfig, src/lv_conf_internal.h * refactor(ime_pinyin): improve coding specification * feat(ime_pinyin): add simple Pinyin IME example * docs(ime_pinyin): Add ime_pinyin documentation * Delete settings.json * Update dictionary based on simsun * Delete lv_font_source_han_sans_normal_16.c * Update lv_example_ime_pinyin_1.c * Update ime_pinyin.md add Chinese translation document * Update lv_ime_pinyin.c * Update lv_ime_pinyin.c * Update lv_ime_pinyin.h * Update lv_ime_pinyin.c * Update lv_example_ime_pinyin_1.c * Update lv_conf_internal.h * Update lv_ime_pinyin.c * Update lv_ime_pinyin.c Co-authored-by: 100askTeam <team100ask@outlook.com>
This commit is contained in:
@@ -22,3 +22,6 @@ test_screenshot_error.h
|
||||
build/
|
||||
tests/build_*/
|
||||
tests/report/
|
||||
.DS_Store
|
||||
.vscode
|
||||
*.bak
|
||||
|
||||
@@ -1018,6 +1018,27 @@ menu "LVGL configuration"
|
||||
config LV_USE_IMGFONT
|
||||
bool "draw img in label or span obj"
|
||||
default n
|
||||
|
||||
config LV_USE_MSG
|
||||
bool "Enable a published subscriber based messaging system"
|
||||
default n
|
||||
|
||||
config LV_USE_IME_PINYIN
|
||||
bool "Enable Pinyin input method"
|
||||
default n
|
||||
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
|
||||
config LV_IME_PINYIN_CAND_TEXT_NUM
|
||||
int "maximum number of candidate panels"
|
||||
depends on LV_USE_IME_PINYIN
|
||||
default 6
|
||||
help
|
||||
Set the maximum number of candidate panels that can be displayed.
|
||||
This needs to be adjusted according to the size of the screen.
|
||||
endmenu
|
||||
|
||||
menu "Examples"
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
# 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.
|
||||
|
||||
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.
|
||||
|
||||
<details>
|
||||
<summary>中文</summary>
|
||||
<p>
|
||||
|
||||
`lv_ime_pinyin`为[键盘](/widgets/extra/keyboard)组件提供汉语拼音输入法(中文输入)的功能(后文简称为拼音输入法)。您可以将 `lv_ime_pinyin` 看成是键盘组件的汉语拼音输入法插件。
|
||||
|
||||
一般情况下,只要是[键盘](/widgets/extra/keyboard)组件能运行的环境 `lv_ime_pinyin` 也能运行。有两个影响因素:字库的大小和词库的大小。
|
||||
|
||||
</p>
|
||||
</details>
|
||||
|
||||
## Usage
|
||||
|
||||
Enable `LV_USE_IME_PINYIN` in `lv_conf.h`.
|
||||
|
||||
First use `lv_ime_pinyin_create(lv_scr_act())` to create a Pinyin input method plug-in, then use `lv_ime_pinyin_set_keyboard(pinyin_ime, kb)` to add the `keyboard` you created to the Pinyin input method plug-in.
|
||||
You can use `lv_ime_pinyin_set_dict(pinyin_ime, your_dict)` to use a custom dictionary (if you don't want to use the built-in dictionary at first, you can disable `LV_IME_PINYIN_USE_DEFAULT_DICT` in `lv_conf.h`, which can save a lot of memory space).
|
||||
|
||||
The built-in thesaurus is customized based on the **LV_FONT_SIMSUN_16_CJK** font library, which currently only has more than `1,000` most common CJK radicals, so it is recommended to use custom fonts and thesaurus.
|
||||
|
||||
In the process of using the Pinyin input method plug-in, you can change the keyboard and dictionary at any time.
|
||||
|
||||
<details>
|
||||
<summary>中文</summary>
|
||||
<p>
|
||||
|
||||
在 `lv_conf.h` 中打开 `LV_USE_IME_PINYIN`。
|
||||
|
||||
首先,使用 `lv_ime_pinyin_create(lv_scr_act())` 函数创建一个拼音输入法插件,
|
||||
然后使用 `lv_ime_pinyin_set_keyboard(pinyin_ime, kb)` 函数将您创建的键盘组件添加到插件中。
|
||||
|
||||
内置的词库是基于 LVGL 的 **LV_FONT_SIMSUN_16_CJK** 字库定制,这个字库目前只有 `1000` 多个最常见的 CJK 部首,所以建议使用自定义字库和词库。
|
||||
|
||||
您可以使用 `lv_ime_pinyin_set_dict(pinyin_ime, your_dict)` 函数来设置使用自定义的词库,如果您一开始就不打算使用内置的词库,建议您在 `lv_conf.h` 中将 `LV_IME_PINYIN_USE_DEFAULT_DICT` 关闭,这可以节省一些内存空间。
|
||||
|
||||
</p>
|
||||
</details>
|
||||
|
||||
## Custom dictionary
|
||||
|
||||
If you don't want to use the built-in Pinyin dictionary, you can use the custom dictionary.
|
||||
Or if you think that the built-in phonetic dictionary consumes a lot of memory, you can also use a custom dictionary.
|
||||
|
||||
Customizing the dictionary is very simple.
|
||||
|
||||
First, set `LV_IME_PINYIN_USE_DEFAULT_DICT` to `0` in `lv_conf.h`
|
||||
|
||||
Then, write a dictionary in the following format.
|
||||
|
||||
<details>
|
||||
<summary>中文</summary>
|
||||
<p>
|
||||
|
||||
如果您不想使用内置的词库,可以通过下面的方法自定义词库。
|
||||
|
||||
自定义词典非常简单。
|
||||
首先,在 `lv_conf.h` 将 `LV_IME_PINYIN_USE_DEFAULT_DICT` 设置为 0。
|
||||
然后按照下面的格式编写词库。
|
||||
|
||||
</p>
|
||||
</details>
|
||||
|
||||
### Dictionary format
|
||||
|
||||
The arrangement order of each pinyin syllable is very important. You need to customize your own thesaurus according to the Hanyu Pinyin syllable table. You can read [here](https://baike.baidu.com/item/%E6%B1%89%E8%AF%AD%E6%8B%BC%E9%9F%B3%E9%9F%B3%E8%8A%82/9167981) to learn about the Hanyu Pinyin syllables and the syllable table.
|
||||
|
||||
Then, write your own dictionary according to the following format:
|
||||
|
||||
<details>
|
||||
<summary>中文</summary>
|
||||
<p>
|
||||
|
||||
**注意**,各个拼音音节的排列顺序非常重要,您需要按照汉语拼音音节表定制自己的词库,可以阅读[这里](https://baike.baidu.com/item/%E6%B1%89%E8%AF%AD%E6%8B%BC%E9%9F%B3%E9%9F%B3%E8%8A%82/9167981)了解[汉语拼音音节](https://baike.baidu.com/item/%E6%B1%89%E8%AF%AD%E6%8B%BC%E9%9F%B3%E9%9F%B3%E8%8A%82/9167981)以及[音节表](https://baike.baidu.com/item/%E6%B1%89%E8%AF%AD%E6%8B%BC%E9%9F%B3%E9%9F%B3%E8%8A%82/9167981#1)。
|
||||
|
||||
然后,根据下面的格式编写自己的词库:
|
||||
|
||||
</p>
|
||||
</details>
|
||||
|
||||
```c
|
||||
lv_100ask_pinyin_dict_t your_pinyin_dict[] = {
|
||||
{ "a", "啊阿呵吖" },
|
||||
{ "ai", "埃挨哎唉哀皑蔼矮碍爱隘癌艾" },
|
||||
{ "an", "按安暗岸俺案鞍氨胺厂广庵揞犴铵桉谙鹌埯黯" },
|
||||
{ "ang", "昂肮盎仰" },
|
||||
{ "ao", "凹敖熬翱袄傲奥懊澳" },
|
||||
{ "ba", "芭捌叭吧笆八疤巴拔跋靶把坝霸罢爸扒耙" },
|
||||
{ "bai", "白摆佰败拜柏百稗伯" },
|
||||
/* ...... */
|
||||
{ "zuo", "昨左佐做作坐座撮琢柞"},
|
||||
{NULL, NULL}
|
||||
|
||||
```
|
||||
|
||||
**The last item** must end with `{null, null}` , or it will not work properly.
|
||||
|
||||
### Apply new dictionary
|
||||
|
||||
After writing a dictionary according to the above dictionary format, you only need to call this function to set up and use your dictionary:
|
||||
|
||||
<details>
|
||||
<summary>中文</summary>
|
||||
<p>
|
||||
|
||||
按照上面的词库格式编写好自己的词库之后,参考下面的用法,调用 `lv_100ask_pinyin_ime_set_dict(pinyin_ime, your_pinyin_dict)` 函数即可设置和使用新词库:
|
||||
|
||||
</p>
|
||||
</details>
|
||||
|
||||
```c
|
||||
lv_obj_t * pinyin_ime = lv_100ask_pinyin_ime_create(lv_scr_act());
|
||||
lv_100ask_pinyin_ime_set_dict(pinyin_ime, your_pinyin_dict);
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. include:: ../../examples/others/ime/index.rst
|
||||
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
```eval_rst
|
||||
|
||||
.. doxygenfile:: lv_ime_pinyin.h
|
||||
:project: lvgl
|
||||
|
||||
```
|
||||
@@ -12,5 +12,6 @@
|
||||
fragment
|
||||
msg
|
||||
imgfont
|
||||
ime_pinyin
|
||||
```
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
Simple Pinyin IME example
|
||||
"""""""""""""""""""
|
||||
|
||||
.. lv_example:: others/ime/lv_example_ime_pinyin_1
|
||||
:language: c
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* @file lv_example_ime_pinyin.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_EX_IME_PINYIN_H
|
||||
#define LV_EX_IME_PINYIN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
void lv_example_ime_pinyin_1(void);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_EX_IME_PINYIN_H*/
|
||||
@@ -0,0 +1,56 @@
|
||||
#include "../../lv_examples.h"
|
||||
#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)
|
||||
{
|
||||
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 || 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*/
|
||||
}
|
||||
}
|
||||
|
||||
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_obj_t * kb = lv_keyboard_create(lv_scr_act());
|
||||
lv_ime_pinyin_set_keyboard(pinyin_ime, kb);
|
||||
|
||||
/* ta1 */
|
||||
lv_obj_t * ta1 = lv_textarea_create(lv_scr_act());
|
||||
lv_obj_set_style_text_font(ta1, &lv_font_simsun_16_cjk, 0);
|
||||
lv_obj_align(ta1, LV_ALIGN_TOP_LEFT, 10, 10);
|
||||
|
||||
lv_keyboard_set_textarea(kb, ta1);
|
||||
|
||||
lv_obj_add_event_cb(ta1, ta_event_cb, LV_EVENT_ALL, kb);
|
||||
|
||||
/* ta2 */
|
||||
lv_obj_t * ta2 = lv_textarea_create(lv_scr_act());
|
||||
lv_obj_set_style_text_font(ta2, &lv_font_simsun_16_cjk, 0);
|
||||
lv_obj_align_to(ta2, ta1, LV_ALIGN_OUT_RIGHT_MID, 10, 0);
|
||||
|
||||
lv_obj_add_event_cb(ta2, ta_event_cb, LV_EVENT_ALL, kb);
|
||||
|
||||
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, 5, 5);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -19,6 +19,7 @@ extern "C" {
|
||||
#include "fragment/lv_example_fragment.h"
|
||||
#include "imgfont/lv_example_imgfont.h"
|
||||
#include "msg/lv_example_msg.h"
|
||||
#include "ime/lv_example_ime_pinyin.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
|
||||
@@ -691,6 +691,18 @@
|
||||
/*1: Enable a published subscriber based messaging system */
|
||||
#define LV_USE_MSG 0
|
||||
|
||||
/*1: Enable Pinyin input method*/
|
||||
/*Requires: lv_keyboard*/
|
||||
#define LV_USE_IME_PINYIN 0
|
||||
#if LV_USE_IME_PINYIN
|
||||
/*1: Use default thesaurus*/
|
||||
/*If you do not use the default thesaurus, be sure to use `lv_ime_pinyin` after setting the thesauruss*/
|
||||
#define LV_IME_PINYIN_USE_DEFAULT_DICT 1
|
||||
/*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
|
||||
#endif
|
||||
|
||||
/*==================
|
||||
* EXAMPLES
|
||||
*==================*/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,117 @@
|
||||
/**
|
||||
* @file lv_ime_pinyin.h
|
||||
*
|
||||
*/
|
||||
#ifndef LV_IME_PINYIN_H
|
||||
#define LV_IME_PINYIN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../../../lvgl.h"
|
||||
|
||||
#if LV_USE_IME_PINYIN != 0
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
typedef struct {
|
||||
const char * const py;
|
||||
const char * const py_mb;
|
||||
} lv_pinyin_dict_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;
|
||||
char * cand_str; /* Candidate string */
|
||||
char * btnm_pinyin_sel[LV_IME_PINYIN_CAND_TEXT_NUM + 3];
|
||||
char input_char[16]; /* Input box character */
|
||||
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_num[26]; /* Number and length of Pinyin */
|
||||
uint16_t py_pos[26]; /* Pinyin position */
|
||||
} lv_ime_pinyin_t;
|
||||
|
||||
/***********************
|
||||
* GLOBAL VARIABLES
|
||||
***********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
lv_obj_t * lv_ime_pinyin_create(lv_obj_t * parent);
|
||||
|
||||
/*=====================
|
||||
* Setter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Set the keyboard of Pinyin input method.
|
||||
* @param obj pointer to a Pinyin input method object
|
||||
* @param dict pointer to a Pinyin input method keyboard
|
||||
*/
|
||||
void lv_ime_pinyin_set_keyboard(lv_obj_t * obj, lv_obj_t * kb);
|
||||
|
||||
/**
|
||||
* Set the dictionary of Pinyin input method.
|
||||
* @param obj pointer to a Pinyin input method object
|
||||
* @param dict pointer to a Pinyin input method dictionary
|
||||
*/
|
||||
void lv_ime_pinyin_set_dict(lv_obj_t * obj, lv_pinyin_dict_t * dict);
|
||||
|
||||
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
||||
/**
|
||||
* Set the dictionary of Pinyin input method.
|
||||
* @param obj pointer to a Pinyin IME object
|
||||
* @return pointer to the Pinyin IME keyboard
|
||||
*/
|
||||
lv_obj_t * lv_ime_pinyin_get_kb(lv_obj_t * obj);
|
||||
|
||||
|
||||
/**
|
||||
* Set the dictionary of Pinyin input method.
|
||||
* @param obj pointer to a Pinyin input method object
|
||||
* @return pointer to the Pinyin input method candidate panel
|
||||
*/
|
||||
lv_obj_t * lv_ime_pinyin_get_cand_panel(lv_obj_t * obj);
|
||||
|
||||
|
||||
/**
|
||||
* Set the dictionary of Pinyin input method.
|
||||
* @param obj pointer to a Pinyin input method object
|
||||
* @return pointer to the Pinyin input method dictionary
|
||||
*/
|
||||
lv_pinyin_dict_t * lv_ime_pinyin_get_dict(lv_obj_t * obj);
|
||||
|
||||
/*=====================
|
||||
* Other functions
|
||||
*====================*/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_IME_PINYIN*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_USE_IME_PINYIN*/
|
||||
|
||||
@@ -19,6 +19,7 @@ extern "C" {
|
||||
#include "fragment/lv_fragment.h"
|
||||
#include "imgfont/lv_imgfont.h"
|
||||
#include "msg/lv_msg.h"
|
||||
#include "ime/lv_ime_pinyin.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
|
||||
@@ -2243,6 +2243,40 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*1: Enable Pinyin input method*/
|
||||
/*Requires: lv_keyboard*/
|
||||
#ifndef LV_USE_IME_PINYIN
|
||||
#ifdef CONFIG_LV_USE_IME_PINYIN
|
||||
#define LV_USE_IME_PINYIN CONFIG_LV_USE_IME_PINYIN
|
||||
#else
|
||||
#define LV_USE_IME_PINYIN 0
|
||||
#endif
|
||||
#endif
|
||||
#if LV_USE_IME_PINYIN
|
||||
/*1: Use default thesaurus*/
|
||||
/*If you do not use the default thesaurus, be sure to use `lv_ime_pinyin` after setting the thesauruss*/
|
||||
#ifndef LV_IME_PINYIN_USE_DEFAULT_DICT
|
||||
#ifdef _LV_KCONFIG_PRESENT
|
||||
#ifdef CONFIG_LV_IME_PINYIN_USE_DEFAULT_DICT
|
||||
#define LV_IME_PINYIN_USE_DEFAULT_DICT CONFIG_LV_IME_PINYIN_USE_DEFAULT_DICT
|
||||
#else
|
||||
#define LV_IME_PINYIN_USE_DEFAULT_DICT 0
|
||||
#endif
|
||||
#else
|
||||
#define LV_IME_PINYIN_USE_DEFAULT_DICT 1
|
||||
#endif
|
||||
#endif
|
||||
/*Set the maximum number of candidate panels that can be displayed*/
|
||||
/*This needs to be adjusted according to the size of the screen*/
|
||||
#ifndef LV_IME_PINYIN_CAND_TEXT_NUM
|
||||
#ifdef CONFIG_LV_IME_PINYIN_CAND_TEXT_NUM
|
||||
#define LV_IME_PINYIN_CAND_TEXT_NUM CONFIG_LV_IME_PINYIN_CAND_TEXT_NUM
|
||||
#else
|
||||
#define LV_IME_PINYIN_CAND_TEXT_NUM 6
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*==================
|
||||
* EXAMPLES
|
||||
*==================*/
|
||||
|
||||
Reference in New Issue
Block a user