efl.ui.text : Fixing cursor movement using keyboard arrows/mouse click

Summary:
if we have an emoji or a cluster combining multiple Unicode inside ui textbox, we can move the cursor inside the emoji/cluster using keyboard arrows/mouse click.
so we should use cluster movement instead of character movement (same as entry).

{F3868931}

this should resolve T8666

Test Plan:
  #define EFL_EO_API_SUPPORT 1
  #define EFL_BETA_API_SUPPORT 1

  #include <Efl_Ui.h>

  static void
  _gui_quit_cb(void *data EINA_UNUSED, const Efl_Event *event EINA_UNUSED)
  {
     efl_exit(0);
  }

  static void
  _gui_setup()
  {
     Eo *win, *box;

     win = efl_add(EFL_UI_WIN_CLASS, efl_main_loop_get(),
                   efl_ui_win_type_set(efl_added, EFL_UI_WIN_TYPE_BASIC),
                   efl_text_set(efl_added, "Hello World"),
                   efl_ui_win_autodel_set(efl_added, EINA_TRUE));

     // when the user clicks "close" on a window there is a request to delete
     efl_event_callback_add(win, EFL_UI_WIN_EVENT_DELETE_REQUEST, _gui_quit_cb, NULL);

     box = efl_add(EFL_UI_BOX_CLASS, win,
                  efl_content_set(win, efl_added),
                  efl_gfx_hint_size_min_set(efl_added, EINA_SIZE2D(360, 240)));

     efl_add(EFL_UI_TEXTBOX_CLASS, box,
             efl_gfx_hint_weight_set(efl_added, 1.0, 1.0),
             efl_gfx_hint_align_set(efl_added, 1.0, 1.0),
             efl_text_markup_set(efl_added, "A&#x262a;&#xfe0f;"),
             efl_pack(box, efl_added));
  }

  EAPI_MAIN void
  efl_main(void *data EINA_UNUSED, const Efl_Event *ev EINA_UNUSED)
  {
     _gui_setup();
  }
  EFL_MAIN()

Reviewers: ali.alzyod, zmike, woohyun, bu5hm4n

Reviewed By: ali.alzyod, woohyun

Subscribers: zmike, cedric, #reviewers, #committers

Tags: #efl

Maniphest Tasks: T8666

Differential Revision: https://phab.enlightenment.org/D11745
This commit is contained in:
abdulleh Ghujeh 2020-10-20 19:20:27 +09:00 committed by WooHyun Jung
parent 3274390f73
commit d6a6dd54a1
2 changed files with 48 additions and 6 deletions

View File

