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);
{"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},
{"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 */
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;
_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;
}
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)
{
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} */
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); \
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";
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;
}
}
/* 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)
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
#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 */
}
}
- /* 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 */
}
}
#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.*
+ * *
+ **************************************************************************************/