#include "includes.h" /* ============================================================================ * app_touch 实现 * * 状态机(与原 Touch_Process 一致): * IDLE → PRESS_WAIT_STABLE → PRESS_STABLE → SLIDING * * 时序参数: * 稳定判定 20ms (TOUCH_STABLE_TIME) * 滑动阈值 10px (TOUCH_SLIDE_THRESH) * 滑动步进 5px (TOUCH_SLIDE_STEP) * 长按触发 1000ms (TOUCH_LONG_PRESS_TIME) * 长按重复 120ms (TOUCH_REPEAT_INTERVAL) * ==========================================================================*/ /* ==================== 状态机枚举 ==================== */ typedef enum { TOUCH_IDLE, /* 空闲 */ TOUCH_PRESS_WAIT_STABLE, /* 按下,等待稳定判定 */ TOUCH_PRESS_STABLE, /* 稳定按下(可长按) */ TOUCH_SLIDING /* 滑动中 */ } touch_state_t; /* ==================== 时序参数 ==================== */ #define TOUCH_STABLE_TIME 20 /* 按下稳定判定时间 ms */ #define TOUCH_SLIDE_THRESH 10 /* 进入滑动的最小位移 px */ #define TOUCH_SLIDE_STEP 5 /* 滑动事件最小步进 px */ #define TOUCH_LONG_PRESS_TIME 1000 /* 长按触发 ms */ #define TOUCH_REPEAT_INTERVAL 120 /* 长按重复间隔 ms */ /* ==================== 状态变量 ==================== */ static touch_state_t touch_state = TOUCH_IDLE; static uint16_t down_x = 0; static uint16_t down_y = 0; static uint32_t touch_tick = 0; static uint32_t repeat_tick = 0; static uint8_t long_press_fired = 0; static uint16_t last_slide_x = 0; static uint16_t last_slide_y = 0; /* 取绝对值(避免引入 math.h) */ static inline uint16_t abs_diff(int16_t a, int16_t b) { int16_t d = a - b; return (d < 0) ? (uint16_t)(-d) : (uint16_t)d; } /* ==================== 重置 ==================== */ void app_touch_reset(void) { touch_state = TOUCH_IDLE; down_x = down_y = 0; touch_tick = repeat_tick = 0; long_press_fired = 0; last_slide_x = last_slide_y = 0; } /* ==================== 手势识别 ==================== */ app_touch_result_t app_touch_process(uint16_t x, uint16_t y, uint8_t pressed) { app_touch_result_t r; r.gesture = GESTURE_NONE; r.x = x; r.y = y; r.down_x = down_x; r.down_y = down_y; uint32_t now = rt_tick_get(); /* ---------- 抬起处理 ---------- */ if (!pressed) { /* 若曾稳定按下且未触发长按 → 释放(可当作 TAP) */ if (touch_state == TOUCH_PRESS_STABLE && !long_press_fired) { r.gesture = GESTURE_RELEASE; r.x = down_x; r.y = down_y; /* 用按下点作为释放坐标 */ } touch_state = TOUCH_IDLE; down_x = down_y = 0; last_slide_x = last_slide_y = 0; touch_tick = repeat_tick = 0; long_press_fired = 0; return r; } /* ---------- 按下处理 ---------- */ switch (touch_state) { case TOUCH_IDLE: down_x = x; down_y = y; touch_tick = now; long_press_fired = 0; repeat_tick = 0; touch_state = TOUCH_PRESS_WAIT_STABLE; break; case TOUCH_PRESS_WAIT_STABLE: if ((now - touch_tick) >= TOUCH_STABLE_TIME) { /* 位移小 → 进入稳定 */ if (abs_diff(x, down_x) < 8 && abs_diff(y, down_y) < 8) { touch_state = TOUCH_PRESS_STABLE; last_slide_x = down_x; last_slide_y = down_y; touch_tick = now; MainTask_Sendmsg(MSG_ID_TOUCH, 1, down_x, down_y); } else { /* 位移大 → 视为误触,回到空闲 */ touch_state = TOUCH_IDLE; } } break; case TOUCH_PRESS_STABLE: { /* ----- 长按检测 ----- */ if (!long_press_fired && (now - touch_tick) >= TOUCH_LONG_PRESS_TIME) { long_press_fired = 1; repeat_tick = now; r.gesture = GESTURE_LONG_PRESS; MainTask_Sendmsg(MSG_ID_TOUCH_LONG_REPEAT, 1, down_x, down_y); return r; } /* ----- 长按重复 ----- */ if (long_press_fired && (now - repeat_tick) >= TOUCH_REPEAT_INTERVAL) { repeat_tick = now; r.gesture = GESTURE_REPEAT; MainTask_Sendmsg(MSG_ID_TOUCH_LONG_REPEAT, 1, down_x, down_y); return r; } /* ----- 位移进入滑动 ----- */ if (abs_diff(x, down_x) >= TOUCH_SLIDE_THRESH || abs_diff(y, down_y) >= TOUCH_SLIDE_THRESH) { touch_state = TOUCH_SLIDING; last_slide_x = x; last_slide_y = y; } break; } case TOUCH_SLIDING: { /* 位移超过步进 → 产生拖动事件 */ if (abs_diff(x, last_slide_x) >= TOUCH_SLIDE_STEP || abs_diff(y, last_slide_y) >= TOUCH_SLIDE_STEP) { r.gesture = GESTURE_DRAG; r.down_x = last_slide_x; /* 记录上次位置,便于消费端算增量 */ r.down_y = last_slide_y; MainTask_Sendmsg(MSG_ID_TOUCH, 1, x, y); last_slide_x = x; last_slide_y = y; return r; } break; } default: touch_state = TOUCH_IDLE; break; } return r; /* 无手势 */ }