#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 ((uint32_t)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, (uint32_t)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, (uint32_t)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); }