edje entry: keep cursor position on mouse down and move
authorYoungbok Shin <youngb.shin@samsung.com>
Thu, 10 Nov 2016 07:21:05 +0000 (16:21 +0900)
committerJunsuChoi <jsuya.choi@samsung.com>
Thu, 17 Nov 2016 07:54:18 +0000 (16:54 +0900)
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
src/lib/edje/edje_object.eo
src/lib/edje/edje_private.h
src/lib/edje/edje_util.c

index 783efa1..20f9a60 100644 (file)
@@ -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)
 {
index 9b45aa3..fc5181f 100644 (file)
@@ -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.
 
index a0bb795..d11565a 100644 (file)
@@ -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);
index 90361cb..b4c848d 100644 (file)
@@ -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)
 {