mirror of
https://gitee.com/zlgopen/awtk.git
synced 2024-11-30 02:58:26 +08:00
support use tab/up/down key to change focused edit
This commit is contained in:
parent
d802b180a9
commit
2227daeade
@ -6,6 +6,7 @@
|
|||||||
* 修改关闭system\_bar时没有注销事件的BUG(感谢朝泽提供补丁)。
|
* 修改关闭system\_bar时没有注销事件的BUG(感谢朝泽提供补丁)。
|
||||||
* window支持fullscreen属性。
|
* window支持fullscreen属性。
|
||||||
* 修改edit缺省焦点的BUG。
|
* 修改edit缺省焦点的BUG。
|
||||||
|
* 支持用tab/up/down键切换编辑器焦点。
|
||||||
|
|
||||||
* 2019/03/19
|
* 2019/03/19
|
||||||
* 增加window\_close\_force函数。
|
* 增加window\_close\_force函数。
|
||||||
|
@ -2082,3 +2082,79 @@ bool_t widget_is_keyboard(widget_t* widget) {
|
|||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool_t widget_is_focusable(widget_t* widget) {
|
||||||
|
value_t v;
|
||||||
|
value_set_bool(&v, FALSE);
|
||||||
|
widget_get_prop(widget, WIDGET_PROP_FOCUSABLE, &v);
|
||||||
|
|
||||||
|
return value_bool(&v);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ret_t widget_on_visit_focusable(void* ctx, const void* data) {
|
||||||
|
widget_t* widget = WIDGET(data);
|
||||||
|
darray_t* all_focusable = (darray_t*)ctx;
|
||||||
|
|
||||||
|
if (widget_is_focusable(widget)) {
|
||||||
|
darray_push(all_focusable, widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
return RET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ret_t widget_get_all_focusable_widgets_win(widget_t* widget, darray_t* all_focusable) {
|
||||||
|
widget_t* win = widget_get_window(widget);
|
||||||
|
return_value_if_fail(win != NULL, RET_BAD_PARAMS);
|
||||||
|
|
||||||
|
widget_foreach(win, widget_on_visit_focusable, all_focusable);
|
||||||
|
|
||||||
|
return RET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ret_t widget_move_focus(widget_t* widget, bool_t next) {
|
||||||
|
uint32_t i = 0;
|
||||||
|
uint32_t focus = 0;
|
||||||
|
darray_t all_focusable;
|
||||||
|
return_value_if_fail(widget != NULL && widget->focused, RET_BAD_PARAMS);
|
||||||
|
return_value_if_fail(darray_init(&all_focusable, 10, NULL, NULL) != NULL, RET_OOM);
|
||||||
|
|
||||||
|
widget_get_all_focusable_widgets_win(widget, &all_focusable);
|
||||||
|
|
||||||
|
if (all_focusable.size > 1) {
|
||||||
|
for (i = 0; i < all_focusable.size; i++) {
|
||||||
|
widget_t* iter = WIDGET(all_focusable.elms[i]);
|
||||||
|
if (iter == widget) {
|
||||||
|
if (next) {
|
||||||
|
if ((i + 1) == all_focusable.size) {
|
||||||
|
focus = 0;
|
||||||
|
} else {
|
||||||
|
focus = i + 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (i == 0) {
|
||||||
|
focus = all_focusable.size - 1;
|
||||||
|
} else {
|
||||||
|
focus = i - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
iter = WIDGET(all_focusable.elms[focus]);
|
||||||
|
widget_set_prop_bool(widget, WIDGET_PROP_FOCUS, FALSE);
|
||||||
|
widget_set_prop_bool(iter, WIDGET_PROP_FOCUS, TRUE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
darray_deinit(&all_focusable);
|
||||||
|
|
||||||
|
return RET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret_t widget_focus_prev(widget_t* widget) {
|
||||||
|
return widget_move_focus(widget, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret_t widget_focus_next(widget_t* widget) {
|
||||||
|
return widget_move_focus(widget, TRUE);
|
||||||
|
}
|
||||||
|
@ -82,6 +82,12 @@ struct _widget_vtable_t {
|
|||||||
* 是否是窗口。
|
* 是否是窗口。
|
||||||
*/
|
*/
|
||||||
uint32_t is_window : 1;
|
uint32_t is_window : 1;
|
||||||
|
/**
|
||||||
|
* 是否是focusable。
|
||||||
|
*
|
||||||
|
*>如编辑器。
|
||||||
|
*/
|
||||||
|
uint32_t is_focusable : 1;
|
||||||
/**
|
/**
|
||||||
* 是否是设计窗口。
|
* 是否是设计窗口。
|
||||||
*/
|
*/
|
||||||
@ -1683,6 +1689,30 @@ ret_t widget_update_style(widget_t* widget);
|
|||||||
*/
|
*/
|
||||||
ret_t widget_set_as_key_target(widget_t* widget);
|
ret_t widget_set_as_key_target(widget_t* widget);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @method widget_focus_next
|
||||||
|
* 把焦点移动下一个控件。
|
||||||
|
*
|
||||||
|
*>widget必须是当前焦点控件。
|
||||||
|
* @annotation ["private"]
|
||||||
|
* @param {widget_t*} widget widget对象。
|
||||||
|
*
|
||||||
|
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||||
|
*/
|
||||||
|
ret_t widget_focus_next(widget_t* widget);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @method widget_focus_prev
|
||||||
|
* 把焦点移动前一个控件。
|
||||||
|
*
|
||||||
|
*>widget必须是当前焦点控件。
|
||||||
|
* @annotation ["private"]
|
||||||
|
* @param {widget_t*} widget widget对象。
|
||||||
|
*
|
||||||
|
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||||
|
*/
|
||||||
|
ret_t widget_focus_prev(widget_t* widget);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @method widget_get_state_for_style
|
* @method widget_get_state_for_style
|
||||||
* 把控件的状态转成获取style选要的状态,一般只在子类中使用。
|
* 把控件的状态转成获取style选要的状态,一般只在子类中使用。
|
||||||
|
@ -647,6 +647,12 @@ BEGIN_C_DECLS
|
|||||||
*/
|
*/
|
||||||
#define WIDGET_PROP_FOCUS "focus"
|
#define WIDGET_PROP_FOCUS "focus"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const WIDGET_PROP_FOCUSABLE
|
||||||
|
* 是否支持焦点停留。
|
||||||
|
*/
|
||||||
|
#define WIDGET_PROP_FOCUSABLE "focusable"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum widget_type_t
|
* @enum widget_type_t
|
||||||
* @annotation ["scriptable", "string"]
|
* @annotation ["scriptable", "string"]
|
||||||
|
@ -597,9 +597,6 @@ ret_t window_manager_on_paint_children(widget_t* widget, canvas_t* c) {
|
|||||||
widget_paint(iter, c);
|
widget_paint(iter, c);
|
||||||
if (!has_fullscreen_win) {
|
if (!has_fullscreen_win) {
|
||||||
has_fullscreen_win = is_window_fullscreen(iter);
|
has_fullscreen_win = is_window_fullscreen(iter);
|
||||||
if (has_fullscreen_win) {
|
|
||||||
log_debug("%s is fullscreen\n", iter->name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -427,6 +427,12 @@ static ret_t edit_on_key_down(widget_t* widget, key_event_t* e) {
|
|||||||
} else {
|
} else {
|
||||||
return edit_set_cursor_pos(widget, edit->cursor_pos + 1, edit->cursor_pos + 1);
|
return edit_set_cursor_pos(widget, edit->cursor_pos + 1, edit->cursor_pos + 1);
|
||||||
}
|
}
|
||||||
|
} else if (key == TK_KEY_TAB || key == TK_KEY_DOWN) {
|
||||||
|
widget_focus_next(widget);
|
||||||
|
return RET_OK;
|
||||||
|
} else if (key == TK_KEY_UP) {
|
||||||
|
widget_focus_prev(widget);
|
||||||
|
return RET_OK;
|
||||||
} else {
|
} else {
|
||||||
if (system_info()->app_type != APP_DESKTOP && key < 128 && isprint(key)) {
|
if (system_info()->app_type != APP_DESKTOP && key < 128 && isprint(key)) {
|
||||||
return edit_input_char(widget, (wchar_t)key);
|
return edit_input_char(widget, (wchar_t)key);
|
||||||
@ -844,6 +850,9 @@ ret_t edit_get_prop(widget_t* widget, const char* name, value_t* v) {
|
|||||||
} else if (tk_str_eq(name, WIDGET_PROP_TIPS)) {
|
} else if (tk_str_eq(name, WIDGET_PROP_TIPS)) {
|
||||||
value_set_str(v, edit->tips);
|
value_set_str(v, edit->tips);
|
||||||
return RET_OK;
|
return RET_OK;
|
||||||
|
} else if (tk_str_eq(name, WIDGET_PROP_FOCUSABLE)) {
|
||||||
|
value_set_bool(v, !(edit->readonly));
|
||||||
|
return RET_OK;
|
||||||
} else if (tk_str_eq(name, WIDGET_PROP_VALUE)) {
|
} else if (tk_str_eq(name, WIDGET_PROP_VALUE)) {
|
||||||
value_set_wstr(v, widget->text.str);
|
value_set_wstr(v, widget->text.str);
|
||||||
return RET_OK;
|
return RET_OK;
|
||||||
@ -1225,6 +1234,7 @@ const char* s_edit_properties[] = {WIDGET_PROP_MIN,
|
|||||||
NULL};
|
NULL};
|
||||||
TK_DECL_VTABLE(edit) = {.size = sizeof(edit_t),
|
TK_DECL_VTABLE(edit) = {.size = sizeof(edit_t),
|
||||||
.type = WIDGET_TYPE_EDIT,
|
.type = WIDGET_TYPE_EDIT,
|
||||||
|
.is_focusable = TRUE,
|
||||||
.clone_properties = s_edit_properties,
|
.clone_properties = s_edit_properties,
|
||||||
.persistent_properties = s_edit_properties,
|
.persistent_properties = s_edit_properties,
|
||||||
.parent = TK_PARENT_VTABLE(widget),
|
.parent = TK_PARENT_VTABLE(widget),
|
||||||
|
@ -164,3 +164,48 @@ TEST(Edit, focus) {
|
|||||||
|
|
||||||
widget_destroy(w);
|
widget_destroy(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Edit, focus_next) {
|
||||||
|
widget_t* w = window_create(NULL, 0, 0, 400, 400);
|
||||||
|
widget_t* g = group_box_create(w, 0, 0, 400, 400);
|
||||||
|
widget_t* e1 = edit_create(g, 10, 20, 30, 40);
|
||||||
|
widget_t* e2 = edit_create(g, 10, 60, 30, 40);
|
||||||
|
widget_t* e3 = edit_create(g, 10, 90, 30, 40);
|
||||||
|
|
||||||
|
ASSERT_EQ(edit_set_focus(e1, TRUE), RET_OK);
|
||||||
|
ASSERT_EQ(g->key_target, e1);
|
||||||
|
ASSERT_EQ(widget_focus_next(e1), RET_OK);
|
||||||
|
ASSERT_EQ(g->key_target, e2);
|
||||||
|
ASSERT_EQ(widget_focus_next(e1), RET_BAD_PARAMS);
|
||||||
|
|
||||||
|
ASSERT_EQ(widget_focus_next(e2), RET_OK);
|
||||||
|
ASSERT_EQ(g->key_target, e3);
|
||||||
|
|
||||||
|
ASSERT_EQ(widget_focus_next(e3), RET_OK);
|
||||||
|
ASSERT_EQ(g->key_target, e1);
|
||||||
|
|
||||||
|
widget_destroy(w);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Edit, focus_prev) {
|
||||||
|
widget_t* w = window_create(NULL, 0, 0, 400, 400);
|
||||||
|
widget_t* g = group_box_create(w, 0, 0, 400, 400);
|
||||||
|
widget_t* e1 = edit_create(g, 10, 20, 30, 40);
|
||||||
|
widget_t* e2 = edit_create(g, 10, 60, 30, 40);
|
||||||
|
widget_t* e3 = edit_create(g, 10, 90, 30, 40);
|
||||||
|
|
||||||
|
ASSERT_EQ(edit_set_focus(e1, TRUE), RET_OK);
|
||||||
|
ASSERT_EQ(g->key_target, e1);
|
||||||
|
|
||||||
|
ASSERT_EQ(widget_focus_prev(e1), RET_OK);
|
||||||
|
ASSERT_EQ(g->key_target, e3);
|
||||||
|
ASSERT_EQ(widget_focus_prev(e1), RET_BAD_PARAMS);
|
||||||
|
|
||||||
|
ASSERT_EQ(widget_focus_prev(e3), RET_OK);
|
||||||
|
ASSERT_EQ(g->key_target, e2);
|
||||||
|
|
||||||
|
ASSERT_EQ(widget_focus_prev(e2), RET_OK);
|
||||||
|
ASSERT_EQ(g->key_target, e1);
|
||||||
|
|
||||||
|
widget_destroy(w);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user