move input device status related code from window_manager to input_device_status.c

This commit is contained in:
xianjimli 2018-11-28 15:40:46 +08:00
parent 0ae1129231
commit c85f116fc8
6 changed files with 438 additions and 162 deletions

View File

@ -0,0 +1,190 @@
/**
* File: input_device_status.h
* Author: AWTK Develop Team
* Brief: input device status
*
* Copyright (c) 2018 - 2018 Guangzhou ZHIYUAN Electronics Co.,Ltd.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* License file for more details.
*
*/
/**
* History:
* ================================================================
* 2018-11-28 Li XianJing <xianjimli@hotmail.com> created
*
*/
#include "base/mem.h"
#include "base/keys.h"
#include "base/system_info.h"
#include "base/input_device_status.h"
input_device_status_t* input_device_status_init(input_device_status_t* ids) {
return_value_if_fail(ids != NULL, NULL);
memset(ids, 0x00, sizeof(input_device_status_t));
return ids;
}
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 || key == TK_KEY_RSHIFT) {
ids->shift = down;
}
if (key == TK_KEY_LALT || key == TK_KEY_RALT) {
ids->alt = down;
}
if (key == TK_KEY_LCTRL || key == TK_KEY_RCTRL) {
ids->ctrl = down;
}
if (key == TK_KEY_CAPSLOCK) {
ids->capslock = down;
}
return RET_OK;
}
typedef struct _key_shift_t {
char key;
char shift_key;
} key_shift_t;
static const key_shift_t key_shift[] = {
{'`', '~'}, {'1', '!'}, {'2', '@'}, {'3', '#'}, {'4', '$'}, {'5', '%'}, {'6', '^'},
{'7', '&'}, {'8', '*'}, {'9', '('}, {'0', ')'}, {'-', '_'}, {'=', '+'}, {'[', '{'},
{']', '}'}, {',', '<'}, {'.', '>'}, {'\\', '|'}, {'/', '?'},
};
static ret_t input_device_status_shift_key(input_device_status_t* ids, key_event_t* e) {
char c = (char)e->key;
if (ids->shift) {
uint32_t i = 0;
for (i = 0; i < ARRAY_SIZE(key_shift); i++) {
if (key_shift[i].key == c) {
e->key = key_shift[i].shift_key;
return RET_OK;
}
}
}
if (ids->shift && ids->capslock) {
return RET_OK;
}
if (ids->shift || ids->capslock) {
if (c >= TK_KEY_a && c <= TK_KEY_z) {
e->key = c - 32;
}
}
return RET_OK;
}
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);
switch (e->type) {
case EVT_POINTER_DOWN: {
pointer_event_t* evt = (pointer_event_t*)e;
pointer_event_rotate(evt, system_info());
evt->alt = ids->alt;
evt->ctrl = ids->ctrl;
evt->shift = ids->shift;
ids->pressed = TRUE;
ids->last_x = evt->x;
ids->last_y = evt->y;
widget_on_pointer_down(widget, evt);
break;
}
case EVT_POINTER_MOVE: {
pointer_event_t* evt = (pointer_event_t*)e;
pointer_event_rotate(evt, system_info());
if (evt->x != ids->last_x || evt->y != ids->last_y) {
ids->last_x = evt->x;
ids->last_y = evt->y;
evt->alt = ids->alt;
evt->ctrl = ids->ctrl;
evt->shift = ids->shift;
widget_on_pointer_move(widget, evt);
}
break;
}
case EVT_POINTER_UP: {
pointer_event_t* evt = (pointer_event_t*)e;
pointer_event_rotate(evt, system_info());
evt->alt = ids->alt;
evt->ctrl = ids->ctrl;
evt->shift = ids->shift;
widget_on_pointer_up(widget, evt);
ids->last_x = evt->x;
ids->last_y = evt->y;
ids->pressed = FALSE;
break;
}
case EVT_KEY_DOWN: {
key_event_t* evt = (key_event_t*)e;
input_device_status_update_key_status(ids, evt->key, TRUE);
evt->alt = ids->alt;
evt->ctrl = ids->ctrl;
evt->shift = ids->shift;
evt->capslock = ids->capslock;
input_device_status_shift_key(ids, evt);
widget_on_keydown(widget, evt);
break;
}
case EVT_KEY_UP: {
key_event_t* evt = (key_event_t*)e;
evt->alt = ids->alt;
evt->ctrl = ids->ctrl;
evt->shift = ids->shift;
evt->capslock = ids->capslock;
input_device_status_shift_key(ids, evt);
widget_on_keyup(widget, evt);
input_device_status_update_key_status(ids, evt->key, FALSE);
break;
}
case EVT_CONTEXT_MENU: {
pointer_event_t* evt = (pointer_event_t*)e;
pointer_event_rotate(evt, system_info());
evt->alt = ids->alt;
evt->ctrl = ids->ctrl;
evt->shift = ids->shift;
widget_dispatch_to_target(widget, e);
break;
}
case EVT_WHEEL: {
wheel_event_t* evt = (wheel_event_t*)e;
evt->alt = ids->alt;
evt->ctrl = ids->ctrl;
evt->shift = ids->shift;
widget_dispatch_to_key_target(widget, e);
break;
}
default:
break;
}
return RET_OK;
}

