当前位置: 首页 > news >正文

LVGL拼音输入法优化(无bug)

一、LVGL8.3的拼音输入法优化

lv_ime_pinyin.c

/*** @file lv_ime_pinyin.c* @author Jaychen (719095404@qq.com)* @brief * @version 0.1* @date 2025-08-17* * @copyright Copyright (c) 2025* */
/**********************      INCLUDES*********************/
#include "lv_ime_pinyin.h"
#if LV_USE_IME_PINYIN != 0#include <stdio.h>/**********************      DEFINES*********************/
#define MY_CLASS    &lv_ime_pinyin_class/***********************      TYPEDEFS**********************//***********************  STATIC PROTOTYPES**********************/
static void lv_ime_pinyin_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
static void lv_ime_pinyin_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
static void lv_ime_pinyin_style_change_event(lv_event_t * e);
static void lv_ime_pinyin_kb_event(lv_event_t * e);
static void lv_ime_pinyin_cand_panel_event(lv_event_t * e);
static void pinyin_ime_clear_data(lv_obj_t * obj);
static void init_pinyin_dict(lv_obj_t * obj, const lv_pinyin_dict_t * dict);
static int 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 * py_str, uint16_t * cand_num);#if LV_IME_PINYIN_USE_K9_MODEstatic 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**********************/
const lv_obj_class_t lv_ime_pinyin_class = {.constructor_cb = lv_ime_pinyin_constructor,.destructor_cb  = lv_ime_pinyin_destructor,.width_def      = LV_SIZE_CONTENT,.height_def     = LV_SIZE_CONTENT,.group_def      = LV_OBJ_CLASS_GROUP_DEF_TRUE,.instance_size  = sizeof(lv_ime_pinyin_t),.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 + 1] = {",", "123",  "abc", "def",  LV_SYMBOL_BACKSPACE, "\n",".", "ghi", "jkl", "mno",  LV_SYMBOL_KEYBOARD, "\n","?", "pqrs", "tuv", "wxyz",  LV_SYMBOL_NEW_LINE, "\n",LV_SYMBOL_LEFT, ""};static lv_btnmatrix_ctrl_t default_kb_ctrl_k9_map[LV_IME_PINYIN_K9_CAND_TEXT_NUM + 16 + 1] = { 1 };
static char   lv_pinyin_k9_cand_str[LV_IME_PINYIN_K9_CAND_TEXT_NUM + 2][LV_IME_PINYIN_K9_MAX_INPUT] = {0};
#endifstatic 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];static const char * kb_26_ch_lower_map[] = {"1#", "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", LV_SYMBOL_BACKSPACE, "\n","abc", "a", "s", "d", "f", "g", "h", "j", "k", "l", LV_SYMBOL_NEW_LINE, "\n","_", "-", "z", "x", "c", "v", "b", "n", "m", ".", ",", ":", "\n",LV_SYMBOL_KEYBOARD, LV_SYMBOL_LEFT, " ", "Ch", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, ""
};static const char * kb_26_en_lower_map[] = {"1#", "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", LV_SYMBOL_BACKSPACE, "\n","abc", "a", "s", "d", "f", "g", "h", "j", "k", "l", LV_SYMBOL_NEW_LINE, "\n","_", "-", "z", "x", "c", "v", "b", "n", "m", ".", ",", ":", "\n",LV_SYMBOL_KEYBOARD, LV_SYMBOL_LEFT, " ", "En", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, ""
};static const char * kb_26_en_upper_map[] = {"1#", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", LV_SYMBOL_BACKSPACE, "\n","ABC", "A", "S", "D", "F", "G", "H", "J", "K", "L", LV_SYMBOL_NEW_LINE, "\n","_", "-", "Z", "X", "C", "V", "B", "N", "M", ".", ",", ":", "\n",LV_SYMBOL_KEYBOARD, LV_SYMBOL_LEFT, " ", "En", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, ""
};static const lv_btnmatrix_ctrl_t kb_26_ctrl[] = {LV_KEYBOARD_CTRL_BTN_FLAGS | 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, LV_BTNMATRIX_CTRL_CHECKED | 1,LV_KEYBOARD_CTRL_BTN_FLAGS | 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, LV_KEYBOARD_CTRL_BTN_FLAGS | 2,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,LV_KEYBOARD_CTRL_BTN_FLAGS | 2, LV_KEYBOARD_CTRL_BTN_FLAGS | 2, 6, LV_KEYBOARD_CTRL_BTN_FLAGS | 2, LV_KEYBOARD_CTRL_BTN_FLAGS | 2, LV_KEYBOARD_CTRL_BTN_FLAGS | 2
};#if LV_IME_PINYIN_USE_DEFAULT_DICT
lv_pinyin_dict_t lv_ime_pinyin_def_dict[] = {{ "a", "啊" },{ "ai", "愛" },{ "an", "安暗案" },{ "ba", "吧把爸八" },{ "bai", "百白敗" },{ "ban", "半般辦" },{ "bang", "旁" },{ "bao", "保薄包報" },{ "bei", "被背悲北杯備" },{ "ben", "本" },{ "bi", "必比避鼻彼筆秘閉" },{ "bian", "便邊變変辺" },{ "biao", "表標" },{ "bie", "別" },{ "bing", "病並氷" },{ "bo", "波薄泊" },{ "bu", "不布步部捕補歩" },{ "ca", "察" },{ "cai", "才材菜財採" },{ "can", "参残參" },{ "ce", "策側" },{ "ceng", "曾" },{ "cha", "差查茶" },{ "chai", "差" },{ "chan", "產産單" },{ "chang", "場廠" },{ "chao", "超朝" },{ "che", "車" },{ "cheng", "成程乗" },{ "chi", "尺吃持赤池遅歯" },{ "chong", "充种重種" },{ "chu", "出初楚触處処" },{ "chuan", "川船傳" },{ "chuang", "創窓" },{ "chun", "春" },{ "ci", "此次辞差" },{ "cong", "從従" },{ "cu", "卒" },{ "cun", "存村" },{ "cuo", "錯" },{ "da", "大打答達" },{ "dai", "代待帯帶貸" },{ "dan", "但担擔誕單単" },{ "dang", "当党當黨" },{ "dao", "到道盗導島辺" },{ "de", "的得" },{ "dei", "得" },{ "deng", "等" },{ "di", "地得低底弟第締" },{ "dian", "点电店點電" },{ "diao", "調" },{ "ding", "定町" },{ "dong", "冬東動働凍" },{ "du", "独度都渡読" },{ "duan", "段断短斷" },{ "dui", "對対" },{ "duo", "多駄" },{ "e", "嗯悪" },{ "en", "嗯" },{ "er", "而耳二兒" },{ "fa", "乏法發発髪" },{ "fan", "反返犯番仮販飯範払" },{ "fang", "方放房坊訪" },{ "fei", "非飛費" },{ "fen", "分份" },{ "feng", "風豐" },{ "fou", "否不" },{ "fu", "父夫富服符付附府幅婦復複負払" },{ "gai", "改概該" },{ "gan", "甘感敢" },{ "gang", "港剛" },{ "gao", "告高" },{ "ge", "各格歌革割個" },{ "gei", "給" },{ "gen", "跟根" },{ "geng", "更" },{ "gong", "工共供功公" },{ "gou", "夠構溝" },{ "gu", "古故鼓" },{ "guai", "掛" },{ "guan", "官管慣館觀関關" },{ "guang", "光広" },{ "gui", "規帰" },{ "guo", "果国裏菓國過" },{ "hai", "孩海害還" },{ "han", "寒漢" },{ "hang", "航行" },{ "hao", "好号" },{ "he", "合和喝何荷" },{ "hei", "黒" },{ "hen", "很" },{ "heng", "行横" },{ "hou", "厚喉候後" },{ "hu", "乎呼湖護" },{ "hua", "化画花話畫劃" },{ "huai", "壊劃" },{ "huan", "緩環歡還換" },{ "huang", "黄" },{ "hui", "回会慧絵揮會" },{ "hun", "混婚" },{ "huo", "活或火獲" },{ "i", "" },{ "ji", "机己计及既急季寄技即集基祭系奇紀積計記済幾際極繼績機濟" },{ "jia", "家加價" },{ "jian", "件建健肩見減間検簡漸" },{ "jiang", "降強講將港" },{ "jiao", "叫教交角覚覺較學" },{ "jie", "介借接姐皆届界解結階節價" },{ "jin", "今近禁金僅進" },{ "jing", "京境景静精經経" },{ "jiu", "就久九酒究" },{ "ju", "句具局居決挙據舉" },{ "jue", "角覚覺" },{ "jun", "均" },{ "kai", "開" },{ "kan", "看刊" },{ "kang", "康" },{ "kao", "考" },{ "ke", "可刻科克客渇課" },{ "ken", "肯" },{ "kong", "空控" },{ "kou", "口" },{ "ku", "苦庫" },{ "kuai", "快塊会會" },{ "kuang", "況" },{ "kun", "困" },{ "kuo", "括拡適" },{ "la", "拉啦落" },{ "lai", "来來頼" },{ "lao", "老絡落" },{ "le", "了楽樂" },{ "lei", "類" },{ "leng", "冷" },{ "li", "力立利理例礼離麗裡勵歷" },{ "lian", "連練臉聯" },{ "liang", "良量涼兩両" },{ "liao", "料" },{ "lie", "列" },{ "lin", "林隣賃" },{ "ling", "另令領" },{ "liu", "六留流" },{ "lu", "律路録緑陸履慮" },{ "lv", "旅" },{ "lun", "輪論" },{ "luo", "落絡" },{ "ma", "媽嗎嘛" },{ "mai", "買売" },{ "man", "滿" },{ "mang", "忙" },{ "mao", "毛猫貿" },{ "me", "麼" },{ "mei", "美妹每沒毎媒" },{ "men", "們" },{ "mi", "米密秘" },{ "mian", "免面勉眠" },{ "miao", "描" },{ "min", "民皿" },{ "ming", "命明名" },{ "mo", "末模麼" },{ "mou", "某" },{ "mu", "母木目模" },{ "na", "那哪拿內南" },{ "nan", "男南難" },{ "nao", "腦" },{ "ne", "那哪呢" },{ "nei", "内那哪內" },{ "neng", "能" },{ "ni", "你妳呢" },{ "nian", "年念" },{ "niang", "娘" },{ "nin", "您" },{ "ning", "凝" },{ "niu", "牛" },{ "nong", "農濃" },{ "nu", "女努" },{ "nuan", "暖" },{ "o", "歐" },{ "ou", "歐" },{ "pa", "怕" },{ "pian", "片便" },{ "pai", "迫派排" },{ "pan", "判番" },{ "pang", "旁" },{ "pei", "配" },{ "peng", "朋" },{ "pi", "疲否" },{ "pin", "品貧" },{ "ping", "平評" },{ "po", "迫破泊頗" },{ "pu", "普僕" },{ "qi", "起其奇七气期泣企妻契気" },{ "qian", "嵌浅千前鉛錢針" },{ "qiang", "強將" },{ "qiao", "橋繰" },{ "qie", "且切契" },{ "qin", "寝勤親" },{ "qing", "青清情晴輕頃請軽" },{ "qiu", "求秋球" },{ "qu", "去取趣曲區" },{ "quan", "全犬券" },{ "que", "缺確卻" },{ "ran", "然" },{ "rang", "讓" },{ "re", "熱" },{ "ren", "人任認" },{ "reng", "仍" },{ "ri", "日" },{ "rong", "容" },{ "rou", "弱若肉" },{ "ru", "如入" },{ "ruan", "軟" },{ "sai", "賽" },{ "san", "三" },{ "sao", "騒繰" },{ "se", "色" },{ "sen", "森" },{ "sha", "砂" },{ "shan", "善山單" },{ "shang", "上尚商" },{ "shao", "少紹" },{ "shaung", "雙" },{ "she", "社射設捨渉" },{ "shei", "誰" },{ "shen", "什申深甚身伸沈神" },{ "sheng", "生声昇勝乗聲" },{ "shi", "是失示食时事式十石施使世实史室市始柿氏士仕拭時視師試適実實識" },{ "shou", "手首守受授" },{ "shu", "束数暑殊樹書屬輸術" },{ "shui", "水説說誰" },{ "shuo", "数説說" },{ "si", "思寺司四私似死価" },{ "song", "送" },{ "su", "速宿素蘇訴" },{ "suan", "算酸" },{ "sui", "隨雖歲歳" },{ "sun", "孫" },{ "suo", "所" },{ "ta", "她他它牠" },{ "tai", "太台態臺" },{ "tan", "探談曇" },{ "tang", "糖" },{ "tao", "桃逃套討" },{ "te", "特" },{ "ti", "体提替題體戻" },{ "tian", "天田" },{ "tiao", "条條調" },{ "tie", "鉄" },{ "ting", "停庭聽町" },{ "tong", "同童通痛统統" },{ "tou", "投透頭" },{ "tu", "土徒茶図" },{ "tuan", "團" },{ "tui", "推退" },{ "tuo", "脱駄" },{ "u", "" },{ "v", "" },{ "wai", "外" },{ "wan", "完万玩晩腕灣" },{ "wang", "忘望亡往網" },{ "wei", "危位未味委為謂維違圍" },{ "wen", "文温問聞" },{ "wo", "我" },{ "wu", "午物五無屋亡鳥務汚" },{ "xi", "夕息西洗喜系昔席希析嬉膝細習係" },{ "xia", "下夏狭暇" },{ "xian", "先限嫌洗現見線顯" },{ "xiang", "向相香像想象降項詳響" },{ "xiao", "小笑消效校削咲" },{ "xie", "写携些解邪械協謝寫契" },{ "xin", "心信新辛" },{ "xing", "行形性幸型星興" },{ "xiong", "兄胸" },{ "xiu", "休秀修" },{ "xu", "須需許續緒続" },{ "xuan", "選懸" },{ "xue", "学雪削靴學" },{ "xun", "訓訊" },{ "ya", "呀押壓" },{ "yan", "言顔研煙嚴厳験驗塩" },{ "yang", "央洋陽樣様" },{ "yao", "要揺腰薬曜" },{ "ye", "也野夜邪業葉" },{ "yi", "一已亦依以移意医易伊役異億義議藝醫訳" },{ "yin", "因引音飲銀" },{ "ying", "英迎影映應營営" },{ "yong", "永用泳擁" },{ "you", "又有右友由尤油遊郵誘優" },{ "yu", "予育余雨浴欲愈御宇域語於魚與込" },{ "yuan", "元原源院員円園遠猿願" },{ "yue", "月越約楽" },{ "yun", "雲伝運" },{ "za", "雑" },{ "zai", "在再載災" },{ "zang", "蔵" },{ "zao", "早造" },{ "ze", "則擇責" },{ "zen", "怎" },{ "zeng", "曾增増" },{ "zha", "札" },{ "zhai", "宅擇" },{ "zhan", "站展戰戦" },{ "zhang", "丈長障帳張" },{ "zhao", "找着朝招" },{ "zhe", "者這" },{ "zhen", "真震針" },{ "zheng", "正整争政爭" },{ "zhi", "之只知支止制至治直指值置智値紙製質誌織隻識職執" },{ "zhong", "中种終重種眾" },{ "zhou", "周州昼宙洲週" },{ "zhu", "助主住柱株祝逐注著諸屬術" },{ "zhuan", "专專転" },{ "zhuang", "状狀" },{ "zhui", "追" },{ "zhun", "準" },{ "zhuo", "着" },{ "zi", "子自字姉資" },{ "zong", "總" },{ "zuo", "左做昨坐座作" },{ "zu", "足祖族卒組" },{ "zui", "最酔" },{ "zou", "走" },{NULL, NULL}
};
#endif/***********************      MACROS**********************//***********************   GLOBAL FUNCTIONS**********************/
lv_obj_t * lv_ime_pinyin_create(lv_obj_t * parent)
{LV_LOG_INFO("begin");lv_obj_t * obj = lv_obj_class_create_obj(MY_CLASS, parent);lv_obj_class_init_obj(obj);return obj;
}/*=====================* 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)
{if(kb) {LV_ASSERT_OBJ(kb, &lv_keyboard_class);}LV_ASSERT_OBJ(obj, MY_CLASS);lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;pinyin_ime->kb = kb;lv_obj_set_parent(obj, lv_obj_get_parent(kb));lv_obj_set_parent(pinyin_ime->cand_panel, lv_obj_get_parent(kb));/*************add by Jaychen****************** */lv_ime_pinyin_set_mode((lv_obj_t *)pinyin_ime, LV_IME_PINYIN_MODE_K26_CH);/******************************* */lv_obj_remove_event_cb(pinyin_ime->kb, lv_keyboard_def_event_cb);lv_obj_add_event_cb(pinyin_ime->kb, lv_ime_pinyin_kb_event, LV_EVENT_VALUE_CHANGED, obj);lv_obj_align_to(pinyin_ime->cand_panel, pinyin_ime->kb, LV_ALIGN_OUT_TOP_MID, 0, 0);
}/*** 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)
{LV_ASSERT_OBJ(obj, MY_CLASS);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)
{static uint8_t K26_mode = LV_KEYBOARD_MODE_TEXT_LOWER;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;switch(mode) {case LV_IME_PINYIN_MODE_K26_CH:lv_keyboard_set_map(pinyin_ime->kb, LV_KEYBOARD_MODE_TEXT_LOWER, kb_26_ch_lower_map, kb_26_ctrl);lv_keyboard_set_mode(pinyin_ime->kb, LV_KEYBOARD_MODE_TEXT_LOWER);K26_mode = LV_KEYBOARD_MODE_TEXT_LOWER;break;case LV_IME_PINYIN_MODE_K26_EN:lv_keyboard_set_map(pinyin_ime->kb, LV_KEYBOARD_MODE_TEXT_LOWER, kb_26_en_lower_map, kb_26_ctrl);lv_keyboard_set_map(pinyin_ime->kb, LV_KEYBOARD_MODE_TEXT_UPPER, kb_26_en_upper_map, kb_26_ctrl);if (K26_mode == LV_KEYBOARD_MODE_TEXT_LOWER) {lv_keyboard_set_mode(pinyin_ime->kb, LV_KEYBOARD_MODE_TEXT_LOWER);}else {lv_keyboard_set_mode(pinyin_ime->kb, LV_KEYBOARD_MODE_TEXT_UPPER);}break;case LV_IME_PINYIN_NODE_K26_SPECIAL:K26_mode = lv_keyboard_get_mode(pinyin_ime->kb);lv_keyboard_set_mode(pinyin_ime->kb, LV_KEYBOARD_MODE_SPECIAL);break;
#if LV_IME_PINYIN_USE_K9_MODEcase LV_IME_PINYIN_MODE_K9_CH: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,default_kb_ctrl_k9_map);lv_keyboard_set_mode(pinyin_ime->kb, LV_KEYBOARD_MODE_USER_1);break;case LV_IME_PINYIN_MODE_K9_NUMBER:lv_keyboard_set_mode(pinyin_ime->kb, LV_KEYBOARD_MODE_NUMBER);break;
#endif}
}/*=====================* 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)
{LV_ASSERT_OBJ(obj, MY_CLASS);lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;return pinyin_ime->kb;
}/*** 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)
{LV_ASSERT_OBJ(obj, MY_CLASS);lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;return pinyin_ime->cand_panel;
}/*** Set the dictionary of Pinyin input method.* @param obj  pointer to a Pinyin input method object* @return     pointer to the Pinyin input method dictionary*/
const lv_pinyin_dict_t * lv_ime_pinyin_get_dict(lv_obj_t * obj)
{LV_ASSERT_OBJ(obj, MY_CLASS);lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;return pinyin_ime->dict;
}/*** @brief Hide pinyin input method.* * @param pinyin_ime */
void lv_ime_pinyin_hide(lv_obj_t *pinyin_ime) 
{lv_obj_t *kb = lv_ime_pinyin_get_kb(pinyin_ime);pinyin_ime_clear_data(pinyin_ime); lv_obj_add_flag(kb, LV_OBJ_FLAG_HIDDEN); 
}/*** @brief Show pinyin input method.* * @param pinyin_ime */
void lv_ime_pinyin_show(lv_obj_t *pinyin_ime) 
{lv_obj_t *kb = lv_ime_pinyin_get_kb(pinyin_ime);pinyin_ime_clear_data(pinyin_ime);lv_obj_clear_flag(kb, LV_OBJ_FLAG_HIDDEN);
}/*=====================* Other functions*====================*//***********************   STATIC FUNCTIONS**********************/static void lv_ime_pinyin_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
{LV_UNUSED(class_p);LV_TRACE_OBJ_CREATE("begin");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 = 0; btnm_i < (LV_IME_PINYIN_CAND_TEXT_NUM + 3); btnm_i++) {if(btnm_i == 0) {lv_btnm_def_pinyin_sel_map[btnm_i] = "<";}else if(btnm_i == (LV_IME_PINYIN_CAND_TEXT_NUM + 1)) {lv_btnm_def_pinyin_sel_map[btnm_i] = ">";}else if(btnm_i == (LV_IME_PINYIN_CAND_TEXT_NUM + 2)) {lv_btnm_def_pinyin_sel_map[btnm_i] = "";}else {lv_pinyin_cand_str[py_str_i][0] = ' ';lv_btnm_def_pinyin_sel_map[btnm_i] = lv_pinyin_cand_str[py_str_i];py_str_i++;}}pinyin_ime->mode = LV_IME_PINYIN_MODE_K26_CH;pinyin_ime->py_page = 0;pinyin_ime->ta_count = 0;pinyin_ime->cand_num = 0;lv_memset_00(pinyin_ime->input_char, sizeof(pinyin_ime->input_char));lv_memset_00(pinyin_ime->py_num, sizeof(pinyin_ime->py_num));lv_memset_00(pinyin_ime->py_pos, sizeof(pinyin_ime->py_pos));lv_obj_add_flag(obj, LV_OBJ_FLAG_HIDDEN);#if LV_IME_PINYIN_USE_DEFAULT_DICTinit_pinyin_dict(obj, lv_ime_pinyin_def_dict);
#endif/* Init pinyin_ime->cand_panel */pinyin_ime->cand_panel = lv_btnmatrix_create(lv_scr_act());lv_btnmatrix_set_map(pinyin_ime->cand_panel, (const char **)lv_btnm_def_pinyin_sel_map);lv_obj_set_size(pinyin_ime->cand_panel, LV_PCT(100), LV_PCT(5));lv_obj_add_flag(pinyin_ime->cand_panel, LV_OBJ_FLAG_HIDDEN);lv_btnmatrix_set_one_checked(pinyin_ime->cand_panel, true);lv_obj_clear_flag(pinyin_ime->cand_panel, LV_OBJ_FLAG_CLICK_FOCUSABLE);/* Set cand_panel style*/// Default stylelv_obj_set_style_bg_opa(pinyin_ime->cand_panel, LV_OPA_50, 0);                     lv_obj_set_style_bg_color(pinyin_ime->cand_panel, lv_color_make(230, 230, 230), 0); lv_obj_set_style_border_width(pinyin_ime->cand_panel, 0, 0);lv_obj_set_style_pad_all(pinyin_ime->cand_panel, 8, 0);lv_obj_set_style_pad_gap(pinyin_ime->cand_panel, 0, 0);lv_obj_set_style_radius(pinyin_ime->cand_panel, 0, 0);lv_obj_set_style_pad_gap(pinyin_ime->cand_panel, 0, 0);lv_obj_set_style_base_dir(pinyin_ime->cand_panel, LV_BASE_DIR_LTR, 0);// LV_PART_ITEMS stylelv_obj_set_style_radius(pinyin_ime->cand_panel, 12, LV_PART_ITEMS);lv_obj_set_style_bg_color(pinyin_ime->cand_panel, lv_color_white(), LV_PART_ITEMS);lv_obj_set_style_bg_opa(pinyin_ime->cand_panel, LV_OPA_0, LV_PART_ITEMS);lv_obj_set_style_shadow_opa(pinyin_ime->cand_panel, LV_OPA_0, LV_PART_ITEMS);// LV_PART_ITEMS | LV_STATE_PRESSED stylelv_obj_set_style_bg_opa(pinyin_ime->cand_panel, LV_OPA_COVER, LV_PART_ITEMS | LV_STATE_PRESSED);lv_obj_set_style_bg_color(pinyin_ime->cand_panel, lv_color_white(), LV_PART_ITEMS | LV_STATE_PRESSED);/* 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_MODEpinyin_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
}static void lv_ime_pinyin_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
{LV_UNUSED(class_p);lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;if(lv_obj_is_valid(pinyin_ime->kb))lv_obj_del(pinyin_ime->kb);if(lv_obj_is_valid(pinyin_ime->cand_panel))lv_obj_del(pinyin_ime->cand_panel);
#if LV_IME_PINYIN_USE_K9_MODE        _lv_ll_clear(&pinyin_ime->k9_legal_py_ll);pinyin_ime->k9_input_str_len = 0;pinyin_ime->k9_py_ll_pos = 0;pinyin_ime->k9_legal_py_count = 0;
#endif
}static void lv_ime_pinyin_kb_event(lv_event_t * e)
{lv_event_code_t code = lv_event_get_code(e);lv_obj_t * kb = lv_event_get_current_target(e);lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)lv_event_get_user_data(e);lv_keyboard_t * keyboard = (lv_keyboard_t *)kb;static uint8_t prv_mode = LV_IME_PINYIN_MODE_K26_CH;#if LV_IME_PINYIN_USE_K9_MODEconst char * k9_py_map[8] = {"abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
#endifif (code != LV_EVENT_VALUE_CHANGED) return;uint16_t btn_id = lv_btnmatrix_get_selected_btn(kb);if(btn_id == LV_BTNMATRIX_BTN_NONE) return;const char * txt = lv_btnmatrix_get_btn_text(kb, btn_id);if(txt == NULL) return ;if (strcmp(txt, LV_SYMBOL_KEYBOARD) == 0){if(pinyin_ime->mode == LV_IME_PINYIN_MODE_K26_CH || pinyin_ime->mode == LV_IME_PINYIN_MODE_K26_EN) {prv_mode = pinyin_ime->mode;
#if LV_IME_PINYIN_USE_K9_MODElv_ime_pinyin_set_mode((lv_obj_t *)pinyin_ime, LV_IME_PINYIN_MODE_K9_CH); 
#endif}else if(pinyin_ime->mode == LV_IME_PINYIN_NODE_K26_SPECIAL) {lv_ime_pinyin_set_mode((lv_obj_t *)pinyin_ime, prv_mode);}
#if LV_IME_PINYIN_USE_K9_MODEelse if(pinyin_ime->mode == LV_IME_PINYIN_MODE_K9_CH) {lv_ime_pinyin_set_mode((lv_obj_t *)pinyin_ime, prv_mode);}else if(pinyin_ime->mode == LV_IME_PINYIN_MODE_K9_NUMBER) {lv_ime_pinyin_set_mode((lv_obj_t *)pinyin_ime, LV_IME_PINYIN_MODE_K9_CH);}
#endif    pinyin_ime_clear_data((lv_obj_t *)pinyin_ime);return;}else if (strcmp(txt, "En") == 0 || strcmp(txt, "Ch") == 0) {if (strcmp(txt, "Ch") == 0) {prv_mode = LV_IME_PINYIN_MODE_K26_CH;lv_ime_pinyin_set_mode((lv_obj_t *)pinyin_ime, LV_IME_PINYIN_MODE_K26_EN);lv_keyboard_set_mode(kb, LV_KEYBOARD_MODE_TEXT_LOWER);}else {prv_mode = LV_IME_PINYIN_MODE_K26_EN;lv_ime_pinyin_set_mode((lv_obj_t *)pinyin_ime, LV_IME_PINYIN_MODE_K26_CH);}pinyin_ime_clear_data((lv_obj_t *)pinyin_ime);return ;}else if(strcmp(txt, "abc") == 0 || strcmp(txt, "ABC") == 0) {if (pinyin_ime->mode == LV_IME_PINYIN_MODE_K26_EN) {lv_keyboard_set_mode(kb, lv_keyboard_get_mode(kb) == LV_KEYBOARD_MODE_TEXT_LOWER ? LV_KEYBOARD_MODE_TEXT_UPPER : LV_KEYBOARD_MODE_TEXT_LOWER);return ;}else if (pinyin_ime->mode == LV_IME_PINYIN_NODE_K26_SPECIAL) {lv_ime_pinyin_set_mode((lv_obj_t *)pinyin_ime, LV_IME_PINYIN_MODE_K26_EN);prv_mode = LV_IME_PINYIN_MODE_K26_EN;return ;}else if (pinyin_ime->mode == LV_IME_PINYIN_MODE_K26_CH) {return ;}}else if(strcmp(txt, "1#") == 0) {prv_mode = pinyin_ime->mode;lv_ime_pinyin_set_mode((lv_obj_t *)pinyin_ime, LV_IME_PINYIN_NODE_K26_SPECIAL);pinyin_ime_clear_data((lv_obj_t *)pinyin_ime);return ;}
#if LV_IME_PINYIN_USE_K9_MODEelse if(strcmp(txt, "123") == 0) {lv_ime_pinyin_set_mode((lv_obj_t *)pinyin_ime, LV_IME_PINYIN_MODE_K9_NUMBER);pinyin_ime_clear_data((lv_obj_t *)pinyin_ime);return ;}
#endifelse if (strcmp(txt, LV_SYMBOL_OK) == 0) {lv_event_send(keyboard->ta, LV_EVENT_READY, NULL);pinyin_ime_clear_data((lv_obj_t *)pinyin_ime);return;}else if(strcmp(txt, LV_SYMBOL_BACKSPACE) == 0) {if(pinyin_ime->ta_count > 0) { pinyin_ime->ta_count--;lv_textarea_del_char(keyboard->ta);if(pinyin_ime->mode == LV_IME_PINYIN_MODE_K26_CH) {pinyin_ime->input_char[pinyin_ime->ta_count] = '\0';}
#if LV_IME_PINYIN_USE_K9_MODEelsepinyin_ime->k9_input_str[pinyin_ime->ta_count] = '\0';
#endif           if(pinyin_ime->ta_count <= 0) {pinyin_ime_clear_data((lv_obj_t *)pinyin_ime);lv_obj_add_flag(pinyin_ime->cand_panel, LV_OBJ_FLAG_HIDDEN);}else if(pinyin_ime->mode == LV_IME_PINYIN_MODE_K26_CH) {pinyin_input_proc((lv_obj_t *)pinyin_ime);}
#if LV_IME_PINYIN_USE_K9_MODEelse if(pinyin_ime->mode == LV_IME_PINYIN_MODE_K9_CH) {pinyin_ime->k9_input_str_len = strlen(pinyin_ime->input_char) - 1;pinyin_k9_get_legal_py((lv_obj_t *)pinyin_ime, pinyin_ime->k9_input_str, k9_py_map);pinyin_k9_fill_cand((lv_obj_t *)pinyin_ime);pinyin_input_proc((lv_obj_t *)pinyin_ime);pinyin_ime->ta_count--;}
#endif  }else{lv_textarea_del_char(keyboard->ta);}return ;}else if (strcmp(txt, LV_SYMBOL_NEW_LINE) == 0) {pinyin_ime_clear_data((lv_obj_t *)pinyin_ime);lv_textarea_add_text(keyboard->ta, "\n");return ;}else if(strcmp(txt, LV_SYMBOL_LEFT) == 0) {if (pinyin_ime->ta_count <= 0) {lv_textarea_cursor_left(keyboard->ta);return ;}
#if LV_IME_PINYIN_USE_K9_MODEelse if (pinyin_ime->mode != LV_IME_PINYIN_MODE_K9_CH) {return ;}
#else   return ;
#endif}else if(strcmp(txt, LV_SYMBOL_RIGHT) == 0 ) {if (pinyin_ime->ta_count <= 0) {lv_textarea_cursor_right(keyboard->ta);return ;}
#if LV_IME_PINYIN_USE_K9_MODEelse if (pinyin_ime->mode != LV_IME_PINYIN_MODE_K9_CH) {return ;}
#else   return ;
#endif}#if LV_IME_PINYIN_USE_K9_MODEelse if(strcmp(txt, "+/-") == 0) {uint16_t cur        = lv_textarea_get_cursor_pos(keyboard->ta);const char * ta_txt = lv_textarea_get_text(keyboard->ta);if(ta_txt[0] == '-') {lv_textarea_set_cursor_pos(keyboard->ta, 1);lv_textarea_del_char(keyboard->ta);lv_textarea_add_char(keyboard->ta, '+');lv_textarea_set_cursor_pos(keyboard->ta, cur);}else if(ta_txt[0] == '+') {lv_textarea_set_cursor_pos(keyboard->ta, 1);lv_textarea_del_char(keyboard->ta);lv_textarea_add_char(keyboard->ta, '-');lv_textarea_set_cursor_pos(keyboard->ta, cur);}else {lv_textarea_set_cursor_pos(keyboard->ta, 0);lv_textarea_add_char(keyboard->ta, '-');lv_textarea_set_cursor_pos(keyboard->ta, cur + 1);}return ;}
#endifswitch(pinyin_ime->mode) {case LV_IME_PINYIN_MODE_K26_CH:if((txt[0] >= 'a' && txt[0] <= 'z') || (txt[0] >= 'A' && txt[0] <= 'Z')) {uint16_t len = strlen(pinyin_ime->input_char);if(len < sizeof(pinyin_ime->input_char) - 1) {pinyin_ime->input_char[len] = txt[0];pinyin_ime->input_char[len+1] = '\0';if (pinyin_input_proc((lv_obj_t *)pinyin_ime) == 0) {lv_textarea_add_text(keyboard->ta, txt);pinyin_ime->ta_count++;}else {pinyin_ime->input_char[len] = '\0';}}}else {pinyin_ime_clear_data((lv_obj_t *)pinyin_ime);lv_textarea_add_text(keyboard->ta, txt);}break;
#if LV_IME_PINYIN_USE_K9_MODEcase LV_IME_PINYIN_MODE_K9_CH: if((btn_id >= 16) && (strlen(pinyin_ime->input_char) > 0) && (btn_id < (16 + LV_IME_PINYIN_K9_CAND_TEXT_NUM))) {uint16_t 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((lv_obj_t *)pinyin_ime);uint16_t len = tmp_btn_str_len > pinyin_ime->ta_count ? tmp_btn_str_len : pinyin_ime->ta_count;for(int index = 0; index < len; index++) {lv_textarea_del_char(keyboard->ta);}pinyin_ime->ta_count = tmp_btn_str_len;pinyin_ime->k9_input_str_len = tmp_btn_str_len;lv_textarea_add_text(keyboard->ta, pinyin_ime->input_char);return;} else if (txt[0] >= 'a' && txt[0] <= 'z') {for(uint16_t i = 0; i < 8; i++) {if(strcmp(txt, k9_py_map[i]) == 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] = '2' + i;pinyin_ime->k9_input_str[pinyin_ime->ta_count + 1] = '\0';break;}}pinyin_k9_get_legal_py((lv_obj_t *)pinyin_ime, pinyin_ime->k9_input_str, k9_py_map);pinyin_k9_fill_cand((lv_obj_t *)pinyin_ime);pinyin_input_proc((lv_obj_t *)pinyin_ime);}else if(strcmp(txt, LV_SYMBOL_LEFT) == 0) {pinyin_k9_cand_page_proc((lv_obj_t *)pinyin_ime, 0);}else if(strcmp(txt, LV_SYMBOL_RIGHT) == 0) {pinyin_k9_cand_page_proc((lv_obj_t *)pinyin_ime, 1);}else{pinyin_ime_clear_data((lv_obj_t *)pinyin_ime);lv_textarea_add_text(keyboard->ta, txt);}break;
#endifdefault:lv_textarea_add_text(keyboard->ta, txt);break;}
}static void lv_ime_pinyin_cand_panel_event(lv_event_t * e)
{lv_event_code_t code = lv_event_get_code(e);lv_obj_t * cand_panel = lv_event_get_current_target(e);lv_obj_t * obj = (lv_obj_t *)lv_event_get_user_data(e);lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;if(code == LV_EVENT_VALUE_CHANGED) {lv_obj_t * ta = lv_keyboard_get_textarea(pinyin_ime->kb);if(ta == NULL) return;uint32_t id = lv_btnmatrix_get_selected_btn(cand_panel);if(id == LV_BTNMATRIX_BTN_NONE) {return;}else if(id == 0) {pinyin_page_proc(obj, 0);return;}else if(id == (LV_IME_PINYIN_CAND_TEXT_NUM + 1)) {pinyin_page_proc(obj, 1);return;}const char * txt = lv_btnmatrix_get_btn_text(cand_panel, id);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_clear_data(obj);}
}static int pinyin_input_proc(lv_obj_t * obj)
{lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;pinyin_ime->cand_str = pinyin_search_matching(obj, pinyin_ime->input_char, &pinyin_ime->cand_num);if(pinyin_ime->cand_str == NULL) {return -1;}pinyin_ime->py_page = 0;for(uint8_t i = 0; i < LV_IME_PINYIN_CAND_TEXT_NUM; i++) {memset(lv_pinyin_cand_str[i], 0x00, sizeof(lv_pinyin_cand_str[i]));lv_pinyin_cand_str[i][0] = ' ';}// fill buffor(uint8_t i = 0; (i < pinyin_ime->cand_num && i < LV_IME_PINYIN_CAND_TEXT_NUM); i++) {for(uint8_t j = 0; j < 3; j++) {lv_pinyin_cand_str[i][j] = pinyin_ime->cand_str[i * 3 + j];}}lv_obj_clear_flag(pinyin_ime->cand_panel, LV_OBJ_FLAG_HIDDEN);lv_obj_invalidate(pinyin_ime->cand_panel);return 0;
}static void pinyin_page_proc(lv_obj_t * obj, uint16_t dir)
{lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;uint16_t page_num = pinyin_ime->cand_num / LV_IME_PINYIN_CAND_TEXT_NUM;uint16_t remainder = pinyin_ime->cand_num % LV_IME_PINYIN_CAND_TEXT_NUM;if(!pinyin_ime->cand_str) return;if(dir == 0) {if(pinyin_ime->py_page) {pinyin_ime->py_page--;}}else {if(remainder == 0) {page_num -= 1;}if(pinyin_ime->py_page < page_num) {pinyin_ime->py_page++;}else return;}for(uint8_t i = 0; i < LV_IME_PINYIN_CAND_TEXT_NUM; i++) {memset(lv_pinyin_cand_str[i], 0x00, sizeof(lv_pinyin_cand_str[i]));lv_pinyin_cand_str[i][0] = ' ';}// fill bufuint16_t offset = pinyin_ime->py_page * (3 * LV_IME_PINYIN_CAND_TEXT_NUM);for(uint8_t i = 0; (i < pinyin_ime->cand_num && i < LV_IME_PINYIN_CAND_TEXT_NUM); i++) {if((remainder > 0) && (pinyin_ime->py_page == page_num)) {if(i >= remainder)break;}for(uint8_t j = 0; j < 3; j++) {lv_pinyin_cand_str[i][j] = pinyin_ime->cand_str[offset + (i * 3) + j];}}
}static void lv_ime_pinyin_style_change_event(lv_event_t * e)
{lv_event_code_t code = lv_event_get_code(e);lv_obj_t * obj = lv_event_get_current_target(e);lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;if(code == LV_EVENT_STYLE_CHANGED) {const lv_font_t * font = lv_obj_get_style_text_font(obj, LV_PART_MAIN);lv_obj_set_style_text_font(pinyin_ime->cand_panel, font, 0);}
}static void init_pinyin_dict(lv_obj_t * obj,const lv_pinyin_dict_t * dict)
{lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;char headletter = 'a';uint16_t offset_sum = 0;uint16_t offset_count = 0;uint16_t letter_calc = 0;pinyin_ime->dict = dict;for(uint16_t i = 0; ; i++) {if((NULL == (dict[i].py)) || (NULL == (dict[i].py_mb))) {headletter = dict[i - 1].py[0];letter_calc = headletter - 'a';pinyin_ime->py_num[letter_calc] = offset_count;break;}if(headletter == (dict[i].py[0])) {offset_count++;}else {headletter = dict[i].py[0];pinyin_ime->py_num[letter_calc] = offset_count;letter_calc = headletter - 'a';offset_sum += offset_count;pinyin_ime->py_pos[letter_calc] = offset_sum;offset_count = 1;}}
}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;const lv_pinyin_dict_t * cpHZ;uint8_t index, len = 0, offset;volatile uint8_t count = 0;if(*py_str == '\0')    return NULL;if(*py_str == 'i')     return NULL;if(*py_str == 'u')     return NULL;if(*py_str == 'v')     return NULL;if(*py_str == ' ')     return NULL;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 matchif(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);}cpHZ++;}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_MODEif(pinyin_ime->mode == LV_IME_PINYIN_MODE_K9_CH) {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));for(uint8_t i = 0; i < LV_IME_PINYIN_CAND_TEXT_NUM; i++) {strcpy(lv_pinyin_k9_cand_str[i], " ");}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");lv_btnmatrix_set_map(pinyin_ime->kb, (const char **)lv_btnm_def_pinyin_k9_map);}
#endifpinyin_ime->ta_count = 0;for(uint8_t i = 0; i < LV_IME_PINYIN_CAND_TEXT_NUM; i++) {lv_memset(lv_pinyin_cand_str[i], 0x00, sizeof(lv_pinyin_cand_str[i]));lv_pinyin_cand_str[i][0] = ' ';}lv_memset_00(pinyin_ime->input_char, sizeof(pinyin_ime->input_char));lv_btnmatrix_set_map(pinyin_ime->cand_panel, (const char **)lv_btnm_def_pinyin_sel_map); 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_UNUSED(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_BTNMATRIX_CTRL_CHECKED | 1;default_kb_ctrl_k9_map[1]  = LV_BTNMATRIX_CTRL_NO_REPEAT | LV_BTNMATRIX_CTRL_CLICK_TRIG | 1;default_kb_ctrl_k9_map[4]  = LV_BTNMATRIX_CTRL_CHECKED | 1;default_kb_ctrl_k9_map[5]  = LV_BTNMATRIX_CTRL_CHECKED | 1;default_kb_ctrl_k9_map[9]  = LV_KEYBOARD_CTRL_BTN_FLAGS | 1;default_kb_ctrl_k9_map[10] = LV_BTNMATRIX_CTRL_CHECKED | 1;default_kb_ctrl_k9_map[14] = LV_BTNMATRIX_CTRL_CHECKED | 1;default_kb_ctrl_k9_map[15] = LV_BTNMATRIX_CTRL_CHECKED | 1;default_kb_ctrl_k9_map[LV_IME_PINYIN_K9_CAND_TEXT_NUM + 16] = LV_BTNMATRIX_CTRL_CHECKED | 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;uint16_t 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((size_t)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--;}}}lv_keyboard_t *keyboard = (lv_keyboard_t *)lv_ime_pinyin_get_kb(obj);for(index = 0; index < pinyin_ime->ta_count; index++) {lv_textarea_del_char(keyboard->ta);}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;const lv_pinyin_dict_t * cpHZ = NULL;uint8_t index = 0, len = 0, offset = 0;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 matchif(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);for(uint8_t i = 0; i < LV_IME_PINYIN_K9_CAND_TEXT_NUM; i++) {strcpy(lv_pinyin_k9_cand_str[i], " ");}while(ll_index) {if(index >= LV_IME_PINYIN_K9_CAND_TEXT_NUM)break;if(index < pinyin_ime->k9_legal_py_count) {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);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;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 pageif(dir == 1) {for(uint8_t i = 0; i < LV_IME_PINYIN_K9_CAND_TEXT_NUM; i++) {strcpy(lv_pinyin_k9_cand_str[i], " ");}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 pageelse {for(uint8_t i = 0; i < LV_IME_PINYIN_K9_CAND_TEXT_NUM; i++) {strcpy(lv_pinyin_k9_cand_str[i], " ");}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*/

