struct _Widget_Data
{
Evas_Object *lbl;
+ Evas_Object *bg;
const char *label;
Evas_Coord lastw;
Ecore_Job *deferred_recalc_job;
Evas_Coord wrap_w;
Eina_Bool linewrap : 1;
Eina_Bool changed : 1;
+ Eina_Bool bgcolor : 1;
+ Eina_Bool ellipsis : 1;
};
static const char *widtype = NULL;
static void _del_hook(Evas_Object *obj);
static void _theme_hook(Evas_Object *obj);
static void _sizing_eval(Evas_Object *obj);
+static int _get_value_in_key_string(const char *oldstring, char *key, char **value);
+static int _strbuf_key_value_replace(Eina_Strbuf *srcbuf, char *key, const char *value, int deleteflag);
+static int _stringshare_key_value_replace(const char **srcstring, 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 void
_elm_win_recalc_job(void *data)
if (!wd) return;
if (wd->deferred_recalc_job) ecore_job_del(wd->deferred_recalc_job);
if (wd->label) eina_stringshare_del(wd->label);
+ if (wd->bg) evas_object_del(wd->bg);
free(wd);
}
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) return;
if (wd->linewrap) _sizing_eval(data);
}
+
+static int
+_get_value_in_key_string(const char *oldstring, char *key, char **value)
+{
+ char *curlocater, *starttag, *endtag;
+ int firstindex = 0, foundflag = -1;
+
+ curlocater = strstr(oldstring, key);
+ if (curlocater)
+ {
+ starttag = curlocater;
+ endtag = curlocater + strlen(key);
+ if (endtag == NULL || *endtag != '=')
+ {
+ foundflag = 0;
+ return -1;
+ }
+
+ firstindex = abs(oldstring - curlocater);
+ firstindex += strlen(key)+1; // strlen("key") + strlen("=")
+ *value = (char*)oldstring + firstindex;
+
+ while (oldstring != starttag)
+ {
+ if (*starttag == '>')
+ {
+ foundflag = 0;
+ break;
+ }
+ if (*starttag == '<')
+ break;
+ else
+ starttag--;
+ if (starttag == NULL) break;
+ }
+
+ while (NULL != endtag)
+ {
+ if (*endtag == '<')
+ {
+ foundflag = 0;
+ break;
+ }
+ if (*endtag == '>')
+ break;
+ else
+ endtag++;
+ if (endtag == NULL) break;
+ }
+
+ if (foundflag != 0 && *starttag == '<' && *endtag == '>')
+ foundflag = 1;
+ else
+ foundflag = 0;
+ }
+ else
+ {
+ foundflag = 0;
+ }
+
+ if (foundflag == 1) return 0;
+
+ return -1;
+}
+
+
+static int
+_strbuf_key_value_replace(Eina_Strbuf *srcbuf, char *key, const char *value, int deleteflag)
+{
+ const char *srcstring = NULL;
+ Eina_Strbuf *repbuf = NULL, *diffbuf = NULL;
+ char *curlocater, *replocater;
+ char *starttag, *endtag;
+ int tagtxtlen = 0, insertflag = 0;
+
+ srcstring = eina_strbuf_string_get(srcbuf);
+ curlocater = strstr(srcstring, key);
+
+ if (curlocater == NULL)
+ {
+ insertflag = 1;
+ }
+ else
+ {
+ do
+ {
+ starttag = strchr(srcstring, '<');
+ endtag = strchr(srcstring, '>');
+ tagtxtlen = endtag - starttag;
+ if (tagtxtlen <= 0) tagtxtlen = 0;
+ if (starttag < curlocater && curlocater < endtag) break;
+ if (endtag != NULL && endtag+1 != NULL)
+ srcstring = endtag+1;
+ else
+ break;
+ } while (strlen(srcstring) > 1);
+
+ if (starttag && endtag && tagtxtlen > strlen(key))
+ {
+ repbuf = eina_strbuf_new();
+ diffbuf = eina_strbuf_new();
+ eina_strbuf_append_n(repbuf, starttag, tagtxtlen);
+ srcstring = eina_strbuf_string_get(repbuf);
+ curlocater = strstr(srcstring, key);
+ if (curlocater != NULL)
+ {
+ replocater = curlocater + strlen(key) + 1;
+ while (*replocater != '=' && replocater != NULL)
+ replocater++;
+ if (replocater != NULL)
+ {
+ replocater++;
+ while (*replocater != ' ' && *replocater != '>' && replocater == NULL)
+ replocater++;
+ }
+ if (replocater != NULL)
+ {
+ replocater--;
+ eina_strbuf_append_n(diffbuf, curlocater, replocater-curlocater);
+ }
+ else
+ insertflag = 1;
+ }
+ else
+ {
+ insertflag = 1;
+ }
+ eina_strbuf_reset(repbuf);
+ }
+ else
+ {
+ insertflag = 1;
+ }
+ }
+
+ if (repbuf == NULL) repbuf = eina_strbuf_new();
+ if (diffbuf == NULL) diffbuf = eina_strbuf_new();
+
+ if (insertflag)
+ {
+ eina_strbuf_append_printf(repbuf, "<%s=%s>", key, value);
+ eina_strbuf_prepend(srcbuf, eina_strbuf_string_get(repbuf));
+ }
+ else
+ {
+ if (deleteflag)
+ {
+ eina_strbuf_prepend(diffbuf, "<");
+ eina_strbuf_append(diffbuf, ">");
+ eina_strbuf_replace_first(srcbuf, eina_strbuf_string_get(diffbuf), "");
+ }
+ else
+ {
+ eina_strbuf_append_printf(repbuf, "%s=%s", key, value);
+ eina_strbuf_replace_first(srcbuf, eina_strbuf_string_get(diffbuf), eina_strbuf_string_get(repbuf));
+ }
+ }
+
+ if (repbuf) eina_strbuf_free(repbuf);
+ if (diffbuf) eina_strbuf_free(diffbuf);
+
+ return 0;
+}
+
+static int
+_stringshare_key_value_replace(const char **srcstring, char *key, const char *value, int deleteflag)
+{
+ Eina_Strbuf *sharebuf = NULL;
+
+ sharebuf = eina_strbuf_new();
+ eina_strbuf_append(sharebuf, *srcstring);
+ _strbuf_key_value_replace(sharebuf, key, value, deleteflag);
+ eina_stringshare_del(*srcstring);
+ *srcstring = eina_stringshare_add(eina_strbuf_string_get(sharebuf));
+ eina_strbuf_free(sharebuf);
+
+ return 0;
+}
+
+static int
+_is_width_over(Evas_Object *obj)
+{
+ Evas_Coord x, y, w, h;
+ Evas_Coord vx, vy, vw, vh;
+ Widget_Data *wd = elm_widget_data_get(obj);
+ const char *ellipsis_string = "...";
+ size_t ellen = strlen(ellipsis_string)+1;
+
+ if (!wd) return 0;
+
+ edje_object_part_geometry_get(wd->lbl,"elm.text",&x,&y,&w,&h);
+
+ evas_object_geometry_get (obj, &vx,&vy,&vw,&vh);
+
+ if (x >= 0 && y >= 0) return 0;
+
+ if (ellen < wd->wrap_w && w > wd->wrap_w) return 1;
+
+ return 0;
+}
+
+static void
+_ellipsis_label_to_width(Evas_Object *obj)
+{
+ 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;
+ const char *ellipsis_string = "...";
+ int minfontsize, maxfontsize, minshowcount;
+
+ minshowcount = strlen(ellipsis_string) + 1;
+ minfont = edje_object_data_get(wd->lbl, "min_font_size");
+ if (minfont) minfontsize = atoi(minfont);
+ else minfontsize = 1;
+ maxfont = edje_object_data_get(wd->lbl, "max_font_size");
+ if (maxfont) maxfontsize = atoi(maxfont);
+ else maxfontsize = 1;
+ 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 (eina_stringshare_strlen(wd->label) <= 0) return;
+
+ if (_get_value_in_key_string(wd->label, "font_size", &kvalue) == 0)
+ {
+ if (*kvalue != NULL) cur_fontsize = atoi((char*)kvalue);
+ }
+
+ txtbuf = eina_strbuf_new();
+ eina_strbuf_append(txtbuf, wd->label);
+
+ while (_is_width_over(obj) == 1)
+ {
+ if (cur_fontsize > minfontsize)
+ {
+ cur_fontsize--;
+ if (fontbuf != NULL)
+ {
+ 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;
+ }
+ else
+ {
+ if (txtbuf != NULL)
+ {
+ eina_strbuf_free(txtbuf);
+ txtbuf = NULL;
+ }
+ 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)
+ {
+ 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;
+ }
+ }
+ }
+
+ if (txtbuf) eina_strbuf_free(txtbuf);
+ wd->changed = 1;
+ _sizing_eval(obj);
+}
+
/**
* Add a new label to the parent
*
wd = ELM_NEW(Widget_Data);
e = evas_object_evas_get(parent);
+ wd->bgcolor = EINA_FALSE;
+ wd->bg = evas_object_rectangle_add(e);
+ evas_object_color_set(wd->bg, 0, 0, 0, 0);
obj = elm_widget_add(e);
ELM_SET_WIDTYPE(widtype, "label");
elm_widget_type_set(obj, "label");
elm_widget_can_focus_set(obj, 0);
wd->linewrap = EINA_FALSE;
+ wd->ellipsis = EINA_FALSE;
wd->lbl = edje_object_add(e);
_elm_theme_object_set(obj, wd->lbl, "label", "base", "default");
if (!wd) return 0;
return wd->wrap_w;
}
+
+/**
+ * Set the font size on the label object
+ *
+ * @param obj The label object
+ * @param size font size
+ *
+ * @ingroup Label
+ */
+EAPI void
+elm_label_fontsize_set(Evas_Object *obj, int fontsize)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd = elm_widget_data_get(obj);
+ char *label, fontvalue[16];
+ int len;
+
+ if (!wd) return;
+ len = strlen(wd->label);
+ if (len <= 0) return;
+ label = alloca(sizeof(char)*(len+32));
+ sprintf(fontvalue, "%d", fontsize);
+
+ if (_stringshare_key_value_replace(&wd->label, "font_size", fontvalue, 0) == 0)
+ edje_object_part_text_set(wd->lbl, "elm.text", wd->label);
+
+ if (fontsize == 0) // remove fontsize tag
+ _stringshare_key_value_replace(&wd->label, "font_size", fontvalue, 1);
+
+ wd->changed = 1;
+ _sizing_eval(obj);
+}
+
+/**
+ * Set the text align on the label object
+ *
+ * @param obj The label object
+ * @param align align mode
+ *
+ * @ingroup Label
+ */
+EAPI void
+elm_label_text_align_set(Evas_Object *obj, const char *alignmode)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd = elm_widget_data_get(obj);
+ char *label;
+ int len;
+
+ if (!wd) return;
+ len = strlen(wd->label);
+ if (len <= 0) return;
+
+ 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;
+ _sizing_eval(obj);
+}
+
+/**
+ * Set the text color on the label object
+ *
+ * @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
+ *
+ * @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_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd = elm_widget_data_get(obj);
+ char *label, colorstring[16];
+ int len;
+
+ if (!wd) return;
+ len = strlen(wd->label);
+ if (len <= 0) return;
+ label = alloca(sizeof(char)*(len+32));
+ sprintf(colorstring, "#%02X%02X%02X%02X", r, g, b, a);
+
+ if (_stringshare_key_value_replace(&wd->label, "color", colorstring, 0) == 0)
+ {
+ edje_object_part_text_set(wd->lbl, "elm.text", wd->label);
+ wd->changed = 1;
+ _sizing_eval(obj);
+ }
+}
+
+
+/**
+ * Set background color of the label
+ *
+ * @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
+ * @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_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd = elm_widget_data_get(obj);
+ evas_object_color_set(wd->bg, r, g, b, a);
+
+ if (wd->bgcolor == EINA_FALSE)
+ {
+ wd->bgcolor = 1;
+ edje_object_part_swallow(wd->lbl, "label.swallow.background", wd->bg);
+ }
+}
+
+/**
+ * Set the ellipsis behavior of the label
+ *
+ * @param obj The label object
+ * @param ellipsis To ellipsis text or not
+ * @ingroup Label
+ */
+EAPI void
+elm_label_ellipsis_set(Evas_Object *obj, Eina_Bool ellipsis)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+ Widget_Data *wd = elm_widget_data_get(obj);
+ if (wd->ellipsis == ellipsis) return;
+ wd->ellipsis = ellipsis;
+ wd->changed = 1;
+ _sizing_eval(obj);
+}