Files
player/Project/Src/MyWin/Window/mywin_input.c

687 lines
17 KiB
C
Raw Normal View History

2025-06-27 00:32:57 +08:00
#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.c"
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);
u32 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;
}