From: 장효영 <hyoyoung.chang@samsung.com>

I've added elm_label features. That are fontsize, color, background color and
ellipsis (cutting text to fit widget size) features. Most of the property
setting API is wrapping to label tag set.

The rllipsis feature checks part size and cuts character to fit its size.



SVN revision: 50275
This commit is contained in:
장효영 2010-07-16 05:50:45 +00:00 committed by Carsten Haitzler
parent c9e3c7dfbc
commit b32cbb2a3a
3 changed files with 498 additions and 21 deletions

View File

@ -527,18 +527,27 @@ collections {
///////////////////////////////////////////////////////////////////////////////
group { name: "elm/label/base/default";
styles
{
style { name: "textblock_style";
base: "font=Sans font_size=10 align=left color=#000 wrap=word";
tag: "br" "\n";
tag: "hilight" "+ font=Sans:style=Bold";
tag: "b" "+ font=Sans:style=Bold";
tag: "tab" "\t";
data.item: "default_font_size" "24";
data.item: "min_font_size" "8";
data.item: "max_font_size" "60";
styles {
style { name: "textblock_style";
base: "font=Sans font_size=10 align=left color=#000 wrap=word";
tag: "br" "\n";
tag: "hilight" "+ font=Sans:style=Bold";
tag: "b" "+ font=Sans:style=Bold";
tag: "tab" "\t";
}
}
parts {
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: "elm.text";
type: TEXTBLOCK;
mouse_events: 0;
@ -554,7 +563,18 @@ collections {
}
group { name: "elm/label/base_wrap/default";
data.item: "default_font_size" "24";
data.item: "min_font_size" "8";
data.item: "max_font_size" "60";
parts {
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: "elm.text";
type: TEXTBLOCK;
mouse_events: 0;
@ -570,18 +590,27 @@ collections {
}
group { name: "elm/label/base/marker";
styles
{
style { name: "textblock_style2";
base: "font=Sans:style=Bold font_size=10 align=center color=#fff wrap=word";
tag: "br" "\n";
tag: "hilight" "+ color=#ffff";
tag: "b" "+ color=#ffff";
tag: "tab" "\t";
}
}
data.item: "default_font_size" "24";
data.item: "min_font_size" "8";
data.item: "max_font_size" "60";
styles {
style { name: "textblock_style2";
base: "font=Sans:style=Bold font_size=10 align=center color=#fff wrap=word";
tag: "br" "\n";
tag: "hilight" "+ color=#ffff";
tag: "b" "+ color=#ffff";
tag: "tab" "\t";
}
}
parts {
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: "elm.text";
type: TEXTBLOCK;
mouse_events: 0;
@ -597,8 +626,19 @@ collections {
}
group { name: "elm/label/base_wrap/marker";
data.item: "default_font_size" "24";
data.item: "min_font_size" "8";
data.item: "max_font_size" "60";
parts {
part { name: "elm.text";
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: "elm.text";
type: TEXTBLOCK;
mouse_events: 0;
scale: 1;

View File

@ -531,6 +531,11 @@ extern "C" {
EAPI Eina_Bool elm_label_line_wrap_get(const Evas_Object *obj);
EAPI void elm_label_wrap_width_set(Evas_Object *obj, Evas_Coord w);
EAPI Evas_Coord elm_label_wrap_width_get(const Evas_Object *obj);
EAPI void elm_label_fontsize_set(Evas_Object *obj, int fontsize);
EAPI void elm_label_text_color_set(Evas_Object *obj, unsigned int r, unsigned int g, unsigned int b, unsigned int a);
EAPI void elm_label_text_align_set(Evas_Object *obj, const char *alignmode);
EAPI void elm_label_background_color_set(Evas_Object *obj, unsigned int r, unsigned int g, unsigned int b, unsigned int a);
EAPI void elm_label_ellipsis_set(Evas_Object *obj, Eina_Bool ellipsis);
/* available styles:
* default
* marker

View File

@ -13,18 +13,26 @@ typedef struct _Widget_Data Widget_Data;
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)
@ -62,6 +70,7 @@ _del_hook(Evas_Object *obj)
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);
}
@ -105,6 +114,9 @@ _sizing_eval(Evas_Object *obj)
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);
}
}
@ -115,6 +127,287 @@ _resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event
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
*
@ -132,6 +425,9 @@ elm_label_add(Evas_Object *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");
@ -142,6 +438,7 @@ elm_label_add(Evas_Object *parent)
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");
@ -269,3 +566,138 @@ elm_label_wrap_width_get(const Evas_Object *obj)
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);
}