1 /**
2 * @file lv_ime_pinyin.c
3 *
4 */
5
6 /*********************
7 * INCLUDES
8 *********************/
9 #include "lv_ime_pinyin_private.h"
10 #include "../../core/lv_obj_class_private.h"
11 #if LV_USE_IME_PINYIN != 0
12
13 #include "../../lvgl.h"
14 #include "../../core/lv_global.h"
15
16 /*********************
17 * DEFINES
18 *********************/
19 #define MY_CLASS (&lv_ime_pinyin_class)
20 #define cand_len LV_GLOBAL_DEFAULT()->ime_cand_len
21
22 /**********************
23 * TYPEDEFS
24 **********************/
25
26 /**********************
27 * STATIC PROTOTYPES
28 **********************/
29 static void lv_ime_pinyin_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
30 static void lv_ime_pinyin_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
31 static void lv_ime_pinyin_style_change_event(lv_event_t * e);
32 static void lv_ime_pinyin_kb_event(lv_event_t * e);
33 static void lv_ime_pinyin_cand_panel_event(lv_event_t * e);
34
35 static void init_pinyin_dict(lv_obj_t * obj, const lv_pinyin_dict_t * dict);
36 static void pinyin_input_proc(lv_obj_t * obj);
37 static void pinyin_page_proc(lv_obj_t * obj, uint16_t btn);
38 static char * pinyin_search_matching(lv_obj_t * obj, char * py_str, uint16_t * cand_num);
39 static void pinyin_ime_clear_data(lv_obj_t * obj);
40
41 #if LV_IME_PINYIN_USE_K9_MODE
42 static void pinyin_k9_init_data(lv_obj_t * obj);
43 static void pinyin_k9_get_legal_py(lv_obj_t * obj, char * k9_input, const char * py9_map[]);
44 static bool pinyin_k9_is_valid_py(lv_obj_t * obj, char * py_str);
45 static void pinyin_k9_fill_cand(lv_obj_t * obj);
46 static void pinyin_k9_cand_page_proc(lv_obj_t * obj, uint16_t dir);
47 #endif
48
49 /**********************
50 * STATIC VARIABLES
51 **********************/
52
53 const lv_obj_class_t lv_ime_pinyin_class = {
54 .constructor_cb = lv_ime_pinyin_constructor,
55 .destructor_cb = lv_ime_pinyin_destructor,
56 .width_def = LV_SIZE_CONTENT,
57 .height_def = LV_SIZE_CONTENT,
58 .group_def = LV_OBJ_CLASS_GROUP_DEF_TRUE,
59 .instance_size = sizeof(lv_ime_pinyin_t),
60 .base_class = &lv_obj_class,
61 .name = "ime-pinyin",
62 };
63
64 #if LV_IME_PINYIN_USE_K9_MODE
65 static const char * lv_btnm_def_pinyin_k9_map[LV_IME_PINYIN_K9_CAND_TEXT_NUM + 21] = {\
66 ",\0", "123\0", "abc \0", "def\0", LV_SYMBOL_BACKSPACE"\0", "\n\0",
67 ".\0", "ghi\0", "jkl\0", "mno\0", LV_SYMBOL_KEYBOARD"\0", "\n\0",
68 "?\0", "pqrs\0", "tuv\0", "wxyz\0", LV_SYMBOL_NEW_LINE"\0", "\n\0",
69 LV_SYMBOL_LEFT"\0", "\0"
70 };
71
72 static lv_buttonmatrix_ctrl_t default_kb_ctrl_k9_map[LV_IME_PINYIN_K9_CAND_TEXT_NUM + 17] = { 1 };
73 static char lv_pinyin_k9_cand_str[LV_IME_PINYIN_K9_CAND_TEXT_NUM + 2][LV_IME_PINYIN_K9_MAX_INPUT] = {0};
74 #endif
75
76 static char lv_pinyin_cand_str[LV_IME_PINYIN_CAND_TEXT_NUM][4];
77 static char * lv_btnm_def_pinyin_sel_map[LV_IME_PINYIN_CAND_TEXT_NUM + 3];
78
79 #if LV_IME_PINYIN_USE_DEFAULT_DICT
80 static const lv_pinyin_dict_t lv_ime_pinyin_def_dict[] = {
81 { "a", "啊" },
82 { "ai", "愛" },
83 { "an", "安暗案" },
84 { "ba", "吧把爸八" },
85 { "bai", "百白敗" },
86 { "ban", "半般辦" },
87 { "bang", "旁" },
88 { "bao", "保薄包報" },
89 { "bei", "被背悲北杯備" },
90 { "ben", "本" },
91 { "bi", "必比避鼻彼筆秘閉" },
92 { "bian", "便邊變変辺" },
93 { "biao", "表標" },
94 { "bie", "別" },
95 { "bing", "病並氷" },
96 { "bo", "波薄泊" },
97 { "bu", "不布步部捕補歩" },
98 { "ca", "察" },
99 { "cai", "才材菜財採" },
100 { "can", "参残參" },
101 { "ce", "策側" },
102 { "ceng", "曾" },
103 { "cha", "差查茶" },
104 { "chai", "差" },
105 { "chan", "產産單" },
106 { "chang", "場廠" },
107 { "chao", "超朝" },
108 { "che", "車" },
109 { "cheng", "成程乗" },
110 { "chi", "尺吃持赤池遅歯" },
111 { "chong", "充种重種" },
112 { "chu", "出初楚触處処" },
113 { "chuan", "川船傳" },
114 { "chuang", "創窓" },
115 { "chun", "春" },
116 { "ci", "此次辞差" },
117 { "cong", "從従" },
118 { "cu", "卒" },
119 { "cun", "存村" },
120 { "cuo", "錯" },
121 { "da", "大打答達" },
122 { "dai", "代待帯帶貸" },
123 { "dan", "但担擔誕單単" },
124 { "dang", "当党當黨" },
125 { "dao", "到道盗導島辺" },
126 { "de", "的得" },
127 { "dei", "" },
128 { "deng", "等" },
129 { "di", "地得低底弟第締" },
130 { "dian", "点电店點電" },
131 { "diao", "調" },
132 { "ding", "定町" },
133 { "dong", "冬東動働凍" },
134 { "du", "独度都渡読" },
135 { "duan", "段断短斷" },
136 { "dui", "對対" },
137 { "duo", "多駄" },
138 { "e", "嗯悪" },
139 { "en", "嗯" },
140 { "er", "而耳二兒" },
141 { "fa", "乏法發発髪" },
142 { "fan", "反返犯番仮販飯範払" },
143 { "fang", "方放房坊訪" },
144 { "fei", "非飛費" },
145 { "fen", "分份" },
146 { "feng", "風豐" },
147 { "fou", "否不" },
148 { "fu", "父夫富服符付附府幅婦復複負払" },
149 { "gai", "改概該" },
150 { "gan", "甘感敢" },
151 { "gang", "港剛" },
152 { "gao", "告高" },
153 { "ge", "各格歌革割個" },
154 { "gei", "給" },
155 { "gen", "跟根" },
156 { "geng", "更" },
157 { "gong", "工共供功公" },
158 { "gou", "夠構溝" },
159 { "gu", "古故鼓" },
160 { "guai", "掛" },
161 { "guan", "官管慣館觀関關" },
162 { "guang", "光広" },
163 { "gui", "規帰" },
164 { "guo", "果国裏菓國過" },
165 { "hai", "孩海害還" },
166 { "han", "寒漢" },
167 { "hang", "航行" },
168 { "hao", "好号" },
169 { "he", "合和喝何荷" },
170 { "hei", "黒" },
171 { "hen", "很" },
172 { "heng", "行横" },
173 { "hou", "厚喉候後" },
174 { "hu", "乎呼湖護" },
175 { "hua", "化画花話畫劃" },
176 { "huai", "壊劃" },
177 { "huan", "緩環歡還換" },
178 { "huang", "黄" },
179 { "hui", "回会慧絵揮會" },
180 { "hun", "混婚" },
181 { "huo", "活或火獲" },
182 { "i", "" },
183 { "ji", "己计及机既急季寄技即集基祭系奇紀積計記済幾際極繼績機濟" },
184 { "jia", "家加價" },
185 { "jian", "件建健肩見減間検簡漸" },
186 { "jiang", "降強講將港" },
187 { "jiao", "叫教交角覚覺較學" },
188 { "jie", "介借接姐皆届界解結階節價" },
189 { "jin", "今近禁金僅進" },
190 { "jing", "京境景静精經経" },
191 { "jiu", "就久九酒究" },
192 { "ju", "句具局居決挙據舉" },
193 { "jue", "角覚覺" },
194 { "jun", "均" },
195 { "kai", "開" },
196 { "kan", "看刊" },
197 { "kang", "康" },
198 { "kao", "考" },
199 { "ke", "可刻科克客渇課" },
200 { "ken", "肯" },
201 { "kong", "空控" },
202 { "kou", "口" },
203 { "ku", "苦庫" },
204 { "kuai", "快塊会會" },
205 { "kuang", "況" },
206 { "kun", "困" },
207 { "kuo", "括拡適" },
208 { "la", "拉啦落" },
209 { "lai", "来來頼" },
210 { "lao", "老絡落" },
211 { "le", "了楽樂" },
212 { "lei", "類" },
213 { "leng", "冷" },
214 { "li", "力立利理例礼離麗裡勵歷" },
215 { "lian", "連練臉聯" },
216 { "liang", "良量涼兩両" },
217 { "liao", "料" },
218 { "lie", "列" },
219 { "lin", "林隣賃" },
220 { "ling", "另令領" },
221 { "liu", "六留流" },
222 { "lu", "律路録緑陸履慮" },
223 { "lv", "旅" },
224 { "lun", "輪論" },
225 { "luo", "落絡" },
226 { "ma", "媽嗎嘛" },
227 { "mai", "買売" },
228 { "man", "滿" },
229 { "mang", "忙" },
230 { "mao", "毛猫貿" },
231 { "me", "麼" },
232 { "mei", "美妹每沒毎媒" },
233 { "men", "們" },
234 { "mi", "米密秘" },
235 { "mian", "免面勉眠" },
236 { "miao", "描" },
237 { "min", "民皿" },
238 { "ming", "命明名" },
239 { "mo", "末模麼" },
240 { "mou", "某" },
241 { "mu", "母木目模" },
242 { "na", "那哪拿內南" },
243 { "nan", "男南難" },
244 { "nao", "腦" },
245 { "ne", "那哪呢" },
246 { "nei", "内那哪內" },
247 { "neng", "能" },
248 { "ni", "你妳呢" },
249 { "nian", "年念" },
250 { "niang", "娘" },
251 { "nin", "您" },
252 { "ning", "凝" },
253 { "niu", "牛" },
254 { "nong", "農濃" },
255 { "nu", "女努" },
256 { "nuan", "暖" },
257 { "o", "" },
258 { "ou", "歐" },
259 { "pa", "怕" },
260 { "pai", "迫派排" },
261 { "pan", "判番" },
262 { "pang", "旁" },
263 { "pei", "配" },
264 { "peng", "朋" },
265 { "pi", "疲否" },
266 { "pian", "片便" },
267 { "pin", "品貧" },
268 { "ping", "平評" },
269 { "po", "迫破泊頗" },
270 { "pu", "普僕" },
271 { "qi", "起其奇七气期泣企妻契気" },
272 { "qian", "嵌浅千前鉛錢針" },
273 { "qiang", "強將" },
274 { "qiao", "橋繰" },
275 { "qie", "且切契" },
276 { "qin", "寝勤親" },
277 { "qing", "青清情晴輕頃請軽" },
278 { "qiu", "求秋球" },
279 { "qu", "去取趣曲區" },
280 { "quan", "全犬券" },
281 { "que", "缺確卻" },
282 { "ran", "然" },
283 { "rang", "讓" },
284 { "re", "熱" },
285 { "ren", "人任認" },
286 { "reng", "仍" },
287 { "ri", "日" },
288 { "rong", "容" },
289 { "rou", "弱若肉" },
290 { "ru", "如入" },
291 { "ruan", "軟" },
292 { "sai", "賽" },
293 { "san", "三" },
294 { "sao", "騒繰" },
295 { "se", "色" },
296 { "sen", "森" },
297 { "sha", "砂" },
298 { "shan", "善山單" },
299 { "shang", "上尚商" },
300 { "shao", "少紹" },
301 { "shaung", "雙" },
302 { "she", "社射設捨渉" },
303 { "shei", "誰" },
304 { "shen", "什申深甚身伸沈神" },
305 { "sheng", "生声昇勝乗聲" },
306 { "shi", "是失示食时事式十石施使世实史室市始柿氏士仕拭時視師試適実實識" },
307 { "shou", "手首守受授" },
308 { "shu", "束数暑殊樹書屬輸術" },
309 { "shui", "水説說誰" },
310 { "shuo", "数説說" },
311 { "si", "思寺司四私似死価" },
312 { "song", "送" },
313 { "su", "速宿素蘇訴" },
314 { "suan", "算酸" },
315 { "sui", "隨雖歲歳" },
316 { "sun", "孫" },
317 { "suo", "所" },
318 { "ta", "她他它牠" },
319 { "tai", "太台態臺" },
320 { "tan", "探談曇" },
321 { "tang", "糖" },
322 { "tao", "桃逃套討" },
323 { "te", "特" },
324 { "ti", "体提替題體戻" },
325 { "tian", "天田" },
326 { "tiao", "条條調" },
327 { "tie", "鉄" },
328 { "ting", "停庭聽町" },
329 { "tong", "同童通痛统統" },
330 { "tou", "投透頭" },
331 { "tu", "土徒茶図" },
332 { "tuan", "團" },
333 { "tui", "推退" },
334 { "tuo", "脱駄" },
335 { "u", "" },
336 { "v", "" },
337 { "wai", "外" },
338 { "wan", "完万玩晩腕灣" },
339 { "wang", "忘望亡往網" },
340 { "wei", "危位未味委為謂維違圍" },
341 { "wen", "文温問聞" },
342 { "wo", "我" },
343 { "wu", "午物五無屋亡鳥務汚" },
344 { "xi", "夕息西洗喜系昔席希析嬉膝細習係" },
345 { "xia", "下夏狭暇" },
346 { "xian", "先限嫌洗現見線顯" },
347 { "xiang", "向相香像想象降項詳響" },
348 { "xiao", "小笑消效校削咲" },
349 { "xie", "写携些解邪械協謝寫契" },
350 { "xin", "心信新辛" },
351 { "xing", "行形性幸型星興" },
352 { "xiong", "兄胸" },
353 { "xiu", "休秀修" },
354 { "xu", "須需許續緒続" },
355 { "xuan", "選懸" },
356 { "xue", "学雪削靴學" },
357 { "xun", "訓訊" },
358 { "ya", "呀押壓" },
359 { "yan", "言顔研煙嚴厳験驗塩" },
360 { "yang", "央洋陽樣様" },
361 { "yao", "要揺腰薬曜" },
362 { "ye", "也野夜邪業葉" },
363 { "yi", "一已亦依以移意医易伊役異億義議藝醫訳" },
364 { "yin", "因引音飲銀" },
365 { "ying", "英迎影映應營営" },
366 { "yong", "永用泳擁" },
367 { "you", "又有右友由尤油遊郵誘優" },
368 { "yu", "予育余雨浴欲愈御宇域語於魚與込" },
369 { "yuan", "元原源院員円園遠猿願" },
370 { "yue", "月越約楽" },
371 { "yun", "雲伝運" },
372 { "za", "雑" },
373 { "zai", "在再載災" },
374 { "zang", "蔵" },
375 { "zao", "早造" },
376 { "ze", "則擇責" },
377 { "zen", "怎" },
378 { "zeng", "曾增増" },
379 { "zha", "札" },
380 { "zhai", "宅擇" },
381 { "zhan", "站展戰戦" },
382 { "zhang", "丈長障帳張" },
383 { "zhao", "找着朝招" },
384 { "zhe", "者這" },
385 { "zhen", "真震針" },
386 { "zheng", "正整争政爭" },
387 { "zhi", "之只知支止制至治直指值置智値紙製質誌織隻識職執" },
388 { "zhong", "中种終重種眾" },
389 { "zhou", "周州昼宙洲週" },
390 { "zhu", "助主住柱株祝逐注著諸屬術" },
391 { "zhuan", "专專転" },
392 { "zhuang", "状狀" },
393 { "zhui", "追" },
394 { "zhun", "準" },
395 { "zhuo", "着" },
396 { "zi", "子自字姉資" },
397 { "zong", "總" },
398 { "zuo", "左做昨坐座作" },
399 { "zu", "足祖族卒組" },
400 { "zui", "最酔" },
401 { "zou", "走" },
402 {NULL, NULL}
403 };
404 #endif
405
406 /**********************
407 * MACROS
408 **********************/
409
410 /**********************
411 * GLOBAL FUNCTIONS
412 **********************/
lv_ime_pinyin_create(lv_obj_t * parent)413 lv_obj_t * lv_ime_pinyin_create(lv_obj_t * parent)
414 {
415 LV_LOG_INFO("begin");
416 lv_obj_t * obj = lv_obj_class_create_obj(MY_CLASS, parent);
417 lv_obj_class_init_obj(obj);
418 return obj;
419 }
420
421 /*=====================
422 * Setter functions
423 *====================*/
424
lv_ime_pinyin_set_keyboard(lv_obj_t * obj,lv_obj_t * kb)425 void lv_ime_pinyin_set_keyboard(lv_obj_t * obj, lv_obj_t * kb)
426 {
427 if(kb) {
428 LV_ASSERT_OBJ(kb, &lv_keyboard_class);
429 }
430
431 LV_ASSERT_OBJ(obj, MY_CLASS);
432 lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;
433
434 pinyin_ime->kb = kb;
435 lv_obj_set_parent(obj, lv_obj_get_parent(kb));
436 lv_obj_set_parent(pinyin_ime->cand_panel, lv_obj_get_parent(kb));
437 lv_obj_add_event_cb(pinyin_ime->kb, lv_ime_pinyin_kb_event, LV_EVENT_VALUE_CHANGED, obj);
438 lv_obj_align_to(pinyin_ime->cand_panel, pinyin_ime->kb, LV_ALIGN_OUT_TOP_MID, 0, 0);
439 }
440
lv_ime_pinyin_set_dict(lv_obj_t * obj,lv_pinyin_dict_t * dict)441 void lv_ime_pinyin_set_dict(lv_obj_t * obj, lv_pinyin_dict_t * dict)
442 {
443 LV_ASSERT_OBJ(obj, MY_CLASS);
444
445 init_pinyin_dict(obj, dict);
446 }
447
lv_ime_pinyin_set_mode(lv_obj_t * obj,lv_ime_pinyin_mode_t mode)448 void lv_ime_pinyin_set_mode(lv_obj_t * obj, lv_ime_pinyin_mode_t mode)
449 {
450 LV_ASSERT_OBJ(obj, MY_CLASS);
451 lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;
452
453 LV_ASSERT_OBJ(pinyin_ime->kb, &lv_keyboard_class);
454
455 pinyin_ime->mode = mode;
456
457 #if LV_IME_PINYIN_USE_K9_MODE
458 if(pinyin_ime->mode == LV_IME_PINYIN_MODE_K9) {
459 pinyin_k9_init_data(obj);
460 lv_keyboard_set_map(pinyin_ime->kb, LV_KEYBOARD_MODE_USER_1, (const char **)lv_btnm_def_pinyin_k9_map,
461 default_kb_ctrl_k9_map);
462 lv_keyboard_set_mode(pinyin_ime->kb, LV_KEYBOARD_MODE_USER_1);
463 }
464 #endif
465 }
466
467 /*=====================
468 * Getter functions
469 *====================*/
470
lv_ime_pinyin_get_kb(lv_obj_t * obj)471 lv_obj_t * lv_ime_pinyin_get_kb(lv_obj_t * obj)
472 {
473 LV_ASSERT_OBJ(obj, MY_CLASS);
474
475 lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;
476
477 return pinyin_ime->kb;
478 }
479
lv_ime_pinyin_get_cand_panel(lv_obj_t * obj)480 lv_obj_t * lv_ime_pinyin_get_cand_panel(lv_obj_t * obj)
481 {
482 LV_ASSERT_OBJ(obj, MY_CLASS);
483
484 lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;
485
486 return pinyin_ime->cand_panel;
487 }
488
lv_ime_pinyin_get_dict(lv_obj_t * obj)489 const lv_pinyin_dict_t * lv_ime_pinyin_get_dict(lv_obj_t * obj)
490 {
491 LV_ASSERT_OBJ(obj, MY_CLASS);
492
493 lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;
494
495 return pinyin_ime->dict;
496 }
497
498 /*=====================
499 * Other functions
500 *====================*/
501
502 /**********************
503 * STATIC FUNCTIONS
504 **********************/
505
lv_ime_pinyin_constructor(const lv_obj_class_t * class_p,lv_obj_t * obj)506 static void lv_ime_pinyin_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
507 {
508 LV_UNUSED(class_p);
509 LV_TRACE_OBJ_CREATE("begin");
510
511 lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;
512
513 uint16_t py_str_i = 0;
514 uint16_t btnm_i = 0;
515 for(btnm_i = 0; btnm_i < (LV_IME_PINYIN_CAND_TEXT_NUM + 3); btnm_i++) {
516 if(btnm_i == 0) {
517 lv_btnm_def_pinyin_sel_map[btnm_i] = "<";
518 }
519 else if(btnm_i == (LV_IME_PINYIN_CAND_TEXT_NUM + 1)) {
520 lv_btnm_def_pinyin_sel_map[btnm_i] = ">";
521 }
522 else if(btnm_i == (LV_IME_PINYIN_CAND_TEXT_NUM + 2)) {
523 lv_btnm_def_pinyin_sel_map[btnm_i] = "";
524 }
525 else {
526 lv_pinyin_cand_str[py_str_i][0] = ' ';
527 lv_btnm_def_pinyin_sel_map[btnm_i] = lv_pinyin_cand_str[py_str_i];
528 py_str_i++;
529 }
530 }
531
532 pinyin_ime->mode = LV_IME_PINYIN_MODE_K26;
533 pinyin_ime->py_page = 0;
534 pinyin_ime->ta_count = 0;
535 pinyin_ime->cand_num = 0;
536 lv_memzero(pinyin_ime->input_char, sizeof(pinyin_ime->input_char));
537 lv_memzero(pinyin_ime->py_num, sizeof(pinyin_ime->py_num));
538 lv_memzero(pinyin_ime->py_pos, sizeof(pinyin_ime->py_pos));
539
540 lv_obj_add_flag(obj, LV_OBJ_FLAG_HIDDEN);
541
542 #if LV_IME_PINYIN_USE_DEFAULT_DICT
543 init_pinyin_dict(obj, lv_ime_pinyin_def_dict);
544 #endif
545
546 /* Init pinyin_ime->cand_panel */
547 pinyin_ime->cand_panel = lv_buttonmatrix_create(lv_obj_get_parent(obj));
548 lv_buttonmatrix_set_map(pinyin_ime->cand_panel, (const char **)lv_btnm_def_pinyin_sel_map);
549 lv_obj_set_size(pinyin_ime->cand_panel, LV_PCT(100), LV_PCT(5));
550 lv_obj_add_flag(pinyin_ime->cand_panel, LV_OBJ_FLAG_HIDDEN);
551
552 lv_buttonmatrix_set_one_checked(pinyin_ime->cand_panel, true);
553 lv_obj_remove_flag(pinyin_ime->cand_panel, LV_OBJ_FLAG_CLICK_FOCUSABLE);
554
555 /* Set cand_panel style*/
556 // Default style
557 lv_obj_set_style_bg_opa(pinyin_ime->cand_panel, LV_OPA_0, 0);
558 lv_obj_set_style_border_width(pinyin_ime->cand_panel, 0, 0);
559 lv_obj_set_style_pad_all(pinyin_ime->cand_panel, 8, 0);
560 lv_obj_set_style_pad_gap(pinyin_ime->cand_panel, 0, 0);
561 lv_obj_set_style_radius(pinyin_ime->cand_panel, 0, 0);
562 lv_obj_set_style_pad_gap(pinyin_ime->cand_panel, 0, 0);
563 lv_obj_set_style_base_dir(pinyin_ime->cand_panel, LV_BASE_DIR_LTR, 0);
564
565 // LV_PART_ITEMS style
566 lv_obj_set_style_radius(pinyin_ime->cand_panel, 12, LV_PART_ITEMS);
567 lv_obj_set_style_bg_color(pinyin_ime->cand_panel, lv_color_white(), LV_PART_ITEMS);
568 lv_obj_set_style_bg_opa(pinyin_ime->cand_panel, LV_OPA_0, LV_PART_ITEMS);
569 lv_obj_set_style_shadow_opa(pinyin_ime->cand_panel, LV_OPA_0, LV_PART_ITEMS);
570
571 // LV_PART_ITEMS | LV_STATE_PRESSED style
572 lv_obj_set_style_bg_opa(pinyin_ime->cand_panel, LV_OPA_COVER, LV_PART_ITEMS | LV_STATE_PRESSED);
573 lv_obj_set_style_bg_color(pinyin_ime->cand_panel, lv_color_white(), LV_PART_ITEMS | LV_STATE_PRESSED);
574
575 /* event handler */
576 lv_obj_add_event_cb(pinyin_ime->cand_panel, lv_ime_pinyin_cand_panel_event, LV_EVENT_VALUE_CHANGED, obj);
577 lv_obj_add_event_cb(obj, lv_ime_pinyin_style_change_event, LV_EVENT_STYLE_CHANGED, NULL);
578
579 #if LV_IME_PINYIN_USE_K9_MODE
580 pinyin_ime->k9_input_str_len = 0;
581 pinyin_ime->k9_py_ll_pos = 0;
582 pinyin_ime->k9_legal_py_count = 0;
583 lv_memzero(pinyin_ime->k9_input_str, LV_IME_PINYIN_K9_MAX_INPUT);
584
585 pinyin_k9_init_data(obj);
586
587 lv_ll_init(&(pinyin_ime->k9_legal_py_ll), sizeof(ime_pinyin_k9_py_str_t));
588 #endif
589 }
590
lv_ime_pinyin_destructor(const lv_obj_class_t * class_p,lv_obj_t * obj)591 static void lv_ime_pinyin_destructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
592 {
593 LV_UNUSED(class_p);
594
595 lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;
596
597 if(lv_obj_is_valid(pinyin_ime->kb))
598 lv_obj_delete(pinyin_ime->kb);
599
600 if(lv_obj_is_valid(pinyin_ime->cand_panel))
601 lv_obj_delete(pinyin_ime->cand_panel);
602 }
603
lv_ime_pinyin_kb_event(lv_event_t * e)604 static void lv_ime_pinyin_kb_event(lv_event_t * e)
605 {
606 lv_event_code_t code = lv_event_get_code(e);
607 lv_obj_t * kb = lv_event_get_current_target(e);
608 lv_obj_t * obj = lv_event_get_user_data(e);
609
610 lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;
611
612 #if LV_IME_PINYIN_USE_K9_MODE
613 static const char * k9_py_map[8] = {"abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
614 #endif
615
616 if(code == LV_EVENT_VALUE_CHANGED) {
617 uint16_t btn_id = lv_buttonmatrix_get_selected_button(kb);
618 if(btn_id == LV_BUTTONMATRIX_BUTTON_NONE) return;
619
620 const char * txt = lv_buttonmatrix_get_button_text(kb, lv_buttonmatrix_get_selected_button(kb));
621 if(txt == NULL) return;
622
623 lv_obj_t * ta = lv_keyboard_get_textarea(pinyin_ime->kb);
624
625 #if LV_IME_PINYIN_USE_K9_MODE
626 if(pinyin_ime->mode == LV_IME_PINYIN_MODE_K9) {
627
628 uint16_t tmp_button_str_len = lv_strlen(pinyin_ime->input_char);
629 if((btn_id >= 16) && (tmp_button_str_len > 0) && (btn_id < (16 + LV_IME_PINYIN_K9_CAND_TEXT_NUM))) {
630 lv_memzero(pinyin_ime->input_char, sizeof(pinyin_ime->input_char));
631 lv_strcat(pinyin_ime->input_char, txt);
632 pinyin_input_proc(obj);
633
634 for(int index = 0; index < (pinyin_ime->ta_count + tmp_button_str_len); index++) {
635 lv_textarea_delete_char(ta);
636 }
637
638 pinyin_ime->ta_count = tmp_button_str_len;
639 pinyin_ime->k9_input_str_len = tmp_button_str_len;
640 lv_textarea_add_text(ta, pinyin_ime->input_char);
641
642 return;
643 }
644 }
645 #endif
646
647 if(lv_strcmp(txt, "Enter") == 0 || lv_strcmp(txt, LV_SYMBOL_NEW_LINE) == 0) {
648 pinyin_ime_clear_data(obj);
649 lv_obj_add_flag(pinyin_ime->cand_panel, LV_OBJ_FLAG_HIDDEN);
650 }
651 else if(lv_strcmp(txt, LV_SYMBOL_BACKSPACE) == 0) {
652 // del input char
653 if(pinyin_ime->ta_count > 0) {
654 if(pinyin_ime->mode == LV_IME_PINYIN_MODE_K26)
655 pinyin_ime->input_char[pinyin_ime->ta_count - 1] = '\0';
656 #if LV_IME_PINYIN_USE_K9_MODE
657 else
658 pinyin_ime->k9_input_str[pinyin_ime->ta_count - 1] = '\0';
659 #endif
660
661 pinyin_ime->ta_count--;
662 if(pinyin_ime->ta_count <= 0) {
663 pinyin_ime_clear_data(obj);
664 lv_obj_add_flag(pinyin_ime->cand_panel, LV_OBJ_FLAG_HIDDEN);
665 }
666 else if(pinyin_ime->mode == LV_IME_PINYIN_MODE_K26) {
667 pinyin_input_proc(obj);
668 }
669 #if LV_IME_PINYIN_USE_K9_MODE
670 else if(pinyin_ime->mode == LV_IME_PINYIN_MODE_K9) {
671 pinyin_ime->k9_input_str_len = lv_strlen(pinyin_ime->input_char) - 1;
672 pinyin_k9_get_legal_py(obj, pinyin_ime->k9_input_str, k9_py_map);
673 pinyin_k9_fill_cand(obj);
674 pinyin_input_proc(obj);
675 pinyin_ime->ta_count--;
676 }
677 #endif
678 }
679 }
680 else if((lv_strcmp(txt, "ABC") == 0) || (lv_strcmp(txt, "abc") == 0) || (lv_strcmp(txt, "1#") == 0) ||
681 (lv_strcmp(txt, LV_SYMBOL_OK) == 0)) {
682 pinyin_ime_clear_data(obj);
683 return;
684 }
685 else if(lv_strcmp(txt, "123") == 0) {
686 for(uint16_t i = 0; i < lv_strlen(txt); i++)
687 lv_textarea_delete_char(ta);
688
689 pinyin_ime_clear_data(obj);
690 lv_textarea_set_cursor_pos(ta, LV_TEXTAREA_CURSOR_LAST);
691 lv_ime_pinyin_set_mode(obj, LV_IME_PINYIN_MODE_K9_NUMBER);
692 lv_keyboard_set_mode(kb, LV_KEYBOARD_MODE_NUMBER);
693 lv_obj_add_flag(pinyin_ime->cand_panel, LV_OBJ_FLAG_HIDDEN);
694 }
695 else if(lv_strcmp(txt, LV_SYMBOL_KEYBOARD) == 0) {
696 if(pinyin_ime->mode == LV_IME_PINYIN_MODE_K26) {
697 lv_ime_pinyin_set_mode(obj, LV_IME_PINYIN_MODE_K9);
698 }
699 else if(pinyin_ime->mode == LV_IME_PINYIN_MODE_K9) {
700 lv_ime_pinyin_set_mode(obj, LV_IME_PINYIN_MODE_K26);
701 lv_keyboard_set_mode(pinyin_ime->kb, LV_KEYBOARD_MODE_TEXT_LOWER);
702 }
703 else if(pinyin_ime->mode == LV_IME_PINYIN_MODE_K9_NUMBER) {
704 lv_ime_pinyin_set_mode(obj, LV_IME_PINYIN_MODE_K9);
705 }
706 pinyin_ime_clear_data(obj);
707 }
708 else if((pinyin_ime->mode == LV_IME_PINYIN_MODE_K26) && ((txt[0] >= 'a' && txt[0] <= 'z') || (txt[0] >= 'A' &&
709 txt[0] <= 'Z'))) {
710 uint16_t len = lv_strlen(pinyin_ime->input_char);
711 lv_snprintf(pinyin_ime->input_char + len, sizeof(pinyin_ime->input_char) - len, "%s", txt);
712 pinyin_input_proc(obj);
713 pinyin_ime->ta_count++;
714 }
715 #if LV_IME_PINYIN_USE_K9_MODE
716 else if((pinyin_ime->mode == LV_IME_PINYIN_MODE_K9) && (txt[0] >= 'a' && txt[0] <= 'z')) {
717 for(uint16_t i = 0; i < 8; i++) {
718 if((lv_strcmp(txt, k9_py_map[i]) == 0) || (lv_strcmp(txt, "abc ") == 0)) {
719 if(lv_strcmp(txt, "abc ") == 0) pinyin_ime->k9_input_str_len += lv_strlen(k9_py_map[i]) + 1;
720 else pinyin_ime->k9_input_str_len += lv_strlen(k9_py_map[i]);
721 pinyin_ime->k9_input_str[pinyin_ime->ta_count] = 50 + i;
722 pinyin_ime->k9_input_str[pinyin_ime->ta_count + 1] = '\0';
723
724 break;
725 }
726 }
727 pinyin_k9_get_legal_py(obj, pinyin_ime->k9_input_str, k9_py_map);
728 pinyin_k9_fill_cand(obj);
729 pinyin_input_proc(obj);
730 }
731 else if(lv_strcmp(txt, LV_SYMBOL_LEFT) == 0) {
732 pinyin_k9_cand_page_proc(obj, 0);
733 }
734 else if(lv_strcmp(txt, LV_SYMBOL_RIGHT) == 0) {
735 pinyin_k9_cand_page_proc(obj, 1);
736 }
737 #endif
738 }
739 }
740
lv_ime_pinyin_cand_panel_event(lv_event_t * e)741 static void lv_ime_pinyin_cand_panel_event(lv_event_t * e)
742 {
743 lv_event_code_t code = lv_event_get_code(e);
744 lv_obj_t * cand_panel = lv_event_get_current_target(e);
745 lv_obj_t * obj = (lv_obj_t *)lv_event_get_user_data(e);
746
747 lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;
748
749 if(code == LV_EVENT_VALUE_CHANGED) {
750 lv_obj_t * ta = lv_keyboard_get_textarea(pinyin_ime->kb);
751 if(ta == NULL) return;
752
753 uint32_t id = lv_buttonmatrix_get_selected_button(cand_panel);
754 if(id == LV_BUTTONMATRIX_BUTTON_NONE) {
755 return;
756 }
757 else if(id == 0) {
758 pinyin_page_proc(obj, 0);
759 return;
760 }
761 else if(id == (LV_IME_PINYIN_CAND_TEXT_NUM + 1)) {
762 pinyin_page_proc(obj, 1);
763 return;
764 }
765
766 const char * txt = lv_buttonmatrix_get_button_text(cand_panel, id);
767 uint16_t index = 0;
768 for(index = 0; index < pinyin_ime->ta_count; index++)
769 lv_textarea_delete_char(ta);
770
771 lv_textarea_add_text(ta, txt);
772
773 pinyin_ime_clear_data(obj);
774 }
775 }
776
pinyin_input_proc(lv_obj_t * obj)777 static void pinyin_input_proc(lv_obj_t * obj)
778 {
779 lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;
780
781 pinyin_ime->cand_str = pinyin_search_matching(obj, pinyin_ime->input_char, &pinyin_ime->cand_num);
782 if(pinyin_ime->cand_str == NULL) {
783 return;
784 }
785
786 pinyin_ime->py_page = 0;
787
788 for(uint8_t i = 0; i < LV_IME_PINYIN_CAND_TEXT_NUM; i++) {
789 lv_memset(lv_pinyin_cand_str[i], 0x00, sizeof(lv_pinyin_cand_str[i]));
790 lv_pinyin_cand_str[i][0] = ' ';
791 }
792
793 // fill buf
794 for(uint8_t i = 0; (i < pinyin_ime->cand_num && i < LV_IME_PINYIN_CAND_TEXT_NUM); i++) {
795 for(uint8_t j = 0; j < 3; j++) {
796 lv_pinyin_cand_str[i][j] = pinyin_ime->cand_str[i * 3 + j];
797 }
798 }
799
800 lv_obj_remove_flag(pinyin_ime->cand_panel, LV_OBJ_FLAG_HIDDEN);
801 }
802
pinyin_page_proc(lv_obj_t * obj,uint16_t dir)803 static void pinyin_page_proc(lv_obj_t * obj, uint16_t dir)
804 {
805 lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;
806 uint16_t page_num = pinyin_ime->cand_num / LV_IME_PINYIN_CAND_TEXT_NUM;
807 uint16_t remainder = pinyin_ime->cand_num % LV_IME_PINYIN_CAND_TEXT_NUM;
808
809 if(!pinyin_ime->cand_str) return;
810
811 if(dir == 0) {
812 if(pinyin_ime->py_page) {
813 pinyin_ime->py_page--;
814 }
815 }
816 else {
817 if(remainder == 0) {
818 page_num -= 1;
819 }
820 if(pinyin_ime->py_page < page_num) {
821 pinyin_ime->py_page++;
822 }
823 else return;
824 }
825
826 for(uint8_t i = 0; i < LV_IME_PINYIN_CAND_TEXT_NUM; i++) {
827 lv_memset(lv_pinyin_cand_str[i], 0x00, sizeof(lv_pinyin_cand_str[i]));
828 lv_pinyin_cand_str[i][0] = ' ';
829 }
830
831 // fill buf
832 uint16_t offset = pinyin_ime->py_page * (3 * LV_IME_PINYIN_CAND_TEXT_NUM);
833 for(uint8_t i = 0; (i < pinyin_ime->cand_num && i < LV_IME_PINYIN_CAND_TEXT_NUM); i++) {
834 if((remainder > 0) && (pinyin_ime->py_page == page_num)) {
835 if(i >= remainder)
836 break;
837 }
838 for(uint8_t j = 0; j < 3; j++) {
839 lv_pinyin_cand_str[i][j] = pinyin_ime->cand_str[offset + (i * 3) + j];
840 }
841 }
842 }
843
lv_ime_pinyin_style_change_event(lv_event_t * e)844 static void lv_ime_pinyin_style_change_event(lv_event_t * e)
845 {
846 lv_event_code_t code = lv_event_get_code(e);
847 lv_obj_t * obj = lv_event_get_current_target(e);
848
849 lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;
850
851 if(code == LV_EVENT_STYLE_CHANGED) {
852 const lv_font_t * font = lv_obj_get_style_text_font(obj, LV_PART_MAIN);
853 lv_obj_set_style_text_font(pinyin_ime->cand_panel, font, 0);
854 }
855 }
856
init_pinyin_dict(lv_obj_t * obj,const lv_pinyin_dict_t * dict)857 static void init_pinyin_dict(lv_obj_t * obj, const lv_pinyin_dict_t * dict)
858 {
859 lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;
860
861 char headletter = 'a';
862 uint16_t offset_sum = 0;
863 uint16_t offset_count = 0;
864 uint16_t letter_calc = 0;
865
866 pinyin_ime->dict = dict;
867
868 for(uint16_t i = 0; ; i++) {
869 if((NULL == (dict[i].py)) || (NULL == (dict[i].py_mb))) {
870 headletter = dict[i - 1].py[0];
871 letter_calc = headletter - 'a';
872 pinyin_ime->py_num[letter_calc] = offset_count;
873 break;
874 }
875
876 if(headletter == (dict[i].py[0])) {
877 offset_count++;
878 }
879 else {
880 headletter = dict[i].py[0];
881 pinyin_ime->py_num[letter_calc] = offset_count;
882 letter_calc = headletter - 'a';
883 offset_sum += offset_count;
884 pinyin_ime->py_pos[letter_calc] = offset_sum;
885
886 offset_count = 1;
887 }
888 }
889 }
890
pinyin_search_matching(lv_obj_t * obj,char * py_str,uint16_t * cand_num)891 static char * pinyin_search_matching(lv_obj_t * obj, char * py_str, uint16_t * cand_num)
892 {
893 lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;
894
895 const lv_pinyin_dict_t * cpHZ;
896 uint8_t index, len = 0, offset;
897 volatile uint8_t count = 0;
898
899 if(*py_str == '\0') return NULL;
900 if(*py_str == 'i') return NULL;
901 if(*py_str == 'u') return NULL;
902 if(*py_str == 'v') return NULL;
903 if(*py_str == ' ') return NULL;
904
905 offset = py_str[0] - 'a';
906 len = lv_strlen(py_str);
907
908 cpHZ = &pinyin_ime->dict[pinyin_ime->py_pos[offset]];
909 count = pinyin_ime->py_num[offset];
910
911 while(count--) {
912 for(index = 0; index < len; index++) {
913 if(*(py_str + index) != *((cpHZ->py) + index)) {
914 break;
915 }
916 }
917
918 // perfect match
919 if(len == 1 || index == len) {
920 // The Chinese character in UTF-8 encoding format is 3 bytes
921 * cand_num = lv_strlen((const char *)(cpHZ->py_mb)) / 3;
922 return (char *)(cpHZ->py_mb);
923 }
924 cpHZ++;
925 }
926 return NULL;
927 }
928
pinyin_ime_clear_data(lv_obj_t * obj)929 static void pinyin_ime_clear_data(lv_obj_t * obj)
930 {
931 lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;
932
933 #if LV_IME_PINYIN_USE_K9_MODE
934 if(pinyin_ime->mode == LV_IME_PINYIN_MODE_K9) {
935 pinyin_ime->k9_input_str_len = 0;
936 pinyin_ime->k9_py_ll_pos = 0;
937 pinyin_ime->k9_legal_py_count = 0;
938 lv_memzero(pinyin_ime->k9_input_str, LV_IME_PINYIN_K9_MAX_INPUT);
939 lv_memzero(lv_pinyin_k9_cand_str, sizeof(lv_pinyin_k9_cand_str));
940 for(uint8_t i = 0; i < LV_IME_PINYIN_CAND_TEXT_NUM; i++) {
941 lv_strcpy(lv_pinyin_k9_cand_str[i], " ");
942 }
943 lv_strcpy(lv_pinyin_k9_cand_str[LV_IME_PINYIN_K9_CAND_TEXT_NUM], LV_SYMBOL_RIGHT"\0");
944 lv_strcpy(lv_pinyin_k9_cand_str[LV_IME_PINYIN_K9_CAND_TEXT_NUM + 1], "\0");
945 lv_buttonmatrix_set_map(pinyin_ime->kb, (const char **)lv_btnm_def_pinyin_k9_map);
946 }
947 #endif
948
949 pinyin_ime->ta_count = 0;
950 for(uint8_t i = 0; i < LV_IME_PINYIN_CAND_TEXT_NUM; i++) {
951 lv_memset(lv_pinyin_cand_str[i], 0x00, sizeof(lv_pinyin_cand_str[i]));
952 lv_pinyin_cand_str[i][0] = ' ';
953 }
954 lv_memzero(pinyin_ime->input_char, sizeof(pinyin_ime->input_char));
955
956 lv_obj_add_flag(pinyin_ime->cand_panel, LV_OBJ_FLAG_HIDDEN);
957 }
958
959 #if LV_IME_PINYIN_USE_K9_MODE
pinyin_k9_init_data(lv_obj_t * obj)960 static void pinyin_k9_init_data(lv_obj_t * obj)
961 {
962 LV_UNUSED(obj);
963
964 uint16_t py_str_i = 0;
965 uint16_t btnm_i = 0;
966 for(btnm_i = 19; btnm_i < (LV_IME_PINYIN_K9_CAND_TEXT_NUM + 21); btnm_i++) {
967 if(py_str_i == LV_IME_PINYIN_K9_CAND_TEXT_NUM) {
968 lv_strcpy(lv_pinyin_k9_cand_str[py_str_i], LV_SYMBOL_RIGHT"\0");
969 }
970 else if(py_str_i == LV_IME_PINYIN_K9_CAND_TEXT_NUM + 1) {
971 lv_strcpy(lv_pinyin_k9_cand_str[py_str_i], "\0");
972 }
973 else {
974 lv_strcpy(lv_pinyin_k9_cand_str[py_str_i], " \0");
975 }
976
977 lv_btnm_def_pinyin_k9_map[btnm_i] = lv_pinyin_k9_cand_str[py_str_i];
978 py_str_i++;
979 }
980
981 default_kb_ctrl_k9_map[0] = LV_BUTTONMATRIX_CTRL_CHECKED | 1;
982 default_kb_ctrl_k9_map[1] = LV_BUTTONMATRIX_CTRL_NO_REPEAT | LV_BUTTONMATRIX_CTRL_CLICK_TRIG | 1;
983 default_kb_ctrl_k9_map[4] = LV_BUTTONMATRIX_CTRL_CHECKED | 1;
984 default_kb_ctrl_k9_map[5] = LV_BUTTONMATRIX_CTRL_CHECKED | 1;
985 default_kb_ctrl_k9_map[9] = LV_KEYBOARD_CTRL_BUTTON_FLAGS | 1;
986 default_kb_ctrl_k9_map[10] = LV_BUTTONMATRIX_CTRL_CHECKED | 1;
987 default_kb_ctrl_k9_map[14] = LV_BUTTONMATRIX_CTRL_CHECKED | 1;
988 default_kb_ctrl_k9_map[15] = LV_BUTTONMATRIX_CTRL_CHECKED | 1;
989 default_kb_ctrl_k9_map[LV_IME_PINYIN_K9_CAND_TEXT_NUM + 16] = LV_BUTTONMATRIX_CTRL_CHECKED | 1;
990 }
991
pinyin_k9_get_legal_py(lv_obj_t * obj,char * k9_input,const char * py9_map[])992 static void pinyin_k9_get_legal_py(lv_obj_t * obj, char * k9_input, const char * py9_map[])
993 {
994 lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;
995
996 uint16_t len = lv_strlen(k9_input);
997
998 if((len == 0) || (len >= LV_IME_PINYIN_K9_MAX_INPUT)) {
999 return;
1000 }
1001
1002 char py_comp[LV_IME_PINYIN_K9_MAX_INPUT] = {0};
1003 int mark[LV_IME_PINYIN_K9_MAX_INPUT] = {0};
1004 int index = 0;
1005 int flag = 0;
1006 uint16_t count = 0;
1007
1008 uint32_t ll_len = 0;
1009 ime_pinyin_k9_py_str_t * ll_index = NULL;
1010
1011 ll_len = lv_ll_get_len(&pinyin_ime->k9_legal_py_ll);
1012 ll_index = lv_ll_get_head(&pinyin_ime->k9_legal_py_ll);
1013
1014 while(index != -1) {
1015 if(index == len) {
1016 if(pinyin_k9_is_valid_py(obj, py_comp)) {
1017 if((count >= ll_len) || (ll_len == 0)) {
1018 ll_index = lv_ll_ins_tail(&pinyin_ime->k9_legal_py_ll);
1019 lv_strcpy(ll_index->py_str, py_comp);
1020 }
1021 else if((count < ll_len)) {
1022 lv_strcpy(ll_index->py_str, py_comp);
1023 ll_index = lv_ll_get_next(&pinyin_ime->k9_legal_py_ll, ll_index);
1024 }
1025 count++;
1026 }
1027 index--;
1028 }
1029 else {
1030 flag = mark[index];
1031 if((size_t)flag < lv_strlen(py9_map[k9_input[index] - '2'])) {
1032 py_comp[index] = py9_map[k9_input[index] - '2'][flag];
1033 mark[index] = mark[index] + 1;
1034 index++;
1035 }
1036 else {
1037 mark[index] = 0;
1038 index--;
1039 }
1040 }
1041 }
1042
1043 if(count > 0) {
1044 pinyin_ime->ta_count++;
1045 pinyin_ime->k9_legal_py_count = count;
1046 }
1047 }
1048
1049 /*true: visible; false: not visible*/
pinyin_k9_is_valid_py(lv_obj_t * obj,char * py_str)1050 static bool pinyin_k9_is_valid_py(lv_obj_t * obj, char * py_str)
1051 {
1052 lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;
1053
1054 const lv_pinyin_dict_t * cpHZ = NULL;
1055 uint8_t index = 0, len = 0, offset = 0;
1056 volatile uint8_t count = 0;
1057
1058 if(*py_str == '\0') return false;
1059 if(*py_str == 'i') return false;
1060 if(*py_str == 'u') return false;
1061 if(*py_str == 'v') return false;
1062
1063 offset = py_str[0] - 'a';
1064 len = lv_strlen(py_str);
1065
1066 cpHZ = &pinyin_ime->dict[pinyin_ime->py_pos[offset]];
1067 count = pinyin_ime->py_num[offset];
1068
1069 while(count--) {
1070 for(index = 0; index < len; index++) {
1071 if(*(py_str + index) != *((cpHZ->py) + index)) {
1072 break;
1073 }
1074 }
1075
1076 // perfect match
1077 if(len == 1 || index == len) {
1078 return true;
1079 }
1080 cpHZ++;
1081 }
1082 return false;
1083 }
1084
pinyin_k9_fill_cand(lv_obj_t * obj)1085 static void pinyin_k9_fill_cand(lv_obj_t * obj)
1086 {
1087 uint16_t index = 0, tmp_len = 0;
1088 ime_pinyin_k9_py_str_t * ll_index = NULL;
1089
1090 lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;
1091
1092 tmp_len = pinyin_ime->k9_legal_py_count;
1093
1094 if(tmp_len != cand_len) {
1095 lv_memzero(lv_pinyin_k9_cand_str, sizeof(lv_pinyin_k9_cand_str));
1096 lv_strcpy(lv_pinyin_k9_cand_str[LV_IME_PINYIN_K9_CAND_TEXT_NUM], LV_SYMBOL_RIGHT"\0");
1097 lv_strcpy(lv_pinyin_k9_cand_str[LV_IME_PINYIN_K9_CAND_TEXT_NUM + 1], "\0");
1098 cand_len = tmp_len;
1099 }
1100
1101 ll_index = lv_ll_get_head(&pinyin_ime->k9_legal_py_ll);
1102 lv_strcpy(pinyin_ime->input_char, ll_index->py_str);
1103
1104 for(uint8_t i = 0; i < LV_IME_PINYIN_K9_CAND_TEXT_NUM; i++) {
1105 lv_strcpy(lv_pinyin_k9_cand_str[i], " ");
1106 }
1107
1108 while(ll_index) {
1109 if(index >= LV_IME_PINYIN_K9_CAND_TEXT_NUM)
1110 break;
1111
1112 if(index < pinyin_ime->k9_legal_py_count) {
1113 lv_strcpy(lv_pinyin_k9_cand_str[index], ll_index->py_str);
1114 }
1115
1116 ll_index = lv_ll_get_next(&pinyin_ime->k9_legal_py_ll, ll_index); /*Find the next list*/
1117 index++;
1118 }
1119 pinyin_ime->k9_py_ll_pos = index;
1120
1121 lv_obj_t * ta = lv_keyboard_get_textarea(pinyin_ime->kb);
1122 for(index = 0; index < pinyin_ime->k9_input_str_len; index++) {
1123 lv_textarea_delete_char(ta);
1124 }
1125 pinyin_ime->k9_input_str_len = lv_strlen(pinyin_ime->input_char);
1126 lv_textarea_add_text(ta, pinyin_ime->input_char);
1127 }
1128
pinyin_k9_cand_page_proc(lv_obj_t * obj,uint16_t dir)1129 static void pinyin_k9_cand_page_proc(lv_obj_t * obj, uint16_t dir)
1130 {
1131 lv_ime_pinyin_t * pinyin_ime = (lv_ime_pinyin_t *)obj;
1132
1133 lv_obj_t * ta = lv_keyboard_get_textarea(pinyin_ime->kb);
1134 uint16_t ll_len = lv_ll_get_len(&pinyin_ime->k9_legal_py_ll);
1135
1136 if((ll_len > LV_IME_PINYIN_K9_CAND_TEXT_NUM) && (pinyin_ime->k9_legal_py_count > LV_IME_PINYIN_K9_CAND_TEXT_NUM)) {
1137 ime_pinyin_k9_py_str_t * ll_index = NULL;
1138 int count = 0;
1139
1140 ll_index = lv_ll_get_head(&pinyin_ime->k9_legal_py_ll);
1141 while(ll_index) {
1142 if(count >= pinyin_ime->k9_py_ll_pos) break;
1143
1144 ll_index = lv_ll_get_next(&pinyin_ime->k9_legal_py_ll, ll_index); /*Find the next list*/
1145 count++;
1146 }
1147
1148 if((NULL == ll_index) && (dir == 1)) return;
1149
1150 lv_memzero(lv_pinyin_k9_cand_str, sizeof(lv_pinyin_k9_cand_str));
1151 lv_strcpy(lv_pinyin_k9_cand_str[LV_IME_PINYIN_K9_CAND_TEXT_NUM], LV_SYMBOL_RIGHT"\0");
1152 lv_strcpy(lv_pinyin_k9_cand_str[LV_IME_PINYIN_K9_CAND_TEXT_NUM + 1], "\0");
1153
1154 // next page
1155 if(dir == 1) {
1156 for(uint8_t i = 0; i < LV_IME_PINYIN_K9_CAND_TEXT_NUM; i++) {
1157 lv_strcpy(lv_pinyin_k9_cand_str[i], " ");
1158 }
1159
1160 count = 0;
1161 while(ll_index) {
1162 if(count >= (LV_IME_PINYIN_K9_CAND_TEXT_NUM - 1))
1163 break;
1164
1165 lv_strcpy(lv_pinyin_k9_cand_str[count], ll_index->py_str);
1166 ll_index = lv_ll_get_next(&pinyin_ime->k9_legal_py_ll, ll_index); /*Find the next list*/
1167 count++;
1168 }
1169 pinyin_ime->k9_py_ll_pos += count - 1;
1170
1171 }
1172 // previous page
1173 else {
1174 for(uint8_t i = 0; i < LV_IME_PINYIN_K9_CAND_TEXT_NUM; i++) {
1175 lv_strcpy(lv_pinyin_k9_cand_str[i], " ");
1176 }
1177 count = LV_IME_PINYIN_K9_CAND_TEXT_NUM - 1;
1178 ll_index = lv_ll_get_prev(&pinyin_ime->k9_legal_py_ll, ll_index);
1179 while(ll_index) {
1180 if(count < 0) break;
1181
1182 lv_strcpy(lv_pinyin_k9_cand_str[count], ll_index->py_str);
1183 ll_index = lv_ll_get_prev(&pinyin_ime->k9_legal_py_ll, ll_index); /*Find the previous list*/
1184 count--;
1185 }
1186
1187 if(pinyin_ime->k9_py_ll_pos > LV_IME_PINYIN_K9_CAND_TEXT_NUM)
1188 pinyin_ime->k9_py_ll_pos -= 1;
1189 }
1190
1191 lv_textarea_set_cursor_pos(ta, LV_TEXTAREA_CURSOR_LAST);
1192 }
1193 }
1194
1195 #endif /*LV_IME_PINYIN_USE_K9_MODE*/
1196
1197 #endif /*LV_USE_IME_PINYIN*/
1198