1 #include <Elementary.h>
3 #include "elm_widget_label.h"
5 EAPI const char ELM_LABEL_SMART_NAME[] = "elm_label";
7 static const char SIG_SLIDE_END[] = "slide,end";
8 static const char SIG_LANGUAGE_CHANGED[] = "language,changed";
10 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
11 {SIG_LANGUAGE_CHANGED, ""},
16 static const Elm_Layout_Part_Alias_Description _text_aliases[] =
18 {"default", "elm.text"},
22 EVAS_SMART_SUBCLASS_NEW
23 (ELM_LABEL_SMART_NAME, _elm_label, Elm_Label_Smart_Class,
24 Elm_Layout_Smart_Class, elm_layout_smart_class_get, NULL);
29 ELM_LABEL_DATA_GET(data, sd);
31 Evas_Coord minw = -1, minh = -1;
34 evas_event_freeze(evas_object_evas_get(data));
35 evas_object_geometry_get
36 (ELM_WIDGET_DATA(sd)->resize_obj, NULL, NULL, &resw, NULL);
37 if (sd->wrap_w > resw)
40 edje_object_size_min_restricted_calc
41 (ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh, resw, 0);
43 /* This is a hack to workaround the way min size hints are treated.
44 * If the minimum width is smaller than the restricted width, it means
45 * the mininmum doesn't matter. */
46 if ((minw <= resw) && (minw != sd->wrap_w))
48 Evas_Coord ominw = -1;
50 evas_object_size_hint_min_get(data, &ominw, NULL);
54 evas_object_size_hint_min_set(data, minw, minh);
55 evas_event_thaw(evas_object_evas_get(data));
56 evas_event_thaw_eval(evas_object_evas_get(data));
60 _label_format_set(Evas_Object *obj,
64 edje_object_part_text_style_user_push(obj, "elm.text", format);
66 edje_object_part_text_style_user_pop(obj, "elm.text");
70 _label_slide_change(Evas_Object *obj)
76 ELM_LABEL_DATA_GET(obj, sd);
78 edje_object_signal_emit(ELM_WIDGET_DATA(sd)->resize_obj,
79 "elm,state,slide,stop", "elm");
81 //doesn't support multiline slide effect
84 WRN("Doesn't support slide effect for multiline! : label=%p", obj);
88 //stop if the text is none.
89 plaintxt = _elm_util_mkup_to_text
90 (edje_object_part_text_get
91 (ELM_WIDGET_DATA(sd)->resize_obj, "elm.text"));
94 plainlen = strlen(plaintxt);
97 if (plainlen < 1) return;
100 if (sd->slide_mode != ELM_LABEL_SLIDE_MODE_NONE)
104 sd->slide_ellipsis = EINA_TRUE;
105 elm_label_ellipsis_set(obj, EINA_FALSE);
108 //slide only if the slide area is smaller than text width size.
109 if (sd->slide_mode == ELM_LABEL_SLIDE_MODE_AUTO)
111 tb = (Evas_Object *) edje_object_part_object_get(ELM_WIDGET_DATA(sd)->resize_obj, "elm.text");
116 evas_object_textblock_size_formatted_get(tb, &tb_w, NULL);
117 evas_object_geometry_get(ELM_WIDGET_DATA(sd)->resize_obj,
118 NULL, NULL, &w, NULL);
119 if ((tb_w > 0) && (tb_w < w))
121 if (sd->slide_ellipsis)
123 sd->slide_ellipsis = EINA_FALSE;
124 elm_label_ellipsis_set(obj, EINA_TRUE);
130 Edje_Message_Float_Set *msg =
131 alloca(sizeof(Edje_Message_Float_Set) + (sizeof(double)));
134 msg->val[0] = sd->slide_duration;
136 edje_object_message_send
137 (ELM_WIDGET_DATA(sd)->resize_obj, EDJE_MESSAGE_FLOAT_SET, 0, msg);
138 edje_object_signal_emit(ELM_WIDGET_DATA(sd)->resize_obj, "elm,state,slide,start", "elm");
143 if (sd->slide_ellipsis)
145 sd->slide_ellipsis = EINA_FALSE;
146 elm_label_ellipsis_set(obj, EINA_TRUE);
152 _elm_label_smart_theme(Evas_Object *obj)
156 ELM_LABEL_DATA_GET(obj, sd);
158 evas_event_freeze(evas_object_evas_get(obj));
160 ret = ELM_WIDGET_CLASS(_elm_label_parent_sc)->theme(obj);
163 _label_format_set(ELM_WIDGET_DATA(sd)->resize_obj, sd->format);
164 _label_slide_change(obj);
167 evas_event_thaw(evas_object_evas_get(obj));
168 evas_event_thaw_eval(evas_object_evas_get(obj));
174 _elm_label_smart_sizing_eval(Evas_Object *obj)
176 Evas_Coord minw = -1, minh = -1;
177 Evas_Coord resw, resh;
179 ELM_LABEL_DATA_GET(obj, sd);
183 evas_object_geometry_get
184 (ELM_WIDGET_DATA(sd)->resize_obj, NULL, NULL, &resw, &resh);
185 if (resw == sd->lastw) return;
191 evas_event_freeze(evas_object_evas_get(obj));
192 evas_object_geometry_get
193 (ELM_WIDGET_DATA(sd)->resize_obj, NULL, NULL, &resw, &resh);
194 edje_object_size_min_calc
195 (ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh);
196 if (sd->wrap_w > 0 && minw > sd->wrap_w) minw = sd->wrap_w;
197 evas_object_size_hint_min_set(obj, minw, minh);
198 evas_event_thaw(evas_object_evas_get(obj));
199 evas_event_thaw_eval(evas_object_evas_get(obj));
204 _on_label_resize(void *data,
206 Evas_Object *obj __UNUSED__,
207 void *event_info __UNUSED__)
209 ELM_LABEL_DATA_GET(data, sd);
211 if (sd->linewrap) elm_layout_sizing_eval(data);
215 _get_value_in_key_string(const char *oldstring,
219 char *curlocater, *endtag;
220 int firstindex = 0, foundflag = -1;
222 curlocater = strstr(oldstring, key);
225 int key_len = strlen(key);
226 endtag = curlocater + key_len;
227 if ((!endtag) || (*endtag != '='))
232 firstindex = abs(oldstring - curlocater);
233 firstindex += key_len + 1; // strlen("key") + strlen("=")
234 *value = (char *)oldstring + firstindex;
243 if (foundflag == 1) return 0;
249 _strbuf_key_value_replace(Eina_Strbuf *srcbuf,
255 const char *srcstring = NULL;
257 srcstring = eina_strbuf_string_get(srcbuf);
259 if (_get_value_in_key_string(srcstring, key, &kvalue) == 0)
263 int key_start_idx = 0;
264 val_end = strchr(kvalue, ' ');
267 val_end_idx = val_end - srcstring;
269 val_end_idx = kvalue - srcstring + strlen(kvalue) - 1;
271 /* -1 is because of the '=' */
272 key_start_idx = kvalue - srcstring - 1 - strlen(key);
273 eina_strbuf_remove(srcbuf, key_start_idx, val_end_idx);
276 eina_strbuf_insert_printf(srcbuf, "%s=%s", key_start_idx, key,
280 else if (!deleteflag)
284 /* -1 because we want it before the ' */
285 eina_strbuf_insert_printf
286 (srcbuf, " %s=%s", eina_strbuf_length_get(srcbuf) - 1, key,
291 eina_strbuf_append_printf(srcbuf, "DEFAULT='%s=%s'", key, value);
299 _stringshare_key_value_replace(const char **srcstring,
304 Eina_Strbuf *sharebuf = NULL;
306 sharebuf = eina_strbuf_new();
307 eina_strbuf_append(sharebuf, *srcstring);
308 _strbuf_key_value_replace(sharebuf, key, value, deleteflag);
309 eina_stringshare_del(*srcstring);
310 *srcstring = eina_stringshare_add(eina_strbuf_string_get(sharebuf));
311 eina_strbuf_free(sharebuf);
317 _elm_label_smart_text_set(Evas_Object *obj,
321 ELM_LABEL_DATA_GET(obj, sd);
323 if (!label) label = "";
324 _label_format_set(ELM_WIDGET_DATA(sd)->resize_obj, sd->format);
326 if (_elm_label_parent_sc->text_set(obj, item, label))
329 _elm_label_smart_sizing_eval(obj);
337 _elm_label_smart_translate(Evas_Object *obj)
339 evas_object_smart_callback_call(obj, SIG_LANGUAGE_CHANGED, NULL);
345 _access_info_cb(void *data __UNUSED__, Evas_Object *obj)
347 const char *txt = elm_widget_access_info_get(obj);
349 if (!txt) txt = _elm_util_mkup_to_text(elm_layout_text_get(obj, NULL));
350 if (txt) return strdup(txt);
356 _on_slide_end(void *data, Evas_Object *obj __UNUSED__,
357 const char *emission __UNUSED__, const char *source __UNUSED__)
359 ELM_LABEL_DATA_GET(data, sd);
360 if (sd->slide_ellipsis)
361 elm_label_ellipsis_set(data, EINA_TRUE);
363 evas_object_smart_callback_call(data, SIG_SLIDE_END, NULL);
367 _elm_label_smart_add(Evas_Object *obj)
369 EVAS_SMART_DATA_ALLOC(obj, Elm_Label_Smart_Data);
371 ELM_WIDGET_CLASS(_elm_label_parent_sc)->base.add(obj);
373 priv->linewrap = ELM_WRAP_NONE;
375 priv->slide_duration = 10;
377 priv->format = eina_stringshare_add("");
378 _label_format_set(ELM_WIDGET_DATA(priv)->resize_obj, priv->format);
380 evas_object_event_callback_add
381 (ELM_WIDGET_DATA(priv)->resize_obj, EVAS_CALLBACK_RESIZE,
382 _on_label_resize, obj);
384 edje_object_signal_callback_add(ELM_WIDGET_DATA(priv)->resize_obj,
385 "elm,state,slide,end", "", _on_slide_end,
388 elm_widget_can_focus_set(obj, _elm_config->access_mode);
390 _elm_access_object_register(obj, ELM_WIDGET_DATA(priv)->resize_obj);
392 (_elm_access_object_get(obj), ELM_ACCESS_TYPE, E_("Label"));
393 _elm_access_callback_set
394 (_elm_access_object_get(obj), ELM_ACCESS_INFO, _access_info_cb, NULL);
396 elm_layout_theme_set(obj, "label", "base", elm_widget_style_get(obj));
397 elm_layout_text_set(obj, NULL, "<br>");
398 elm_layout_sizing_eval(obj);
402 _elm_label_smart_set_user(Elm_Label_Smart_Class *sc)
404 ELM_WIDGET_CLASS(sc)->base.add = _elm_label_smart_add;
406 /* not a 'focus chain manager' */
407 ELM_WIDGET_CLASS(sc)->focus_next = NULL;
408 ELM_WIDGET_CLASS(sc)->focus_direction = NULL;
410 ELM_WIDGET_CLASS(sc)->theme = _elm_label_smart_theme;
411 ELM_WIDGET_CLASS(sc)->translate = _elm_label_smart_translate;
413 ELM_LAYOUT_CLASS(sc)->sizing_eval = _elm_label_smart_sizing_eval;
414 ELM_LAYOUT_CLASS(sc)->text_set = _elm_label_smart_text_set;
416 ELM_LAYOUT_CLASS(sc)->text_aliases = _text_aliases;
419 EAPI const Elm_Label_Smart_Class *
420 elm_label_smart_class_get(void)
422 static Elm_Label_Smart_Class _sc =
423 ELM_LABEL_SMART_CLASS_INIT_NAME_VERSION(ELM_LABEL_SMART_NAME);
424 static const Elm_Label_Smart_Class *class = NULL;
429 _elm_label_smart_set(&_sc);
436 elm_label_add(Evas_Object *parent)
440 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
442 obj = elm_widget_add(_elm_label_smart_class_new(), parent);
443 if (!obj) return NULL;
445 if (!elm_widget_sub_object_add(parent, obj))
446 ERR("could not add %p as sub object of %p", obj, parent);
452 elm_label_line_wrap_set(Evas_Object *obj,
455 const char *wrap_str, *text;
458 ELM_LABEL_CHECK(obj);
459 ELM_LABEL_DATA_GET(obj, sd);
461 if (sd->linewrap == wrap) return;
464 text = elm_layout_text_get(obj, NULL);
468 if (len <= 0) return;
489 if (_stringshare_key_value_replace(&sd->format, "wrap", wrap_str, 0) == 0)
491 _label_format_set(ELM_WIDGET_DATA(sd)->resize_obj, sd->format);
492 elm_layout_sizing_eval(obj);
497 elm_label_line_wrap_get(const Evas_Object *obj)
499 ELM_LABEL_CHECK(obj) EINA_FALSE;
500 ELM_LABEL_DATA_GET(obj, sd);
506 elm_label_wrap_width_set(Evas_Object *obj,
509 ELM_LABEL_CHECK(obj);
510 ELM_LABEL_DATA_GET(obj, sd);
514 if (sd->wrap_w == w) return;
517 _label_format_set(ELM_WIDGET_DATA(sd)->resize_obj, sd->format);
520 elm_layout_sizing_eval(obj);
524 elm_label_wrap_width_get(const Evas_Object *obj)
526 ELM_LABEL_CHECK(obj) 0;
527 ELM_LABEL_DATA_GET(obj, sd);
533 elm_label_ellipsis_set(Evas_Object *obj,
536 Eina_Strbuf *fontbuf = NULL;
537 int len, removeflag = 0;
540 ELM_LABEL_CHECK(obj);
541 ELM_LABEL_DATA_GET(obj, sd);
543 if (sd->ellipsis == ellipsis) return;
544 sd->ellipsis = ellipsis;
546 text = elm_layout_text_get(obj, NULL);
550 if (len <= 0) return;
552 if (ellipsis == EINA_FALSE) removeflag = 1; // remove fontsize tag
554 fontbuf = eina_strbuf_new();
555 eina_strbuf_append_printf(fontbuf, "%f", 1.0);
557 if (_stringshare_key_value_replace
558 (&sd->format, "ellipsis", eina_strbuf_string_get
559 (fontbuf), removeflag) == 0)
561 _label_format_set(ELM_WIDGET_DATA(sd)->resize_obj, sd->format);
562 elm_layout_sizing_eval(obj);
564 eina_strbuf_free(fontbuf);
568 elm_label_ellipsis_get(const Evas_Object *obj)
570 ELM_LABEL_CHECK(obj) EINA_FALSE;
571 ELM_LABEL_DATA_GET(obj, sd);
577 elm_label_slide_mode_set(Evas_Object *obj, Elm_Label_Slide_Mode mode)
579 ELM_LABEL_CHECK(obj);
580 ELM_LABEL_DATA_GET(obj, sd);
581 sd->slide_mode = mode;
584 EAPI Elm_Label_Slide_Mode
585 elm_label_slide_mode_get(const Evas_Object *obj)
587 ELM_LABEL_CHECK(obj) ELM_LABEL_SLIDE_MODE_NONE;
588 ELM_LABEL_DATA_GET(obj, sd);
589 return sd->slide_mode;
592 EINA_DEPRECATED EAPI void
593 elm_label_slide_set(Evas_Object *obj,
597 elm_label_slide_mode_set(obj, ELM_LABEL_SLIDE_MODE_ALWAYS);
599 elm_label_slide_mode_set(obj, ELM_LABEL_SLIDE_MODE_NONE);
602 EINA_DEPRECATED EAPI Eina_Bool
603 elm_label_slide_get(const Evas_Object *obj)
605 Eina_Bool ret = EINA_FALSE;
606 if (elm_label_slide_mode_get(obj) == ELM_LABEL_SLIDE_MODE_ALWAYS)
612 elm_label_slide_go(Evas_Object *obj)
614 ELM_LABEL_CHECK(obj);
615 _label_slide_change(obj);
616 elm_layout_sizing_eval(obj);
620 elm_label_slide_duration_set(Evas_Object *obj, double duration)
622 ELM_LABEL_CHECK(obj);
623 ELM_LABEL_DATA_GET(obj, sd);
625 sd->slide_duration = duration;
629 elm_label_slide_duration_get(const Evas_Object *obj)
631 ELM_LABEL_CHECK(obj) 0.0;
632 ELM_LABEL_DATA_GET(obj, sd);
634 return sd->slide_duration;