yakov pushed a commit to branch master.
commit a70abbb3811bd9426bc3e30bd70fb3b027cc29e6
Author: Tom 'TAsn' Hacohen <[email protected]>
Date: Mon Jan 14 16:18:07 2013 +0000
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 <[email protected]>
---
src/lib/edje/edje_entry.c | 38 +++++++++++-
src/lib/evas/Evas.h | 5 ++
src/lib/evas/canvas/evas_object_textblock.c | 94 +++++++++++++++++++++++++++++
3 files changed, 134 insertions(+), 3 deletions(-)
diff --git a/src/lib/edje/edje_entry.c b/src/lib/edje/edje_entry.c
index 5f43d39..d7b0f77 100644
--- a/src/lib/edje/edje_entry.c
+++ b/src/lib/edje/edje_entry.c
@@ -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 *
diff --git a/src/lib/evas/Evas.h b/src/lib/evas/Evas.h
index 900836e..9d3603b 100644
--- a/src/lib/evas/Evas.h
+++ b/src/lib/evas/Evas.h
@@ -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
diff --git a/src/lib/evas/canvas/evas_object_textblock.c
b/src/lib/evas/canvas/evas_object_textblock.c
index fce36ee..994b258 100644
--- a/src/lib/evas/canvas/evas_object_textblock.c
+++ b/src/lib/evas/canvas/evas_object_textblock.c
@@ -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)
{
--
------------------------------------------------------------------------------
Precog is a next-generation analytics platform capable of advanced
analytics on semi-structured data. The platform includes APIs for building
apps and a phenomenal toolset for data science. Developers can use
our toolset for easy data analysis & visualization. Get a free account!
http://www2.precog.com/precogplatform/slashdotnewsletter