lv_ime_pinyin.h

/*** @file lv_ime_pinyin.h* @author Jaychen (719095404@qq.com)* @brief * @version 0.1* @date 2025-08-17* * @copyright Copyright (c) 2025* */
#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*********************/
#if LV_IME_PINYIN_USE_K9_MODE
#define LV_IME_PINYIN_K9_MAX_INPUT  7
#endif
/***********************      TYPEDEFS**********************/typedef enum {LV_IME_PINYIN_MODE_K26_CH,LV_IME_PINYIN_MODE_K26_EN,LV_IME_PINYIN_NODE_K26_SPECIAL,
#if LV_IME_PINYIN_USE_K9_MODELV_IME_PINYIN_MODE_K9_NUMBER,LV_IME_PINYIN_MODE_K9_CH,
#endif
} 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;const lv_pinyin_dict_t * dict;lv_ll_t k9_legal_py_ll;char * cand_str;            /* Candidate string */char   input_char[16];      /* Input box character */
#if LV_IME_PINYIN_USE_K9_MODEchar   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 */
#endifuint16_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(k26) */uint16_t py_num[26];        /* Number and length of Pinyin */uint16_t py_pos[26];        /* Pinyin position */uint8_t  mode : 3;          /* Set mode */
} lv_ime_pinyin_t;/************************ GLOBAL VARIABLES***********************/extern const lv_obj_class_t lv_ime_pinyin_class;/*********************** 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 kb 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);/*** 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*====================*//*** 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*/
const lv_pinyin_dict_t * lv_ime_pinyin_get_dict(lv_obj_t * obj);/*** @brief Hide pinyin input method.* * @param pinyin_ime */
void lv_ime_pinyin_hide(lv_obj_t *pinyin_ime);/*** @brief Show pinyin input method.* * @param pinyin_ime */
void lv_ime_pinyin_show(lv_obj_t *pinyin_ime);/*=====================* Other functions*====================*//***********************      MACROS**********************/#endif  /*LV_IME_PINYIN*/#ifdef __cplusplus
} /*extern "C"*/
#endif#endif /*LV_IME_PINYIN_H*/

