From 544a6f064b26fb9a9d1acace93a9d742f9222395 Mon Sep 17 00:00:00 2001 From: Youngbok Shin Date: Thu, 10 Nov 2016 16:21:05 +0900 Subject: [PATCH] edje entry: keep cursor position on mouse down and move When elm_entry takes focus by a mouse click event, elm_entry needs to get new cursor position which is changed by mouse down/move/up. But, elm_entry takes focus before updating the cursor of edje_entry. It causes an issue about showing proper region. So, the internal API will be used when elm_entry takes focus. @tizen_fix Change-Id: Ie479f9c2763eca56effc57ad7d3409fad7f0830e --- src/lib/edje/edje_entry.c | 79 +++++++++++++++++++++++++++++++++++++++++++++ src/lib/edje/edje_object.eo | 19 +++++++++++ src/lib/edje/edje_private.h | 3 ++ src/lib/edje/edje_util.c | 22 +++++++++++++ 4 files changed, 123 insertions(+) diff --git a/src/lib/edje/edje_entry.c b/src/lib/edje/edje_entry.c index 783efa1..20f9a60 100644 --- a/src/lib/edje/edje_entry.c +++ b/src/lib/edje/edje_entry.c @@ -31,6 +31,9 @@ struct _Entry Evas_Textblock_Cursor *sel_start, *sel_end; Evas_Textblock_Cursor *cursor_user, *cursor_user_extra; Evas_Textblock_Cursor *preedit_start, *preedit_end; + /* TIZEN_ONLY(20161110): keep cursor position on mouse down and move */ + Evas_Textblock_Cursor *cursor_on_mouse; + /* END */ Ecore_Timer *pw_timer; Eina_List *sel; Eina_List *anchors; @@ -2390,6 +2393,12 @@ _edje_part_mouse_down_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_ cx = ev->canvas.x - x; cy = ev->canvas.y - y; + /* TIZEN_ONLY(20161110): keep cursor position on mouse down and move */ + if (!en->cursor_on_mouse) + en->cursor_on_mouse = evas_object_textblock_cursor_new(rp->object); + evas_textblock_cursor_cluster_coord_set(en->cursor_on_mouse, cx, cy); + /* END */ + /* TIZEN ONLY(20161109): only change cursor position in mouse up if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, cy)) */ @@ -2527,14 +2536,25 @@ _edje_part_mouse_up_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UN if ((!ev) || (ev->button != 1)) return; if (!rp) return; + /* TIZEN_ONLY(20161110): keep cursor position on mouse down and move if (ev->flags & EVAS_BUTTON_TRIPLE_CLICK) return; if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK) return; + */ if ((rp->type != EDJE_RP_TYPE_TEXT) || (!rp->typedata.text)) return; en = rp->typedata.text->entry_data; if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) || (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE)) return; + /* TIZEN_ONLY(20161110): keep cursor position on mouse down and move */ + if (en->cursor_on_mouse) + { + evas_textblock_cursor_free(en->cursor_on_mouse); + en->cursor_on_mouse = NULL; + } + if (ev->flags & EVAS_BUTTON_TRIPLE_CLICK) return; + if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK) return; + /* END */ /* We don't check for ON_HOLD because we'd like to end selection anyway when * mouse is up, even if it's held. */ @@ -2671,6 +2691,15 @@ _edje_part_mouse_move_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_ (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE)) return; + /* TIZEN_ONLY(20161110): keep cursor position on mouse down and move */ + evas_object_geometry_get(rp->object, &x, &y, &w, &h); + cx = ev->cur.canvas.x - x; + cy = ev->cur.canvas.y - y; + + if (en->cursor_on_mouse) + evas_textblock_cursor_cluster_coord_set(en->cursor_on_mouse, cx, cy); + /* END */ + #ifdef HAVE_ECORE_IMF if (en->imf_context) { @@ -2687,9 +2716,11 @@ _edje_part_mouse_move_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_ { tc = evas_object_textblock_cursor_new(rp->object); evas_textblock_cursor_copy(en->cursor, tc); + /* TIZEN_ONLY(20161110): keep cursor position on mouse down and move evas_object_geometry_get(rp->object, &x, &y, &w, &h); cx = ev->cur.canvas.x - x; cy = ev->cur.canvas.y - y; + */ // TIZEN_ONLY(20150127): Add evas_textblock_cursor_cluster_* APIs. //if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, cy)) if (!evas_textblock_cursor_cluster_coord_set(en->cursor, cx, cy)) @@ -3481,6 +3512,54 @@ _edje_entry_cursor_geometry_get(Edje_Real_Part *rp, Evas_Coord *cx, Evas_Coord * if (cdir) *cdir = dir; } +/* TIZEN_ONLY(20161110): keep cursor position on mouse down and move */ +void +_edje_entry_cursor_on_mouse_geometry_get(Edje_Real_Part *rp, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch, Evas_BiDi_Direction *cdir) +{ + Evas_Coord x, y, w, h, xx, yy, ww, hh; + Entry *en; + Evas_Textblock_Cursor_Type cur_type; + Evas_BiDi_Direction dir; + + if ((rp->type != EDJE_RP_TYPE_TEXT) || + (!rp->typedata.text)) return; + en = rp->typedata.text->entry_data; + if (!en) return; + + if (!en->cursor_on_mouse) + { + _edje_entry_cursor_geometry_get(rp, cx, cy, cw, ch, cdir); + } + else + { + switch (rp->part->cursor_mode) + { + case EDJE_ENTRY_CURSOR_MODE_BEFORE: + cur_type = EVAS_TEXTBLOCK_CURSOR_BEFORE; + break; + + case EDJE_ENTRY_CURSOR_MODE_UNDER: + /* no break for a reason */ + default: + cur_type = EVAS_TEXTBLOCK_CURSOR_UNDER; + } + + 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_on_mouse, &xx, &yy, &ww, &hh, &dir, cur_type); + if (ww < 1) ww = 1; + if (rp->part->cursor_mode == EDJE_ENTRY_CURSOR_MODE_BEFORE) + edje_object_size_min_restricted_calc(en->cursor_fg, &ww, NULL, ww, 0); + if (hh < 1) hh = 1; + if (cx) *cx = x + xx; + if (cy) *cy = y + yy; + if (cw) *cw = ww; + if (ch) *ch = hh; + if (cdir) *cdir = dir; + } +} + void _edje_entry_user_insert(Edje_Real_Part *rp, const char *text) { diff --git a/src/lib/edje/edje_object.eo b/src/lib/edje/edje_object.eo index 9b45aa3..fc5181f 100644 --- a/src/lib/edje/edje_object.eo +++ b/src/lib/edje/edje_object.eo @@ -2692,6 +2692,25 @@ class Edje.Object (Evas.Smart_Clipped, Efl.File) @out h: Evas.Coord; [[Cursor height]] } } + /* TIZEN_ONLY(20161110): keep cursor position on mouse down and move */ + part_text_cursor_on_mouse_geometry_get @const { + [[Returns the cursor geometry of the part relative to the edje + object. The cursor geometry is kept in mouse down and move. + + \@internal + \@if MOBILE \@since_tizen 3.0 + \@elseif WEARABLE \@since_tizen 3.0 + \@endif + ]] + params { + @in part: const(char)*; [[The part name]] + @out x: Evas.Coord; [[Cursor X position]] + @out y: Evas.Coord; [[Cursor Y position]] + @out w: Evas.Coord; [[Cursor width]] + @out h: Evas.Coord; [[Cursor height]] + } + } + /* END */ part_text_anchor_list_get @const { [[Return a list of char anchor names. diff --git a/src/lib/edje/edje_private.h b/src/lib/edje/edje_private.h index a0bb795..d11565a 100644 --- a/src/lib/edje/edje_private.h +++ b/src/lib/edje/edje_private.h @@ -2769,6 +2769,9 @@ const Eina_List *_edje_entry_anchors_list(Edje_Real_Part *rp); Eina_Bool _edje_entry_item_geometry_get(Edje_Real_Part *rp, const char *item, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch); const Eina_List *_edje_entry_items_list(Edje_Real_Part *rp); void _edje_entry_cursor_geometry_get(Edje_Real_Part *rp, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch, Evas_BiDi_Direction *cdir); +/* TIZEN_ONLY(20161110): keep cursor position on mouse down and move */ +void _edje_entry_cursor_on_mouse_geometry_get(Edje_Real_Part *rp, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch, Evas_BiDi_Direction *cdir); +/* END */ void _edje_entry_user_insert(Edje_Real_Part *rp, const char *text); void _edje_entry_select_allow_set(Edje_Real_Part *rp, Eina_Bool allow); Eina_Bool _edje_entry_select_allow_get(const Edje_Real_Part *rp); diff --git a/src/lib/edje/edje_util.c b/src/lib/edje/edje_util.c index 90361cb..b4c848d 100644 --- a/src/lib/edje/edje_util.c +++ b/src/lib/edje/edje_util.c @@ -2687,6 +2687,28 @@ _edje_object_part_text_cursor_geometry_get(Eo *obj EINA_UNUSED, Edje *ed, const } } +/* TIZEN_ONLY(20161110): keep cursor position on mouse down and move */ +EOLIAN void +_edje_object_part_text_cursor_on_mouse_geometry_get(Eo *obj EINA_UNUSED, Edje *ed, const char *part, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h) +{ + Edje_Real_Part *rp; + + if (x) *x = 0; + if (y) *y = 0; + if (w) *w = 0; + if (h) *h = 0; + if ((!ed) || (!part)) return; + rp = _edje_real_part_recursive_get(&ed, part); + if (!rp) return; + if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE) + { + _edje_entry_cursor_on_mouse_geometry_get(rp, x, y, w, h, NULL); + if (x) *x -= ed->x; + if (y) *y -= ed->y; + } +} +/* END */ + EOLIAN void _edje_object_part_text_user_insert(Eo *obj EINA_UNUSED, Edje *ed, const char *part, const char *text) { -- 2.7.4