141 lines
4.0 KiB
C
141 lines
4.0 KiB
C
#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;
|
|
}
|