Files
player/Project/Src/MyWin/Window/mywin_touch.c
2025-06-27 00:32:57 +08:00

564 lines
12 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "mywin_inc.h"
WIN_TouchWinStruct *WIN_CreatTouch (WIN_WindowStruct *base,
void (*msgLoop)(struct _WIN_WindowStruct *win,WIN_MsgStruct *msg),
int x,int y,int x_size,int y_size)
{
//重设消息循环
void (*userMsgLoop)(struct _WIN_WindowStruct *win,WIN_MsgStruct *msg)=0;
if (msgLoop==0)
{
msgLoop=(void (*)(struct _WIN_WindowStruct *win,WIN_MsgStruct *msg))TOUCHWIN_DefaultMsgLoop;
}
else
{
userMsgLoop=msgLoop;
msgLoop=(void (*)(struct _WIN_WindowStruct *win,WIN_MsgStruct *msg))TOUCHWIN_DefaultMsgLoop;
}
WIN_TouchWinStruct *ret=mymalloc (sizeof ( WIN_TouchWinStruct));
//调用父类的构造函数
if (ret)
{
mymemset (ret,0,sizeof ( WIN_TouchWinStruct));
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_TouchWinStruct";
((WIN_WindowStruct *)ret)->bkcolor=0x342f2a;
((WIN_WindowStruct *)ret)->color=0xc2ae9b;
((WIN_WindowStruct *)ret)->keyChid=0; //不作为子窗口被创建
ret->msgloop=(void (*)(struct _WIN_TouchWinStruct *win,WIN_MsgStruct *msg))userMsgLoop;
}
}
return ret;
}
int WIN_CreatTouchEx (WIN_TouchWinStruct *win,WIN_WindowStruct *base,
void (*msgLoop)(struct _WIN_WindowStruct *win,WIN_MsgStruct *msg),
int x,int y,int x_size,int y_size)
{
//重设消息循环
void (*userMsgLoop)(struct _WIN_WindowStruct *win,WIN_MsgStruct *msg)=0;
if (msgLoop==0)
{
msgLoop=(void (*)(struct _WIN_WindowStruct *win,WIN_MsgStruct *msg))TOUCHWIN_DefaultMsgLoop;
}
else
{
userMsgLoop=msgLoop;
msgLoop=(void (*)(struct _WIN_WindowStruct *win,WIN_MsgStruct *msg))TOUCHWIN_DefaultMsgLoop;
}
//调用父类的构造函数
if (win)
{
mymemset (win,0,sizeof ( WIN_TouchWinStruct));
if (0==WIN_CreatWindowExt((WIN_WindowStruct *)win,base,msgLoop,x,y,x_size,y_size))
{
return 0;
}
else
{
//构造一个
((WIN_WindowStruct *)win)->winType="WIN_TouchWinStruct";
((WIN_WindowStruct *)win)->bkcolor=0x342f2a;
((WIN_WindowStruct *)win)->color=0xc2ae9b;
((WIN_WindowStruct *)win)->keyChid=0; //不作为子窗口被创建
win->msgloop=(void (*)(struct _WIN_TouchWinStruct *win,WIN_MsgStruct *msg))userMsgLoop;
TOUCHWIN_SetOutCon(win,TOUCH_CON_RIGHT_PAR(x_size,y_size,0));
return 1;
}
}
return 0;
}
//创建子窗口函数
WIN_TouchWinStruct *WIN_CreatTouchChild(WIN_TouchWinStruct *base)
{
WIN_WindowStruct *w_base=(WIN_WindowStruct *)base;
WIN_TouchWinStruct *ret=WIN_CreatTouch(w_base,0,0,0,w_base->x_size,w_base->y_size);
WIN_SetBackPic((WIN_WindowStruct *)ret);
mymemcpy(&ret->out,TOUCH_CON_UP_PAR(w_base->x_size,w_base->y_size,0),sizeof(TouchConditionStruct));
return ret;
}
//创建父窗口函数
WIN_TouchWinStruct *WIN_CreatTouchBase(WIN_WindowStruct *base)
{
WIN_WindowStruct *w_base=(WIN_WindowStruct *)base;
WIN_TouchWinStruct *ret=WIN_CreatTouch(w_base,0,0,0,w_base->x_size,w_base->y_size);
WIN_SetBackPic((WIN_WindowStruct *)ret);
return ret;
}
//添加滑动时自动创建的子窗口
int TOUCHWIN_AddChild(WIN_TouchWinStruct *touch,TouchConditionStruct *c)
{
if(touch->child_num<TOUCHWIN_CHILD_MAX_NUM)
{
TouchConditionStruct *d=&touch->child[touch->child_num];
mymemcpy(d,c,sizeof(TouchConditionStruct));
touch->child_num++;
return 1;
}
return 0;
}
//清空自动创建的子窗口
int TOUCHWIN_ClearChild(WIN_TouchWinStruct *touch)
{
for(int i=0;i<touch->child_num;i++)
{
TouchConditionStruct *d=&touch->child[i];
mymemset(d,0,sizeof(TouchConditionStruct));
}
touch->child_num=0;
return 1;
}
//设置退出动画
int TOUCHWIN_SetOutCon(WIN_TouchWinStruct *touch,TouchConditionStruct *c)
{
c->creat=0;
mymemcpy(&touch->out,c,sizeof(TouchConditionStruct));
return 1;
}
void TOUCHWIN_DefaultPaint(WIN_TouchWinStruct *touch)
{
WIN_PaintBackGround ((WIN_WindowStruct *)touch);
}
//创建子窗口
int TOUCHWIN_CreatChild(WIN_TouchWinStruct *touch,WIN_MoveStruct *m)
{
if (touch->work) return 1;
for(int i=0;i<touch->child_num;i++)
{
RECT_Struct *rect=&touch->child[i].start;
if(POS_InRect(rect->x,rect->y,rect->x_size,rect->y_size,m->x_move,m->y_move)==1)
{
if(touch->child[i].creat)
{
touch->work=touch->child[i].creat(touch);
mymemcpy(&touch->work_con,&touch->child[i],sizeof(TouchConditionStruct));
WIN_WindowStruct *win=(WIN_WindowStruct *)touch->work;
win->keyShield=1; //屏蔽按键
win->intercept=0; //不拦截发给父窗口的按键
if(touch->child[i].slide==TOUCH_SLIDE_DOWN)
{
//像下滑
WIN_Move((WIN_WindowStruct *)touch->work,0,-((WIN_WindowStruct *)touch)->y_size);
}
else if(touch->child[i].slide==TOUCH_SLIDE_UP)
{
//像上滑
WIN_Move((WIN_WindowStruct *)touch->work,0,((WIN_WindowStruct *)touch)->y_size);
}
else if(touch->child[i].slide==TOUCH_SLIDE_LEFT)
{
//像左滑
WIN_Move((WIN_WindowStruct *)touch->work,((WIN_WindowStruct *)touch)->x_size,0);
}
else if(touch->child[i].slide==TOUCH_SLIDE_RIGHT)
{
//像右滑
WIN_Move((WIN_WindowStruct *)touch->work,-((WIN_WindowStruct *)touch)->x_size,0);
}
((WIN_WindowStruct *)touch->work)->keyShield=1; //不接受交互
}
return 1;
}
}
return 0;
}
//移动子窗口
void TOUCHWIN_MoveChild(WIN_TouchWinStruct *touch,WIN_MoveStruct *m)
{
int mov_x=m->x_move;
int mov_y=m->y_move;
WIN_WindowStruct *win=(WIN_WindowStruct *)touch->work;
int y=win->y+mov_y;
int x=win->x+mov_x;
TouchConditionStruct *child=&touch->work_con;
if(child->slide==TOUCH_SLIDE_DOWN)
{
//child->creat 不为0则是进入动作
if(child->creat)
{if(y>0) y=0;}
else {if(y<0) y=0;}
WIN_SetPos(win,0,y);
}
else if(child->slide==TOUCH_SLIDE_UP)
{
if(child->creat)
{if(y<0) y=0;}
else {if(y>0) y=0;}
WIN_SetPos(win,0,y);
}
else if(child->slide==TOUCH_SLIDE_LEFT)
{
if(child->creat)
{if(x<0) x=0;}
else {if(x>0) x=0;}
WIN_SetPos(win,x,0);
}
else if(child->slide==TOUCH_SLIDE_RIGHT)
{
if(child->creat)
{if(x>0) x=0;}
else {if(x<0) x=0;}
WIN_SetPos(win,x,0);
}
}
//在子窗口过程中触屏松开
void TOUCHWIN_ReleseChild(WIN_TouchWinStruct *touch,WIN_MoveStruct *m)
{
int mov_x=m->x_move;
int mov_y=m->y_move;
WIN_WindowStruct *win=(WIN_WindowStruct *)touch->work;
WIN_WindowStruct *base=(WIN_WindowStruct *)touch;
TouchConditionStruct *child=&touch->work_con;
int xs=win->x;
int ys=win->y;
int xe=win->x+win->x_size-1;
int ye=win->y+win->y_size-1;
int ok=0;//此项为1则创建定时器
// win->keyShield=0; //不屏蔽按键
// win->intercept=1; //拦截发给父窗口的按键
if(child->slide==TOUCH_SLIDE_DOWN)
{
if(ye<child->dis)
{
win->deleteWindow(win);
touch->work=0;
}
else ok=1;
}
else if(child->slide==TOUCH_SLIDE_UP)
{
if(base->y_size-ys<child->dis)
{
win->deleteWindow(win);
touch->work=0;
}
else ok=1;
}
else if(child->slide==TOUCH_SLIDE_LEFT)
{
if(base->x_size-xs<child->dis)
{
win->deleteWindow(win);
touch->work=0;
}
else ok=1;
}
else if(child->slide==TOUCH_SLIDE_RIGHT)
{
if(xe<child->dis)
{
win->deleteWindow(win);
touch->work=0;
}
else ok=1;
}
if(ok)
{
touch->timer_id=WIN_CreatTimer((WIN_WindowStruct *)touch,20);
}
}
//子窗口定时器处理
void TOUCHWIN_TimerChild(WIN_TouchWinStruct *touch)
{
WIN_WindowStruct *win=(WIN_WindowStruct *)touch->work;
int x=win->x/3;
int y=win->y/3;
WIN_SetPos(win,x,y);
if((y==0)&&(x==0))
{
WIN_DeleteTimer(touch->timer_id);
touch->timer_id=0;
win->keyShield=0;
win->intercept=1;
touch->work=0;
}
}
//判断滑动距离是否达到保留条件
static int check_slide_ok(WIN_TouchWinStruct *touch,TouchConditionStruct *t)
{
WIN_WindowStruct *win=(WIN_WindowStruct *)touch;
if(t->slide==TOUCH_SLIDE_LEFT)
{
if(t->creat)
{ if(win->x_size-win->x>t->dis) return 1; }
else {if(-win->x<t->dis) return 1;}
}
else if(t->slide==TOUCH_SLIDE_RIGHT)
{
if(t->creat)
{ if(win->x+win->x_size>t->dis) return 1;}
else {if(win->x<t->dis) return 1;}
}
else if(t->slide==TOUCH_SLIDE_UP)
{
if(t->creat)
{ if(win->y_size-win->y>t->dis) return 1; }
else {if(-win->y<t->dis) return 1;}
}
else if(t->slide==TOUCH_SLIDE_DOWN)
{
if(t->creat)
{ if(win->y+win->y_size>t->dis) return 1;}
else {if(win->y<t->dis) return 1;}
}
return 0;
}
//处理子窗口消息有返回1无返回0
int TOUCHWIN_ChildMsg(WIN_TouchWinStruct *touch,WIN_MsgStruct *msg)
{
int ret=0;
switch (msg->data.v)
{
case TOUCH_CHILD_MOV_START:
touch->work=(WIN_TouchWinStruct *)msg->data2.v;
mymemcpy(&touch->work_con,&touch->work->out,sizeof(TouchConditionStruct));
ret=1;
break;
case TOUCH_CHILD_MOV_END:
if((u32)touch->work==msg->data2.v)
{
WIN_WindowStruct *win=(WIN_WindowStruct *)touch->work;
if(check_slide_ok(touch->work,&touch->work_con)==0)
{
win->deleteWindow(win);
touch->work=0;
}
else
{
touch->timer_id=WIN_CreatTimer((WIN_WindowStruct *)touch,20);
}
ret=1;
}
break;
default:
break;
}
return ret;
}
//惯性定时器消息
int TOUCHWIN_TimerInertia(WIN_TouchWinStruct *touch)
{
if(touch->x_inertia>0) touch->x_inertia--;
else if(touch->x_inertia<0) touch->x_inertia++;
if(touch->y_inertia>0) touch->y_inertia--;
else if(touch->y_inertia<0) touch->y_inertia++;
//惯性滑动
WIN_SendTouchMove((WIN_WindowStruct *)touch,touch->x_inertia,touch->y_inertia);
if(touch->y_inertia==0&&touch->x_inertia==0)
{
WIN_DeleteTimer(touch->timer_inertia);
touch->timer_inertia=0;
}
return 0;
}
//默认消息循环
void TOUCHWIN_DefaultMsgLoop(WIN_TouchWinStruct *touch,WIN_MsgStruct *msg)
{
WIN_MoveStruct *m=0;
WIN_KeyStruct *k=0;
int ok=1; //此项为1则调用用户消息处理函数
switch (msg->msg)
{
// case WIN_MSG_PAINT:
// TOUCHWIN_DefaultPaint(touch);
// break;
case WIN_MSG_MOVE:
m=msg->data.p;
switch (m->moveType)
{
case MOVE_DATA_TOUCHIN:
case MOVE_DATA_MOVEIN:
{
//清除惯性定时器
if(touch->timer_inertia)
{
WIN_DeleteTimer(touch->timer_inertia);
touch->timer_inertia=0;
touch->x_inertia=0;
touch->y_inertia=0;
}
RECT_Struct *rect=&touch->out.start;
if(POS_InRect(rect->x,rect->y,rect->x_size,rect->y_size,m->x_move,m->y_move)==1)
{
//触发了退出动作
touch->move_start=1;
((WIN_WindowStruct *)touch)->intercept=0;
WIN_SetChildWinkeyShield((WIN_WindowStruct *)touch,1);
WIN_SendMsgToPrent((WIN_WindowStruct *)touch,TOUCH_CHILD_MOV_START,(u32)touch);
ok=0;
}
else if(TOUCHWIN_CreatChild(touch,m)==1)
{
ok=0;
}
}
break;
case MOVE_DATA_MOVED:
if(touch->work)
{
TOUCHWIN_MoveChild(touch,m);
ok=0;
}
else if(touch->move_start)
{
ok=0;
}
else if(touch->timer_inertia==0)
{
//存储惯性值
touch->x_inertia=m->x_move;
touch->y_inertia=m->y_move;
}
break;
case MOVE_DATA_TOUCHOUT:
case MOVE_DATA_MOVEOUT:
if(touch->work)
{
TOUCHWIN_ReleseChild(touch,m);
ok=0;
}
else if(touch->move_start)
{
touch->move_start=0;
((WIN_WindowStruct *)touch)->intercept=1;
WIN_SetChildWinkeyShield((WIN_WindowStruct *)touch,0);
WIN_SendMsgToPrent((WIN_WindowStruct *)touch,TOUCH_CHILD_MOV_END,(u32)touch);
ok=0;
}
else
{
//添加惯性定时器
if((touch->timer_inertia==0)&&(touch->x_inertia||touch->y_inertia))
touch->timer_inertia=WIN_CreatTimer((WIN_WindowStruct *)touch,20);
else if(touch->timer_inertia==0)
{
// 滑动停止
WIN_SendTouchMove((WIN_WindowStruct *)touch,0,0);
}
}
break;
// if(touch->work)
// {
// TOUCHWIN_ReleseChild(touch,m);
// ok=0;
// }
// break;
default:
break;
}
break;
case WIN_MSG_TIMER:
if(msg->data.v==touch->timer_id)
{
TOUCHWIN_TimerChild(touch);
ok=0;
}
else if(msg->data.v==touch->timer_inertia)
{
TOUCHWIN_TimerInertia(touch);
ok=0;
}
break;
case WIN_MSG_CHID:
if(TOUCHWIN_ChildMsg(touch,msg)==1)
{
ok=0;
}
break;
default:
WIN_DefaultMsgLoop((WIN_WindowStruct *)touch,msg);
break;
}
//调用用户消息处理函数
if(ok&&touch->msgloop)
touch->msgloop(touch,msg);
}