Ah, Sorry. It's filtered out.

I re-attached patch files.

-------------------------------------------
Hyoyoung CHANG
Engineer 

SAMSUNG ELECTRONICS, Co., Ltd. 
E-mail: hyoyoung.ch...@samsung.com 
-------------------------------------------

-----Original Message-----
From: Hyoyoung Chang [mailto:hyoyoung.ch...@samsung.com] 
Sent: Wednesday, December 15, 2010 8:45 PM
To: 'enlightenment-devel@lists.sourceforge.net'
Subject: elm_label patch(ellipsis, sliding)

Dear Elementary developers.

It's a elm_label patch.
My previous patch is too big to submit.
So I did split into patch files.
(Thanks for Gastavo and Rasterman)

main changes are
 1. refine ellipsis algorithm
     - improve to cut string to fit 
 2. adding label text sliding feature

Thank you.

-------------------------------------------
Hyoyoung CHANG
Engineer 

SAMSUNG ELECTRONICS, Co., Ltd. 
E-mail: hyoyoung.ch...@samsung.com 
-------------------------------------------
>From 2c78fdf93d30d1363dee48e1ae9416cb153a8059 Mon Sep 17 00:00:00 2001
From: Hyoyoung Chang <hyoyoung.ch...@samsung.com>
Date: Wed, 15 Dec 2010 20:23:35 +0900
Subject: [PATCH 1/3] improve label ellipsis algorithm

---
 data/themes/default.edc |   31 +++
 src/lib/elm_label.c     |  614 +++++++++++++++++++++++++++++++++++++++--------
 2 files changed, 546 insertions(+), 99 deletions(-)

diff --git a/data/themes/default.edc b/data/themes/default.edc
index a8bf2ad..79ae9ef 100644
--- a/data/themes/default.edc
+++ b/data/themes/default.edc
@@ -1447,6 +1447,37 @@ collections {
                  style: "textblock_style";
                  min: 0 1;
               }
+           } 
+        }
+      }
+   } 
+
+   group { name: "elm/label/base_wrap_ellipsis/default";
+      data.item: "default_font_size" "24";
+      data.item: "min_font_size" "8";
+      data.item: "max_font_size" "60";
+      parts {
+        part { name: "label.swallow.background";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+                  visible: 1;
+                  rel1 { relative: 0 0; to: "elm.text"; }
+                  rel2 { relative: 1 1; to: "elm.text"; }
+           }
+     }
+        part { name: "elm.text";
+           type: TEXTBLOCK;
+           mouse_events: 0;
+           scale: 1;
+           multiline: 1;
+           description { state: "default" 0.0;
+               // FIXME : fixed for multiline ellipsis.
+               //         does it need to make another ellipsis style? 
+              fixed: 0 1; 
+              text {
+                 style: "textblock_style";
+                 min: 0 1;
+              }
            }
         }
       }
diff --git a/src/lib/elm_label.c b/src/lib/elm_label.c
index 2d53916..126c15b 100644
--- a/src/lib/elm_label.c
+++ b/src/lib/elm_label.c
@@ -17,7 +17,8 @@ struct _Widget_Data
    const char *label;
    Evas_Coord lastw;
    Ecore_Job *deferred_recalc_job;
-   Evas_Coord wrap_w;
+   Evas_Coord   wrap_w;
+   Evas_Coord   wrap_h;
    Eina_Bool linewrap : 1;
    Eina_Bool changed : 1;
    Eina_Bool bgcolor : 1;
@@ -31,8 +32,8 @@ static void _sizing_eval(Evas_Object *obj);
 static int _get_value_in_key_string(const char *oldstring, const char *key, 
char **value);
 static int _strbuf_key_value_replace(Eina_Strbuf *srcbuf, const char *key, 
const char *value, int deleteflag);
 static int _stringshare_key_value_replace(const char **srcstring, const char 
*key, const char *value, int deleteflag);
-static int _is_width_over(Evas_Object *obj);
-static void _ellipsis_label_to_width(Evas_Object *obj);
+static int _is_width_over(Evas_Object *obj, int linemode);
+static void _ellipsis_label_to_width(Evas_Object *obj, int linemode);
 
 static void
 _elm_win_recalc_job(void *data)
@@ -58,6 +59,10 @@ _elm_win_recalc_job(void *data)
         edje_object_size_min_restricted_calc(wd->lbl, &minw, &minh, resw, 0);
         evas_object_size_hint_min_set(data, minminw, minh);
      }
+
+   if ((wd->ellipsis) && (wd->linewrap) && (wd->wrap_h > 0) && 
(_is_width_over(data, 1) == 1))
+     _ellipsis_label_to_width(data, 1);
+
    maxh = minh;
    evas_object_size_hint_max_set(data, -1, maxh);
 }
@@ -74,14 +79,28 @@ _del_hook(Evas_Object *obj)
 }
 
 static void
-_theme_hook(Evas_Object *obj)
+_theme_change(Evas_Object *obj)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return;
+
    if (wd->linewrap)
-     _elm_theme_object_set(obj, wd->lbl, "label", "base_wrap", 
elm_widget_style_get(obj));
+     {
+        if (wd->ellipsis)
+          _elm_theme_object_set(obj, wd->lbl, "label", "base_wrap_ellipsis", 
elm_widget_style_get(obj));
+        else
+          _elm_theme_object_set(obj, wd->lbl, "label", "base_wrap", 
elm_widget_style_get(obj));
+     }
    else
      _elm_theme_object_set(obj, wd->lbl, "label", "base", 
elm_widget_style_get(obj));
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   _theme_change(obj);
    edje_object_part_text_set(wd->lbl, "elm.text", wd->label);
    edje_object_scale_set(wd->lbl, elm_widget_scale_get(obj) * 
                          _elm_config->scale);
@@ -110,12 +129,14 @@ _sizing_eval(Evas_Object *obj)
      {
         evas_object_geometry_get(wd->lbl, NULL, NULL, &resw, &resh);
         edje_object_size_min_calc(wd->lbl, &minw, &minh);
+        if (wd->wrap_w > 0 && minw > wd->wrap_w)
+          minw = wd->wrap_w;
         evas_object_size_hint_min_set(obj, minw, minh);
         maxh = minh;
         evas_object_size_hint_max_set(obj, maxw, maxh);
-        
-        if ((wd->ellipsis) && (_is_width_over(obj) == 1)) 
-          _ellipsis_label_to_width(obj);
+
+        if ((wd->ellipsis) && (_is_width_over(obj, 0) == 1))
+          _ellipsis_label_to_width(obj, 0);
      }
 }
 
@@ -140,8 +161,10 @@ _get_value_in_key_string(const char *oldstring, const char 
*key, char **value)
         starttag = curlocater;
         endtag = curlocater + key_len;
         if ((!endtag) || (*endtag != '='))
-           return -1;
-        
+          {
+             foundflag = 0;
+             return -1;
+          }
         firstindex = abs(oldstring - curlocater);
         firstindex += key_len + 1; // strlen("key") + strlen("=")
         *value = (char *)oldstring + firstindex;
@@ -301,40 +324,409 @@ _stringshare_key_value_replace(const char **srcstring, 
const char *key, const ch
    return 0;
 }
 
