From: Hyoyoung Chang <hyoyoung.chang@samsung.com>
authorHyoyoung Chang <hyoyoung.chang@samsung.com>
Mon, 20 Dec 2010 08:55:06 +0000 (08:55 +0000)
committerCarsten Haitzler <raster@rasterman.com>
Mon, 20 Dec 2010 08:55:06 +0000 (08:55 +0000)
Subject: Re: [E-devel] elm_label patch(ellipsis, sliding)

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)

 2. adding label text sliding feature

SVN revision: 55654

data/themes/default.edc
src/lib/Elementary.h.in
src/lib/elm_label.c

index 06b6b760337f9d5db35609428425f5917f2f0884..18d4f59e37e4ec08d865ca837b201e9b25dca9d3 100644 (file)
@@ -1388,9 +1388,11 @@ collections {
    }
 
 ///////////////////////////////////////////////////////////////////////////////
+#define TEXT_SLIDE_DURATION     10
+
    group { name: "elm/label/base/default";
-      data.item: "default_font_size" "24";
-      data.item: "min_font_size" "8";
+      data.item: "default_font_size" "10";
+      data.item: "min_font_size" "6";
       data.item: "max_font_size" "60";
       styles {
          style { name: "textblock_style";
@@ -1403,31 +1405,39 @@ collections {
           }
        }
       parts {
-         part { name: "label.swallow.background";
-            type: SWALLOW;
-            description { state: "default" 0.0;
+        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.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;
+               }
            }
         }
       }
    }
 
    group { name: "elm/label/base_wrap/default";
-      data.item: "default_font_size" "24";
-      data.item: "min_font_size" "8";
+      data.item: "default_font_size" "10";
+      data.item: "min_font_size" "6";
       data.item: "max_font_size" "60";
       parts {
          part { name: "label.swallow.background";
@@ -1482,8 +1492,8 @@ collections {
    }
 
    group { name: "elm/label/base/marker";
-      data.item: "default_font_size" "24";
-      data.item: "min_font_size" "8";
+      data.item: "default_font_size" "10";
+      data.item: "min_font_size" "6";
       data.item: "max_font_size" "60";
       styles {
          style { name: "textblock_style2";
@@ -1519,8 +1529,8 @@ collections {
    }
 
    group { name: "elm/label/base_wrap/marker";
-      data.item: "default_font_size" "24";
-      data.item: "min_font_size" "8";
+      data.item: "default_font_size" "10";
+      data.item: "min_font_size" "6";
       data.item: "max_font_size" "60";
       parts {
          part { name: "label.swallow.background";
@@ -1545,6 +1555,395 @@ collections {
       }
    }
 
+   group { name: "elm/label/base/slide_long";
+      data.item: "default_font_size" "10";
+      data.item: "min_font_size" "6";
+      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_FLOAT_SET) && (id == 0)) {
+              new Float:duration;
+              duration = getarg(2);
+              set_float(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 Float:duration;
+           stopflag = get_int(g_stopslide);
+           if (stopflag == 1) return;
+           duration = get_float(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" "10";
+      data.item: "min_font_size" "6";
+      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_FLOAT_SET) && (id == 0)) {
+               new Float:duration;
+               duration = getarg(2);
+               set_float(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 Float:duration;
+            stopflag = get_int(g_stopslide);
+            if (stopflag == 1) return;
+            duration = get_float(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" "10";
+      data.item: "min_font_size" "6";
+      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_FLOAT_SET) && (id == 0)) {
+               new Float:duration;
+               duration = getarg(2);
+               set_float(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 Float:duration;
+            stopflag = get_int(g_stopslide);
+            if (stopflag == 1) return;
+            duration = get_float(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 Float:duration;
+            stopflag = get_int(g_stopslide);
+            if (stopflag == 1) return;
+            duration = get_float(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";
index 31cdac32ce0dcc468a5ed5d94f1c9af500909614..a536be1ed16e3837e56cc2b8d4e4fe2a032e0799 100644 (file)
@@ -811,6 +811,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, double duration) EINA_ARG_NONNULL(1);
+   EAPI double       elm_label_slide_duration_get(Evas_Object *obj) EINA_ARG_NONNULL(1);
    /* available styles:
     * default
     * marker
index 7ee4237f68b1b9fcfa6f602524b047f888d0494b..7665d71ed29c1b6b715144985b5a26685a9932cd 100644 (file)
@@ -15,14 +15,17 @@ struct _Widget_Data
    Evas_Object *lbl;
    Evas_Object *bg;
    const char *label;
-   Evas_Coord lastw;
    Ecore_Job *deferred_recalc_job;
+   double slide_duration;
+   Evas_Coord lastw;
    Evas_Coord wrap_w;
    Evas_Coord wrap_h;
    Eina_Bool linewrap : 1;
    Eina_Bool changed : 1;
    Eina_Bool bgcolor : 1;
    Eina_Bool ellipsis : 1;
+   Eina_Bool slidingmode : 1;
+   Eina_Bool slidingellipsis : 1;
 };
 
 static const char *widtype = NULL;
@@ -34,6 +37,7 @@ static int _strbuf_key_value_replace(Eina_Strbuf *srcbuf, const char *key, const
 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, Eina_Bool multiline);
 static void _ellipsis_label_to_width(Evas_Object *obj, Eina_Bool multiline);
+static void _label_sliding_change(Evas_Object *obj);
 
 static void
 _elm_win_recalc_job(void *data)
@@ -108,6 +112,7 @@ _theme_hook(Evas_Object *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);
+   _label_sliding_change(obj);
    _sizing_eval(obj);
 }
 
@@ -561,6 +566,60 @@ _ellipsis_label_to_width(Evas_Object *obj, Eina_Bool multiline)
      }
 }
 
+static void
+_label_sliding_change(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   char *plaintxt;
+   int plainlen = 0;
+   
+   // dosen't support multiline sliding effect
+   if (wd->linewrap)
+     { 
+        wd->slidingmode = EINA_FALSE;
+        return;
+     }
+
+   plaintxt = _elm_util_mkup_to_text(edje_object_part_text_get(wd->lbl, "elm.text"));
+   if (plaintxt != NULL)
+     {
+        plainlen = strlen(plaintxt);
+        free(plaintxt);
+     }
+   // too short to slide label
+   if (plainlen < 1)
+     {
+        wd->slidingmode = EINA_TRUE;
+        return;
+     }
+
+   if (wd->slidingmode)
+     {
+        Edje_Message_Float_Set *msg = alloca(sizeof(Edje_Message_Float_Set) + (sizeof(double)));
+        
+        if (wd->ellipsis)
+          {
+             wd->slidingellipsis = EINA_TRUE;
+             elm_label_ellipsis_set(obj, EINA_FALSE);
+          }
+        
+        msg->count = 1;
+        msg->val[0] = wd->slide_duration;
+
+        edje_object_message_send(wd->lbl, EDJE_MESSAGE_FLOAT_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
@@ -596,8 +655,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");
@@ -926,3 +988,79 @@ 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, double duration)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   Edje_Message_Float_Set *msg = alloca(sizeof(Edje_Message_Float_Set) + (sizeof(double)));
+
+   if (!wd) return;
+   wd->slide_duration = duration;
+   msg->count = 1;
+   msg->val[0] = wd->slide_duration;
+   edje_object_message_send(wd->lbl, EDJE_MESSAGE_FLOAT_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 double
+elm_label_slide_duration_get(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) 0.0;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return 0;
+   return wd->slide_duration;
+}
+