View File

@ -0,0 +1,67 @@
/**
* File: input_device_status.h
* Author: AWTK Develop Team
* Brief: input device status
*
* Copyright (c) 2018 - 2018 Guangzhou ZHIYUAN Electronics Co.,Ltd.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* License file for more details.
*
*/
/**
* History:
* ================================================================
* 2018-11-28 Li XianJing <xianjimli@hotmail.com> created
*
*/
#ifndef TK_INPUT_DEVICE_STATUS_H
#define TK_INPUT_DEVICE_STATUS_H
#include "base/widget.h"
BEGIN_C_DECLS
/**
* @class input_device_status_t
* 使
*/
typedef struct _input_device_status_t {
uint8_t ctrl : 1;
uint8_t alt : 1;
uint8_t shift : 1;
uint8_t capslock : 1;
xy_t last_x;
xy_t last_y;
bool_t pressed;
} input_device_status_t;
/**
* @method input_device_status_init
*
* @annotation ["constructor"]
* @param {input_device_status_t*} ids
*
* @return {input_device_status_t*}
*/
input_device_status_t* input_device_status_init(input_device_status_t* ids);
/**
* @method input_device_status_on_input_event
* widget
* @param {input_device_status_t*} ids
* @param {widget_t*} widget
* @param {event_t*} e
*
* @return {ret_t} RET_OK表示成功
*/
ret_t input_device_status_on_input_event(input_device_status_t* ids, widget_t* widget, event_t* e);
END_C_DECLS
#endif /*TK_INPUT_DEVICE_STATUS_H*/

View File