+// FIXME: move to some where(such as elm_util??).
+//        copied from elm_entry for check pure text length w/o tags.
+static char *
+_str_append(char       *str,
+            const char *txt,
+            int        *len,
+            int        *alloc)
+{
+   int txt_len = strlen(txt);
+
+   if (txt_len <= 0) return str;
+   if ((*len + txt_len) >= *alloc)
+     {
+        char *str2;
+        int alloc2;
+
+        alloc2 = *alloc + txt_len + 128;
+        str2 = realloc(str, alloc2);
+        if (!str2) return str;
+        *alloc = alloc2;
+        str = str2;
+     }
+   strcpy(str + *len, txt);
+   *len += txt_len;
+   return str;
+}
+
+// FIXME: move to some where(such as elm_util??).
+//        copied from elm_entry for check pure text length w/o tags.
+static char *
+_strncpy(char       *dest,
+         const char *src,
+         size_t      count)
+{
+   if (!dest)
+     {
+        ERR("dest is NULL");
+        return NULL;
+     }
+   if (!src)
+     {
+        ERR("src is NULL");
+        return NULL;
+     }
+   if (count < 0)
+     {
+        ERR("count is smaller than 0");
+        return NULL;
+     }
+
+   return strncpy(dest, src, count);
+}
+
+// FIXME: move to some where(such as elm_util??).
+//        copied from elm_entry for check pure text length w/o tags.
+static char *
+_mkup_to_text(const char *mkup)
+{
+   char *str = NULL;
+   int str_len = 0, str_alloc = 0;
+   char *s, *p;
+   char *tag_start, *tag_end, *esc_start, *esc_end, *ts;
+
+   if (!mkup) return NULL;
+   s = p = NULL;
+   tag_start = tag_end = esc_start = esc_end = NULL;
+   p = (char *)mkup;
+   s = p;
+   for (;; )
+     {
+        if (((p != NULL) && (*p == 0)) ||
+            (tag_end) || (esc_end) ||
+            (tag_start) || (esc_start))
+          {
+             if (tag_end)
+               {
+                  char *ttag;
+
+                  ttag = malloc(tag_end - tag_start);
+                  if (ttag)
+                    {
+                       _strncpy(ttag, tag_start + 1, tag_end - tag_start - 1);
+                       ttag[tag_end - tag_start - 1] = 0;
+                       if (!strcmp(ttag, "br"))
+                         str = _str_append(str, "\n", &str_len, &str_alloc);
+                       else if (!strcmp(ttag, "\n"))
+                         str = _str_append(str, "\n", &str_len, &str_alloc);
+                       else if (!strcmp(ttag, "\\n"))
+                         str = _str_append(str, "\n", &str_len, &str_alloc);
+                       else if (!strcmp(ttag, "\t"))
+                         str = _str_append(str, "\t", &str_len, &str_alloc);
+                       else if (!strcmp(ttag, "\\t"))
+                         str = _str_append(str, "\t", &str_len, &str_alloc);
+                       else if (!strcmp(ttag, "ps")) /* Unicode paragraph 
separator */
+                         str = _str_append(str, "\xE2\x80\xA9", &str_len, 
&str_alloc);
+                       free(ttag);
+                    }
+                  tag_start = tag_end = NULL;
+               }
+             else if (esc_end)
+               {
+                  ts = malloc(esc_end - esc_start + 1);
+                  if (ts)
+                    {
+                       const char *esc;
+                       _strncpy(ts, esc_start, esc_end - esc_start);
+                       ts[esc_end - esc_start] = 0;
+                       esc = evas_textblock_escape_string_get(ts);
+                       if (esc)
+                         str = _str_append(str, esc, &str_len, &str_alloc);
+                       free(ts);
+                    }
+                  esc_start = esc_end = NULL;
+               }
+             else if ((p != NULL) && (*p == 0))
+               {
+                  ts = malloc(p - s + 1);
+                  if (ts)
+                    {
+                       _strncpy(ts, s, p - s);
+                       ts[p - s] = 0;
+                       str = _str_append(str, ts, &str_len, &str_alloc);
+                       free(ts);
+                    }
+                  break;
+               }
+          }
+        if ((p != NULL) && (*p == '<'))
+          {
+             if (!esc_start)
+               {
+                  tag_start = p;
+                  tag_end = NULL;
+                  ts = malloc(p - s + 1);
+                  if (ts)
+                    {
+                       _strncpy(ts, s, p - s);
+                       ts[p - s] = 0;
+                       str = _str_append(str, ts, &str_len, &str_alloc);
+                       free(ts);
+                    }
+                  s = NULL;
+               }
+          }
+        else if ((p != NULL) && (*p == '>'))
+          {
+             if (tag_start)
+               {
+                  tag_end = p;
+                  s = p + 1;
+               }
+          }
+        else if ((p != NULL) && (*p == '&'))
+          {
+             if (!tag_start)
+               {
+                  esc_start = p;
+                  esc_end = NULL;
+                  ts = malloc(p - s + 1);
+                  if (ts)
+                    {
+                       _strncpy(ts, s, p - s);
+                       ts[p - s] = 0;
+                       str = _str_append(str, ts, &str_len, &str_alloc);
+                       free(ts);
+                    }
+                  s = NULL;
+               }
+          }
+        else if ((p != NULL) && (*p == ';'))
+          {
+             if (esc_start)
+               {
+                  esc_end = p;
+                  s = p + 1;
+               }
+          }
+        p++;
+     }
+   return str;
+}
+
 static int
-_is_width_over(Evas_Object *obj)
+_is_width_over(Evas_Object *obj, int linemode)
 {
    Evas_Coord x, y, w, h;
    Evas_Coord vx, vy, vw, vh;
    Widget_Data *wd = elm_widget_data_get(obj);
    const char *ellipsis_string = "...";
-   Evas_Coord ellen = strlen(ellipsis_string)+1;
-   
+   Evas_Coord ellen = strlen(ellipsis_string) + 1;
+
    if (!wd) return 0;
 
-   edje_object_part_geometry_get(wd->lbl,"elm.text",&x,&y,&w,&h);
+   char *plaintxt = _mkup_to_text(edje_object_part_text_get(wd->lbl, 
"elm.text"));
+   int plainlen = 0;
+   if (plaintxt != NULL)
+     {
+        plainlen = strlen(plaintxt);
+        free(plaintxt);
+     }
+   // too short to ellipsis
+   if (plainlen <= ellen) return 0;
 
-   evas_object_geometry_get (obj, &vx,&vy,&vw,&vh);
+   edje_object_part_geometry_get(wd->lbl, "elm.text", &x, &y, &w, &h);
 
-   if ((x >= 0) && (y >= 0)) return 0;
+   evas_object_geometry_get(obj, &vx, &vy, &vw, &vh);
 
-   if ((ellen < wd->wrap_w) && (w > wd->wrap_w)) return 1;
+   if (linemode == 0) // single line
+     {
+        // skip if too early to check widget size
+          if (w < 0 && h < 0)
+            return 0;
+          // if string fits at widget
+          if ((x >= 0) && (y >= 0))
+            {
+               if ((wd->wrap_w > 0) && (wd->wrap_w < w))
+                 {
+                    Evas_Coord minw, minh;
+                    edje_object_size_min_calc(wd->lbl, &minw, &minh);
+
+                    if (minw < wd->wrap_w) // min insufficient
+                      {
+                         return 0;
+                      }
+                    else
+                      return 1;
+                 }
+               else
+                 return 0;
+            }
+
+          if (0 < wd->wrap_w && w > wd->wrap_w) return 1;
+     }
+   else // multiline
+     {
+        if ((x >= 0 || y >= 0) && h > wd->wrap_h) return 1;
+     }
 
    return 0;
 }
 
 static void
