#include "includes.h" /* 按下即发点击;抬起仅补发未发出的短按 */ typedef enum { TOUCH_IDLE, TOUCH_PRESS_WAIT_STABLE, TOUCH_PRESS_STABLE, TOUCH_SLIDING } touch_state_t; #define TOUCH_STABLE_TIME 8 #define TOUCH_SLIDE_THRESH 12 #define TOUCH_SLIDE_STEP 5 #define TOUCH_LONG_PRESS_TIME 800 #define TOUCH_REPEAT_INTERVAL 120 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 uint8_t click_sent = 0; static uint16_t last_slide_x = 0; static uint16_t last_slide_y = 0; 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; click_sent = 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) { if (!long_press_fired && !click_sent && (touch_state == TOUCH_PRESS_WAIT_STABLE || touch_state == TOUCH_PRESS_STABLE)) { r.gesture = GESTURE_RELEASE; r.x = down_x; r.y = down_y; MainTask_Sendmsg(MSG_ID_TOUCH, 1, down_x, 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; click_sent = 0; return r; } switch (touch_state) { case TOUCH_IDLE: down_x = x; down_y = y; touch_tick = now; long_press_fired = 0; click_sent = 0; repeat_tick = 0; touch_state = TOUCH_PRESS_WAIT_STABLE; /* 第一帧就发点击,模式选择等页跟手 */ click_sent = 1; MainTask_Sendmsg(MSG_ID_TOUCH, 1, down_x, down_y); break; case TOUCH_PRESS_WAIT_STABLE: if ((now - touch_tick) >= TOUCH_STABLE_TIME) { if (abs_diff(x, down_x) < 24 && abs_diff(y, down_y) < 24) touch_state = TOUCH_PRESS_STABLE; else { down_x = x; down_y = y; touch_tick = now; } } 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; }