Skip to content

Commit

Permalink
improve editor
Browse files Browse the repository at this point in the history
  • Loading branch information
xianjimli committed Dec 9, 2023
1 parent 0e29ab4 commit b30756c
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 10 deletions.
4 changes: 2 additions & 2 deletions design/default/ui/keyboard.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
<list_view x="0" y="0" w="100%" h="-50" item_height="36" auto_hide_scroll_bar="true">
<scroll_view name="view" x="0" y="0" w="-12" h="100%">
<list_item style="empty" children_layout="default(r=1,c=0,ym=1)">
<label w="30%" text="Name"/>
<edit w="70%" text="" tips="name" action_text="next"/>
<label w="30%" text="Name(3-10)"/>
<edit w="70%" text="" tips="name" action_text="next" validator="(len(text) >= 3) && (len(text) <= 10)"/>
</list_item>
<list_item style="empty" children_layout="default(r=1,c=0,ym=1)">
<label w="30%" text="Desc"/>
Expand Down
1 change: 1 addition & 0 deletions docs/changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
2023/12/09
* 增加函数 date\_time\_parse\_date/date\_time\_parse\_time/date\_time\_parse\_date\_time
* 完善 fscript ulen。
* edit 增加了 validator 属性,支持使用fscript校验输入数据是否合法。

2023/12/07
* csv file object 支持通过 MVVM 来查询。
Expand Down
6 changes: 6 additions & 0 deletions src/base/widget_consts.h
Original file line number Diff line number Diff line change
Expand Up @@ -1099,6 +1099,12 @@ BEGIN_C_DECLS
*/
#define WIDGET_PROP_MAX_FPS "max_fps"

/**
* @const WIDGET_PROP_VALIDATOR
* 数据校验脚本。
*/
#define WIDGET_PROP_VALIDATOR "validator"

