From: Youngbok Shin Date: Thu, 9 Nov 2017 10:26:51 +0000 (+0900) Subject: edje: import ellipsize features from Tizen with new TIZEN_ONLY tags X-Git-Tag: submit/sandbox/upgrade/efl120/20180319.053334~919 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fde9afde3a52ed9aa4976eec69b5197cd9988218;p=platform%2Fupstream%2Fefl.git edje: import ellipsize features from Tizen with new TIZEN_ONLY tags All code for ellipsize and fade_ellipsis are merged by a common TIZEN_ONLY tag. Put the following tag if you want to add a new code section for this feature. This is for convenience of migration work. /*********************************************************************************** * TIZEN_ONLY_FEATURE: ellipsize.marquee, ellipsize.fade for TEXTBLOCK, TEXT part. * ***********************************************************************************/ ... code ... /******* * END * *******/ @tizen_feature Change-Id: I601d410732cd258300e3aa575a8cb1ca670fcf2d --- diff --git a/src/bin/edje/edje_cc_handlers.c b/src/bin/edje/edje_cc_handlers.c index 73a09f1..bb7671d 100644 --- a/src/bin/edje/edje_cc_handlers.c +++ b/src/bin/edje/edje_cc_handlers.c @@ -418,10 +418,24 @@ static void st_collections_group_parts_part_description_text_align(void); static void st_collections_group_parts_part_description_text_source(void); static void st_collections_group_parts_part_description_text_text_source(void); static void st_collections_group_parts_part_description_text_ellipsis(void); -//TIZEN_ONLY(20160923): introduction of text marquee +/*********************************************************************************** + * TIZEN_ONLY_FEATURE: ellipsize.marquee, ellipsize.fade for TEXTBLOCK, TEXT part. * + ***********************************************************************************/ +static void st_collections_group_parts_part_description_text_fade_ellipsis(void); /* Legacy */ static void st_collections_group_parts_part_description_text_ellipsize_mode(void); static void st_collections_group_parts_part_description_text_ellipsize_marquee_repeat_limit(void); -// +static void st_collections_group_parts_part_description_text_ellipsize_align(void); +static void st_collections_group_parts_part_description_text_ellipsize_marquee_type(void); +static void st_collections_group_parts_part_description_text_ellipsize_marquee_loop(void); +static void st_collections_group_parts_part_description_text_ellipsize_marquee_loop_delay(void); +static void st_collections_group_parts_part_description_text_ellipsize_marquee_speed(void); +static void st_collections_group_parts_part_description_text_ellipsize_marquee_duration(void); +static void st_collections_group_parts_part_description_text_ellipsize_normal_mode(void); +static void st_collections_group_parts_part_description_text_ellipsize_fade_mode(void); +static void st_collections_group_parts_part_description_text_ellipsize_marquee_mode(void); +/******* + * END * + *******/ static void st_collections_group_parts_part_description_box_layout(void); static void st_collections_group_parts_part_description_box_align(void); static void st_collections_group_parts_part_description_box_padding(void); @@ -949,11 +963,25 @@ New_Statement_Handler statement_handlers[] = {"collections.group.parts.part.description.text.fonts.font", st_fonts_font}, /* dup */ {"collections.group.parts.part.description.text.elipsis", st_collections_group_parts_part_description_text_ellipsis}, {"collections.group.parts.part.description.text.ellipsis", st_collections_group_parts_part_description_text_ellipsis}, - //TIZEN_ONLY(20160923): introduction of text marquee + {"collections.group.parts.part.description.text.filter", st_collections_group_parts_part_description_filter_code}, /* dup */ + /*********************************************************************************** + * TIZEN_ONLY_FEATURE: ellipsize.marquee, ellipsize.fade for TEXTBLOCK, TEXT part. * + ***********************************************************************************/ {"collections.group.parts.part.description.text.ellipsize.mode", st_collections_group_parts_part_description_text_ellipsize_mode}, {"collections.group.parts.part.description.text.ellipsize.marquee_repeat_limit", st_collections_group_parts_part_description_text_ellipsize_marquee_repeat_limit}, - // - {"collections.group.parts.part.description.text.filter", st_collections_group_parts_part_description_filter_code}, /* dup */ + {"collections.group.parts.part.description.text.ellipsize.align", st_collections_group_parts_part_description_text_ellipsize_align}, + {"collections.group.parts.part.description.text.ellipsize.marquee.type", st_collections_group_parts_part_description_text_ellipsize_marquee_type}, + {"collections.group.parts.part.description.text.ellipsize.marquee.loop", st_collections_group_parts_part_description_text_ellipsize_marquee_loop}, + {"collections.group.parts.part.description.text.ellipsize.marquee.loop_delay", st_collections_group_parts_part_description_text_ellipsize_marquee_loop_delay}, + {"collections.group.parts.part.description.text.ellipsize.marquee.speed", st_collections_group_parts_part_description_text_ellipsize_marquee_speed}, + {"collections.group.parts.part.description.text.ellipsize.marquee.duration", st_collections_group_parts_part_description_text_ellipsize_marquee_duration}, + {"collections.group.parts.part.description.text.ellipsize.normal.mode", st_collections_group_parts_part_description_text_ellipsize_normal_mode}, + {"collections.group.parts.part.description.text.ellipsize.fade.mode", st_collections_group_parts_part_description_text_ellipsize_fade_mode}, + {"collections.group.parts.part.description.text.ellipsize.marquee.mode", st_collections_group_parts_part_description_text_ellipsize_marquee_mode}, + {"collections.group.parts.part.description.text.fade_ellipsis", st_collections_group_parts_part_description_text_fade_ellipsis}, /* Legacy */ + /******* + * END * + *******/ {"collections.group.parts.part.description.box.layout", st_collections_group_parts_part_description_box_layout}, {"collections.group.parts.part.description.box.align", st_collections_group_parts_part_description_box_align}, {"collections.group.parts.part.description.box.padding", st_collections_group_parts_part_description_box_padding}, @@ -1551,8 +1579,17 @@ New_Object_Handler object_handlers[] = {"collections.group.parts.part.description.fill.origin", NULL}, {"collections.group.parts.part.description.fill.size", NULL}, {"collections.group.parts.part.description.text", NULL}, - {"collections.group.parts.part.description.text.ellipsize", NULL}, {"collections.group.parts.part.description.text.fonts", NULL}, /* dup */ + /*********************************************************************************** + * TIZEN_ONLY_FEATURE: ellipsize.marquee, ellipsize.fade for TEXTBLOCK, TEXT part. * + ***********************************************************************************/ + {"collections.group.parts.part.description.text.ellipsize", NULL}, + {"collections.group.parts.part.description.text.ellipsize.marquee", NULL}, + {"collections.group.parts.part.description.text.ellipsize.normal", NULL}, + {"collections.group.parts.part.description.text.ellipsize.fade", NULL}, + /******* + * END * + *******/ {"collections.group.parts.part.description.images", NULL}, /* dup */ {"collections.group.parts.part.description.images.set", ob_images_set}, /* dup */ {"collections.group.parts.part.description.images.set.image", ob_images_set_image}, /* dup */ @@ -1787,9 +1824,10 @@ _edje_part_description_alloc(unsigned char type, const char *collection, const c ed->text.align.y = FROM_DOUBLE(0.5); ed->text.id_source = -1; ed->text.id_text_source = -1; - //TIZEN_ONLY(20160923): introduction of text marquee + /* TIZEN_ONLY_FEATURE: ellipsize.marquee, ellipsize.fade for TEXTBLOCK, TEXT part. */ + ed->text.fade_ellipsis = FROM_DOUBLE(0.0); /* Legacy */ ed->text.ellipsize.marquee_repeat_limit = -1; - // + /* END */ result = &ed->common; break; @@ -8726,6 +8764,9 @@ st_collections_group_parts_part_description_inherit(void) _filter_copy(&ted->filter, &tparent->filter); data_queue_copied_part_nest_lookup(pc, &(tparent->text.id_source), &(ted->text.id_source), &ted->text.id_source_part); data_queue_copied_part_nest_lookup(pc, &(tparent->text.id_text_source), &(ted->text.id_text_source), &ted->text.id_text_source_part); + /* TIZEN_ONLY_FEATURE: ellipsize.marquee, ellipsize.fade for TEXTBLOCK, TEXT part. */ + ted->text.fade_ellipsis = tparent->text.fade_ellipsis; + /* END */ break; } @@ -11771,7 +11812,30 @@ st_collections_group_parts_part_description_text_ellipsis(void) ed->text.ellipsis = parse_float_range(0, -1.0, 1.0); } -//TIZEN_ONLY(20160923): introduction of text marquee +/*********************************************************************************** + * TIZEN_ONLY_FEATURE: ellipsize.marquee, ellipsize.fade for TEXTBLOCK, TEXT part. * + ***********************************************************************************/ +/* Legacy */ +static void +st_collections_group_parts_part_description_text_fade_ellipsis(void) +{ + Edje_Part_Description_Text *ed; + + check_arg_count(1); + + if ((current_part->type != EDJE_PART_TYPE_TEXT) && + (current_part->type != EDJE_PART_TYPE_TEXTBLOCK)) + { + ERR("parse error %s:%i. text attributes in non-TEXT part.", + file_in, line - 1); + exit(-1); + } + + ed = (Edje_Part_Description_Text*) current_desc; + + ed->text.fade_ellipsis = parse_float_range(0, -1.0, 1.0) + 1.0; +} + static void st_collections_group_parts_part_description_text_ellipsize_mode(void) { @@ -11819,7 +11883,214 @@ st_collections_group_parts_part_description_text_ellipsize_marquee_repeat_limit( ed->text.ellipsize.marquee_repeat_limit = parse_int_range(0, -1, 0x7fffffff); } -// + +static void +st_collections_group_parts_part_description_text_ellipsize_align(void) +{ + Edje_Part_Description_Text *ed; + + check_arg_count(1); + + if ((current_part->type != EDJE_PART_TYPE_TEXT) && + (current_part->type != EDJE_PART_TYPE_TEXTBLOCK)) + { + ERR("parse error %s:%i. text attributes in non-TEXT part.", + file_in, line - 1); + exit(-1); + } + + ed = (Edje_Part_Description_Text*) current_desc; + + ed->text.ellipsize.align = parse_enum(0, + "END", EDJE_TEXT_ELLIPSIZE_ALIGN_END, + "START", EDJE_TEXT_ELLIPSIZE_ALIGN_START, + "RIGHT", EDJE_TEXT_ELLIPSIZE_ALIGN_RIGHT, + "LEFT", EDJE_TEXT_ELLIPSIZE_ALIGN_LEFT, + "LOCALE", EDJE_TEXT_ELLIPSIZE_ALIGN_LOCALE, + NULL); +} + +static void +st_collections_group_parts_part_description_text_ellipsize_marquee_type(void) +{ + Edje_Part_Description_Text *ed; + + check_arg_count(1); + + if ((current_part->type != EDJE_PART_TYPE_TEXT) && + (current_part->type != EDJE_PART_TYPE_TEXTBLOCK)) + { + ERR("parse error %s:%i. text attributes in non-TEXT part.", + file_in, line - 1); + exit(-1); + } + + ed = (Edje_Part_Description_Text*) current_desc; + + ed->text.ellipsize.marquee.type = parse_enum(0, + "DEFAULT", EDJE_TEXT_ELLIPSIZE_MARQUEE_TYPE_DEFAULT, + "ROLL", EDJE_TEXT_ELLIPSIZE_MARQUEE_TYPE_ROLL, + NULL); +} + +static void +st_collections_group_parts_part_description_text_ellipsize_marquee_loop(void) +{ + Edje_Part_Description_Text *ed; + + check_arg_count(1); + + if ((current_part->type != EDJE_PART_TYPE_TEXT) && + (current_part->type != EDJE_PART_TYPE_TEXTBLOCK)) + { + ERR("parse error %s:%i. text attributes in non-TEXT part.", + file_in, line - 1); + exit(-1); + } + + ed = (Edje_Part_Description_Text*) current_desc; + + ed->text.ellipsize.marquee_repeat_limit = parse_int_range(0, -1, 0x7fffffff); +} + +static void +st_collections_group_parts_part_description_text_ellipsize_marquee_loop_delay(void) +{ + Edje_Part_Description_Text *ed; + + check_arg_count(1); + + if ((current_part->type != EDJE_PART_TYPE_TEXT) && + (current_part->type != EDJE_PART_TYPE_TEXTBLOCK)) + { + ERR("parse error %s:%i. text attributes in non-TEXT part.", + file_in, line - 1); + exit(-1); + } + + ed = (Edje_Part_Description_Text*) current_desc; + + ed->text.ellipsize.marquee.loop_delay = parse_float(0); +} + +static void +st_collections_group_parts_part_description_text_ellipsize_marquee_speed(void) +{ + Edje_Part_Description_Text *ed; + + check_arg_count(1); + + if ((current_part->type != EDJE_PART_TYPE_TEXT) && + (current_part->type != EDJE_PART_TYPE_TEXTBLOCK)) + { + ERR("parse error %s:%i. text attributes in non-TEXT part.", + file_in, line - 1); + exit(-1); + } + + ed = (Edje_Part_Description_Text*) current_desc; + + ed->text.ellipsize.marquee.speed = parse_float(0); + ed->text.ellipsize.marquee.duration = 0.0; +} + +static void +st_collections_group_parts_part_description_text_ellipsize_marquee_duration(void) +{ + Edje_Part_Description_Text *ed; + + check_arg_count(1); + + if ((current_part->type != EDJE_PART_TYPE_TEXT) && + (current_part->type != EDJE_PART_TYPE_TEXTBLOCK)) + { + ERR("parse error %s:%i. text attributes in non-TEXT part.", + file_in, line - 1); + exit(-1); + } + + ed = (Edje_Part_Description_Text*) current_desc; + + ed->text.ellipsize.marquee.duration = parse_float(0); + ed->text.ellipsize.marquee.speed = 0.0; +} + +static void +st_collections_group_parts_part_description_text_ellipsize_normal_mode(void) +{ + Edje_Part_Description_Text *ed; + + check_arg_count(1); + + if ((current_part->type != EDJE_PART_TYPE_TEXT) && + (current_part->type != EDJE_PART_TYPE_TEXTBLOCK)) + { + ERR("parse error %s:%i. text attributes in non-TEXT part.", + file_in, line - 1); + exit(-1); + } + + ed = (Edje_Part_Description_Text*) current_desc; + + ed->text.ellipsize.mode = 0; + ed->text.ellipsize.normal.mode = parse_enum(0, + "OFF", EDJE_TEXT_ELLIPSIZE_NORMAL_MODE_OFF, + "ON", EDJE_TEXT_ELLIPSIZE_NORMAL_MODE_ON, + NULL); +} + +static void +st_collections_group_parts_part_description_text_ellipsize_fade_mode(void) +{ + Edje_Part_Description_Text *ed; + + check_arg_count(1); + + if ((current_part->type != EDJE_PART_TYPE_TEXT) && + (current_part->type != EDJE_PART_TYPE_TEXTBLOCK)) + { + ERR("parse error %s:%i. text attributes in non-TEXT part.", + file_in, line - 1); + exit(-1); + } + + ed = (Edje_Part_Description_Text*) current_desc; + + ed->text.ellipsize.mode = 0; + ed->text.ellipsize.fade.mode = parse_enum(0, + "OFF", EDJE_TEXT_ELLIPSIZE_FADE_MODE_OFF, + "ON", EDJE_TEXT_ELLIPSIZE_FADE_MODE_ON, + NULL); +} + +static void +st_collections_group_parts_part_description_text_ellipsize_marquee_mode(void) +{ + Edje_Part_Description_Text *ed; + + check_arg_count(1); + + if ((current_part->type != EDJE_PART_TYPE_TEXT) && + (current_part->type != EDJE_PART_TYPE_TEXTBLOCK)) + { + ERR("parse error %s:%i. text attributes in non-TEXT part.", + file_in, line - 1); + exit(-1); + } + + ed = (Edje_Part_Description_Text*) current_desc; + + ed->text.ellipsize.mode = 0; + ed->text.ellipsize.marquee.mode = parse_enum(0, + "OFF", EDJE_TEXT_ELLIPSIZE_MARQUEE_MODE_OFF, + "ON", EDJE_TEXT_ELLIPSIZE_MARQUEE_MODE_ON, + "ALWAYS", EDJE_TEXT_ELLIPSIZE_MARQUEE_MODE_ALWAYS, + NULL); +} +/*******/ +/* END */ +/*******/ + /** @edcsubsection{collections_group_parts_description_box, * Group.Parts.Part.Description.Box} */ diff --git a/src/lib/edje/Edje_Common.h b/src/lib/edje/Edje_Common.h index 1ab6d44..18f09cd 100644 --- a/src/lib/edje/Edje_Common.h +++ b/src/lib/edje/Edje_Common.h @@ -1325,19 +1325,62 @@ typedef enum _Edje_Text_Effect EDJE_TEXT_EFFECT_SHADOW_DIRECTION_RIGHT = (0x7 << 4) /**< right shadow direction value */ } Edje_Text_Effect; -//TIZEN_ONLY(20160923): introduction of text marquee +/*********************************************************************************** + * TIZEN_ONLY_FEATURE: ellipsize.marquee, ellipsize.fade for TEXTBLOCK, TEXT part. * + ***********************************************************************************/ typedef enum _Edje_Text_Ellipsize_Mode { - EDJE_TEXT_ELLIPSIZE_MODE_NONE = 0, - EDJE_TEXT_ELLIPSIZE_MODE_START = 1, - EDJE_TEXT_ELLIPSIZE_MODE_MIDDLE = 2, - EDJE_TEXT_ELLIPSIZE_MODE_END = 3, - EDJE_TEXT_ELLIPSIZE_MODE_FADE_START = 4, - EDJE_TEXT_ELLIPSIZE_MODE_FADE_END = 5, - EDJE_TEXT_ELLIPSIZE_MODE_MARQUEE = 6, - EDJE_TEXT_ELLIPSIZE_MODE_LAST = 7 + EDJE_TEXT_ELLIPSIZE_MODE_NONE = 0, + EDJE_TEXT_ELLIPSIZE_MODE_START = 1, /* Deprecated */ + EDJE_TEXT_ELLIPSIZE_MODE_MIDDLE = 2, /* Deprecated */ + EDJE_TEXT_ELLIPSIZE_MODE_END = 3, /* Deprecated */ + EDJE_TEXT_ELLIPSIZE_MODE_FADE_START = 4, /* Deprecated */ + EDJE_TEXT_ELLIPSIZE_MODE_FADE_END = 5, /* Deprecated */ + EDJE_TEXT_ELLIPSIZE_MODE_MARQUEE = 6, + EDJE_TEXT_ELLIPSIZE_MODE_NORMAL = 7, + EDJE_TEXT_ELLIPSIZE_MODE_FADE = 8, + EDJE_TEXT_ELLIPSIZE_MODE_FADE_MARQUEE = 9, + EDJE_TEXT_ELLIPSIZE_MODE_LAST = 10 } Edje_Text_Ellipsize_Mode; -// + +typedef enum _Edje_Text_Ellipsize_Normal_Mode +{ + EDJE_TEXT_ELLIPSIZE_NORMAL_MODE_OFF = 0, + EDJE_TEXT_ELLIPSIZE_NORMAL_MODE_ON +} Edje_Text_Ellipsize_Normal_Mode; + +typedef enum _Edje_Text_Ellipsize_Fade_Mode +{ + EDJE_TEXT_ELLIPSIZE_FADE_MODE_OFF = 0, + EDJE_TEXT_ELLIPSIZE_FADE_MODE_ON +} Edje_Text_Ellipsize_Fade_Mode; + +typedef enum _Edje_Text_Ellipsize_Marquee_Mode +{ + EDJE_TEXT_ELLIPSIZE_MARQUEE_MODE_OFF = 0, + EDJE_TEXT_ELLIPSIZE_MARQUEE_MODE_ON, + EDJE_TEXT_ELLIPSIZE_MARQUEE_MODE_ALWAYS +} Edje_Text_Ellipsize_Marquee_Mode; + +typedef enum _Edje_Text_Ellipsize_Align +{ + EDJE_TEXT_ELLIPSIZE_ALIGN_END = 0, + EDJE_TEXT_ELLIPSIZE_ALIGN_START = 1, + EDJE_TEXT_ELLIPSIZE_ALIGN_RIGHT = 2, + EDJE_TEXT_ELLIPSIZE_ALIGN_LEFT = 3, + EDJE_TEXT_ELLIPSIZE_ALIGN_LOCALE = 4, + EDJE_TEXT_ELLIPSIZE_ALIGN_LAST = 5 +} Edje_Text_Ellipsize_Align; + +typedef enum _Edje_Text_Ellipsize_Marquee_Type +{ + EDJE_TEXT_ELLIPSIZE_MARQUEE_TYPE_DEFAULT = 0, + EDJE_TEXT_ELLIPSIZE_MARQUEE_TYPE_ROLL = 1, + EDJE_TEXT_ELLIPSIZE_MARQUEE_TYPE_LAST = 2 +} Edje_Text_Ellipsize_Marquee_Type; +/******* + * END * + *******/ /** * @typedef (*Edje_Text_Change_Cb) diff --git a/src/lib/edje/edje_calc.c b/src/lib/edje/edje_calc.c index b05e012..8524c43 100644 --- a/src/lib/edje/edje_calc.c +++ b/src/lib/edje/edje_calc.c @@ -19,6 +19,11 @@ static void _edje_part_recalc_single(Edje *ed, Edje_Rea Edje_Calc_Params *params, Evas_Coord mmw, Evas_Coord mmh, FLOAT_T pos); +/* TIZEN_ONLY_FEATURE: ellipsize.marquee, ellipsize.fade for TEXTBLOCK, TEXT part. */ +static void _edje_text_ellipsize_apply(Edje *ed, Edje_Real_Part *ep, + Edje_Calc_Params *pf, + Edje_Part_Description_Text *chosen_desc); +/* END */ #define EINA_COW_CALC_PHYSICS_BEGIN(Calc, Write) \ _edje_calc_params_need_ext(Calc); \ @@ -746,10 +751,6 @@ _edje_part_description_apply(Edje *ed, Edje_Real_Part *ep, const char *d1, doubl Edje_Part_Description_Common *last_desc; Eina_Bool change_w, change_h; Edje_Part_Description_Image *epdi; - //TIZEN_ONLY(20160923): introduction of text marquee - Edje_Part_Description_Text *last_desc_text; - Edje_Part_Description_Text *desc_text; - // if (!d1) d1 = "default"; @@ -855,49 +856,6 @@ _edje_part_description_apply(Edje *ed, Edje_Real_Part *ep, const char *d1, doubl edje_object_mirrored_set(ep->typedata.swallow->swallowed_object, edje_object_mirrored_get(ed->obj)); } - //TIZEN_ONLY(20160923): introduction of text marquee - /* reset margquee_repeat_count */ - else if (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK || - ep->part->type == EDJE_PART_TYPE_TEXT) - { - if (last_desc) - { - last_desc_text = (Edje_Part_Description_Text *)last_desc; - last_desc_text->text.ellipsize.marquee_repeat_count = 0; - - desc_text = (Edje_Part_Description_Text *)ep->chosen_description; - if (ep->part->type == EDJE_PART_TYPE_TEXT) - { - if (desc_text->text.ellipsize.mode == EDJE_TEXT_ELLIPSIZE_MODE_MARQUEE) - { - desc_text->text.ellipsis = -1; - evas_object_text_ellipsis_set(ep->object, -1.0); - } - else if ((last_desc_text->text.ellipsize.mode == EDJE_TEXT_ELLIPSIZE_MODE_MARQUEE) && - (last_desc_text->text.ellipsize.mode != desc_text->text.ellipsize.mode)) - { - //FIXME: Need to enhancement using other ellipsize modes - evas_object_text_ellipsis_set(ep->object, desc_text->text.ellipsis); - evas_object_resize(ep->object, ep->w, ep->h); - } - } - else if (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK) - { - if (desc_text->text.ellipsize.mode == EDJE_TEXT_ELLIPSIZE_MODE_MARQUEE) - { - efl_text_ellipsis_set(ep->object, EINA_FALSE); - } - else if (last_desc_text->text.ellipsize.mode == EDJE_TEXT_ELLIPSIZE_MODE_MARQUEE && - last_desc_text->text.ellipsize.mode != desc_text->text.ellipsize.mode) - { - //FIXME: Need to enhancement using other ellipsize modes - Eina_Bool ellipsis = evas_object_text_ellipsis_get(ep->object); - efl_text_ellipsis_set(ep->object, !ellipsis); - } - } - } - } - // } ed->recalc_hints = EINA_TRUE; @@ -3789,232 +3747,6 @@ _edje_part_calc_params_memcpy(Edje_Calc_Params *p, Edje_Calc_Params *s, Edje_Par } } /* END */ -//TIZEN_ONLY(20160923): introduction of text marquee -static Eina_Bool -_text_object_marquee_animator(void *data) -{ - double cur_time; - double elapsed_time; - double default_time = 0.025; /* moving 1 px for 0.025 sec makes 40 px/sec */ - Evas_Coord move_length = 0; - Edje_Real_Part *ep; - Edje_Part_Description_Text *chosen_desc; - Evas_Coord_Rectangle text_cur_area; - Evas_Coord_Rectangle clipper_area; - - ep = data; - chosen_desc = (Edje_Part_Description_Text *)ep->chosen_description; - - evas_object_geometry_get(ep->object, &text_cur_area.x, &text_cur_area.y, - &text_cur_area.w, &text_cur_area.h); - - if (!ep->text_marquee_clipper) - { - ep->text_marquee_clipper = evas_object_rectangle_add(evas_object_evas_get(ep->object)); - evas_object_color_set(ep->text_marquee_clipper, 255, 255, 255, 255); - evas_object_show(ep->text_marquee_clipper); - - Evas_Object *prev_clipper = evas_object_clip_get(ep->object); - if (prev_clipper) evas_object_clip_set(ep->text_marquee_clipper, prev_clipper); - - evas_object_clip_set(ep->object, ep->text_marquee_clipper); - evas_object_move(ep->text_marquee_clipper, text_cur_area.x - ep->typedata.text->offset.x, - text_cur_area.y - ep->typedata.text->offset.y); - - ep->text_marquee_prev_time = ecore_time_get(); - } - - evas_object_resize(ep->text_marquee_clipper, ep->w, ep->h); - evas_object_geometry_get(ep->text_marquee_clipper, &clipper_area.x, &clipper_area.y, - &clipper_area.w, &clipper_area.h); - - cur_time = ecore_time_get(); - elapsed_time = cur_time - ep->text_marquee_prev_time; - default_time = default_time / evas_object_scale_get(ep->object); - while (elapsed_time > default_time) - { - elapsed_time -= default_time; - move_length++; - } - - ep->text_marquee_prev_time = cur_time - elapsed_time; - if (ep->text_marquee_to_left) - { - if (text_cur_area.x + text_cur_area.w < clipper_area.x) - { - if (chosen_desc->text.ellipsize.marquee_repeat_limit != -1) - chosen_desc->text.ellipsize.marquee_repeat_count++; - - text_cur_area.x = clipper_area.x + clipper_area.w; - } - else - { - text_cur_area.x = text_cur_area.x - move_length; - } - } - else - { - if (text_cur_area.x > clipper_area.x + clipper_area.w) - { - if (chosen_desc->text.ellipsize.marquee_repeat_limit != -1) - chosen_desc->text.ellipsize.marquee_repeat_count++; - - text_cur_area.x = clipper_area.x - text_cur_area.w; - } - else - { - text_cur_area.x = text_cur_area.x + move_length; - } - } - - /* reset text to start point */ - if (chosen_desc->text.ellipsize.marquee_repeat_limit == - chosen_desc->text.ellipsize.marquee_repeat_count) - { - evas_object_move(ep->object, - chosen_desc->text.ellipsize.marquee_start_point.x, - chosen_desc->text.ellipsize.marquee_start_point.y); - return ECORE_CALLBACK_CANCEL; - } - - evas_object_move(ep->object, text_cur_area.x, text_cur_area.y); - return ECORE_CALLBACK_RENEW; -} - -static void -_text_marquee_job(void *data) -{ - Edje_Real_Part *ep; - Evas_BiDi_Direction dir; - Edje_Part_Description_Text *chosen_desc; - Evas_Coord_Rectangle text_cur_position; - - ep = data; - chosen_desc = (Edje_Part_Description_Text *)ep->chosen_description; - - /* keep marquee start point */ - evas_object_geometry_get(ep->object, &text_cur_position.x, - &text_cur_position.y, - NULL, NULL); - chosen_desc->text.ellipsize.marquee_start_point.x = text_cur_position.x; - chosen_desc->text.ellipsize.marquee_start_point.y = text_cur_position.y; - - if (ep->text_marquee_animator) - { - ecore_animator_del(ep->text_marquee_animator); - ep->text_marquee_animator = NULL; - } - ep->text_marquee_animator = ecore_animator_add(_text_object_marquee_animator, ep); - - /* check text direction */ - if (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK) - { - dir = evas_object_paragraph_direction_get(ep->object); - if (dir == EVAS_BIDI_DIRECTION_NEUTRAL) - { - Evas_Textblock_Cursor *cur; - cur = evas_object_textblock_cursor_new(ep->object); - evas_textblock_cursor_geometry_get(cur, - NULL, NULL, NULL, NULL, &dir, - EVAS_TEXTBLOCK_CURSOR_BEFORE); - evas_textblock_cursor_free(cur); - } - } - else - { - dir = evas_object_text_direction_get(ep->object); - } - - /* define marquee direction */ - ep->text_marquee_to_left = (dir != EVAS_BIDI_DIRECTION_RTL); - - ep->text_marquee_job = NULL; -} - -static void -_text_marquee_clipper_update(Edje_Real_Part *ep, Eina_Bool del_clipper) -{ - Evas_Object *prev_clipper; - Evas_Coord_Rectangle text_cur_area; - - prev_clipper = evas_object_clip_get(ep->text_marquee_clipper); - if (!del_clipper) - { - /* reset marquee clipper changed in _edje_part_recalc */ - if (prev_clipper && prev_clipper != ep->text_marquee_clipper) - { - evas_object_clip_set(ep->text_marquee_clipper, prev_clipper); - evas_object_clip_set(ep->object, ep->text_marquee_clipper); - } - - evas_object_geometry_get(ep->object, &text_cur_area.x, &text_cur_area.y, - &text_cur_area.w, &text_cur_area.h); - evas_object_move(ep->text_marquee_clipper, text_cur_area.x - ep->typedata.text->offset.x, - text_cur_area.y - ep->typedata.text->offset.y); - evas_object_resize(ep->text_marquee_clipper, ep->w, ep->h); - } - else - { - evas_object_del(ep->text_marquee_clipper); - ep->text_marquee_clipper = NULL; - - if (prev_clipper) evas_object_clip_set(ep->object, prev_clipper); - } -} - -static void -_text_object_del_cb(void *data, EINA_UNUSED Evas *e, EINA_UNUSED Evas_Object *obj, EINA_UNUSED void *event_info) -{ - Edje_Real_Part *ep; - - ep = data; - if (ep->text_marquee_job) - { - ecore_job_del(ep->text_marquee_job); - ep->text_marquee_job = NULL; - } - - if (ep->text_marquee_animator) - { - ecore_animator_del(ep->text_marquee_animator); - ep->text_marquee_animator = NULL; - _text_marquee_clipper_update(ep, EINA_TRUE); - } -} - -static void -_edje_text_marquee_apply(Edje *ed EINA_UNUSED, Edje_Real_Part *ep, - Edje_Calc_Params *params EINA_UNUSED, - Edje_Part_Description_Text *chosen_desc) -{ - Eina_Bool is_marquee_on; - - is_marquee_on = ((chosen_desc->text.ellipsize.mode == EDJE_TEXT_ELLIPSIZE_MODE_MARQUEE) && - (chosen_desc->text.ellipsize.marquee_repeat_count != - chosen_desc->text.ellipsize.marquee_repeat_limit)); - - if (ep->text_marquee_job) - { - ecore_job_del(ep->text_marquee_job); - ep->text_marquee_job = NULL; - } - - if (ep->text_marquee_animator) - { - ecore_animator_del(ep->text_marquee_animator); - ep->text_marquee_animator = NULL; - /* in case of marquee mode, do not remove existing clipper */ - _text_marquee_clipper_update(ep, !is_marquee_on); - } - - if (is_marquee_on) - { - ep->text_marquee_job = ecore_job_add(_text_marquee_job, ep); - evas_object_event_callback_add(ep->object, EVAS_CALLBACK_DEL, - _text_object_del_cb, ep); - } -} -// void _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *state) @@ -4049,10 +3781,6 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta Edje_Calc_Params lp3 = { {0} }; Evas_Coord mmw = 0, mmh = 0; Eina_Bool map_colors_free = EINA_FALSE; - //TIZEN_ONLY(20160923): introduction of text marquee - Evas_Coord tw, th; - Edje_Part_Description_Text *text_chosen_desc; - // #ifdef EDJE_CALC_CACHE #else @@ -4958,26 +4686,7 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta #else efl_gfx_position_set(ep->object, EINA_POSITION2D(ed->x + pf->final.x, ed->y + pf->final.y)); - //TIZEN_ONLY(20160923): introduction of text marquee - if(ep->part->type == EDJE_PART_TYPE_TEXTBLOCK) - { - tw = pf->final.w; - th = pf->final.h; - - text_chosen_desc = (Edje_Part_Description_Text *)ep->chosen_description; - if (text_chosen_desc->text.ellipsize.mode == EDJE_TEXT_ELLIPSIZE_MODE_MARQUEE && - text_chosen_desc->text.ellipsize.marquee_repeat_limit != 0) - { - evas_object_textblock_size_formatted_get(ep->object, &tw, &th); - efl_gfx_size_set(ep->object, EINA_SIZE2D(tw, th)); - if (tw < pf->final.w) tw = pf->final.w; - if (th < pf->final.h) th = pf->final.h; - } - efl_gfx_size_set(ep->object, EINA_SIZE2D(tw, th)); - } - // - else - efl_gfx_size_set(ep->object, EINA_SIZE2D(pf->final.w, pf->final.h)); + efl_gfx_size_set(ep->object, EINA_SIZE2D(pf->final.w, pf->final.h)); #endif if (ep->nested_smart) /* Move, Resize all nested parts */ @@ -5322,14 +5031,10 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta } } - /* TIZEN_ONLY(20160920): Add fade_ellipsis feature to TEXTBLOCK, TEXT part. */ + /* TIZEN_ONLY_FEATURE: ellipsize.marquee, ellipsize.fade for TEXTBLOCK, TEXT part. */ if (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK || ep->part->type == EDJE_PART_TYPE_TEXT) - { - //TIZEN_ONLY(20160923): introduction of text marquee - _edje_text_marquee_apply(ed, ep, pf, (Edje_Part_Description_Text *) chosen_desc); - // - } + _edje_text_ellipsize_apply(ed, ep, pf, (Edje_Part_Description_Text*) chosen_desc); /* END */ } } @@ -5368,3 +5073,1303 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta #endif } + + + +/************************************************************************************** + * * + * TIZEN_ONLY_FEATURE: ellipsize.marquee, ellipsize.fade for TEXTBLOCK, TEXT part. * + * 20160920: Add fade_ellipsis feature to TEXTBLOCK, TEXT part. * + * 20160923: introduction of text marquee * + * 20170322: fix crash issue when Edje tries to clean up fade object * + * 20170427: fix clipper loop issue caused by clipper object for fade * + * 20170703: Add ellipsize feature and refactory fade_ellipsis, marquee features. * + * 20170725: fix wrong speed calculation for text marquee's duration. * + * 20170725: fix to apply loop_delay even if there is no loop limit. * + * 20170725: restore ellipsis state of TEXT part when marquee mode is NONE. * + * 20170801: add text marquee duration set/get APIs for internal usages. * + * 20170802: remove build warnings caused by unused parameter or variable. * + * 20170804: add text marquee speed set/get APIs for internal usages. * + * 20170804: fixed top-aligned issue when marquee is started. * + * 20170818: move Text, Textblock object based on its original position in smart move * + * 20170830: fix valign issue when slide_roll style. * + * 20170906: apply x/y offset to run marquee with short text * + * 20171109: import ellipsize features from Tizen with new TIZEN_ONLY tags. * + * * + **************************************************************************************/ +#define EDJE_DEFAULT_FADE_IMAGE "edje_default_fade_image.png" +#define LEFT_BORDER 20 +#define RIGHT_BORDER 20 +#define TOP_BORDER 20 +#define BOTTOM_BORDER 20 +#define EDJE_ELLIPSIZE_FADE_SENSITIVITY 4 + +/* moving 1 px for 0.025 sec makes 40 px/sec */ +#define EDJE_TEXT_ELLIPSIZE_MARQUEE_DEFAULT_SEC_PER_PIXEL 0.025 +#define EDJE_TEXT_ELLIPSIZE_MARQUEE_ROLL_GAP 60 + +static Evas_Object * +_edje_text_ellipsize_fade_mask_object_get(Edje_Real_Part *ep) +{ + if (!ep->typedata.text->ellipsize.fade.mask_obj) + { + Evas_Object *smart_parent; + Evas_Object *mask_obj; + char buf[1024]; + int iw = 0; + + smart_parent = evas_object_smart_parent_get(ep->object); + +#if 0 + mask_obj = evas_object_rectangle_add(evas_object_evas_get(ep->object)); + evas_object_color_set(mask_obj, 150, 0, 0, 150); +#else + mask_obj = evas_object_image_add(evas_object_evas_get(ep->object)); + snprintf(buf, sizeof(buf), "/usr/share/edje/images/%s", EDJE_DEFAULT_FADE_IMAGE); + evas_object_image_file_set(mask_obj, buf, NULL); + + if (evas_object_image_load_error_get(mask_obj) != EVAS_LOAD_ERROR_NONE) + { + ERR("Error loading fade image from file \"%s\".", buf); + + switch (evas_object_image_load_error_get(mask_obj)) + { + case EVAS_LOAD_ERROR_GENERIC: + ERR("Error type: EVAS_LOAD_ERROR_GENERIC"); + break; + case EVAS_LOAD_ERROR_DOES_NOT_EXIST: + ERR("Error type: EVAS_LOAD_ERROR_DOES_NOT_EXIST"); + break; + case EVAS_LOAD_ERROR_PERMISSION_DENIED: + ERR("Error type: EVAS_LOAD_ERROR_PERMISSION_DENIED"); + break; + case EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED: + ERR("Error type: EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED"); + break; + case EVAS_LOAD_ERROR_CORRUPT_FILE: + ERR("Error type: EVAS_LOAD_ERROR_CORRUPT_FILE"); + break; + case EVAS_LOAD_ERROR_UNKNOWN_FORMAT: + ERR("Error type: EVAS_LOAD_ERROR_UNKNOWN_FORMAT"); + break; + default: + ERR("Error type: ???"); + break; + } + } + + evas_object_image_size_get(mask_obj, &iw, NULL); + evas_object_pass_events_set(mask_obj, 1); + evas_object_pointer_mode_set(mask_obj, EVAS_OBJECT_POINTER_MODE_NOGRAB); + evas_object_image_border_set(mask_obj, LEFT_BORDER, RIGHT_BORDER, TOP_BORDER, BOTTOM_BORDER); + evas_object_image_border_scale_set(mask_obj, 1.0); + evas_object_image_border_center_fill_set(mask_obj, EVAS_BORDER_FILL_DEFAULT); +#endif + evas_object_smart_member_add(mask_obj, smart_parent); + ep->typedata.text->ellipsize.fade.mask_obj = mask_obj; + } + + return ep->typedata.text->ellipsize.fade.mask_obj; +} + +void +_edje_text_ellipsize_marquee_remove(Edje_Real_Part *ep) +{ + if (!ep || !ep->typedata.text) return; + + if (ep->typedata.text->ellipsize.marquee.proxy_obj) + { + evas_object_del(ep->typedata.text->ellipsize.marquee.proxy_obj); + ep->typedata.text->ellipsize.marquee.proxy_obj = NULL; + } + + if (ep->typedata.text->ellipsize.marquee.animator) + { + ecore_animator_del(ep->typedata.text->ellipsize.marquee.animator); + ep->typedata.text->ellipsize.marquee.animator = NULL; + } + + ep->typedata.text->ellipsize.marquee.loop_count = 0; + ep->typedata.text->ellipsize.marquee.distance = 0; +} + +void +_edje_text_ellipsize_fade_remove(Edje_Real_Part *ep) +{ + if (!ep || !ep->typedata.text) return; + + if (ep->typedata.text->ellipsize.fade.animator) + { + ecore_animator_del(ep->typedata.text->ellipsize.fade.animator); + ep->typedata.text->ellipsize.fade.animator = NULL; + } + + if (ep->typedata.text->ellipsize.fade.mask_obj) + { + evas_object_del(ep->typedata.text->ellipsize.fade.mask_obj); + ep->typedata.text->ellipsize.fade.mask_obj = NULL; + } +} + +/* TIZEN_ONLY(20170322): fix crash issue when Edje tries to clean up fade object */ +void +_edje_text_ellipsize_remove(Edje_Real_Part *ep) +{ + if (!ep || !ep->typedata.text) return; + + _edje_text_ellipsize_marquee_remove(ep); + _edje_text_ellipsize_fade_remove(ep); + + if (ep->typedata.text->ellipsize.clipper_obj) + { + evas_object_del(ep->typedata.text->ellipsize.clipper_obj); + ep->typedata.text->ellipsize.clipper_obj = NULL; + } +} +/* END */ + +/* Get alignment of ellipsize according to ellipsize.align and Text/Textblock's status */ +static void +_edje_text_ellipsize_align_get(Edje_Real_Part *ep, Edje_Text_Ellipsize_Align ellip_align, Eina_Bool is_normal, double *halign, double *valign) +{ + Evas_BiDi_Direction bidi_dir; + Eina_Bool is_multiline = EINA_FALSE; + double valign_ret = -1.0; + double halign_ret = -1.0; + + if (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK) + { + Evas_Textblock_Cursor *cur; + + cur = evas_object_textblock_cursor_new(ep->object); + + bidi_dir = evas_textblock_cursor_paragraph_direction_get(cur); + is_multiline = evas_textblock_cursor_line_set(cur, 1); + + evas_textblock_cursor_free(cur); + } + else + { + bidi_dir = evas_object_text_direction_get(ep->object); + } + + /* Handle NORMAL ellipsis. It considers difference of TEXTBLOCK and TEXT. + * Also, it considers a logic inside of each type of object with the given ellipsis value. + */ + if (is_normal) + { + /* variable for improving readability */ + double text_ellipsis_end; + double text_ellipsis_start; + + if (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK) + { + text_ellipsis_end = 1.0; + text_ellipsis_start = 0.0; + } + else + { + text_ellipsis_end = 0.0; + text_ellipsis_start = 1.0; + } + + switch (ellip_align) + { + case EDJE_TEXT_ELLIPSIZE_ALIGN_LEFT: + if (bidi_dir != EVAS_BIDI_DIRECTION_RTL) + halign_ret = text_ellipsis_start; + else + halign_ret = text_ellipsis_end; + break; + case EDJE_TEXT_ELLIPSIZE_ALIGN_RIGHT: + if (bidi_dir != EVAS_BIDI_DIRECTION_RTL) + halign_ret = text_ellipsis_end; + else + halign_ret = text_ellipsis_start; + break; + case EDJE_TEXT_ELLIPSIZE_ALIGN_START: + halign_ret = text_ellipsis_start; + break; + case EDJE_TEXT_ELLIPSIZE_ALIGN_END: + halign_ret = text_ellipsis_end; + break; + case EDJE_TEXT_ELLIPSIZE_ALIGN_LOCALE: + if (evas_language_direction_get() == EVAS_BIDI_DIRECTION_RTL) + { + if (bidi_dir == EVAS_BIDI_DIRECTION_RTL) + halign_ret = text_ellipsis_end; + else + halign_ret = text_ellipsis_start; + } + else + { + if (bidi_dir == EVAS_BIDI_DIRECTION_RTL) + halign_ret = text_ellipsis_start; + else + halign_ret = text_ellipsis_end; + } + break; + default: + halign_ret = -1.0; + } + } + else + { + /* variable for improving readability */ + double text_ellipsis_left; + double text_ellipsis_right; + + text_ellipsis_left = 0.0; + text_ellipsis_right = 1.0; + + switch (ellip_align) + { + case EDJE_TEXT_ELLIPSIZE_ALIGN_LEFT: + halign_ret = text_ellipsis_left; + break; + case EDJE_TEXT_ELLIPSIZE_ALIGN_RIGHT: + halign_ret = text_ellipsis_right; + break; + case EDJE_TEXT_ELLIPSIZE_ALIGN_START: + if (bidi_dir != EVAS_BIDI_DIRECTION_RTL) + halign_ret = text_ellipsis_left; + else + halign_ret = text_ellipsis_right; + break; + case EDJE_TEXT_ELLIPSIZE_ALIGN_END: + if (bidi_dir != EVAS_BIDI_DIRECTION_RTL) + halign_ret = text_ellipsis_right; + else + halign_ret = text_ellipsis_left; + break; + case EDJE_TEXT_ELLIPSIZE_ALIGN_LOCALE: + if (evas_language_direction_get() == EVAS_BIDI_DIRECTION_RTL) + halign_ret = text_ellipsis_left; + else + halign_ret = text_ellipsis_right; + break; + default: + halign_ret = -1.0; + } + } + + if (is_multiline) + { + /* variable for improving readability */ + double text_ellipsis_top; + double text_ellipsis_bottom; + + text_ellipsis_top = 0.0; + text_ellipsis_bottom = 1.0; + + /* LEFT, RIGHT, LOCALE are meaningless for vertical direction. + * So, LEFT, RIGHT, LOCALE will work just like END (default). + * Only START, END will work. */ + switch (ellip_align) + { + case EDJE_TEXT_ELLIPSIZE_ALIGN_LEFT: + valign_ret = text_ellipsis_bottom; + break; + case EDJE_TEXT_ELLIPSIZE_ALIGN_RIGHT: + valign_ret = text_ellipsis_bottom; + break; + case EDJE_TEXT_ELLIPSIZE_ALIGN_START: + valign_ret = text_ellipsis_top; + break; + case EDJE_TEXT_ELLIPSIZE_ALIGN_END: + valign_ret = text_ellipsis_bottom; + break; + case EDJE_TEXT_ELLIPSIZE_ALIGN_LOCALE: + valign_ret = text_ellipsis_bottom; + break; + default: + valign_ret = -1.0; + } + } + + if (halign) + *halign = halign_ret; + + if (valign) + *valign = valign_ret; +} + +static Evas_Object * +_edje_text_ellipsize_marquee_proxy_object_get(Edje_Real_Part *ep) +{ + if (!ep->typedata.text->ellipsize.marquee.proxy_obj) + { + Evas_Object *p_obj; + Evas_Object *smart_parent; + double scale = evas_object_scale_get(ep->object); + int pr, pg, pb, pa; + + smart_parent = evas_object_smart_parent_get(ep->object); + evas_object_color_get(ep->object, &pr, &pg, &pb, &pa); + + if (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK) + { + const Evas_Textblock_Style *st = evas_object_textblock_style_get(ep->object); + double valign = evas_object_textblock_valign_get(ep->object); + + p_obj = evas_object_textblock_add(evas_object_evas_get(ep->object)); + evas_object_textblock_style_set(p_obj, st); + evas_object_textblock_text_markup_set(p_obj, ep->typedata.text->text); + evas_object_textblock_valign_set(p_obj, valign); + } + else + { + const char *font = NULL; + int font_size = 0; + Evas_Text_Style_Type style; + int tr, tg, tb, ta; + + evas_object_text_font_get(ep->object, &font, &font_size); + style = evas_object_text_style_get(ep->object); + + p_obj = evas_object_text_add(evas_object_evas_get(ep->object)); + evas_object_text_font_set(p_obj, font, font_size); + evas_object_text_style_set(p_obj, style); + + evas_object_text_outline_color_get(ep->object, &tr, &tg, &tb, &ta); + evas_object_text_outline_color_set(p_obj, tr, tg, tb, ta); + evas_object_text_shadow_color_get(ep->object, &tr, &tg, &tb, &ta); + evas_object_text_shadow_color_set(p_obj, tr, tg, tb, ta); + evas_object_text_glow_color_get(ep->object, &tr, &tg, &tb, &ta); + evas_object_text_glow_color_set(p_obj, tr, tg, tb, ta); + evas_object_text_glow2_color_get(ep->object, &tr, &tg, &tb, &ta); + evas_object_text_glow2_color_set(p_obj, tr, tg, tb, ta); + + evas_object_text_text_set(p_obj, ep->typedata.text->text); + } + + evas_object_smart_member_add(p_obj, smart_parent); + evas_object_color_set(p_obj, pr, pg, pb, pa); + + if (ep->typedata.text->ellipsize.is_fade) + evas_object_clip_set(p_obj, ep->typedata.text->ellipsize.fade.mask_obj); + else + evas_object_clip_set(p_obj, ep->typedata.text->ellipsize.clipper_obj); + + if (ep->typedata.text->ellipsize.is_normal) + evas_object_textblock_ellipsis_set(p_obj, + evas_object_textblock_ellipsis_get(ep->object)); + + evas_object_scale_set(p_obj, scale); + ep->typedata.text->ellipsize.marquee.proxy_obj = p_obj; + } + + return ep->typedata.text->ellipsize.marquee.proxy_obj; +} + +static Eina_Bool +_edje_text_ellipsize_fade_animator_cb(void *data) +{ + Edje_Real_Part *ep = (Edje_Real_Part *)data; + Evas_Object *mask_obj = _edje_text_ellipsize_fade_mask_object_get(ep); + int x, y, w, h; + + if (!mask_obj) + { + ep->typedata.text->ellipsize.fade.animator = NULL; + return ECORE_CALLBACK_CANCEL; + } + + evas_object_geometry_get(mask_obj, &x, &y, &w, &h); + + if ((x == ep->typedata.text->ellipsize.fade.x) && + (y == ep->typedata.text->ellipsize.fade.y) && + (w == ep->typedata.text->ellipsize.fade.w) && + (h == ep->typedata.text->ellipsize.fade.h)) + { + ep->typedata.text->ellipsize.fade.animator = NULL; + return ECORE_CALLBACK_DONE; + } + + if (x < ep->typedata.text->ellipsize.fade.x) + { + x += EDJE_ELLIPSIZE_FADE_SENSITIVITY; + if (x > ep->typedata.text->ellipsize.fade.x) + x = ep->typedata.text->ellipsize.fade.x; + } + else if (x > ep->typedata.text->ellipsize.fade.x) + { + x -= EDJE_ELLIPSIZE_FADE_SENSITIVITY; + if (x < ep->typedata.text->ellipsize.fade.x) + x = ep->typedata.text->ellipsize.fade.x; + } + + if (y < ep->typedata.text->ellipsize.fade.y) + { + y += EDJE_ELLIPSIZE_FADE_SENSITIVITY; + if (y > ep->typedata.text->ellipsize.fade.y) + y = ep->typedata.text->ellipsize.fade.y; + } + else if (y > ep->typedata.text->ellipsize.fade.y) + { + y -= EDJE_ELLIPSIZE_FADE_SENSITIVITY; + if (y < ep->typedata.text->ellipsize.fade.y) + y = ep->typedata.text->ellipsize.fade.y; + } + + if (w < ep->typedata.text->ellipsize.fade.w) + { + w += EDJE_ELLIPSIZE_FADE_SENSITIVITY; + if (w > ep->typedata.text->ellipsize.fade.w) + w = ep->typedata.text->ellipsize.fade.w; + } + else if (w > ep->typedata.text->ellipsize.fade.w) + { + w -= EDJE_ELLIPSIZE_FADE_SENSITIVITY; + if (w < ep->typedata.text->ellipsize.fade.w) + w = ep->typedata.text->ellipsize.fade.w; + } + + if (h < ep->typedata.text->ellipsize.fade.h) + { + h += EDJE_ELLIPSIZE_FADE_SENSITIVITY; + if (h > ep->typedata.text->ellipsize.fade.h) + h = ep->typedata.text->ellipsize.fade.h; + } + else if (h > ep->typedata.text->ellipsize.fade.h) + { + h -= EDJE_ELLIPSIZE_FADE_SENSITIVITY; + if (h < ep->typedata.text->ellipsize.fade.h) + h = ep->typedata.text->ellipsize.fade.h; + } + + evas_object_resize(mask_obj, w, h); + evas_object_image_fill_set(mask_obj, 0, 0, w, h); + evas_object_move(mask_obj, x, y); + + return ECORE_CALLBACK_RENEW; +} + +void +_edje_text_ellipsize_fade_update(Edje_Real_Part *ep, Eina_Bool anim) +{ + Evas_Object *mask_obj = _edje_text_ellipsize_fade_mask_object_get(ep); + int left_fade_off_x, right_fade_off_x, left_fade_x, right_fade_x; + int top_fade_off_y, bottom_fade_off_y, top_fade_y, bottom_fade_y; + int tx, ty, tw, th; + int cx, cy, cw, ch; + + evas_object_geometry_get(ep->typedata.text->ellipsize.clipper_obj, &cx, &cy, &cw, &ch); + + left_fade_x = left_fade_off_x = cx - LEFT_BORDER; + right_fade_x = right_fade_off_x = cx + cw + RIGHT_BORDER; + top_fade_y = top_fade_off_y = cy - TOP_BORDER; + bottom_fade_y = bottom_fade_off_y = cy + ch + BOTTOM_BORDER; + + evas_object_geometry_get(ep->object, &tx, &ty, NULL, NULL); + tx += ep->typedata.text->ellipsize.offset_x; + ty += ep->typedata.text->ellipsize.offset_y; + tw = ep->typedata.text->ellipsize.text_w; + th = ep->typedata.text->ellipsize.text_h; + + /* Calculate position and size of fade mask object */ + if ((tx < cx) && (tx + tw > cx)) + { + if (left_fade_x < left_fade_off_x + (cx - tx) * EDJE_ELLIPSIZE_FADE_SENSITIVITY) + left_fade_x = left_fade_off_x + (cx - tx) * EDJE_ELLIPSIZE_FADE_SENSITIVITY; + if (left_fade_x > cx) + left_fade_x = cx; + } + + if ((tx < cx + cw) && (tx + tw > cx + cw)) + { + if (right_fade_x > right_fade_off_x - ((tx + tw) - (cx + cw)) * EDJE_ELLIPSIZE_FADE_SENSITIVITY) + right_fade_x = right_fade_off_x - ((tx + tw) - (cx + cw)) * EDJE_ELLIPSIZE_FADE_SENSITIVITY; + if (right_fade_x < cx + cw) + right_fade_x = cx + cw; + } + + if ((ty < cy) && (ty + th > cy)) + { + if (top_fade_y < top_fade_off_y + (cy - ty) * EDJE_ELLIPSIZE_FADE_SENSITIVITY) + top_fade_y = top_fade_off_y + (cy - ty) * EDJE_ELLIPSIZE_FADE_SENSITIVITY; + if (top_fade_y > cy) + top_fade_y = cy; + } + + if ((ty < cy + ch) && (ty + th > cy + ch)) + { + if (bottom_fade_y > bottom_fade_off_y - ((ty + th) - (cy + ch)) * EDJE_ELLIPSIZE_FADE_SENSITIVITY) + bottom_fade_y = bottom_fade_off_y - ((ty + th) - (cy + ch)) * EDJE_ELLIPSIZE_FADE_SENSITIVITY; + if (bottom_fade_y < cy + ch) + bottom_fade_y = cy + ch; + } + + if (ep->typedata.text->ellipsize.marquee.proxy_obj && + evas_object_visible_get(ep->typedata.text->ellipsize.marquee.proxy_obj)) + { + evas_object_geometry_get(ep->typedata.text->ellipsize.marquee.proxy_obj, + &tx, &ty, NULL, NULL); + tx += ep->typedata.text->ellipsize.offset_x; + ty += ep->typedata.text->ellipsize.offset_y; + + if ((tx < cx) && (tx + tw > cx)) + { + if (left_fade_x < left_fade_off_x + (cx - tx) * EDJE_ELLIPSIZE_FADE_SENSITIVITY) + left_fade_x = left_fade_off_x + (cx - tx) * EDJE_ELLIPSIZE_FADE_SENSITIVITY; + if (left_fade_x > cx) + left_fade_x = cx; + } + + if ((tx < cx + cw) && (tx + tw > cx + cw)) + { + if (right_fade_x > right_fade_off_x - ((tx + tw) - (cx + cw)) * EDJE_ELLIPSIZE_FADE_SENSITIVITY) + right_fade_x = right_fade_off_x - ((tx + tw) - (cx + cw)) * EDJE_ELLIPSIZE_FADE_SENSITIVITY; + if (right_fade_x < cx + cw) + right_fade_x = cx + cw; + } + + if ((ty < cy) && (ty + th > cy)) + { + if (top_fade_y < top_fade_off_y + (cy - ty) * EDJE_ELLIPSIZE_FADE_SENSITIVITY) + top_fade_y = top_fade_off_y + (cy - ty) * EDJE_ELLIPSIZE_FADE_SENSITIVITY; + if (top_fade_y > cy) + top_fade_y = cy; + } + + if ((ty < cy + ch) && (ty + th > cy + ch)) + { + if (bottom_fade_y > bottom_fade_off_y - ((ty + th) - (cy + ch)) * EDJE_ELLIPSIZE_FADE_SENSITIVITY) + bottom_fade_y = bottom_fade_off_y - ((ty + th) - (cy + ch)) * EDJE_ELLIPSIZE_FADE_SENSITIVITY; + if (bottom_fade_y < cy + ch) + bottom_fade_y = cy + ch; + } + } + + ep->typedata.text->ellipsize.fade.x = left_fade_x; + ep->typedata.text->ellipsize.fade.y = top_fade_y; + ep->typedata.text->ellipsize.fade.w = right_fade_x - left_fade_x; + ep->typedata.text->ellipsize.fade.h = bottom_fade_y - top_fade_y; + + if (anim) + { + if (!ep->typedata.text->ellipsize.fade.animator) + ep->typedata.text->ellipsize.fade.animator = ecore_animator_add(_edje_text_ellipsize_fade_animator_cb, ep); + } + else + { + if (ep->typedata.text->ellipsize.fade.animator) + { + ecore_animator_del(ep->typedata.text->ellipsize.fade.animator); + ep->typedata.text->ellipsize.fade.animator = NULL; + } + + evas_object_resize(mask_obj, + ep->typedata.text->ellipsize.fade.w, + ep->typedata.text->ellipsize.fade.h); + evas_object_image_fill_set(mask_obj, 0, 0, + ep->typedata.text->ellipsize.fade.w, + ep->typedata.text->ellipsize.fade.h); + evas_object_move(mask_obj, + ep->typedata.text->ellipsize.fade.x, + ep->typedata.text->ellipsize.fade.y); + } +} + +static Eina_Bool +_edje_text_ellipsize_marquee_animator_cb(void *data) +{ + double cur_time; + double elapsed_time; + Edje_Real_Part *ep = (Edje_Real_Part *)data; + Edje *ed = ep->typedata.text->ellipsize.marquee.edje; + Edje_Part_Description_Text *chosen_desc = (Edje_Part_Description_Text *)ep->chosen_description; + Evas_Object *clipper_obj = ep->typedata.text->ellipsize.clipper_obj; + Evas_Coord_Rectangle text_cur_area; + Evas_Coord_Rectangle clipper_area; + /* TODO: roll_gap should be controlled by edc developers? */ + double time_sec_per_pixel = ep->typedata.text->ellipsize.marquee.sec_per_pixel; + int roll_gap = EDJE_TEXT_ELLIPSIZE_MARQUEE_ROLL_GAP; + int loop_jump_from_pos = 0; + int loop_jump_to_pos = 0; + int distance_per_loop = 0; + int move_pixel = 0; + Eina_Bool text_marquee_top_left; + Eina_Bool text_marquee_vertical; + + evas_object_geometry_get(ep->object, &text_cur_area.x, &text_cur_area.y, + &text_cur_area.w, &text_cur_area.h); + + if (ep->typedata.text->ellipsize.valign != -1.0) + text_marquee_vertical = EINA_TRUE; + else + text_marquee_vertical = EINA_FALSE; + + if (text_marquee_vertical) + { + if (ep->typedata.text->ellipsize.valign == 1.0) + text_marquee_top_left = EINA_TRUE; + else + text_marquee_top_left = EINA_FALSE; + } + else + { + if (ep->typedata.text->ellipsize.halign == 1.0) + text_marquee_top_left = EINA_TRUE; + else + text_marquee_top_left = EINA_FALSE; + } + + evas_object_geometry_get(clipper_obj, + &clipper_area.x, &clipper_area.y, + &clipper_area.w, &clipper_area.h); + + cur_time = ecore_time_get(); + elapsed_time = cur_time - ep->typedata.text->ellipsize.marquee.animator_prev_time; + + /* Calculates move_pixel when only elapsed_time has positive value. + * The elapsed_time variable could have negative value if there is loop_delay. */ + if (elapsed_time > 0.0) + { + while (elapsed_time > time_sec_per_pixel) + { + elapsed_time -= time_sec_per_pixel; + move_pixel++; + } + + ep->typedata.text->ellipsize.marquee.animator_prev_time = cur_time - elapsed_time; + } + + if (move_pixel > 0) + { + double overpixel_for_jump = 0.0; + double overtime_for_loop = 0.0; + double overpixel_for_loop = 0.0; + int clipper_pos, clipper_length; + int text_pos, text_length; + Edje_Text_Ellipsize_Marquee_Type marquee_type; + int offset = 0; + + if (text_marquee_vertical) + { + clipper_pos = clipper_area.y; + clipper_length = clipper_area.h; + text_pos = text_cur_area.y; + text_length = ep->typedata.text->ellipsize.text_h; + offset = ep->typedata.text->ellipsize.offset_y; + } + else + { + clipper_pos = clipper_area.x; + clipper_length = clipper_area.w; + text_pos = text_cur_area.x; + text_length = ep->typedata.text->ellipsize.text_w; + offset = ep->typedata.text->ellipsize.offset_x; + } + + marquee_type = chosen_desc->text.ellipsize.marquee.type; + + /* Calculate basic information of a loop according to marquee type */ + switch (marquee_type) + { + case EDJE_TEXT_ELLIPSIZE_MARQUEE_TYPE_ROLL: + if (clipper_length - text_length - offset > roll_gap) + roll_gap = clipper_length - text_length - offset; + + distance_per_loop = text_length + roll_gap; + + if (text_marquee_top_left) + { + loop_jump_from_pos = clipper_pos - text_length - roll_gap; + loop_jump_to_pos = clipper_pos; + } + else + { + loop_jump_from_pos = clipper_pos + clipper_length + roll_gap; + loop_jump_to_pos = clipper_pos + clipper_length - text_length; + } + break; + case EDJE_TEXT_ELLIPSIZE_MARQUEE_TYPE_DEFAULT: + default: + distance_per_loop = text_length + clipper_length; + + if (text_marquee_top_left) + { + loop_jump_from_pos = clipper_pos - text_length; + loop_jump_to_pos = clipper_pos + clipper_length; + } + else + { + loop_jump_from_pos = clipper_pos + clipper_length; + loop_jump_to_pos = clipper_pos - text_length; + } + } + + loop_jump_from_pos -= offset; + loop_jump_to_pos -= offset; + + /* Calculate new x, y position according to current marquee direction */ + if (text_marquee_top_left) + { + text_pos -= move_pixel; + + /* If x pos exceed loop_jump_from_pos, jump to loop_jump_to_pos */ + if (text_pos <= loop_jump_from_pos) + { + overpixel_for_jump = loop_jump_from_pos - text_pos; + text_pos = loop_jump_to_pos - overpixel_for_jump; + } + } + else + { + text_pos += move_pixel; + + /* If x pos exceed loop_jump_from_pos, jump to loop_jump_to_pos */ + if (text_pos >= loop_jump_from_pos) + { + overpixel_for_jump = text_pos - loop_jump_from_pos; + text_pos = loop_jump_to_pos + overpixel_for_jump; + } + } + + /* Update moved distance which is used to update loop count */ + ep->typedata.text->ellipsize.marquee.distance += move_pixel; + + /* Update loop count */ + if (ep->typedata.text->ellipsize.marquee.distance >= distance_per_loop) + { + ep->typedata.text->ellipsize.marquee.loop_count += ep->typedata.text->ellipsize.marquee.distance / distance_per_loop; + ep->typedata.text->ellipsize.marquee.distance %= distance_per_loop; + + /* Give a latency for next loop. The code below corrects the latency of the next loop, + taking into account the pixels beyond the loop. */ + if (chosen_desc->text.ellipsize.marquee.loop_delay > 0.0) + { + double next_delay_time; + + overpixel_for_loop = ep->typedata.text->ellipsize.marquee.distance; + overtime_for_loop = overpixel_for_loop * time_sec_per_pixel; + next_delay_time = chosen_desc->text.ellipsize.marquee.loop_delay - overtime_for_loop; + + if (next_delay_time >= 0.0) + { + ep->typedata.text->ellipsize.marquee.animator_prev_time += next_delay_time; + overpixel_for_loop = -ep->typedata.text->ellipsize.marquee.distance; + } + else + { + /* Below is a code of extraordinary situations. + If the time beyond a loop is greater than the latency of a given loop, + then it is necessary to remove the pixels of the corresponding delay. + The overpixel_for_loop variable will have negative value. */ + overpixel_for_loop = next_delay_time * time_sec_per_pixel; + } + + ep->typedata.text->ellipsize.marquee.distance += overpixel_for_loop; + } + + /* Emit a signal when a loop(or loops) is done. */ + _edje_emit(ed, "text,ellipsize,marquee,loop", ep->part->name); + } + + /* Check if the loop count reaches the given loop limit. */ + if ((chosen_desc->text.ellipsize.marquee_repeat_limit > 0) && + (ep->typedata.text->ellipsize.marquee.loop_count >= chosen_desc->text.ellipsize.marquee_repeat_limit)) + { + evas_object_move(ep->object, + ep->typedata.text->ellipsize.marquee.orig_x, + ep->typedata.text->ellipsize.marquee.orig_y); + + ep->typedata.text->ellipsize.marquee.animator = NULL; + _edje_text_ellipsize_marquee_remove(ep); + _edje_text_ellipsize_fade_update(ep, EINA_TRUE); + + /* Emit a signal when all loops are done. */ + _edje_emit(ed, "text,ellipsize,marquee,done", ep->part->name); + + return ECORE_CALLBACK_DONE; + } + + if (text_marquee_top_left) + text_pos -= overpixel_for_loop; + else + text_pos += overpixel_for_loop; + + /* If current marquee type needs a proxy object, update it, too. */ + if (marquee_type == EDJE_TEXT_ELLIPSIZE_MARQUEE_TYPE_ROLL) + { + Evas_Object *p_obj = _edje_text_ellipsize_marquee_proxy_object_get(ep); + int proxy_text_x, proxy_text_y; + int proxy_text_pos = text_pos; + + if (text_marquee_top_left) + proxy_text_pos += text_length + roll_gap; + else + proxy_text_pos -= text_length + roll_gap; + + if (text_marquee_vertical) + { + proxy_text_x = text_cur_area.x; + proxy_text_y = proxy_text_pos; + } + else + { + proxy_text_x = proxy_text_pos; + proxy_text_y = text_cur_area.y; + } + + evas_object_move(p_obj, proxy_text_x, proxy_text_y); + evas_object_resize(p_obj, text_cur_area.w, text_cur_area.h); + evas_object_show(p_obj); + } + + if (text_marquee_vertical) + text_cur_area.y = text_pos; + else + text_cur_area.x = text_pos; + + /* Update Textblock/Text object using updated position */ + evas_object_move(ep->object, text_cur_area.x, text_cur_area.y); + + _edje_text_ellipsize_fade_update(ep, EINA_TRUE); + } + + return ECORE_CALLBACK_RENEW; +} + +static void +_edje_text_ellipsize_position_offset_get(Edje_Real_Part *ep, + int pw, int ph, int tw, int th, + int *x_offset, int *y_offset) +{ + int ret_x = 0, ret_y = 0; + + if ((tw >= pw) && (th >= ph)) return; + + if (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK) + { + Evas_Textblock_Cursor *cur; + int lx, ly, lw, lh; + + /* FIXME: It does not make sense for horizontal marquee of multiline Textblock */ + cur = evas_object_textblock_cursor_new(ep->object); + evas_textblock_cursor_line_geometry_get(cur, &lx, &ly, &lw, &lh); + evas_textblock_cursor_free(cur); + + ret_x = lx; + ret_y = ly; + } + else + { + ret_x = ep->typedata.text->offset.x; + ret_y = ep->typedata.text->offset.y; + } + + if (x_offset && (pw > tw)) *x_offset = ret_x; + if (y_offset && (ph > th)) *y_offset = ret_y; +} + +static void +_edje_text_ellipsize_update_legacy_mode(Edje_Part_Description_Text *chosen_desc) +{ + if ((chosen_desc->text.ellipsize.mode == EDJE_TEXT_ELLIPSIZE_MODE_FADE) || + (chosen_desc->text.ellipsize.mode == EDJE_TEXT_ELLIPSIZE_MODE_FADE_MARQUEE) || + (chosen_desc->text.fade_ellipsis > 0.0)) + chosen_desc->text.ellipsize.fade.mode = EDJE_TEXT_ELLIPSIZE_FADE_MODE_ON; + + if ((chosen_desc->text.ellipsize.mode == EDJE_TEXT_ELLIPSIZE_MODE_MARQUEE) || + (chosen_desc->text.ellipsize.mode == EDJE_TEXT_ELLIPSIZE_MODE_FADE_MARQUEE)) + chosen_desc->text.ellipsize.marquee.mode = EDJE_TEXT_ELLIPSIZE_MARQUEE_MODE_ON; + + if (chosen_desc->text.ellipsize.mode == EDJE_TEXT_ELLIPSIZE_MODE_NORMAL) + chosen_desc->text.ellipsize.normal.mode = EDJE_TEXT_ELLIPSIZE_NORMAL_MODE_ON; + + if (chosen_desc->text.fade_ellipsis == 2.0) + chosen_desc->text.ellipsize.align = EDJE_TEXT_ELLIPSIZE_ALIGN_END; + else if (chosen_desc->text.fade_ellipsis == 1.0) + chosen_desc->text.ellipsize.align = EDJE_TEXT_ELLIPSIZE_ALIGN_START; +} + +/* + * _edje_text_ellipsize_apply() is a main function to apply ellipsis, fade, marquee. + * ellipsize.mode: NONE will off this feature and respect old way of ellipsis. + * + * example: + * description { + * text { + * ellipsize { + * mode: FADE_MARQUEE; // NONE(default), NORMAL, FADE, FADE_MARQUEE, MARQUEE + * align: END; // END(default), START, LEFT, RIGHT, LOCALE + * marquee { + * type: ROLL; // NORMAL(default), ROLL + * speed: 50; // pixel per sec. It is a scalable variable when its part is scalable. + * // duration: 4.0;// sec per loop. The speed will be changed according to text's length. + * loop: 3; + * loop_delay: 2.0; // sec. delay for starting each loop + * } + * } + * } + * } + * + * It also support legacy fade_ellipsis. + */ +static void +_edje_text_ellipsize_apply(Edje *ed, Edje_Real_Part *ep, + Edje_Calc_Params *pf, + Edje_Part_Description_Text *chosen_desc) +{ + Evas_Object *edje_orig_clipper; + Evas_Object *clipper_obj; + Evas_Object *mask_obj; + double halign, valign; + Eina_Bool is_normal = EINA_FALSE; + Eina_Bool is_fade = EINA_FALSE; + Eina_Bool is_marquee = EINA_FALSE; + Eina_Bool ellipsis_status = EINA_FALSE; + /* TODO: roll_gap should be controlled by edc developers? */ + int roll_gap = EDJE_TEXT_ELLIPSIZE_MARQUEE_ROLL_GAP; + int clipper_x, clipper_y, clipper_w, clipper_h; + int tx, ty, tw, th; + int resize_w, resize_h; + int offset_x, offset_y; + + if ((ep->part->type != EDJE_PART_TYPE_TEXTBLOCK) && + (ep->part->type != EDJE_PART_TYPE_TEXT)) + return; + + if (!pf || !pf->type.text) + { + ERR("Edje ellipsize: pf[%p] or pf->type.text is NULL. Do nothing for the ellipsize feature.", pf); + return; + } + + /* Reset clipper objects from Edje. + * It should be same as other code for setting default clipper in Edje. */ + if (pf->ext && pf->ext->clip_to && pf->ext->clip_to->object) + evas_object_clip_set(ep->object, pf->ext->clip_to->object); + else if (ep->part->clip_to_id >= 0) + evas_object_clip_set(ep->object, ed->table_parts[ep->part->clip_to_id % ed->table_parts_size]->object); + else + evas_object_clip_set(ep->object, ed->base.clipper); + + if (ep->typedata.text->ellipsize.fade.animator) + { + ecore_animator_del(ep->typedata.text->ellipsize.fade.animator); + ep->typedata.text->ellipsize.fade.animator = NULL; + } + + if (ep->typedata.text->ellipsize.marquee.animator) + { + _edje_text_ellipsize_marquee_remove(ep); + _edje_text_ellipsize_fade_update(ep, EINA_FALSE); + } + + /* Update ellipsize properties using legacy properties. */ + _edje_text_ellipsize_update_legacy_mode(chosen_desc); + + if (chosen_desc->text.ellipsize.normal.mode == EDJE_TEXT_ELLIPSIZE_NORMAL_MODE_ON) + is_normal = EINA_TRUE; + + /* Enable fade if one of fade types is set or legacy fade_ellipsis option is set */ + if (chosen_desc->text.ellipsize.fade.mode == EDJE_TEXT_ELLIPSIZE_FADE_MODE_ON) + is_fade = EINA_TRUE; + + /* Enable marquee if one of marquee types is set and loop count is bigger than zero */ + if ((chosen_desc->text.ellipsize.marquee.mode >= EDJE_TEXT_ELLIPSIZE_MARQUEE_MODE_ON) && + (chosen_desc->text.ellipsize.marquee_repeat_limit != 0)) + is_marquee = EINA_TRUE; + + /* Hide ellipsize clipper and mask object all options are disabled. */ + if ((pf->final.w == 0) || (pf->final.h == 0) || + !(is_normal || is_fade || is_marquee)) + { + if (ep->typedata.text->ellipsize.clipper_obj) + { + evas_object_clip_unset(ep->typedata.text->ellipsize.clipper_obj); + evas_object_hide(ep->typedata.text->ellipsize.clipper_obj); + } + + if (ep->typedata.text->ellipsize.fade.mask_obj) + { + evas_object_clip_unset(ep->typedata.text->ellipsize.fade.mask_obj); + evas_object_hide(ep->typedata.text->ellipsize.fade.mask_obj); + } + + /* Disable normal ellipsis and proceed */ + if (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK) + evas_object_textblock_ellipsis_set(ep->object, -1.0); + else if (ep->part->type == EDJE_PART_TYPE_TEXT) + evas_object_text_ellipsis_set(ep->object, + chosen_desc->text.min_x ? -1.0 : pf->type.text->ellipsis); + + if (is_marquee) + { + /* Emit a signal when text is too short to do slide. */ + _edje_emit(ed, "text,ellipsize,marquee,none", ep->part->name); + } + + return; + } + + /* Enable normal ellipsis */ + if (is_normal) + { + /* Get align only for normal ellipsis */ + _edje_text_ellipsize_align_get(ep, chosen_desc->text.ellipsize.align, EINA_TRUE, &halign, NULL); + + if (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK) + { + evas_object_textblock_ellipsis_set(ep->object, halign); + } + else if (ep->part->type == EDJE_PART_TYPE_TEXT) + { + evas_object_text_ellipsis_set(ep->object, halign); + evas_object_resize(ep->object, pf->final.w, pf->final.h); + } + + /* Skip the rest of code if only normal mode is turned on. */ + if (!(is_fade || is_marquee)) + { + if (ep->typedata.text->ellipsize.clipper_obj) + { + evas_object_clip_unset(ep->typedata.text->ellipsize.clipper_obj); + evas_object_hide(ep->typedata.text->ellipsize.clipper_obj); + } + + if (ep->typedata.text->ellipsize.fade.mask_obj) + { + evas_object_clip_unset(ep->typedata.text->ellipsize.fade.mask_obj); + evas_object_hide(ep->typedata.text->ellipsize.fade.mask_obj); + } + + return; + } + } + else + { + /* Disable normal ellipsis and proceed */ + if (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK) + evas_object_textblock_ellipsis_set(ep->object, -1.0); + else if (ep->part->type == EDJE_PART_TYPE_TEXT) + evas_object_text_ellipsis_set(ep->object, -1.0); + } + + /* Get size of contents. If normal mode is off, disable ellipsis and get whole size. */ + if (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK) + { + ellipsis_status = evas_object_textblock_ellipsis_status_get(ep->object); + + if (ellipsis_status && !is_normal) + evas_object_textblock_ellipsis_disabled_set(ep->object, EINA_TRUE); + + evas_object_textblock_size_formatted_get(ep->object, &tw, &th); + + if (ellipsis_status && !is_normal) + evas_object_textblock_ellipsis_disabled_set(ep->object, EINA_FALSE); + } + else + { + ellipsis_status = evas_object_text_ellipsis_status_get(ep->object); + + if (ellipsis_status && !is_normal) + tw = evas_object_text_horiz_width_without_ellipsis_get(ep->object); + else + tw = evas_object_text_horiz_advance_get(ep->object); + th = evas_object_text_vert_advance_get(ep->object); + } + + /* Hide fade image if text is not exceed the given area. */ + if ((chosen_desc->text.ellipsize.marquee.mode != EDJE_TEXT_ELLIPSIZE_MARQUEE_MODE_ALWAYS) && + ((tw <= pf->final.w) && (th <= pf->final.h))) + { + if (ep->typedata.text->ellipsize.clipper_obj) + { + evas_object_clip_unset(ep->typedata.text->ellipsize.clipper_obj); + evas_object_hide(ep->typedata.text->ellipsize.clipper_obj); + } + + if (ep->typedata.text->ellipsize.fade.mask_obj) + { + evas_object_clip_unset(ep->typedata.text->ellipsize.fade.mask_obj); + evas_object_hide(ep->typedata.text->ellipsize.fade.mask_obj); + } + + if (is_marquee) + { + /* Emit a signal when text is too short to do slide. */ + _edje_emit(ed, "text,ellipsize,marquee,none", ep->part->name); + } + + return; + } + + /* Add a cllipper object */ + if (!ep->typedata.text->ellipsize.clipper_obj) + { + ep->typedata.text->ellipsize.clipper_obj = evas_object_rectangle_add(evas_object_evas_get(ep->object)); + evas_object_pass_events_set(ep->typedata.text->ellipsize.clipper_obj, 1); + evas_object_pointer_mode_set(ep->typedata.text->ellipsize.clipper_obj, EVAS_OBJECT_POINTER_MODE_NOGRAB); + evas_object_smart_member_add(ep->typedata.text->ellipsize.clipper_obj, ed->obj); + } + + clipper_obj = ep->typedata.text->ellipsize.clipper_obj; + clipper_x = ed->x + pf->final.x; + clipper_y = ed->y + pf->final.y; + clipper_w = pf->final.w; + clipper_h = pf->final.h; + + /* Get alignment of ellipsize according to ellipsize.align and Text/Textblock's status */ + _edje_text_ellipsize_align_get(ep, chosen_desc->text.ellipsize.align, EINA_FALSE, &halign, &valign); + + if ((halign == 0.0) && (tw > pf->final.w)) + tx = ed->x + pf->final.x + pf->final.w - tw; + else + tx = ed->x + pf->final.x; + + if ((valign == 0.0) && (th > pf->final.h)) + ty = ed->y + pf->final.y + pf->final.h - th; + else + ty = ed->y + pf->final.y; + + ep->typedata.text->ellipsize.text_w = tw; + ep->typedata.text->ellipsize.text_h = th; + ep->typedata.text->ellipsize.is_normal = is_normal; + ep->typedata.text->ellipsize.is_fade = is_fade; + ep->typedata.text->ellipsize.is_marquee = is_marquee; + ep->typedata.text->ellipsize.halign = (float)halign; + ep->typedata.text->ellipsize.valign = (float)valign; + + /* Set clippers for ellipsize */ + edje_orig_clipper = evas_object_clip_get(ep->object); + evas_object_clip_set(clipper_obj, edje_orig_clipper); + + /* If fade feature is enabled, set additional clipper for masking. */ + if (is_fade) + { + mask_obj = _edje_text_ellipsize_fade_mask_object_get(ep); +#if 0 + evas_object_clip_set(ep->object, clipper_obj); +#else + evas_object_clip_set(ep->object, mask_obj); + evas_object_clip_set(mask_obj, clipper_obj); +#endif + evas_object_show(mask_obj); + } + else + { + evas_object_hide(ep->typedata.text->ellipsize.fade.mask_obj); + evas_object_clip_set(ep->object, clipper_obj); + } + + evas_object_resize(clipper_obj, clipper_w, clipper_h); + evas_object_move(clipper_obj, clipper_x, clipper_y); + evas_object_show(clipper_obj); + + resize_w = (pf->final.w > tw) ? pf->final.w : tw; + resize_h = (pf->final.h > th) ? pf->final.h : th; + evas_object_resize(ep->object, resize_w, resize_h); + evas_object_move(ep->object, tx, ty); + + offset_x = offset_y = 0; + _edje_text_ellipsize_position_offset_get(ep, + pf->final.w, pf->final.h, tw, th, + &offset_x, &offset_y); + ep->typedata.text->ellipsize.offset_x = offset_x; + ep->typedata.text->ellipsize.offset_y = offset_y; + + if (is_marquee) + { + double duration = chosen_desc->text.ellipsize.marquee.duration; + double speed = chosen_desc->text.ellipsize.marquee.speed; + Eina_Bool text_marquee_vertical; + + if (valign != -1.0) + text_marquee_vertical = EINA_TRUE; + else + text_marquee_vertical = EINA_FALSE; + + if (ep->typedata.text->ellipsize.marquee.duration > 0.0) + duration = ep->typedata.text->ellipsize.marquee.duration; + + if (ep->typedata.text->ellipsize.marquee.speed > 0.0) + speed = ep->typedata.text->ellipsize.marquee.speed; + + if (speed > 0.0) + { + /* Convert px_per_sec (speed) to sec_per_pixel */ + FLOAT_T sc = 1.0; + + if (ep->part->scale) + { + sc = DIV(ed->scale, ed->file->base_scale); + if (sc == 0.0) sc = 1.0; + } + + ep->typedata.text->ellipsize.marquee.sec_per_pixel = 1.0 / (speed * TO_DOUBLE(sc)); + } + else if (duration > 0.0) + { + /* Convert sec_per_loop (duration) to sec_per_pixel */ + int distance_per_loop = 0.0; + int text_length; + int clipper_length; + int offset; + + if (text_marquee_vertical) + { + clipper_length = clipper_h; + text_length = th; + offset = offset_y; + } + else + { + clipper_length = clipper_w; + text_length = tw; + offset = offset_x; + } + + switch (chosen_desc->text.ellipsize.marquee.type) + { + case EDJE_TEXT_ELLIPSIZE_MARQUEE_TYPE_ROLL: + if (clipper_length - text_length - offset > roll_gap) + roll_gap = clipper_length - text_length - offset; + + distance_per_loop = text_length + roll_gap; + break; + case EDJE_TEXT_ELLIPSIZE_MARQUEE_TYPE_DEFAULT: + default: + distance_per_loop = text_length + clipper_length; + } + + ep->typedata.text->ellipsize.marquee.sec_per_pixel = duration / (double)distance_per_loop; + } + else + { + /* If there is no description for speed or duration, set default speed */ + FLOAT_T sc = 1.0; + + if (ep->part->scale) + { + sc = DIV(ed->scale, ed->file->base_scale); + if (sc == 0.0) sc = 1.0; + } + + ep->typedata.text->ellipsize.marquee.sec_per_pixel = EDJE_TEXT_ELLIPSIZE_MARQUEE_DEFAULT_SEC_PER_PIXEL / TO_DOUBLE(sc); + } + + ep->typedata.text->ellipsize.marquee.animator_prev_time = ecore_time_get(); + ep->typedata.text->ellipsize.marquee.orig_x = tx; + ep->typedata.text->ellipsize.marquee.orig_y = ty; + ep->typedata.text->ellipsize.marquee.edje = ed; + + /* Give a latency for first loop. */ + if (chosen_desc->text.ellipsize.marquee.loop_delay > 0.0) + ep->typedata.text->ellipsize.marquee.animator_prev_time += chosen_desc->text.ellipsize.marquee.loop_delay; + + ep->typedata.text->ellipsize.marquee.animator = ecore_animator_add(_edje_text_ellipsize_marquee_animator_cb, ep); + } + + if (is_fade) + _edje_text_ellipsize_fade_update(ep, EINA_FALSE); +} + +/************************************************************************************** + * * + * TIZEN_ONLY_FEATURE_END: ellipsize.marquee, ellipsize.fade for TEXTBLOCK, TEXT part.* + * * + **************************************************************************************/ diff --git a/src/lib/edje/edje_data.c b/src/lib/edje/edje_data.c index bb92cc3..dca8f05 100644 --- a/src/lib/edje/edje_data.c +++ b/src/lib/edje/edje_data.c @@ -1177,13 +1177,26 @@ _edje_edd_init(void) EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_text, Edje_Part_Description_Text, "text.id_text_source", text.id_text_source, EET_T_INT); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_text, Edje_Part_Description_Text, "text.id_text_source_part", text.id_text_source_part, EET_T_STRING); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_text, Edje_Part_Description_Text, "text.ellipsis", text.ellipsis, EET_T_DOUBLE); - //TIZEN_ONLY(20160923): introduction of text marquee - EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_text, Edje_Part_Description_Text, "text.ellipsize.mode", text.ellipsize.mode, EET_T_INT); - EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_text, Edje_Part_Description_Text, "text.ellipsize.marquee_repeat_limit", text.ellipsize.marquee_repeat_limit, EET_T_INT); - // EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_text, Edje_Part_Description_Text, "text.filter", filter.code, EET_T_STRING); EET_DATA_DESCRIPTOR_ADD_LIST_STRING(_edje_edd_edje_part_description_text, Edje_Part_Description_Text, "text.filter_sources", filter.sources); EET_DATA_DESCRIPTOR_ADD_VAR_ARRAY(_edje_edd_edje_part_description_text, Edje_Part_Description_Text, "text.filter.data", filter.data, _edje_edd_edje_part_description_filter_data); // @since 1.15 + /*********************************************************************************** + * TIZEN_ONLY_FEATURE: ellipsize.marquee, ellipsize.fade for TEXTBLOCK, TEXT part. * + ***********************************************************************************/ + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_text, Edje_Part_Description_Text, "text.fade_ellipsis", text.fade_ellipsis, EET_T_DOUBLE); + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_text, Edje_Part_Description_Text, "text.ellipsize.mode", text.ellipsize.mode, EET_T_INT); + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_text, Edje_Part_Description_Text, "text.ellipsize.marquee_repeat_limit", text.ellipsize.marquee_repeat_limit, EET_T_INT); + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_text, Edje_Part_Description_Text, "text.ellipsize.align", text.ellipsize.align, EET_T_INT); + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_text, Edje_Part_Description_Text, "text.ellipsize.marquee.type", text.ellipsize.marquee.type, EET_T_INT); + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_text, Edje_Part_Description_Text, "text.ellipsize.marquee.loop_delay", text.ellipsize.marquee.loop_delay, EET_T_DOUBLE); + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_text, Edje_Part_Description_Text, "text.ellipsize.marquee.speed", text.ellipsize.marquee.speed, EET_T_DOUBLE); + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_text, Edje_Part_Description_Text, "text.ellipsize.marquee.duration", text.ellipsize.marquee.duration, EET_T_DOUBLE); + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_text, Edje_Part_Description_Text, "text.ellipsize.normal.mode", text.ellipsize.normal.mode, EET_T_INT); + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_text, Edje_Part_Description_Text, "text.ellipsize.fade.mode", text.ellipsize.fade.mode, EET_T_INT); + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_text, Edje_Part_Description_Text, "text.ellipsize.marquee.mode", text.ellipsize.marquee.mode, EET_T_INT); + /******* + * END * + *******/ EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Edje_Part_Description_Text); eddc.func.mem_free = mem_free_textblock; @@ -1217,10 +1230,23 @@ _edje_edd_init(void) EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_textblock, Edje_Part_Description_Text, "text.id_text_source", text.id_text_source, EET_T_INT); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_textblock, Edje_Part_Description_Text, "text.id_text_source_part", text.id_text_source_part, EET_T_STRING); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_textblock, Edje_Part_Description_Text, "text.ellipsis", text.ellipsis, EET_T_DOUBLE); - //TIZEN_ONLY(20160923): introduction of text marquee + /*********************************************************************************** + * TIZEN_ONLY_FEATURE: ellipsize.marquee, ellipsize.fade for TEXTBLOCK, TEXT part. * + ***********************************************************************************/ + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_textblock, Edje_Part_Description_Text, "text.fade_ellipsis", text.fade_ellipsis, EET_T_DOUBLE); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_textblock, Edje_Part_Description_Text, "text.ellipsize.mode", text.ellipsize.mode, EET_T_INT); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_textblock, Edje_Part_Description_Text, "text.ellipsize.marquee_repeat_limit", text.ellipsize.marquee_repeat_limit, EET_T_INT); - // + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_textblock, Edje_Part_Description_Text, "text.ellipsize.align", text.ellipsize.align, EET_T_INT); + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_textblock, Edje_Part_Description_Text, "text.ellipsize.marquee.type", text.ellipsize.marquee.type, EET_T_INT); + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_textblock, Edje_Part_Description_Text, "text.ellipsize.marquee.loop_delay", text.ellipsize.marquee.loop_delay, EET_T_DOUBLE); + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_textblock, Edje_Part_Description_Text, "text.ellipsize.marquee.speed", text.ellipsize.marquee.speed, EET_T_DOUBLE); + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_textblock, Edje_Part_Description_Text, "text.ellipsize.marquee.duration", text.ellipsize.marquee.duration, EET_T_DOUBLE); + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_textblock, Edje_Part_Description_Text, "text.ellipsize.normal.mode", text.ellipsize.normal.mode, EET_T_INT); + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_textblock, Edje_Part_Description_Text, "text.ellipsize.fade.mode", text.ellipsize.fade.mode, EET_T_INT); + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_textblock, Edje_Part_Description_Text, "text.ellipsize.marquee.mode", text.ellipsize.marquee.mode, EET_T_INT); + /******* + * END * + *******/ EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Edje_Part_Description_Box); eddc.func.mem_free = mem_free_box; diff --git a/src/lib/edje/edje_load.c b/src/lib/edje/edje_load.c index cf207a9..2ab005b 100644 --- a/src/lib/edje/edje_load.c +++ b/src/lib/edje/edje_load.c @@ -1950,6 +1950,9 @@ _edje_file_del(Edje *ed) eina_stringshare_del(rp->typedata.text->font); eina_stringshare_del(rp->typedata.text->cache.in_str); eina_stringshare_del(rp->typedata.text->cache.out_str); + /* TIZEN_ONLY_FEATURE: ellipsize.marquee, ellipsize.fade for TEXTBLOCK, TEXT part. */ + _edje_text_ellipsize_remove(rp); + /* END */ free(rp->typedata.text); rp->typedata.text = NULL; } diff --git a/src/lib/edje/edje_private.h b/src/lib/edje/edje_private.h index f801a0c..1cff50d 100644 --- a/src/lib/edje/edje_private.h +++ b/src/lib/edje/edje_private.h @@ -1465,14 +1465,38 @@ struct _Edje_Part_Description_Spec_Text unsigned char max_x; /* if text size should be part max size */ unsigned char max_y; /* if text size should be part max size */ - //TIZEN_ONLY(20160923): introduction of text marquee + /*********************************************************************************** + * TIZEN_ONLY_FEATURE: ellipsize.marquee, ellipsize.fade for TEXTBLOCK, TEXT part. * + ***********************************************************************************/ + double fade_ellipsis; + struct { Edje_Text_Ellipsize_Mode mode; int marquee_repeat_limit; - int marquee_repeat_count; - Evas_Coord_Point marquee_start_point; + int marquee_repeat_count; /* Deprecated: Use loop_count in Edje_Real_Part_Text */ + Evas_Coord_Point marquee_start_point; /* Deprecated: Use marquee_start_x, y in Edje_Real_Part_Text */ + + Edje_Text_Ellipsize_Align align; + + struct { + Edje_Text_Ellipsize_Marquee_Type type; + double loop_delay; + double speed; + double duration; + Edje_Text_Ellipsize_Marquee_Mode mode; + } marquee; + + struct { + Edje_Text_Ellipsize_Normal_Mode mode; + } normal; + + struct { + Edje_Text_Ellipsize_Fade_Mode mode; + } fade; } ellipsize; - // + /******* + * END * + *******/ }; struct _Edje_Part_Description_Spec_Box @@ -1992,6 +2016,48 @@ struct _Edje_Real_Part_Text const char *style; // 4 Edje_Position offset; // 8 short size; // 2 + + /*********************************************************************************** + * TIZEN_ONLY_FEATURE: ellipsize.marquee, ellipsize.fade for TEXTBLOCK, TEXT part. * + ***********************************************************************************/ + struct { + double duration; // 8 + } marquee; + + struct { + Evas_Object *clipper_obj; // 4 + float halign; // 4 + float valign; // 4 + int text_w, text_h; + int offset_x, offset_y; + Eina_Bool is_normal; + Eina_Bool is_fade; + Eina_Bool is_marquee; + + struct { + Evas_Object *mask_obj; + Ecore_Animator *animator; + int x, y, w, h; + } fade; + + struct { + Edje *edje; + Evas_Object *proxy_obj; + Ecore_Animator *animator; + double animator_prev_time; + double sec_per_pixel; + int orig_x, orig_y; + int loop_count; + int distance; + + double duration; + double speed; + } marquee; + } ellipsize; + /******* + * END * + *******/ + struct { unsigned char fit_x, fit_y; // 2 short in_size; // 2 @@ -2060,12 +2126,6 @@ struct _Edje_Real_Part unsigned short state; // 2 #endif char clicked_button; // 1 - //TIZEN_ONLY(20160923): introduction of text marquee - double text_marquee_prev_time; - Ecore_Animator *text_marquee_animator; - Ecore_Job *text_marquee_job; - Evas_Object *text_marquee_clipper; - // unsigned char type; // 1 Evas_Event_Flags ignore_flags; Evas_Event_Flags mask_flags; @@ -2077,9 +2137,6 @@ struct _Edje_Real_Part #ifdef EDJE_CALC_CACHE Eina_Bool invalidate : 1; // 0 #endif - //TIZEN_ONLY(20160923): introduction of text marquee - unsigned char text_marquee_to_left : 1; - // }; // 128 // WITH EDJE_CALC_CACHE: 407 @@ -3169,6 +3226,9 @@ Evas_Event_Flags _edje_real_part_ignore_flags_get(Edje *ed, Edje_Real_Part *rp); void _edje_real_part_ignore_flags_set(Edje *ed, Edje_Real_Part *rp, Evas_Event_Flags ignore_flags); Evas_Event_Flags _edje_real_part_mask_flags_get(Edje *ed, Edje_Real_Part *rp); void _edje_real_part_mask_flags_set(Edje *ed, Edje_Real_Part *rp, Evas_Event_Flags mask_flags); +/* TIZEN_ONLY_FEATURE: ellipsize.marquee, ellipsize.fade for TEXTBLOCK, TEXT part. */ +void _edje_text_ellipsize_remove(Edje_Real_Part *ep); +/* END */ /* part drag apis */ Edje_Drag_Dir _edje_object_part_drag_dir_get(Edje *ed, const char *part); diff --git a/src/lib/edje/edje_smart.c b/src/lib/edje/edje_smart.c index 3ca56d4..5cda974 100644 --- a/src/lib/edje/edje_smart.c +++ b/src/lib/edje/edje_smart.c @@ -154,28 +154,55 @@ _efl_canvas_layout_efl_canvas_group_group_del(Eo *obj, Edje *ed) efl_canvas_group_del(efl_super(obj, MY_CLASS)); } -//TIZEN_ONLY(20160923): introduction of text marquee +/*********************************************************************************** + * TIZEN_ONLY_FEATURE: ellipsize.marquee, ellipsize.fade for TEXTBLOCK, TEXT part. * + ***********************************************************************************/ static void -_marquee_text_object_move(Edje *ed, Edje_Real_Part *ep, Evas_Coord_Point ed_diff) +_edje_object_text_ellipsize_clipper_move(Edje *ed, Edje_Real_Part *ep, Evas_Coord_Point ed_diff) { - Evas_Coord x, y; - Edje_Part_Description_Text *chosen_desc; - - chosen_desc = (Edje_Part_Description_Text *)ep->chosen_description; + Evas_Coord x = 0, y = 0; evas_object_geometry_get(ep->object, &x, &y, NULL, NULL); - /* ed_diff should be handled because of horizontal scroll */ - evas_object_move(ep->object, - x + ed_diff.x, - ed->y + ep->y + ep->typedata.text->offset.y); + x += ed_diff.x; + y += ed_diff.y; + + /* ed_diff should be handled because of marquee */ + ep->typedata.text->ellipsize.marquee.orig_x += ed_diff.x; + ep->typedata.text->ellipsize.marquee.orig_y += ed_diff.y; - evas_object_move(ep->text_marquee_clipper, ed->x + ep->x, ed->y + ep->y); + if (ep->typedata.text->ellipsize.marquee.proxy_obj) + { + int px, py; - chosen_desc->text.ellipsize.marquee_start_point.x += ed_diff.x; - chosen_desc->text.ellipsize.marquee_start_point.y += ed_diff.y; + evas_object_geometry_get(ep->typedata.text->ellipsize.marquee.proxy_obj, + &px, &py, NULL, NULL); + evas_object_move(ep->typedata.text->ellipsize.marquee.proxy_obj, + px + ed_diff.x, py + ed_diff.y); + } + + if (ep->typedata.text->ellipsize.fade.animator) + { + ep->typedata.text->ellipsize.fade.x += ed_diff.x; + ep->typedata.text->ellipsize.fade.y += ed_diff.y; + } + + if (ep->typedata.text->ellipsize.fade.mask_obj) + { + int mx, my; + + evas_object_geometry_get(ep->typedata.text->ellipsize.fade.mask_obj, + &mx, &my, NULL, NULL); + evas_object_move(ep->typedata.text->ellipsize.fade.mask_obj, + mx + ed_diff.x, my + ed_diff.y); + } + + evas_object_move(ep->typedata.text->ellipsize.clipper_obj, ed->x + ep->x, ed->y + ep->y); + evas_object_move(ep->object, x, y); } -// +/******* + * END * + *******/ EOLIAN static void _efl_canvas_layout_efl_gfx_position_set(Eo *obj, Edje *ed, Eina_Position2D pos) @@ -185,11 +212,11 @@ _efl_canvas_layout_efl_gfx_position_set(Eo *obj, Edje *ed, Eina_Position2D pos) if (_evas_object_intercept_call(obj, EVAS_OBJECT_INTERCEPT_CB_MOVE, 0, pos.x, pos.y)) return; - //TIZEN_ONLY(20160923): introduction of text marquee + /* TIZEN_ONLY_FEATURE: ellipsize.marquee, ellipsize.fade for TEXTBLOCK, TEXT part. */ Evas_Coord_Point ed_diff; ed_diff.x = pos.x - ed->x; ed_diff.y = pos.y - ed->y; - // + /* END */ efl_gfx_position_set(efl_super(obj, MY_CLASS), pos); @@ -211,23 +238,23 @@ _efl_canvas_layout_efl_gfx_position_set(Eo *obj, Edje *ed, Eina_Position2D pos) ep = ed->table_parts[i]; if ((ep->type == EDJE_RP_TYPE_TEXT) && (ep->typedata.text)) { - //TIZEN_ONLY(20160923): introduction of text marquee - if (ep->text_marquee_animator) - _marquee_text_object_move(ed, ep, ed_diff); + /* TIZEN_ONLY_FEATURE: ellipsize.marquee, ellipsize.fade for TEXTBLOCK, TEXT part. + evas_object_move(ep->object, + ed->x + ep->x + ep->typedata.text->offset.x, + ed->y + ep->y + ep->typedata.text->offset.y); + */ + if (ep->typedata.text->ellipsize.clipper_obj && + evas_object_visible_get(ep->typedata.text->ellipsize.clipper_obj)) + _edje_object_text_ellipsize_clipper_move(ed, ep, ed_diff); else - // evas_object_move(ep->object, ed->x + ep->x + ep->typedata.text->offset.x, ed->y + ep->y + ep->typedata.text->offset.y); + /* END */ } else { - //TIZEN_ONLY(20160923): introduction of text marquee - if (ep->text_marquee_animator) - _marquee_text_object_move(ed, ep, ed_diff); - else - // - evas_object_move(ep->object, ed->x + ep->x, ed->y + ep->y); + evas_object_move(ep->object, ed->x + ep->x, ed->y + ep->y); if ((ep->type == EDJE_RP_TYPE_SWALLOW) && (ep->typedata.swallow)) diff --git a/src/lib/edje/edje_text.c b/src/lib/edje/edje_text.c index 402a3e2..562bd56 100644 --- a/src/lib/edje/edje_text.c +++ b/src/lib/edje/edje_text.c @@ -218,11 +218,11 @@ _edje_text_recalc_apply(Edje *ed, Edje_Real_Part *ep, Eina_Bool same_text = EINA_FALSE; FLOAT_T sc; - //TIZEN_ONLY(20160923): introduction of text marquee - //Necessary for state having EDJE_TEXT_ELLIPSIZE_MODE_MARQUEE by default + /* TIZEN_ONLY_FEATURE: ellipsize.marquee, ellipsize.fade for TEXTBLOCK, TEXT part. * + * Necessary for state having EDJE_TEXT_ELLIPSIZE_MODE_MARQUEE by default */ if (chosen_desc->text.ellipsize.mode == EDJE_TEXT_ELLIPSIZE_MODE_MARQUEE) params->type.text->ellipsis = -1; - // + /* END */ if ((ep->type != EDJE_RP_TYPE_TEXT) || (!ep->typedata.text)) return; diff --git a/src/lib/edje/edje_util.c b/src/lib/edje/edje_util.c index 258a749..a87caa7 100644 --- a/src/lib/edje/edje_util.c +++ b/src/lib/edje/edje_util.c @@ -6281,4 +6281,112 @@ edje_object_part_text_get(const Edje_Object *obj, const char *part) return _edje_efl_text_get((Eo *)obj, ed, part, EINA_TRUE, EINA_FALSE); } +/*********************************************************************************** + * TIZEN_ONLY_FEATURE: ellipsize.marquee, ellipsize.fade for TEXTBLOCK, TEXT part. * + ***********************************************************************************/ +EOLIAN Eina_Bool +_edje_object_part_text_marquee_duration_set(Eo *eo_obj EINA_UNUSED, Edje *ed, const char *part, double duration) +{ + Edje_Real_Part *rp; + + if (!part) return EINA_FALSE; + rp = _edje_real_part_recursive_get(&ed, part); + if (!rp) return EINA_FALSE; + if ((rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) && + (rp->part->type != EDJE_PART_TYPE_TEXT)) + return EINA_FALSE; + + if (rp->typedata.text) + { + rp->typedata.text->ellipsize.marquee.duration = duration; + + return EINA_TRUE; + } + + return EINA_FALSE; +} + +EOLIAN double +_edje_object_part_text_marquee_duration_get(Eo *eo_obj EINA_UNUSED, Edje *ed, const char *part) +{ + Edje_Real_Part *rp; + Edje_Part_Description_Text *desc; + + if (!part) return -1.0; + rp = _edje_real_part_recursive_get(&ed, part); + if (!rp) return -1.0; + if ((rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) && + (rp->part->type != EDJE_PART_TYPE_TEXT)) + return -1.0; + + if (rp->typedata.text) + { + if (rp->typedata.text->ellipsize.marquee.duration <= 0.0) + { + desc = (Edje_Part_Description_Text *)rp->chosen_description; + return desc->text.ellipsize.marquee.duration; + } + else + { + return rp->typedata.text->ellipsize.marquee.duration; + } + } + + return -1.0; +} + +EOLIAN Eina_Bool +_edje_object_part_text_marquee_speed_set(Eo *eo_obj EINA_UNUSED, Edje *ed, const char *part, double speed) +{ + Edje_Real_Part *rp; + + if (!part) return EINA_FALSE; + rp = _edje_real_part_recursive_get(&ed, part); + if (!rp) return EINA_FALSE; + if ((rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) && + (rp->part->type != EDJE_PART_TYPE_TEXT)) + return EINA_FALSE; + + if (rp->typedata.text) + { + rp->typedata.text->ellipsize.marquee.speed = speed; + + return EINA_TRUE; + } + + return EINA_FALSE; +} + +EOLIAN double +_edje_object_part_text_marquee_speed_get(Eo *eo_obj EINA_UNUSED, Edje *ed, const char *part) +{ + Edje_Real_Part *rp; + Edje_Part_Description_Text *desc; + + if (!part) return -1.0; + rp = _edje_real_part_recursive_get(&ed, part); + if (!rp) return -1.0; + if ((rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) && + (rp->part->type != EDJE_PART_TYPE_TEXT)) + return -1.0; + + if (rp->typedata.text) + { + if (rp->typedata.text->ellipsize.marquee.speed <= 0.0) + { + desc = (Edje_Part_Description_Text *)rp->chosen_description; + return desc->text.ellipsize.marquee.speed; + } + else + { + return rp->typedata.text->ellipsize.marquee.speed; + } + } + + return -1.0; +} +/******* + * END * + *******/ + /* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/