elementary - removed deprecated widgets & APIs.
[framework/uifw/elementary.git] / src / lib / elm_label.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 typedef struct _Widget_Data Widget_Data;
5
6 struct _Widget_Data
7 {
8    Evas_Object *lbl;
9    Evas_Object *bg;
10    const char *label;
11    const char *format;
12    Ecore_Job *deferred_recalc_job;
13    double slide_duration;
14    Evas_Coord lastw;
15    Evas_Coord wrap_w;
16    Evas_Coord wrap_h;
17    Elm_Wrap_Type linewrap;
18    Eina_Bool changed : 1;
19    Eina_Bool bgcolor : 1;
20    Eina_Bool ellipsis : 1;
21    Eina_Bool slidingmode : 1;
22    Eina_Bool slidingellipsis : 1;
23 };
24
25 static const char *widtype = NULL;
26 static void _del_hook(Evas_Object *obj);
27 static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl);
28 static void _theme_hook(Evas_Object *obj);
29 static void _sizing_eval(Evas_Object *obj);
30 static int _get_value_in_key_string(const char *oldstring, const char *key, char **value);
31 static int _strbuf_key_value_replace(Eina_Strbuf *srcbuf, const char *key, const char *value, int deleteflag);
32 static int _stringshare_key_value_replace(const char **srcstring, const char *key, const char *value, int deleteflag);
33 static int _is_width_over(Evas_Object *obj);
34 static void _ellipsis_label_to_width(Evas_Object *obj);
35 static void _label_sliding_change(Evas_Object *obj);
36
37 static void
38 _elm_win_recalc_job(void *data)
39 {
40    Widget_Data *wd = elm_widget_data_get(data);
41    Evas_Coord minw = -1, minh = -1;
42    Evas_Coord resw, resh;
43
44    if (!wd) return;
45    wd->deferred_recalc_job = NULL;
46
47    evas_object_geometry_get(wd->lbl, NULL, NULL, &resw, &resh);
48    if (wd->wrap_w > resw)
49      resw = wd->wrap_w;
50    if (wd->wrap_h > resh)
51      resh = wd->wrap_h;
52
53    if (wd->wrap_h == -1) /* open source routine */
54      {
55         edje_object_size_min_restricted_calc(wd->lbl, &minw, &minh, resw, 0);
56         /* This is a hack to workaround the way min size hints are treated.
57          * If the minimum width is smaller than the restricted width, it means
58          * the mininmum doesn't matter. */
59         if ((minw <= resw) && (minw != wd->wrap_w))
60           {
61              Evas_Coord ominw = -1;
62              evas_object_size_hint_min_get(data, &ominw, NULL);
63              minw = ominw;
64           }
65      }
66    else /* ellipsis && linewrap && wrap_height_set routine */
67      {
68         edje_object_size_min_restricted_calc(wd->lbl, &minw, &minh, 0, resh);
69         if ((minh <= resh) && (minh != wd->wrap_h))
70           {
71              Evas_Coord ominh = -1;
72              evas_object_size_hint_min_get(data, NULL, &ominh);
73              minh = ominh;
74           }
75
76                 evas_object_geometry_get(wd->lbl, NULL, NULL, &resw, &resh);
77                 minw = resw;
78                 if (minh > wd->wrap_h)
79                         minh = wd->wrap_h;
80      }
81
82    evas_object_size_hint_min_set(data, minw, minh);
83    evas_object_size_hint_max_set(data, wd->wrap_w, wd->wrap_h);
84
85    if ((wd->ellipsis) && (wd->linewrap) && (wd->wrap_h > 0) &&
86        (_is_width_over(data) == 1))
87      _ellipsis_label_to_width(data);
88 }
89
90 static void
91 _del_hook(Evas_Object *obj)
92 {
93    Widget_Data *wd = elm_widget_data_get(obj);
94    if (!wd) return;
95    if (wd->deferred_recalc_job) ecore_job_del(wd->deferred_recalc_job);
96    if (wd->label) eina_stringshare_del(wd->label);
97    if (wd->bg) evas_object_del(wd->bg);
98    free(wd);
99 }
100
101 static void
102 _theme_change(Evas_Object *obj)
103 {
104    Widget_Data *wd = elm_widget_data_get(obj);
105    if (!wd) return;
106
107    _elm_theme_object_set(obj, wd->lbl, "label", "base",
108          elm_widget_style_get(obj));
109 }
110
111 static void
112 _mirrored_set(Evas_Object *obj, Eina_Bool rtl)
113 {
114    Widget_Data *wd = elm_widget_data_get(obj);
115    if (!wd) return;
116    edje_object_mirrored_set(wd->lbl, rtl);
117 }
118
119 static void
120 _theme_hook(Evas_Object *obj)
121 {
122    Widget_Data *wd = elm_widget_data_get(obj);
123    if (!wd) return;
124    _elm_widget_mirrored_reload(obj);
125    _mirrored_set(obj, elm_widget_mirrored_get(obj));
126    _theme_change(obj);
127    edje_object_part_text_set(wd->lbl, "elm.text", wd->format);
128    edje_object_part_text_append(wd->lbl, "elm.text", wd->label);
129    edje_object_scale_set(wd->lbl, elm_widget_scale_get(obj) *
130                          _elm_config->scale);
131    _label_sliding_change(obj);
132    _sizing_eval(obj);
133 }
134
135 static void
136 _sizing_eval(Evas_Object *obj)
137 {
138    Widget_Data *wd = elm_widget_data_get(obj);
139    Evas_Coord minw = -1, minh = -1;
140    Evas_Coord resw, resh;
141    if (!wd) return;
142
143    if (wd->linewrap)
144      {
145         evas_object_geometry_get(wd->lbl, NULL, NULL, &resw, &resh);
146         if ((resw == wd->lastw) && (!wd->changed)) return;
147         wd->changed = EINA_FALSE;
148         wd->lastw = resw;
149         _elm_win_recalc_job(obj);
150         // FIXME: works ok. but NOT for genlist. what should genlist do?
151         //        if (wd->deferred_recalc_job) ecore_job_del(wd->deferred_recalc_job);
152         //        wd->deferred_recalc_job = ecore_job_add(_elm_win_recalc_job, obj);
153      }
154    else
155      {
156         evas_object_geometry_get(wd->lbl, NULL, NULL, &resw, &resh);
157         edje_object_size_min_calc(wd->lbl, &minw, &minh);
158         if (wd->wrap_w > 0 && minw > wd->wrap_w) minw = wd->wrap_w;
159         if (wd->wrap_h > 0 && minh > wd->wrap_h) minh = wd->wrap_h;
160         evas_object_size_hint_min_set(obj, minw, minh);
161         evas_object_size_hint_max_set(obj, wd->wrap_w, wd->wrap_h);
162         if ((wd->ellipsis) && (_is_width_over(obj) == 1))
163           _ellipsis_label_to_width(obj);
164      }
165 }
166
167 static void
168 _lbl_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
169 {
170    Widget_Data *wd = elm_widget_data_get(data);
171    if (!wd) return;
172    if (wd->linewrap) _sizing_eval(data);
173 }
174
175 static int
176 _get_value_in_key_string(const char *oldstring, const char *key, char **value)
177 {
178    char *curlocater, *starttag, *endtag;
179    int firstindex = 0, foundflag = -1;
180
181    curlocater = strstr(oldstring, key);
182    if (curlocater)
183      {
184         int key_len = strlen(key);
185         starttag = curlocater;
186         endtag = curlocater + key_len;
187         if ((!endtag) || (*endtag != '='))
188           {
189              foundflag = 0;
190              return -1;
191           }
192         firstindex = abs(oldstring - curlocater);
193         firstindex += key_len + 1; // strlen("key") + strlen("=")
194         *value = (char *)oldstring + firstindex;
195
196         while (oldstring != starttag)
197           {
198              if (*starttag == '>')
199                {
200                   foundflag = 0;
201                   break;
202                }
203              if (*starttag == '<')
204                break;
205              else
206                starttag--;
207              if (!starttag) break;
208           }
209
210         while (endtag)
211           {
212              if (*endtag == '<')
213                {
214                   foundflag = 0;
215                   break;
216                }
217              if (*endtag == '>')
218                break;
219              else
220                endtag++;
221              if (!endtag) break;
222           }
223
224         if ((foundflag) && (*starttag == '<') && (*endtag == '>'))
225           foundflag = 1;
226         else
227           foundflag = 0;
228      }
229    else
230      {
231         foundflag = 0;
232      }
233
234    if (foundflag == 1) return 0;
235
236    return -1;
237 }
238
239
240 static int
241 _strbuf_key_value_replace(Eina_Strbuf *srcbuf, const char *key, const char *value, int deleteflag)
242 {
243    const char *srcstring = NULL;
244    Eina_Strbuf *repbuf = NULL, *diffbuf = NULL;
245    char *curlocater, *replocater;
246    char *starttag, *endtag;
247    int tagtxtlen = 0, insertflag = 0;
248
249    srcstring = eina_strbuf_string_get(srcbuf);
250    curlocater = strstr(srcstring, key);
251
252    if (!curlocater)
253      insertflag = 1;
254    else
255      {
256         int key_len = strlen(key);
257         do
258           {
259              starttag = strchr(srcstring, '<');
260              endtag = strchr(srcstring, '>');
261              tagtxtlen = endtag - starttag;
262              if (tagtxtlen <= 0) tagtxtlen = 0;
263              if ((starttag < curlocater) && (curlocater < endtag)) break;
264              if ((endtag) && ((endtag + 1)))
265                srcstring = endtag + 1;
266              else
267                break;
268           } while (strlen(srcstring) > 1);
269
270         if ((starttag) && (endtag) && (tagtxtlen > key_len))
271           {
272              char *eqchar = NULL;
273              repbuf = eina_strbuf_new();
274              diffbuf = eina_strbuf_new();
275              eina_strbuf_append_n(repbuf, starttag, tagtxtlen);
276              srcstring = eina_strbuf_string_get(repbuf);
277              curlocater = strstr(srcstring, key);
278              // key=value
279              //    ^ : move to here
280              eqchar = curlocater + key_len;
281              if ((curlocater) && (eqchar))
282                {
283                   // some case at useless many whitespaces (key  =value)
284                   // find the separator(=) position
285                   eqchar = strchr(curlocater + key_len, '=');
286                   if (eqchar)
287                     {
288                        // key=value
289                        //     ^ : move to here
290                        replocater = eqchar + 1;
291                        while ((*replocater) &&
292                               (*replocater != ' ') &&
293                               (*replocater != '>'))
294                          replocater++;
295
296                        if ((replocater - curlocater) > key_len)
297                          eina_strbuf_append_n(diffbuf, curlocater,
298                                               replocater-curlocater);
299                        else
300                          insertflag = 1;
301                     }
302                   else
303                     insertflag = 1;
304                }
305              else
306                insertflag = 1;
307              eina_strbuf_reset(repbuf);
308           }
309         else
310           insertflag = 1;
311      }
312
313    if (!repbuf) repbuf = eina_strbuf_new();
314    if (!diffbuf) diffbuf = eina_strbuf_new();
315
316    if (insertflag)
317      {
318         eina_strbuf_append_printf(repbuf, "<%s=%s>", key, value);
319         eina_strbuf_prepend(srcbuf, eina_strbuf_string_get(repbuf));
320      }
321    else
322      {
323         if (deleteflag)
324           {
325              eina_strbuf_prepend(diffbuf, "<");
326              eina_strbuf_append(diffbuf, ">");
327              eina_strbuf_replace_first(srcbuf, eina_strbuf_string_get(diffbuf), "");
328           }
329         else
330           {
331              eina_strbuf_append_printf(repbuf, "%s=%s", key, value);
332              eina_strbuf_replace_first(srcbuf, eina_strbuf_string_get(diffbuf), eina_strbuf_string_get(repbuf));
333           }
334      }
335
336    if (repbuf) eina_strbuf_free(repbuf);
337    if (diffbuf) eina_strbuf_free(diffbuf);
338
339    return 0;
340 }
341
342 static int
343 _stringshare_key_value_replace(const char **srcstring, const char *key, const char *value, int deleteflag)
344 {
345    Eina_Strbuf *sharebuf = NULL;
346
347    sharebuf = eina_strbuf_new();
348    eina_strbuf_append(sharebuf, *srcstring);
349    _strbuf_key_value_replace(sharebuf, key, value, deleteflag);
350    eina_stringshare_del(*srcstring);
351    *srcstring = eina_stringshare_add(eina_strbuf_string_get(sharebuf));
352    eina_strbuf_free(sharebuf);
353
354    return 0;
355 }
356
357 static int
358 _is_width_over(Evas_Object *obj)
359 {
360    Evas_Coord x, y, w, h;
361    Evas_Coord vx, vy, vw, vh;
362    Widget_Data *wd = elm_widget_data_get(obj);
363    if (!wd) return 0;
364
365    edje_object_part_geometry_get(wd->lbl, "elm.text", &x, &y, NULL, NULL);
366    /* Calc the formatted size with ellipsis turned off */
367    if (wd->ellipsis)
368      {
369         const Evas_Object *tb;
370         char *_kvalue;
371         double ellipsis = 0.0;
372         Eina_Bool found_key = EINA_FALSE;
373         if (_get_value_in_key_string(wd->format, "ellipsis", &_kvalue) == 0)
374           {
375              ellipsis = atof(_kvalue);
376              found_key = EINA_TRUE;
377           }
378
379         if (_stringshare_key_value_replace(&wd->format,
380                  "ellipsis", NULL, 1) == 0)
381           {
382              edje_object_part_text_set(wd->lbl, "elm.text", wd->format);
383              edje_object_part_text_append(wd->lbl, "elm.text", wd->label);
384           }
385
386         tb = edje_object_part_object_get(wd->lbl, "elm.text");
387         evas_object_textblock_size_formatted_get(tb, &w, &h);
388
389         if (found_key)
390           {
391              Eina_Strbuf *elpbuf;
392              elpbuf = eina_strbuf_new();
393              eina_strbuf_append_printf(elpbuf, "%f", ellipsis);
394              if (_stringshare_key_value_replace(&wd->format, "ellipsis",
395                       eina_strbuf_string_get(elpbuf), 0) == 0)
396                {
397                   edje_object_part_text_set(wd->lbl, "elm.text", wd->format);
398                   edje_object_part_text_append(wd->lbl, "elm.text", wd->label);
399                }
400              eina_strbuf_free(elpbuf);
401           }
402      }
403    else
404      {
405         const Evas_Object *tb;
406         tb = edje_object_part_object_get(wd->lbl, "elm.text");
407         evas_object_textblock_size_formatted_get(tb, &w, &h);
408      }
409    evas_object_geometry_get(obj, &vx, &vy, &vw, &vh);
410
411    if (w > wd->wrap_w || h > wd->wrap_h)
412       return 1;
413
414    return 0;
415 }
416
417 static void
418 _ellipsis_fontsize_set(Evas_Object *obj, int fontsize)
419 {
420    Widget_Data *wd = elm_widget_data_get(obj);
421    Eina_Strbuf *fontbuf = NULL;
422    int removeflag = 0;
423    if (!wd) return;
424
425    fontbuf = eina_strbuf_new();
426    eina_strbuf_append_printf(fontbuf, "%d", fontsize);
427    if (fontsize == 0) removeflag = 1;  // remove fontsize tag
428
429    if (_stringshare_key_value_replace(&wd->format, "font_size", eina_strbuf_string_get(fontbuf), removeflag) == 0)
430      {
431         edje_object_part_text_set(wd->lbl, "elm.text", wd->format);
432         edje_object_part_text_append(wd->lbl, "elm.text", wd->label);
433      }
434    eina_strbuf_free(fontbuf);
435 }
436
437 static void
438 _ellipsis_label_to_width(Evas_Object *obj)
439 {
440    Widget_Data *wd = elm_widget_data_get(obj);
441    if (!wd) return;
442    int cur_fontsize = 0;
443    char *kvalue;
444    const char *minfont, *deffont, *maxfont;
445    int minfontsize, maxfontsize;
446
447    minfont = edje_object_data_get(wd->lbl, "min_font_size");
448    if (minfont) minfontsize = atoi(minfont);
449    else minfontsize = 1;
450    maxfont = edje_object_data_get(wd->lbl, "max_font_size");
451    if (maxfont) maxfontsize = atoi(maxfont);
452    else maxfontsize = 1;
453    deffont = edje_object_data_get(wd->lbl, "default_font_size");
454    if (deffont) cur_fontsize = atoi(deffont);
455    else cur_fontsize = 1;
456    if (minfontsize > maxfontsize || cur_fontsize == 1) return;  // theme is not ready for ellipsis
457    if (eina_stringshare_strlen(wd->label) <= 0) return;
458
459    if (_get_value_in_key_string(wd->format, "font_size", &kvalue) == 0)
460      {
461         if (kvalue != NULL) cur_fontsize = atoi(kvalue);
462      }
463
464    /* TODO : Remove ellipsis logic in elm_lable and use ellipsis feature in evas textblock */
465    _ellipsis_fontsize_set(obj, cur_fontsize);
466    return;
467
468 /*
469    while (_is_width_over(obj))
470      {
471         if (cur_fontsize > minfontsize)
472           {
473              cur_fontsize -= 3;
474              if (cur_fontsize < minfontsize) cur_fontsize = minfontsize;
475              _ellipsis_fontsize_set(obj, cur_fontsize);
476           }
477         else
478           {
479              break;
480           }
481      }
482 */
483 }
484
485 static void
486 _label_sliding_change(Evas_Object *obj)
487 {
488    Widget_Data *wd = elm_widget_data_get(obj);
489    if (!wd) return;
490    char *plaintxt;
491    int plainlen = 0;
492
493    // dosen't support multiline sliding effect
494    if (wd->linewrap)
495      {
496         wd->slidingmode = EINA_FALSE;
497         return;
498      }
499
500    plaintxt = _elm_util_mkup_to_text(edje_object_part_text_get(wd->lbl, "elm.text"));
501    if (plaintxt != NULL)
502      {
503         plainlen = strlen(plaintxt);
504         free(plaintxt);
505      }
506    // too short to slide label
507    if (plainlen < 1)
508      {
509         wd->slidingmode = EINA_TRUE;
510         return;
511      }
512
513    if (wd->slidingmode)
514      {
515         Edje_Message_Float_Set *msg = alloca(sizeof(Edje_Message_Float_Set) + (sizeof(double)));
516
517         if (wd->ellipsis)
518           {
519              wd->slidingellipsis = EINA_TRUE;
520              elm_label_ellipsis_set(obj, EINA_FALSE);
521           }
522
523         msg->count = 1;
524         msg->val[0] = wd->slide_duration;
525
526         edje_object_message_send(wd->lbl, EDJE_MESSAGE_FLOAT_SET, 0, msg);
527         edje_object_signal_emit(wd->lbl, "elm,state,slide,start", "elm");
528      }
529    else
530      {
531         edje_object_signal_emit(wd->lbl, "elm,state,slide,stop", "elm");
532         if (wd->slidingellipsis)
533           {
534              wd->slidingellipsis = EINA_FALSE;
535              elm_label_ellipsis_set(obj, EINA_TRUE);
536           }
537      }
538 }
539
540 static void
541 _elm_label_label_set(Evas_Object *obj, const char *item, const char *label)
542 {
543    ELM_CHECK_WIDTYPE(obj, widtype);
544    Widget_Data *wd = elm_widget_data_get(obj);
545    if (!wd) return;
546    if (item && strcmp(item, "default")) return;
547    if (!label) label = "";
548    eina_stringshare_replace(&wd->label, label);
549    edje_object_part_text_set(wd->lbl, "elm.text", wd->format);
550    edje_object_part_text_append(wd->lbl, "elm.text", wd->label);
551    wd->changed = 1;
552    _sizing_eval(obj);
553 }
554
555 static const char *
556 _elm_label_label_get(const Evas_Object *obj, const char *item)
557 {
558    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
559    Widget_Data *wd = elm_widget_data_get(obj);
560    if (item && strcmp(item, "default")) return NULL;
561    if (!wd) return NULL;
562    return wd->label;
563 }
564
565 static void
566 _translate_hook(Evas_Object *obj)
567 {
568    evas_object_smart_callback_call(obj, "language,changed", NULL);
569 }
570
571 EAPI Evas_Object *
572 elm_label_add(Evas_Object *parent)
573 {
574    Evas_Object *obj;
575    Evas *e;
576    Widget_Data *wd;
577
578    ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
579
580    ELM_SET_WIDTYPE(widtype, "label");
581    elm_widget_type_set(obj, "label");
582    elm_widget_sub_object_add(parent, obj);
583    elm_widget_data_set(obj, wd);
584    elm_widget_del_hook_set(obj, _del_hook);
585    elm_widget_theme_hook_set(obj, _theme_hook);
586    elm_widget_can_focus_set(obj, EINA_FALSE);
587    elm_widget_text_set_hook_set(obj, _elm_label_label_set);
588    elm_widget_text_get_hook_set(obj, _elm_label_label_get);
589    elm_widget_translate_hook_set(obj, _translate_hook);
590
591    wd->bgcolor = EINA_FALSE;
592    wd->bg = evas_object_rectangle_add(e);
593    evas_object_color_set(wd->bg, 0, 0, 0, 0);
594
595    wd->linewrap = ELM_WRAP_NONE;
596    wd->ellipsis = EINA_FALSE;
597    wd->slidingmode = EINA_FALSE;
598    wd->slidingellipsis = EINA_FALSE;
599    wd->wrap_w = -1;
600    wd->wrap_h = -1;
601    wd->slide_duration = 10;
602
603    wd->lbl = edje_object_add(e);
604    _elm_theme_object_set(obj, wd->lbl, "label", "base", "default");
605    wd->format = eina_stringshare_add("");
606    wd->label = eina_stringshare_add("<br>");
607    edje_object_part_text_set(wd->lbl, "elm.text", wd->format);
608    edje_object_part_text_append(wd->lbl, "elm.text", wd->label);
609
610    elm_widget_resize_object_set(obj, wd->lbl);
611
612    evas_object_event_callback_add(wd->lbl, EVAS_CALLBACK_RESIZE, _lbl_resize, obj);
613
614    _mirrored_set(obj, elm_widget_mirrored_get(obj));
615    wd->changed = 1;
616    _sizing_eval(obj);
617    return obj;
618 }
619
620 EAPI void
621 elm_label_label_set(Evas_Object *obj, const char *label)
622 {
623   _elm_label_label_set(obj, NULL, label);
624 }
625
626 EAPI const char *
627 elm_label_label_get(const Evas_Object *obj)
628 {
629   return _elm_label_label_get(obj, NULL);
630 }
631
632 EAPI void
633 elm_label_line_wrap_set(Evas_Object *obj, Elm_Wrap_Type wrap)
634 {
635    ELM_CHECK_WIDTYPE(obj, widtype);
636    Widget_Data *wd = elm_widget_data_get(obj);
637    const char *wrap_str;
638    int len;
639
640    if (!wd) return;
641    if (wd->linewrap == wrap) return;
642    wd->linewrap = wrap;
643    len = strlen(wd->label);
644    if (len <= 0) return;
645
646    switch (wrap)
647      {
648       case ELM_WRAP_CHAR:
649          wrap_str = "char";
650          break;
651       case ELM_WRAP_WORD:
652          wrap_str = "word";
653          break;
654       case ELM_WRAP_MIXED:
655          wrap_str = "mixed";
656          break;
657       default:
658          wrap_str = "none";
659          break;
660      }
661
662    if (_stringshare_key_value_replace(&wd->format,
663             "wrap", wrap_str, 0) == 0)
664      {
665         edje_object_part_text_set(wd->lbl, "elm.text", wd->format);
666         edje_object_part_text_append(wd->lbl, "elm.text", wd->label);
667         wd->changed = 1;
668         _sizing_eval(obj);
669      }
670 }
671
672 EAPI Elm_Wrap_Type
673 elm_label_line_wrap_get(const Evas_Object *obj)
674 {
675    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
676    Widget_Data *wd = elm_widget_data_get(obj);
677    if (!wd) return EINA_FALSE;
678    return wd->linewrap;
679 }
680
681 EAPI void
682 elm_label_wrap_width_set(Evas_Object *obj, Evas_Coord w)
683 {
684    ELM_CHECK_WIDTYPE(obj, widtype);
685    Widget_Data *wd = elm_widget_data_get(obj);
686    if (!wd) return;
687    if (w < 0) w = 0;
688    if (wd->wrap_w == w) return;
689    if (wd->ellipsis)
690      {
691         edje_object_part_text_set(wd->lbl, "elm.text", wd->format);
692         edje_object_part_text_append(wd->lbl, "elm.text", wd->label);
693      }
694    wd->wrap_w = w;
695    _sizing_eval(obj);
696 }
697
698 EAPI Evas_Coord
699 elm_label_wrap_width_get(const Evas_Object *obj)
700 {
701    ELM_CHECK_WIDTYPE(obj, widtype) 0;
702    Widget_Data *wd = elm_widget_data_get(obj);
703    if (!wd) return 0;
704    return wd->wrap_w;
705 }
706
707 EAPI void
708 elm_label_wrap_height_set(Evas_Object *obj,
709                           Evas_Coord   h)
710 {
711    ELM_CHECK_WIDTYPE(obj, widtype);
712    Widget_Data *wd = elm_widget_data_get(obj);
713    if (!wd) return;
714    if (h < 0) h = 0;
715    if (wd->wrap_h == h) return;
716    if (wd->ellipsis)
717      {
718         edje_object_part_text_set(wd->lbl, "elm.text", wd->format);
719         edje_object_part_text_append(wd->lbl, "elm.text", wd->label);
720      }
721    wd->wrap_h = h;
722    _sizing_eval(obj);
723 }
724
725 EAPI Evas_Coord
726 elm_label_wrap_height_get(const Evas_Object *obj)
727 {
728    ELM_CHECK_WIDTYPE(obj, widtype) 0;
729    Widget_Data *wd = elm_widget_data_get(obj);
730    if (!wd) return 0;
731    return wd->wrap_h;
732 }
733
734 EAPI void
735 elm_label_fontsize_set(Evas_Object *obj, int fontsize)
736 {
737    ELM_CHECK_WIDTYPE(obj, widtype);
738    Widget_Data *wd = elm_widget_data_get(obj);
739    Eina_Strbuf *fontbuf = NULL;
740    int len, removeflag = 0;
741
742    if (!wd) return;
743    _elm_dangerous_call_check(__FUNCTION__);
744    len = strlen(wd->label);
745    if (len <= 0) return;
746    fontbuf = eina_strbuf_new();
747    eina_strbuf_append_printf(fontbuf, "%d", fontsize);
748
749    if (fontsize == 0) removeflag = 1;  // remove fontsize tag
750
751    if (_stringshare_key_value_replace(&wd->format, "font_size", eina_strbuf_string_get(fontbuf), removeflag) == 0)
752      {
753         edje_object_part_text_set(wd->lbl, "elm.text", wd->format);
754         edje_object_part_text_append(wd->lbl, "elm.text", wd->label);
755         wd->changed = 1;
756         _sizing_eval(obj);
757      }
758    eina_strbuf_free(fontbuf);
759 }
760
761 EAPI void
762 elm_label_text_align_set(Evas_Object *obj, const char *alignmode)
763 {
764    ELM_CHECK_WIDTYPE(obj, widtype);
765    Widget_Data *wd = elm_widget_data_get(obj);
766    int len;
767
768    if (!wd) return;
769    _elm_dangerous_call_check(__FUNCTION__);
770    len = strlen(wd->label);
771    if (len <= 0) return;
772
773    if (_stringshare_key_value_replace(&wd->format, "align", alignmode, 0) == 0)
774      {
775         edje_object_part_text_set(wd->lbl, "elm.text", wd->format);
776         edje_object_part_text_append(wd->lbl, "elm.text", wd->label);
777      }
778
779    wd->changed = 1;
780    _sizing_eval(obj);
781 }
782
783 EAPI void
784 elm_label_text_color_set(Evas_Object *obj,
785                          unsigned int r,
786                          unsigned int g,
787                          unsigned int b,
788                          unsigned int a)
789 {
790    ELM_CHECK_WIDTYPE(obj, widtype);
791    Widget_Data *wd = elm_widget_data_get(obj);
792    Eina_Strbuf *colorbuf = NULL;
793    int len;
794
795    if (!wd) return;
796    _elm_dangerous_call_check(__FUNCTION__);
797    len = strlen(wd->label);
798    if (len <= 0) return;
799    colorbuf = eina_strbuf_new();
800    eina_strbuf_append_printf(colorbuf, "#%02X%02X%02X%02X", r, g, b, a);
801
802    if (_stringshare_key_value_replace(&wd->format, "color", eina_strbuf_string_get(colorbuf), 0) == 0)
803      {
804         edje_object_part_text_set(wd->lbl, "elm.text", wd->format);
805         edje_object_part_text_append(wd->lbl, "elm.text", wd->label);
806         wd->changed = 1;
807         _sizing_eval(obj);
808      }
809    eina_strbuf_free(colorbuf);
810 }
811
812 EAPI void
813 elm_label_background_color_set(Evas_Object *obj,
814                                unsigned int r,
815                                unsigned int g,
816                                unsigned int b,
817                                unsigned int a)
818 {
819    ELM_CHECK_WIDTYPE(obj, widtype);
820    Widget_Data *wd = elm_widget_data_get(obj);
821    if (!wd) return;
822    evas_object_color_set(wd->bg, r, g, b, a);
823
824    _elm_dangerous_call_check(__FUNCTION__);
825    if (wd->bgcolor == EINA_FALSE)
826      {
827         wd->bgcolor = 1;
828         edje_object_part_swallow(wd->lbl, "label.swallow.background", wd->bg);
829      }
830 }
831
832 EAPI void
833 elm_label_ellipsis_set(Evas_Object *obj, Eina_Bool ellipsis)
834 {
835    ELM_CHECK_WIDTYPE(obj, widtype);
836    Widget_Data *wd = elm_widget_data_get(obj);
837    Eina_Strbuf *fontbuf = NULL;
838    int len, removeflag = 0;
839
840    if (!wd) return;
841    if (wd->ellipsis == ellipsis) return;
842    wd->ellipsis = ellipsis;
843    len = strlen(wd->label);
844    if (len <= 0) return;
845
846    if (ellipsis == EINA_FALSE) removeflag = 1;  // remove fontsize tag
847
848    fontbuf = eina_strbuf_new();
849    eina_strbuf_append_printf(fontbuf, "%f", 1.0);
850
851    if (_stringshare_key_value_replace(&wd->format,
852             "ellipsis", eina_strbuf_string_get(fontbuf), removeflag) == 0)
853      {
854         edje_object_part_text_set(wd->lbl, "elm.text", wd->format);
855         edje_object_part_text_append(wd->lbl, "elm.text", wd->label);
856         wd->changed = 1;
857         _sizing_eval(obj);
858      }
859    eina_strbuf_free(fontbuf);
860
861 }
862
863 EAPI void
864 elm_label_slide_set(Evas_Object *obj,
865                     Eina_Bool    slide)
866 {
867    ELM_CHECK_WIDTYPE(obj, widtype);
868    Widget_Data *wd = elm_widget_data_get(obj);
869    if (!wd) return;
870
871    if (wd->slidingmode == slide) return;
872    wd->slidingmode = slide;
873    _label_sliding_change(obj);
874    wd->changed = 1;
875    _sizing_eval(obj);
876 }
877
878 EAPI Eina_Bool
879 elm_label_slide_get(Evas_Object *obj)
880 {
881    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
882    Widget_Data *wd = elm_widget_data_get(obj);
883    if (!wd) return EINA_FALSE;
884    return wd->slidingmode;
885 }
886
887 EAPI void
888 elm_label_slide_duration_set(Evas_Object *obj, double duration)
889 {
890    ELM_CHECK_WIDTYPE(obj, widtype);
891    Widget_Data *wd = elm_widget_data_get(obj);
892    Edje_Message_Float_Set *msg = alloca(sizeof(Edje_Message_Float_Set) + (sizeof(double)));
893
894    if (!wd) return;
895    wd->slide_duration = duration;
896    msg->count = 1;
897    msg->val[0] = wd->slide_duration;
898    edje_object_message_send(wd->lbl, EDJE_MESSAGE_FLOAT_SET, 0, msg);
899 }
900
901 EAPI double
902 elm_label_slide_duration_get(Evas_Object *obj)
903 {
904    ELM_CHECK_WIDTYPE(obj, widtype) 0.0;
905    Widget_Data *wd = elm_widget_data_get(obj);
906    if (!wd) return 0;
907    return wd->slide_duration;
908 }
909