forked from enlightenment/efl
Efl textblock/entry: Added support for split BiDi cursor.
If logical cursor is between LTR/RTL text two cursors will be shown. Upper cursor is shown for the text of the same direction as paragraph, lower cursor - for opposite. NOT DONE YET Signed-off-by: Tom 'TAsn' Hacohen <tom@stosb.com>
This commit is contained in:
parent
afddaf94a0
commit
a70abbb381
|
@ -21,7 +21,7 @@ struct _Entry
|
|||
Edje_Real_Part *rp;
|
||||
Edje *ed;
|
||||
Evas_Object *cursor_bg;
|
||||
Evas_Object *cursor_fg;
|
||||
Evas_Object *cursor_fg, *cursor_fg2;
|
||||
Evas_Textblock_Cursor *cursor;
|
||||
Evas_Textblock_Cursor *sel_start, *sel_end;
|
||||
Evas_Textblock_Cursor *cursor_user, *cursor_user_extra;
|
||||
|
@ -2406,12 +2406,26 @@ _edje_entry_real_part_init(Edje *ed, Edje_Real_Part *rp)
|
|||
evas_object_pass_events_set(en->cursor_fg, EINA_TRUE);
|
||||
_edje_subobj_register(ed, en->cursor_fg);
|
||||
|
||||
/* A proxy to the main cursor. */
|
||||
if (rp->part->cursor_mode == EDJE_ENTRY_CURSOR_MODE_BEFORE)
|
||||
{
|
||||
en->cursor_fg2 = evas_object_image_add(rp->edje->base->evas);
|
||||
evas_object_image_source_set(en->cursor_fg2, en->cursor_fg);
|
||||
evas_object_image_fill_set(en->cursor_fg2, 0, 0, 1, 1);
|
||||
evas_object_smart_member_add(en->cursor_fg2, rp->edje->obj);
|
||||
evas_object_stack_above(en->cursor_fg2, rp->object);
|
||||
evas_object_clip_set(en->cursor_fg2, evas_object_clip_get(rp->object));
|
||||
evas_object_pass_events_set(en->cursor_fg2, EINA_TRUE);
|
||||
_edje_subobj_register(en->rp->edje, en->cursor_fg2);
|
||||
}
|
||||
|
||||
evas_object_textblock_legacy_newline_set(rp->object, EINA_TRUE);
|
||||
|
||||
if (rp->part->entry_mode >= EDJE_ENTRY_EDIT_MODE_EDITABLE)
|
||||
{
|
||||
evas_object_show(en->cursor_bg);
|
||||
evas_object_show(en->cursor_fg);
|
||||
evas_object_show(en->cursor_fg2);
|
||||
en->input_panel_enable = EINA_TRUE;
|
||||
|
||||
#ifdef HAVE_ECORE_IMF
|
||||
|
@ -2487,6 +2501,7 @@ _edje_entry_real_part_shutdown(Edje *ed, Edje_Real_Part *rp)
|
|||
#endif
|
||||
evas_object_del(en->cursor_bg);
|
||||
evas_object_del(en->cursor_fg);
|
||||
evas_object_del(en->cursor_fg2);
|
||||
|
||||
if (en->pw_timer)
|
||||
{
|
||||
|
@ -2519,9 +2534,10 @@ _edje_entry_real_part_shutdown(Edje *ed, Edje_Real_Part *rp)
|
|||
void
|
||||
_edje_entry_real_part_configure(Edje *ed, Edje_Real_Part *rp)
|
||||
{
|
||||
Evas_Coord x, y, w, h, xx, yy, ww, hh;
|
||||
Evas_Coord x, y, w, h, xx, yy, ww, hh, xx2, yy2;
|
||||
Entry *en;
|
||||
Evas_Textblock_Cursor_Type cur_type;
|
||||
Eina_Bool bidi_cursor = EINA_FALSE;
|
||||
|
||||
if ((rp->type != EDJE_RP_TYPE_TEXT) ||
|
||||
(!rp->typedata.text)) return;
|
||||
|
@ -2543,7 +2559,7 @@ _edje_entry_real_part_configure(Edje *ed, Edje_Real_Part *rp)
|
|||
x = y = w = h = -1;
|
||||
xx = yy = ww = hh = -1;
|
||||
evas_object_geometry_get(rp->object, &x, &y, &w, &h);
|
||||
evas_textblock_cursor_geometry_get(en->cursor, &xx, &yy, &ww, &hh, NULL, cur_type);
|
||||
bidi_cursor = evas_textblock_cursor_geometry_bidi_get(en->cursor, &xx, &yy, &ww, &hh, &xx2, &yy2, NULL, NULL, cur_type);
|
||||
if (ww < 1) ww = 1;
|
||||
if (hh < 1) hh = 1;
|
||||
if (en->cursor_bg)
|
||||
|
@ -2556,6 +2572,22 @@ _edje_entry_real_part_configure(Edje *ed, Edje_Real_Part *rp)
|
|||
evas_object_move(en->cursor_fg, x + xx, y + yy);
|
||||
evas_object_resize(en->cursor_fg, ww, hh);
|
||||
}
|
||||
if (en->cursor_fg2)
|
||||
{
|
||||
if (bidi_cursor)
|
||||
{
|
||||
evas_object_image_fill_set(en->cursor_fg2, 0, 0, ww, hh / 2);
|
||||
evas_object_move(en->cursor_fg2, x + xx2, y + yy2 + (hh / 2));
|
||||
evas_object_resize(en->cursor_fg, ww, hh / 2);
|
||||
evas_object_resize(en->cursor_fg2, ww, hh / 2);
|
||||
|
||||
evas_object_show(en->cursor_fg2);
|
||||
}
|
||||
else
|
||||
{
|
||||
evas_object_hide(en->cursor_fg2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
|
|
|
@ -11628,6 +11628,11 @@ EAPI char *evas_textblock_cursor_range_text_g
|
|||
*/
|
||||
EAPI char *evas_textblock_cursor_content_get(const Evas_Textblock_Cursor *cur) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC;
|
||||
|
||||
/** FIXME: doc.
|
||||
* The cw2 and etc are not valid if false is returned. */
|
||||
EAPI Eina_Bool
|
||||
evas_textblock_cursor_geometry_bidi_get(const Evas_Textblock_Cursor *cur, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch, Evas_Coord *cx2, Evas_Coord *cy2, Evas_Coord *cw2, Evas_Coord *ch2, Evas_Textblock_Cursor_Type ctype);
|
||||
|
||||
/**
|
||||
* Returns the geometry of the cursor. Depends on the type of cursor requested.
|
||||
* This should be used instead of char_geometry_get because there are weird
|
||||
|
|
|
@ -8950,6 +8950,100 @@ evas_textblock_cursor_format_is_visible_get(const Evas_Textblock_Cursor *cur)
|
|||
return EVAS_TEXTBLOCK_IS_VISIBLE_FORMAT_CHAR(text[cur->pos]);
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
evas_textblock_cursor_geometry_bidi_get(const Evas_Textblock_Cursor *cur, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch, Evas_Coord *cx2, Evas_Coord *cy2, Evas_Coord *cw2, Evas_Coord *ch2, Evas_Textblock_Cursor_Type ctype)
|
||||
{
|
||||
const Evas_Textblock_Cursor *dir_cur;
|
||||
Evas_Textblock_Cursor cur2;
|
||||
if (!cur) return EINA_FALSE;
|
||||
Evas_Object_Textblock *o = eo_data_get(cur->obj, MY_CLASS);
|
||||
if (!o->formatted.valid) _relayout(cur->obj);
|
||||
|
||||
dir_cur = cur;
|
||||
if (ctype == EVAS_TEXTBLOCK_CURSOR_UNDER)
|
||||
{
|
||||
evas_textblock_cursor_pen_geometry_get(cur, cx, cy, cw, ch);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
Evas_Object_Textblock_Line *ln = NULL;
|
||||
Evas_Object_Textblock_Item *it = NULL;
|
||||
_find_layout_item_match(cur, &ln, &it);
|
||||
if (ln && it)
|
||||
{
|
||||
if (cw) *cw = 0;
|
||||
if (cw2) *cw2 = 0;
|
||||
/* If we are at the start or the end of the item there's a chance
|
||||
* we'll want a split cursor.
|
||||
* FIXME: Handle the last char of the last paragraph.
|
||||
* FIXME: Handle multiple items of the same direction.
|
||||
* FIXME: Handle items across different lines.. */
|
||||
if (cur->pos == it->text_pos)
|
||||
{
|
||||
Evas_BiDi_Direction itdir = (it->type == EVAS_TEXTBLOCK_ITEM_TEXT) ?
|
||||
_ITEM_TEXT(it)->text_props.bidi_dir : _ITEM_FORMAT(it)->bidi_dir;
|
||||
Evas_Object_Textblock_Item *previt = NULL;
|
||||
Evas_BiDi_Direction previtdir = EVAS_BIDI_DIRECTION_NEUTRAL;
|
||||
/* Get the logically previous item. */
|
||||
{
|
||||
Eina_List *itr;
|
||||
Evas_Object_Textblock_Item *ititr;
|
||||
EINA_LIST_FOREACH(ln->par->logical_items, itr, ititr)
|
||||
{
|
||||
if (ititr == it)
|
||||
break;
|
||||
previt = ititr;
|
||||
}
|
||||
|
||||
if (previt)
|
||||
{
|
||||
previtdir = (previt->type == EVAS_TEXTBLOCK_ITEM_TEXT) ?
|
||||
_ITEM_TEXT(previt)->text_props.bidi_dir : _ITEM_FORMAT(previt)->bidi_dir;
|
||||
}
|
||||
}
|
||||
|
||||
if (previt && (itdir != previtdir))
|
||||
{
|
||||
Evas_Object_Textblock_Item *curit = NULL;
|
||||
/* If the current dir is different than the paragraph dir
|
||||
* this is our item. */
|
||||
if (itdir != ln->par->direction)
|
||||
{
|
||||
curit = it;
|
||||
}
|
||||
else
|
||||
{
|
||||
curit = previt;
|
||||
}
|
||||
|
||||
if (((curit == it) && (ln->par->direction == EVAS_BIDI_DIRECTION_LTR)) ||
|
||||
((curit == previt) && (ln->par->direction == EVAS_BIDI_DIRECTION_RTL)))
|
||||
{
|
||||
if (cx) *cx = ln->x + curit->x;
|
||||
if (cx2) *cx2 = ln->x + curit->x + curit->w;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cx) *cx = ln->x + curit->x + curit->w;
|
||||
if (cx2) *cx2 = ln->x + curit->x;
|
||||
}
|
||||
|
||||
if (cy) *cy = ln->par->y + ln->y;
|
||||
if (ch) *ch = curit->h;
|
||||
|
||||
if (cy2) *cy2 = ln->par->y + ln->y;
|
||||
if (ch2) *ch2 = curit->h;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
evas_textblock_cursor_geometry_get(cur, cx, cy, cw, ch, NULL, ctype);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
EAPI int
|
||||
evas_textblock_cursor_geometry_get(const Evas_Textblock_Cursor *cur, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch, Evas_BiDi_Direction *dir, Evas_Textblock_Cursor_Type ctype)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue