diff --git a/src/lv_core/lv_obj_draw.h b/src/lv_core/lv_obj_draw.h index d7ec13f509..bf67fbcd82 100644 --- a/src/lv_core/lv_obj_draw.h +++ b/src/lv_core/lv_obj_draw.h @@ -41,6 +41,7 @@ typedef struct lv_draw_line_dsc_t * line_dsc; lv_draw_img_dsc_t * img_dsc; lv_draw_arc_dsc_t * arc_dsc; + char text[16]; const lv_area_t * draw_area; const lv_point_t * p1; const lv_point_t * p2; diff --git a/src/lv_draw/lv_draw_arc.c b/src/lv_draw/lv_draw_arc.c index 5626038e80..c5d105eeaf 100644 --- a/src/lv_draw/lv_draw_arc.c +++ b/src/lv_draw/lv_draw_arc.c @@ -88,10 +88,15 @@ void lv_draw_arc(lv_coord_t center_x, lv_coord_t center_y, uint16_t radius, uin lv_draw_rect_dsc_t cir_dsc; lv_draw_rect_dsc_init(&cir_dsc); - cir_dsc.bg_opa = dsc->opa; - cir_dsc.bg_color = dsc->color; cir_dsc.blend_mode = dsc->blend_mode; - cir_dsc.bg_img_src = dsc->bg_img_src; + if(dsc->bg_img_src) { + cir_dsc.bg_opa = LV_OPA_TRANSP; + cir_dsc.bg_img_src = dsc->bg_img_src; + cir_dsc.bg_img_opa = dsc->opa; + } else { + cir_dsc.bg_opa = dsc->opa; + cir_dsc.bg_color = dsc->color; + } lv_area_t area_out; area_out.x1 = center_x - radius; diff --git a/src/lv_themes/lv_theme_default.c b/src/lv_themes/lv_theme_default.c index 7f29ccf770..4e769bf129 100644 --- a/src/lv_themes/lv_theme_default.c +++ b/src/lv_themes/lv_theme_default.c @@ -211,7 +211,6 @@ static void basic_init(void) lv_style_set_bg_opa(&styles->scr, LV_OPA_COVER); lv_style_set_bg_color(&styles->scr, COLOR_SCR); lv_style_set_text_color(&styles->scr, COLOR_SCR_TEXT); - lv_style_set_pad_all(&styles->scr, PAD_DEF); lv_style_set_pad_row(&styles->scr, PAD_DEF); lv_style_set_pad_column(&styles->scr, PAD_DEF); @@ -352,15 +351,14 @@ static void basic_init(void) style_init_reset(&styles->chart_series); lv_style_set_line_width(&styles->chart_series, LV_DPX(3)); lv_style_set_radius(&styles->chart_series, LV_DPX(1)); + lv_style_set_size(&styles->chart_series, LV_DPX(5)); style_init_reset(&styles->chart_ticks); lv_style_set_line_width(&styles->chart_ticks, LV_DPX(1)); lv_style_set_line_color(&styles->chart_ticks, COLOR_GRAY); - #endif - #if LV_USE_METER style_init_reset(&styles->meter_marker); lv_style_set_line_width(&styles->meter_marker, LV_DPX(5)); @@ -381,41 +379,20 @@ static void basic_init(void) lv_style_set_border_width(&styles->table_cell, LV_DPX(1)); lv_style_set_border_color(&styles->table_cell, CARD_BORDER_COLOR); #endif -} -// -//static void linemeter_init(void) -//{ -//#if LV_USE_LINEMETER != 0 -// style_init_reset(&styles->lmeter); -// lv_style_set_radius(&styles->lmeter, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE); -// lv_style_set_pad_left(&styles->lmeter, LV_STATE_DEFAULT, LV_DPX(20)); -// lv_style_set_pad_right(&styles->lmeter, LV_STATE_DEFAULT, LV_DPX(20)); -// lv_style_set_pad_top(&styles->lmeter, LV_STATE_DEFAULT, LV_DPX(20)); -// lv_style_set_scale_width(&styles->lmeter, LV_STATE_DEFAULT, LV_DPX(25)); -// -// lv_style_set_line_color(&styles->lmeter, LV_STATE_DEFAULT, theme.color_primary); -// lv_style_set_scale_grad_color(&styles->lmeter, LV_STATE_DEFAULT, theme.color_primary); -// lv_style_set_scale_end_color(&styles->lmeter, LV_STATE_DEFAULT, lv_color_hex3(0x888)); -// lv_style_set_line_width(&styles->lmeter, LV_STATE_DEFAULT, LV_DPX(10)); -// lv_style_set_scale_end_line_width(&styles->lmeter, LV_STATE_DEFAULT, LV_DPX(7)); -//#endif -//} -// -static void textarea_init(void) -{ #if LV_USE_TEXTAREA style_init_reset(&styles->ta_cursor); - lv_style_set_border_color(&styles->ta_cursor, LV_STATE_DEFAULT, COLOR_BG_SEC_TEXT); - lv_style_set_border_width(&styles->ta_cursor, LV_STATE_DEFAULT, LV_DPX(2)); - lv_style_set_pad_left(&styles->ta_cursor, LV_STATE_DEFAULT, LV_DPX(1)); - lv_style_set_border_side(&styles->ta_cursor, LV_STATE_DEFAULT, LV_BORDER_SIDE_LEFT); + lv_style_set_border_color(&styles->ta_cursor, COLOR_BG_SEC_TEXT); + lv_style_set_border_width(&styles->ta_cursor, LV_DPX(2)); + lv_style_set_pad_left(&styles->ta_cursor, LV_DPX(1)); + lv_style_set_border_side(&styles->ta_cursor, LV_BORDER_SIDE_LEFT); + lv_style_set_anim_time(&styles->ta_cursor, 400); style_init_reset(&styles->ta_placeholder); - lv_style_set_text_color(&styles->ta_placeholder, LV_STATE_DEFAULT, - IS_LIGHT ? COLOR_BG_TEXT_DIS : lv_color_hex(0xa1adbd)); + lv_style_set_text_color(&styles->ta_placeholder, IS_LIGHT ? COLOR_BG_TEXT_DIS : lv_color_hex(0xa1adbd)); #endif } + // //static void ddlist_init(void) //{ @@ -486,7 +463,6 @@ lv_theme_t * lv_theme_default_init(lv_color_t color_primary, lv_color_t color_se theme.flags = flags; basic_init(); - textarea_init(); theme.apply_cb = theme_apply; @@ -646,25 +622,16 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj) else if(lv_obj_check_type(obj, &lv_meter)) { lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card); lv_obj_add_style_no_refresh(obj, LV_PART_MARKER, LV_STATE_DEFAULT, &styles->meter_marker); - lv_obj_add_style_no_refresh(obj, LV_PART_INDICATOR, LV_STATE_DEFAULT, &styles->meter_indic); } #endif - #if LV_USE_TEXTAREA -case LV_THEME_TEXTAREA: - list = _lv_obj_get_style_list(obj, LV_TEXTAREA_PART_MAIN); - _lv_style_list_add_style(list, &styles->card); - _lv_style_list_add_style(list, &styles->pad_small); - _lv_style_list_add_style(list, &styles->sb); - - list = _lv_obj_get_style_list(obj, LV_TEXTAREA_PART_PLACEHOLDER); - _lv_style_list_add_style(list, &styles->ta_placeholder); - - list = _lv_obj_get_style_list(obj, LV_TEXTAREA_PART_CURSOR); - _lv_style_list_add_style(list, &styles->ta_cursor); - break; - + else if(lv_obj_check_type(obj, &lv_textarea)) { + lv_obj_add_style_no_refresh(obj, LV_PART_MAIN, LV_STATE_DEFAULT, &styles->card); + lv_obj_add_style_no_refresh(obj, LV_PART_SCROLLBAR, LV_STATE_DEFAULT, &styles->scrollbar); + lv_obj_add_style_no_refresh(obj, LV_PART_SCROLLBAR, LV_STATE_SCROLLED, &styles->scrollbar_scrolled); + lv_obj_add_style_no_refresh(obj, LV_PART_MARKER, LV_STATE_DEFAULT, &styles->ta_cursor); + } #endif //#if LV_USE_LINEMETER diff --git a/src/lv_widgets/lv_chart.c b/src/lv_widgets/lv_chart.c index 1b90dd73b2..54bd38a60e 100644 --- a/src/lv_widgets/lv_chart.c +++ b/src/lv_widgets/lv_chart.c @@ -13,6 +13,7 @@ #include "../lv_core/lv_refr.h" #include "../lv_draw/lv_draw.h" #include "../lv_core/lv_disp.h" +#include "../lv_core/lv_indev.h" #include "../lv_misc/lv_math.h" #include "../lv_themes/lv_theme.h" @@ -1203,7 +1204,7 @@ static void draw_cursors(lv_obj_t * obj, const lv_area_t * clip_area) } -static void draw_y_ticks(lv_obj_t * obj, const lv_area_t * mask, lv_chart_axis_t axis) +static void draw_y_ticks(lv_obj_t * obj, const lv_area_t * clip_area, lv_chart_axis_t axis) { lv_chart_t * chart = (lv_chart_t *)obj; @@ -1216,7 +1217,6 @@ static void draw_y_ticks(lv_obj_t * obj, const lv_area_t * mask, lv_chart_axis_t lv_coord_t x_ofs; lv_coord_t y_ofs = obj->coords.y1; lv_coord_t h = (lv_obj_get_height(obj) * chart->y_zoom) >> 8; - char buf[LV_CHART_AXIS_TICK_LABEL_MAX_LEN + 1]; /* up to N symbols per label + null terminator */ /* chose correct side of the chart */ lv_coord_t major_tick_len; @@ -1237,6 +1237,11 @@ static void draw_y_ticks(lv_obj_t * obj, const lv_area_t * mask, lv_chart_axis_t minor_tick_len *= -1; } + lv_obj_draw_hook_dsc_t hook_dsc; + lv_obj_draw_hook_dsc_init(&hook_dsc, clip_area); + hook_dsc.id = axis; + hook_dsc.part = LV_PART_MARKER; + lv_draw_line_dsc_t line_dsc; lv_draw_line_dsc_init(&line_dsc); lv_obj_init_draw_line_dsc(obj, LV_PART_MARKER, &line_dsc); @@ -1252,8 +1257,8 @@ static void draw_y_ticks(lv_obj_t * obj, const lv_area_t * mask, lv_chart_axis_t /* draw a line at moving y position */ p2.y = p1.y = y_ofs + (int32_t)((int32_t)(h - line_dsc.width) * i) / total_tick_num; - if(p2.y - label_dsc.font->line_height > mask->y2) return; - if(p2.y + label_dsc.font->line_height < mask->y1) continue; + if(p2.y - label_dsc.font->line_height > clip_area->y2) return; + if(p2.y + label_dsc.font->line_height < clip_area->y1) continue; /* first point of the tick */ p1.x = x_ofs; @@ -1269,15 +1274,18 @@ static void draw_y_ticks(lv_obj_t * obj, const lv_area_t * mask, lv_chart_axis_t if(major) p2.x = p1.x - major_tick_len; /* major tick */ else p2.x = p1.x - minor_tick_len; /* minor tick */ - lv_draw_line(&p1, &p2, mask, &line_dsc); + lv_draw_line(&p1, &p2, clip_area, &line_dsc); /* add text only to major tick */ if(!major) continue; - chart->tick_label_cb(obj, axis, i / sub_tick_cnt, buf, sizeof(buf)); + + int32_t tick_value = chart->ymax[axis] - lv_map(i, 0, total_tick_num, chart->ymin[axis], chart->ymax[axis]); + lv_snprintf(hook_dsc.text, sizeof(hook_dsc.text), "%d", tick_value); + lv_event_send(obj, LV_EVENT_DRAW_PART_BEGIN, &hook_dsc); /* reserve appropriate area */ lv_point_t size; - _lv_txt_get_size(&size, buf, label_dsc.font, label_dsc.letter_space, label_dsc.line_space, + _lv_txt_get_size(&size, hook_dsc.text, label_dsc.font, label_dsc.letter_space, label_dsc.line_space, LV_COORD_MAX, LV_TEXT_FLAG_CENTER); /* set the area at some distance of the major tick len left of the tick */ @@ -1294,16 +1302,16 @@ static void draw_y_ticks(lv_obj_t * obj, const lv_area_t * mask, lv_chart_axis_t a.x2 = p2.x + size.x + label_gap; } - lv_draw_label(&a, mask, &label_dsc, buf, NULL); + lv_draw_label(&a, clip_area, &label_dsc, hook_dsc.text, NULL); } } -static void draw_x_ticks(lv_obj_t * obj, const lv_area_t * mask) +static void draw_x_ticks(lv_obj_t * obj, const lv_area_t * clip_area) { lv_chart_t * chart = (lv_chart_t *)obj; lv_area_t series_mask; - bool mask_ret = _lv_area_intersect(&series_mask, &obj->coords, mask); + bool mask_ret = _lv_area_intersect(&series_mask, &obj->coords, clip_area); if(mask_ret == false) return; uint32_t i; @@ -1324,8 +1332,8 @@ static void draw_x_ticks(lv_obj_t * obj, const lv_area_t * mask) lv_coord_t minor_tick_len = major_tick_len / 2; lv_coord_t label_gap = TICK_LABEL_GAP; - if(h + y_ofs > mask->y2) return; - if(h + y_ofs + label_gap + label_dsc.font->line_height + major_tick_len < mask->y1) return; + if(h + y_ofs > clip_area->y2) return; + if(h + y_ofs + label_gap + label_dsc.font->line_height + major_tick_len < clip_area->y1) return; lv_draw_line_dsc_t line_dsc; lv_draw_line_dsc_init(&line_dsc); @@ -1333,6 +1341,12 @@ static void draw_x_ticks(lv_obj_t * obj, const lv_area_t * mask) line_dsc.dash_gap = 0; line_dsc.dash_width = 0; + lv_obj_draw_hook_dsc_t hook_dsc; + lv_obj_draw_hook_dsc_init(&hook_dsc, clip_area); + hook_dsc.id = LV_CHART_AXIS_X; + hook_dsc.part = LV_PART_MARKER; + + /* The columns don't start at the most right position * so change the width and offset accordingly. */ if(chart->type == LV_CHART_TYPE_COLUMN) { @@ -1343,7 +1357,6 @@ static void draw_x_ticks(lv_obj_t * obj, const lv_area_t * mask) } p1.y = h + y_ofs; - char buf[LV_CHART_AXIS_TICK_LABEL_MAX_LEN + 1]; /* up to N symbols per label + null terminator */ uint32_t total_tick_num = major_tick_cnt * sub_tick_cnt; for(i = 0; i <= total_tick_num; i++) { /* one extra loop - it may not exist in the list, empty label */ bool major = false; @@ -1354,15 +1367,17 @@ static void draw_x_ticks(lv_obj_t * obj, const lv_area_t * mask) if(p1.x > series_mask.x2) return; p2.y = p1.y + (major ? major_tick_len : minor_tick_len); - lv_draw_line(&p1, &p2, mask, &line_dsc); + lv_draw_line(&p1, &p2, clip_area, &line_dsc); /* add text only to major tick */ if(!major) continue; - chart->tick_label_cb(obj, LV_CHART_AXIS_X, i / sub_tick_cnt, buf, sizeof(buf)); + + lv_snprintf(hook_dsc.text, sizeof(hook_dsc.text), "%d", i / sub_tick_cnt); + lv_event_send(obj, LV_EVENT_DRAW_PART_BEGIN, &hook_dsc.text); /* reserve appropriate area */ lv_point_t size; - _lv_txt_get_size(&size, buf, label_dsc.font, label_dsc.letter_space, label_dsc.line_space, + _lv_txt_get_size(&size, hook_dsc.text, label_dsc.font, label_dsc.letter_space, label_dsc.line_space, LV_COORD_MAX, LV_TEXT_FLAG_CENTER); /* set the area at some distance of the major tick len under of the tick */ @@ -1371,7 +1386,7 @@ static void draw_x_ticks(lv_obj_t * obj, const lv_area_t * mask) a.x2 = (p2.x + size.x / 2), a.y1 = p2.y + label_gap; a.y2 = (a.y1 + size.y); - lv_draw_label(&a, mask, &label_dsc, buf, NULL); + lv_draw_label(&a, clip_area, &label_dsc, hook_dsc.text, NULL); } } diff --git a/src/lv_widgets/lv_dropdown.c b/src/lv_widgets/lv_dropdown.c index 26350ef9e1..c927ff48f2 100644 --- a/src/lv_widgets/lv_dropdown.c +++ b/src/lv_widgets/lv_dropdown.c @@ -503,10 +503,11 @@ void lv_dropdown_open(lv_obj_t * dropdown_obj) { lv_dropdown_t * dropdown = (lv_dropdown_t *) dropdown_obj; + lv_obj_add_state(dropdown_obj, LV_STATE_CHECKED); + lv_obj_clear_flag(dropdown->list, LV_OBJ_FLAG_HIDDEN); lv_obj_clear_flag(dropdown->list, LV_OBJ_FLAG_CLICK_FOCUSABLE); lv_obj_set_parent(dropdown->list, lv_obj_get_screen(dropdown_obj)); - /*Set smaller width to the width of the button*/ if(lv_obj_get_width(dropdown->list) <= lv_obj_get_width(dropdown_obj) && (dropdown->dir == LV_DIR_TOP || dropdown->dir == LV_DIR_BOTTOM)) { @@ -594,6 +595,7 @@ void lv_dropdown_open(lv_obj_t * dropdown_obj) */ void lv_dropdown_close(lv_obj_t * obj) { + lv_obj_clear_state(obj, LV_STATE_CHECKED); lv_dropdown_t * dropdown = (lv_dropdown_t *) obj; dropdown->pr_opt_id = LV_DROPDOWN_PR_NONE; @@ -641,7 +643,6 @@ static void lv_dropdown_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_ ((lv_dropdown_list_t*)list_obj)->dropdown = (lv_obj_t *) dropdown; dropdown->list = list_obj; lv_obj_add_flag(dropdown->list, LV_OBJ_FLAG_HIDDEN); - lv_obj_add_flag(obj, LV_OBJ_FLAG_CHECKABLE); if(copy == NULL) { lv_obj_set_width(obj, LV_DPX(150)); @@ -751,6 +752,7 @@ static lv_draw_res_t lv_dropdown_draw(lv_obj_t * obj, const lv_area_t * clip_are symbol_area.x1 = obj->coords.x2 - right - symbol_w; symbol_area.x2 = symbol_area.x1 + symbol_w - 1; } + if(symbol_type == LV_IMG_SRC_SYMBOL) { lv_draw_label(&symbol_area, clip_area, &label_dsc, dropdown->symbol, NULL); } else { @@ -762,47 +764,31 @@ static lv_draw_res_t lv_dropdown_draw(lv_obj_t * obj, const lv_area_t * clip_are img_dsc.angle = lv_obj_get_style_transform_angle(obj, LV_PART_MAIN); lv_draw_img(&symbol_area, clip_area, dropdown->symbol, &img_dsc); } - } -// txt = rev ? dropdown->symbol : opt_txt; -// if(txt) { -// _lv_txt_get_size(&txt_size, txt, label_dsc.font, label_dsc.letter_space, label_dsc.line_space, LV_COORD_MAX, -// label_dsc.flag); -// -// txt_area.y1 = obj->coords.y1 + top; -// txt_area.y2 = txt_area.y1 + txt_size.y; -// -// /*Center align the text if no symbol*/ -// if(dropdown->symbol == NULL && txt == opt_txt) { -// txt_area.x1 = obj->coords.x1 + (lv_obj_get_width(obj) - txt_size.x) / 2; -// txt_area.x2 = txt_area.x1 + txt_size.x; -// } -// else { -// txt_area.x1 = obj->coords.x1 + left; -// txt_area.x2 = txt_area.x1 + txt_size.x; -// } -// lv_draw_label(&txt_area, clip_area, &label_dsc, txt, NULL); -// } -// -// txt = rev ? opt_txt : dropdown->symbol; -// if(txt) { -// _lv_txt_get_size(&txt_size, txt, label_dsc.font, label_dsc.letter_space, label_dsc.line_space, LV_COORD_MAX, -// label_dsc.flag); -// txt_area.y1 = obj->coords.y1 + top; -// txt_area.y2 = txt_area.y1 + txt_size.y; -// -// /*Center align the text if no symbol*/ -// if(dropdown->symbol == NULL && txt == opt_txt) { -// txt_area.x1 = obj->coords.x1 + (lv_obj_get_width(obj) - txt_size.x) / 2; -// txt_area.x2 = txt_area.x1 + txt_size.x; -// } -// else { -// txt_area.x1 = obj->coords.x2 - right - txt_size.x; -// txt_area.x2 = txt_area.x1 + txt_size.x; -// } -// -// lv_draw_label(&txt_area, clip_area, &label_dsc, txt, NULL); -// } + lv_point_t size; + _lv_txt_get_size(&size, opt_txt, label_dsc.font, label_dsc.letter_space, label_dsc.line_space, LV_COORD_MAX, + label_dsc.flag); + + lv_area_t txt_area; + txt_area.y1 = obj->coords.y1 + top; + txt_area.y2 = txt_area.y1 + size.y; + /*Center align the text if no symbol*/ + if(dropdown->symbol == NULL) { + txt_area.x1 = obj->coords.x1 + (lv_obj_get_width(obj) - size.x) / 2; + txt_area.x2 = txt_area.x1 + size.x; + } + else { + /*Text to the right*/ + if(symbol_to_left) { + txt_area.x1 = obj->coords.x2 - right - size.x; + txt_area.x2 = txt_area.x1 + size.x; + } else { + txt_area.x1 = obj->coords.x1 + left; + txt_area.x2 = txt_area.x1 + size.x; + } + } + lv_draw_label(&txt_area, clip_area, &label_dsc, opt_txt, NULL); + } if(dropdown->text == NULL) { lv_mem_buf_release((char *)opt_txt); diff --git a/src/lv_widgets/lv_label.h b/src/lv_widgets/lv_label.h index fd98a3f28c..acb82e0ebb 100644 --- a/src/lv_widgets/lv_label.h +++ b/src/lv_widgets/lv_label.h @@ -164,13 +164,6 @@ char * lv_label_get_text(const lv_obj_t * label); */ lv_label_long_mode_t lv_label_get_long_mode(const lv_obj_t * label); -/** - * Get the align attribute - * @param label pointer to a label object - * @return LV_TEXT_ALIGN_LEFT or LV_TEXT_ALIGN_CENTER - */ -lv_text_align_t lv_label_get_align(const lv_obj_t * label); - /** * Get the recoloring attribute * @param label pointer to a label object diff --git a/src/lv_widgets/lv_meter.c b/src/lv_widgets/lv_meter.c index c76ade476e..30502c6b82 100644 --- a/src/lv_widgets/lv_meter.c +++ b/src/lv_widgets/lv_meter.c @@ -476,6 +476,10 @@ static void draw_lines_and_labels(lv_obj_t * obj, const lv_area_t * clip_area, c lv_draw_label_dsc_init(&label_dsc); lv_obj_init_draw_label_dsc(obj, LV_PART_MARKER, &label_dsc); + lv_obj_draw_hook_dsc_t hook_dsc; + lv_obj_draw_hook_dsc_init(&hook_dsc, clip_area); + hook_dsc.part = LV_PART_MARKER; + uint32_t sub_cnt = meter->marker_nth - 1; lv_opa_t opa_main = lv_obj_get_style_opa(obj, LV_PART_MAIN); bool marker; @@ -564,11 +568,11 @@ static void draw_lines_and_labels(lv_obj_t * obj, const lv_area_t * clip_area, c p.x = (int32_t)(((int32_t)cos_mid * r_text + 127) >> (LV_TRIGO_SHIFT)) + scale_center.y; p.y = (int32_t)(((int32_t)sin_mid * r_text + 127) >> (LV_TRIGO_SHIFT)) + scale_center.x; - char buf[32]; - lv_snprintf(buf, sizeof(buf), "%d", value_of_line); + lv_snprintf(hook_dsc.text, sizeof(hook_dsc.text), "%d", value_of_line); + lv_event_send(obj, LV_EVENT_DRAW_PART_BEGIN, &hook_dsc); lv_point_t label_size; - _lv_txt_get_size(&label_size, buf, label_dsc.font, label_dsc.letter_space, label_dsc.line_space, + _lv_txt_get_size(&label_size, hook_dsc.text, label_dsc.font, label_dsc.letter_space, label_dsc.line_space, LV_COORD_MAX, LV_TEXT_FLAG_NONE); lv_area_t label_cord; @@ -577,7 +581,7 @@ static void draw_lines_and_labels(lv_obj_t * obj, const lv_area_t * clip_area, c label_cord.x2 = label_cord.x1 + label_size.x; label_cord.y2 = label_cord.y1 + label_size.y; - lv_draw_label(&label_cord, clip_area, &label_dsc, buf, NULL); + lv_draw_label(&label_cord, clip_area, &label_dsc, hook_dsc.text, NULL); } } } diff --git a/src/lv_widgets/lv_switch.c b/src/lv_widgets/lv_switch.c index f3b19e35f0..152e39759d 100644 --- a/src/lv_widgets/lv_switch.c +++ b/src/lv_widgets/lv_switch.c @@ -35,14 +35,21 @@ * STATIC PROTOTYPES **********************/ static void lv_switch_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_obj_t * copy); -static void lv_switch_destructor(void * obj); +static void lv_switch_destructor(lv_obj_t * obj); static lv_res_t lv_switch_signal(lv_obj_t * obj, lv_signal_t sign, void * param); static lv_draw_res_t lv_switch_draw(lv_obj_t * sw, const lv_area_t * clip_area, lv_draw_mode_t mode); /********************** * STATIC VARIABLES **********************/ -lv_switch_class_t lv_switch; +const lv_obj_class_t lv_switch = { + .constructor = lv_switch_constructor, + .destructor = lv_switch_destructor, + .signal_cb = lv_switch_signal, + .draw_cb = lv_switch_draw, + .instance_size = sizeof(lv_switch_t), + .base_class = &lv_obj +}; /********************** * MACROS @@ -61,23 +68,9 @@ lv_switch_class_t lv_switch; */ lv_obj_t * lv_switch_create(lv_obj_t * parent, const lv_obj_t * copy) { - if(!lv_switch._inited) { - LV_CLASS_INIT(lv_switch, lv_obj); - lv_switch.constructor = lv_switch_constructor; - lv_switch.destructor = lv_switch_destructor; - lv_switch.draw_cb = lv_switch_draw; - lv_switch.signal_cb = lv_switch_signal; - } - - lv_obj_t * obj = lv_class_new(&lv_switch); - lv_switch.constructor(obj, parent, copy); - - lv_obj_create_finish(obj, parent, copy); - - return obj; + return lv_obj_create_from_class(&lv_switch, parent, copy); } - /********************** * STATIC FUNCTIONS **********************/ @@ -86,10 +79,7 @@ static void lv_switch_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_ob { LV_LOG_TRACE("switch create started"); - LV_CLASS_CONSTRUCTOR_BEGIN(obj, lv_switch) - lv_switch.base_p->constructor(obj, parent, copy); - - lv_switch_t * sw = (lv_switch_t *) obj; + lv_obj_construct_base(obj, parent, copy); if(copy == NULL) { lv_obj_clear_flag(obj, LV_OBJ_FLAG_SCROLLABLE); @@ -97,11 +87,10 @@ static void lv_switch_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_ob lv_obj_set_size(obj, LV_DPX(60), LV_DPX(35)); } - LV_CLASS_CONSTRUCTOR_END(obj, lv_switch) LV_LOG_INFO("switch created"); } -static void lv_switch_destructor(void * obj) +static void lv_switch_destructor(lv_obj_t * obj) { // lv_bar_t * bar = obj; // @@ -124,19 +113,16 @@ static void lv_switch_destructor(void * obj) static lv_draw_res_t lv_switch_draw(lv_obj_t * obj, const lv_area_t * clip_area, lv_draw_mode_t mode) { /*Return false if the object is not covers the mask_p area*/ - if(mode == LV_DRAW_COVER_CHK) { + if(mode == LV_DRAW_MODE_COVER_CHECK) { return LV_DRAW_RES_NOT_COVER; } /*Draw the object*/ - else if(mode == LV_DRAW_DRAW_MAIN) { - + else if(mode == LV_DRAW_MODE_MAIN_DRAW) { /*The ancestor draw function will draw the background.*/ - lv_switch.base_p->draw_cb(obj, clip_area, mode); + lv_obj.draw_cb(obj, clip_area, mode); lv_bidi_dir_t base_dir = lv_obj_get_base_dir(obj); - lv_switch_t * sw = (lv_switch_t *)obj; - /*Calculate the indicator area*/ lv_coord_t bg_left = lv_obj_get_style_pad_left(obj, LV_PART_MAIN); lv_coord_t bg_right = lv_obj_get_style_pad_right(obj, LV_PART_MAIN); @@ -148,7 +134,7 @@ static lv_draw_res_t lv_switch_draw(lv_obj_t * obj, const lv_area_t * clip_area, if(chk) { /*Respect the background's padding*/ lv_area_t indic_area; - lv_area_copy(&indic_area, &sw->coords); + lv_area_copy(&indic_area, &obj->coords); indic_area.x1 += bg_left; indic_area.x2 -= bg_right; indic_area.y1 += bg_top; @@ -167,16 +153,16 @@ static lv_draw_res_t lv_switch_draw(lv_obj_t * obj, const lv_area_t * clip_area, /*Left*/ if((base_dir != LV_BIDI_DIR_RTL && !chk) || (base_dir == LV_BIDI_DIR_RTL && chk)) { - knob_area.x1 = sw->coords.x1 + bg_left; + knob_area.x1 = obj->coords.x1 + bg_left; knob_area.x2 = knob_area.x1 + knob_size; } else { - knob_area.x2 = sw->coords.x2 - bg_right; + knob_area.x2 = obj->coords.x2 - bg_right; knob_area.x1 = knob_area.x2 - knob_size; } - knob_area.y1 = sw->coords.y1 + bg_top; - knob_area.y2 = sw->coords.y2 - bg_bottom; + knob_area.y1 = obj->coords.y1 + bg_top; + knob_area.y2 = obj->coords.y2 - bg_bottom; lv_coord_t knob_left = lv_obj_get_style_pad_left(obj, LV_PART_KNOB); lv_coord_t knob_right = lv_obj_get_style_pad_right(obj, LV_PART_KNOB); @@ -197,8 +183,8 @@ static lv_draw_res_t lv_switch_draw(lv_obj_t * obj, const lv_area_t * clip_area, } /*Post draw when the children are drawn*/ - else if(mode == LV_DRAW_DRAW_POST) { - return lv_switch.base_p->draw_cb(obj, clip_area, mode); + else if(mode == LV_DRAW_MODE_POST_DRAW) { + return lv_obj.draw_cb(obj, clip_area, mode); } return LV_DRAW_RES_OK; @@ -217,7 +203,7 @@ static lv_res_t lv_switch_signal(lv_obj_t * obj, lv_signal_t sign, void * param) lv_res_t res; /* Include the ancient signal function */ - res = lv_switch.base_p->signal_cb(obj, sign, param); + res = lv_obj.signal_cb(obj, sign, param); if(res != LV_RES_OK) return res; diff --git a/src/lv_widgets/lv_switch.h b/src/lv_widgets/lv_switch.h index 7231c96076..d845377fda 100644 --- a/src/lv_widgets/lv_switch.h +++ b/src/lv_widgets/lv_switch.h @@ -32,19 +32,12 @@ extern "C" { * TYPEDEFS **********************/ -LV_CLASS_DECLARE_START(lv_switch, lv_obj); +typedef struct { + lv_obj_t obj; +}lv_switch_t; -#define _lv_switch_constructor void (*constructor)(struct _lv_obj_t * obj, struct _lv_obj_t * parent, const struct _lv_obj_t * copy) -#define _lv_switch_data \ - _lv_obj_data - -#define _lv_switch_class_dsc \ - _lv_obj_class_dsc \ - -LV_CLASS_DECLARE_END(lv_switch, lv_obj); - -extern lv_switch_class_t lv_switch; +extern const lv_obj_class_t lv_switch; /********************** * GLOBAL PROTOTYPES diff --git a/src/lv_widgets/lv_textarea.c b/src/lv_widgets/lv_textarea.c index 72cb67777a..bc2ec5e4b5 100644 --- a/src/lv_widgets/lv_textarea.c +++ b/src/lv_widgets/lv_textarea.c @@ -46,27 +46,36 @@ /********************** * STATIC PROTOTYPES **********************/ -static lv_draw_res_t lv_textarea_draw(lv_obj_t * ta, const lv_area_t * clip_area, lv_draw_mode_t mode); -static lv_res_t lv_textarea_signal(lv_obj_t * ta, lv_signal_t sign, void * param); -static lv_style_list_t * lv_textarea_get_style(lv_obj_t * ta, uint8_t part); +static void lv_textarea_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_obj_t * copy); +static void lv_textarea_destructor(lv_obj_t * obj); +static lv_draw_res_t lv_textarea_draw(lv_obj_t * obj, const lv_area_t * clip_area, lv_draw_mode_t mode); +static lv_res_t lv_textarea_signal(lv_obj_t * obj, lv_signal_t sign, void * param); #if LV_USE_ANIMATION - static void cursor_blink_anim(lv_obj_t * ta, lv_anim_value_t show); - static void pwd_char_hider_anim(lv_obj_t * ta, lv_anim_value_t x); + static void cursor_blink_anim_cb(lv_obj_t * obj, lv_anim_value_t show); + static void pwd_char_hider_anim(lv_obj_t * obj, lv_anim_value_t x); static void pwd_char_hider_anim_ready(lv_anim_t * a); #endif -static void pwd_char_hider(lv_obj_t * ta); -static bool char_is_accepted(lv_obj_t * ta, uint32_t c); -static void refr_cursor_area(lv_obj_t * ta); -static void update_cursor_position_on_click(lv_obj_t * ta, lv_signal_t sign, lv_indev_t * click_source); -static lv_res_t insert_handler(lv_obj_t * ta, const char * txt); -static void draw_placeholder(lv_obj_t * ta, const lv_area_t * clip_area); -static void draw_cursor(lv_obj_t * ta, const lv_area_t * clip_area); +static void pwd_char_hider(lv_obj_t * obj); +static bool char_is_accepted(lv_obj_t * obj, uint32_t c); +static void start_cursor_blink(lv_obj_t * obj); +static void refr_cursor_area(lv_obj_t * obj); +static void update_cursor_position_on_click(lv_obj_t * obj, lv_signal_t sign, lv_indev_t * click_source); +static lv_res_t insert_handler(lv_obj_t * obj, const char * txt); +static void draw_placeholder(lv_obj_t * obj, const lv_area_t * clip_area); +static void draw_cursor(lv_obj_t * obj, const lv_area_t * clip_area); /********************** * STATIC VARIABLES **********************/ -static lv_draw_cb_t ancestor_draw; -static lv_signal_cb_t ancestor_signal; +const lv_obj_class_t lv_textarea = { + .constructor = lv_textarea_constructor, + .destructor = lv_textarea_destructor, + .signal_cb = lv_textarea_signal, + .draw_cb = lv_textarea_draw, + .instance_size = sizeof(lv_textarea_t), + .base_class = &lv_obj +}; + static const char * ta_insert_replace; /********************** @@ -83,122 +92,9 @@ static const char * ta_insert_replace; * @param copy pointer to a text area object, if not NULL then the new object will be copied from it * @return pointer to the created text area */ -lv_obj_t * lv_textarea_create(lv_obj_t * par, const lv_obj_t * copy) +lv_obj_t * lv_textarea_create(lv_obj_t * parent, const lv_obj_t * copy) { - LV_LOG_TRACE("text area create started"); - - /*Create the ancestor object*/ - lv_obj_t * ta = lv_obj_create(par, copy); - LV_ASSERT_MEM(ta); - if(ta == NULL) return NULL; - - if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(ta); - if(ancestor_draw == NULL) ancestor_draw = lv_obj_get_draw_cb(ta); - - /*Allocate the object type specific extended data*/ - lv_textarea_ext_t * ext = lv_obj_allocate_ext_attr(ta, sizeof(lv_textarea_ext_t)); - LV_ASSERT_MEM(ext); - if(ext == NULL) { - lv_obj_del(ta); - return NULL; - } - - ext->pwd_mode = 0; - ext->pwd_tmp = NULL; - ext->pwd_show_time = LV_TEXTAREA_DEF_PWD_SHOW_TIME; - ext->accepted_chars = NULL; - ext->max_length = 0; - ext->cursor.state = 1; - ext->cursor.hidden = 0; - ext->cursor.blink_time = LV_TEXTAREA_DEF_CURSOR_BLINK_TIME; - ext->cursor.pos = 0; - ext->cursor.click_pos = 1; - ext->cursor.valid_x = 0; - ext->one_line = 0; -#if LV_LABEL_TEXT_SEL - ext->text_sel_en = 0; -#endif - ext->label = NULL; - ext->placeholder_txt = NULL; - - lv_style_list_init(&ext->cursor.style); - lv_style_list_init(&ext->style_placeholder); - -#if LV_USE_ANIMATION == 0 - ext->pwd_show_time = 0; - ext->cursor.blink_time = 0; -#endif - - lv_obj_set_signal_cb(ta, lv_textarea_signal); - lv_obj_set_draw_cb(ta, lv_textarea_draw); - - /*Init the new text area object*/ - if(copy == NULL) { - ext->label = lv_label_create(ta, NULL); - lv_label_set_long_mode(ext->label, LV_LABEL_LONG_BREAK); - lv_label_set_text(ext->label, "Text area"); - lv_obj_set_size(ta, LV_TEXTAREA_DEF_WIDTH, LV_TEXTAREA_DEF_HEIGHT); - lv_theme_apply(ta, LV_THEME_TEXTAREA); - - } - /*Copy an existing object*/ - else { - lv_textarea_ext_t * copy_ext = lv_obj_get_ext_attr(copy); - ext->label = lv_label_create(ta, copy_ext->label); - ext->pwd_mode = copy_ext->pwd_mode; - ext->accepted_chars = copy_ext->accepted_chars; - ext->max_length = copy_ext->max_length; - ext->cursor.pos = copy_ext->cursor.pos; - ext->cursor.valid_x = copy_ext->cursor.valid_x; - ext->cursor.hidden = copy_ext->cursor.hidden; - - lv_style_list_copy(&ext->cursor.style, ©_ext->cursor.style); - lv_style_list_copy(&ext->style_placeholder, ©_ext->style_placeholder); - - if(ext->pwd_mode != 0) pwd_char_hider(ta); - - if(copy_ext->placeholder_txt) { - lv_textarea_set_placeholder_text(ta, copy_ext->placeholder_txt); - } - - if(copy_ext->pwd_tmp) { - uint32_t len = lv_mem_get_size(copy_ext->pwd_tmp); - ext->pwd_tmp = lv_mem_alloc(len); - LV_ASSERT_MEM(ext->pwd_tmp); - if(ext->pwd_tmp == NULL) return NULL; - - lv_memcpy(ext->pwd_tmp, copy_ext->pwd_tmp, len); - } - - if(copy_ext->one_line) lv_textarea_set_one_line(ta, true); - - /*Refresh the style with new signal function*/ - _lv_obj_refresh_style(ta, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); - } - -#if LV_USE_ANIMATION - if(ext->cursor.blink_time) { - /*Create a cursor blinker animation*/ - lv_anim_path_t path; - lv_anim_path_init(&path); - lv_anim_path_set_cb(&path, lv_anim_path_step); - - lv_anim_t a; - lv_anim_init(&a); - lv_anim_set_var(&a, ta); - lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)cursor_blink_anim); - lv_anim_set_time(&a, ext->cursor.blink_time); - lv_anim_set_playback_time(&a, ext->cursor.blink_time); - lv_anim_set_values(&a, 0, 1); - lv_anim_set_path(&a, &path); - lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE); - lv_anim_start(&a); - } -#endif - - LV_LOG_INFO("text area created"); - - return ta; + return lv_obj_create_from_class(&lv_textarea, parent, copy); } /*====================== @@ -211,11 +107,11 @@ lv_obj_t * lv_textarea_create(lv_obj_t * par, const lv_obj_t * copy) * @param ta pointer to a text area object * @param c a character (e.g. 'a') */ -void lv_textarea_add_char(lv_obj_t * ta, uint32_t c) +void lv_textarea_add_char(lv_obj_t * obj, uint32_t c) { - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); + lv_textarea_t * ta = (lv_textarea_t *) obj; const char * letter_buf; @@ -229,44 +125,44 @@ void lv_textarea_add_char(lv_obj_t * ta, uint32_t c) if(c != 0) while(*letter_buf == 0) ++letter_buf; #endif - lv_res_t res = insert_handler(ta, letter_buf); + lv_res_t res = insert_handler(obj, letter_buf); if(res != LV_RES_OK) return; - if(ext->one_line && (c == '\n' || c == '\r')) { + if(ta->one_line && (c == '\n' || c == '\r')) { LV_LOG_INFO("Text area: line break ignored in one-line mode"); return; } uint32_t c_uni = _lv_txt_encoded_next((const char *)&c, NULL); - if(char_is_accepted(ta, c_uni) == false) { + if(char_is_accepted(obj, c_uni) == false) { LV_LOG_INFO("Character is no accepted by the text area (too long text or not in the " "accepted list)"); return; } - if(ext->pwd_mode != 0) pwd_char_hider(ta); /*Make sure all the current text contains only '*'*/ + if(ta->pwd_mode != 0) pwd_char_hider(obj); /*Make sure all the current text contains only '*'*/ /*If the textarea is empty, invalidate it to hide the placeholder*/ - if(ext->placeholder_txt) { - const char * txt = lv_label_get_text(ext->label); - if(txt[0] == '\0') lv_obj_invalidate(ta); + if(ta->placeholder_txt) { + const char * txt = lv_label_get_text(ta->label); + if(txt[0] == '\0') lv_obj_invalidate(obj); } - lv_label_ins_text(ext->label, ext->cursor.pos, letter_buf); /*Insert the character*/ - lv_textarea_clear_selection(ta); /*Clear selection*/ + lv_label_ins_text(ta->label, ta->cursor.pos, letter_buf); /*Insert the character*/ + lv_textarea_clear_selection(obj); /*Clear selection*/ - if(ext->pwd_mode != 0) { - ext->pwd_tmp = lv_mem_realloc(ext->pwd_tmp, strlen(ext->pwd_tmp) + strlen(letter_buf) + 1); /*+2: the new char + \0 */ - LV_ASSERT_MEM(ext->pwd_tmp); - if(ext->pwd_tmp == NULL) return; + if(ta->pwd_mode != 0) { + ta->pwd_tmp = lv_mem_realloc(ta->pwd_tmp, strlen(ta->pwd_tmp) + strlen(letter_buf) + 1); /*+2: the new char + \0 */ + LV_ASSERT_MEM(ta->pwd_tmp); + if(ta->pwd_tmp == NULL) return; - _lv_txt_ins(ext->pwd_tmp, ext->cursor.pos, (const char *)letter_buf); + _lv_txt_ins(ta->pwd_tmp, ta->cursor.pos, (const char *)letter_buf); #if LV_USE_ANIMATION /*Auto hide characters*/ - if(ext->pwd_show_time == 0) { - pwd_char_hider(ta); + if(ta->pwd_show_time == 0) { + pwd_char_hider(obj); } else { lv_anim_path_t path; @@ -277,7 +173,7 @@ void lv_textarea_add_char(lv_obj_t * ta, uint32_t c) lv_anim_init(&a); lv_anim_set_var(&a, ta); lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)pwd_char_hider_anim); - lv_anim_set_time(&a, ext->pwd_show_time); + lv_anim_set_time(&a, ta->pwd_show_time); lv_anim_set_values(&a, 0, 1); lv_anim_set_path(&a, &path); lv_anim_set_ready_cb(&a, pwd_char_hider_anim_ready); @@ -285,14 +181,14 @@ void lv_textarea_add_char(lv_obj_t * ta, uint32_t c) } #else - pwd_char_hider(ta); + pwd_char_hider(obj); #endif } /*Move the cursor after the new character*/ - lv_textarea_set_cursor_pos(ta, lv_textarea_get_cursor_pos(ta) + 1); + lv_textarea_set_cursor_pos(obj, lv_textarea_get_cursor_pos(obj) + 1); - lv_event_send(ta, LV_EVENT_VALUE_CHANGED, NULL); + lv_event_send(obj, LV_EVENT_VALUE_CHANGED, NULL); } /** @@ -300,49 +196,49 @@ void lv_textarea_add_char(lv_obj_t * ta, uint32_t c) * @param ta pointer to a text area object * @param txt a '\0' terminated string to insert */ -void lv_textarea_add_text(lv_obj_t * ta, const char * txt) +void lv_textarea_add_text(lv_obj_t * obj, const char * txt) { - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); LV_ASSERT_NULL(txt); - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); + lv_textarea_t * ta = (lv_textarea_t *) obj; - if(ext->pwd_mode != 0) pwd_char_hider(ta); /*Make sure all the current text contains only '*'*/ + if(ta->pwd_mode != 0) pwd_char_hider(obj); /*Make sure all the current text contains only '*'*/ /*Add the character one-by-one if not all characters are accepted or there is character limit.*/ - if(lv_textarea_get_accepted_chars(ta) || lv_textarea_get_max_length(ta)) { + if(lv_textarea_get_accepted_chars(obj) || lv_textarea_get_max_length(obj)) { uint32_t i = 0; while(txt[i] != '\0') { uint32_t c = _lv_txt_encoded_next(txt, &i); - lv_textarea_add_char(ta, _lv_txt_unicode_to_encoded(c)); + lv_textarea_add_char(obj, _lv_txt_unicode_to_encoded(c)); } return; } - lv_res_t res = insert_handler(ta, txt); + lv_res_t res = insert_handler(obj, txt); if(res != LV_RES_OK) return; /*If the textarea is empty, invalidate it to hide the placeholder*/ - if(ext->placeholder_txt) { - const char * txt_act = lv_label_get_text(ext->label); - if(txt_act[0] == '\0') lv_obj_invalidate(ta); + if(ta->placeholder_txt) { + const char * txt_act = lv_label_get_text(ta->label); + if(txt_act[0] == '\0') lv_obj_invalidate(obj); } /*Insert the text*/ - lv_label_ins_text(ext->label, ext->cursor.pos, txt); - lv_textarea_clear_selection(ta); + lv_label_ins_text(ta->label, ta->cursor.pos, txt); + lv_textarea_clear_selection(obj); - if(ext->pwd_mode != 0) { - ext->pwd_tmp = lv_mem_realloc(ext->pwd_tmp, strlen(ext->pwd_tmp) + strlen(txt) + 1); - LV_ASSERT_MEM(ext->pwd_tmp); - if(ext->pwd_tmp == NULL) return; + if(ta->pwd_mode != 0) { + ta->pwd_tmp = lv_mem_realloc(ta->pwd_tmp, strlen(ta->pwd_tmp) + strlen(txt) + 1); + LV_ASSERT_MEM(ta->pwd_tmp); + if(ta->pwd_tmp == NULL) return; - _lv_txt_ins(ext->pwd_tmp, ext->cursor.pos, txt); + _lv_txt_ins(ta->pwd_tmp, ta->cursor.pos, txt); #if LV_USE_ANIMATION /*Auto hide characters*/ - if(ext->pwd_show_time == 0) { - pwd_char_hider(ta); + if(ta->pwd_show_time == 0) { + pwd_char_hider(obj); } else { lv_anim_path_t path; @@ -353,69 +249,69 @@ void lv_textarea_add_text(lv_obj_t * ta, const char * txt) lv_anim_init(&a); lv_anim_set_var(&a, ta); lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)pwd_char_hider_anim); - lv_anim_set_time(&a, ext->pwd_show_time); + lv_anim_set_time(&a, ta->pwd_show_time); lv_anim_set_values(&a, 0, 1); lv_anim_set_path(&a, &path); lv_anim_set_ready_cb(&a, pwd_char_hider_anim_ready); lv_anim_start(&a); } #else - pwd_char_hider(ta); + pwd_char_hider(obj); #endif } /*Move the cursor after the new text*/ - lv_textarea_set_cursor_pos(ta, lv_textarea_get_cursor_pos(ta) + _lv_txt_get_encoded_length(txt)); + lv_textarea_set_cursor_pos(obj, lv_textarea_get_cursor_pos(obj) + _lv_txt_get_encoded_length(txt)); - lv_event_send(ta, LV_EVENT_VALUE_CHANGED, NULL); + lv_event_send(obj, LV_EVENT_VALUE_CHANGED, NULL); } /** * Delete a the left character from the current cursor position * @param ta pointer to a text area object */ -void lv_textarea_del_char(lv_obj_t * ta) +void lv_textarea_del_char(lv_obj_t * obj) { - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); - uint32_t cur_pos = ext->cursor.pos; + lv_textarea_t * ta = (lv_textarea_t *) obj; + uint32_t cur_pos = ta->cursor.pos; if(cur_pos == 0) return; char del_buf[2] = {LV_KEY_DEL, '\0'}; - lv_res_t res = insert_handler(ta, del_buf); + lv_res_t res = insert_handler(obj, del_buf); if(res != LV_RES_OK) return; - char * label_txt = lv_label_get_text(ext->label); + char * label_txt = lv_label_get_text(ta->label); /*Delete a character*/ - _lv_txt_cut(label_txt, ext->cursor.pos - 1, 1); + _lv_txt_cut(label_txt, ta->cursor.pos - 1, 1); /*Refresh the label*/ - lv_label_set_text(ext->label, label_txt); - lv_textarea_clear_selection(ta); + lv_label_set_text(ta->label, label_txt); + lv_textarea_clear_selection(obj); /*If the textarea became empty, invalidate it to hide the placeholder*/ - if(ext->placeholder_txt) { - const char * txt = lv_label_get_text(ext->label); - if(txt[0] == '\0') lv_obj_invalidate(ta); + if(ta->placeholder_txt) { + const char * txt = lv_label_get_text(ta->label); + if(txt[0] == '\0') lv_obj_invalidate(obj); } - if(ext->pwd_mode != 0) { - uint32_t byte_pos = _lv_txt_encoded_get_byte_id(ext->pwd_tmp, ext->cursor.pos - 1); - _lv_txt_cut(ext->pwd_tmp, ext->cursor.pos - 1, _lv_txt_encoded_size(&ext->pwd_tmp[byte_pos])); + if(ta->pwd_mode != 0) { + uint32_t byte_pos = _lv_txt_encoded_get_byte_id(ta->pwd_tmp, ta->cursor.pos - 1); + _lv_txt_cut(ta->pwd_tmp, ta->cursor.pos - 1, _lv_txt_encoded_size(&ta->pwd_tmp[byte_pos])); - ext->pwd_tmp = lv_mem_realloc(ext->pwd_tmp, strlen(ext->pwd_tmp) + 1); - LV_ASSERT_MEM(ext->pwd_tmp); - if(ext->pwd_tmp == NULL) return; + ta->pwd_tmp = lv_mem_realloc(ta->pwd_tmp, strlen(ta->pwd_tmp) + 1); + LV_ASSERT_MEM(ta->pwd_tmp); + if(ta->pwd_tmp == NULL) return; } /*Move the cursor to the place of the deleted character*/ - lv_textarea_set_cursor_pos(ta, ext->cursor.pos - 1); + lv_textarea_set_cursor_pos(obj, ta->cursor.pos - 1); - lv_event_send(ta, LV_EVENT_VALUE_CHANGED, NULL); + lv_event_send(obj, LV_EVENT_VALUE_CHANGED, NULL); } @@ -423,13 +319,13 @@ void lv_textarea_del_char(lv_obj_t * ta) * Delete the right character from the current cursor position * @param ta pointer to a text area object */ -void lv_textarea_del_char_forward(lv_obj_t * ta) +void lv_textarea_del_char_forward(lv_obj_t * obj) { - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - uint32_t cp = lv_textarea_get_cursor_pos(ta); - lv_textarea_set_cursor_pos(ta, cp + 1); - if(cp != lv_textarea_get_cursor_pos(ta)) lv_textarea_del_char(ta); + uint32_t cp = lv_textarea_get_cursor_pos(obj); + lv_textarea_set_cursor_pos(obj, cp + 1); + if(cp != lv_textarea_get_cursor_pos(obj)) lv_textarea_del_char(obj); } /*===================== @@ -441,51 +337,51 @@ void lv_textarea_del_char_forward(lv_obj_t * ta) * @param ta pointer to a text area * @param txt pointer to the text */ -void lv_textarea_set_text(lv_obj_t * ta, const char * txt) +void lv_textarea_set_text(lv_obj_t * obj, const char * txt) { - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); LV_ASSERT_NULL(txt); - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); + lv_textarea_t * ta = (lv_textarea_t *) obj; /*Clear the existing selection*/ - lv_textarea_clear_selection(ta); + lv_textarea_clear_selection(obj); /*Add the character one-by-one if not all characters are accepted or there is character limit.*/ - if(lv_textarea_get_accepted_chars(ta) || lv_textarea_get_max_length(ta)) { - lv_label_set_text(ext->label, ""); - lv_textarea_set_cursor_pos(ta, LV_TEXTAREA_CURSOR_LAST); - if(ext->pwd_mode != 0) { - ext->pwd_tmp[0] = '\0'; /*Clear the password too*/ + if(lv_textarea_get_accepted_chars(obj) || lv_textarea_get_max_length(obj)) { + lv_label_set_text(ta->label, ""); + lv_textarea_set_cursor_pos(obj, LV_TEXTAREA_CURSOR_LAST); + if(ta->pwd_mode != 0) { + ta->pwd_tmp[0] = '\0'; /*Clear the password too*/ } uint32_t i = 0; while(txt[i] != '\0') { uint32_t c = _lv_txt_encoded_next(txt, &i); - lv_textarea_add_char(ta, _lv_txt_unicode_to_encoded(c)); + lv_textarea_add_char(obj, _lv_txt_unicode_to_encoded(c)); } } else { - lv_label_set_text(ext->label, txt); - lv_textarea_set_cursor_pos(ta, LV_TEXTAREA_CURSOR_LAST); + lv_label_set_text(ta->label, txt); + lv_textarea_set_cursor_pos(obj, LV_TEXTAREA_CURSOR_LAST); } /*If the textarea is empty, invalidate it to hide the placeholder*/ - if(ext->placeholder_txt) { - const char * txt_act = lv_label_get_text(ext->label); - if(txt_act[0] == '\0') lv_obj_invalidate(ta); + if(ta->placeholder_txt) { + const char * txt_act = lv_label_get_text(ta->label); + if(txt_act[0] == '\0') lv_obj_invalidate(obj); } - if(ext->pwd_mode != 0) { - ext->pwd_tmp = lv_mem_realloc(ext->pwd_tmp, strlen(txt) + 1); - LV_ASSERT_MEM(ext->pwd_tmp); - if(ext->pwd_tmp == NULL) return; - strcpy(ext->pwd_tmp, txt); + if(ta->pwd_mode != 0) { + ta->pwd_tmp = lv_mem_realloc(ta->pwd_tmp, strlen(txt) + 1); + LV_ASSERT_MEM(ta->pwd_tmp); + if(ta->pwd_tmp == NULL) return; + strcpy(ta->pwd_tmp, txt); #if LV_USE_ANIMATION /*Auto hide characters*/ - if(ext->pwd_show_time == 0) { - pwd_char_hider(ta); + if(ta->pwd_show_time == 0) { + pwd_char_hider(obj); } else { lv_anim_path_t path; @@ -496,18 +392,18 @@ void lv_textarea_set_text(lv_obj_t * ta, const char * txt) lv_anim_init(&a); lv_anim_set_var(&a, ta); lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)pwd_char_hider_anim); - lv_anim_set_time(&a, ext->pwd_show_time); + lv_anim_set_time(&a, ta->pwd_show_time); lv_anim_set_values(&a, 0, 1); lv_anim_set_path(&a, &path); lv_anim_set_ready_cb(&a, pwd_char_hider_anim_ready); lv_anim_start(&a); } #else - pwd_char_hider(ta); + pwd_char_hider(obj); #endif } - lv_event_send(ta, LV_EVENT_VALUE_CHANGED, NULL); + lv_event_send(obj, LV_EVENT_VALUE_CHANGED, NULL); } /** @@ -515,40 +411,40 @@ void lv_textarea_set_text(lv_obj_t * ta, const char * txt) * @param ta pointer to a text area * @param txt pointer to the text */ -void lv_textarea_set_placeholder_text(lv_obj_t * ta, const char * txt) +void lv_textarea_set_placeholder_text(lv_obj_t * obj, const char * txt) { - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); LV_ASSERT_NULL(txt); - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); + lv_textarea_t * ta = (lv_textarea_t *) obj; size_t txt_len = strlen(txt); if(txt_len == 0) { - if(ext->placeholder_txt) { - lv_mem_free(ext->placeholder_txt); - ext->placeholder_txt = NULL; + if(ta->placeholder_txt) { + lv_mem_free(ta->placeholder_txt); + ta->placeholder_txt = NULL; } } else { /*Allocate memory for the placeholder_txt text*/ - if(ext->placeholder_txt == NULL) { - ext->placeholder_txt = lv_mem_alloc(txt_len + 1); + if(ta->placeholder_txt == NULL) { + ta->placeholder_txt = lv_mem_alloc(txt_len + 1); } else { - ext->placeholder_txt = lv_mem_realloc(ext->placeholder_txt, txt_len + 1); + ta->placeholder_txt = lv_mem_realloc(ta->placeholder_txt, txt_len + 1); } - LV_ASSERT_MEM(ext->placeholder_txt); - if(ext->placeholder_txt == NULL) { + LV_ASSERT_MEM(ta->placeholder_txt); + if(ta->placeholder_txt == NULL) { LV_LOG_ERROR("lv_textarea_set_placeholder_text: couldn't allocate memory for placeholder"); return; } - strcpy(ext->placeholder_txt, txt); + strcpy(ta->placeholder_txt, txt); } - lv_obj_invalidate(ta); + lv_obj_invalidate(obj); } /** @@ -558,80 +454,46 @@ void lv_textarea_set_placeholder_text(lv_obj_t * ta, const char * txt) * < 0 : index from the end of the text * LV_TEXTAREA_CURSOR_LAST: go after the last character */ -void lv_textarea_set_cursor_pos(lv_obj_t * ta, int32_t pos) +void lv_textarea_set_cursor_pos(lv_obj_t * obj, int32_t pos) { - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); - if((uint32_t)ext->cursor.pos == (uint32_t)pos) return; + lv_textarea_t * ta = (lv_textarea_t *) obj; + if((uint32_t)ta->cursor.pos == (uint32_t)pos) return; - uint32_t len = _lv_txt_get_encoded_length(lv_label_get_text(ext->label)); + uint32_t len = _lv_txt_get_encoded_length(lv_label_get_text(ta->label)); if(pos < 0) pos = len + pos; if(pos > (int32_t)len || pos == LV_TEXTAREA_CURSOR_LAST) pos = len; - ext->cursor.pos = pos; + ta->cursor.pos = pos; - /*Position the label to make the cursor visible*/ + /*Position the label to make the cursor show*/ lv_point_t cur_pos; - const lv_font_t * font = lv_obj_get_style_text_font(ta, LV_TEXTAREA_PART_MAIN); + const lv_font_t * font = lv_obj_get_style_text_font(obj, LV_PART_MAIN); lv_area_t label_cords; lv_area_t ta_cords; - lv_label_get_letter_pos(ext->label, pos, &cur_pos); - lv_obj_get_coords(ta, &ta_cords); - lv_obj_get_coords(ext->label, &label_cords); + lv_label_get_letter_pos(ta->label, pos, &cur_pos); + lv_obj_get_coords(obj, &ta_cords); + lv_obj_get_coords(ta->label, &label_cords); /*Check the top*/ lv_coord_t font_h = lv_font_get_line_height(font); - if(cur_pos.y < lv_obj_get_scroll_top(ta)) { - lv_obj_scroll_to_y(ta, cur_pos.y, LV_ANIM_ON); + if(cur_pos.y < lv_obj_get_scroll_top(obj)) { + lv_obj_scroll_to_y(obj, cur_pos.y, LV_ANIM_ON); } /*Check the bottom*/ - lv_coord_t h = lv_obj_get_height_fit(ta); - if(cur_pos.y + font_h - lv_obj_get_scroll_top(ta) > h) { - lv_obj_scroll_to_y(ta, cur_pos.y - h + font_h, LV_ANIM_ON); + lv_coord_t h = lv_obj_get_height_fit(obj); + if(cur_pos.y + font_h - lv_obj_get_scroll_top(obj) > h) { + lv_obj_scroll_to_y(obj, cur_pos.y - h + font_h, LV_ANIM_ON); } - ext->cursor.valid_x = cur_pos.x; + ta->cursor.valid_x = cur_pos.x; -#if LV_USE_ANIMATION - if(ext->cursor.blink_time) { - /*Reset cursor blink animation*/ - lv_anim_path_t path; - lv_anim_path_init(&path); - lv_anim_path_set_cb(&path, lv_anim_path_step); + start_cursor_blink(obj); - lv_anim_t a; - lv_anim_init(&a); - lv_anim_set_var(&a, ta); - lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)cursor_blink_anim); - lv_anim_set_time(&a, ext->cursor.blink_time); - lv_anim_set_playback_time(&a, ext->cursor.blink_time); - lv_anim_set_values(&a, 1, 0); - lv_anim_set_path(&a, &path); - lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE); - lv_anim_start(&a); - } -#endif - - refr_cursor_area(ta); -} - -/** - * Hide/Unhide the cursor. - * @param ta pointer to a text area object - * @param hide: true: hide the cursor - */ -void lv_textarea_set_cursor_hidden(lv_obj_t * ta, bool hide) -{ - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); - - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); - - ext->cursor.hidden = hide ? 1 : 0; - - refr_cursor_area(ta); + refr_cursor_area(obj); } /** @@ -639,12 +501,12 @@ void lv_textarea_set_cursor_hidden(lv_obj_t * ta, bool hide) * @param ta pointer to a text area object * @param en true: enable click positions; false: disable */ -void lv_textarea_set_cursor_click_pos(lv_obj_t * ta, bool en) +void lv_textarea_set_cursor_click_pos(lv_obj_t * obj, bool en) { - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); - ext->cursor.click_pos = en ? 1 : 0; + lv_textarea_t * ta = (lv_textarea_t *) obj; + ta->cursor.click_pos = en ? 1 : 0; } /** @@ -652,37 +514,37 @@ void lv_textarea_set_cursor_click_pos(lv_obj_t * ta, bool en) * @param ta pointer to a text area object * @param en true: enable, false: disable */ -void lv_textarea_set_pwd_mode(lv_obj_t * ta, bool en) +void lv_textarea_set_pwd_mode(lv_obj_t * obj, bool en) { - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); - if(ext->pwd_mode == en) return; + lv_textarea_t * ta = (lv_textarea_t *) obj; + if(ta->pwd_mode == en) return; - ext->pwd_mode = en == false ? 0 : 1; + ta->pwd_mode = en == false ? 0 : 1; /*Pwd mode is now enabled*/ if(en != false) { - char * txt = lv_label_get_text(ext->label); + char * txt = lv_label_get_text(ta->label); size_t len = strlen(txt); - ext->pwd_tmp = lv_mem_alloc(len + 1); - LV_ASSERT_MEM(ext->pwd_tmp); - if(ext->pwd_tmp == NULL) return; + ta->pwd_tmp = lv_mem_alloc(len + 1); + LV_ASSERT_MEM(ta->pwd_tmp); + if(ta->pwd_tmp == NULL) return; - strcpy(ext->pwd_tmp, txt); + strcpy(ta->pwd_tmp, txt); - pwd_char_hider(ta); + pwd_char_hider(obj); - lv_textarea_clear_selection(ta); + lv_textarea_clear_selection(obj); } /*Pwd mode is now disabled*/ else { - lv_textarea_clear_selection(ta); - lv_label_set_text(ext->label, ext->pwd_tmp); - lv_mem_free(ext->pwd_tmp); - ext->pwd_tmp = NULL; + lv_textarea_clear_selection(obj); + lv_label_set_text(ta->label, ta->pwd_tmp); + lv_mem_free(ta->pwd_tmp); + ta->pwd_tmp = NULL; } - refr_cursor_area(ta); + refr_cursor_area(obj); } /** @@ -690,66 +552,29 @@ void lv_textarea_set_pwd_mode(lv_obj_t * ta, bool en) * @param ta pointer to a Text area object * @param en true: one line, false: normal */ -void lv_textarea_set_one_line(lv_obj_t * ta, bool en) +void lv_textarea_set_one_line(lv_obj_t * obj, bool en) { - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); - if(ext->one_line == en) return; - lv_text_align_t old_align = lv_label_get_align(ext->label); + lv_textarea_t * ta = (lv_textarea_t *) obj; + if(ta->one_line == en) return; if(en) { - const lv_font_t * font = lv_obj_get_style_text_font(ta, LV_TEXTAREA_PART_MAIN); + const lv_font_t * font = lv_obj_get_style_text_font(obj, LV_PART_MAIN); lv_coord_t font_h = lv_font_get_line_height(font); - ext->one_line = 1; - lv_obj_set_content_height(ta, font_h); - lv_label_set_long_mode(ext->label, LV_LABEL_LONG_EXPAND); - lv_obj_scroll_to(ta, 0, 0, LV_ANIM_OFF); + ta->one_line = 1; + lv_obj_set_content_height(obj, font_h); + lv_label_set_long_mode(ta->label, LV_LABEL_LONG_EXPAND); + lv_obj_scroll_to(obj, 0, 0, LV_ANIM_OFF); } else { - ext->one_line = 0; - lv_label_set_long_mode(ext->label, LV_LABEL_LONG_BREAK); + ta->one_line = 0; + lv_label_set_long_mode(ta->label, LV_LABEL_LONG_WRAP); - lv_obj_set_height(ta, LV_TEXTAREA_DEF_HEIGHT); - lv_obj_scroll_to(ta, 0, 0, LV_ANIM_OFF); + lv_obj_set_height(obj, LV_TEXTAREA_DEF_HEIGHT); + lv_obj_scroll_to(obj, 0, 0, LV_ANIM_OFF); } - - /* `refr_cursor_area` is called at the end of lv_ta_set_text_align */ - lv_textarea_set_text_align(ta, old_align); -} - -/** - * Set the alignment of the text area. - * In one line mode the text can be scrolled only with `LV_TEXT_ALIGN_LEFT`. - * This function should be called if the size of text area changes. - * @param ta pointer to a text are object - * @param align the desired alignment from `lv_text_align_t`. (LV_TEXT_ALIGN_LEFT/CENTER/RIGHT) - */ -void lv_textarea_set_text_align(lv_obj_t * ta, lv_text_align_t align) -{ - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); - - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); - lv_obj_t * label = lv_textarea_get_label(ta); - if(!ext->one_line) { - lv_label_set_align(label, align); - } - else { - /*Normal left align. Just let the text expand*/ - if(align == LV_TEXT_ALIGN_LEFT) { - lv_label_set_long_mode(label, LV_LABEL_LONG_EXPAND); - lv_label_set_align(label, align); - } - /*Else use fix label width equal to the Text area width*/ - else { - lv_label_set_long_mode(label, LV_LABEL_LONG_CROP); - lv_obj_set_width(label, lv_obj_get_width_fit(ta)); - lv_label_set_align(label, align); - } - } - - refr_cursor_area(ta); } /** @@ -757,13 +582,13 @@ void lv_textarea_set_text_align(lv_obj_t * ta, lv_text_align_t align) * @param ta pointer to Text Area * @param list list of characters. Only the pointer is saved. E.g. "+-.,0123456789" */ -void lv_textarea_set_accepted_chars(lv_obj_t * ta, const char * list) +void lv_textarea_set_accepted_chars(lv_obj_t * obj, const char * list) { - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); + lv_textarea_t * ta = (lv_textarea_t *) obj; - ext->accepted_chars = list; + ta->accepted_chars = list; } /** @@ -771,13 +596,13 @@ void lv_textarea_set_accepted_chars(lv_obj_t * ta, const char * list) * @param ta pointer to Text Area * @param num the maximal number of characters can be added (`lv_textarea_set_text` ignores it) */ -void lv_textarea_set_max_length(lv_obj_t * ta, uint32_t num) +void lv_textarea_set_max_length(lv_obj_t * obj, uint32_t num) { - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); + lv_textarea_t * ta = (lv_textarea_t *) obj; - ext->max_length = num; + ta->max_length = num; } /** @@ -788,11 +613,11 @@ void lv_textarea_set_max_length(lv_obj_t * ta, uint32_t num) * The variable must be live after the `event_cb` exists. (Should be `global` or * `static`) */ -void lv_textarea_set_insert_replace(lv_obj_t * ta, const char * txt) +void lv_textarea_set_insert_replace(lv_obj_t * obj, const char * txt) { - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - (void)ta; /*Unused*/ + LV_UNUSED(obj); ta_insert_replace = txt; } @@ -801,16 +626,16 @@ void lv_textarea_set_insert_replace(lv_obj_t * ta, const char * txt) * @param ta pointer to a text area object * @param en true or false to enable/disable selection mode */ -void lv_textarea_set_text_sel(lv_obj_t * ta, bool en) +void lv_textarea_set_text_sel(lv_obj_t * obj, bool en) { - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); #if LV_LABEL_TEXT_SEL - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); + lv_textarea_t * ta = (lv_textarea_t *) obj; - ext->text_sel_en = en; + ta->text_sel_en = en; - if(!en) lv_textarea_clear_selection(ta); + if(!en) lv_textarea_clear_selection(obj); #else (void)ta; /*Unused*/ (void)en; /*Unused*/ @@ -822,58 +647,16 @@ void lv_textarea_set_text_sel(lv_obj_t * ta, bool en) * @param ta pointer to Text area * @param time show time in milliseconds. 0: hide immediately. */ -void lv_textarea_set_pwd_show_time(lv_obj_t * ta, uint16_t time) +void lv_textarea_set_pwd_show_time(lv_obj_t * obj, uint16_t time) { - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); #if LV_USE_ANIMATION == 0 time = 0; #endif - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); - ext->pwd_show_time = time; -} - -/** - * Set cursor blink animation time - * @param ta pointer to Text area - * @param time blink period. 0: disable blinking - */ -void lv_textarea_set_cursor_blink_time(lv_obj_t * ta, uint16_t time) -{ - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); - -#if LV_USE_ANIMATION == 0 - time = 0; -#endif - - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); - ext->cursor.blink_time = time; - -#if LV_USE_ANIMATION - if(ext->cursor.blink_time) { - /*Reset cursor blink animation*/ - lv_anim_path_t path; - lv_anim_path_init(&path); - lv_anim_path_set_cb(&path, lv_anim_path_step); - - lv_anim_t a; - lv_anim_init(&a); - lv_anim_set_var(&a, ta); - lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)cursor_blink_anim); - lv_anim_set_time(&a, ext->cursor.blink_time); - lv_anim_set_playback_time(&a, ext->cursor.blink_time); - lv_anim_set_values(&a, 1, 0); - lv_anim_set_path(&a, &path); - lv_anim_start(&a); - } - else { - lv_anim_del(ta, (lv_anim_exec_xcb_t)cursor_blink_anim); - ext->cursor.state = 1; - } -#else - ext->cursor.state = 1; -#endif + lv_textarea_t * ta = (lv_textarea_t *) obj; + ta->pwd_show_time = time; } /*===================== @@ -885,18 +668,18 @@ void lv_textarea_set_cursor_blink_time(lv_obj_t * ta, uint16_t time) * @param ta pointer to a text area object * @return pointer to the text */ -const char * lv_textarea_get_text(const lv_obj_t * ta) +const char * lv_textarea_get_text(const lv_obj_t * obj) { - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); + lv_textarea_t * ta = (lv_textarea_t *) obj; const char * txt; - if(ext->pwd_mode == 0) { - txt = lv_label_get_text(ext->label); + if(ta->pwd_mode == 0) { + txt = lv_label_get_text(ta->label); } else { - txt = ext->pwd_tmp; + txt = ta->pwd_tmp; } return txt; @@ -907,12 +690,12 @@ const char * lv_textarea_get_text(const lv_obj_t * ta) * @param ta pointer to a text area object * @return pointer to the text */ -const char * lv_textarea_get_placeholder_text(lv_obj_t * ta) +const char * lv_textarea_get_placeholder_text(lv_obj_t * obj) { - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); - if(ext->placeholder_txt) return ext->placeholder_txt; + lv_textarea_t * ta = (lv_textarea_t *) obj; + if(ta->placeholder_txt) return ta->placeholder_txt; else return ""; } @@ -921,12 +704,12 @@ const char * lv_textarea_get_placeholder_text(lv_obj_t * ta) * @param ta pointer to a text area object * @return pointer to the label object */ -lv_obj_t * lv_textarea_get_label(const lv_obj_t * ta) +lv_obj_t * lv_textarea_get_label(const lv_obj_t * obj) { - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); - return ext->label; + lv_textarea_t * ta = (lv_textarea_t *) obj; + return ta->label; } /** @@ -934,25 +717,12 @@ lv_obj_t * lv_textarea_get_label(const lv_obj_t * ta) * @param ta pointer to a text area object * @return the cursor position */ -uint32_t lv_textarea_get_cursor_pos(const lv_obj_t * ta) +uint32_t lv_textarea_get_cursor_pos(const lv_obj_t * obj) { - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); - return ext->cursor.pos; -} - -/** - * Get whether the cursor is hidden or not - * @param ta pointer to a text area object - * @return true: the cursor is hidden - */ -bool lv_textarea_get_cursor_hidden(const lv_obj_t * ta) -{ - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); - - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); - return ext->cursor.hidden ? true : false; + lv_textarea_t * ta = (lv_textarea_t *) obj; + return ta->cursor.pos; } /** @@ -960,12 +730,12 @@ bool lv_textarea_get_cursor_hidden(const lv_obj_t * ta) * @param ta pointer to a text area object * @return true: enable click positions; false: disable */ -bool lv_textarea_get_cursor_click_pos(lv_obj_t * ta) +bool lv_textarea_get_cursor_click_pos(lv_obj_t * obj) { - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); - return ext->cursor.click_pos ? true : false; + lv_textarea_t * ta = (lv_textarea_t *) obj; + return ta->cursor.click_pos ? true : false; } /** @@ -973,12 +743,12 @@ bool lv_textarea_get_cursor_click_pos(lv_obj_t * ta) * @param ta pointer to a text area object * @return true: password mode is enabled, false: disabled */ -bool lv_textarea_get_pwd_mode(const lv_obj_t * ta) +bool lv_textarea_get_pwd_mode(const lv_obj_t * obj) { - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); - return ext->pwd_mode == 0 ? false : true; + lv_textarea_t * ta = (lv_textarea_t *) obj; + return ta->pwd_mode == 0 ? false : true; } /** @@ -986,12 +756,12 @@ bool lv_textarea_get_pwd_mode(const lv_obj_t * ta) * @param ta pointer to a text area object * @return true: one line configuration is enabled, false: disabled */ -bool lv_textarea_get_one_line(const lv_obj_t * ta) +bool lv_textarea_get_one_line(const lv_obj_t * obj) { - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); - return ext->one_line == 0 ? false : true; + lv_textarea_t * ta = (lv_textarea_t *) obj; + return ta->one_line == 0 ? false : true; } /** @@ -999,13 +769,13 @@ bool lv_textarea_get_one_line(const lv_obj_t * ta) * @param ta pointer to Text Area * @return list of accented characters. */ -const char * lv_textarea_get_accepted_chars(lv_obj_t * ta) +const char * lv_textarea_get_accepted_chars(lv_obj_t * obj) { - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); + lv_textarea_t * ta = (lv_textarea_t *) obj; - return ext->accepted_chars; + return ta->accepted_chars; } /** @@ -1013,12 +783,12 @@ const char * lv_textarea_get_accepted_chars(lv_obj_t * ta) * @param ta pointer to Text Area * @return the maximal number of characters to be add */ -uint32_t lv_textarea_get_max_length(lv_obj_t * ta) +uint32_t lv_textarea_get_max_length(lv_obj_t * obj) { - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); - return ext->max_length; + lv_textarea_t * ta = (lv_textarea_t *) obj; + return ta->max_length; } /** @@ -1026,15 +796,15 @@ uint32_t lv_textarea_get_max_length(lv_obj_t * ta) * @param ta Text area object * @return whether text is selected or not */ -bool lv_textarea_text_is_selected(const lv_obj_t * ta) +bool lv_textarea_text_is_selected(const lv_obj_t * obj) { - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); #if LV_LABEL_TEXT_SEL - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); + lv_textarea_t * ta = (lv_textarea_t *) obj; - if((lv_label_get_text_sel_start(ext->label) == LV_DRAW_LABEL_NO_TXT_SEL || - lv_label_get_text_sel_end(ext->label) == LV_DRAW_LABEL_NO_TXT_SEL)) { + if((lv_label_get_text_sel_start(ta->label) == LV_DRAW_LABEL_NO_TXT_SEL || + lv_label_get_text_sel_end(ta->label) == LV_DRAW_LABEL_NO_TXT_SEL)) { return true; } else { @@ -1051,13 +821,13 @@ bool lv_textarea_text_is_selected(const lv_obj_t * ta) * @param ta pointer to a text area object * @return true: selection mode is enabled, false: disabled */ -bool lv_textarea_get_text_sel_en(lv_obj_t * ta) +bool lv_textarea_get_text_sel_en(lv_obj_t * obj) { - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); #if LV_LABEL_TEXT_SEL - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); - return ext->text_sel_en; + lv_textarea_t * ta = (lv_textarea_t *) obj; + return ta->text_sel_en; #else (void)ta; /*Unused*/ return false; @@ -1069,26 +839,13 @@ bool lv_textarea_get_text_sel_en(lv_obj_t * ta) * @param ta pointer to Text area * @return show time in milliseconds. 0: hide immediately. */ -uint16_t lv_textarea_get_pwd_show_time(lv_obj_t * ta) +uint16_t lv_textarea_get_pwd_show_time(lv_obj_t * obj) { - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); + lv_textarea_t * ta = (lv_textarea_t *) obj; - return ext->pwd_show_time; -} - -/** - * Set cursor blink animation time - * @param ta pointer to Text area - * @return time blink period. 0: disable blinking - */ -uint16_t lv_textarea_get_cursor_blink_time(lv_obj_t * ta) -{ - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); - - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); - return ext->cursor.blink_time; + return ta->pwd_show_time; } /*===================== @@ -1099,17 +856,17 @@ uint16_t lv_textarea_get_cursor_blink_time(lv_obj_t * ta) * Clear the selection on the text area. * @param ta Text area object */ -void lv_textarea_clear_selection(lv_obj_t * ta) +void lv_textarea_clear_selection(lv_obj_t * obj) { - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); #if LV_LABEL_TEXT_SEL - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); + lv_textarea_t * ta = (lv_textarea_t *) obj; - if(lv_label_get_text_sel_start(ext->label) != LV_DRAW_LABEL_NO_TXT_SEL || - lv_label_get_text_sel_end(ext->label) != LV_DRAW_LABEL_NO_TXT_SEL) { - lv_label_set_text_sel_start(ext->label, LV_DRAW_LABEL_NO_TXT_SEL); - lv_label_set_text_sel_end(ext->label, LV_DRAW_LABEL_NO_TXT_SEL); + if(lv_label_get_text_sel_start(ta->label) != LV_DRAW_LABEL_NO_TXT_SEL || + lv_label_get_text_sel_end(ta->label) != LV_DRAW_LABEL_NO_TXT_SEL) { + lv_label_set_text_sel_start(ta->label, LV_DRAW_LABEL_NO_TXT_SEL); + lv_label_set_text_sel_end(ta->label, LV_DRAW_LABEL_NO_TXT_SEL); } #else (void)ta; /*Unused*/ @@ -1120,27 +877,27 @@ void lv_textarea_clear_selection(lv_obj_t * ta) * Move the cursor one character right * @param ta pointer to a text area object */ -void lv_textarea_cursor_right(lv_obj_t * ta) +void lv_textarea_cursor_right(lv_obj_t * obj) { - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - uint32_t cp = lv_textarea_get_cursor_pos(ta); + uint32_t cp = lv_textarea_get_cursor_pos(obj); cp++; - lv_textarea_set_cursor_pos(ta, cp); + lv_textarea_set_cursor_pos(obj, cp); } /** * Move the cursor one character left * @param ta pointer to a text area object */ -void lv_textarea_cursor_left(lv_obj_t * ta) +void lv_textarea_cursor_left(lv_obj_t * obj) { - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - uint32_t cp = lv_textarea_get_cursor_pos(ta); + uint32_t cp = lv_textarea_get_cursor_pos(obj); if(cp > 0) { cp--; - lv_textarea_set_cursor_pos(ta, cp); + lv_textarea_set_cursor_pos(obj, cp); } } @@ -1148,32 +905,32 @@ void lv_textarea_cursor_left(lv_obj_t * ta) * Move the cursor one line down * @param ta pointer to a text area object */ -void lv_textarea_cursor_down(lv_obj_t * ta) +void lv_textarea_cursor_down(lv_obj_t * obj) { - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); + lv_textarea_t * ta = (lv_textarea_t *) obj; lv_point_t pos; /*Get the position of the current letter*/ - lv_label_get_letter_pos(ext->label, lv_textarea_get_cursor_pos(ta), &pos); + lv_label_get_letter_pos(ta->label, lv_textarea_get_cursor_pos(obj), &pos); /*Increment the y with one line and keep the valid x*/ - lv_coord_t line_space = lv_obj_get_style_text_line_space(ta, LV_TEXTAREA_PART_MAIN); - const lv_font_t * font = lv_obj_get_style_text_font(ta, LV_TEXTAREA_PART_MAIN); + lv_coord_t line_space = lv_obj_get_style_text_line_space(obj, LV_PART_MAIN); + const lv_font_t * font = lv_obj_get_style_text_font(obj, LV_PART_MAIN); lv_coord_t font_h = lv_font_get_line_height(font); pos.y += font_h + line_space + 1; - pos.x = ext->cursor.valid_x; + pos.x = ta->cursor.valid_x; /*Do not go below the last line*/ - if(pos.y < lv_obj_get_height(ext->label)) { + if(pos.y < lv_obj_get_height(ta->label)) { /*Get the letter index on the new cursor position and set it*/ - uint32_t new_cur_pos = lv_label_get_letter_on(ext->label, &pos); + uint32_t new_cur_pos = lv_label_get_letter_on(ta->label, &pos); - lv_coord_t cur_valid_x_tmp = ext->cursor.valid_x; /*Cursor position set overwrites the valid position */ - lv_textarea_set_cursor_pos(ta, new_cur_pos); - ext->cursor.valid_x = cur_valid_x_tmp; + lv_coord_t cur_valid_x_tmp = ta->cursor.valid_x; /*Cursor position set overwrites the valid position */ + lv_textarea_set_cursor_pos(obj, new_cur_pos); + ta->cursor.valid_x = cur_valid_x_tmp; } } @@ -1181,34 +938,118 @@ void lv_textarea_cursor_down(lv_obj_t * ta) * Move the cursor one line up * @param ta pointer to a text area object */ -void lv_textarea_cursor_up(lv_obj_t * ta) +void lv_textarea_cursor_up(lv_obj_t * obj) { - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); + LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); + lv_textarea_t * ta = (lv_textarea_t *) obj; lv_point_t pos; /*Get the position of the current letter*/ - lv_label_get_letter_pos(ext->label, lv_textarea_get_cursor_pos(ta), &pos); + lv_label_get_letter_pos(ta->label, lv_textarea_get_cursor_pos(obj), &pos); /*Decrement the y with one line and keep the valid x*/ - lv_coord_t line_space = lv_obj_get_style_text_line_space(ta, LV_TEXTAREA_PART_MAIN); - const lv_font_t * font = lv_obj_get_style_text_font(ta, LV_TEXTAREA_PART_MAIN); + lv_coord_t line_space = lv_obj_get_style_text_line_space(obj, LV_PART_MAIN); + const lv_font_t * font = lv_obj_get_style_text_font(obj, LV_PART_MAIN); lv_coord_t font_h = lv_font_get_line_height(font); pos.y -= font_h + line_space - 1; - pos.x = ext->cursor.valid_x; + pos.x = ta->cursor.valid_x; /*Get the letter index on the new cursor position and set it*/ - uint32_t new_cur_pos = lv_label_get_letter_on(ext->label, &pos); - lv_coord_t cur_valid_x_tmp = ext->cursor.valid_x; /*Cursor position set overwrites the valid position */ - lv_textarea_set_cursor_pos(ta, new_cur_pos); - ext->cursor.valid_x = cur_valid_x_tmp; + uint32_t new_cur_pos = lv_label_get_letter_on(ta->label, &pos); + lv_coord_t cur_valid_x_tmp = ta->cursor.valid_x; /*Cursor position set overwrites the valid position */ + lv_textarea_set_cursor_pos(obj, new_cur_pos); + ta->cursor.valid_x = cur_valid_x_tmp; } /********************** * STATIC FUNCTIONS **********************/ +static void lv_textarea_constructor(lv_obj_t * obj, lv_obj_t * parent, const lv_obj_t * copy) +{ + LV_LOG_TRACE("text area create started"); + lv_obj_construct_base(obj, parent, copy); + + lv_textarea_t * ta = (lv_textarea_t *) obj; + + ta->pwd_mode = 0; + ta->pwd_tmp = NULL; + ta->pwd_show_time = LV_TEXTAREA_DEF_PWD_SHOW_TIME; + ta->accepted_chars = NULL; + ta->max_length = 0; + ta->cursor.show = 1; + ta->cursor.pos = 0; + ta->cursor.click_pos = 1; + ta->cursor.valid_x = 0; + ta->one_line = 0; + #if LV_LABEL_TEXT_SEL + ta->text_sel_en = 0; + #endif + ta->label = NULL; + ta->placeholder_txt = NULL; + + #if LV_USE_ANIMATION == 0 + ta->pwd_show_time = 0; + ta->cursor.blink_time = 0; + #endif + + /*Init the new text area object*/ + if(copy == NULL) { + ta->label = lv_label_create(obj, NULL); + lv_label_set_long_mode(ta->label, LV_LABEL_LONG_WRAP); + lv_label_set_text(ta->label, ""); + lv_obj_set_size(obj, LV_TEXTAREA_DEF_WIDTH, LV_TEXTAREA_DEF_HEIGHT); + } + /*Copy an existing object*/ + else { + + lv_textarea_t * copy_ta = (lv_textarea_t *) copy; + ta->label = lv_label_create(obj, copy_ta->label); + ta->pwd_mode = copy_ta->pwd_mode; + ta->accepted_chars = copy_ta->accepted_chars; + ta->max_length = copy_ta->max_length; + ta->cursor.pos = copy_ta->cursor.pos; + ta->cursor.valid_x = copy_ta->cursor.valid_x; + + if(ta->pwd_mode != 0) pwd_char_hider(obj); + + if(copy_ta->placeholder_txt) { + lv_textarea_set_placeholder_text(obj, copy_ta->placeholder_txt); + } + + if(copy_ta->pwd_tmp) { + uint32_t len = lv_mem_get_size(copy_ta->pwd_tmp); + ta->pwd_tmp = lv_mem_alloc(len); + LV_ASSERT_MEM(ta->pwd_tmp); + if(ta->pwd_tmp == NULL) return; + + lv_memcpy(ta->pwd_tmp, copy_ta->pwd_tmp, len); + } + + if(copy_ta->one_line) lv_textarea_set_one_line(obj, true); + } + + start_cursor_blink(obj); + + LV_LOG_INFO("text area created"); +} + +static void lv_textarea_destructor(lv_obj_t * obj) +{ +// else if(sign == LV_SIGNAL_CLEANUP) { +// if(ta->pwd_tmp != NULL) lv_mem_free(ta->pwd_tmp); +// if(ta->placeholder_txt != NULL) lv_mem_free(ta->placeholder_txt); +// +// ta->pwd_tmp = NULL; +// ta->placeholder_txt = NULL; +// +// _lv_obj_reset_style_list_no_refr(obj, LV_PART_MARKER); +// _lv_obj_reset_style_list_no_refr(obj, LV_TEXTAREA_PART_PLACEHOLDER); +// +// /* (The created label will be deleted automatically) */ +} + /** * Handle the drawing related tasks of the text areas * @param ta pointer to an object @@ -1219,21 +1060,21 @@ void lv_textarea_cursor_up(lv_obj_t * ta) * LV_DRAW_DRAW_POST: drawing after every children are drawn * @param return an element of `lv_draw_res_t` */ -static lv_draw_res_t lv_textarea_draw(lv_obj_t * ta, const lv_area_t * clip_area, lv_draw_mode_t mode) +static lv_draw_res_t lv_textarea_draw(lv_obj_t * obj, const lv_area_t * clip_area, lv_draw_mode_t mode) { - if(mode == LV_DRAW_COVER_CHK) { + if(mode == LV_DRAW_MODE_COVER_CHECK) { /*Return false if the object is not covers the mask_p area*/ - return ancestor_draw(ta, clip_area, mode); + return lv_obj.draw_cb(obj, clip_area, mode); } - else if(mode == LV_DRAW_DRAW_MAIN) { + else if(mode == LV_DRAW_MODE_MAIN_DRAW) { /*Draw the object*/ - ancestor_draw(ta, clip_area, mode); - draw_placeholder(ta, clip_area); + lv_obj.draw_cb(obj, clip_area, mode); + draw_placeholder(obj, clip_area); } - else if(mode == LV_DRAW_DRAW_POST) { - ancestor_draw(ta, clip_area, mode); - draw_cursor(ta, clip_area); + else if(mode == LV_DRAW_MODE_POST_DRAW) { + lv_obj.draw_cb(obj, clip_area, mode); + draw_cursor(obj, clip_area); } return LV_DRAW_RES_OK; } @@ -1245,66 +1086,47 @@ static lv_draw_res_t lv_textarea_draw(lv_obj_t * ta, const lv_area_t * clip_area * @param param pointer to a signal specific variable * @return LV_RES_OK: the object is not deleted in the function; LV_RES_INV: the object is deleted */ -static lv_res_t lv_textarea_signal(lv_obj_t * ta, lv_signal_t sign, void * param) +static lv_res_t lv_textarea_signal(lv_obj_t * obj, lv_signal_t sign, void * param) { lv_res_t res; /* Include the ancient signal function */ - res = ancestor_signal(ta, sign, param); + res = lv_obj.signal_cb(obj, sign, param); if(res != LV_RES_OK) return res; - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); + lv_textarea_t * ta = (lv_textarea_t *) obj; - if(sign == LV_SIGNAL_GET_TYPE) { - return _lv_obj_handle_get_type_signal(param, LV_OBJX_NAME); - } - else if(sign == LV_SIGNAL_GET_STYLE) { - lv_get_style_info_t * info = param; - info->result = lv_textarea_get_style(ta, info->part); - if(info->result != NULL) return LV_RES_OK; - } - else if(sign == LV_SIGNAL_CLEANUP) { - if(ext->pwd_tmp != NULL) lv_mem_free(ext->pwd_tmp); - if(ext->placeholder_txt != NULL) lv_mem_free(ext->placeholder_txt); - - ext->pwd_tmp = NULL; - ext->placeholder_txt = NULL; - - _lv_obj_reset_style_list_no_refr(ta, LV_TEXTAREA_PART_CURSOR); - _lv_obj_reset_style_list_no_refr(ta, LV_TEXTAREA_PART_PLACEHOLDER); - - /* (The created label will be deleted automatically) */ - } - else if(sign == LV_SIGNAL_STYLE_CHG) { - if(ext->label) { - if(ext->one_line) { - lv_coord_t top = lv_obj_get_style_pad_top(ta, LV_TEXTAREA_PART_MAIN); - lv_coord_t bottom = lv_obj_get_style_pad_bottom(ta, LV_TEXTAREA_PART_MAIN); - const lv_font_t * font = lv_obj_get_style_text_font(ta, LV_TEXTAREA_PART_MAIN); + if(sign == LV_SIGNAL_STYLE_CHG) { + if(ta->label) { + if(ta->one_line) { + lv_coord_t top = lv_obj_get_style_pad_top(obj, LV_PART_MAIN); + lv_coord_t bottom = lv_obj_get_style_pad_bottom(obj, LV_PART_MAIN); + const lv_font_t * font = lv_obj_get_style_text_font(obj, LV_PART_MAIN); /*In one line mode refresh the Text Area height because 'vpad' can modify it*/ lv_coord_t font_h = lv_font_get_line_height(font); - lv_obj_set_height(ext->label, font_h); - lv_obj_set_height(ta, font_h + top + bottom); + lv_obj_set_height(ta->label, font_h); + lv_obj_set_height(obj, font_h + top + bottom); } else { /*In not one line mode refresh the Label width because 'hpad' can modify it*/ - lv_obj_set_width(ext->label, lv_obj_get_width_fit(ta)); - lv_obj_set_pos(ext->label, 0, 0); /*Be sure the Label is in the correct position*/ + lv_obj_set_width(ta->label, lv_obj_get_width_fit(obj)); + lv_obj_set_pos(ta->label, 0, 0); /*Be sure the Label is in the correct position*/ } - lv_label_set_text(ext->label, NULL); - refr_cursor_area(ta); + lv_label_set_text(ta->label, NULL); + refr_cursor_area(obj); + start_cursor_blink(obj); } } else if(sign == LV_SIGNAL_COORD_CHG) { /*Set the label width according to the text area width*/ - if(ext->label) { - if(lv_obj_get_width(ta) != lv_area_get_width(param) || lv_obj_get_height(ta) != lv_area_get_height(param)) { - lv_obj_set_width(ext->label, lv_obj_get_width_fit(ta)); - lv_obj_set_pos(ext->label, 0, 0); - lv_label_set_text(ext->label, NULL); /*Refresh the label*/ + if(ta->label) { + if(lv_obj_get_width(obj) != lv_area_get_width(param) || lv_obj_get_height(obj) != lv_area_get_height(param)) { + lv_obj_set_width(ta->label, lv_obj_get_width_fit(obj)); + lv_obj_set_pos(ta->label, 0, 0); + lv_label_set_text(ta->label, NULL); /*Refresh the label*/ - refr_cursor_area(ta); + refr_cursor_area(obj); } } } @@ -1312,25 +1134,25 @@ static lv_res_t lv_textarea_signal(lv_obj_t * ta, lv_signal_t sign, void * param #if LV_USE_GROUP uint32_t c = *((uint32_t *)param); /*uint32_t because can be UTF-8*/ if(c == LV_KEY_RIGHT) - lv_textarea_cursor_right(ta); + lv_textarea_cursor_right(obj); else if(c == LV_KEY_LEFT) - lv_textarea_cursor_left(ta); + lv_textarea_cursor_left(obj); else if(c == LV_KEY_UP) - lv_textarea_cursor_up(ta); + lv_textarea_cursor_up(obj); else if(c == LV_KEY_DOWN) - lv_textarea_cursor_down(ta); + lv_textarea_cursor_down(obj); else if(c == LV_KEY_BACKSPACE) - lv_textarea_del_char(ta); + lv_textarea_del_char(obj); else if(c == LV_KEY_DEL) - lv_textarea_del_char_forward(ta); + lv_textarea_del_char_forward(obj); else if(c == LV_KEY_HOME) - lv_textarea_set_cursor_pos(ta, 0); + lv_textarea_set_cursor_pos(obj, 0); else if(c == LV_KEY_END) - lv_textarea_set_cursor_pos(ta, LV_TEXTAREA_CURSOR_LAST); - else if(c == LV_KEY_ENTER && lv_textarea_get_one_line(ta)) - lv_event_send(ta, LV_EVENT_APPLY, NULL); + lv_textarea_set_cursor_pos(obj, LV_TEXTAREA_CURSOR_LAST); + else if(c == LV_KEY_ENTER && lv_textarea_get_one_line(obj)) + lv_event_send(obj, LV_EVENT_APPLY, NULL); else { - lv_textarea_add_char(ta, c); + lv_textarea_add_char(obj, c); } #endif } @@ -1342,41 +1164,11 @@ static lv_res_t lv_textarea_signal(lv_obj_t * ta, lv_signal_t sign, void * param } else if(sign == LV_SIGNAL_PRESSED || sign == LV_SIGNAL_PRESSING || sign == LV_SIGNAL_PRESS_LOST || sign == LV_SIGNAL_RELEASED) { - update_cursor_position_on_click(ta, sign, (lv_indev_t *)param); + update_cursor_position_on_click(obj, sign, (lv_indev_t *)param); } return res; } -/** - * Get the style descriptor of a part of the object - * @param page pointer the object - * @param part the part from `lv_textarea_part_t`. (LV_TEXTAREA_PART_...) - * @return pointer to the style descriptor of the specified part - */ -static lv_style_list_t * lv_textarea_get_style(lv_obj_t * ta, uint8_t part) -{ - LV_ASSERT_OBJ(ta, LV_OBJX_NAME); - - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); - lv_style_list_t * style_dsc_p; - - switch(part) { - case LV_TEXTAREA_PART_MAIN: - style_dsc_p = &ta->style_list; - break; - case LV_TEXTAREA_PART_CURSOR: - style_dsc_p = &ext->cursor.style; - break; - case LV_TEXTAREA_PART_PLACEHOLDER: - style_dsc_p = &ext->style_placeholder; - break; - default: - style_dsc_p = NULL; - } - - return style_dsc_p; -} - #if LV_USE_ANIMATION /** @@ -1384,20 +1176,18 @@ static lv_style_list_t * lv_textarea_get_style(lv_obj_t * ta, uint8_t part) * @param ta pointer to a text area * @param hide 1: hide the cursor, 0: show it */ -static void cursor_blink_anim(lv_obj_t * ta, lv_anim_value_t show) +static void cursor_blink_anim_cb(lv_obj_t * obj, lv_anim_value_t show) { - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); - if(show != ext->cursor.state) { - ext->cursor.state = show == 0 ? 0 : 1; - if(ext->cursor.hidden == 0) { - lv_area_t area_tmp; - lv_area_copy(&area_tmp, &ext->cursor.area); - area_tmp.x1 += ext->label->coords.x1; - area_tmp.y1 += ext->label->coords.y1; - area_tmp.x2 += ext->label->coords.x1; - area_tmp.y2 += ext->label->coords.y1; - lv_obj_invalidate_area(ta, &area_tmp); - } + lv_textarea_t * ta = (lv_textarea_t *) obj; + if(show != ta->cursor.show) { + ta->cursor.show = show == 0 ? 0 : 1; + lv_area_t area_tmp; + lv_area_copy(&area_tmp, &ta->cursor.area); + area_tmp.x1 += ta->label->coords.x1; + area_tmp.y1 += ta->label->coords.y1; + area_tmp.x2 += ta->label->coords.x1; + area_tmp.y2 += ta->label->coords.y1; + lv_obj_invalidate_area(obj, &area_tmp); } } @@ -1408,10 +1198,10 @@ static void cursor_blink_anim(lv_obj_t * ta, lv_anim_value_t show) * @param ta unused * @param x unused */ -static void pwd_char_hider_anim(lv_obj_t * ta, lv_anim_value_t x) +static void pwd_char_hider_anim(lv_obj_t * obj, lv_anim_value_t x) { - (void)ta; - (void)x; + LV_UNUSED(obj); + LV_UNUSED(x); } /** @@ -1420,8 +1210,8 @@ static void pwd_char_hider_anim(lv_obj_t * ta, lv_anim_value_t x) */ static void pwd_char_hider_anim_ready(lv_anim_t * a) { - lv_obj_t * ta = a->var; - pwd_char_hider(ta); + lv_obj_t * obj = a->var; + pwd_char_hider(obj); } #endif @@ -1429,16 +1219,16 @@ static void pwd_char_hider_anim_ready(lv_anim_t * a) * Hide all characters (convert them to '*') * @param ta: pointer to text area object */ -static void pwd_char_hider(lv_obj_t * ta) +static void pwd_char_hider(lv_obj_t * obj) { - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); - if(ext->pwd_mode != 0) { - char * txt = lv_label_get_text(ext->label); + lv_textarea_t * ta = (lv_textarea_t *) obj; + if(ta->pwd_mode != 0) { + char * txt = lv_label_get_text(ta->label); int32_t enc_len = _lv_txt_get_encoded_length(txt); if(enc_len == 0) return; /*If the textarea's font has "bullet" character use it else fallback to "*"*/ - const lv_font_t * font = lv_obj_get_style_text_font(ta, LV_TEXTAREA_PART_MAIN); + const lv_font_t * font = lv_obj_get_style_text_font(obj, LV_PART_MAIN); lv_font_glyph_dsc_t g; bool has_bullet; has_bullet = lv_font_get_glyph_dsc(font, &g, LV_TEXTAREA_PWD_BULLET_UNICODE, 0); @@ -1455,9 +1245,9 @@ static void pwd_char_hider(lv_obj_t * ta) txt_tmp[i * bullet_len] = '\0'; - lv_label_set_text(ext->label, txt_tmp); + lv_label_set_text(ta->label, txt_tmp); lv_mem_buf_release(txt_tmp); - refr_cursor_area(ta); + refr_cursor_area(obj); } } @@ -1467,24 +1257,24 @@ static void pwd_char_hider(lv_obj_t * ta) * @param c an unicode character * @return true: accepted; false: rejected */ -static bool char_is_accepted(lv_obj_t * ta, uint32_t c) +static bool char_is_accepted(lv_obj_t * obj, uint32_t c) { - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); + lv_textarea_t * ta = (lv_textarea_t *) obj; /*If no restriction accept it*/ - if(ext->accepted_chars == NULL && ext->max_length == 0) return true; + if(ta->accepted_chars == NULL && ta->max_length == 0) return true; /*Too many characters?*/ - if(ext->max_length > 0 && _lv_txt_get_encoded_length(lv_textarea_get_text(ta)) >= ext->max_length) { + if(ta->max_length > 0 && _lv_txt_get_encoded_length(lv_textarea_get_text(obj)) >= ta->max_length) { return false; } /*Accepted character?*/ - if(ext->accepted_chars) { + if(ta->accepted_chars) { uint32_t i = 0; - while(ext->accepted_chars[i] != '\0') { - uint32_t a = _lv_txt_encoded_next(ext->accepted_chars, &i); + while(ta->accepted_chars[i] != '\0') { + uint32_t a = _lv_txt_encoded_next(ta->accepted_chars, &i); if(a == c) return true; /*Accepted*/ } @@ -1495,16 +1285,42 @@ static bool char_is_accepted(lv_obj_t * ta, uint32_t c) } } - -static void refr_cursor_area(lv_obj_t * ta) +static void start_cursor_blink(lv_obj_t * obj) { - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); +#if LV_USE_ANIMATION + lv_textarea_t * ta = (lv_textarea_t *) obj; + uint32_t blink_time = lv_obj_get_style_anim_time(obj, LV_PART_MARKER); + if(blink_time == 0) { + lv_anim_del(obj, (lv_anim_exec_xcb_t)cursor_blink_anim_cb); + ta->cursor.show = 1; + } else { + lv_anim_path_t path; + lv_anim_path_init(&path); + lv_anim_path_set_cb(&path, lv_anim_path_step); - const lv_font_t * font = lv_obj_get_style_text_font(ta, LV_TEXTAREA_PART_MAIN); - lv_coord_t line_space = lv_obj_get_style_text_line_space(ta, LV_TEXTAREA_PART_MAIN); + lv_anim_t a; + lv_anim_init(&a); + lv_anim_set_var(&a, ta); + lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)cursor_blink_anim_cb); + lv_anim_set_time(&a, blink_time); + lv_anim_set_playback_time(&a, blink_time); + lv_anim_set_values(&a, 1, 0); + lv_anim_set_path(&a, &path); + lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE); + lv_anim_start(&a); + } +#endif +} - uint32_t cur_pos = lv_textarea_get_cursor_pos(ta); - const char * txt = lv_label_get_text(ext->label); +static void refr_cursor_area(lv_obj_t * obj) +{ + lv_textarea_t * ta = (lv_textarea_t *) obj; + + const lv_font_t * font = lv_obj_get_style_text_font(obj, LV_PART_MAIN); + lv_coord_t line_space = lv_obj_get_style_text_line_space(obj, LV_PART_MAIN); + + uint32_t cur_pos = lv_textarea_get_cursor_pos(obj); + const char * txt = lv_label_get_text(ta->label); uint32_t byte_pos; byte_pos = _lv_txt_encoded_get_byte_id(txt, cur_pos); @@ -1524,11 +1340,11 @@ static void refr_cursor_area(lv_obj_t * ta) } lv_point_t letter_pos; - lv_label_get_letter_pos(ext->label, cur_pos, &letter_pos); + lv_label_get_letter_pos(ta->label, cur_pos, &letter_pos); /*If the cursor is out of the text (most right) draw it to the next line*/ - if(letter_pos.x + ext->label->coords.x1 + letter_w > ext->label->coords.x2 && ext->one_line == 0 && - lv_label_get_align(ext->label) != LV_TEXT_ALIGN_RIGHT) { + if(letter_pos.x + ta->label->coords.x1 + letter_w > ta->label->coords.x2 && ta->one_line == 0 && + lv_obj_get_style_text_align(ta->label, LV_PART_MAIN) != LV_TEXT_ALIGN_RIGHT) { letter_pos.x = 0; letter_pos.y += letter_h + line_space; @@ -1546,13 +1362,13 @@ static void refr_cursor_area(lv_obj_t * ta) } /*Save the byte position. It is required to draw `LV_CURSOR_BLOCK`*/ - ext->cursor.txt_byte_pos = byte_pos; + ta->cursor.txt_byte_pos = byte_pos; /*Calculate the cursor according to its type*/ - lv_coord_t top = lv_obj_get_style_pad_top(ta, LV_TEXTAREA_PART_CURSOR); - lv_coord_t bottom = lv_obj_get_style_pad_bottom(ta, LV_TEXTAREA_PART_CURSOR); - lv_coord_t left = lv_obj_get_style_pad_left(ta, LV_TEXTAREA_PART_CURSOR); - lv_coord_t right = lv_obj_get_style_pad_right(ta, LV_TEXTAREA_PART_CURSOR); + lv_coord_t top = lv_obj_get_style_pad_top(obj, LV_PART_MARKER); + lv_coord_t bottom = lv_obj_get_style_pad_bottom(obj, LV_PART_MARKER); + lv_coord_t left = lv_obj_get_style_pad_left(obj, LV_PART_MARKER); + lv_coord_t right = lv_obj_get_style_pad_right(obj, LV_PART_MARKER); lv_area_t cur_area; cur_area.x1 = letter_pos.x - left; @@ -1562,30 +1378,29 @@ static void refr_cursor_area(lv_obj_t * ta) /*Save the new area*/ lv_area_t area_tmp; - lv_area_copy(&area_tmp, &ext->cursor.area); - area_tmp.x1 += ext->label->coords.x1; - area_tmp.y1 += ext->label->coords.y1; - area_tmp.x2 += ext->label->coords.x1; - area_tmp.y2 += ext->label->coords.y1; - lv_obj_invalidate_area(ta, &area_tmp); + lv_area_copy(&area_tmp, &ta->cursor.area); + area_tmp.x1 += ta->label->coords.x1; + area_tmp.y1 += ta->label->coords.y1; + area_tmp.x2 += ta->label->coords.x1; + area_tmp.y2 += ta->label->coords.y1; + lv_obj_invalidate_area(obj, &area_tmp); - lv_area_copy(&ext->cursor.area, &cur_area); + lv_area_copy(&ta->cursor.area, &cur_area); - lv_area_copy(&area_tmp, &ext->cursor.area); - area_tmp.x1 += ext->label->coords.x1; - area_tmp.y1 += ext->label->coords.y1; - area_tmp.x2 += ext->label->coords.x1; - area_tmp.y2 += ext->label->coords.y1; - lv_obj_invalidate_area(ta, &area_tmp); + lv_area_copy(&area_tmp, &ta->cursor.area); + area_tmp.x1 += ta->label->coords.x1; + area_tmp.y1 += ta->label->coords.y1; + area_tmp.x2 += ta->label->coords.x1; + area_tmp.y2 += ta->label->coords.y1; + lv_obj_invalidate_area(obj, &area_tmp); } -static void update_cursor_position_on_click(lv_obj_t * ta, lv_signal_t sign, lv_indev_t * click_source) +static void update_cursor_position_on_click(lv_obj_t * obj, lv_signal_t sign, lv_indev_t * click_source) { if(click_source == NULL) return; - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); - if(ext->cursor.click_pos == 0) return; - if(ext->cursor.hidden) return; + lv_textarea_t * ta = (lv_textarea_t *) obj; + if(ta->cursor.click_pos == 0) return; if(lv_indev_get_type(click_source) == LV_INDEV_TYPE_KEYPAD || lv_indev_get_type(click_source) == LV_INDEV_TYPE_ENCODER) { @@ -1593,7 +1408,7 @@ static void update_cursor_position_on_click(lv_obj_t * ta, lv_signal_t sign, lv_ } lv_area_t label_coords; - lv_obj_get_coords(ext->label, &label_coords); + lv_obj_get_coords(ta->label, &label_coords); lv_point_t point_act, vect_act; lv_indev_get_point(click_source, &point_act); @@ -1604,12 +1419,12 @@ static void update_cursor_position_on_click(lv_obj_t * ta, lv_signal_t sign, lv_ rel_pos.x = point_act.x - label_coords.x1; rel_pos.y = point_act.y - label_coords.y1; - lv_coord_t label_width = lv_obj_get_width(ext->label); + lv_coord_t label_width = lv_obj_get_width(ta->label); uint16_t char_id_at_click; #if LV_LABEL_TEXT_SEL - lv_label_ext_t * ext_label = lv_obj_get_ext_attr(ext->label); + lv_label_t * label_data = (lv_label_t *) ta->label; bool click_outside_label; /*Check if the click happened on the left side of the area outside the label*/ if(rel_pos.x < 0) { @@ -1622,58 +1437,58 @@ static void update_cursor_position_on_click(lv_obj_t * ta, lv_signal_t sign, lv_ click_outside_label = true; } else { - char_id_at_click = lv_label_get_letter_on(ext->label, &rel_pos); - click_outside_label = !lv_label_is_char_under_pos(ext->label, &rel_pos); + char_id_at_click = lv_label_get_letter_on(ta->label, &rel_pos); + click_outside_label = !lv_label_is_char_under_pos(ta->label, &rel_pos); } - if(ext->text_sel_en) { - if(!ext->text_sel_in_prog && !click_outside_label && sign == LV_SIGNAL_PRESSED) { + if(ta->text_sel_en) { + if(!ta->text_sel_in_prog && !click_outside_label && sign == LV_SIGNAL_PRESSED) { /*Input device just went down. Store the selection start position*/ - ext->sel_start = char_id_at_click; - ext->sel_end = LV_LABEL_TEXT_SEL_OFF; - ext->text_sel_in_prog = 1; - lv_obj_add_flag(ta, LV_OBJ_FLAG_SCROLL_FREEZE); + ta->sel_start = char_id_at_click; + ta->sel_end = LV_LABEL_TEXT_SEL_OFF; + ta->text_sel_in_prog = 1; + lv_obj_clear_flag(obj, LV_OBJ_FLAG_SCROLL_CHAIN); } - else if(ext->text_sel_in_prog && sign == LV_SIGNAL_PRESSING) { + else if(ta->text_sel_in_prog && sign == LV_SIGNAL_PRESSING) { /*Input device may be moving. Store the end position */ - ext->sel_end = char_id_at_click; + ta->sel_end = char_id_at_click; } - else if(ext->text_sel_in_prog && (sign == LV_SIGNAL_PRESS_LOST || sign == LV_SIGNAL_RELEASED)) { + else if(ta->text_sel_in_prog && (sign == LV_SIGNAL_PRESS_LOST || sign == LV_SIGNAL_RELEASED)) { /*Input device is released. Check if anything was selected.*/ - lv_obj_clear_flag(ta, LV_OBJ_FLAG_SCROLL_FREEZE); + lv_obj_add_flag(obj, LV_OBJ_FLAG_SCROLL_CHAIN); } } - if(ext->text_sel_in_prog || sign == LV_SIGNAL_PRESSED) lv_textarea_set_cursor_pos(ta, char_id_at_click); + if(ta->text_sel_in_prog || sign == LV_SIGNAL_PRESSED) lv_textarea_set_cursor_pos(obj, char_id_at_click); - if(ext->text_sel_in_prog) { + if(ta->text_sel_in_prog) { /*If the selected area has changed then update the real values and*/ /*Invalidate the text area.*/ - if(ext->sel_start > ext->sel_end) { - if(ext_label->sel_start != ext->sel_end || ext_label->sel_end != ext->sel_start) { - ext_label->sel_start = ext->sel_end; - ext_label->sel_end = ext->sel_start; - lv_obj_invalidate(ta); + if(ta->sel_start > ta->sel_end) { + if(label_data->sel_start != ta->sel_end || label_data->sel_end != ta->sel_start) { + label_data->sel_start = ta->sel_end; + label_data->sel_end = ta->sel_start; + lv_obj_invalidate(obj); } } - else if(ext->sel_start < ext->sel_end) { - if(ext_label->sel_start != ext->sel_start || ext_label->sel_end != ext->sel_end) { - ext_label->sel_start = ext->sel_start; - ext_label->sel_end = ext->sel_end; - lv_obj_invalidate(ta); + else if(ta->sel_start < ta->sel_end) { + if(label_data->sel_start != ta->sel_start || label_data->sel_end != ta->sel_end) { + label_data->sel_start = ta->sel_start; + label_data->sel_end = ta->sel_end; + lv_obj_invalidate(obj); } } else { - if(ext_label->sel_start != LV_DRAW_LABEL_NO_TXT_SEL || ext_label->sel_end != LV_DRAW_LABEL_NO_TXT_SEL) { - ext_label->sel_start = LV_DRAW_LABEL_NO_TXT_SEL; - ext_label->sel_end = LV_DRAW_LABEL_NO_TXT_SEL; - lv_obj_invalidate(ta); + if(label_data->sel_start != LV_DRAW_LABEL_NO_TXT_SEL || label_data->sel_end != LV_DRAW_LABEL_NO_TXT_SEL) { + label_data->sel_start = LV_DRAW_LABEL_NO_TXT_SEL; + label_data->sel_end = LV_DRAW_LABEL_NO_TXT_SEL; + lv_obj_invalidate(obj); } } /*Finish selection if necessary */ if(sign == LV_SIGNAL_PRESS_LOST || sign == LV_SIGNAL_RELEASED) { - ext->text_sel_in_prog = 0; + ta->text_sel_in_prog = 0; } } #else @@ -1686,23 +1501,23 @@ static void update_cursor_position_on_click(lv_obj_t * ta, lv_signal_t sign, lv_ char_id_at_click = LV_TEXTAREA_CURSOR_LAST; } else { - char_id_at_click = lv_label_get_letter_on(ext->label, &rel_pos); + char_id_at_click = lv_label_get_letter_on(ta->label, &rel_pos); } - if(sign == LV_SIGNAL_PRESSED) lv_textarea_set_cursor_pos(ta, char_id_at_click); + if(sign == LV_SIGNAL_PRESSED) lv_textarea_set_cursor_pos(obj, char_id_at_click); #endif } -static lv_res_t insert_handler(lv_obj_t * ta, const char * txt) +static lv_res_t insert_handler(lv_obj_t * obj, const char * txt) { ta_insert_replace = NULL; - lv_event_send(ta, LV_EVENT_INSERT, txt); + lv_event_send(obj, LV_EVENT_INSERT, txt); if(ta_insert_replace) { if(ta_insert_replace[0] == '\0') return LV_RES_INV; /*Drop this text*/ /*Add the replaced text directly it's different from the original*/ if(strcmp(ta_insert_replace, txt)) { - lv_textarea_add_text(ta, ta_insert_replace); + lv_textarea_add_text(obj, ta_insert_replace); return LV_RES_INV; } } @@ -1710,78 +1525,65 @@ static lv_res_t insert_handler(lv_obj_t * ta, const char * txt) return LV_RES_OK; } -static void draw_placeholder(lv_obj_t * ta, const lv_area_t * clip_area) +static void draw_placeholder(lv_obj_t * obj, const lv_area_t * clip_area) { - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); - const char * txt = lv_label_get_text(ext->label); + lv_textarea_t * ta = (lv_textarea_t *) obj; + const char * txt = lv_label_get_text(ta->label); /*Draw the place holder*/ - if(txt[0] == '\0' && ext->placeholder_txt && ext->placeholder_txt[0] != 0) { + if(txt[0] == '\0' && ta->placeholder_txt && ta->placeholder_txt[0] != 0) { lv_draw_label_dsc_t ph_dsc; lv_draw_label_dsc_init(&ph_dsc); - lv_obj_init_draw_label_dsc(ta, LV_TEXTAREA_PART_PLACEHOLDER, &ph_dsc); - switch(lv_label_get_align(ext->label)) { - case LV_TEXT_ALIGN_CENTER: - ph_dsc.flag |= LV_TEXT_FLAG_CENTER; - break; - case LV_TEXT_ALIGN_RIGHT: - ph_dsc.flag |= LV_TEXT_FLAG_RIGHT; - break; - default: - break; - } + lv_obj_init_draw_label_dsc(obj, LV_PART_PLACEHOLDER, &ph_dsc); - if(ext->one_line) ph_dsc.flag |= LV_TEXT_FLAG_EXPAND; + if(ta->one_line) ph_dsc.flag |= LV_TEXT_FLAG_EXPAND; - lv_coord_t left = lv_obj_get_style_pad_left(ta, LV_TEXTAREA_PART_MAIN); - lv_coord_t top = lv_obj_get_style_pad_top(ta, LV_TEXTAREA_PART_MAIN); + lv_coord_t left = lv_obj_get_style_pad_left(obj, LV_PART_MAIN); + lv_coord_t top = lv_obj_get_style_pad_top(obj, LV_PART_MAIN); lv_area_t ph_coords; - lv_area_copy(&ph_coords, &ta->coords); + lv_area_copy(&ph_coords, &obj->coords); ph_coords.x1 += left; ph_coords.x2 += left; ph_coords.y1 += top; ph_coords.y2 += top; - lv_draw_label(&ph_coords, clip_area, &ph_dsc, ext->placeholder_txt, NULL); + lv_draw_label(&ph_coords, clip_area, &ph_dsc, ta->placeholder_txt, NULL); } } -static void draw_cursor(lv_obj_t * ta, const lv_area_t * clip_area) +static void draw_cursor(lv_obj_t * obj, const lv_area_t * clip_area) { - lv_textarea_ext_t * ext = lv_obj_get_ext_attr(ta); - const char * txt = lv_label_get_text(ext->label); + lv_textarea_t * ta = (lv_textarea_t *) obj; + const char * txt = lv_label_get_text(ta->label); - /*Draw the cursor*/ - if(ext->cursor.hidden || ext->cursor.state == 0) { - return; /*The cursor is not visible now*/ - } + if(ta->cursor.show == 0) return; lv_draw_rect_dsc_t cur_dsc; lv_draw_rect_dsc_init(&cur_dsc); - lv_obj_init_draw_rect_dsc(ta, LV_TEXTAREA_PART_CURSOR, &cur_dsc); + lv_obj_init_draw_rect_dsc(obj, LV_PART_MARKER, &cur_dsc); /*Draw he cursor according to the type*/ lv_area_t cur_area; - lv_area_copy(&cur_area, &ext->cursor.area); + lv_area_copy(&cur_area, &ta->cursor.area); - cur_area.x1 += ext->label->coords.x1; - cur_area.y1 += ext->label->coords.y1; - cur_area.x2 += ext->label->coords.x1; - cur_area.y2 += ext->label->coords.y1; + cur_area.x1 += ta->label->coords.x1; + cur_area.y1 += ta->label->coords.y1; + cur_area.x2 += ta->label->coords.x1; + cur_area.y2 += ta->label->coords.y1; lv_draw_rect(&cur_area, clip_area, &cur_dsc); char letter_buf[8] = {0}; - lv_memcpy(letter_buf, &txt[ext->cursor.txt_byte_pos], _lv_txt_encoded_size(&txt[ext->cursor.txt_byte_pos])); + lv_memcpy(letter_buf, &txt[ta->cursor.txt_byte_pos], _lv_txt_encoded_size(&txt[ta->cursor.txt_byte_pos])); if(cur_dsc.bg_opa == LV_OPA_COVER) { - lv_coord_t left = lv_obj_get_style_pad_left(ta, LV_TEXTAREA_PART_CURSOR); - lv_coord_t top = lv_obj_get_style_pad_top(ta, LV_TEXTAREA_PART_CURSOR); + lv_coord_t left = lv_obj_get_style_pad_left(obj, LV_PART_MARKER); + lv_coord_t top = lv_obj_get_style_pad_top(obj, LV_PART_MARKER); cur_area.x1 += left; cur_area.y1 += top; lv_draw_label_dsc_t cur_label_dsc; lv_draw_label_dsc_init(&cur_label_dsc); - lv_obj_init_draw_label_dsc(ta, LV_TEXTAREA_PART_CURSOR, &cur_label_dsc); + lv_obj_init_draw_label_dsc(obj, LV_PART_MARKER, &cur_label_dsc); lv_draw_label(&cur_area, clip_area, &cur_label_dsc, letter_buf, NULL); } } diff --git a/src/lv_widgets/lv_textarea.h b/src/lv_widgets/lv_textarea.h index cbe9ba83c2..62bda1882c 100644 --- a/src/lv_widgets/lv_textarea.h +++ b/src/lv_widgets/lv_textarea.h @@ -38,25 +38,21 @@ LV_EXPORT_CONST_INT(LV_TEXTAREA_CURSOR_LAST); /*Data of text area*/ typedef struct { - /*New data for this type */ + lv_obj_t obj; lv_obj_t * label; /*Label of the text area*/ char * placeholder_txt; /*Place holder label. only visible if text is an empty string*/ - lv_style_list_t style_placeholder; char * pwd_tmp; /*Used to store the original text in password mode*/ const char * accepted_chars; /*Only these characters will be accepted. NULL: accept all*/ uint32_t max_length; /*The max. number of characters. 0: no limit*/ uint16_t pwd_show_time; /*Time to show characters in password mode before change them to '*' */ struct { - lv_style_list_t style; /* Style of the cursor (NULL to use label's style)*/ lv_coord_t valid_x; /* Used when stepping up/down to a shorter line. * (Used by the library)*/ uint32_t pos; /* The current cursor position * (0: before 1st letter; 1: before 2nd letter ...)*/ - uint16_t blink_time; /*Blink period*/ lv_area_t area; /* Cursor area relative to the Text Area*/ uint32_t txt_byte_pos; /* Byte index of the letter after (on) the cursor*/ - uint8_t state : 1; /*Cursor is visible now or not (Handled by the library)*/ - uint8_t hidden : 1; /*Cursor is hidden by he user */ + uint8_t show : 1; /*Cursor is visible now or not (Handled by the library)*/ uint8_t click_pos : 1; /*1: Enable positioning the cursor by clicking the text area*/ } cursor; #if LV_LABEL_TEXT_SEL @@ -67,17 +63,9 @@ typedef struct { #endif uint8_t pwd_mode : 1; /*Replace characters with '*' */ uint8_t one_line : 1; /*One line mode (ignore line breaks)*/ -} lv_textarea_ext_t; +} lv_textarea_t; -/** Possible text areas styles. */ -enum { - LV_TEXTAREA_PART_MAIN, /**< Text area background style */ - LV_TEXTAREA_PART_CURSOR, /**< Cursor style */ - LV_TEXTAREA_PART_PLACEHOLDER, /**< Placeholder style */ - _LV_TEXTAREA_PART_VIRTUAL_LAST, -}; - -typedef uint8_t lv_textarea_style_t; +extern const lv_obj_class_t lv_textarea; /********************** * GLOBAL PROTOTYPES @@ -177,15 +165,6 @@ void lv_textarea_set_pwd_mode(lv_obj_t * ta, bool en); */ void lv_textarea_set_one_line(lv_obj_t * ta, bool en); -/** - * Set the alignment of the text area. - * In one line mode the text can be scrolled only with `LV_TEXT_ALIGN_LEFT`. - * This function should be called if the size of text area changes. - * @param ta pointer to a text are object - * @param align the desired alignment from `lv_text_align_t`. (LV_TEXT_ALIGN_LEFT/CENTER/RIGHT) - */ -void lv_textarea_set_text_align(lv_obj_t * ta, lv_text_align_t align); - /** * Set a list of characters. Only these characters will be accepted by the text area * @param ta pointer to Text Area @@ -224,13 +203,6 @@ void lv_textarea_set_text_sel(lv_obj_t * ta, bool en); */ void lv_textarea_set_pwd_show_time(lv_obj_t * ta, uint16_t time); -/** - * Set cursor blink animation time - * @param ta pointer to Text area - * @param time blink period. 0: disable blinking - */ -void lv_textarea_set_cursor_blink_time(lv_obj_t * ta, uint16_t time); - /*===================== * Getter functions *====================*/ @@ -326,13 +298,6 @@ bool lv_textarea_get_text_sel_en(lv_obj_t * ta); */ uint16_t lv_textarea_get_pwd_show_time(lv_obj_t * ta); -/** - * Set cursor blink animation time - * @param ta pointer to Text area - * @return time blink period. 0: disable blinking - */ -uint16_t lv_textarea_get_cursor_blink_time(lv_obj_t * ta); - /*===================== * Other functions *====================*/