edje: introduction of text marquee with new ellipsis grammar 29/86329/18
authorShinwoo Kim <cinoo.kim@samsung.com>
Wed, 31 Aug 2016 12:56:18 +0000 (21:56 +0900)
committerGerrit Code Review <gerrit@review.vlan103.tizen.org>
Thu, 13 Oct 2016 06:15:17 +0000 (23:15 -0700)
[fixed issue]
 - issue coming with clipper deletion when device is rotated.
 - issue coming with horizontal scrolling.
 - issue coming with textblock on RTL status.
 - issue coming with textblock clipper when device is rotated.

[enhanced]
 - use HEAD, TAIL for ellipsis direction.
 - add slide speed factor (px/sec).
 - change to marquee from slide.
 - remove slide speed factor, adding repeat limit factor.
 - handle start point with scrolling.
 - set default ellipsis marquee repeat limit to -1.
 - reset ellipsis marquee repeat count to handle state changing.
 - remove "ellipsis.on", using EDJE_TEXT_ELLIPSIS_MODE_NONE.
 - use "ellipsize", separated from "ellipsis".
 - check if last description is using ellipsis.
 - enhance readability.

Conflicts:
        src/bin/edje/edje_cc_handlers.c
        src/lib/edje/edje_calc.c
        src/lib/edje/edje_data.c

Change-Id: Iee6d3b815e5929c06578dee47106291632200879

src/bin/edje/edje_cc_handlers.c
src/lib/edje/Edje_Common.h
src/lib/edje/edje_calc.c
src/lib/edje/edje_data.c
src/lib/edje/edje_private.h
src/lib/edje/edje_smart.c
src/lib/edje/edje_text.c

index a2c0735..cef0d87 100644 (file)
@@ -391,6 +391,10 @@ static void st_collections_group_parts_part_description_text_ellipsis(void);
 /* TIZEN_ONLY(20160920): Add fade_ellipsis feature to TEXTBLOCK, TEXT part. */
 static void st_collections_group_parts_part_description_text_fade_ellipsis(void);
 /* END */
+//TIZEN_ONLY(20160923): introduction of text marquee
+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_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);
@@ -886,6 +890,10 @@ 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.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 */
      /* TIZEN_ONLY(20160920): Add fade_ellipsis feature to TEXTBLOCK, TEXT part. */
      {"collections.group.parts.part.description.text.fade_ellipsis", st_collections_group_parts_part_description_text_fade_ellipsis},
@@ -1292,6 +1300,7 @@ 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 */
      {"collections.group.parts.part.description.images", NULL}, /* dup */
      {"collections.group.parts.part.description.images.set", ob_images_set}, /* dup */
@@ -1528,6 +1537,9 @@ _edje_part_description_alloc(unsigned char type, const char *collection, const c
            /* TIZEN_ONLY(20160920): Add fade_ellipsis feature to TEXTBLOCK, TEXT part. */
           ed->text.fade_ellipsis = FROM_DOUBLE(0.0);
            /* END */
+           //TIZEN_ONLY(20160923): introduction of text marquee
+           ed->text.ellipsize.marquee_repeat_limit = -1;
+           //
 
           result = &ed->common;
           break;
@@ -9960,6 +9972,55 @@ st_collections_group_parts_part_description_text_fade_ellipsis(void)
 }
 /* END */
 
+//TIZEN_ONLY(20160923): introduction of text marquee
+static void
+st_collections_group_parts_part_description_text_ellipsize_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 = parse_enum(0,
+                                       "NONE", EDJE_TEXT_ELLIPSIZE_MODE_NONE,
+                                       "START", EDJE_TEXT_ELLIPSIZE_MODE_START,
+                                       "MIDDLE", EDJE_TEXT_ELLIPSIZE_MODE_MIDDLE,
+                                       "END", EDJE_TEXT_ELLIPSIZE_MODE_END,
+                                       "FADE_START", EDJE_TEXT_ELLIPSIZE_MODE_FADE_START,
+                                       "FADE_END", EDJE_TEXT_ELLIPSIZE_MODE_FADE_END,
+                                       "MARQUEE", EDJE_TEXT_ELLIPSIZE_MODE_MARQUEE,
+                                       NULL);
+}
+
+static void
+st_collections_group_parts_part_description_text_ellipsize_marquee_repeat_limit(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);
+}
+//
 /** @edcsubsection{collections_group_parts_description_box,
  *                 Group.Parts.Part.Description.Box} */
 
index 646ea87..c010e01 100644 (file)
@@ -1443,6 +1443,20 @@ 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
+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;
+//
+
 /**
  * @typedef (*Edje_Text_Change_Cb)
  *
index ff9ba66..b9a1808 100644 (file)
@@ -721,6 +721,10 @@ _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";
 
@@ -828,6 +832,49 @@ _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)
+                         {
+                            evas_object_textblock_ellipsis_disabled_set(ep->object, EINA_TRUE);
+                         }
+                       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);
+                            evas_object_textblock_ellipsis_disabled_set(ep->object, ellipsis);
+                         }
+                    }
+               }
+          }
+        //
      }
 
    ed->recalc_hints = EINA_TRUE;
@@ -4042,6 +4089,232 @@ _edje_fade_ellipsis_apply(Edje *ed, Edje_Real_Part *ep,
 #endif
 }
 /* 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)
@@ -4076,6 +4349,10 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta
    Edje_Calc_Params lp3;
    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;
+   //
 
    /* GRADIENT ARE GONE, WE MUST IGNORE IT FROM OLD FILE. */
    if (ep->part->type == EDJE_PART_TYPE_GRADIENT)
