#include "mywin_inc.h" // 定义输入法类型 #define WIN_INPUT_TYPE "WIN_InputStruct" // 定义输入法按键别名 #define INPUT_BUTTON_Q button[0] #define INPUT_BUTTON_W button[1] #define INPUT_BUTTON_E button[2] #define INPUT_BUTTON_R button[3] #define INPUT_BUTTON_T button[4] #define INPUT_BUTTON_Y button[5] #define INPUT_BUTTON_U button[6] #define INPUT_BUTTON_I button[7] #define INPUT_BUTTON_O button[8] #define INPUT_BUTTON_P button[9] #define INPUT_BUTTON_A button[10] #define INPUT_BUTTON_S button[11] #define INPUT_BUTTON_D button[12] #define INPUT_BUTTON_F button[13] #define INPUT_BUTTON_G button[14] #define INPUT_BUTTON_H button[15] #define INPUT_BUTTON_J button[16] #define INPUT_BUTTON_K button[17] #define INPUT_BUTTON_L button[18] #define INPUT_BUTTON_Z button[19] #define INPUT_BUTTON_X button[20] #define INPUT_BUTTON_C button[21] #define INPUT_BUTTON_V button[22] #define INPUT_BUTTON_B button[23] #define INPUT_BUTTON_N button[24] #define INPUT_BUTTON_M button[25] #define INPUT_BUTTON_LEFT button[26] #define INPUT_BUTTON_RIGHT button[27] #define INPUT_BUTTON_ESC button[28] #define INPUT_BUTTON_SHIFT button[29] #define INPUT_BUTTON_EN button[30] #define INPUT_BUTTON_123 button[31] #define INPUT_BUTTON_COMMA button[32] #define INPUT_BUTTON_SPACE button[33] #define INPUT_BUTTON_FULLSTOP button[34] #define INPUT_BUTTON_BACK button[35] #define INPUT_BUTTON_ENTER button[36] #include "res/pymb.txt" static const char *g_keybord_txt = "QWERTYUIOPASDFGHJKLZXCVBNM"; static const char *g_keybord_mini = "qwertyuiopasdfghjklzxcvbnm"; static const char *g_keybord_num[] = {"1234567890-=!@#$%^&*()_+`~", "[]\\;',./{}|:\"<>?"}; // 在堆中创建一个输入法 WIN_InputStruct *WIN_CreatInput(WIN_WindowStruct *base, void (*msgLoop)(struct _WIN_WindowStruct *win, WIN_MsgStruct *msg), int x, int y, int x_size, int y_size) { // 重设消息循环 if (msgLoop == 0) { msgLoop = (void (*)(struct _WIN_WindowStruct *win, WIN_MsgStruct *msg))INPUT_DefaultMsgLoop; } WIN_InputStruct *ret = mymalloc(sizeof(WIN_InputStruct)); // 调用父类的构造函数 if (ret) { mymemset(ret, 0, sizeof(WIN_InputStruct)); if (0 == WIN_CreatWindowExt((WIN_WindowStruct *)ret, base, msgLoop, x, y, x_size, y_size)) { // 创建失败 myfree(ret); ret = 0; } else { // 构造一个 ((WIN_WindowStruct *)ret)->winType = WIN_INPUT_TYPE; ((WIN_WindowStruct *)ret)->intercept = 1; // 输入阻塞 ((WIN_WindowStruct *)ret)->bkcolor = 0x7700cc; ret->button_ysize = 30; int x = 0; int y = 0; int x_size = ((WIN_WindowStruct *)ret)->x_size; int y_size = ((WIN_WindowStruct *)ret)->y_size; int button_x_size = x_size / 10; int button_y_size = ret->button_ysize; int button_x = x; int button_y = y + y_size - 1 - button_y_size * 5; ret->pinyin_y = button_y - WIN_GetFontHight(); // 拼音显示位置 // 候选字按键 for (int i = 0; i < 10; i++) { ret->word[i].x = button_x; ret->word[i].y = button_y; ret->word[i].x_size = button_x_size; ret->word[i].y_size = button_y_size; button_x += button_x_size; } button_x = x; button_y += button_y_size; // 字母按键 for (int i = 0; i < 26; i++) { if (i == 10) { button_y += button_y_size; button_x = x + button_x_size / 3; } if (i == 19) { button_y += button_y_size; button_x = x + button_x_size * 2 / 3; } ret->button[i].x = button_x; ret->button[i].y = button_y; ret->button[i].x_size = button_x_size; ret->button[i].y_size = button_y_size; button_x += button_x_size; char chars[2] = {0}; chars[0] = g_keybord_txt[i]; mymemcpy(ret->button[i].txt, chars, 2); } // 功能按键 ret->INPUT_BUTTON_LEFT.x = button_x; ret->INPUT_BUTTON_LEFT.y = button_y; ret->INPUT_BUTTON_LEFT.x_size = button_x_size; ret->INPUT_BUTTON_LEFT.y_size = button_y_size; mymemcpy(ret->INPUT_BUTTON_LEFT.txt, "<", 2); button_x += button_x_size; ret->INPUT_BUTTON_RIGHT.x = button_x; ret->INPUT_BUTTON_RIGHT.y = button_y; ret->INPUT_BUTTON_RIGHT.x_size = button_x_size; ret->INPUT_BUTTON_RIGHT.y_size = button_y_size; mymemcpy(ret->INPUT_BUTTON_RIGHT.txt, ">", 2); button_x = x; button_y += button_y_size; ret->INPUT_BUTTON_ESC.x = button_x; ret->INPUT_BUTTON_ESC.y = button_y; ret->INPUT_BUTTON_ESC.x_size = button_x_size; ret->INPUT_BUTTON_ESC.y_size = button_y_size; mymemcpy(ret->INPUT_BUTTON_ESC.txt, "ESC", 5); button_x += button_x_size; ret->INPUT_BUTTON_SHIFT.x = button_x; ret->INPUT_BUTTON_SHIFT.y = button_y; ret->INPUT_BUTTON_SHIFT.x_size = button_x_size; ret->INPUT_BUTTON_SHIFT.y_size = button_y_size; mymemcpy(ret->INPUT_BUTTON_SHIFT.txt, "SHIFT", 5); button_x += button_x_size; ret->INPUT_BUTTON_EN.x = button_x; ret->INPUT_BUTTON_EN.y = button_y; ret->INPUT_BUTTON_EN.x_size = button_x_size; ret->INPUT_BUTTON_EN.y_size = button_y_size; mymemcpy(ret->INPUT_BUTTON_EN.txt, "EN", 5); button_x += button_x_size; ret->INPUT_BUTTON_123.x = button_x; ret->INPUT_BUTTON_123.y = button_y; ret->INPUT_BUTTON_123.x_size = button_x_size; ret->INPUT_BUTTON_123.y_size = button_y_size; mymemcpy(ret->INPUT_BUTTON_123.txt, "123", 5); button_x += button_x_size; ret->INPUT_BUTTON_COMMA.x = button_x; ret->INPUT_BUTTON_COMMA.y = button_y; ret->INPUT_BUTTON_COMMA.x_size = button_x_size; ret->INPUT_BUTTON_COMMA.y_size = button_y_size; mymemcpy(ret->INPUT_BUTTON_COMMA.txt, ",", 5); button_x += button_x_size; ret->INPUT_BUTTON_SPACE.x = button_x; ret->INPUT_BUTTON_SPACE.y = button_y; ret->INPUT_BUTTON_SPACE.x_size = button_x_size * 2; ret->INPUT_BUTTON_SPACE.y_size = button_y_size; mymemcpy(ret->INPUT_BUTTON_SPACE.txt, " ", 5); button_x += button_x_size * 2; ret->INPUT_BUTTON_FULLSTOP.x = button_x; ret->INPUT_BUTTON_FULLSTOP.y = button_y; ret->INPUT_BUTTON_FULLSTOP.x_size = button_x_size; ret->INPUT_BUTTON_FULLSTOP.y_size = button_y_size; mymemcpy(ret->INPUT_BUTTON_FULLSTOP.txt, ".", 5); button_x += button_x_size; ret->INPUT_BUTTON_BACK.x = button_x; ret->INPUT_BUTTON_BACK.y = button_y; ret->INPUT_BUTTON_BACK.x_size = button_x_size; ret->INPUT_BUTTON_BACK.y_size = button_y_size; mymemcpy(ret->INPUT_BUTTON_BACK.txt, "Back", 5); button_x += button_x_size; ret->INPUT_BUTTON_ENTER.x = button_x; ret->INPUT_BUTTON_ENTER.y = button_y; ret->INPUT_BUTTON_ENTER.x_size = button_x_size; ret->INPUT_BUTTON_ENTER.y_size = button_y_size; mymemcpy(ret->INPUT_BUTTON_ENTER.txt, "ENTER", 5); button_x += button_x_size; } } return ret; } // 键盘切换至字母大写 void INPUT_SetToAscBig(WIN_InputStruct *input) { // 字母按键 for (int i = 0; i < 26; i++) { char chars[2] = {0}; chars[0] = g_keybord_txt[i]; mymemcpy(input->button[i].txt, chars, 2); } } // 键盘切换至字母小写 void INPUT_SetToAscMini(WIN_InputStruct *input) { // 字母按键 for (int i = 0; i < 26; i++) { char chars[2] = {0}; chars[0] = g_keybord_mini[i]; if (chars[0] == 0) break; mymemcpy(input->button[i].txt, chars, 2); } } // 键盘切换至数字 void INPUT_SetToNum(WIN_InputStruct *input) { // 字母按键 for (int i = 0; i < 26; i++) { char chars[2] = {0}; chars[0] = g_keybord_num[input->num_symbol_page][i]; if (chars[0] == 0) break; mymemcpy(input->button[i].txt, chars, 2); } } // 按键按下 void INPUT_SetPressDown(WIN_InputStruct *input) { for (int i = 0; i < 37; i++) { if (POS_InRect(input->button[i].x, input->button[i].y, input->button[i].x_size, input->button[i].y_size, input->press_x, input->press_y) == 1) { input->button[i].press = 1; input->press_down_index = i; return; } } for (int i = 0; i < 10; i++) { if (POS_InRect(input->word[i].x, input->word[i].y, input->word[i].x_size, input->word[i].y_size, input->press_x, input->press_y) == 1) { input->word[i].press = 1; input->press_down_index_word = i; return; } } } // 按键抬起 void INPUT_SetPressUp(WIN_InputStruct *input) { input->button[input->press_down_index].press = 0; input->word[input->press_down_index_word].press = 0; } // 添加拼音 void INPUT_PinYinAppend(WIN_InputStruct *input) { int pinyin_len = strlen(input->inputPinyin); if ((pinyin_len < 10) && input->button[input->press_down_index].press) { char txt = input->button[input->press_down_index].txt[0]; if (txt < 'a') txt += 'a' - 'A'; input->inputPinyin[pinyin_len] = txt; } } // 拼音截短 void INPUT_PinYinCut(WIN_InputStruct *input) { int pinyin_len = strlen(input->inputPinyin); if (pinyin_len) input->inputPinyin[pinyin_len - 1] = 0; } // 追加输入字符 void INPUT_WordAppend(WIN_InputStruct *input) { int word_len = strlen(input->inputWords); if (word_len < INPUT_WORDS_MAXNUM - 2) // 预留至少可以输入一个汉字的空间,并且最后一位要用来做结尾符 { input->candidateWord[2] = 0; int candidate_len = strlen(input->candidateWord); if (candidate_len == 2) { mymemcpy(&input->inputWords[word_len], input->candidateWord, candidate_len + 1); mymemset(input->candidateWord, 0, 3); } else if (input->button[input->press_down_index].press) { input->inputWords[word_len] = input->button[input->press_down_index].txt[0]; input->inputWords[word_len + 1] = 0; } } } // 输入字符截短 void INPUT_WordCut(WIN_InputStruct *input) { int word_len = strlen(input->inputWords); char *p_txt = input->inputWords; int reback = 0; while (*p_txt) { if (*p_txt & 0x80) reback = 2; else reback = 1; p_txt += reback; } input->inputWords[word_len - reback] = 0; } // 比较两个字符串是否相等,最多比较str1长度的字符串 static int input_strcmp(const char *str1, const char *str2) { int len = strlen(str1); if (len == 0) return -1; for (int i = 0; i < len; i++) { if (str1[i] != str2[i]) return -1; } return 0; } // 查询候选字符 void INPUT_FindWord(WIN_InputStruct *input) { for (int i = 0; g_py_index[i].str; i++) { // if (strcmp ((char *)g_py_index[i].str,input->inputPinyin)==0) if (input_strcmp(input->inputPinyin, (char *)g_py_index[i].str) == 0) { input->word_const = g_py_index[i].word; input->word_page = 0; // 重置到第0页 return; } } input->word_const = 0; input->word_page = 0; // 重置到第0页 } // 把待选字符复制到字符按钮中 void INPUT_StorWordButton(WIN_InputStruct *input) { int i = 0; if (input->word_const) { char *word = (char *)input->word_const + input->word_page * 20; for (; i < 10; i++) { if (word[i * 2]) { input->word[i].txt[0] = word[i * 2]; input->word[i].txt[1] = word[i * 2 + 1]; input->word[i].txt[2] = 0; } else { break; } } } { for (; i < 10; i++) { input->word[i].txt[0] = 0; } } } // 功能按键 void INPUT_FunctionKey(WIN_InputStruct *input) { if (input->INPUT_BUTTON_BACK.press) { int pinyin_len = strlen(input->inputPinyin); if (pinyin_len) { INPUT_PinYinCut(input); INPUT_FindWord(input); INPUT_StorWordButton(input); } else INPUT_WordCut(input); } else if (input->INPUT_BUTTON_LEFT.press) { // 左键 if (input->inputMode == INPUT_MODE_PINYIN) { if (input->word_page > 0) input->word_page--; INPUT_StorWordButton(input); } else if (input->inputMode == INPUT_MODE_NUM) { if (input->num_symbol_page > 0) input->num_symbol_page--; INPUT_SetToNum(input); } } else if (input->INPUT_BUTTON_RIGHT.press) { // 右键 if (input->inputMode == INPUT_MODE_PINYIN) { if (input->word_const) { int str_len = strlen((char *)input->word_const); if ((input->word_page + 1) * 20 < str_len) input->word_page++; INPUT_StorWordButton(input); } } else if (input->inputMode == INPUT_MODE_NUM) { if (input->num_symbol_page < 1) input->num_symbol_page++; INPUT_SetToNum(input); } } else if (input->INPUT_BUTTON_ESC.press) { input->exit = 1; // 退出,不保存输入 WIN_SetBlockWinReturn(0, 0, 0); } else if (input->INPUT_BUTTON_SHIFT.press) { if (input->inputMode == INPUT_MODE_BIG) { INPUT_SetToAscMini(input); input->inputMode = INPUT_MODE_MINI; } else if (input->inputMode == INPUT_MODE_MINI) { INPUT_SetToAscBig(input); input->inputMode = INPUT_MODE_BIG; } } else if (input->INPUT_BUTTON_EN.press) { if (input->inputMode == INPUT_MODE_PINYIN) { INPUT_SetToAscMini(input); input->inputMode = INPUT_MODE_MINI; mymemset(input->inputPinyin, 0, 10); // 清除拼音输入 INPUT_FindWord(input); INPUT_StorWordButton(input); mymemset(input->candidateWord, 0, 3); } else { INPUT_SetToAscBig(input); input->inputMode = INPUT_MODE_PINYIN; } } else if (input->INPUT_BUTTON_123.press) { input->inputMode = INPUT_MODE_NUM; input->num_symbol_page = 0; INPUT_SetToNum(input); mymemset(input->inputPinyin, 0, 10); // 清除拼音输入 INPUT_FindWord(input); INPUT_StorWordButton(input); mymemset(input->candidateWord, 0, 3); } else if (input->INPUT_BUTTON_ENTER.press) { input->exit = 1; // 退出,保存输入 void *retdata = mymalloc(100); mymemcpy(retdata, input->inputWords, strlen(input->inputWords) + 1); WIN_SetBlockWinReturn(1, retdata, 100); myfree(retdata); } } // 按键松开的时候做点什么 void INPUT_DoSomethingPressUp(WIN_InputStruct *input) { if (input->press_down_index < 26) { // 是输入按键 if (input->inputMode == INPUT_MODE_PINYIN) { INPUT_PinYinAppend(input); INPUT_FindWord(input); INPUT_StorWordButton(input); } else { INPUT_WordAppend(input); } } else if ((input->press_down_index >= 32) && (input->press_down_index <= 34)) { // 主界面的标点符号 mymemset(input->inputPinyin, 0, 10); // 清除拼音输入 INPUT_FindWord(input); INPUT_StorWordButton(input); mymemset(input->candidateWord, 0, 3); INPUT_WordAppend(input); } else { // 功能按键 INPUT_FunctionKey(input); // 更新功能按键上显示的字符 if (input->inputMode == INPUT_MODE_PINYIN) { mymemcpy(input->INPUT_BUTTON_EN.txt, "EN", 3); } else { mymemcpy(input->INPUT_BUTTON_EN.txt, "拼", 3); } } if (input->word[input->press_down_index_word].press) { // 选择了候选字 mymemcpy(input->candidateWord, input->word[input->press_down_index_word].txt, 3); INPUT_WordAppend(input); mymemset(input->inputPinyin, 0, 10); // 清除拼音输入 INPUT_FindWord(input); INPUT_StorWordButton(input); } } // 默认绘制函数 void INPUT_DefaultPaint(WIN_InputStruct *input) { // 使用双缓冲,防止闪烁 int x = 0; int y = 0; int x_size = ((WIN_WindowStruct *)input)->x_size; int y_size = ((WIN_WindowStruct *)input)->y_size - (((WIN_WindowStruct *)input)->y_size - input->pinyin_y) - 1; char txt_buff[20] = {0}; WIN_PaintBackGround((WIN_WindowStruct *)input); uint32_t font_type = WIN_SetFontSize(20); // 显示文本 WIN_SetLcdColor(0x00ffff); WIN_SetFontMode(WIN_DRAWMODE_ALONE); WIN_DrawTxtAt(input->inputWords, x + 2, y + 2); WIN_SetLcdColor(0xff0000); WIN_DrawVLine(strlen(input->inputWords) * WIN_GetFontWidth() / 2 + x + 4, y, y + 2 + WIN_GetFontHight()); WIN_SetLcdColor(0xffff00); WIN_DrawRect(x, y, x_size, y_size); // 显示键盘 WIN_SetFontSize(20); for (int i = 0; i < 37; i++) { if (input->button[i].press) { WIN_SetLcdColor(0xbb00aa); } else { WIN_SetLcdColor(0xffffff); } WIN_FillRectByColor(input->button[i].x, input->button[i].y, input->button[i].x_size, input->button[i].y_size); WIN_SetLcdColor(0x000000); WIN_DrawRect(input->button[i].x, input->button[i].y, input->button[i].x_size, input->button[i].y_size); WIN_DrawTxtHCenterAt(input->button[i].txt, input->button[i].x + input->button[i].x_size / 2, input->button[i].y + input->button[i].y_size / 2 - WIN_GetFontHight() / 2); } // 显示拼音和候选字 if (input->inputMode == INPUT_MODE_PINYIN) { WIN_SetFontSize(20); if (input->inputPinyin[0]) { WIN_SetLcdColor(0xaabbcc); WIN_DrawTxtAt(input->inputPinyin, x, input->pinyin_y); for (int i = 0; i < 10; i++) { if (input->word[i].press) { WIN_SetLcdColor(0xbb00aa); } else { WIN_SetLcdColor(0xffffff); } WIN_FillRectByColor(input->word[i].x, input->word[i].y, input->word[i].x_size, input->word[i].y_size); WIN_DrawRect(input->word[i].x, input->word[i].y, input->word[i].x_size, input->word[i].y_size); WIN_SetLcdColor(0x55bbaa); WIN_DrawTxtHCenterAt(input->word[i].txt, input->word[i].x + input->word[i].x_size / 2, input->word[i].y + input->word[i].y_size / 2 - WIN_GetFontHight() / 2); } } } WIN_SetFontSize(font_type); } // 默认消息处理函数 void INPUT_DefaultMsgLoop(WIN_InputStruct *input, WIN_MsgStruct *msg) { WIN_MoveStruct *m = 0; WIN_KeyStruct *k = 0; switch (msg->msg) { case WIN_MSG_PAINT: INPUT_DefaultPaint(input); break; case WIN_MSG_KEY: k = msg->data.p; if (k->shortPress & KEY_VALUE_HOME) { ((WIN_WindowStruct *)input)->deleteWindow((WIN_WindowStruct *)input); } break; case WIN_MSG_MOVE: m = msg->data.p; switch (m->moveType) { case MOVE_DATA_TOUCHOUT: INPUT_DoSomethingPressUp(input); INPUT_SetPressUp(input); WIN_SetInvalid((WIN_WindowStruct *)input); if (input->exit) ((WIN_WindowStruct *)input)->deleteWindow((WIN_WindowStruct *)input); break; case MOVE_DATA_TOUCHIN: input->press_x = m->x_move; input->press_y = m->y_move; INPUT_SetPressDown(input); WIN_SetInvalid((WIN_WindowStruct *)input); break; default: WIN_DefaultMsgLoop((WIN_WindowStruct *)input, msg); break; } break; default: WIN_DefaultMsgLoop((WIN_WindowStruct *)input, msg); break; } } // 使用键盘输入一些数据 int INPUT_KeyBoard(WIN_WindowStruct *win, char *txt, int len) { WIN_InputStruct *input = 0; if (win) input = WIN_CreatInput(win, 0, 0, 0, win->x_size, win->y_size); else input = WIN_CreatInput(0, 0, 0, 0, WIN_GetWinStruct()->lcd->getLcdSizeX(), WIN_GetWinStruct()->lcd->getLcdSizeY()); int str_len = strlen(txt); if (str_len < INPUT_WORDS_MAXNUM) { mymemcpy(input->inputWords, txt, str_len + 1); } WIN_ShowWindow((WIN_WindowStruct *)input); int ret = WIN_RunBlock((WIN_WindowStruct *)input); WIN_GetBlockWinReturn(&ret, txt, len); return ret; }