2026-08-26 07:26:58 +08:00
|
|
|
#include "includes.h"
|
|
|
|
|
|
2026-08-31 11:24:10 +08:00
|
|
|
/* ?????????????????????????????? */
|
2026-08-26 07:26:58 +08:00
|
|
|
|
|
|
|
|
typedef enum {
|
2026-08-31 11:13:01 +08:00
|
|
|
TOUCH_IDLE,
|
|
|
|
|
TOUCH_PRESS_WAIT_STABLE,
|
|
|
|
|
TOUCH_PRESS_STABLE,
|
|
|
|
|
TOUCH_SLIDING
|
2026-08-26 07:26:58 +08:00
|
|
|
} touch_state_t;
|
|
|
|
|
|
2026-08-31 11:13:01 +08:00
|
|
|
#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
|
2026-08-26 07:26:58 +08:00
|
|
|
|
|
|
|
|
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;
|
2026-08-31 11:13:01 +08:00
|
|
|
static uint8_t click_sent = 0;
|
2026-08-26 07:26:58 +08:00
|
|
|
static uint16_t last_slide_x = 0;
|
|
|
|
|
static uint16_t last_slide_y = 0;
|
2026-08-31 21:59:12 +08:00
|
|
|
static uint32_t suppress_until = 0;
|
2026-08-26 07:26:58 +08:00
|
|
|
|
|
|
|
|
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;
|
2026-08-31 11:13:01 +08:00
|
|
|
click_sent = 0;
|
2026-08-26 07:26:58 +08:00
|
|
|
last_slide_x = last_slide_y = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-31 21:59:12 +08:00
|
|
|
void app_touch_suppress(uint32_t ms)
|
|
|
|
|
{
|
|
|
|
|
uint32_t now = rt_tick_get();
|
|
|
|
|
uint32_t ticks = (ms * RT_TICK_PER_SECOND + 999U) / 1000U;
|
|
|
|
|
suppress_until = now + ticks;
|
|
|
|
|
app_touch_reset();
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-26 07:26:58 +08:00
|
|
|
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();
|
|
|
|
|
|
2026-08-31 21:59:12 +08:00
|
|
|
/* 切页抑制窗口内丢弃按下,避免误触底栏设置 */
|
|
|
|
|
if ((int32_t)(now - suppress_until) < 0) {
|
|
|
|
|
if (!pressed) {
|
|
|
|
|
app_touch_reset();
|
|
|
|
|
}
|
|
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-26 07:26:58 +08:00
|
|
|
if (!pressed) {
|
2026-08-31 11:13:01 +08:00
|
|
|
if (!long_press_fired && !click_sent &&
|
|
|
|
|
(touch_state == TOUCH_PRESS_WAIT_STABLE ||
|
2026-08-31 21:59:12 +08:00
|
|
|
touch_state == TOUCH_PRESS_STABLE ||
|
|
|
|
|
touch_state == TOUCH_SLIDING))
|
2026-08-31 11:13:01 +08:00
|
|
|
{
|
2026-08-31 21:59:12 +08:00
|
|
|
/* 导航页:抬起时发一次点击(坐标更稳,避免按下瞬间误触底栏) */
|
|
|
|
|
if (CurrUIProcress != UI_Mixer_Process) {
|
|
|
|
|
r.gesture = GESTURE_RELEASE;
|
|
|
|
|
r.x = down_x;
|
|
|
|
|
r.y = down_y;
|
|
|
|
|
LOG_TPI("release x=%u y=%u -> MSG", (unsigned)down_x, (unsigned)down_y);
|
|
|
|
|
MainTask_Sendmsg(MSG_ID_TOUCH, 1, down_x, down_y);
|
|
|
|
|
}
|
2026-08-26 07:26:58 +08:00
|
|
|
}
|
|
|
|
|
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;
|
2026-08-31 11:13:01 +08:00
|
|
|
click_sent = 0;
|
2026-08-26 07:26:58 +08:00
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (touch_state)
|
|
|
|
|
{
|
|
|
|
|
case TOUCH_IDLE:
|
|
|
|
|
down_x = x;
|
|
|
|
|
down_y = y;
|
|
|
|
|
touch_tick = now;
|
|
|
|
|
long_press_fired = 0;
|
2026-08-31 11:13:01 +08:00
|
|
|
click_sent = 0;
|
2026-08-26 07:26:58 +08:00
|
|
|
repeat_tick = 0;
|
|
|
|
|
touch_state = TOUCH_PRESS_WAIT_STABLE;
|
2026-08-31 21:59:12 +08:00
|
|
|
/* Mixer 推子:按下即报;其它页等抬起再报,防止进页后残留按下误触设置 */
|
|
|
|
|
if (CurrUIProcress == UI_Mixer_Process) {
|
|
|
|
|
click_sent = 1;
|
|
|
|
|
LOG_TPI("press x=%u y=%u -> MSG", (unsigned)down_x, (unsigned)down_y);
|
|
|
|
|
MainTask_Sendmsg(MSG_ID_TOUCH, 1, down_x, down_y);
|
|
|
|
|
} else {
|
|
|
|
|
LOG_TPI("press down x=%u y=%u (wait release)", (unsigned)down_x, (unsigned)down_y);
|
|
|
|
|
}
|
2026-08-26 07:26:58 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case TOUCH_PRESS_WAIT_STABLE:
|
|
|
|
|
if ((now - touch_tick) >= TOUCH_STABLE_TIME) {
|
2026-08-31 21:59:12 +08:00
|
|
|
if (abs_diff(x, down_x) < 24 && abs_diff(y, down_y) < 24) {
|
|
|
|
|
/* 用稳定后的坐标替换首采样噪声 */
|
|
|
|
|
down_x = x;
|
|
|
|
|
down_y = y;
|
2026-08-26 07:26:58 +08:00
|
|
|
touch_state = TOUCH_PRESS_STABLE;
|
2026-08-31 21:59:12 +08:00
|
|
|
} else {
|
2026-08-31 11:13:01 +08:00
|
|
|
down_x = x;
|
|
|
|
|
down_y = y;
|
2026-08-26 07:26:58 +08:00
|
|
|
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;
|
2026-08-31 21:59:12 +08:00
|
|
|
LOG_TPI("long_press x=%u y=%u", (unsigned)down_x, (unsigned)down_y);
|
2026-08-26 07:26:58 +08:00
|
|
|
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:
|
2026-08-31 21:59:12 +08:00
|
|
|
/* 仅 Mixer 需要拖动连续坐标;其它页拖动会误触底栏设置 Tab */
|
|
|
|
|
if (CurrUIProcress == UI_Mixer_Process &&
|
|
|
|
|
(abs_diff(x, last_slide_x) >= TOUCH_SLIDE_STEP ||
|
|
|
|
|
abs_diff(y, last_slide_y) >= TOUCH_SLIDE_STEP)) {
|
2026-08-26 07:26:58 +08:00
|
|
|
r.gesture = GESTURE_DRAG;
|
2026-08-31 11:13:01 +08:00
|
|
|
r.down_x = last_slide_x;
|
2026-08-26 07:26:58 +08:00
|
|
|
r.down_y = last_slide_y;
|
2026-08-31 21:59:12 +08:00
|
|
|
LOG_TPI("drag x=%u y=%u", (unsigned)x, (unsigned)y);
|
2026-08-26 07:26:58 +08:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-31 11:13:01 +08:00
|
|
|
return r;
|
2026-08-26 07:26:58 +08:00
|
|
|
}
|