mirror of
https://gitee.com/zlgopen/awtk.git
synced 2024-11-29 18:48:09 +08:00
support key long press event
This commit is contained in:
parent
b7e3df2f7d
commit
99af46c719
@ -162,7 +162,7 @@ OS_PROJECTS=[]
|
||||
OS_WHOLE_ARCHIVE=''
|
||||
if OS_NAME == 'Darwin':
|
||||
TOOLS_NAME = ''
|
||||
OS_FLAGS='-g -Wall -fPIC '
|
||||
OS_FLAGS='-g -Wall -fPIC -DWITHOUT_GLAD=1 '
|
||||
OS_LIBS = ['stdc++', 'iconv','pthread', 'm', 'dl']
|
||||
OS_LINKFLAGS='-framework IOKit -framework Cocoa -framework QuartzCore -framework OpenGL -weak_framework Metal -weak_framework MetalKit'
|
||||
COMMON_CCFLAGS = COMMON_CCFLAGS + ' -DHAS_SEM_OPEN '
|
||||
|
@ -1,4 +1,7 @@
|
||||
# 最新动态
|
||||
* 2020/09/15
|
||||
* 支持长按键事件
|
||||
|
||||
* 2020/09/11
|
||||
* 支持 packed 图片。
|
||||
* 增加 [如何使用 packed 图](docs/how_to_use_packed_image.md)
|
||||
|
@ -121,6 +121,11 @@ typedef enum _event_type_t {
|
||||
* 键按下事件名(key_event_t)。
|
||||
*/
|
||||
EVT_KEY_DOWN,
|
||||
/**
|
||||
* @const EVT_KEY_LONG_PRESS
|
||||
* 键长按事件名(key_event_t)。
|
||||
*/
|
||||
EVT_KEY_LONG_PRESS,
|
||||
/**
|
||||
* @const EVT_KEY_DOWN_BEFORE_CHILDREN
|
||||
* 键按下事件名,在子控件处理之前触发(key_event_t)。
|
||||
|
@ -20,6 +20,7 @@
|
||||
*/
|
||||
|
||||
#include "tkc/mem.h"
|
||||
#include "tkc/time_now.h"
|
||||
#include "base/keys.h"
|
||||
#include "base/system_info.h"
|
||||
#include "base/input_device_status.h"
|
||||
@ -31,6 +32,89 @@ input_device_status_t* input_device_status_init(input_device_status_t* ids) {
|
||||
return ids;
|
||||
}
|
||||
|
||||
static key_pressed_info_t* input_device_status_find_press_info(input_device_status_t* ids,
|
||||
uint32_t key) {
|
||||
uint32_t i = 0;
|
||||
for (i = 0; i < MAX_PRESSED_KEYS_NR; i++) {
|
||||
key_pressed_info_t* iter = ids->pressed_info + i;
|
||||
if (iter->key == key) {
|
||||
return iter;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool_t input_device_status_has_pressed_key(input_device_status_t* ids) {
|
||||
uint32_t i = 0;
|
||||
for (i = 0; i < MAX_PRESSED_KEYS_NR; i++) {
|
||||
key_pressed_info_t* iter = ids->pressed_info + i;
|
||||
if (iter->key) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static ret_t input_device_status_dispatch_long_press(input_device_status_t* ids) {
|
||||
uint32_t i = 0;
|
||||
key_event_t evt;
|
||||
uint64_t now = time_now_ms();
|
||||
widget_t* widget = ids->widget;
|
||||
|
||||
for (i = 0; i < MAX_PRESSED_KEYS_NR; i++) {
|
||||
key_pressed_info_t* iter = ids->pressed_info + i;
|
||||
if (iter->key && !iter->emitted) {
|
||||
uint64_t t = now - iter->time;
|
||||
if (t >= TK_LONG_PRESS_TIME) {
|
||||
key_event_init(&evt, EVT_KEY_LONG_PRESS, widget, iter->key);
|
||||
widget_on_keydown(widget, &evt);
|
||||
log_debug("long press:%d\n", iter->key);
|
||||
iter->emitted = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t long_press_check_on_timer(const timer_info_t* info) {
|
||||
input_device_status_t* ids = (input_device_status_t*)(info->ctx);
|
||||
|
||||
input_device_status_dispatch_long_press(ids);
|
||||
|
||||
if (input_device_status_has_pressed_key(ids)) {
|
||||
return RET_REPEAT;
|
||||
} else {
|
||||
ids->long_press_check_timer = TK_INVALID_ID;
|
||||
return RET_REMOVE;
|
||||
}
|
||||
}
|
||||
|
||||
static ret_t input_device_status_update_key_press_info(input_device_status_t* ids, uint32_t key,
|
||||
bool_t down) {
|
||||
key_pressed_info_t* info = input_device_status_find_press_info(ids, key);
|
||||
|
||||
if (down) {
|
||||
if (info == NULL) {
|
||||
info = input_device_status_find_press_info(ids, 0);
|
||||
return_value_if_fail(info != NULL, RET_BAD_PARAMS);
|
||||
info->key = key;
|
||||
info->time = time_now_ms();
|
||||
}
|
||||
|
||||
if (ids->long_press_check_timer == TK_INVALID_ID) {
|
||||
ids->long_press_check_timer = timer_add(long_press_check_on_timer, ids, TK_LONG_PRESS_TIME);
|
||||
}
|
||||
} else {
|
||||
return_value_if_fail(info != NULL, RET_BAD_PARAMS);
|
||||
memset(info, 0x00, sizeof(key_pressed_info_t));
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t input_device_status_update_key_status(input_device_status_t* ids, uint32_t key,
|
||||
bool_t down) {
|
||||
if (key == TK_KEY_LSHIFT) {
|
||||
@ -62,6 +146,7 @@ static ret_t input_device_status_update_key_status(input_device_status_t* ids, u
|
||||
ids->capslock = !(ids->capslock);
|
||||
}
|
||||
}
|
||||
input_device_status_update_key_press_info(ids, key, down);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
@ -148,6 +233,7 @@ static ret_t input_device_status_init_key_event(input_device_status_t* ids, key_
|
||||
ret_t input_device_status_on_input_event(input_device_status_t* ids, widget_t* widget, event_t* e) {
|
||||
return_value_if_fail(ids != NULL && e != NULL, RET_BAD_PARAMS);
|
||||
|
||||
ids->widget = widget;
|
||||
switch (e->type) {
|
||||
case EVT_POINTER_DOWN: {
|
||||
pointer_event_t* evt = (pointer_event_t*)e;
|
||||
|
@ -26,6 +26,14 @@
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
#define MAX_PRESSED_KEYS_NR 16
|
||||
|
||||
typedef struct _key_pressed_info_t {
|
||||
uint32_t key;
|
||||
uint32_t emitted;
|
||||
uint64_t time;
|
||||
} key_pressed_info_t;
|
||||
|
||||
/**
|
||||
* @class input_device_status_t
|
||||
* 输入设备状态管理器。本类仅供窗口管理器内部使用。
|
||||
@ -47,6 +55,9 @@ typedef struct _input_device_status_t {
|
||||
xy_t last_x;
|
||||
xy_t last_y;
|
||||
bool_t pressed;
|
||||
widget_t* widget;
|
||||
uint32_t long_press_check_timer;
|
||||
key_pressed_info_t pressed_info[MAX_PRESSED_KEYS_NR + 1];
|
||||
} input_device_status_t;
|
||||
|
||||
/**
|
||||
|
@ -2198,14 +2198,19 @@ ret_t widget_on_keydown(widget_t* widget, key_event_t* e) {
|
||||
|
||||
widget_ref(widget);
|
||||
widget_map_key(widget, e);
|
||||
ret = widget_on_keydown_impl(widget, e);
|
||||
if (widget->feedback) {
|
||||
ui_feedback_request(widget, (event_t*)e);
|
||||
}
|
||||
if (e->e.type == EVT_KEY_DOWN) {
|
||||
ret = widget_on_keydown_impl(widget, e);
|
||||
if (widget->feedback) {
|
||||
ui_feedback_request(widget, (event_t*)e);
|
||||
}
|
||||
|
||||
e->key = key;
|
||||
if (ret != RET_STOP) {
|
||||
ret = widget_on_keydown_general(widget, e);
|
||||
e->key = key;
|
||||
if (ret != RET_STOP) {
|
||||
ret = widget_on_keydown_general(widget, e);
|
||||
}
|
||||
} else if (e->e.type == EVT_KEY_LONG_PRESS) {
|
||||
return_if_equal(widget_on_keydown_children(widget, e), RET_STOP);
|
||||
ret = widget_on_keydown_after_children(widget, e);
|
||||
}
|
||||
widget_unref(widget);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user