forked from enlightenment/efl
Evas textblock: Added ellipsis support (actually only for the 1.0 case) to textblock.
SVN revision: 56542
This commit is contained in:
parent
604f4d5549
commit
5a5ebae319
|
@ -301,6 +301,7 @@ struct _Evas_Object_Textblock_Line
|
||||||
EINA_INLIST;
|
EINA_INLIST;
|
||||||
Evas_Object_Textblock_Item *items;
|
Evas_Object_Textblock_Item *items;
|
||||||
Evas_Object_Textblock_Paragraph *par;
|
Evas_Object_Textblock_Paragraph *par;
|
||||||
|
Evas_Object_Textblock_Text_Item *ellip_ti;
|
||||||
int x, y, w, h;
|
int x, y, w, h;
|
||||||
int baseline;
|
int baseline;
|
||||||
int line_no;
|
int line_no;
|
||||||
|
@ -379,6 +380,7 @@ struct _Evas_Object_Textblock_Format
|
||||||
int linegap;
|
int linegap;
|
||||||
double linerelgap;
|
double linerelgap;
|
||||||
double linefill;
|
double linefill;
|
||||||
|
double ellipsis;
|
||||||
unsigned char style;
|
unsigned char style;
|
||||||
unsigned char wrap_word : 1;
|
unsigned char wrap_word : 1;
|
||||||
unsigned char wrap_char : 1;
|
unsigned char wrap_char : 1;
|
||||||
|
@ -681,9 +683,10 @@ _item_free(const Evas_Object *obj, Evas_Object_Textblock_Line *ln, Evas_Object_T
|
||||||
* @param ln the layout line to be freed, must not be NULL.
|
* @param ln the layout line to be freed, must not be NULL.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
_line_free(const Evas_Object *obj __UNUSED__, Evas_Object_Textblock_Line *ln)
|
_line_free(const Evas_Object *obj, Evas_Object_Textblock_Line *ln)
|
||||||
{
|
{
|
||||||
/* Items are freed from the logical list */
|
/* Items are freed from the logical list, except for the ellip item */
|
||||||
|
if (ln->ellip_ti) _item_free(obj, NULL, _ITEM(ln->ellip_ti));
|
||||||
if (ln) free(ln);
|
if (ln) free(ln);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1126,6 +1129,7 @@ static const char *linegapstr = NULL;
|
||||||
static const char *linerelgapstr = NULL;
|
static const char *linerelgapstr = NULL;
|
||||||
static const char *itemstr = NULL;
|
static const char *itemstr = NULL;
|
||||||
static const char *linefillstr = NULL;
|
static const char *linefillstr = NULL;
|
||||||
|
static const char *ellipsisstr = NULL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
|
@ -1165,6 +1169,7 @@ _format_command_init(void)
|
||||||
linerelgapstr = eina_stringshare_add("linerelgap");
|
linerelgapstr = eina_stringshare_add("linerelgap");
|
||||||
itemstr = eina_stringshare_add("item");
|
itemstr = eina_stringshare_add("item");
|
||||||
linefillstr = eina_stringshare_add("linefill");
|
linefillstr = eina_stringshare_add("linefill");
|
||||||
|
ellipsisstr = eina_stringshare_add("ellipsis");
|
||||||
}
|
}
|
||||||
format_refcount++;
|
format_refcount++;
|
||||||
}
|
}
|
||||||
|
@ -1207,6 +1212,7 @@ _format_command_shutdown(void)
|
||||||
eina_stringshare_del(linerelgapstr);
|
eina_stringshare_del(linerelgapstr);
|
||||||
eina_stringshare_del(itemstr);
|
eina_stringshare_del(itemstr);
|
||||||
eina_stringshare_del(linefillstr);
|
eina_stringshare_del(linefillstr);
|
||||||
|
eina_stringshare_del(ellipsisstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1551,6 +1557,13 @@ _format_command(Evas_Object *obj, Evas_Object_Textblock_Format *fmt, const char
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (cmd == ellipsisstr)
|
||||||
|
{
|
||||||
|
char *endptr = NULL;
|
||||||
|
fmt->ellipsis = strtod(tmp_param, &endptr);
|
||||||
|
if ((fmt->ellipsis < 0.0) || (fmt->ellipsis > 1.0))
|
||||||
|
fmt->ellipsis = -1.0;
|
||||||
|
}
|
||||||
|
|
||||||
if (new_font)
|
if (new_font)
|
||||||
{
|
{
|
||||||
|
@ -1769,7 +1782,7 @@ struct _Ctxt
|
||||||
Eina_Bool align_auto;
|
Eina_Bool align_auto;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void _layout_text_add_logical_item(Ctxt *c, Evas_Object_Textblock_Format *fmt, Evas_Object_Textblock_Text_Item *ti, const Evas_Object_Textblock_Item *rel);
|
static void _layout_text_add_logical_item(Ctxt *c, Evas_Object_Textblock_Text_Item *ti, const Evas_Object_Textblock_Item *rel);
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
* Adjust the ascent/descent of the format and context.
|
* Adjust the ascent/descent of the format and context.
|
||||||
|
@ -2060,7 +2073,7 @@ _layout_line_align_get(Ctxt *c)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
* Reorder the items in a line.
|
* Reorder the items in visual order
|
||||||
*
|
*
|
||||||
* @param line the line to reorder
|
* @param line the line to reorder
|
||||||
*/
|
*/
|
||||||
|
@ -2460,7 +2473,7 @@ _layout_item_text_split_strip_white(Ctxt *c,
|
||||||
|
|
||||||
evas_common_text_props_split(&ti->parent.text_props,
|
evas_common_text_props_split(&ti->parent.text_props,
|
||||||
&new_ti->parent.text_props, cut2);
|
&new_ti->parent.text_props, cut2);
|
||||||
_layout_text_add_logical_item(c, ti->parent.format, new_ti, _ITEM(ti));
|
_layout_text_add_logical_item(c, new_ti, _ITEM(ti));
|
||||||
|
|
||||||
/* FIXME: Will break with kerning and a bunch of other stuff, should
|
/* FIXME: Will break with kerning and a bunch of other stuff, should
|
||||||
* maybe adjust the last adv of the prev and the offset of the cur
|
* maybe adjust the last adv of the prev and the offset of the cur
|
||||||
|
@ -2480,7 +2493,7 @@ _layout_item_text_split_strip_white(Ctxt *c,
|
||||||
|
|
||||||
evas_common_text_props_split(&ti->parent.text_props,
|
evas_common_text_props_split(&ti->parent.text_props,
|
||||||
&white_ti->parent.text_props, cut);
|
&white_ti->parent.text_props, cut);
|
||||||
_layout_text_add_logical_item(c, ti->parent.format, white_ti, _ITEM(ti));
|
_layout_text_add_logical_item(c, white_ti, _ITEM(ti));
|
||||||
ti->parent.w -= white_ti->parent.w;
|
ti->parent.w -= white_ti->parent.w;
|
||||||
ti->parent.adv -= white_ti->parent.adv;
|
ti->parent.adv -= white_ti->parent.adv;
|
||||||
}
|
}
|
||||||
|
@ -2621,19 +2634,16 @@ _layout_word_next(Eina_Unicode *str, int p)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
* Adds the item to the list, updates the item's properties (e.g, x,w,h)
|
* Calculates an item's size.
|
||||||
*
|
*
|
||||||
* @param c the context
|
* @param c the context
|
||||||
* @param fmt the format of the item.
|
|
||||||
* @param it the item itself.
|
* @param it the item itself.
|
||||||
* @param rel item ti will be appened after, NULL = last.
|
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
_layout_text_add_logical_item(Ctxt *c, Evas_Object_Textblock_Format *fmt,
|
_text_item_update_sizes(Ctxt *c, Evas_Object_Textblock_Text_Item *ti)
|
||||||
Evas_Object_Textblock_Text_Item *ti,
|
|
||||||
const Evas_Object_Textblock_Item *rel)
|
|
||||||
{
|
{
|
||||||
int tw, th, adv, inset;
|
int tw, th, adv, inset;
|
||||||
|
const Evas_Object_Textblock_Format *fmt = ti->parent.format;
|
||||||
|
|
||||||
tw = th = 0;
|
tw = th = 0;
|
||||||
if (fmt->font.font)
|
if (fmt->font.font)
|
||||||
|
@ -2652,6 +2662,22 @@ _layout_text_add_logical_item(Ctxt *c, Evas_Object_Textblock_Format *fmt,
|
||||||
ti->text, &ti->parent.text_props);
|
ti->text, &ti->parent.text_props);
|
||||||
ti->parent.adv = adv;
|
ti->parent.adv = adv;
|
||||||
ti->parent.x = 0;
|
ti->parent.x = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
* Adds the item to the list, updates the item's properties (e.g, x,w,h)
|
||||||
|
*
|
||||||
|
* @param c the context
|
||||||
|
* @param it the item itself.
|
||||||
|
* @param rel item ti will be appened after, NULL = last.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
_layout_text_add_logical_item(Ctxt *c, Evas_Object_Textblock_Text_Item *ti,
|
||||||
|
const Evas_Object_Textblock_Item *rel)
|
||||||
|
{
|
||||||
|
_text_item_update_sizes(c, ti);
|
||||||
|
|
||||||
c->par->logical_items = eina_list_append_relative(
|
c->par->logical_items = eina_list_append_relative(
|
||||||
c->par->logical_items, ti, rel);
|
c->par->logical_items, ti, rel);
|
||||||
}
|
}
|
||||||
|
@ -2773,7 +2799,7 @@ skip:
|
||||||
}
|
}
|
||||||
str += tmp_len;
|
str += tmp_len;
|
||||||
|
|
||||||
_layout_text_add_logical_item(c, fmt, ti, NULL);
|
_layout_text_add_logical_item(c, ti, NULL);
|
||||||
|
|
||||||
/* Break if we reached the end. */
|
/* Break if we reached the end. */
|
||||||
if (!*str)
|
if (!*str)
|
||||||
|
@ -3156,13 +3182,51 @@ _layout_get_mixedwrap(Ctxt *c, Evas_Object_Textblock_Format *fmt,
|
||||||
return _layout_get_word_mixwrap_common(c, fmt, ti, EINA_TRUE);
|
return _layout_get_word_mixwrap_common(c, fmt, ti, EINA_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static Evas_Object_Textblock_Text_Item *
|
||||||
|
_layout_ellipsis_item_new(Ctxt *c, const Evas_Object_Textblock_Item *cur_it)
|
||||||
|
{
|
||||||
|
Evas_Object_Textblock_Text_Item *ellip_ti;
|
||||||
|
const Eina_Unicode _ellip_str[4] = { '.', '.', '.', '\0' };
|
||||||
|
/* We assume that the format stack has at least one time,
|
||||||
|
* the only reason it may not have, is more </> than <>, other
|
||||||
|
* than that, we're safe. The last item is the base format. */
|
||||||
|
ellip_ti = _layout_text_item_new(c,
|
||||||
|
eina_list_data_get(eina_list_last(c->format_stack)),
|
||||||
|
_ellip_str);
|
||||||
|
ellip_ti->parent.text_node = cur_it->text_node;
|
||||||
|
ellip_ti->parent.text_pos = cur_it->text_pos;
|
||||||
|
if (cur_it->type == EVAS_TEXTBLOCK_ITEM_TEXT)
|
||||||
|
{
|
||||||
|
ellip_ti->parent.text_pos += eina_unicode_strlen(ellip_ti->text);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ellip_ti->parent.text_pos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
evas_common_text_props_bidi_set(&ellip_ti->parent.text_props,
|
||||||
|
ellip_ti->parent.text_node->bidi_props, ellip_ti->parent.text_pos);
|
||||||
|
evas_common_text_props_script_set (&ellip_ti->parent.text_props,
|
||||||
|
ellip_ti->text);
|
||||||
|
c->ENFN->font_shape(c->ENDT, ellip_ti->parent.format->font.font,
|
||||||
|
ellip_ti->text, &ellip_ti->parent.text_props,
|
||||||
|
ellip_ti->parent.text_node->bidi_props,
|
||||||
|
ellip_ti->parent.text_pos, eina_unicode_strlen(_ellip_str));
|
||||||
|
_text_item_update_sizes(c, ellip_ti);
|
||||||
|
|
||||||
|
return ellip_ti;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 0 means go ahead, 1 means break without an error, 2 means
|
||||||
|
* break with an error, should probably clean this a bit (enum/macro)
|
||||||
|
* FIXME ^ */
|
||||||
|
static int
|
||||||
_layout_visualize_par(Ctxt *c)
|
_layout_visualize_par(Ctxt *c)
|
||||||
{
|
{
|
||||||
Evas_Object_Textblock_Item *it;
|
Evas_Object_Textblock_Item *it;
|
||||||
Eina_List *i;
|
Eina_List *i;
|
||||||
if (!c->par->logical_items)
|
if (!c->par->logical_items)
|
||||||
return;
|
return 2;
|
||||||
|
|
||||||
it = _ITEM(eina_list_data_get(c->par->logical_items));
|
it = _ITEM(eina_list_data_get(c->par->logical_items));
|
||||||
_layout_line_new(c, it->format);
|
_layout_line_new(c, it->format);
|
||||||
|
@ -3182,11 +3246,85 @@ _layout_visualize_par(Ctxt *c)
|
||||||
|
|
||||||
/* Check if we need to wrap, i.e the text is bigger than the width */
|
/* Check if we need to wrap, i.e the text is bigger than the width */
|
||||||
if ((c->w >= 0) &&
|
if ((c->w >= 0) &&
|
||||||
((it->format->wrap_word) || (it->format->wrap_char) ||
|
|
||||||
it->format->wrap_mixed) &&
|
|
||||||
((c->x + it->adv) >
|
((c->x + it->adv) >
|
||||||
(c->w - c->o->style_pad.l - c->o->style_pad.r -
|
(c->w - c->o->style_pad.l - c->o->style_pad.r -
|
||||||
c->marginl - c->marginr)))
|
c->marginl - c->marginr)))
|
||||||
|
{
|
||||||
|
/* Handle ellipsis here */
|
||||||
|
if ((it->format->ellipsis == 1.0) && (c->h >= 0) &&
|
||||||
|
(2 * it->h + c->y >
|
||||||
|
c->h - c->o->style_pad.t - c->o->style_pad.b))
|
||||||
|
{
|
||||||
|
Evas_Object_Textblock_Text_Item *ellip_ti, *last_ti;
|
||||||
|
Evas_Object_Textblock_Item *last_it;
|
||||||
|
Evas_Coord save_cx;
|
||||||
|
int wrap;
|
||||||
|
ellip_ti = _layout_ellipsis_item_new(c, it);
|
||||||
|
last_it = it;
|
||||||
|
last_ti = _ITEM_TEXT(it);
|
||||||
|
|
||||||
|
save_cx = c->x;
|
||||||
|
c->w -= ellip_ti->parent.w;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
wrap = _layout_text_cutoff_get(c, last_it->format,
|
||||||
|
last_ti);
|
||||||
|
if ((wrap > 0) && last_ti->text[wrap])
|
||||||
|
{
|
||||||
|
_layout_item_text_split_strip_white(c, last_ti,
|
||||||
|
wrap);
|
||||||
|
}
|
||||||
|
else if (wrap == 0)
|
||||||
|
{
|
||||||
|
if (!c->ln->items)
|
||||||
|
break;
|
||||||
|
/* We haven't added it yet at this point */
|
||||||
|
if (_ITEM(last_ti) != it)
|
||||||
|
{
|
||||||
|
last_it =
|
||||||
|
_ITEM(EINA_INLIST_GET(last_it)->prev);
|
||||||
|
c->ln->items = _ITEM(eina_inlist_remove(
|
||||||
|
EINA_INLIST_GET(c->ln->items),
|
||||||
|
EINA_INLIST_GET(_ITEM(last_ti))));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
last_it =
|
||||||
|
_ITEM(EINA_INLIST_GET(c->ln->items)->last);
|
||||||
|
}
|
||||||
|
last_ti = _ITEM_TEXT(last_it);
|
||||||
|
if (last_it)
|
||||||
|
{
|
||||||
|
c->x -= last_it->adv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (last_it && (wrap == 0));
|
||||||
|
c->x = save_cx;
|
||||||
|
c->w += ellip_ti->parent.w;
|
||||||
|
/* If we should add this item, do it */
|
||||||
|
if (last_it == it)
|
||||||
|
{
|
||||||
|
c->ln->items = (Evas_Object_Textblock_Item *)
|
||||||
|
eina_inlist_append(EINA_INLIST_GET(c->ln->items),
|
||||||
|
EINA_INLIST_GET(it));
|
||||||
|
if (it->type == EVAS_TEXTBLOCK_ITEM_FORMAT)
|
||||||
|
{
|
||||||
|
Evas_Object_Textblock_Format_Item *fi;
|
||||||
|
fi = _ITEM_FORMAT(it);
|
||||||
|
fi->y = c->y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c->ln->items = (Evas_Object_Textblock_Item *)
|
||||||
|
eina_inlist_append(EINA_INLIST_GET(c->ln->items),
|
||||||
|
EINA_INLIST_GET(_ITEM(ellip_ti)));
|
||||||
|
c->ln->ellip_ti = ellip_ti;
|
||||||
|
_layout_line_finalize(c, ellip_ti->parent.format);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (it->format->wrap_word || it->format->wrap_char ||
|
||||||
|
it->format->wrap_mixed)
|
||||||
{
|
{
|
||||||
if (it->type == EVAS_TEXTBLOCK_ITEM_FORMAT)
|
if (it->type == EVAS_TEXTBLOCK_ITEM_FORMAT)
|
||||||
{
|
{
|
||||||
|
@ -3226,6 +3364,7 @@ _layout_visualize_par(Ctxt *c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!redo_item)
|
if (!redo_item)
|
||||||
{
|
{
|
||||||
|
@ -3261,6 +3400,7 @@ _layout_visualize_par(Ctxt *c)
|
||||||
/* Here 'it' is the last format used */
|
/* Here 'it' is the last format used */
|
||||||
_layout_line_finalize(c, it->format);
|
_layout_line_finalize(c, it->format);
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3478,7 +3618,9 @@ _layout(const Evas_Object *obj, int calc_only, int w, int h, int *w_ret, int *h_
|
||||||
{
|
{
|
||||||
c->par = par;
|
c->par = par;
|
||||||
_layout_update_par(c);
|
_layout_update_par(c);
|
||||||
_layout_visualize_par(c);
|
/* Break if we should stop here. */
|
||||||
|
if (_layout_visualize_par(c))
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* End of visual layout creation */
|
/* End of visual layout creation */
|
||||||
|
|
Loading…
Reference in New Issue