-_ellipsis_label_to_width(Evas_Object *obj)
+_ellipsis_fontsize_set(Evas_Object *obj,
+                       int          fontsize)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
-   int cur_fontsize = 0, len, showcount;
-   Eina_Strbuf *fontbuf = NULL, *txtbuf = NULL;
-   char *kvalue = NULL;
-   const char *minfont, *deffont, *maxfont;
+   if (!wd) return;
+
+   Eina_Strbuf *fontbuf = NULL;
+   Eina_Strbuf *txtbuf = NULL;
+   txtbuf = eina_strbuf_new();
+   fontbuf = eina_strbuf_new();
+   eina_strbuf_append(txtbuf, edje_object_part_text_get(wd->lbl, "elm.text"));
+   eina_strbuf_append_printf(fontbuf, "%d", fontsize);
+   _strbuf_key_value_replace(txtbuf, "font_size", 
eina_strbuf_string_get(fontbuf), 0);
+   edje_object_part_text_set(wd->lbl, "elm.text", 
eina_strbuf_string_get(txtbuf));
+   eina_strbuf_free(fontbuf);
+   eina_strbuf_free(txtbuf);
+}
+
+static Eina_Bool
+_ellipsis_cut_chars_to_widget(Evas_Object *obj,
+                              int          fontsize,
+                              int          linemode)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+
+   const char *ellipsis_string = "...";
+   int minshowcount = strlen(ellipsis_string);
+   Evas_Coord w, h;
+   Evas_Textblock_Cursor *tc1, *tc2;
+   char *cutstr, *elstr;
+   int limitw = 0;
+   int lencutstr = 0;
+   int i = 0;
+
+   edje_object_part_geometry_get(wd->lbl, "elm.text", NULL, NULL, &w, &h);
+   if (w <= 0)
+     return EINA_FALSE;
+   tc1 = evas_object_textblock_cursor_new((Evas_Object 
*)edje_object_part_object_get(wd->lbl, "elm.text"));
+   tc2 = evas_object_textblock_cursor_new((Evas_Object 
*)edje_object_part_object_get(wd->lbl, "elm.text"));
+
+   if (wd->wrap_w > 0 && wd->wrap_w < w)
+     limitw = wd->wrap_w;
+   else
+     limitw = w;
+   evas_textblock_cursor_pos_set(tc1, 0);
+   evas_textblock_cursor_char_coord_set(tc2, limitw, 0);
+
+   // if too small to cut,(is it bug? or any other reasons?)
+   // then fallback to one step mode
+   if (evas_textblock_cursor_pos_get(tc2) < minshowcount)
+     {
+        int eolpos = evas_textblock_cursor_paragraph_text_length_get(tc1);
+        Evas_Coord cx, cy, cw, ch;
+        for (i = eolpos; i > minshowcount; i--)
+          {
+             evas_textblock_cursor_pos_set(tc2, i);
+             evas_textblock_cursor_char_geometry_get(tc2, &cx, &cy, &cw, &ch);
+             if (cx <= limitw)
+               break;
+          }
+
+        if (evas_textblock_cursor_pos_get(tc2) < minshowcount)
+          {
+             evas_textblock_cursor_free(tc1);
+             evas_textblock_cursor_free(tc2);
+
+             return EINA_FALSE;
+          }
+     }
+
+   for (i = 0; i <= minshowcount; i++)
+     evas_textblock_cursor_char_prev(tc2);
+   cutstr = evas_textblock_cursor_range_text_get(tc1, tc2, 
EVAS_TEXTBLOCK_TEXT_PLAIN);
+
+   // FIXME: consider other unicode encoding, currently only care about utf-8
+   lencutstr = strlen(cutstr);
+   elstr = malloc(sizeof(char) * (lencutstr + minshowcount + 1));
+   strcpy(elstr, cutstr);
+   strcat(elstr, ellipsis_string);
+
+   edje_object_part_text_set(wd->lbl, "elm.text", elstr);
+
+   free(elstr);
+   evas_textblock_cursor_free(tc1);
+   evas_textblock_cursor_free(tc2);
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_ellipsis_cut_lines_to_widget(Evas_Object *obj,
+                              int          fontsize,
+                              int          linemode)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+
    const char *ellipsis_string = "...";
-   int minfontsize, maxfontsize, minshowcount;
+   int minshowcount = strlen(ellipsis_string);
+   Evas_Coord w, h;
+   Evas_Textblock_Cursor *tc1, *tc2;
+   int linenum = 0, cutline = 0;
+   double lineheight = 0.0;
+   char *cutstr, *elstr;
+   int lencutstr = 0;
+   int limith = 0;
+   int i;
+
+   edje_object_part_geometry_get(wd->lbl, "elm.text", NULL, NULL, &w, &h);
+
+   tc1 = evas_object_textblock_cursor_new((Evas_Object 
*)edje_object_part_object_get(wd->lbl, "elm.text"));
+   tc2 = evas_object_textblock_cursor_new((Evas_Object 
*)edje_object_part_object_get(wd->lbl, "elm.text"));
+   // goto last paragraph
+   while (evas_textblock_cursor_paragraph_next(tc2) == EINA_TRUE)
+     ;
+   evas_textblock_cursor_paragraph_last(tc2);
+   // get total linenumber
+   linenum = evas_textblock_cursor_line_geometry_get(tc2, NULL, NULL, NULL, 
NULL);
+   lineheight = h / linenum * 1.0;
+   if (wd->wrap_h > 0 && wd->wrap_h < h)
+     limith = wd->wrap_h;
+   else
+     limith = h;
+   cutline = limith / lineheight;
+   if (cutline < 1)
+     cutline = 1;
+
+   evas_textblock_cursor_pos_set(tc1, 0);
+   evas_textblock_cursor_line_set(tc2, cutline - 1);
+   evas_textblock_cursor_line_char_last(tc2);
+   for (i = 0; i <= minshowcount; i++)
+     evas_textblock_cursor_char_prev(tc2);
+   cutstr = evas_textblock_cursor_range_text_get(tc1, tc2, 
EVAS_TEXTBLOCK_TEXT_PLAIN);
+
+   // FIXME: consider other unicode encoding, currently only care about utf-8
+   lencutstr = strlen(cutstr);
+   elstr = malloc(sizeof(char) * (lencutstr + minshowcount + 1));
+   strcpy(elstr, cutstr);
+   strcat(elstr, ellipsis_string);
+
+   edje_object_part_text_set(wd->lbl, "elm.text", elstr);
+
+   free(elstr);
+   evas_textblock_cursor_free(tc1);
+   evas_textblock_cursor_free(tc2);
+
+   return EINA_TRUE;
+}
+
+static void
+_ellipsis_label_to_width(Evas_Object *obj, int linemode)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+
+   int cur_fontsize = 0;
+   char *kvalue;
+   const char *minfont, *deffont, *maxfont;
+   int minfontsize, maxfontsize;
 