/**
* @enum widget_type_t
* @annotation ["scriptable", "string"]
Expand Down
51 changes: 43 additions & 8 deletions src/widgets/edit.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ static ret_t edit_reset_layout(widget_t* widget);
static ret_t edit_update_status(widget_t* widget);
static ret_t edit_check_valid_value(widget_t* widget);
static ret_t edit_select_all_async(const idle_info_t* info);
static ret_t edit_dispatch_value_change_event(widget_t* widget, event_type_t type);
static ret_t edit_dispatch_value_change_event(widget_t* widget, uint32_t type);
static ret_t edit_paste(widget_t* widget, const wchar_t* str, uint32_t size);

static ret_t edit_save_text(widget_t* widget) {
Expand Down Expand Up @@ -87,7 +87,7 @@ static ret_t edit_commit_text(widget_t* widget) {
return RET_OK;
}

static ret_t edit_dispatch_value_change_event(widget_t* widget, event_type_t type) {
static ret_t edit_dispatch_value_change_event(widget_t* widget, uint32_t type) {
value_change_event_t evt;
edit_t* edit = EDIT(widget);
wstr_t* text = &(widget->text);
Expand Down Expand Up @@ -702,7 +702,8 @@ static ret_t edit_on_key_down(widget_t* widget, key_event_t* e) {

if (key == TK_KEY_TAB || key == TK_KEY_ESCAPE || (key >= TK_KEY_F1 && key <= TK_KEY_F12)) {
return RET_OK;
} else if (key == TK_KEY_DOWN && keyboard_type != KEYBOARD_3KEYS && keyboard_type != KEYBOARD_5KEYS) {
} else if (key == TK_KEY_DOWN && keyboard_type != KEYBOARD_3KEYS &&
keyboard_type != KEYBOARD_5KEYS) {
if (widget_is_change_focus_key(widget, e)) {
return RET_OK;
}
Expand All @@ -713,7 +714,8 @@ static ret_t edit_on_key_down(widget_t* widget, key_event_t* e) {
widget_focus_next(widget);
}
return RET_STOP;
} else if (key == TK_KEY_UP && keyboard_type != KEYBOARD_3KEYS && keyboard_type != KEYBOARD_5KEYS) {
} else if (key == TK_KEY_UP && keyboard_type != KEYBOARD_3KEYS &&
keyboard_type != KEYBOARD_5KEYS) {
if (widget_is_change_focus_key(widget, e)) {
return RET_OK;
}
Expand Down Expand Up @@ -874,7 +876,8 @@ ret_t edit_on_event(widget_t* widget, event_t* e) {
#else
bool_t is_control = evt->ctrl;
#endif
if ((!edit->is_activated || key == TK_KEY_RETURN) && (keyboard_type == KEYBOARD_3KEYS || keyboard_type == KEYBOARD_5KEYS)) {
if ((!edit->is_activated || key == TK_KEY_RETURN) &&
(keyboard_type == KEYBOARD_3KEYS || keyboard_type == KEYBOARD_5KEYS)) {
break;
}
if (edit->readonly) {
Expand All @@ -894,7 +897,8 @@ ret_t edit_on_event(widget_t* widget, event_t* e) {
break;
}
case EVT_KEY_UP: {
if (!edit->is_activated && (keyboard_type == KEYBOARD_3KEYS || keyboard_type == KEYBOARD_5KEYS)) {
if (!edit->is_activated &&
(keyboard_type == KEYBOARD_3KEYS || keyboard_type == KEYBOARD_5KEYS)) {
break;
}
edit->is_key_inputing = TRUE;
Expand Down Expand Up @@ -958,8 +962,7 @@ ret_t edit_on_event(widget_t* widget, event_t* e) {
break;
}
case EVT_FOCUS: {
if (keyboard_type != KEYBOARD_3KEYS &&
keyboard_type != KEYBOARD_5KEYS &&
if (keyboard_type != KEYBOARD_3KEYS && keyboard_type != KEYBOARD_5KEYS &&
edit->open_im_when_focused) {
edit_on_focused(widget);
}
Expand Down Expand Up @@ -1445,6 +1448,10 @@ ret_t edit_get_prop(widget_t* widget, const char* name, value_t* v) {
}
value_set_bool(v, inputing);

return RET_OK;
} else if(tk_str_eq(name, WIDGET_PROP_VALIDATOR)) {
value_set_str(v, edit->validator);

return RET_OK;
}

Expand Down Expand Up @@ -1574,6 +1581,9 @@ ret_t edit_set_prop(widget_t* widget, const char* name, const value_t* v) {
} else if (tk_str_eq(name, WIDGET_PROP_VALUE) || tk_str_eq(name, WIDGET_PROP_TEXT)) {
edit_set_text(widget, v);
return RET_OK;
} else if(tk_str_eq(name, WIDGET_PROP_VALIDATOR)) {
edit_set_validator(widget, value_str(v));
return RET_OK;
}

edit_update_status(widget);
Expand Down Expand Up @@ -1967,6 +1977,7 @@ ret_t edit_on_destroy(widget_t* widget) {
TKMEM_FREE(edit->tips);
TKMEM_FREE(edit->tr_tips);
TKMEM_FREE(edit->keyboard);
TKMEM_FREE(edit->validator);
TKMEM_FREE(edit->action_text);
wstr_reset(&(edit->saved_text));
wstr_reset(&(edit->last_changing_text));
Expand Down Expand Up @@ -2344,12 +2355,36 @@ static ret_t edit_auto_fix(widget_t* widget) {
}
}

#include "tkc/fscript.h"
#include "base/object_widget.h"

ret_t edit_set_validator(widget_t* widget, const char* validator) {
edit_t* edit = EDIT(widget);
return_value_if_fail(edit != NULL, RET_BAD_PARAMS);

edit->validator = tk_str_copy(edit->validator, validator);

return RET_OK;
}

bool_t edit_is_valid_value(widget_t* widget) {
edit_t* edit = EDIT(widget);
return_value_if_fail(edit != NULL, RET_BAD_PARAMS);
if (edit->is_valid_value != NULL) {
return edit->is_valid_value(widget);
} else {
#ifndef WITHOUT_FSCRIPT
if (edit->validator != NULL) {
value_t v;
tk_object_t* obj = object_widget_create(widget);
if (fscript_eval(obj, edit->validator, &v) == RET_OK) {
TK_OBJECT_UNREF(obj);
return value_bool(&v);
}
TK_OBJECT_UNREF(obj);
}
#endif/*WITHOUT_FSCRIPT*/

return edit_is_valid_value_default(widget);
}
}
20 changes: 20 additions & 0 deletions src/widgets/edit.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,14 @@ typedef struct _edit_t {
*
*/
char* action_text;
/**
* @property {char*} validator
* @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"]
* fscript脚本,用输入校验,如:(len(text) > 3) && (len(text) < 10)。
*
* > 用于校验输入的文本是否合法。
*/
char* validator;

/**
* @property {char*} keyboard
Expand Down Expand Up @@ -567,6 +575,18 @@ ret_t edit_set_is_valid_char(widget_t* widget, edit_is_valid_char_t is_valid_cha
*/
ret_t edit_set_is_valid_value(widget_t* widget, edit_is_valid_value_t is_valid_value);

/**
* @method edit_set_validator
* 设置输入内容校验脚本。
*> 如果内置函数不能满足需求时,可以设置自定义的检查脚本。
*
* @param {widget_t*} widget widget对象。
* @param {const char*} validator 校验输入内容的脚本。
*
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
*/
ret_t edit_set_validator(widget_t* widget, const char* validator);

/**
* @method edit_set_fix_value
* 设置修正输入内容的回调函数。
Expand Down
12 changes: 12 additions & 0 deletions tests/edit_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -666,3 +666,15 @@ TEST(Edit, set_props) {

widget_destroy(e);
}

TEST(Edit, validator) {
widget_t* e = edit_create(NULL, 10, 20, 30, 40);

widget_set_text(e, L"abcd");
ASSERT_EQ(edit_is_valid_value(e), TRUE);

edit_set_validator(e, "len(text) < 3");
ASSERT_EQ(edit_is_valid_value(e), FALSE);

widget_destroy(e);
}

0 comments on commit b30756c

Please sign in to comment.