K1Guitar/APP/app_touch.c

144 lines
4.3 KiB
C
Raw Normal View History

#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;
LOG_D("TP", "release x=%u y=%u", (unsigned)down_x, (unsigned)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;
LOG_D("TP", "press down x=%u y=%u", (unsigned)down_x, (unsigned)down_y);
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;
LOG_D("TP", "long_press x=%u y=%u", (unsigned)down_x, (unsigned)down_y);
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;
}