@ -1251,7 +1251,7 @@ _key_down_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void
#endif
if (efl_text_interactive_have_selection_get(obj))
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
if (efl_text_cursor_object_move(cur,EFL_TEXT_CURSOR_MOVE_TYPE_CHARACTER_PREVIOUS))
if (efl_text_cursor_object_move(cur,EFL_TEXT_CURSOR_MOVE_TYPE_CLUSTER_PREVIOUS))
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
_key_down_sel_post(obj, cur, en, shift);
@ -1270,7 +1270,7 @@ _key_down_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void
#endif
if (efl_text_interactive_have_selection_get(obj))
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
if (efl_text_cursor_object_move(cur, EFL_TEXT_CURSOR_MOVE_TYPE_CHARACTER_NEXT))
if (efl_text_cursor_object_move(cur, EFL_TEXT_CURSOR_MOVE_TYPE_CLUSTER_NEXT))
ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
_key_down_sel_post(obj, cur, en, shift);
@ -1551,7 +1551,7 @@ end:
}
static void
_cursor_char_coord_set(Efl_Canvas_Textblock *obj, Efl_Text_Cursor_Object *cur, Evas_Coord canvasx, Evas_Coord canvasy, Evas_Coord *_cx, Evas_Coord *_cy)
_cursor_cluster_coord_set(Efl_Canvas_Textblock *obj, Efl_Text_Cursor_Object *cur, Evas_Coord canvasx, Evas_Coord canvasy, Evas_Coord *_cx, Evas_Coord *_cy)
{
Evas_Coord cx, cy;
Evas_Coord x, y, lh = 0, cly = 0;
@ -1582,7 +1582,7 @@ _cursor_char_coord_set(Efl_Canvas_Textblock *obj, Efl_Text_Cursor_Object *cur, E
efl_del(line_cur);
/* No need to check return value if not able to set the char coord Textblock
* will take care */
efl_text_cursor_object_char_coord_set(cur, EINA_POSITION2D(cx, cy));
efl_text_cursor_object_cluster_coord_set(cur, EINA_POSITION2D(cx, cy));
if (_cx) *_cx = cx;
if (_cy) *_cy = cy;
}
@ -1676,7 +1676,7 @@ _mouse_down_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EIN
goto end;
}
}
_cursor_char_coord_set(obj, cur, ev->canvas.x, ev->canvas.y, &cx, &cy);
_cursor_cluster_coord_set(obj, cur, ev->canvas.x, ev->canvas.y, &cx, &cy);
if (dosel)
{
@ -1721,7 +1721,7 @@ _mouse_up_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void
}
#endif
_cursor_char_coord_set(obj, cur, ev->canvas.x, ev->canvas.y, &cx, &cy);
_cursor_cluster_coord_set(obj, cur, ev->canvas.x, ev->canvas.y, &cx, &cy);
if (en->select_allow)
{

View File

@ -483,6 +483,47 @@ EFL_START_TEST(text_multiline_singleline_cursor_pos)
}
EFL_END_TEST
EFL_START_TEST(text_keyboard_mouse_cluster_cursor_movement)
{
Eo *txt;
Eo *cursor;
Eo *win = win_add();
Evas *e;
Eina_Rect rc, rc2;
txt = efl_add(EFL_UI_TEXTBOX_CLASS, win);
efl_gfx_entity_size_set(win, EINA_SIZE2D(300, 300));
efl_gfx_entity_size_set(txt, EINA_SIZE2D(300, 300));
efl_ui_textbox_scrollable_set(txt, EINA_TRUE);
get_me_to_those_events(txt);
efl_text_markup_set(txt, "A\u1100\u1161\u11AA");
cursor = efl_text_interactive_main_cursor_get(txt);
efl_text_cursor_object_position_set(cursor, 1);
e = evas_object_evas_get(txt);
efl_ui_focus_util_focus(txt);
evas_event_feed_key_down(e, "Right", "Right", "Right", "Right", time(NULL), NULL);
ck_assert_int_eq(4, efl_text_cursor_object_position_get(cursor));
efl_text_cursor_object_position_set(cursor, 1);
efl_text_cursor_object_move(cursor, EFL_TEXT_CURSOR_MOVE_TYPE_CHARACTER_NEXT);
efl_text_cursor_object_move(cursor, EFL_TEXT_CURSOR_MOVE_TYPE_CHARACTER_NEXT);
rc = efl_text_cursor_object_content_geometry_get(cursor);
rc2 = efl_ui_scrollable_viewport_geometry_get(txt);
efl_text_cursor_object_position_set(cursor, 0);
click_object_at(win, rc2.x + rc.x + (rc.w/2), rc2.y + rc.y + (rc.h/2));
ck_assert_int_eq(4, efl_text_cursor_object_position_get(cursor));
efl_del(txt);
efl_del(win);
}
EFL_END_TEST
void efl_ui_test_text(TCase *tc)
{
tcase_add_test(tc, text_cnp);
@ -497,4 +538,5 @@ void efl_ui_test_text(TCase *tc)
tcase_add_test(tc, text_singleline_cursor_movement);
tcase_add_test(tc, text_multiline_singleline_cursor_pos);
tcase_add_test(tc, text_on_startup);
tcase_add_test(tc, text_keyboard_mouse_cluster_cursor_movement);
}