-   minshowcount = strlen(ellipsis_string) + 1;
    minfont = edje_object_data_get(wd->lbl, "min_font_size");
    if (minfont) minfontsize = atoi(minfont);
    else minfontsize = 1;
@@ -344,65 +736,40 @@ _ellipsis_label_to_width(Evas_Object *obj)
    deffont = edje_object_data_get(wd->lbl, "default_font_size");
    if (deffont) cur_fontsize = atoi(deffont);
    else cur_fontsize = 1;
-   if ((minfontsize == maxfontsize) || (cur_fontsize == 1)) return; // theme 
is not ready for ellipsis
+   if (minfontsize > maxfontsize || cur_fontsize == 1) return;  // theme is 
not ready for ellipsis
    if (eina_stringshare_strlen(wd->label) <= 0) return;
 
-   if (!_get_value_in_key_string(wd->label, "font_size", &kvalue))
+   if (_get_value_in_key_string(wd->label, "font_size", &kvalue) == 0)
      {
-        if (kvalue) cur_fontsize = atoi((char *)kvalue);
+        if (kvalue != NULL) cur_fontsize = atoi(kvalue);
      }
-   
-   txtbuf = eina_strbuf_new();
-   eina_strbuf_append(txtbuf, wd->label);
-   
-   while (_is_width_over(obj) == 1)
+
+   while (_is_width_over(obj, linemode))
      {
         if (cur_fontsize > minfontsize)
           {
-             cur_fontsize--;
-             if (fontbuf)
-               {
-                  eina_strbuf_free(fontbuf);
-                  fontbuf = NULL;
-               }
-             fontbuf = eina_strbuf_new();
-             eina_strbuf_append_printf(fontbuf, "%d", cur_fontsize);
-             _strbuf_key_value_replace(txtbuf, "font_size", 
eina_strbuf_string_get(fontbuf), 0);
-             edje_object_part_text_set(wd->lbl, "elm.text", 
eina_strbuf_string_get(txtbuf));
-             eina_strbuf_free(fontbuf);
-             fontbuf = NULL;
+             cur_fontsize -= 3;
+             if (cur_fontsize < minfontsize)
+               cur_fontsize = minfontsize;
+             _ellipsis_fontsize_set(obj, cur_fontsize);
           }
         else
           {
-             if (txtbuf)
+             if (linemode == 0) // single line
                {
-                  eina_strbuf_free(txtbuf);
-                  txtbuf = NULL;
+                  _ellipsis_cut_chars_to_widget(obj, cur_fontsize, linemode);
+                  break;
                }
-             txtbuf = eina_strbuf_new();
-             eina_strbuf_append_printf(txtbuf, "%s", 
edje_object_part_text_get(wd->lbl, "elm.text"));
-             len = eina_strbuf_length_get(txtbuf);
-             showcount = len - 1;
-             while (showcount > minshowcount)
+             else // multiline
                {
-                  len = eina_strbuf_length_get(txtbuf);
-                  eina_strbuf_remove(txtbuf, len - minshowcount, len);
-                  eina_strbuf_append(txtbuf, ellipsis_string);
-                  edje_object_part_text_set(wd->lbl, "elm.text", 
eina_strbuf_string_get(txtbuf));
-                  
-                  if (_is_width_over(obj) == 1) 
-                    showcount--;
-                  else 
-                    break;
+                  _ellipsis_cut_lines_to_widget(obj, cur_fontsize, linemode);
+                  break;
                }
           }
      }
-   
-   if (txtbuf) eina_strbuf_free(txtbuf);
-   wd->changed = 1;
-   _sizing_eval(obj);
 }
 
+
 /**
  * Add a new label to the parent
  *
@@ -437,6 +804,8 @@ elm_label_add(Evas_Object *parent)
 
    wd->linewrap = EINA_FALSE;
    wd->ellipsis = EINA_FALSE;
+   wd->wrap_w = 0;
+   wd->wrap_h = 0;
 
    wd->lbl = edje_object_add(e);
    _elm_theme_object_set(obj, wd->lbl, "label", "base", "default");
@@ -505,10 +874,7 @@ elm_label_line_wrap_set(Evas_Object *obj, Eina_Bool wrap)
    if (wd->linewrap == wrap) return;
    wd->linewrap = wrap;
    t = eina_stringshare_add(elm_label_label_get(obj));
-   if (wd->linewrap)
-     _elm_theme_object_set(obj, wd->lbl, "label", "base_wrap", 
elm_widget_style_get(obj));
-   else
-     _elm_theme_object_set(obj, wd->lbl, "label", "base", 
elm_widget_style_get(obj));
+   _theme_change(obj);
    elm_label_label_set(obj, t);
    eina_stringshare_del(t);
    wd->changed = 1;
@@ -544,7 +910,9 @@ elm_label_wrap_width_set(Evas_Object *obj, Evas_Coord w)
    ELM_CHECK_WIDTYPE(obj, widtype);
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return;
+   if (w < 0) w = 0;
    if (wd->wrap_w == w) return;
+   if (wd->ellipsis) edje_object_part_text_set(wd->lbl, "elm.text", wd->label);
    wd->wrap_w = w;
    _sizing_eval(obj);
 }
@@ -566,6 +934,44 @@ elm_label_wrap_width_get(const Evas_Object *obj)
 }
 
 /**
+ * Set wrap height of the label
+ *
+ * @param obj The label object
+ * @param w The wrap width in pixels at a minimum where words need to wrap
+ * @ingroup Label
+ */
+EAPI void
+elm_label_wrap_height_set(Evas_Object *obj,
+                          Evas_Coord   h)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   if (h < 0) h = 0;
+   if (wd->wrap_h == h) return;
+   if (wd->ellipsis) edje_object_part_text_set(wd->lbl, "elm.text", wd->label);
+   wd->wrap_h = h;
+   _sizing_eval(obj);
+}
+
+/**
+ * get wrap width of the label
+ *
+ * @param obj The label object
+ * @return The wrap height in pixels at a minimum where words need to wrap
+ * @ingroup Label
+ */
+EAPI Evas_Coord
+elm_label_wrap_height_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) 0;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return 0;
+   return wd->wrap_h;
+}
+
+/**
+   /**
  * Set the font size on the label object.
  * 
  * NEVER use this. It is for hyper-special cases only. use styles instead. e.g.
@@ -582,24 +988,25 @@ elm_label_fontsize_set(Evas_Object *obj, int fontsize)
 {
    ELM_CHECK_WIDTYPE(obj, widtype);
    Widget_Data *wd = elm_widget_data_get(obj);
-   char fontvalue[16];
-   int len;
-   
+   Eina_Strbuf *fontbuf = NULL;
+   int len, removeflag = 0;
+
    if (!wd) return;
    _elm_dangerous_call_check(__FUNCTION__);
    len = strlen(wd->label);
    if (len <= 0) return;
-   sprintf(fontvalue, "%i", fontsize);
-   
-   if (!_stringshare_key_value_replace(&wd->label, "font_size", fontvalue, 0))
-     edje_object_part_text_set(wd->lbl, "elm.text", wd->label);
-   
-   if (!fontsize) // remove fontsize tag
-     _stringshare_key_value_replace(&wd->label, "font_size", fontvalue, 1);
-   
-   wd->changed = 1;
-   _sizing_eval(obj);
+   fontbuf = eina_strbuf_new();
+   eina_strbuf_append_printf(fontbuf, "%d", fontsize);
+
+   if (fontsize == 0) removeflag = 1;  // remove fontsize tag
 
+   if (_stringshare_key_value_replace(&wd->label, "font_size", 
eina_strbuf_string_get(fontbuf), removeflag) == 0)
+     {
+        edje_object_part_text_set(wd->lbl, "elm.text", wd->label);
+        wd->changed = 1;
+        _sizing_eval(obj);
+     }
+   eina_strbuf_free(fontbuf);
 }
 
 /**
@@ -610,7 +1017,7 @@ elm_label_fontsize_set(Evas_Object *obj, int fontsize)
  * "title", "footnote", "quote" etc.
  *
  * @param obj The label object
- * @param align align mode
+ * @param align align mode ("left", "center", "right")
  *
  * @ingroup Label
  */