@ -613,65 +613,14 @@ ret_t window_manager_resize(widget_t* widget, wh_t w, wh_t h) {
return window_manger_layout_children(widget);
}
static ret_t window_manager_update_key_status(window_manager_t* wm, uint32_t key, bool_t down) {
if (key == FKEY_LSHIFT || key == FKEY_RSHIFT) {
wm->shift = down;
}
if (key == FKEY_LALT || key == FKEY_RALT) {
wm->alt = down;
}
if (key == FKEY_LCTRL || key == FKEY_RCTRL) {
wm->ctrl = down;
}
if (key == FKEY_CAPSLOCK) {
wm->caplock = down;
}
return RET_OK;
}
typedef struct _key_shift_t {
char key;
char shift_key;
} key_shift_t;
static const key_shift_t key_shift[] = {
{'`', '~'}, {'1', '!'}, {'2', '@'}, {'3', '#'}, {'4', '$'}, {'5', '%'}, {'6', '^'},
{'7', '&'}, {'8', '*'}, {'9', '('}, {'0', ')'}, {'-', '_'}, {'=', '+'}, {'[', '{'},
{']', '}'}, {',', '<'}, {'.', '>'}, {'\\', '|'}, {'/', '?'},
};
static ret_t window_manager_shift_key(window_manager_t* wm, key_event_t* e) {
char c = (char)e->key;
if (wm->shift) {
uint32_t i = 0;
for (i = 0; i < ARRAY_SIZE(key_shift); i++) {
if (key_shift[i].key == c) {
e->key = key_shift[i].shift_key;
return RET_OK;
}
}
}
if (wm->shift && wm->caplock) {
return RET_OK;
}
if (wm->shift || wm->caplock) {
if (c >= FKEY_a && c <= FKEY_z) {
e->key = c - 32;
}
}
return RET_OK;
}
ret_t window_manager_dispatch_input_event(widget_t* widget, event_t* e) {
input_device_status_t* ids = NULL;
window_manager_t* wm = WINDOW_MANAGER(widget);
return_value_if_fail(wm != NULL && e != NULL, RET_BAD_PARAMS);
ids = &(wm->input_device_status);
if (wm->ignore_user_input) {
if (wm->pressed && e->type == EVT_POINTER_UP) {
if (ids->pressed && e->type == EVT_POINTER_UP) {
log_debug("animating ignore input, but it is last pointer_up\n");
} else {
log_debug("animating ignore input\n");
@ -679,104 +628,8 @@ ret_t window_manager_dispatch_input_event(widget_t* widget, event_t* e) {
}
}
switch (e->type) {
case EVT_POINTER_DOWN: {
pointer_event_t* evt = (pointer_event_t*)e;
pointer_event_rotate(evt, system_info());
evt->alt = wm->alt;
evt->ctrl = wm->ctrl;
evt->shift = wm->shift;
wm->pressed = TRUE;
wm->last_x = evt->x;
wm->last_y = evt->y;
widget_on_pointer_down(widget, evt);
window_manager_update_cursor(widget, evt->x, evt->y);
break;
}
case EVT_POINTER_MOVE: {
pointer_event_t* evt = (pointer_event_t*)e;
pointer_event_rotate(evt, system_info());
if (evt->x != wm->last_x || evt->y != wm->last_y) {
wm->last_x = evt->x;
wm->last_y = evt->y;
evt->alt = wm->alt;
evt->ctrl = wm->ctrl;
evt->shift = wm->shift;
widget_on_pointer_move(widget, evt);
window_manager_update_cursor(widget, evt->x, evt->y);
}
break;
}
case EVT_POINTER_UP: {
pointer_event_t* evt = (pointer_event_t*)e;
pointer_event_rotate(evt, system_info());
evt->alt = wm->alt;
evt->ctrl = wm->ctrl;
evt->shift = wm->shift;
widget_on_pointer_up(widget, evt);
wm->last_x = evt->x;
wm->last_y = evt->y;
wm->pressed = FALSE;
window_manager_update_cursor(widget, evt->x, evt->y);
break;
}
case EVT_KEY_DOWN: {
key_event_t* evt = (key_event_t*)e;
window_manager_update_key_status(wm, evt->key, TRUE);
evt->alt = wm->alt;
evt->ctrl = wm->ctrl;
evt->shift = wm->shift;
evt->caplock = wm->caplock;
window_manager_shift_key(wm, evt);
widget_on_keydown(widget, evt);
break;
}
case EVT_KEY_UP: {
key_event_t* evt = (key_event_t*)e;
evt->alt = wm->alt;
evt->ctrl = wm->ctrl;
evt->shift = wm->shift;
evt->caplock = wm->caplock;
window_manager_shift_key(wm, evt);
widget_on_keyup(widget, evt);
window_manager_update_key_status(wm, evt->key, FALSE);
break;
}
case EVT_CONTEXT_MENU: {
pointer_event_t* evt = (pointer_event_t*)e;
pointer_event_rotate(evt, system_info());
evt->alt = wm->alt;
evt->ctrl = wm->ctrl;
evt->shift = wm->shift;
widget_dispatch_to_target(widget, e);
break;
}
case EVT_WHEEL: {
wheel_event_t* evt = (wheel_event_t*)e;
evt->alt = wm->alt;
evt->ctrl = wm->ctrl;
evt->shift = wm->shift;
widget_dispatch_to_key_target(widget, e);
break;
}
default:
break;
}
input_device_status_on_input_event(ids, widget, e);
window_manager_update_cursor(widget, ids->last_x, ids->last_y);
return RET_OK;
}

View File

@ -25,6 +25,7 @@
#include "base/widget.h"
#include "base/canvas.h"
#include "base/window_animator.h"
#include "base/input_device_status.h"
BEGIN_C_DECLS
@ -48,11 +49,6 @@ typedef struct _window_manager_t {
rect_t dirty_rect;
rect_t last_dirty_rect;
uint8_t ctrl : 1;
uint8_t alt : 1;
uint8_t shift : 1;
uint8_t caplock : 1;
bool_t animating;
bool_t ignore_user_input;
window_animator_t* animator;
@ -62,7 +58,6 @@ typedef struct _window_manager_t {
uint32_t fps;
uint32_t fps_time;
uint32_t fps_count;
bool_t pressed;
widget_t* pending_close_window;
widget_t* pending_open_window;
@ -70,8 +65,7 @@ typedef struct _window_manager_t {
char* cursor;
rect_t r_cursor;
xy_t last_x;
xy_t last_y;
input_device_status_t input_device_status;
} window_manager_t;
/**

View File

@ -1,15 +1,18 @@
import os
import sys
TK_ROOT=os.environ['TK_ROOT'];
GTEST_ROOT=os.environ['GTEST_ROOT'];
BIN_DIR=os.environ['BIN_DIR'];
TK_ROOT=os.environ['TK_ROOT'];
TK_3RD_ROOT=os.environ['TK_3RD_ROOT'];
GTEST_ROOT=os.environ['GTEST_ROOT'];
env=DefaultEnvironment().Clone();
INCLUDE_PATH = [TK_ROOT,
GTEST_ROOT,
os.path.join(TK_ROOT, 'src'),
os.path.join(TK_3RD_ROOT, 'SDL/src'),
os.path.join(TK_3RD_ROOT, 'SDL/include'),
os.path.join(TK_ROOT, 'src/ext_widgets'),
os.path.join(TK_ROOT, '3rd/libunibreak'),
os.path.join(GTEST_ROOT, 'src'),

View File

@ -0,0 +1,169 @@
#include "gtest/gtest.h"
#include <string>
#include "base/keys.h"
#include "base/button.h"
#include "base/input_device_status.h"
using std::string;
TEST(InputDeviceStatus, basic) {
input_device_status_t input_device_status;
input_device_status_t* ids = input_device_status_init(&input_device_status);
ASSERT_EQ(ids->alt, FALSE);
ASSERT_EQ(ids->ctrl, FALSE);
ASSERT_EQ(ids->capslock, FALSE);
ASSERT_EQ(ids->pressed, FALSE);
ASSERT_EQ(ids->last_x, 0);
ASSERT_EQ(ids->last_y, 0);
}
static string s_log;
static ret_t on_event(void* ctx, event_t* e) {
if (e->type == EVT_KEY_DOWN) {
s_log = "keydown";
} else if (e->type == EVT_KEY_UP) {
s_log = "keyup";
} else if (e->type == EVT_POINTER_DOWN) {
s_log = "pointerdown";
} else if (e->type == EVT_POINTER_MOVE) {
s_log = "pointermove";
} else if (e->type == EVT_POINTER_UP) {
s_log = "pointerup";
}
return RET_OK;
}
TEST(InputDeviceStatus, alt) {
key_event_t e;
widget_t* w = button_create(NULL, 0, 0, 0, 0);
input_device_status_t input_device_status;
input_device_status_t* ids = input_device_status_init(&input_device_status);
widget_on(w, EVT_KEY_DOWN, on_event, w);
widget_on(w, EVT_KEY_UP, on_event, w);
e.key = TK_KEY_LALT;
e.e = event_init(EVT_KEY_DOWN, NULL);
input_device_status_on_input_event(ids, w, (event_t*)(&e));
ASSERT_EQ(ids->alt, TRUE);
ASSERT_EQ(s_log, "keydown");
e.e = event_init(EVT_KEY_UP, NULL);
input_device_status_on_input_event(ids, w, (event_t*)(&e));
ASSERT_EQ(ids->alt, FALSE);
ASSERT_EQ(s_log, "keyup");
e.key = TK_KEY_RALT;
e.e = event_init(EVT_KEY_DOWN, NULL);
input_device_status_on_input_event(ids, w, (event_t*)(&e));
ASSERT_EQ(ids->alt, TRUE);
ASSERT_EQ(s_log, "keydown");
e.e = event_init(EVT_KEY_UP, NULL);
input_device_status_on_input_event(ids, w, (event_t*)(&e));
ASSERT_EQ(ids->alt, FALSE);
ASSERT_EQ(s_log, "keyup");
widget_destroy(w);
}
TEST(InputDeviceStatus, ctrl) {
key_event_t e;
widget_t* w = button_create(NULL, 0, 0, 0, 0);
input_device_status_t input_device_status;
input_device_status_t* ids = input_device_status_init(&input_device_status);
widget_on(w, EVT_KEY_DOWN, on_event, w);
widget_on(w, EVT_KEY_UP, on_event, w);
e.key = TK_KEY_LCTRL;
e.e = event_init(EVT_KEY_DOWN, NULL);
input_device_status_on_input_event(ids, w, (event_t*)(&e));
ASSERT_EQ(ids->ctrl, TRUE);
ASSERT_EQ(s_log, "keydown");
e.e = event_init(EVT_KEY_UP, NULL);
input_device_status_on_input_event(ids, w, (event_t*)(&e));
ASSERT_EQ(ids->ctrl, FALSE);
ASSERT_EQ(s_log, "keyup");
e.key = TK_KEY_RCTRL;
e.e = event_init(EVT_KEY_DOWN, NULL);
input_device_status_on_input_event(ids, w, (event_t*)(&e));
ASSERT_EQ(ids->ctrl, TRUE);
ASSERT_EQ(s_log, "keydown");
e.e = event_init(EVT_KEY_UP, NULL);
input_device_status_on_input_event(ids, w, (event_t*)(&e));
ASSERT_EQ(ids->ctrl, FALSE);
ASSERT_EQ(s_log, "keyup");
widget_destroy(w);
}
TEST(InputDeviceStatus, capslock) {
key_event_t e;
widget_t* w = button_create(NULL, 0, 0, 0, 0);
input_device_status_t input_device_status;
input_device_status_t* ids = input_device_status_init(&input_device_status);
widget_on(w, EVT_KEY_DOWN, on_event, w);
widget_on(w, EVT_KEY_UP, on_event, w);
e.key = TK_KEY_CAPSLOCK;
e.e = event_init(EVT_KEY_DOWN, NULL);
input_device_status_on_input_event(ids, w, (event_t*)(&e));
ASSERT_EQ(ids->capslock, TRUE);
ASSERT_EQ(s_log, "keydown");
e.e = event_init(EVT_KEY_UP, NULL);
input_device_status_on_input_event(ids, w, (event_t*)(&e));
ASSERT_EQ(ids->capslock, FALSE);
ASSERT_EQ(s_log, "keyup");
widget_destroy(w);
}
TEST(InputDeviceStatus, pointer) {
pointer_event_t e;
widget_t* w = button_create(NULL, 0, 0, 0, 0);
input_device_status_t input_device_status;
input_device_status_t* ids = input_device_status_init(&input_device_status);
widget_on(w, EVT_POINTER_DOWN, on_event, w);
widget_on(w, EVT_POINTER_MOVE, on_event, w);
widget_on(w, EVT_POINTER_UP, on_event, w);
e.x = 10;
e.y = 20;
e.pressed = TRUE;
e.e = event_init(EVT_POINTER_DOWN, NULL);
input_device_status_on_input_event(ids, w, (event_t*)(&e));
ASSERT_EQ(ids->last_x, e.x);
ASSERT_EQ(ids->last_y, e.y);
ASSERT_EQ(ids->pressed, TRUE);
ASSERT_EQ(s_log, "pointerdown");
e.x = 20;
e.y = 30;
e.pressed = TRUE;
e.e = event_init(EVT_POINTER_MOVE, NULL);
input_device_status_on_input_event(ids, w, (event_t*)(&e));
ASSERT_EQ(ids->last_x, e.x);
ASSERT_EQ(ids->last_y, e.y);
ASSERT_EQ(ids->pressed, TRUE);
ASSERT_EQ(s_log, "pointermove");
e.x = 30;
e.y = 40;
e.pressed = TRUE;
e.e = event_init(EVT_POINTER_UP, NULL);
input_device_status_on_input_event(ids, w, (event_t*)(&e));
ASSERT_EQ(ids->last_x, e.x);
ASSERT_EQ(ids->last_y, e.y);
ASSERT_EQ(ids->pressed, FALSE);
ASSERT_EQ(s_log, "pointerup");
widget_destroy(w);
}