mirror of
https://gitee.com/zlgopen/awtk.git
synced 2024-11-30 02:58:26 +08:00
rework label
This commit is contained in:
parent
9759614b44
commit
050e03e51f
@ -1,5 +1,8 @@
|
||||
# 最新动态
|
||||
|
||||
2021/04/28
|
||||
* 重构 label 并完善对 margin 的支持。
|
||||
|
||||
2021/04/27
|
||||
* 完善 label 对 auto adjust size 的处理。
|
||||
* 完善 line\_parser\_next,让空格在行尾。
|
||||
|
@ -4569,3 +4569,24 @@ bool_t widget_get_feedback(widget_t* widget) {
|
||||
|
||||
return widget->feedback;
|
||||
}
|
||||
|
||||
rect_t widget_get_content_area(widget_t* widget) {
|
||||
if (widget != NULL && widget->astyle != NULL) {
|
||||
style_t* style = widget->astyle;
|
||||
int32_t margin = style_get_int(style, STYLE_ID_MARGIN, 2);
|
||||
int32_t margin_top = style_get_int(style, STYLE_ID_MARGIN_TOP, margin);
|
||||
int32_t margin_left = style_get_int(style, STYLE_ID_MARGIN_LEFT, margin);
|
||||
int32_t margin_right = style_get_int(style, STYLE_ID_MARGIN_RIGHT, margin);
|
||||
int32_t margin_bottom = style_get_int(style, STYLE_ID_MARGIN_BOTTOM, margin);
|
||||
int32_t w = widget->w - margin_left - margin_right;
|
||||
int32_t h = widget->h - margin_top - margin_bottom;
|
||||
|
||||
return rect_init(margin_left, margin_top, w, h);
|
||||
} else {
|
||||
if (widget != NULL) {
|
||||
return rect_init(0, 0, widget->w, widget->h);
|
||||
} else {
|
||||
return rect_init(0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2845,6 +2845,15 @@ ret_t widget_end_wait_pointer_cursor(widget_t* widget);
|
||||
*/
|
||||
ret_t widget_set_style(widget_t* widget, const char* state_and_name, const value_t* value);
|
||||
|
||||
/**
|
||||
* @method widget_get_content_area
|
||||
* 获取widget去掉margin之外的区域。
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
*
|
||||
* @return {rect_t} 返回去掉margin之外的区域。
|
||||
*/
|
||||
rect_t widget_get_content_area(widget_t* widget);
|
||||
|
||||
/**
|
||||
* @method widget_calc_icon_text_rect
|
||||
* 计算icon text的位置。
|
||||
|
@ -28,49 +28,39 @@
|
||||
|
||||
static ret_t label_auto_adjust_size(widget_t* widget);
|
||||
|
||||
static ret_t label_paint_text_mlines(widget_t* widget, canvas_t* c, line_parser_t* p) {
|
||||
int32_t x = 0;
|
||||
int32_t y = 0;
|
||||
int32_t w = 0;
|
||||
int32_t h_text = 0;
|
||||
static ret_t label_paint_text_mlines(widget_t* widget, canvas_t* c, line_parser_t* p, int32_t x,
|
||||
int32_t y, int32_t w, int32_t h) {
|
||||
int32_t top = y;
|
||||
int32_t bottom = y + h;
|
||||
style_t* style = widget->astyle;
|
||||
int32_t font_size = c->font_size;
|
||||
int32_t margin = style_get_int(style, STYLE_ID_MARGIN, 2);
|
||||
int32_t spacer = style_get_int(style, STYLE_ID_SPACER, 2);
|
||||
int32_t line_height = font_size + style_get_int(style, STYLE_ID_SPACER, 2);
|
||||
align_v_t align_v = (align_v_t)style_get_int(style, STYLE_ID_TEXT_ALIGN_V, ALIGN_V_MIDDLE);
|
||||
align_h_t align_h = (align_h_t)style_get_int(style, STYLE_ID_TEXT_ALIGN_H, ALIGN_H_CENTER);
|
||||
int32_t line_height = font_size + spacer;
|
||||
|
||||
x = margin;
|
||||
y = margin;
|
||||
w = widget->w - margin - margin;
|
||||
h_text = p->total_lines * line_height;
|
||||
int32_t h_text = p->total_lines * line_height;
|
||||
|
||||
switch (align_v) {
|
||||
case ALIGN_V_TOP: {
|
||||
y = margin;
|
||||
break;
|
||||
}
|
||||
case ALIGN_V_BOTTOM: {
|
||||
y = widget->h - margin - h_text;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
case ALIGN_V_MIDDLE: {
|
||||
y = (widget->h - h_text) / 2;
|
||||
break;
|
||||
}
|
||||
case ALIGN_V_BOTTOM: {
|
||||
y = y + h - h_text;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (y < margin) {
|
||||
y = margin;
|
||||
}
|
||||
|
||||
y = tk_max(y, top);
|
||||
canvas_set_text_align(c, align_h, align_v);
|
||||
|
||||
while (line_parser_next(p) == RET_OK) {
|
||||
uint32_t size = 0;
|
||||
rect_t r = rect_init(x, y, w, font_size);
|
||||
|
||||
if ((y + font_size) > widget->h) {
|
||||
if ((y + font_size) > bottom) {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -79,6 +69,7 @@ static ret_t label_paint_text_mlines(widget_t* widget, canvas_t* c, line_parser_
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
canvas_draw_text_in_rect(c, p->line, size, &r);
|
||||
|
||||
y += line_height;
|
||||
@ -90,16 +81,15 @@ static ret_t label_paint_text_mlines(widget_t* widget, canvas_t* c, line_parser_
|
||||
static ret_t label_paint_text(widget_t* widget, canvas_t* c, const wchar_t* str, uint32_t size) {
|
||||
line_parser_t p;
|
||||
label_t* label = LABEL(widget);
|
||||
style_t* style = widget->astyle;
|
||||
int32_t margin = style_get_int(style, STYLE_ID_MARGIN, 2);
|
||||
int32_t w = widget->w - margin - margin;
|
||||
rect_t r = widget_get_content_area(widget);
|
||||
|
||||
return_value_if_fail(line_parser_init(&p, c, widget->text.str, widget->text.size, c->font_size, w,
|
||||
label->line_wrap, label->word_wrap) == RET_OK,
|
||||
return_value_if_fail((r.w > 0 && r.h > c->font_size), RET_FAIL);
|
||||
return_value_if_fail(line_parser_init(&p, c, widget->text.str, widget->text.size, c->font_size,
|
||||
r.w, label->line_wrap, label->word_wrap) == RET_OK,
|
||||
RET_BAD_PARAMS);
|
||||
|
||||
if (p.total_lines > 1) {
|
||||
return label_paint_text_mlines(widget, c, &p);
|
||||
return label_paint_text_mlines(widget, c, &p, r.x, r.y, r.w, r.h);
|
||||
} else {
|
||||
wstr_t str = widget->text;
|
||||
str.size = size;
|
||||
@ -152,51 +142,6 @@ static wh_t label_get_text_line_max_w(widget_t* widget, canvas_t* c) {
|
||||
return line_max_w;
|
||||
}
|
||||
|
||||
ret_t label_resize_to_content(widget_t* widget, uint32_t min_w, uint32_t max_w, uint32_t min_h,
|
||||
uint32_t max_h) {
|
||||
wh_t w = 0;
|
||||
wh_t h = 0;
|
||||
wh_t tmp_w = 0;
|
||||
int32_t margin = 0;
|
||||
int32_t spacer = 0;
|
||||
int32_t line_height = 0;
|
||||
style_t* style = NULL;
|
||||
line_parser_t p;
|
||||
label_t* label = LABEL(widget);
|
||||
canvas_t* c = widget_get_canvas(widget);
|
||||
return_value_if_fail(label != NULL, RET_BAD_PARAMS);
|
||||
|
||||
style = widget->astyle;
|
||||
margin = style_get_int(style, STYLE_ID_MARGIN, 2);
|
||||
spacer = style_get_int(style, STYLE_ID_SPACER, 2);
|
||||
|
||||
widget_prepare_text_style(widget, c);
|
||||
line_height = c->font_size + spacer;
|
||||
w = label_get_text_line_max_w(widget, c);
|
||||
|
||||
w = tk_clampi(w, min_w, max_w);
|
||||
if (w >= max_w) {
|
||||
tmp_w = max_w - 2 * margin;
|
||||
} else {
|
||||
tmp_w = w;
|
||||
w = w + 2 * margin;
|
||||
if (w >= max_w) {
|
||||
w = max_w;
|
||||
tmp_w = max_w - 2 * margin;
|
||||
}
|
||||
}
|
||||
return_value_if_fail(line_parser_init(&p, c, widget->text.str, widget->text.size, c->font_size,
|
||||
tmp_w, label->line_wrap, label->word_wrap) == RET_OK,
|
||||
RET_BAD_PARAMS);
|
||||
|
||||
h = p.total_lines * line_height + 2 * margin;
|
||||
h = tk_clampi(h, min_h, max_h);
|
||||
|
||||
widget_resize(widget, w, h);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
ret_t label_set_length(widget_t* widget, int32_t length) {
|
||||
label_t* label = LABEL(widget);
|
||||
return_value_if_fail(label != NULL, RET_BAD_PARAMS);
|
||||
@ -277,32 +222,72 @@ static ret_t label_set_prop(widget_t* widget, const char* name, const value_t* v
|
||||
return RET_NOT_FOUND;
|
||||
}
|
||||
|
||||
static ret_t label_auto_adjust_size(widget_t* widget) {
|
||||
static ret_t label_auto_adjust_size_impl(widget_t* widget, canvas_t* c, uint32_t min_w,
|
||||
uint32_t max_w, uint32_t min_h, uint32_t max_h) {
|
||||
wh_t w = 0;
|
||||
wh_t max_line_w = 0;
|
||||
int32_t max_w = 0;
|
||||
int32_t margin = 0;
|
||||
int32_t spacer = 0;
|
||||
int32_t line_height = 0;
|
||||
style_t* style = NULL;
|
||||
line_parser_t p;
|
||||
wh_t max_line_w = 0;
|
||||
int32_t line_height = 0;
|
||||
label_t* label = LABEL(widget);
|
||||
canvas_t* c = widget_get_canvas(widget);
|
||||
return_value_if_fail(label != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(c != NULL && widget->astyle != NULL, RET_BAD_PARAMS);
|
||||
style_t* style = widget->astyle;
|
||||
int32_t margin = style_get_int(style, STYLE_ID_MARGIN, 2);
|
||||
int32_t margin_top = style_get_int(style, STYLE_ID_MARGIN_TOP, margin);
|
||||
int32_t margin_left = style_get_int(style, STYLE_ID_MARGIN_LEFT, margin);
|
||||
int32_t margin_right = style_get_int(style, STYLE_ID_MARGIN_RIGHT, margin);
|
||||
int32_t margin_bottom = style_get_int(style, STYLE_ID_MARGIN_BOTTOM, margin);
|
||||
int32_t spacer = style_get_int(style, STYLE_ID_SPACER, 2);
|
||||
|
||||
if (!widget_is_window_created(widget)) {
|
||||
widget_prepare_text_style(widget, c);
|
||||
line_height = c->font_size + spacer;
|
||||
if (widget->text.size == 0) {
|
||||
widget->h = line_height;
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
style = widget->astyle;
|
||||
margin = style_get_int(style, STYLE_ID_MARGIN, 2);
|
||||
spacer = style_get_int(style, STYLE_ID_SPACER, 2);
|
||||
widget_prepare_text_style(widget, c);
|
||||
line_height = c->font_size + spacer;
|
||||
max_line_w = label_get_text_line_max_w(widget, c);
|
||||
if (label->line_wrap) {
|
||||
w = widget->w - margin_left - margin_right;
|
||||
if (max_w != 0) {
|
||||
w = max_line_w;
|
||||
}
|
||||
} else {
|
||||
w = max_line_w;
|
||||
}
|
||||
|
||||
if (widget->text.size == 0) {
|
||||
widget->h = line_height;
|
||||
if (max_w != 0) {
|
||||
if (w > max_w) {
|
||||
w = max_w - margin_left - margin_right;
|
||||
}
|
||||
}
|
||||
return_value_if_fail(w > 0, RET_BAD_PARAMS);
|
||||
|
||||
return_value_if_fail(line_parser_init(&p, c, widget->text.str, widget->text.size, c->font_size, w,
|
||||
label->line_wrap, label->word_wrap) == RET_OK,
|
||||
RET_BAD_PARAMS);
|
||||
|
||||
widget->w = w + margin_left + margin_right;
|
||||
widget->h = line_height * p.total_lines + margin_top + margin_bottom;
|
||||
|
||||
widget->w = tk_max(widget->w, min_w);
|
||||
widget->h = tk_max(widget->h, min_h);
|
||||
if (max_w > 0) {
|
||||
widget->w = tk_min(widget->w, max_w);
|
||||
}
|
||||
|
||||
if (max_h > 0) {
|
||||
widget->h = tk_min(widget->h, max_h);
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t label_auto_adjust_size(widget_t* widget) {
|
||||
int32_t max_w = 0;
|
||||
label_t* label = LABEL(widget);
|
||||
canvas_t* c = widget_get_canvas(widget);
|
||||
return_value_if_fail(c != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(label != NULL && widget->astyle != NULL, RET_BAD_PARAMS);
|
||||
if (!widget->auto_adjust_size || !widget_is_window_created(widget)) {
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
@ -310,31 +295,16 @@ static ret_t label_auto_adjust_size(widget_t* widget) {
|
||||
max_w = label->max_w > 0 ? label->max_w : (widget->parent->w + label->max_w);
|
||||
}
|
||||
|
||||
max_line_w = label_get_text_line_max_w(widget, c);
|
||||
if (label->line_wrap) {
|
||||
w = widget->w;
|
||||
if (max_w != 0) {
|
||||
w = max_line_w + 2 * margin;
|
||||
}
|
||||
} else {
|
||||
w = max_line_w + 2 * margin;
|
||||
}
|
||||
return label_auto_adjust_size_impl(widget, c, 0, max_w, 0, 0xffff);
|
||||
}
|
||||
|
||||
if (max_w != 0) {
|
||||
if (w > max_w) {
|
||||
w = max_w;
|
||||
}
|
||||
}
|
||||
ret_t label_resize_to_content(widget_t* widget, uint32_t min_w, uint32_t max_w, uint32_t min_h,
|
||||
uint32_t max_h) {
|
||||
label_t* label = LABEL(widget);
|
||||
canvas_t* c = widget_get_canvas(widget);
|
||||
return_value_if_fail(label != NULL && c != NULL && widget->astyle != NULL, RET_BAD_PARAMS);
|
||||
|
||||
return_value_if_fail(
|
||||
line_parser_init(&p, c, widget->text.str, widget->text.size, c->font_size, w - 2 * margin,
|
||||
label->line_wrap, label->word_wrap) == RET_OK,
|
||||
RET_BAD_PARAMS);
|
||||
|
||||
widget->w = w;
|
||||
widget->h = line_height * p.total_lines + 2 * margin;
|
||||
|
||||
return RET_OK;
|
||||
return label_auto_adjust_size_impl(widget, c, min_w, max_w, min_h, max_h);
|
||||
}
|
||||
|
||||
static ret_t label_on_event(widget_t* widget, event_t* e) {
|
||||
@ -345,18 +315,13 @@ static ret_t label_on_event(widget_t* widget, event_t* e) {
|
||||
switch (type) {
|
||||
case EVT_RESIZE:
|
||||
case EVT_MOVE_RESIZE: {
|
||||
if (widget->auto_adjust_size) {
|
||||
label_auto_adjust_size(widget);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EVT_WINDOW_WILL_OPEN: {
|
||||
if (widget->auto_adjust_size) {
|
||||
label_auto_adjust_size(widget);
|
||||
break;
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -365,7 +330,7 @@ static ret_t label_on_event(widget_t* widget, event_t* e) {
|
||||
}
|
||||
|
||||
static const char* const s_label_properties[] = {WIDGET_PROP_LENGTH, WIDGET_PROP_LINE_WRAP,
|
||||
WIDGET_PROP_WORD_WRAP, NULL};
|
||||
WIDGET_PROP_MAX_W, WIDGET_PROP_WORD_WRAP, NULL};
|
||||
|
||||
TK_DECL_VTABLE(label) = {.size = sizeof(label_t),
|
||||
.type = WIDGET_TYPE_LABEL,
|
||||
@ -383,6 +348,7 @@ widget_t* label_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h) {
|
||||
label_t* label = LABEL(widget);
|
||||
return_value_if_fail(label != NULL, NULL);
|
||||
|
||||
label->max_w = 0;
|
||||
label->length = -1;
|
||||
label->line_wrap = FALSE;
|
||||
label->word_wrap = FALSE;
|
||||
|
@ -87,14 +87,15 @@ typedef struct _label_t {
|
||||
/**
|
||||
* @property {bool_t} line_wrap
|
||||
* @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"]
|
||||
* 是否自动换行。
|
||||
* 是否自动换行(默认FALSE)。
|
||||
*/
|
||||
bool_t line_wrap;
|
||||
|
||||
/**
|
||||
* @property {bool_t} word_wrap
|
||||
* @annotation ["set_prop","get_prop","readable","persitent","design","scriptable"]
|
||||
* 是否允许整个单词换行。(需要开启自动换行才有效果)
|
||||
* 是否允许整个单词换行(默认FALSE)。
|
||||
* > 需要开启自动换行才有效果
|
||||
*/
|
||||
bool_t word_wrap;
|
||||
|
||||
@ -123,7 +124,7 @@ widget_t* label_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h);
|
||||
|
||||
/**
|
||||
* @method label_set_length
|
||||
* 设置显示字符的个数(小余0时全部显示)。。
|
||||
* 设置显示字符的个数(小余0时全部显示)。
|
||||
* @annotation ["scriptable"]
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
* @param {int32_t} length 最大可显示字符个数。
|
||||
|
Loading…
Reference in New Issue
Block a user