@@ -626,7 +1033,7 @@ elm_label_text_align_set(Evas_Object *obj, const char 
*alignmode)
    len = strlen(wd->label);
    if (len <= 0) return;
 
-   if (!_stringshare_key_value_replace(&wd->label, "align", alignmode, 0))
+   if (_stringshare_key_value_replace(&wd->label, "align", alignmode, 0) == 0)
      edje_object_part_text_set(wd->lbl, "elm.text", wd->label);
 
    wd->changed = 1;
@@ -636,41 +1043,42 @@ elm_label_text_align_set(Evas_Object *obj, const char 
*alignmode)
 /**
  * Set the text color on the label object
  *
- * NEVER use this. It is for hyper-special cases only. use styles instead. e.g.
- * "big", "medium", "small" - or better name them by use:
- * "title", "footnote", "quote" etc.
- *
  * @param obj The label object
- * @param r Red property background color of The label object 
- * @param g Green property background color of The label object 
- * @param b Blue property background color of The label object 
- * @param a Alpha property background alpha of The label object 
+ * @param r Red property background color of The label object
+ * @param g Green property background color of The label object
+ * @param b Blue property background color of The label object
+ * @param a Alpha property background color of The label object
  *
  * @ingroup Label
  */
 EAPI void
-elm_label_text_color_set(Evas_Object *obj, unsigned int r, unsigned int g, 
unsigned int b, unsigned int a)
+elm_label_text_color_set(Evas_Object *obj,
+                         unsigned int r,
+                         unsigned int g,
+                         unsigned int b,
+                         unsigned int a)
 {
    ELM_CHECK_WIDTYPE(obj, widtype);
    Widget_Data *wd = elm_widget_data_get(obj);
-   char colorstring[16];
+   Eina_Strbuf *colorbuf = NULL;
    int len;
 
    if (!wd) return;
    _elm_dangerous_call_check(__FUNCTION__);
    len = strlen(wd->label);
    if (len <= 0) return;
-   sprintf(colorstring, "#%02x%02x%02x%02x", r, g, b, a);
+   colorbuf = eina_strbuf_new();
+   eina_strbuf_append_printf(colorbuf, "#%02X%02X%02X%02X", r, g, b, a);
 
-   if (!_stringshare_key_value_replace(&wd->label, "color", colorstring, 0))
+   if (_stringshare_key_value_replace(&wd->label, "color", 
eina_strbuf_string_get(colorbuf), 0) == 0)
      {
         edje_object_part_text_set(wd->lbl, "elm.text", wd->label);
         wd->changed = 1;
         _sizing_eval(obj);
      }
+   eina_strbuf_free(colorbuf);
 }
 
-
 /**
  * Set background color of the label
  *
@@ -683,15 +1091,21 @@ elm_label_text_color_set(Evas_Object *obj, unsigned int 
r, unsigned int g, unsig
  * @param g Green property background color of The label object 
  * @param b Blue property background color of The label object 
  * @param a Alpha property background alpha of The label object 
+ *
  * @ingroup Label
  */
 EAPI void
-elm_label_background_color_set(Evas_Object *obj, unsigned int r, unsigned int 
g, unsigned int b, unsigned int a)
+elm_label_background_color_set(Evas_Object *obj,
+                               unsigned int r,
+                               unsigned int g,
+                               unsigned int b,
+                               unsigned int a)
 {
    ELM_CHECK_WIDTYPE(obj, widtype);
    Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
    evas_object_color_set(wd->bg, r, g, b, a);
-   
+
    if (!wd) return;
    _elm_dangerous_call_check(__FUNCTION__);
    if (wd->bgcolor == EINA_FALSE)
@@ -716,6 +1130,8 @@ elm_label_ellipsis_set(Evas_Object *obj, Eina_Bool 
ellipsis)
    if (!wd) return;
    if (wd->ellipsis == ellipsis) return;
    wd->ellipsis = ellipsis;
+   if (wd->linewrap) _theme_change(obj);
+   edje_object_part_text_set(wd->lbl, "elm.text", wd->label);
    wd->changed = 1;
    _sizing_eval(obj);
 }
-- 
1.7.1

>From f977187d8c0bc24bed21beb40b36bf245f5075cc Mon Sep 17 00:00:00 2001
From: Hyoyoung Chang <hyoyoung.ch...@samsung.com>
Date: Wed, 15 Dec 2010 20:29:25 +0900
Subject: [PATCH 2/3] export label wrap height get/set functions

---
 src/lib/Elementary.h.in |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/src/lib/Elementary.h.in b/src/lib/Elementary.h.in