@@ -4888,8 +5165,30 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta
                      efl_gfx_position_set(ed->x + pf->final.x, ed->y + pf->final.y));
 #else
              eo_do(ep->object,
-                   efl_gfx_position_set(ed->x + pf->final.x, ed->y + pf->final.y),
-                   efl_gfx_size_set(pf->final.w, pf->final.h));
+                   efl_gfx_position_set(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)
+                    {
+                       eo_do(ep->object,
+                             evas_obj_textblock_size_formatted_get(&tw, &th));
+                       if (tw < pf->final.w) tw = pf->final.w;
+                       if (th < pf->final.h) th = pf->final.h;
+                    }
+                  eo_do(ep->object,
+                        efl_gfx_size_set(tw, th));
+               }
+             //
+              else
+                eo_do(ep->object,
+                      efl_gfx_size_set(pf->final.w, pf->final.h));
 #endif
 
              if (ep->nested_smart) /* Move, Resize all nested parts */
@@ -5248,7 +5547,12 @@ _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. */
              if (ep->part->type == EDJE_PART_TYPE_TEXTBLOCK ||
                  ep->part->type == EDJE_PART_TYPE_TEXT)
-               _edje_fade_ellipsis_apply(ed, ep, pf, (Edje_Part_Description_Text*) chosen_desc);
+               {
+                  _edje_fade_ellipsis_apply(ed, ep, pf, (Edje_Part_Description_Text*) chosen_desc);
+                  //TIZEN_ONLY(20160923): introduction of text marquee
+                  _edje_text_marquee_apply(ed, ep, pf, (Edje_Part_Description_Text *) chosen_desc);
+                  //
+               }
              /* END */
           }
 
index 9a38dee..d8d3c16 100644 (file)
@@ -1132,6 +1132,10 @@ _edje_edd_init(void)
    /* TIZEN_ONLY(20160920): Add fade_ellipsis feature to 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);
    /* END */
+   //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
@@ -1171,6 +1175,10 @@ _edje_edd_init(void)
    /* TIZEN_ONLY(20160920): Add fade_ellipsis feature to 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);
    /* END */
+   //TIZEN_ONLY(20160923): introduction of text marquee
+   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_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Edje_Part_Description_Box);
    eddc.func.mem_free = mem_free_box;
index e0da59f..fdc3bd3 100644 (file)
@@ -1425,6 +1425,15 @@ struct _Edje_Part_Description_Spec_Text
    unsigned char  max_y; /* if text size should be part max size */
    int            size_range_min;
    int            size_range_max; /* -1 means, no bound. */
+
+   //TIZEN_ONLY(20160923): introduction of text marquee
+   struct {
+      Edje_Text_Ellipsize_Mode mode;
+      int marquee_repeat_limit;
+      int marquee_repeat_count;
+      Evas_Coord_Point marquee_start_point;
+   } ellipsize;
+   //
 };
 
 struct _Edje_Part_Description_Spec_Box
@@ -1990,6 +1999,12 @@ struct _Edje_Real_Part
 #ifdef EDJE_CALC_CACHE
    int                       state; // 4
 #endif
+   //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
    unsigned char             calculated : 2; // 1
    unsigned char             calculating : 2; // 0
@@ -1997,6 +2012,9 @@ 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
 
index 50f8b52..67ba26c 100644 (file)
@@ -143,10 +143,38 @@ _edje_object_evas_object_smart_del(Eo *obj, Edje *ed)
    _edje_lib_unref();
 }
 
+//TIZEN_ONLY(20160923): introduction of text marquee
+static void
+_marquee_text_object_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_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);
+
+   evas_object_move(ep->text_marquee_clipper, ed->x + ep->x, ed->y + ep->y);
+
+   chosen_desc->text.ellipsize.marquee_start_point.x += ed_diff.x;
+   chosen_desc->text.ellipsize.marquee_start_point.y += ed_diff.y;
+}
+//
+
 EOLIAN static void
 _edje_object_evas_object_smart_move(Eo *obj EINA_UNUSED, Edje *ed, Evas_Coord x, Evas_Coord y)
 {
    unsigned int i;
+   //TIZEN_ONLY(20160923): introduction of text marquee
+   Evas_Coord_Point ed_diff;
+   ed_diff.x = x - ed->x;
+   ed_diff.y = y - ed->y;
+   //
 
    if ((ed->x == x) && (ed->y == y)) return;
    ed->x = x;
@@ -166,13 +194,24 @@ _edje_object_evas_object_smart_move(Eo *obj EINA_UNUSED, Edje *ed, Evas_Coord x,
         ep = ed->table_parts[i];
         if ((ep->type == EDJE_RP_TYPE_TEXT) && (ep->typedata.text))
           {
-             evas_object_move(ep->object,
-                              ed->x + ep->x + ep->typedata.text->offset.x,
-                              ed->y + ep->y + ep->typedata.text->offset.y);
+             //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 + ep->typedata.text->offset.x,
+                                ed->y + ep->y + ep->typedata.text->offset.y);
           }
         else
           {
-             evas_object_move(ep->object, ed->x + ep->x, ed->y + ep->y);
+             //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);
+
              if ((ep->type == EDJE_RP_TYPE_SWALLOW) &&
                  (ep->typedata.swallow))
                {
index 1b5d705..cc40df1 100644 (file)
@@ -210,6 +210,12 @@ _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
+   if (chosen_desc->text.ellipsize.mode == EDJE_TEXT_ELLIPSIZE_MODE_MARQUEE)
+     params->type.text.ellipsis = -1;
+   //
+
    if ((ep->type != EDJE_RP_TYPE_TEXT) ||
        (!ep->typedata.text)) return;
    sc = DIV(ed->scale, ed->file->base_scale);