diff --git a/docs/changes.md b/docs/changes.md index 1b45e4829..98b01f1cf 100644 --- a/docs/changes.md +++ b/docs/changes.md @@ -7,6 +7,7 @@ * 修复 tkc/event.c/event.h 中的错误(感谢忠吉提供补丁) * 修复 text\_selector 控件空选项时候选值出错问题(感谢智明提供补丁) * edit 控件的 text 值设置为错误的值时没有正确显示 error 状态和一开始 xml 上面设置错误值没有正确显示 error 状态(感谢智明提供补丁) + * 修改edit和mledit的边距属性以及优化了这两个控件的结构体布局(感谢智明提供补丁) 2021/01/12 * 增加函数 tk\_atoul diff --git a/src/base/text_edit.c b/src/base/text_edit.c index 3470e24b1..ecf9b33db 100644 --- a/src/base/text_edit.c +++ b/src/base/text_edit.c @@ -111,64 +111,28 @@ static align_h_t widget_get_text_align_h(widget_t* widget) { return (align_h_t)style_get_int(widget->astyle, STYLE_ID_TEXT_ALIGN_H, ALIGN_H_LEFT); } +#define TEXT_EDIT_GET_WIDGET_MARGIN(widget, style, out_value, type) { \ + value_t v; \ + value_set_int(&v, 0); \ + if (widget_get_prop((widget), WIDGET_PROP_##type##_MARGIN, &v) == RET_OK) { \ + (out_value) = value_int(&v); \ + } \ + TEXT_EDIT_GET_STYLE_MARGIN(style, out_value, type) \ +} \ + static ret_t widget_get_text_layout_info(widget_t* widget, text_layout_info_t* info) { - value_t v; style_t* style = widget->astyle; return_value_if_fail(widget != NULL && info != NULL && style != NULL, RET_BAD_PARAMS); - value_set_int(&v, 0); info->widget_w = widget->w; info->widget_h = widget->h; info->virtual_w = widget->w; info->virtual_h = widget->h; - if (widget_get_prop(widget, WIDGET_PROP_LEFT_MARGIN, &v) == RET_OK) { - info->margin_l = value_int(&v); - } - - if (info->margin_l == 0) { - info->margin_l = style_get_int(style, STYLE_ID_MARGIN_LEFT, 1); - } - - if (info->margin_l == 0) { - info->margin_l = style_get_int(style, STYLE_ID_MARGIN, 1); - } - - if (widget_get_prop(widget, WIDGET_PROP_RIGHT_MARGIN, &v) == RET_OK) { - info->margin_r = value_int(&v); - } - - if (info->margin_r == 0) { - info->margin_r = style_get_int(style, STYLE_ID_MARGIN_RIGHT, 1); - } - - if (info->margin_r == 0) { - info->margin_r = style_get_int(style, STYLE_ID_MARGIN, 1); - } - - if (widget_get_prop(widget, WIDGET_PROP_TOP_MARGIN, &v) == RET_OK) { - info->margin_t = value_int(&v); - } - - if (info->margin_t == 0) { - info->margin_t = style_get_int(style, STYLE_ID_MARGIN_TOP, 1); - } - - if (info->margin_t == 0) { - info->margin_t = style_get_int(style, STYLE_ID_MARGIN, 1); - } - - if (widget_get_prop(widget, WIDGET_PROP_BOTTOM_MARGIN, &v) == RET_OK) { - info->margin_b = value_int(&v); - } - - if (info->margin_b == 0) { - info->margin_b = style_get_int(style, STYLE_ID_MARGIN_BOTTOM, 1); - } - - if (info->margin_b == 0) { - info->margin_b = style_get_int(style, STYLE_ID_MARGIN, 1); - } + TEXT_EDIT_GET_WIDGET_MARGIN(widget, style, info->margin_l, LEFT); + TEXT_EDIT_GET_WIDGET_MARGIN(widget, style, info->margin_r, RIGHT); + TEXT_EDIT_GET_WIDGET_MARGIN(widget, style, info->margin_t, TOP); + TEXT_EDIT_GET_WIDGET_MARGIN(widget, style, info->margin_b, BOTTOM); info->w = info->widget_w - info->margin_l - info->margin_r; info->h = info->widget_h - info->margin_t - info->margin_b; @@ -724,6 +688,7 @@ static ret_t text_edit_do_paint(text_edit_t* text_edit, canvas_t* c) { return_value_if_fail(text_edit != NULL && c != NULL, RET_BAD_PARAMS); widget_prepare_text_style(text_edit->widget, c); + widget_get_text_layout_info(text_edit->widget, &(impl->layout_info)); new_line_height = c->font_size * FONT_BASELINE; is_notify = impl->line_height != new_line_height; diff --git a/src/base/text_edit.h b/src/base/text_edit.h index 21684ab24..b828c0420 100644 --- a/src/base/text_edit.h +++ b/src/base/text_edit.h @@ -26,6 +26,15 @@ BEGIN_C_DECLS +#define TEXT_EDIT_GET_STYLE_MARGIN(style, out_value, type) { \ + if ((out_value) == 0) { \ + (out_value) = style_get_int((style), STYLE_ID_MARGIN_##type, 0); \ + } \ + if ((out_value) == 0) { \ + (out_value) = style_get_int((style), STYLE_ID_MARGIN, 0); \ + } \ +} \ + /** * @class text_edit_state_t */ diff --git a/src/ext_widgets/mledit/mledit.c b/src/ext_widgets/mledit/mledit.c index c618ecb7c..0ce9259dd 100644 --- a/src/ext_widgets/mledit/mledit.c +++ b/src/ext_widgets/mledit/mledit.c @@ -190,16 +190,42 @@ static ret_t mledit_get_prop(widget_t* widget, const char* name, value_t* v) { value_set_int(v, mledit->scroll_line); return RET_OK; } else if (tk_str_eq(name, WIDGET_PROP_LEFT_MARGIN)) { - value_set_int(v, mledit->left_margin); + uint32_t margin = 0; + if (widget->astyle != NULL) { + TEXT_EDIT_GET_STYLE_MARGIN(widget->astyle, margin, LEFT); + } + if (margin == 0) { + margin = mledit->left_margin != 0 ? mledit->left_margin : mledit->margin; + } + value_set_int(v, margin); return RET_OK; } else if (tk_str_eq(name, WIDGET_PROP_RIGHT_MARGIN)) { - value_set_int(v, mledit->right_margin); + uint32_t margin = 0; + if (widget->astyle != NULL) { + TEXT_EDIT_GET_STYLE_MARGIN(widget->astyle, margin, RIGHT); + } + if (margin == 0) { + margin = mledit->right_margin != 0 ? mledit->right_margin : mledit->margin; + } + value_set_int(v, margin); return RET_OK; } else if (tk_str_eq(name, WIDGET_PROP_TOP_MARGIN)) { - value_set_int(v, mledit->top_margin); + uint32_t margin = 0; + if (widget->astyle != NULL) { + TEXT_EDIT_GET_STYLE_MARGIN(widget->astyle, margin, TOP); + } + if (margin == 0) { + margin = mledit->top_margin != 0 ? mledit->top_margin : mledit->margin; + } return RET_OK; } else if (tk_str_eq(name, WIDGET_PROP_BOTTOM_MARGIN)) { - value_set_int(v, mledit->bottom_margin); + uint32_t margin = 0; + if (widget->astyle != NULL) { + TEXT_EDIT_GET_STYLE_MARGIN(widget->astyle, margin, BOTTOM); + } + if (margin == 0) { + margin = mledit->bottom_margin != 0 ? mledit->bottom_margin : mledit->margin; + } return RET_OK; } else if (tk_str_eq(name, WIDGET_PROP_TIPS)) { value_set_str(v, mledit->tips); @@ -243,7 +269,8 @@ static ret_t mledit_get_prop(widget_t* widget, const char* name, value_t* v) { return RET_NOT_FOUND; } -static inline void mledit_reset_text_edit_layout(text_edit_t* text_edit) { +static void mledit_reset_text_edit_layout(text_edit_t* text_edit) { + text_edit_layout(text_edit); text_edit_set_offset(text_edit, 0, 0); text_edit_set_select(text_edit, 0, 0); text_edit_set_cursor(text_edit, text_edit_get_cursor(text_edit)); @@ -296,11 +323,7 @@ static ret_t mledit_set_prop(widget_t* widget, const char* name, const value_t* mledit->close_im_when_blured = value_bool(v); return RET_OK; } else if (tk_str_eq(name, WIDGET_PROP_MARGIN)) { - int margin = value_int(v); - mledit->left_margin = margin; - mledit->right_margin = margin; - mledit->top_margin = margin; - mledit->bottom_margin = margin; + mledit->margin = value_int(v); mledit_reset_text_edit_layout(mledit->model); return RET_OK; } else if (tk_str_eq(name, WIDGET_PROP_LEFT_MARGIN)) { @@ -866,10 +889,11 @@ widget_t* mledit_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h) { mledit->model = text_edit_create(widget, FALSE); ENSURE(mledit->model != NULL); - mledit->left_margin = 1; - mledit->top_margin = 1; - mledit->right_margin = 1; - mledit->bottom_margin = 1; + mledit->margin = 1; + mledit->top_margin = 0; + mledit->left_margin = 0; + mledit->right_margin = 0; + mledit->bottom_margin = 0; mledit->scroll_line = 1.0f; wstr_init(&(mledit->temp), 0); widget_set_text(widget, L""); diff --git a/src/ext_widgets/mledit/mledit.h b/src/ext_widgets/mledit/mledit.h index dc360a74a..4359541e2 100644 --- a/src/ext_widgets/mledit/mledit.h +++ b/src/ext_widgets/mledit/mledit.h @@ -59,36 +59,6 @@ BEGIN_C_DECLS typedef struct _mledit_t { widget_t widget; - /** - * @property {bool_t} readonly - * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"] - * 编辑器是否为只读。 - */ - bool_t readonly; - /** - * @property {uint8_t} top_margin - * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"] - * 上边距。 - */ - uint8_t top_margin; - /** - * @property {uint8_t} bottom_margin - * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"] - * 下边距。 - */ - uint8_t bottom_margin; - /** - * @property {uint8_t} left_margin - * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"] - * 左边距。 - */ - uint8_t left_margin; - /** - * @property {uint8_t} right_margin - * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"] - * 右边距。 - */ - uint8_t right_margin; /** * @property {char*} tips * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"] @@ -108,13 +78,6 @@ typedef struct _mledit_t { */ char* keyboard; - /** - * @property {bool_t} wrap_word - * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"] - * 是否自动折行。 - */ - bool_t wrap_word; - /** * @property {uint32_t} max_lines * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"] @@ -122,12 +85,24 @@ typedef struct _mledit_t { */ uint32_t max_lines; + /** + * @property {bool_t} wrap_word + * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"] + * 是否自动折行。 + */ + bool_t wrap_word; /** * @property {uint32_t} scroll_line * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"] * 鼠标一次滚动行数。 */ uint32_t scroll_line; + /** + * @property {bool_t} readonly + * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"] + * 编辑器是否为只读。 + */ + bool_t readonly; /** * @property {bool_t} cancelable @@ -155,6 +130,12 @@ typedef struct _mledit_t { */ bool_t close_im_when_blured; /*private*/ + uint8_t margin; + uint8_t top_margin; + uint8_t left_margin; + uint8_t right_margin; + uint8_t bottom_margin; + text_edit_t* model; uint32_t timer_id; diff --git a/src/widgets/edit.c b/src/widgets/edit.c index 433df5966..f655309f3 100644 --- a/src/widgets/edit.c +++ b/src/widgets/edit.c @@ -44,6 +44,7 @@ #define PASSWORD_MASK_CHAR '*' static ret_t edit_auto_fix(widget_t* widget); +static ret_t edit_reset_layout(widget_t* widget); static ret_t edit_update_status(widget_t* widget); static ret_t edit_pre_input(widget_t* widget, uint32_t key); static ret_t edit_select_all_async(const idle_info_t* info); @@ -702,8 +703,7 @@ ret_t edit_on_event(widget_t* widget, event_t* e) { if (edit->readonly) { if (type == EVT_RESIZE || type == EVT_MOVE_RESIZE) { - text_edit_layout(edit->model); - widget_invalidate(widget, NULL); + edit_reset_layout(widget); } return RET_OK; } @@ -825,8 +825,7 @@ ret_t edit_on_event(widget_t* widget, event_t* e) { } case EVT_RESIZE: case EVT_MOVE_RESIZE: { - text_edit_layout(edit->model); - widget_invalidate(widget, NULL); + edit_reset_layout(widget); break; } case EVT_VALUE_CHANGING: { @@ -1045,6 +1044,14 @@ static ret_t edit_apply_tr_text_before_paint(void* ctx, event_t* e) { return RET_REMOVE; } +static ret_t edit_reset_layout(widget_t* widget) { + edit_t* edit = EDIT(widget); + return_value_if_fail(edit != NULL, RET_BAD_PARAMS); + text_edit_layout(edit->model); + widget_invalidate(widget, NULL); + return RET_OK; +} + ret_t edit_set_tr_tips(widget_t* widget, const char* tr_tips) { edit_t* edit = EDIT(widget); widget_t* win = widget_get_window(widget); @@ -1130,16 +1137,44 @@ ret_t edit_get_prop(widget_t* widget, const char* name, value_t* v) { value_set_bool(v, edit->close_im_when_blured); return RET_OK; } else if (tk_str_eq(name, WIDGET_PROP_LEFT_MARGIN)) { - value_set_int(v, edit->left_margin); + uint32_t margin = 0; + if (widget->astyle != NULL) { + TEXT_EDIT_GET_STYLE_MARGIN(widget->astyle, margin, LEFT); + } + if (margin == 0) { + margin = edit->left_margin != 0 ? edit->left_margin : edit->margin; + } + value_set_int(v, margin); return RET_OK; } else if (tk_str_eq(name, WIDGET_PROP_RIGHT_MARGIN)) { - value_set_int(v, edit->right_margin); + uint32_t margin = 0; + if (widget->astyle != NULL) { + TEXT_EDIT_GET_STYLE_MARGIN(widget->astyle, margin, RIGHT); + } + if (margin == 0) { + margin = edit->right_margin != 0 ? edit->right_margin : edit->margin; + } + value_set_int(v, margin); return RET_OK; } else if (tk_str_eq(name, WIDGET_PROP_TOP_MARGIN)) { - value_set_int(v, edit->top_margin); + uint32_t margin = 0; + if (widget->astyle != NULL) { + TEXT_EDIT_GET_STYLE_MARGIN(widget->astyle, margin, TOP); + } + if (margin == 0) { + margin = edit->top_margin != 0 ? edit->top_margin : edit->margin; + } + value_set_int(v, margin); return RET_OK; } else if (tk_str_eq(name, WIDGET_PROP_BOTTOM_MARGIN)) { - value_set_int(v, edit->bottom_margin); + uint32_t margin = 0; + if (widget->astyle != NULL) { + TEXT_EDIT_GET_STYLE_MARGIN(widget->astyle, margin, BOTTOM); + } + if (margin == 0) { + margin = edit->bottom_margin != 0 ? edit->bottom_margin : edit->margin; + } + value_set_int(v, margin); return RET_OK; } else if (tk_str_eq(name, WIDGET_PROP_PASSWORD_VISIBLE)) { value_set_bool(v, edit->password_visible); @@ -1284,22 +1319,24 @@ ret_t edit_set_prop(widget_t* widget, const char* name, const value_t* v) { edit->close_im_when_blured = value_bool(v); return RET_OK; } else if (tk_str_eq(name, WIDGET_PROP_MARGIN)) { - int margin = value_int(v); - edit->left_margin = margin; - edit->right_margin = margin; - edit->top_margin = margin; - edit->bottom_margin = margin; + edit->margin = value_int(v); + edit_reset_layout(widget); + return RET_OK; } else if (tk_str_eq(name, WIDGET_PROP_LEFT_MARGIN)) { edit->left_margin = value_int(v); + edit_reset_layout(widget); return RET_OK; } else if (tk_str_eq(name, WIDGET_PROP_RIGHT_MARGIN)) { edit->right_margin = value_int(v); + edit_reset_layout(widget); return RET_OK; } else if (tk_str_eq(name, WIDGET_PROP_TOP_MARGIN)) { edit->top_margin = value_int(v); + edit_reset_layout(widget); return RET_OK; } else if (tk_str_eq(name, WIDGET_PROP_BOTTOM_MARGIN)) { edit->bottom_margin = value_int(v); + edit_reset_layout(widget); return RET_OK; } else if (tk_str_eq(name, WIDGET_PROP_PASSWORD_VISIBLE)) { edit_set_password_visible(widget, value_bool(v)); @@ -1689,10 +1726,11 @@ widget_t* edit_create_ex(widget_t* parent, const widget_vtable_t* vt, xy_t x, xy edit_t* edit = EDIT(widget); return_value_if_fail(edit != NULL, NULL); - edit->left_margin = 2; - edit->right_margin = 2; - edit->top_margin = 2; - edit->bottom_margin = 2; + edit->margin = 2; + edit->top_margin = 0; + edit->left_margin = 0; + edit->right_margin = 0; + edit->bottom_margin = 0; edit->close_im_when_blured = TRUE; edit->open_im_when_focused = TRUE; edit_set_text_limit(widget, 0, 1024); diff --git a/src/widgets/edit.h b/src/widgets/edit.h index 7e152d6ed..a9fcfe335 100644 --- a/src/widgets/edit.h +++ b/src/widgets/edit.h @@ -99,6 +99,68 @@ typedef bool_t (*edit_is_valid_char_t)(widget_t* widget, wchar_t c); typedef struct _edit_t { widget_t widget; + /** + * @property {char*} tips + * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"] + * 输入提示。 + */ + char* tips; + + /** + * @property {char*} tr_tips + * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"] + * 保存用于翻译的提示信息。 + */ + char* tr_tips; + + /** + * @property {char*} action_text + * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"] + * 软键盘上action按钮的文本。内置取值有: + * + * * next 将焦点切换到下一个控件。 + * * done 完成,关闭软键盘。 + * + * 也可以使用其它文本,比如send表示发送。这个需要自己实现相应的功能,处理EVT\_IM\_ACTION事件即可。 + * + */ + char* action_text; + + /** + * @property {char*} keyboard + * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"] + * 自定义软键盘名称。AWTK优先查找keyboard属性设置的键盘文件名(该键盘的XML文件需要在default\raw\ui目录下存在),如果keyboard为空就找input_type设置的键盘类型 + */ + char* keyboard; + + /** + * @property {double} min + * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"] + * 最小值或最小长度。 + */ + double min; + + /** + * @property {double} max + * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"] + * 最大值或最大长度。 + */ + double max; + + /** + * @property {double} step + * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"] + * 步长。 + * 作为数值型编辑器时,一次增加和减少时的数值。 + */ + double step; + + /** + * @property {input_type_t} input_type + * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"] + * 输入类型。 + */ + input_type_t input_type; /** * @property {bool_t} readonly * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"] @@ -141,93 +203,6 @@ typedef struct _edit_t { * */ bool_t close_im_when_blured; - /** - * @property {uint8_t} top_margin - * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"] - * 上边距。 - */ - uint8_t top_margin; - /** - * @property {uint8_t} bottom_margin - * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"] - * 下边距。 - */ - uint8_t bottom_margin; - /** - * @property {uint8_t} left_margin - * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"] - * 左边距。 - */ - uint8_t left_margin; - /** - * @property {uint8_t} right_margin - * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"] - * 右边距。 - */ - uint8_t right_margin; - - /** - * @property {char*} tips - * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"] - * 输入提示。 - */ - char* tips; - - /** - * @property {char*} tr_tips - * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"] - * 保存用于翻译的提示信息。 - */ - char* tr_tips; - - /** - * @property {char*} action_text - * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"] - * 软键盘上action按钮的文本。内置取值有: - * - * * next 将焦点切换到下一个控件。 - * * done 完成,关闭软键盘。 - * - * 也可以使用其它文本,比如send表示发送。这个需要自己实现相应的功能,处理EVT\_IM\_ACTION事件即可。 - * - */ - char* action_text; - - /** - * @property {char*} keyboard - * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"] - * 自定义软键盘名称。AWTK优先查找keyboard属性设置的键盘文件名(该键盘的XML文件需要在default\raw\ui目录下存在),如果keyboard为空就找input_type设置的键盘类型 - */ - char* keyboard; - - /** - * @property {input_type_t} input_type - * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"] - * 输入类型。 - */ - input_type_t input_type; - - /** - * @property {double} min - * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"] - * 最小值或最小长度。 - */ - double min; - - /** - * @property {double} max - * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"] - * 最大值或最大长度。 - */ - double max; - - /** - * @property {double} step - * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"] - * 步长。 - * 作为数值型编辑器时,一次增加和减少时的数值。 - */ - double step; /** * @property {bool_t} cancelable * @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"] @@ -239,6 +214,12 @@ typedef struct _edit_t { bool_t cancelable; /*private*/ + uint8_t margin; + uint8_t top_margin; + uint8_t bottom_margin; + uint8_t left_margin; + uint8_t right_margin; + uint32_t idle_id; uint32_t timer_id; text_edit_t* model;