index d00cfaf..3a0a1e2 100644
--- a/src/lib/Elementary.h.in
+++ b/src/lib/Elementary.h.in
@@ -801,6 +801,8 @@ extern "C" {
    EAPI Eina_Bool    elm_label_line_wrap_get(const Evas_Object *obj) 
EINA_ARG_NONNULL(1);
    EAPI void         elm_label_wrap_width_set(Evas_Object *obj, Evas_Coord w) 
EINA_ARG_NONNULL(1);
    EAPI Evas_Coord   elm_label_wrap_width_get(const Evas_Object *obj) 
EINA_ARG_NONNULL(1);
+   EAPI void         elm_label_wrap_height_set(Evas_Object *obj, Evas_Coord h) 
EINA_ARG_NONNULL(1);
+   EAPI Evas_Coord   elm_label_wrap_height_get(const Evas_Object *obj) 
EINA_ARG_NONNULL(1);
    EAPI void         elm_label_fontsize_set(Evas_Object *obj, int fontsize) 
EINA_ARG_NONNULL(1);
    EAPI void         elm_label_text_color_set(Evas_Object *obj, unsigned int 
r, unsigned int g, unsigned int b, unsigned int a) EINA_ARG_NONNULL(1);
    EAPI void         elm_label_text_align_set(Evas_Object *obj, const char 
*alignmode) EINA_ARG_NONNULL(1);
-- 
1.7.1

>From f514c8cf30abb846a0428aad90e1eab298a0c3ca Mon Sep 17 00:00:00 2001
From: Hyoyoung Chang <hyoyoung.ch...@samsung.com>
Date: Wed, 15 Dec 2010 20:30:04 +0900
Subject: [PATCH 3/3] add label text sliding feature

---
 data/themes/default.edc |  451 +++++++++++++++++++++++++++++++++++++++++++++--
 src/lib/Elementary.h.in |    4 +
 src/lib/elm_label.c     |  138 +++++++++++++++
 3 files changed, 581 insertions(+), 12 deletions(-)

diff --git a/data/themes/default.edc b/data/themes/default.edc
index 79ae9ef..73b0095 100644
--- a/data/themes/default.edc
+++ b/data/themes/default.edc
@@ -1388,6 +1388,8 @@ collections {
    }
 
 ///////////////////////////////////////////////////////////////////////////////
+#define TEXT_SLIDE_DURATION     10
+
    group { name: "elm/label/base/default";
       data.item: "default_font_size" "24";
       data.item: "min_font_size" "8";
@@ -1403,23 +1405,31 @@ collections {
           }
        }
       parts {
-         part { name: "label.swallow.background";
-            type: SWALLOW;
-            description { state: "default" 0.0;
-               visible: 1;
-               rel1 { relative: 0 0; to: "elm.text"; }
-               rel2 { relative: 1 1; to: "elm.text"; }
-            }
-         }
+        part { name: "label.swallow.background";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+                  visible: 1;
+           }
+     }
+        part { name: "label.text.clip";
+               type: RECT;
+           description { state: "default" 0.0;
+                  rel1 { relative: 0 0; to: "label.swallow.background"; }
+                  rel2 { relative: 1 1; to: "label.swallow.background"; }
+           }
+        }
         part { name: "elm.text";
            type: TEXTBLOCK;
            mouse_events: 0;
            scale: 1;
+           clip_to: "label.text.clip";
            description { state: "default" 0.0;
-              text {
-                 style: "textblock_style";
-                 min: 1 1;
-              }
+                       rel1.relative, 0.0 0.0;
+                       rel2.relative, 1.0 1.0;
+                       text {
+                               style: "textblock_style";
+                               min: 1 0;
+                       }
            }
         }
       }
@@ -1547,6 +1557,423 @@ collections {
       }
    }
 
