From: Hyoyoung Chang <hyoyoung.chang@samsung.com>

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
This commit is contained in:
Hyoyoung Chang 2010-12-20 08:55:06 +00:00 committed by Carsten Haitzler
parent 0c61ced335
commit 95032260a7
3 changed files with 560 additions and 19 deletions

View 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";

View 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

View 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;
}