improve edit

This commit is contained in:
xianjimli 2018-06-19 18:21:58 +08:00
parent 82a9ecc1fe
commit d0033a7d1f
10 changed files with 136 additions and 27 deletions

View File

@ -59,7 +59,7 @@
brew install scons sdl2
```
编译运行:
编译运行(在终端下进入awtk所在的目录并运行下列命令)
```
scons
@ -74,7 +74,7 @@ scons
sudo apt-get install scons libsdl2-dev
```
编译运行:
编译运行(在终端下进入awtk所在的目录并运行下列命令)
```
scons
@ -83,9 +83,9 @@ scons
### Windows
(请先安装scons和Visual Studio C++)
(请先安装scons和Visual Studio C++(版本>=2012)
编译运行:
编译运行(在命令行模式下进入awtk所在的目录并运行下列命令)
```
scons
@ -136,6 +136,10 @@ bin\demoui
[TODO.md](TODO.md)
## 最新动态
* 2018/06/19
* 实现输入法框架。
* 实现软键盘基本功能。
* 2018/06/18
* 实现软键盘部分功能。
* 完善现有代码。

View File

@ -30,13 +30,13 @@ sources += ['lcd/lcd_mem_rgb565.c'];
if os.environ['VGCANVAS'] == 'NANOVG':
sources += Glob('vgcanvas/vgcanvas_nanovg.c')
sources += Glob('input_methods/input_method_default.c')
sources += Glob('input_methods/input_method_null.c')
elif os.environ['VGCANVAS'] == 'AGG':
sources += Glob('vgcanvas/vgcanvas_agg.cpp')
sources += Glob('input_methods/input_method_null.c')
sources += Glob('input_methods/input_method_default.c')
else:
sources += Glob('vgcanvas/vgcanvas_picasso.cpp')
sources += Glob('input_methods/input_method_null.c')
sources += Glob('input_methods/input_method_default.c')
env=DefaultEnvironment().Clone()
env.Library(os.path.join(LIB_DIR, 'awtk'), sources)

View File

@ -30,7 +30,7 @@
static ret_t edit_update_status(widget_t* widget);
static ret_t edit_update_carent(const timer_info_t* timer) {
static ret_t edit_update_caret(const timer_info_t* timer) {
rect_t r;
edit_t* edit = EDIT(timer->ctx);
widget_t* widget = WIDGET(timer->ctx);
@ -47,14 +47,18 @@ static ret_t edit_update_carent(const timer_info_t* timer) {
}
}
#define MAX_PASSWORD_LEN 31
static ret_t edit_on_paint_self(widget_t* widget, canvas_t* c) {
int32_t i = 0;
wstr_t text;
int32_t i = 0;
edit_t* edit = EDIT(widget);
wstr_t* str = &(widget->text);
style_t* style = &(widget->style);
wchar_t password[MAX_PASSWORD_LEN + 1];
int32_t margin = style_get_int(style, STYLE_ID_MARGIN, 4);
wh_t caret_x = margin;
wchar_t invisible_char = '*';
bool_t invisible = str->size && (edit->limit.type == INPUT_PASSWORD && !(edit->password_visible));
if (!str->size && !widget->focused) {
str = &(edit->tips);
@ -73,7 +77,9 @@ static ret_t edit_on_paint_self(widget_t* widget, canvas_t* c) {
i = str->size - 1;
while (w > 0 && i >= 0) {
cw = canvas_measure_text(c, str->str + i, 1);
wchar_t chr = invisible ? invisible_char : str->str[i];
cw = canvas_measure_text(c, &chr, 1);
caret_x += cw;
w -= cw;
if (w > cw && i > 0) {
@ -91,6 +97,17 @@ static ret_t edit_on_paint_self(widget_t* widget, canvas_t* c) {
text.size = 0;
}
if (invisible) {
uint32_t i = 0;
uint32_t size = tk_min(text.size, MAX_PASSWORD_LEN);
for (i = 0; i < size; i++) {
password[i] = invisible_char;
}
password[size] = '\0';
text.str = password;
text.size = size;
}
widget_paint_helper(widget, c, NULL, &text);
if (widget->focused && !edit->readonly && edit->caret_visible) {
@ -120,18 +137,68 @@ static ret_t edit_delete_next_char(widget_t* widget) {
static ret_t edit_input_char(widget_t* widget, wchar_t c) {
edit_t* edit = EDIT(widget);
wstr_t* text = &(widget->text);
input_type_t input_type = edit->limit.type;
switch (input_type) {
case INPUT_INT:
case INPUT_FLOAT: {
case INPUT_UINT: {
if (c == '0') {
if (text->size > 0) {
wstr_push(text, c);
}
break;
} else if (c >= '1' && c <= '9') {
wstr_push(text, c);
break;
} else if (c == '+' || (c == '-' && input_type == INPUT_INT)) {
if (text->size == 0) {
wstr_push(text, c);
}
break;
}
break;
}
case INPUT_FLOAT:
case INPUT_UFLOAT: {
if (c == '0') {
if (text->size > 0) {
wstr_push(text, c);
}
break;
} else if (c >= '1' && c <= '9') {
wstr_push(text, c);
break;
} else if (c == '+' || (c == '-' && input_type == INPUT_FLOAT)) {
if (text->size == 0) {
wstr_push(text, c);
}
break;
} else if (c == '.' || c == 'e') {
if (text->size > 0 && wcs_chr(text->str, c) == NULL) {
wstr_push(text, c);
}
}
break;
}
case INPUT_EMAIL: {
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '-' ||
c == '.' || c == '_') {
wstr_push(text, c);
} else if (c == '@') {
if (text->size > 0 && wcs_chr(text->str, c) == NULL) {
wstr_push(text, c);
}
}
break;
}
case INPUT_PHONE: {
if (c >= '0' && c <= '9') {
wstr_push(&(widget->text), c);
} else if (widget->text.size == 0 && (c == '-' || c == '+')) {
wstr_push(&(widget->text), c);
} else if (input_type == INPUT_FLOAT && c == '.') {
if (wcschr(widget->text.str, '.') == NULL) {
wstr_push(&(widget->text), c);
wstr_push(text, c);
break;
} else if (c == '-') {
if (text->size > 0 && wcs_chr(text->str, c) == NULL) {
wstr_push(text, c);
}
}
break;
@ -143,9 +210,6 @@ static ret_t edit_input_char(widget_t* widget, wchar_t c) {
}
}
edit_update_status(widget);
widget_invalidate(widget, NULL);
return RET_OK;
}
@ -220,23 +284,26 @@ static ret_t edit_on_event(widget_t* widget, event_t* e) {
switch (type) {
case EVT_POINTER_DOWN:
if (edit->timer_id == 0) {
edit->timer_id = timer_add(edit_update_carent, widget, 600);
edit->timer_id = timer_add(edit_update_caret, widget, 600);
}
edit_update_status(widget);
break;
case EVT_KEY_DOWN: {
key_event_t* evt = (key_event_t*)e;
edit_on_key_down(widget, evt);
widget_invalidate(widget, NULL);
break;
}
case EVT_IM_COMMIT: {
im_commit_event_t* evt = (im_commit_event_t*)e;
edit_commit_str(widget, evt->str);
widget_invalidate(widget, NULL);
break;
}
case EVT_KEY_UP: {
key_event_t* evt = (key_event_t*)e;
edit_on_key_up(widget, evt);
widget_invalidate(widget, NULL);
break;
}
case EVT_BLUR: {
@ -422,6 +489,15 @@ static ret_t edit_set_prop(widget_t* widget, const char* name, const value_t* v)
return RET_NOT_FOUND;
}
ret_t edit_set_password_visible(widget_t* widget, bool_t password_visible) {
edit_t* edit = EDIT(widget);
return_value_if_fail(widget != NULL, RET_BAD_PARAMS);
edit->password_visible = password_visible;
return RET_OK;
}
static const widget_vtable_t s_edit_vtable = {.on_paint_self = edit_on_paint_self,
.set_prop = edit_set_prop,
.get_prop = edit_get_prop,

View File

@ -59,8 +59,9 @@ typedef struct _edit_t {
uint16_t selected_start;
uint16_t selected_end;
xy_t caret_x;
bool_t caret_visible;
bool_t readonly;
bool_t caret_visible;
bool_t password_visible;
wstr_t tips;
uint32_t timer_id;
@ -145,6 +146,16 @@ ret_t edit_set_input_type(widget_t* widget, input_type_t type);
*/
ret_t edit_set_input_tips(widget_t* widget, const wchar_t* tips);
/**
* @method edit_set_password_visible
*
* @param {widget_t*} widget widget对象
* @param {bool_t} password_visible
*
* @return {ret_t} RET_OK表示成功
*/
ret_t edit_set_password_visible(widget_t* widget, bool_t password_visible);
#define EDIT(widget) ((edit_t*)(widget))
END_C_DECLS

View File

@ -1082,6 +1082,13 @@ ret_t widget_invalidate(widget_t* widget, rect_t* r) {
}
}
ret_t widget_invalidate_force(widget_t* widget) {
return_value_if_fail(widget != NULL, RET_BAD_PARAMS);
widget->dirty = FALSE;
return widget_invalidate(widget, NULL);
}
const void* widget_get_window_theme(widget_t* widget) {
widget_t* win = widget_get_window(widget);
return_value_if_fail(win != NULL, NULL);

View File

@ -856,7 +856,7 @@ ret_t widget_off_by_func(widget_t* widget, event_type_t type, event_func_t on_ev
/**
* @method widget_invalidate
*
* widget->dirty已经为TRUE
* @param {widget_t*} widget
* @param {rect_t*} r
*
@ -864,6 +864,15 @@ ret_t widget_off_by_func(widget_t* widget, event_type_t type, event_func_t on_ev
*/
ret_t widget_invalidate(widget_t* widget, rect_t* r);
/**
* @method widget_invalidate_force
*
* @param {widget_t*} widget
*
* @return {ret_t} RET_OK表示成功
*/
ret_t widget_invalidate_force(widget_t* widget);
/**
* @method widget_paint
* canvas上

View File

@ -70,7 +70,7 @@ static ret_t input_method_default_show_keyboard(input_method_t* im) {
}
}
im->keyboard = window_open(keyboard);
im->keyboard = keyboard_open(keyboard);
return RET_OK;
}

View File

@ -112,6 +112,7 @@ static ret_t ui_builder_default_on_end(ui_builder_t* b) {
widget_update_style(win);
widget_layout(win);
widget_dispatch(win, &e);
widget_invalidate_force(win);
}
return RET_OK;

View File

@ -30,6 +30,7 @@ ui_builder_t* ui_builder_default(const char* name);
widget_t* window_open(const char* name);
widget_t* dialog_open(const char* name);
widget_t* keyboard_open(const char* name);
END_C_DECLS