+    group { name: "elm/label/base/slide_long";
+      data.item: "default_font_size" "24";
+      data.item: "min_font_size" "8";
+      data.item: "max_font_size" "60";
+
+       script {
+               public g_duration, g_stopslide, g_timer_id, g_anim_id;
+               
+               public message(Msg_Type:type, id, ...) {
+                       if( (type==MSG_INT_SET) && (id==0) )
+                       {
+                               new duration;
+                               duration = getarg(2);
+                               set_int(g_duration, duration);
+                       }
+               }
+               public slide_to_end_anim(val, Float:pos)
+               {
+                       new stopflag;
+                       new id;
+                       stopflag = get_int(g_stopslide);
+                       if (stopflag == 1) return;
+                       set_tween_state(PART:"elm.text", pos, "slide_begin", 
0.0, "slide_end", 0.0);
+                       if (pos >=1.0) {
+                               id = timer(0.5, "slide_to_begin", 1);
+                               set_int(g_timer_id, id);
+                       }
+               }
+               public slide_to_end()
+               {
+                       new stopflag;
+                       new id;
+                       new duration;
+                       stopflag = get_int(g_stopslide);
+                       if (stopflag == 1) return;
+                       duration = get_int(g_duration);
+                       id = anim(duration, "slide_to_end_anim", 1);
+                       set_int(g_anim_id, id);
+
+               }
+               public slide_to_begin()
+               {
+                       new stopflag;
+                       new id;
+                       stopflag = get_int(g_stopslide);
+                       if (stopflag == 1) return;
+                       set_state(PART:"elm.text", "slide_begin", 0.0);
+                       id = timer(0.5, "slide_to_end", 1);
+                       set_int(g_timer_id, id);
+               }
+               public start_slide()
+               {
+                       set_int(g_stopslide, 0);
+                       set_state(PART:"elm.text", "slide_begin", 0.0);
+                       slide_to_end();
+               }
+               public stop_slide()
+               {
+                       new id;
+                       set_int(g_stopslide, 1);
+                       id = get_int(g_anim_id);
+                       cancel_anim(id);
+                       id = get_int(g_timer_id);
+                       cancel_timer(id);
+                       set_state(PART:"elm.text", "default", 0.0);
+               }
+       }
+
+      parts {
+        part { name: "label.swallow.background";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+                  visible: 1;
+           }
+     }
+        part { name: "label.text.clip";
+               type: RECT;
+           description { state: "default" 0.0;
+                  visible: 1;
+                  color: 255 255 255 255;
+                  rel1 { relative: 0 0; to: "label.swallow.background"; }
+                  rel2 { relative: 1 1; to: "label.swallow.background"; }
+           }
+        }
+        part { name: "elm.text";
+           type: TEXTBLOCK;
+           mouse_events: 0;
+           scale: 1;
+           clip_to: "label.text.clip";
+           description { state: "default" 0.0;
+                       rel1.relative, 0.0 0.0;
+                       rel2.relative, 1.0 1.0;
+                       align, 0.0 0.0;
+                       text {
+                               style: "textblock_style";
+                               min: 1 0;
+                       }
+           }
+               description { state, "slide_end" 0.0;
+                       inherit, "default" 0.0;
+                       rel1.relative, 0.0 0.0;
+                       rel2.relative, 0.0 1.0;
+                       align, 1.0 0.0;
+               }
+               description { state, "slide_begin" 0.0;
+                       inherit, "default" 0.0;
+                       rel1.relative, 1.0 0.0;
+                       rel2.relative, 1.0 1.0;
+                       align, 0.0 0.0;
+               }
+
+        }
+      }
+         programs
+         {
+               program { name, "start_slide";
+                       source: "elm";
+                       signal: "elm,state,slide,start";
+                       script
+                       {
+                               start_slide();
+                       }
+               }
+               program { name, "stop_slide";
+                       source: "elm";
+                       signal: "elm,state,slide,stop";
+                       script
+                       {
+                               stop_slide();
+                       }
+               }
+         }
+   }
+
+
+   group { name: "elm/label/base/slide_short";
+      data.item: "default_font_size" "24";
+      data.item: "min_font_size" "8";
+      data.item: "max_font_size" "60";
+
+       script {
+               public g_duration, g_stopslide, g_timer_id, g_anim_id;
+               
+               public message(Msg_Type:type, id, ...) {
+                       if( (type==MSG_INT_SET) && (id==0) )
+                       {
+                               new duration;
+                               duration = getarg(2);
+                               set_int(g_duration, duration);
+                       }
+               }
+               public slide_to_end_anim(val, Float:pos)
+               {
+                       new stopflag;
+                       new id;
+                       stopflag = get_int(g_stopslide);
+                       if (stopflag == 1) return;
+                       set_tween_state(PART:"elm.text", pos, "slide_begin", 
0.0, "slide_end", 0.0);
+                       if (pos >=1.0) {
+                               id = timer(0.5, "slide_to_begin", 1);
+                               set_int(g_timer_id, id);
+                       }
+               }
+               public slide_to_end()
+               {
+                       new stopflag;
+                       new id;
+                       new duration;
+                       stopflag = get_int(g_stopslide);
+                       if (stopflag == 1) return;
+                       duration = get_int(g_duration);
+                       id = anim(duration, "slide_to_end_anim", 1);
+                       set_int(g_anim_id, id);
+
+               }
+               public slide_to_begin()
+               {
+                       new stopflag;
+                       new id;
+                       stopflag = get_int(g_stopslide);
+                       if (stopflag == 1) return;
+                       set_state(PART:"elm.text", "slide_begin", 0.0);
+                       id = timer(0.5, "slide_to_end", 1);
+                       set_int(g_timer_id, id);
+               }
+               public start_slide()
+               {
+                       set_int(g_stopslide, 0);
+                       set_state(PART:"elm.text", "slide_begin", 0.0);
+                       slide_to_end();
+               }
+               public stop_slide()
+               {
+                       new id;
+                       set_int(g_stopslide, 1);
+                       id = get_int(g_anim_id);
+                       cancel_anim(id);
+                       id = get_int(g_timer_id);
+                       cancel_timer(id);
+                       set_state(PART:"elm.text", "default", 0.0);
+               }
+       }
+
+      parts {
+        part { name: "label.swallow.background";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+                  visible: 1;
+           }
+     }
+        part { name: "label.text.clip";
+               type: RECT;
+           description { state: "default" 0.0;
+                  visible: 1;
+                  color: 255 255 255 255;
+                  rel1 { relative: 0 0; to: "label.swallow.background"; }
+                  rel2 { relative: 1 1; to: "label.swallow.background"; }
+           }
+        }
+        part { name: "elm.text";
+           type: TEXTBLOCK;
+           mouse_events: 0;
+           scale: 1;
+           clip_to: "label.text.clip";
+           description { state: "default" 0.0;
+                       rel1.relative, 0.0 0.0;
+                       rel2.relative, 1.0 1.0;
+                       align, 0.0 0.0;
+                       text {
+                               style: "textblock_style";
+                               min: 1 0;
+                       }
+           }
+               description { state, "slide_end" 0.0;
+                       inherit, "default" 0.0;
+                       rel1.relative, 1.0 0.0;
+                       rel2.relative, 1.0 1.0;
+                       align, 1.0 0.0;
+               }
+               description { state, "slide_begin" 0.0;
+                       inherit, "default" 0.0;
+                       rel1.relative, 0.0 0.0;
+                       rel2.relative, 0.0 1.0;
+                       align, 0.0 0.0;
+               }
+
+        }
+      }
+         programs
+         {
+               program { name, "start_slide";
+                       source: "elm";
+                       signal: "elm,state,slide,start";
+                       script
+                       {
+                               start_slide();
+                       }
+               }
+               program { name, "stop_slide";
+                       source: "elm";
+                       signal: "elm,state,slide,stop";
+                       script
+                       {
+                               stop_slide();
+                       }
+               }
+         }
+   }
+
+   group { name: "elm/label/base/slide_bounce";
+      data.item: "default_font_size" "24";
+      data.item: "min_font_size" "8";
+      data.item: "max_font_size" "60";
+
+       script {
+               public g_duration, g_stopslide, g_timer_id, g_anim_id;
+               
+               public message(Msg_Type:type, id, ...) {
+                       if( (type==MSG_INT_SET) && (id==0) )
+                       {
+                               new duration;
+                               duration = getarg(2);
+                               set_int(g_duration, duration);
+                       }
+               }
+               public slide_to_end_anim(val, Float:pos)
+               {
+                       new stopflag;
+                       new id;
+                       stopflag = get_int(g_stopslide);
+                       if (stopflag == 1) return;
+                       set_tween_state(PART:"elm.text", pos, "slide_begin", 
0.0, "slide_end", 0.0);
+                       if (pos >=1.0) {
+                               id = timer(0.5, "slide_to_begin", 1);
+                               set_int(g_timer_id, id);
+                       }
+               }
+               public slide_to_end()
+               {
+                       new stopflag;
+                       new id;
+                       new duration;
+                       stopflag = get_int(g_stopslide);
+                       if (stopflag == 1) return;
+                       duration = get_int(g_duration);
+                       id = anim(duration, "slide_to_end_anim", 1);
+                       set_int(g_anim_id, id);
+
+               }
+               public slide_to_begin_anim(val, Float:pos)
+               {
+                       new stopflag;
+                       new id;
+                       stopflag = get_int(g_stopslide);
+                       if (stopflag == 1) return;
+                       set_tween_state(PART:"elm.text", pos, "slide_end", 0.0, 
"slide_begin", 0.0);
+                       if (pos >=1.0) {
+                               id = timer(0.5, "slide_to_end", 1);
+                               set_int(g_timer_id, id);
+                       }
+               }
+               public slide_to_begin()
+               {
+                       new stopflag;
+                       new id;
+                       new duration;
+                       stopflag = get_int(g_stopslide);
+                       if (stopflag == 1) return;
+                       duration = get_int(g_duration);
+                       id = anim(duration, "slide_to_begin_anim", 1);
+                       set_int(g_anim_id, id);
+               }
+               public start_slide()
+               {
+                       set_int(g_stopslide, 0);
+                       set_state(PART:"elm.text", "slide_begin", 0.0);
+                       slide_to_end();
+               }
+               public stop_slide()
+               {
+                       new id;
+                       set_int(g_stopslide, 1);
+                       id = get_int(g_anim_id);
+                       cancel_anim(id);
+                       id = get_int(g_timer_id);
+                       cancel_timer(id);
+                       set_state(PART:"elm.text", "default", 0.0);
+               }
+       }
+
+      parts {
+        part { name: "label.swallow.background";
+           type: SWALLOW;
+           description { state: "default" 0.0;
+                  visible: 1;
+           }
+     }
+        part { name: "label.text.clip";
+               type: RECT;
+           description { state: "default" 0.0;
+                  visible: 1;
+                  color: 255 255 255 255;
+                  rel1 { relative: 0 0; to: "label.swallow.background"; }
+                  rel2 { relative: 1 1; to: "label.swallow.background"; }
+           }
+        }
+        part { name: "elm.text";
+           type: TEXTBLOCK;
+           mouse_events: 0;
+           scale: 1;
+           clip_to: "label.text.clip";
+           description { state: "default" 0.0;
+                       rel1.relative, 0.0 0.0;
+                       rel2.relative, 1.0 1.0;
+                       align, 0.0 0.0;
+                       text {
+                               style: "textblock_style";
+                               min: 1 0;
+                       }
+           }
+               description { state, "slide_end" 0.0;
+                       inherit, "default" 0.0;
+                       rel1.relative, 1.0 0.0;
+                       rel2.relative, 1.0 1.0;
+                       align, 1.0 0.0;
+               }
+               description { state, "slide_begin" 0.0;
+                       inherit, "default" 0.0;
+                       rel1.relative, 0.0 0.0;
+                       rel2.relative, 0.0 1.0;
+                       align, 0.0 0.0;
+               }
+
+        }
+      }
+         programs
+         {
+               program { name, "start_slide";
+                       source: "elm";
+                       signal: "elm,state,slide,start";
+                       script
+                       {
+                               start_slide();
+                       }
+               }
+               program { name, "stop_slide";
+                       source: "elm";
+                       signal: "elm,state,slide,stop";
+                       script
+                       {
+                               stop_slide();
+                       }
+               }
+         }
+   }
+
+
 ///////////////////////////////////////////////////////////////////////////////
 
    group { name: "elm/button/base/default";
diff --git a/src/lib/Elementary.h.in b/src/lib/Elementary.h.in
index 3a0a1e2..bfeb18d 100644
--- a/src/lib/Elementary.h.in
+++ b/src/lib/Elementary.h.in
@@ -808,6 +808,10 @@ extern "C" {
    EAPI void         elm_label_text_align_set(Evas_Object *obj, const char 
*alignmode) EINA_ARG_NONNULL(1);
    EAPI void         elm_label_background_color_set(Evas_Object *obj, unsigned 
int r, unsigned int g, unsigned int b, unsigned int a) EINA_ARG_NONNULL(1);
    EAPI void         elm_label_ellipsis_set(Evas_Object *obj, Eina_Bool 
ellipsis) EINA_ARG_NONNULL(1);
+   EAPI void         elm_label_slide_set(Evas_Object *obj, Eina_Bool slide) 
EINA_ARG_NONNULL(1);
+   EAPI Eina_Bool    elm_label_slide_get(Evas_Object *obj) EINA_ARG_NONNULL(1);
+   EAPI void         elm_label_slide_duration_set(Evas_Object *obj, int 
duration) EINA_ARG_NONNULL(1);
+   EAPI int          elm_label_slide_duration_get(Evas_Object *obj) 
EINA_ARG_NONNULL(1);
    /* available styles:
     * default
     * marker
diff --git a/src/lib/elm_label.c b/src/lib/elm_label.c
index 126c15b..4c84094 100644
--- a/src/lib/elm_label.c
+++ b/src/lib/elm_label.c
@@ -23,6 +23,9 @@ struct _Widget_Data
    Eina_Bool changed : 1;
    Eina_Bool bgcolor : 1;
    Eina_Bool ellipsis : 1;
+   Eina_Bool slidingmode : 1;
+   Eina_Bool slidingellipsis : 1;
+   int          slide_duration;
 };
 
 static const char *widtype = NULL;
@@ -769,6 +772,58 @@ _ellipsis_label_to_width(Evas_Object *obj, int linemode)
      }
 }
 
+void
+_label_sliding_change(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+
+   // dosen't support multiline sliding effect
+   if (wd->linewrap)
+     { 
+        wd->slidingmode = EINA_FALSE;
+        return;
+     }
+
+   char *plaintxt = _mkup_to_text(edje_object_part_text_get(wd->lbl, 
"elm.text"));
+   int plainlen = 0;
+   if (plaintxt != NULL)
+     {
+        plainlen = strlen(plaintxt);
+        free(plaintxt);
+     }
+   // too short to slide label
+   if (plainlen < 1)
+     {
+        wd->slidingmode = EINA_TRUE;
+        return;
+     }
+
+   if (wd->slidingmode)
+     {
+        if (wd->ellipsis)
+          {
+             wd->slidingellipsis = EINA_TRUE;
+             elm_label_ellipsis_set(obj, EINA_FALSE);
+          }
+        Edje_Message_Int_Set *msg = alloca(sizeof(Edje_Message_Int_Set) + 
(sizeof(int)));
+
+        msg->count = 1;
+        msg->val[0] = (int)wd->slide_duration;
+
+        edje_object_message_send(wd->lbl, EDJE_MESSAGE_INT_SET, 0, msg);
+        edje_object_signal_emit(wd->lbl, "elm,state,slide,start", "elm");
+     }
+   else
+     {
+        edje_object_signal_emit(wd->lbl, "elm,state,slide,stop", "elm");
+        if (wd->slidingellipsis)
+          {
+             wd->slidingellipsis = EINA_FALSE;
+             elm_label_ellipsis_set(obj, EINA_TRUE);
+          }
+     }
+}
 
 /**
  * Add a new label to the parent
@@ -804,8 +859,11 @@ elm_label_add(Evas_Object *parent)
 
    wd->linewrap = EINA_FALSE;
    wd->ellipsis = EINA_FALSE;
+   wd->slidingmode = EINA_FALSE;
+   wd->slidingellipsis = EINA_FALSE;
    wd->wrap_w = 0;
    wd->wrap_h = 0;
+   wd->slide_duration = 10;
 
    wd->lbl = edje_object_add(e);
    _elm_theme_object_set(obj, wd->lbl, "label", "base", "default");
@@ -1135,3 +1193,83 @@ elm_label_ellipsis_set(Evas_Object *obj, Eina_Bool 
ellipsis)
    wd->changed = 1;
    _sizing_eval(obj);
 }
+
+/**
+ * Set the text slide of the label
+ *
+ * @param obj The label object
+ * @param slide To start slide or stop
+ * @ingroup Label
+ */
+EAPI void
+elm_label_slide_set(Evas_Object *obj,
+                    Eina_Bool    slide)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+
+   if (wd->slidingmode == slide) return;
+   wd->slidingmode = slide;
+   _label_sliding_change(obj);
+   wd->changed = 1;
+   _sizing_eval(obj);
+}
+
+/**
+ * get the text slide mode of the label
+ *
+ * @param obj The label object
+ * @return slide slide mode value
+ * @ingroup Label
+ */
+EAPI Eina_Bool
+elm_label_slide_get(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+
+   return wd->slidingmode;
+}
+
+/**
+ * set the slide duration(speed) of the label
+ *
+ * @param obj The label object
+ * @return The duration time in moving text from slide begin position to slide 
end position
+ * @ingroup Label
+ */
+EAPI void
+elm_label_slide_duration_set(Evas_Object *obj,
+                             int          duration)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Edje_Message_Int_Set *msg = alloca(sizeof(Edje_Message_Int_Set) + 
(sizeof(int)));
+
+   if (!wd) return;
+   wd->slide_duration = duration;
+
+   msg->count = 1;
+   msg->val[0] = (int)wd->slide_duration;
+
+   edje_object_message_send(wd->lbl, EDJE_MESSAGE_INT_SET, 0, msg);
+}
+
+/**
+ * get the slide duration(speed) of the label
+ *
+ * @param obj The label object
+ * @return The duration time in moving text from slide begin position to slide 
end position
+ * @ingroup Label
+ */
+EAPI int
+elm_label_slide_duration_get(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) 0;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return 0;
+   return wd->slide_duration;
+}
+
-- 
1.7.1

------------------------------------------------------------------------------
Lotusphere 2011
Register now for Lotusphere 2011 and learn how
to connect the dots, take your collaborative environment
to the next level, and enter the era of Social Business.
http://p.sf.net/sfu/lotusphere-d2d
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to