二、LVGL9.4的拼音输入法优化

lv_ime_pinyin.c

/*** @file lv_ime_pinyin.c**//**********************      INCLUDES*********************/
#include "lv_ime_pinyin_private.h"
#include "../../core/lv_obj_class_private.h"
#if LV_USE_IME_PINYIN != 0#include "../../lvgl.h"
#include "../../core/lv_global.h"/**********************      DEFINES*********************/
#define MY_CLASS (&lv_ime_pinyin_class)
#define cand_len LV_GLOBAL_DEFAULT()->ime_cand_len/***********************      TYPEDEFS**********************//***********************  STATIC PROTOTYPES**********************/
static void lv_ime_pinyin_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
static void lv_ime_pinyin_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
static void lv_ime_pinyin_style_change_event(lv_event_t * e);
static void lv_ime_pinyin_kb_event(lv_event_t * e);
static void lv_ime_pinyin_cand_panel_event(lv_event_t * e);static void init_pinyin_dict(lv_obj_t * obj, const lv_pinyin_dict_t * dict);
static int 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 * py_str, uint16_t * cand_num);
static void pinyin_ime_clear_data(lv_obj_t * obj);#if LV_IME_PINYIN_USE_K9_MODEstatic 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**********************/const lv_obj_class_t lv_ime_pinyin_class = {.constructor_cb = lv_ime_pinyin_constructor,.destructor_cb  = lv_ime_pinyin_destructor,.width_def      = LV_SIZE_CONTENT,.height_def     = LV_SIZE_CONTENT,.group_def      = LV_OBJ_CLASS_GROUP_DEF_TRUE,.instance_size  = sizeof(lv_ime_pinyin_t),.base_class     = &lv_obj_class,.name = "lv_ime_pinyin",
};#if LV_IME_PINYIN_USE_K9_MODE
static const char * lv_btnm_def_pinyin_k9_map[LV_IME_PINYIN_K9_CAND_TEXT_NUM + 21] = {",", "123",  "abc", "def",  LV_SYMBOL_BACKSPACE, "\n",".", "ghi", "jkl", "mno",  LV_SYMBOL_KEYBOARD, "\n","?", "pqrs", "tuv", "wxyz",  LV_SYMBOL_NEW_LINE, "\n",LV_SYMBOL_LEFT, ""
};static lv_buttonmatrix_ctrl_t default_kb_ctrl_k9_map[LV_IME_PINYIN_K9_CAND_TEXT_NUM + 17] = { 1 };
static char   lv_pinyin_k9_cand_str[LV_IME_PINYIN_K9_CAND_TEXT_NUM + 2][LV_IME_PINYIN_K9_MAX_INPUT] = {0};
#endifstatic 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];static const char * kb_26_ch_lower_map[] = {"1#", "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", LV_SYMBOL_BACKSPACE, "\n","abc", "a", "s", "d", "f", "g", "h", "j", "k", "l", LV_SYMBOL_NEW_LINE, "\n","_", "-", "z", "x", "c", "v", "b", "n", "m", ".", ",", ":", "\n",LV_SYMBOL_KEYBOARD, LV_SYMBOL_LEFT, " ", "Ch", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, ""
};static const char * kb_26_en_lower_map[] = {"1#", "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", LV_SYMBOL_BACKSPACE, "\n","abc", "a", "s", "d", "f", "g", "h", "j", "k", "l", LV_SYMBOL_NEW_LINE, "\n","_", "-", "z", "x", "c", "v", "b", "n", "m", ".", ",", ":", "\n",LV_SYMBOL_KEYBOARD, LV_SYMBOL_LEFT, " ", "En", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, ""
};static const char * kb_26_en_upper_map[] = {"1#", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", LV_SYMBOL_BACKSPACE, "\n","ABC", "A", "S", "D", "F", "G", "H", "J", "K", "L", LV_SYMBOL_NEW_LINE, "\n","_", "-", "Z", "X", "C", "V", "B", "N", "M", ".", ",", ":", "\n",LV_SYMBOL_KEYBOARD, LV_SYMBOL_LEFT, " ", "En", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, ""
};static const lv_btnmatrix_ctrl_t kb_26_ctrl[] = {LV_KEYBOARD_CTRL_BUTTON_FLAGS | 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, LV_BUTTONMATRIX_CTRL_CHECKED | 1,LV_KEYBOARD_CTRL_BUTTON_FLAGS | 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, LV_KEYBOARD_CTRL_BUTTON_FLAGS | 2,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,LV_KEYBOARD_CTRL_BUTTON_FLAGS | 2, LV_KEYBOARD_CTRL_BUTTON_FLAGS | 2, 6, LV_KEYBOARD_CTRL_BUTTON_FLAGS | 2,LV_KEYBOARD_CTRL_BUTTON_FLAGS | 2, LV_KEYBOARD_CTRL_BUTTON_FLAGS | 2
};#if LV_IME_PINYIN_USE_DEFAULT_DICT
static const lv_pinyin_dict_t lv_ime_pinyin_def_dict[] = {{ "a", "啊" },{ "ai", "愛" },{ "an", "安暗案" },{ "ba", "吧把爸八" },{ "bai", "百白敗" },{ "ban", "半般辦" },{ "bang", "旁" },{ "bao", "保薄包報" },{ "bei", "被背悲北杯備" },{ "ben", "本" },{ "bi", "必比避鼻彼筆秘閉" },{ "bian", "便邊變変辺" },{ "biao", "表標" },{ "bie", "別" },{ "bing", "病並氷" },{ "bo", "波薄泊" },{ "bu", "不布步部捕補歩" },{ "ca", "察" },{ "cai", "才材菜財採" },{ "can", "参残參" },{ "ce", "策側" },{ "ceng", "曾" },{ "cha", "差查茶" },{ "chai", "差" },{ "chan", "產産單" },{ "chang", "場廠" },{ "chao", "超朝" },{ "che", "車" },{ "cheng", "成程乗" },{ "chi", "尺吃持赤池遅歯" },{ "chong", "充种重種" },{ "chu", "出初楚触處処" },{ "chuan", "川船傳" },{ "chuang", "創窓" },{ "chun", "春" },{ "ci", "此次辞差" },{ "cong", "從従" },{ "cu", "卒" },{ "cun", "存村" },{ "cuo", "錯" },{ "da", "大打答達" },{ "dai", "代待帯帶貸" },{ "dan", "但担擔誕單単" },{ "dang", "当党當黨" },{ "dao", "到道盗導島辺" },{ "de", "的得" },{ "dei", "" },{ "deng", "等" },{ "di", "地得低底弟第締" },{ "dian", "点电店點電" },{ "diao", "調" },{ "ding", "定町" },{ "dong", "冬東動働凍" },{ "du", "独度都渡読" },{ "duan", "段断短斷" },{ "dui", "對対" },{ "duo", "多駄" },{ "e", "嗯悪" },{ "en", "嗯" },{ "er", "而耳二兒" },{ "fa", "乏法發発髪" },{ "fan", "反返犯番仮販飯範払" },{ "fang", "方放房坊訪" },{ "fei", "非飛費" },{ "fen", "分份" },{ "feng", "風豐" },{ "fou", "否不" },{ "fu", "父夫富服符付附府幅婦復複負払" },{ "gai", "改概該" },{ "gan", "甘感敢" },{ "gang", "港剛" },{ "gao", "告高" },{ "ge", "各格歌革割個" },{ "gei", "給" },{ "gen", "跟根" },{ "geng", "更" },{ "gong", "工共供功公" },{ "gou", "夠構溝" },{ "gu", "古故鼓" },{ "guai", "掛" },{ "guan", "官管慣館觀関關" },{ "guang", "光広" },{ "gui", "規帰" },{ "guo", "果国裏菓國過" },{ "hai", "孩海害還" },{ "han", "寒漢" },{ "hang", "航行" },{ "hao", "好号" },{ "he", "合和喝何荷" },{ "hei", "黒" },{ "hen", "很" },{ "heng", "行横" },{ "hou", "厚喉候後" },{ "hu", "乎呼湖護" },{ "hua", "化画花話畫劃" },{ "huai", "壊劃" },{ "huan", "緩環歡還換" },{ "huang", "黄" },{ "hui", "回会慧絵揮會" },{ "hun", "混婚" },{ "huo", "活或火獲" },{ "i", "" },{ "ji", "己计及机既急季寄技即集基祭系奇紀積計記済幾際極繼績機濟" },{ "jia", "家加價" },{ "jian", "件建健肩見減間検簡漸" },{ "jiang", "降強講將港" },{ "jiao", "叫教交角覚覺較學" },{ "jie", "介借接姐皆届界解結階節價" },{ "jin", "今近禁金僅進" },{ "jing", "京境景静精經経" },{ "jiu", "就久九酒究" },{ "ju", "句具局居決挙據舉" },{ "jue", "角覚覺" },{ "jun", "均" },{ "kai", "開" },{ "kan", "看刊" },{ "kang", "康" },{ "kao", "考" },{ "ke", "可刻科克客渇課" },{ "ken", "肯" },{ "kong", "空控" },{ "kou", "口" },{ "ku", "苦庫" },{ "kuai", "快塊会會" },{ "kuang", "況" },{ "kun", "困" },{ "kuo", "括拡適" },{ "la", "拉啦落" },{ "lai", "来來頼" },{ "lao", "老絡落" },{ "le", "了楽樂" },{ "lei", "類" },{ "leng", "冷" },{ "li", "力立利理例礼離麗裡勵歷" },{ "lian", "連練臉聯" },{ "liang", "良量涼兩両" },{ "liao", "料" },{ "lie", "列" },{ "lin", "林隣賃" },{ "ling", "另令領" },{ "liu", "六留流" },{ "lu", "律路録緑陸履慮" },{ "lv", "旅" },{ "lun", "輪論" },{ "luo", "落絡" },{ "ma", "媽嗎嘛" },{ "mai", "買売" },{ "man", "滿" },{ "mang", "忙" },{ "mao", "毛猫貿" },{ "me", "麼" },{ "mei", "美妹每沒毎媒" },{ "men", "們" },{ "mi", "米密秘" },{ "mian", "免面勉眠" },{ "miao", "描" },{ "min", "民皿" },{ "ming", "命明名" },{ "mo", "末模麼" },{ "mou", "某" },{ "mu", "母木目模" },{ "na", "那哪拿內南" },{ "nan", "男南難" },{ "nao", "腦" },{ "ne", "那哪呢" },{ "nei", "内那哪內" },{ "neng", "能" },{ "ni", "你妳呢" },{ "nian", "年念" },{ "niang", "娘" },{ "nin", "您" },{ "ning", "凝" },{ "niu", "牛" },{ "nong", "農濃" },{ "nu", "女努" },{ "nuan", "暖" },{ "o", "" },{ "ou", "歐" },{ "pa", "怕" },{ "pai", "迫派排" },{ "pan", "判番" },{ "pang", "旁" },{ "pei", "配" },{ "peng", "朋" },{ "pi", "疲否" },{ "pian", "片便" },{ "pin", "品貧" },{ "ping", "平評" },{ "po", "迫破泊頗" },{ "pu", "普僕" },{ "qi", "起其奇七气期泣企妻契気" },{ "qian", "嵌浅千前鉛錢針" },{ "qiang", "強將" },{ "qiao", "橋繰" },{ "qie", "且切契" },{ "qin", "寝勤親" },{ "qing", "青清情晴輕頃請軽" },{ "qiu", "求秋球" },{ "qu", "去取趣曲區" },{ "quan", "全犬券" },{ "que", "缺確卻" },{ "ran", "然" },{ "rang", "讓" },{ "re", "熱" },{ "ren", "人任認" },{ "reng", "仍" },{ "ri", "日" },{ "rong", "容" },{ "rou", "弱若肉" },{ "ru", "如入" },{ "ruan", "軟" },{ "sai", "賽" },{ "san", "三" },{ "sao", "騒繰" },{ "se", "色" },{ "sen", "森" },{ "sha", "砂" },{ "shan", "善山單" },{ "shang", "上尚商" },{ "shao", "少紹" },{ "shaung", "雙" },{ "she", "社射設捨渉" },{ "shei", "誰" },{ "shen", "什申深甚身伸沈神" },{ "sheng", "生声昇勝乗聲" },{ "shi", "是失示食时事式十石施使世实史室市始柿氏士仕拭時視師試適実實識" },{ "shou", "手首守受授" },{ "shu", "束数暑殊樹書屬輸術" },{ "shui", "水説說誰" },{ "shuo", "数説說" },{ "si", "思寺司四私似死価" },{ "song", "送" },{ "su", "速宿素蘇訴" },{ "suan", "算酸" },{ "sui", "隨雖歲歳" },{ "sun", "孫" },{ "suo", "所" },{ "ta", "她他它牠" },{ "tai", "太台態臺" },{ "tan", "探談曇" },{ "tang", "糖" },{ "tao", "桃逃套討" },{ "te", "特" },{ "ti", "体提替題體戻" },{ "tian", "天田" },{ "tiao", "条條調" },{ "tie", "鉄" },{ "ting", "停庭聽町" },{ "tong", "同童通痛统統" },{ "tou", "投透頭" },{ "tu", "土徒茶図" },{ "tuan", "團" },{ "tui", "推退" },{ "tuo", "脱駄" },{ "u", "" },{ "v", "" },{ "wai", "外" },{ "wan", "完万玩晩腕灣" },{ "wang", "忘望亡往網" },{ "wei", "危位未味委為謂維違圍" },{ "wen", "文温問聞" },{ "wo", "我" },{ "wu", "午物五無屋亡鳥務汚" },{ "xi", "夕息西洗喜系昔席希析嬉膝細習係" },{ "xia", "下夏狭暇" },{ "xian", "先限嫌洗現見線顯" },{ "xiang", "向相香像想象降項詳響" },{ "xiao", "小笑消效校削咲" },{ "xie", "写携些解邪械協謝寫契" },{ "xin", "心信新辛" },{ "xing", "行形性幸型星興" },{ "xiong", "兄胸" },{ "xiu", "休秀修" },{ "xu", "須需許續緒続" },{ "xuan", "選懸" },{ "xue", "学雪削靴學" },{ "xun", "訓訊" },{ "ya", "呀押壓" },{ "yan", "言顔研煙嚴厳験驗塩" },{ "yang", "央洋陽樣様" },{ "yao", "要揺腰薬曜" },{ "ye", "也野夜邪業葉" },{ "yi", "一已亦依以移意医易伊役異億義議藝醫訳" },{ "yin", "因引音飲銀" },{ "ying", "英迎影映應營営" },{ "yong", "永用泳擁" },{ "you", "又有右友由尤油遊郵誘優" },{ "yu", "予育余雨浴欲愈御宇域語於魚與込" },{ "yuan", "元原源院員円園遠猿願" },{ "yue", "月越約楽" },{ "yun", "雲伝運" },{ "za", "雑" },{ "zai", "在再載災" },{ "zang", "蔵" },{ "zao", "早造" },{ "ze", "則擇責" },{ "zen", "怎" },{ "zeng", "曾增増" },{ "zha", "札" },{ "zhai", "宅擇" },{ "zhan", "站展戰戦" },{ "zhang", "丈長障帳張" },{ "zhao", "找着朝招" },{ "zhe", "者這" },{ "zhen", "真震針" },{ "zheng", "正整争政爭" },{ "zhi", "之只知支止制至治直指值置智値紙製質誌織隻識職執" },{ "zhong", "中种終重種眾" },{ "zhou", "周州昼宙洲週" },{ "zhu", "助主住柱株祝逐注著諸屬術" },{ "zhuan", "专專転" },{ "zhuang", "状狀" },{ "zhui", "追" },{ "zhun", "準" },{ "zhuo", "着" },{ "zi", "子自字姉資" },{ "zong", "總" },{ "zuo", "左做昨坐座作" },{ "zu", "足祖族卒組" },{ "zui", "最酔" },{ "zou", "走" },{NULL, NULL}
};
#endif/***********************      MACROS**********************//***********************   GLOBAL FUNCTIONS**********************/
lv_obj_t * lv_ime_pinyin_create(lv_obj_t * parent)
{LV_LOG_INFO("begin");lv_obj_t * obj = lv_obj_class_create_obj(MY_CLASS, parent);lv_obj_class_init_obj(obj);return obj;
}/*=====================* Setter functions*====================*/void lv_ime_pinyin_set_keyboard(lv_obj_t * obj, lv_obj_t * kb)
{if(kb) {LV_ASSERT_OBJ(kb, &lv_keyboard_class);}LV_ASSERT_OBJ(obj, MY_CLASS);lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;pinyin_ime->kb = kb;lv_obj_set_parent(obj, lv_obj_get_parent(kb));lv_obj_set_parent(pinyin_ime->cand_panel, lv_obj_get_parent(kb));lv_ime_pinyin_set_mode((lv_obj_t *)pinyin_ime, LV_IME_PINYIN_MODE_K26_CH);lv_obj_remove_event_cb(pinyin_ime->kb, lv_keyboard_def_event_cb);lv_obj_add_event_cb(pinyin_ime->kb, lv_ime_pinyin_kb_event, LV_EVENT_VALUE_CHANGED, obj);lv_obj_align_to(pinyin_ime->cand_panel, pinyin_ime->kb, LV_ALIGN_OUT_TOP_MID, 0, 0);
}void lv_ime_pinyin_set_dict(lv_obj_t * obj, lv_pinyin_dict_t * dict)
{LV_ASSERT_OBJ(obj, MY_CLASS);init_pinyin_dict(obj, dict);
}void lv_ime_pinyin_set_mode(lv_obj_t * obj, lv_ime_pinyin_mode_t mode)
{static uint8_t K26_mode = LV_KEYBOARD_MODE_TEXT_LOWER;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;switch(mode) {case LV_IME_PINYIN_MODE_K26_CH:lv_keyboard_set_map(pinyin_ime->kb, LV_KEYBOARD_MODE_TEXT_LOWER, kb_26_ch_lower_map, kb_26_ctrl);lv_keyboard_set_mode(pinyin_ime->kb, LV_KEYBOARD_MODE_TEXT_LOWER);K26_mode = LV_KEYBOARD_MODE_TEXT_LOWER;break;case LV_IME_PINYIN_MODE_K26_EN:lv_keyboard_set_map(pinyin_ime->kb, LV_KEYBOARD_MODE_TEXT_LOWER, kb_26_en_lower_map, kb_26_ctrl);lv_keyboard_set_map(pinyin_ime->kb, LV_KEYBOARD_MODE_TEXT_UPPER, kb_26_en_upper_map, kb_26_ctrl);if(K26_mode == LV_KEYBOARD_MODE_TEXT_LOWER) {lv_keyboard_set_mode(pinyin_ime->kb, LV_KEYBOARD_MODE_TEXT_LOWER);}else {lv_keyboard_set_mode(pinyin_ime->kb, LV_KEYBOARD_MODE_TEXT_UPPER);}break;case LV_IME_PINYIN_MODE_K26_SPECIAL:K26_mode = lv_keyboard_get_mode(pinyin_ime->kb);lv_keyboard_set_mode(pinyin_ime->kb, LV_KEYBOARD_MODE_SPECIAL);break;
#if LV_IME_PINYIN_USE_K9_MODEcase LV_IME_PINYIN_MODE_K9_CH: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,default_kb_ctrl_k9_map);lv_keyboard_set_mode(pinyin_ime->kb, LV_KEYBOARD_MODE_USER_1);break;case LV_IME_PINYIN_MODE_K9_NUMBER:lv_keyboard_set_mode(pinyin_ime->kb, LV_KEYBOARD_MODE_NUMBER);break;
#endif}
}/*=====================* Getter functions*====================*/lv_obj_t * lv_ime_pinyin_get_kb(lv_obj_t * obj)
{LV_ASSERT_OBJ(obj, MY_CLASS);lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;return pinyin_ime->kb;
}lv_obj_t * lv_ime_pinyin_get_cand_panel(lv_obj_t * obj)
{LV_ASSERT_OBJ(obj, MY_CLASS);lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;return pinyin_ime->cand_panel;
}const lv_pinyin_dict_t * lv_ime_pinyin_get_dict(lv_obj_t * obj)
{LV_ASSERT_OBJ(obj, MY_CLASS);lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;return pinyin_ime->dict;
}/*=====================* Other functions*====================*//***********************   STATIC FUNCTIONS**********************/static void lv_ime_pinyin_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
{LV_UNUSED(class_p);LV_TRACE_OBJ_CREATE("begin");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 = 0; btnm_i < (LV_IME_PINYIN_CAND_TEXT_NUM + 3); btnm_i++) {if(btnm_i == 0) {lv_btnm_def_pinyin_sel_map[btnm_i] = "<";}else if(btnm_i == (LV_IME_PINYIN_CAND_TEXT_NUM + 1)) {lv_btnm_def_pinyin_sel_map[btnm_i] = ">";}else if(btnm_i == (LV_IME_PINYIN_CAND_TEXT_NUM + 2)) {lv_btnm_def_pinyin_sel_map[btnm_i] = "";}else {lv_pinyin_cand_str[py_str_i][0] = ' ';lv_btnm_def_pinyin_sel_map[btnm_i] = lv_pinyin_cand_str[py_str_i];py_str_i++;}}pinyin_ime->mode = LV_IME_PINYIN_MODE_K26_CH;pinyin_ime->py_page = 0;pinyin_ime->ta_count = 0;pinyin_ime->cand_num = 0;lv_memzero(pinyin_ime->input_char, sizeof(pinyin_ime->input_char));lv_memzero(pinyin_ime->py_num, sizeof(pinyin_ime->py_num));lv_memzero(pinyin_ime->py_pos, sizeof(pinyin_ime->py_pos));lv_obj_add_flag(obj, LV_OBJ_FLAG_HIDDEN);#if LV_IME_PINYIN_USE_DEFAULT_DICTinit_pinyin_dict(obj, lv_ime_pinyin_def_dict);
#endif/* Init pinyin_ime->cand_panel */pinyin_ime->cand_panel = lv_buttonmatrix_create(lv_obj_get_parent(obj));lv_buttonmatrix_set_map(pinyin_ime->cand_panel, (const char **)lv_btnm_def_pinyin_sel_map);lv_obj_set_size(pinyin_ime->cand_panel, LV_PCT(100), LV_PCT(5));lv_obj_add_flag(pinyin_ime->cand_panel, LV_OBJ_FLAG_HIDDEN);lv_buttonmatrix_set_one_checked(pinyin_ime->cand_panel, true);lv_obj_remove_flag(pinyin_ime->cand_panel, LV_OBJ_FLAG_CLICK_FOCUSABLE);/* Set cand_panel style*/// Default stylelv_obj_set_style_bg_opa(pinyin_ime->cand_panel, LV_OPA_50, 0);lv_obj_set_style_bg_color(pinyin_ime->cand_panel, lv_color_make(230, 230, 230), 0);lv_obj_set_style_border_width(pinyin_ime->cand_panel, 0, 0);lv_obj_set_style_pad_all(pinyin_ime->cand_panel, 8, 0);lv_obj_set_style_pad_gap(pinyin_ime->cand_panel, 0, 0);lv_obj_set_style_radius(pinyin_ime->cand_panel, 0, 0);lv_obj_set_style_pad_gap(pinyin_ime->cand_panel, 0, 0);lv_obj_set_style_base_dir(pinyin_ime->cand_panel, LV_BASE_DIR_LTR, 0);// LV_PART_ITEMS stylelv_obj_set_style_radius(pinyin_ime->cand_panel, 12, LV_PART_ITEMS);lv_obj_set_style_bg_color(pinyin_ime->cand_panel, lv_color_white(), LV_PART_ITEMS);lv_obj_set_style_bg_opa(pinyin_ime->cand_panel, LV_OPA_0, LV_PART_ITEMS);lv_obj_set_style_shadow_opa(pinyin_ime->cand_panel, LV_OPA_0, LV_PART_ITEMS);// LV_PART_ITEMS | LV_STATE_PRESSED stylelv_obj_set_style_bg_opa(pinyin_ime->cand_panel, LV_OPA_COVER, LV_PART_ITEMS | LV_STATE_PRESSED);lv_obj_set_style_bg_color(pinyin_ime->cand_panel, lv_color_white(), LV_PART_ITEMS | LV_STATE_PRESSED);/* 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_MODEpinyin_ime->k9_input_str_len = 0;pinyin_ime->k9_py_ll_pos = 0;pinyin_ime->k9_legal_py_count = 0;lv_memzero(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
}static void lv_ime_pinyin_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
{LV_UNUSED(class_p);lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;if(lv_obj_is_valid(pinyin_ime->kb))lv_obj_delete(pinyin_ime->kb);if(lv_obj_is_valid(pinyin_ime->cand_panel))lv_obj_delete(pinyin_ime->cand_panel);
#if LV_IME_PINYIN_USE_K9_MODE_lv_ll_clear(&pinyin_ime->k9_legal_py_ll);pinyin_ime->k9_input_str_len = 0;pinyin_ime->k9_py_ll_pos = 0;pinyin_ime->k9_legal_py_count = 0;
#endif
}static void lv_ime_pinyin_kb_event(lv_event_t * e)
{lv_event_code_t code = lv_event_get_code(e);lv_obj_t * kb = lv_event_get_current_target(e);lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)lv_event_get_user_data(e);lv_obj_t * ta = lv_keyboard_get_textarea(pinyin_ime->kb);static uint8_t prv_mode = LV_IME_PINYIN_MODE_K26_CH;#if LV_IME_PINYIN_USE_K9_MODEstatic const char * k9_py_map[8] = {"abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
#endifif(code != LV_EVENT_VALUE_CHANGED) return;uint16_t btn_id = lv_buttonmatrix_get_selected_button(kb);if(btn_id == LV_BUTTONMATRIX_BUTTON_NONE) return;const char * txt = lv_buttonmatrix_get_button_text(kb, btn_id);if(txt == NULL) return ;if(lv_strcmp(txt, LV_SYMBOL_KEYBOARD) == 0) {if(pinyin_ime->mode == LV_IME_PINYIN_MODE_K26_CH || pinyin_ime->mode == LV_IME_PINYIN_MODE_K26_EN) {prv_mode = pinyin_ime->mode;
#if LV_IME_PINYIN_USE_K9_MODElv_ime_pinyin_set_mode((lv_obj_t *)pinyin_ime, LV_IME_PINYIN_MODE_K9_CH);
#endif}else if(pinyin_ime->mode == LV_IME_PINYIN_MODE_K26_SPECIAL) {lv_ime_pinyin_set_mode((lv_obj_t *)pinyin_ime, prv_mode);}
#if LV_IME_PINYIN_USE_K9_MODEelse if(pinyin_ime->mode == LV_IME_PINYIN_MODE_K9_CH) {lv_ime_pinyin_set_mode((lv_obj_t *)pinyin_ime, prv_mode);}else if(pinyin_ime->mode == LV_IME_PINYIN_MODE_K9_NUMBER) {lv_ime_pinyin_set_mode((lv_obj_t *)pinyin_ime, LV_IME_PINYIN_MODE_K9_CH);}
#endifpinyin_ime_clear_data((lv_obj_t *)pinyin_ime);return;}else if(lv_strcmp(txt, "En") == 0 || lv_strcmp(txt, "Ch") == 0) {if(lv_strcmp(txt, "Ch") == 0) {prv_mode = LV_IME_PINYIN_MODE_K26_CH;lv_ime_pinyin_set_mode((lv_obj_t *)pinyin_ime, LV_IME_PINYIN_MODE_K26_EN);lv_keyboard_set_mode(kb, LV_KEYBOARD_MODE_TEXT_LOWER);}else {prv_mode = LV_IME_PINYIN_MODE_K26_EN;lv_ime_pinyin_set_mode((lv_obj_t *)pinyin_ime, LV_IME_PINYIN_MODE_K26_CH);}pinyin_ime_clear_data((lv_obj_t *)pinyin_ime);return ;}else if(lv_strcmp(txt, "abc") == 0 || lv_strcmp(txt, "ABC") == 0) {if(pinyin_ime->mode == LV_IME_PINYIN_MODE_K26_EN) {lv_keyboard_set_mode(kb,lv_keyboard_get_mode(kb) == LV_KEYBOARD_MODE_TEXT_LOWER ?LV_KEYBOARD_MODE_TEXT_UPPER : LV_KEYBOARD_MODE_TEXT_LOWER);return ;}else if(pinyin_ime->mode == LV_IME_PINYIN_MODE_K26_SPECIAL) {lv_ime_pinyin_set_mode((lv_obj_t *)pinyin_ime, LV_IME_PINYIN_MODE_K26_EN);prv_mode = LV_IME_PINYIN_MODE_K26_EN;return ;}else if(pinyin_ime->mode == LV_IME_PINYIN_MODE_K26_CH) {return ;}}else if(lv_strcmp(txt, "1#") == 0) {prv_mode = pinyin_ime->mode;lv_ime_pinyin_set_mode((lv_obj_t *)pinyin_ime, LV_IME_PINYIN_MODE_K26_SPECIAL);pinyin_ime_clear_data((lv_obj_t *)pinyin_ime);return ;}
#if LV_IME_PINYIN_USE_K9_MODEelse if(lv_strcmp(txt, "123") == 0) {lv_ime_pinyin_set_mode((lv_obj_t *)pinyin_ime, LV_IME_PINYIN_MODE_K9_NUMBER);pinyin_ime_clear_data((lv_obj_t *)pinyin_ime);return ;}
#endifelse if(lv_strcmp(txt, LV_SYMBOL_OK) == 0) {lv_obj_send_event(ta, LV_EVENT_READY, NULL);pinyin_ime_clear_data((lv_obj_t *)pinyin_ime);return;}else if(lv_strcmp(txt, LV_SYMBOL_BACKSPACE) == 0) {if(pinyin_ime->ta_count > 0) {pinyin_ime->ta_count--;lv_textarea_delete_char(ta);if(pinyin_ime->mode == LV_IME_PINYIN_MODE_K26_CH) {pinyin_ime->input_char[pinyin_ime->ta_count] = '\0';}
#if LV_IME_PINYIN_USE_K9_MODEelsepinyin_ime->k9_input_str[pinyin_ime->ta_count] = '\0';
#endifif(pinyin_ime->ta_count <= 0) {pinyin_ime_clear_data((lv_obj_t *)pinyin_ime);lv_obj_add_flag(pinyin_ime->cand_panel, LV_OBJ_FLAG_HIDDEN);}else if(pinyin_ime->mode == LV_IME_PINYIN_MODE_K26_CH) {pinyin_input_proc((lv_obj_t *)pinyin_ime);}
#if LV_IME_PINYIN_USE_K9_MODEelse if(pinyin_ime->mode == LV_IME_PINYIN_MODE_K9_CH) {pinyin_ime->k9_input_str_len = lv_strlen(pinyin_ime->input_char) - 1;pinyin_k9_get_legal_py((lv_obj_t *)pinyin_ime, pinyin_ime->k9_input_str, k9_py_map);pinyin_k9_fill_cand((lv_obj_t *)pinyin_ime);pinyin_input_proc((lv_obj_t *)pinyin_ime);pinyin_ime->ta_count--;}
#endif}else {lv_textarea_delete_char(ta);}return ;}else if(lv_strcmp(txt, LV_SYMBOL_NEW_LINE) == 0) {pinyin_ime_clear_data((lv_obj_t *)pinyin_ime);lv_textarea_add_text(ta, "\n");return ;}else if(lv_strcmp(txt, LV_SYMBOL_LEFT) == 0) {if(pinyin_ime->ta_count <= 0) {lv_textarea_cursor_left(ta);return ;}
#if LV_IME_PINYIN_USE_K9_MODEelse if(pinyin_ime->mode != LV_IME_PINYIN_MODE_K9_CH) {return ;}
#elsereturn ;
#endif}else if(lv_strcmp(txt, LV_SYMBOL_RIGHT) == 0) {if(pinyin_ime->ta_count <= 0) {lv_textarea_cursor_right(ta);return ;}
#if LV_IME_PINYIN_USE_K9_MODEelse if(pinyin_ime->mode != LV_IME_PINYIN_MODE_K9_CH) {return ;}
#elsereturn ;
#endif}#if LV_IME_PINYIN_USE_K9_MODEelse if(lv_strcmp(txt, "+/-") == 0) {uint16_t cur        = lv_textarea_get_cursor_pos(ta);const char * ta_txt = lv_textarea_get_text(ta);if(ta_txt[0] == '-') {lv_textarea_set_cursor_pos(ta, 1);lv_textarea_delete_char(ta);lv_textarea_add_char(ta, '+');lv_textarea_set_cursor_pos(ta, cur);}else if(ta_txt[0] == '+') {lv_textarea_set_cursor_pos(ta, 1);lv_textarea_delete_char(ta);lv_textarea_add_char(ta, '-');lv_textarea_set_cursor_pos(ta, cur);}else {lv_textarea_set_cursor_pos(ta, 0);lv_textarea_add_char(ta, '-');lv_textarea_set_cursor_pos(ta, cur + 1);}return ;}
#endifswitch(pinyin_ime->mode) {case LV_IME_PINYIN_MODE_K26_CH:if((txt[0] >= 'a' && txt[0] <= 'z') || (txt[0] >= 'A' && txt[0] <= 'Z')) {uint16_t len = lv_strlen(pinyin_ime->input_char);if(len < sizeof(pinyin_ime->input_char) - 1) {pinyin_ime->input_char[len] = txt[0];pinyin_ime->input_char[len + 1] = '\0';if(pinyin_input_proc((lv_obj_t *)pinyin_ime) == 0) {lv_textarea_add_text(ta, txt);pinyin_ime->ta_count++;}else {pinyin_ime->input_char[len] = '\0';}}}else {pinyin_ime_clear_data((lv_obj_t *)pinyin_ime);lv_textarea_add_text(ta, txt);}break;
#if LV_IME_PINYIN_USE_K9_MODEcase LV_IME_PINYIN_MODE_K9_CH:if((btn_id >= 16) && (lv_strlen(pinyin_ime->input_char) > 0) && (btn_id < (16 + LV_IME_PINYIN_K9_CAND_TEXT_NUM))) {uint16_t tmp_btn_str_len = lv_strlen(pinyin_ime->input_char);lv_memzero(pinyin_ime->input_char, sizeof(pinyin_ime->input_char));lv_strcat(pinyin_ime->input_char, txt);pinyin_input_proc((lv_obj_t *)pinyin_ime);uint16_t len = tmp_btn_str_len > pinyin_ime->ta_count ? tmp_btn_str_len : pinyin_ime->ta_count;for(int index = 0; index < len; index++) {lv_textarea_delete_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;}else if(txt[0] >= 'a' && txt[0] <= 'z') {for(uint16_t i = 0; i < 8; i++) {if(lv_strcmp(txt, k9_py_map[i]) == 0) {if(lv_strcmp(txt, "abc") == 0)    pinyin_ime->k9_input_str_len += lv_strlen(k9_py_map[i]) + 1;else                            pinyin_ime->k9_input_str_len += lv_strlen(k9_py_map[i]);pinyin_ime->k9_input_str[pinyin_ime->ta_count] = '2' + i;pinyin_ime->k9_input_str[pinyin_ime->ta_count + 1] = '\0';break;}}pinyin_k9_get_legal_py((lv_obj_t *)pinyin_ime, pinyin_ime->k9_input_str, k9_py_map);pinyin_k9_fill_cand((lv_obj_t *)pinyin_ime);pinyin_input_proc((lv_obj_t *)pinyin_ime);}else if(lv_strcmp(txt, LV_SYMBOL_LEFT) == 0) {pinyin_k9_cand_page_proc((lv_obj_t *)pinyin_ime, 0);}else if(lv_strcmp(txt, LV_SYMBOL_RIGHT) == 0) {pinyin_k9_cand_page_proc((lv_obj_t *)pinyin_ime, 1);}else {pinyin_ime_clear_data((lv_obj_t *)pinyin_ime);lv_textarea_add_text(ta, txt);}break;
#endifdefault:lv_textarea_add_text(ta, txt);break;}
}static void lv_ime_pinyin_cand_panel_event(lv_event_t * e)
{lv_event_code_t code = lv_event_get_code(e);lv_obj_t * cand_panel = lv_event_get_current_target(e);lv_obj_t * obj = (lv_obj_t *)lv_event_get_user_data(e);lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;if(code == LV_EVENT_VALUE_CHANGED) {lv_obj_t * ta = lv_keyboard_get_textarea(pinyin_ime->kb);if(ta == NULL) return;uint32_t id = lv_buttonmatrix_get_selected_button(cand_panel);if(id == LV_BUTTONMATRIX_BUTTON_NONE) {return;}else if(id == 0) {pinyin_page_proc(obj, 0);return;}else if(id == (LV_IME_PINYIN_CAND_TEXT_NUM + 1)) {pinyin_page_proc(obj, 1);return;}const char * txt = lv_buttonmatrix_get_button_text(cand_panel, id);uint16_t index = 0;for(index = 0; index < pinyin_ime->ta_count; index++)lv_textarea_delete_char(ta);lv_textarea_add_text(ta, txt);pinyin_ime_clear_data(obj);}
}static int pinyin_input_proc(lv_obj_t * obj)
{lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;pinyin_ime->cand_str = pinyin_search_matching(obj, pinyin_ime->input_char, &pinyin_ime->cand_num);if(pinyin_ime->cand_str == NULL) {return -1;}pinyin_ime->py_page = 0;for(uint8_t i = 0; i < LV_IME_PINYIN_CAND_TEXT_NUM; i++) {lv_memset(lv_pinyin_cand_str[i], 0x00, sizeof(lv_pinyin_cand_str[i]));lv_pinyin_cand_str[i][0] = ' ';}// fill buffor(uint8_t i = 0; (i < pinyin_ime->cand_num && i < LV_IME_PINYIN_CAND_TEXT_NUM); i++) {for(uint8_t j = 0; j < 3; j++) {lv_pinyin_cand_str[i][j] = pinyin_ime->cand_str[i * 3 + j];}}lv_obj_remove_flag(pinyin_ime->cand_panel, LV_OBJ_FLAG_HIDDEN);lv_obj_invalidate(pinyin_ime->cand_panel);return 0;
}static void pinyin_page_proc(lv_obj_t * obj, uint16_t dir)
{lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;uint16_t page_num = pinyin_ime->cand_num / LV_IME_PINYIN_CAND_TEXT_NUM;uint16_t remainder = pinyin_ime->cand_num % LV_IME_PINYIN_CAND_TEXT_NUM;if(!pinyin_ime->cand_str) return;if(dir == 0) {if(pinyin_ime->py_page) {pinyin_ime->py_page--;}}else {if(remainder == 0) {page_num -= 1;}if(pinyin_ime->py_page < page_num) {pinyin_ime->py_page++;}else return;}for(uint8_t i = 0; i < LV_IME_PINYIN_CAND_TEXT_NUM; i++) {lv_memset(lv_pinyin_cand_str[i], 0x00, sizeof(lv_pinyin_cand_str[i]));lv_pinyin_cand_str[i][0] = ' ';}// fill bufuint16_t offset = pinyin_ime->py_page * (3 * LV_IME_PINYIN_CAND_TEXT_NUM);for(uint8_t i = 0; (i < pinyin_ime->cand_num && i < LV_IME_PINYIN_CAND_TEXT_NUM); i++) {if((remainder > 0) && (pinyin_ime->py_page == page_num)) {if(i >= remainder)break;}for(uint8_t j = 0; j < 3; j++) {lv_pinyin_cand_str[i][j] = pinyin_ime->cand_str[offset + (i * 3) + j];}}
}static void lv_ime_pinyin_style_change_event(lv_event_t * e)
{lv_event_code_t code = lv_event_get_code(e);lv_obj_t * obj = lv_event_get_current_target(e);lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;if(code == LV_EVENT_STYLE_CHANGED) {const lv_font_t * font = lv_obj_get_style_text_font(obj, LV_PART_MAIN);lv_obj_set_style_text_font(pinyin_ime->cand_panel, font, 0);}
}static void init_pinyin_dict(lv_obj_t * obj, const lv_pinyin_dict_t * dict)
{lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;char headletter = 'a';uint16_t offset_sum = 0;uint16_t offset_count = 0;uint16_t letter_calc = 0;pinyin_ime->dict = dict;for(uint16_t i = 0; ; i++) {if((NULL == (dict[i].py)) || (NULL == (dict[i].py_mb))) {headletter = dict[i - 1].py[0];letter_calc = headletter - 'a';pinyin_ime->py_num[letter_calc] = offset_count;break;}if(headletter == (dict[i].py[0])) {offset_count++;}else {headletter = dict[i].py[0];pinyin_ime->py_num[letter_calc] = offset_count;letter_calc = headletter - 'a';offset_sum += offset_count;pinyin_ime->py_pos[letter_calc] = offset_sum;offset_count = 1;}}
}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;const lv_pinyin_dict_t * cpHZ;uint8_t index, len = 0, offset;volatile uint8_t count = 0;if(*py_str == '\0')    return NULL;if(*py_str == 'i')     return NULL;if(*py_str == 'u')     return NULL;if(*py_str == 'v')     return NULL;if(*py_str == ' ')     return NULL;offset = py_str[0] - 'a';len = lv_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 matchif(len == 1 || index == len) {// The Chinese character in UTF-8 encoding format is 3 bytes* cand_num = lv_strlen((const char *)(cpHZ->py_mb)) / 3;return (char *)(cpHZ->py_mb);}cpHZ++;}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_MODEif(pinyin_ime->mode == LV_IME_PINYIN_MODE_K9_CH) {pinyin_ime->k9_input_str_len = 0;pinyin_ime->k9_py_ll_pos = 0;pinyin_ime->k9_legal_py_count = 0;lv_memzero(pinyin_ime->k9_input_str,  LV_IME_PINYIN_K9_MAX_INPUT);lv_memzero(lv_pinyin_k9_cand_str, sizeof(lv_pinyin_k9_cand_str));for(uint8_t i = 0; i < LV_IME_PINYIN_CAND_TEXT_NUM; i++) {lv_strcpy(lv_pinyin_k9_cand_str[i], " ");}lv_strcpy(lv_pinyin_k9_cand_str[LV_IME_PINYIN_K9_CAND_TEXT_NUM], LV_SYMBOL_RIGHT"\0");lv_strcpy(lv_pinyin_k9_cand_str[LV_IME_PINYIN_K9_CAND_TEXT_NUM + 1], "\0");lv_buttonmatrix_set_map(pinyin_ime->kb, (const char **)lv_btnm_def_pinyin_k9_map);}
#endifpinyin_ime->ta_count = 0;for(uint8_t i = 0; i < LV_IME_PINYIN_CAND_TEXT_NUM; i++) {lv_memset(lv_pinyin_cand_str[i], 0x00, sizeof(lv_pinyin_cand_str[i]));lv_pinyin_cand_str[i][0] = ' ';}lv_memzero(pinyin_ime->input_char, sizeof(pinyin_ime->input_char));lv_buttonmatrix_set_map(pinyin_ime->cand_panel, (const char **)lv_btnm_def_pinyin_sel_map);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_UNUSED(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) {lv_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) {lv_strcpy(lv_pinyin_k9_cand_str[py_str_i], "\0");}else {lv_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_BUTTONMATRIX_CTRL_CHECKED | 1;default_kb_ctrl_k9_map[1]  = LV_BUTTONMATRIX_CTRL_NO_REPEAT | LV_BUTTONMATRIX_CTRL_CLICK_TRIG | 1;default_kb_ctrl_k9_map[4]  = LV_BUTTONMATRIX_CTRL_CHECKED | 1;default_kb_ctrl_k9_map[5]  = LV_BUTTONMATRIX_CTRL_CHECKED | 1;default_kb_ctrl_k9_map[9]  = LV_KEYBOARD_CTRL_BUTTON_FLAGS | 1;default_kb_ctrl_k9_map[10] = LV_BUTTONMATRIX_CTRL_CHECKED | 1;default_kb_ctrl_k9_map[14] = LV_BUTTONMATRIX_CTRL_CHECKED | 1;default_kb_ctrl_k9_map[15] = LV_BUTTONMATRIX_CTRL_CHECKED | 1;default_kb_ctrl_k9_map[LV_IME_PINYIN_K9_CAND_TEXT_NUM + 16] = LV_BUTTONMATRIX_CTRL_CHECKED | 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 = lv_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;uint16_t 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);lv_strcpy(ll_index->py_str, py_comp);}else if((count < ll_len)) {lv_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((size_t)flag < lv_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--;}}}lv_obj_t * ta = lv_keyboard_get_textarea(((lv_ime_pinyin_t *)obj)->kb);for(index = 0; index < pinyin_ime->ta_count; index++) {lv_textarea_delete_char(ta);}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;const lv_pinyin_dict_t * cpHZ = NULL;uint8_t index = 0, len = 0, offset = 0;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 = lv_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 matchif(len == 1 || index == len) {return true;}cpHZ++;}return false;
}static void pinyin_k9_fill_cand(lv_obj_t * obj)
{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 != cand_len) {lv_memzero(lv_pinyin_k9_cand_str, sizeof(lv_pinyin_k9_cand_str));lv_strcpy(lv_pinyin_k9_cand_str[LV_IME_PINYIN_K9_CAND_TEXT_NUM], LV_SYMBOL_RIGHT"\0");lv_strcpy(lv_pinyin_k9_cand_str[LV_IME_PINYIN_K9_CAND_TEXT_NUM + 1], "\0");cand_len = tmp_len;}ll_index = lv_ll_get_head(&pinyin_ime->k9_legal_py_ll);lv_strcpy(pinyin_ime->input_char, ll_index->py_str);for(uint8_t i = 0; i < LV_IME_PINYIN_K9_CAND_TEXT_NUM; i++) {lv_strcpy(lv_pinyin_k9_cand_str[i], " ");}while(ll_index) {if(index >= LV_IME_PINYIN_K9_CAND_TEXT_NUM)break;if(index < pinyin_ime->k9_legal_py_count) {lv_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);pinyin_ime->k9_input_str_len = lv_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;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_memzero(lv_pinyin_k9_cand_str, sizeof(lv_pinyin_k9_cand_str));lv_strcpy(lv_pinyin_k9_cand_str[LV_IME_PINYIN_K9_CAND_TEXT_NUM], LV_SYMBOL_RIGHT"\0");lv_strcpy(lv_pinyin_k9_cand_str[LV_IME_PINYIN_K9_CAND_TEXT_NUM + 1], "\0");// next pageif(dir == 1) {for(uint8_t i = 0; i < LV_IME_PINYIN_K9_CAND_TEXT_NUM; i++) {lv_strcpy(lv_pinyin_k9_cand_str[i], " ");}count = 0;while(ll_index) {if(count >= (LV_IME_PINYIN_K9_CAND_TEXT_NUM - 1))break;lv_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 pageelse {for(uint8_t i = 0; i < LV_IME_PINYIN_K9_CAND_TEXT_NUM; i++) {lv_strcpy(lv_pinyin_k9_cand_str[i], " ");}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;lv_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*/

lv_ime_pinyin.h

/*** @file lv_ime_pinyin.h**/
#ifndef LV_IME_PINYIN_H
#define LV_IME_PINYIN_H#ifdef __cplusplus
extern "C" {
#endif/**********************      INCLUDES*********************/
#include "../../lv_conf_internal.h"
#include "../../core/lv_obj.h"#if LV_USE_IME_PINYIN != 0/**********************      DEFINES*********************/
#if LV_IME_PINYIN_USE_K9_MODE
#define LV_IME_PINYIN_K9_MAX_INPUT  7
#endif
/***********************      TYPEDEFS**********************/typedef enum {LV_IME_PINYIN_MODE_K26_CH,LV_IME_PINYIN_MODE_K26_EN,LV_IME_PINYIN_MODE_K26_SPECIAL,
#if LV_IME_PINYIN_USE_K9_MODELV_IME_PINYIN_MODE_K9_NUMBER,LV_IME_PINYIN_MODE_K9_CH,
#endif
} 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;/************************ GLOBAL VARIABLES***********************/extern const lv_obj_class_t lv_ime_pinyin_class;/*********************** 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 kb 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);/*** 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*====================*//*** 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*/
const 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_IME_PINYIN_H*/

lv_example_ime_pinyin_1.c

#include "../../lv_examples.h"
#if LV_USE_LABEL && LV_USE_TEXTAREA && LV_FONT_SOURCE_HAN_SANS_SC_16_CJK && LV_USE_IME_PINYIN && LV_BUILD_EXAMPLESstatic 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_obj(e);lv_obj_t * kb = (lv_obj_t *) lv_event_get_user_data(e);if(code == LV_EVENT_FOCUSED) {if(lv_indev_get_type(lv_indev_active()) != LV_INDEV_TYPE_KEYPAD) {lv_keyboard_set_textarea(kb, ta);lv_obj_remove_flag(kb, LV_OBJ_FLAG_HIDDEN);}}else if(code == LV_EVENT_CANCEL || code == LV_EVENT_DEFOCUSED || code == LV_EVENT_READY) {lv_obj_add_flag(kb, LV_OBJ_FLAG_HIDDEN);lv_obj_remove_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_screen_active());lv_obj_set_style_text_font(pinyin_ime, &lv_font_source_han_sans_sc_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_screen_active());lv_textarea_set_one_line(ta1, true);lv_obj_set_style_text_font(ta1, &lv_font_source_han_sans_sc_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_screen_active());lv_ime_pinyin_set_keyboard(pinyin_ime, kb);lv_keyboard_set_textarea(kb, ta1);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);
}#endif

http://www.dtcms.com/a/389646.html

相关文章:

  • 多层感知机:从感知机到深度学习的关键一步
  • PostgreSQL绿色版整合PostGIS插件,以Windows 64位系统为例
  • GEO优化推荐案例:2025年上海源易信息科技的全链路实践
  • 时空预测论文分享:多模态融合 空间索引结构 超图 时演化因果关系
  • 智能手机产量增长4%
  • MySQL高可用MHA实战指南
  • Coze源码分析-资源库-创建工作流-后端源码-核心技术/总结
  • 《棒球团建》国家级运动健将·棒球1号位
  • 基于STM32单片机生理监控心率脉搏TFT彩屏波形曲线加体温测量
  • Selenium 浏览器自动化完全指南:从环境搭建到实战应用
  • C51单片机——开发学习:中断
  • 树与二叉树【数据结构】
  • RPM包版本号系统解析:设计哲学、比较规则与实践指南
  • IDEA启动异常
  • vite使用vue2项目
  • 前端性能优化实用方案(一):减少50%首屏资源体积的Webpack配置
  • SQL 条件函数 IF、CASE WHEN 用法速查
  • 【深度学习新浪潮】如何估算大模型的训练和推理内存需求?
  • PyTorch查看模块/类的所有方法/属性
  • 8大Android开发框架效率翻倍
  • docker基础知识与具体实践
  • 【多模态】Simple o3 提高多模态模型准确率
  • hybrid的配置
  • 理解虚拟细胞:初学者指南
  • 哪种体量的公司或者哪些行业哪些项目需要上云服务器?
  • Linux安装问题:404 Not Found?配置源列表sources.list,修改为可用镜像源就可以了!
  • Vue3 中 props 与 $emit 的使用及 defineProps 与 defineEmits 的区别详解
  • vue的跨域配置
  • 计算机网络实验03:交换机VLAN配置
  • Vue中v-if与v-show的区别及应用场景解析