From: InHong Han Date: Thu, 29 Jun 2017 05:48:36 +0000 (+0900) Subject: Support floating keyboard X-Git-Tag: submit/tizen/20170729.030654~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0e872c8b3ec3bb887bf4fe088f179c948b672cb7;p=platform%2Fcore%2Fuifw%2Fe-mod-tizen-wl-textinput.git Support floating keyboard Change-Id: I32409b63f3e101a54d158e2c19341471cbedccaf --- diff --git a/src/e_mod_input_panel.c b/src/e_mod_input_panel.c index 9727dcf..3e8a65d 100644 --- a/src/e_mod_input_panel.c +++ b/src/e_mod_input_panel.c @@ -7,6 +7,13 @@ typedef struct _E_Input_Panel E_Input_Panel; typedef struct _E_Input_Panel_Surface E_Input_Panel_Surface; +typedef struct _E_Input_Panel_Floating_Info E_Input_Panel_Floating_Info; + +typedef enum +{ + E_INPUT_PANEL_COORDINATE_TYPE_ABSOLUTE, + E_INPUT_PANEL_COORDINATE_TYPE_LOGICAL, +} E_Input_Panel_Coordinate_Type; struct _E_Input_Panel { @@ -38,15 +45,25 @@ struct _E_Input_Panel_Surface Eina_Bool need_show; }; -typedef struct _E_Floating_Position { - int portrait_x; - int portrait_y; - int landscape_x; - int landscape_y; -} E_Floating_Position; +struct _E_Input_Panel_Floating_Info +{ + Eina_Bool moving_req; + Eina_Bool init_portrait_position; + Eina_Bool init_landscape_position; + int before_canvas_x; + int before_canvas_y; + + struct + { + int portrait_x; + int portrait_y; + int landscape_x; + int landscape_y; + } start_position; +}; E_Input_Panel *g_input_panel = NULL; -E_Floating_Position g_floating_position = {-1, -1, -1, -1}; +E_Input_Panel_Floating_Info *g_floating_info = NULL; Eina_List *handlers = NULL; static Eina_Bool panel_show_need_rerun = EINA_FALSE; @@ -180,15 +197,40 @@ static void return; } - if (ips->ec) - ips->ec->vkbd.floating = !!state; + if (!ips->ec) return; + + if (ips->ec->vkbd.floating == state) return; + + ips->ec->vkbd.floating = !!state; + + if (ips->ec->vkbd.floating) + e_policy_conformant_part_del(ips->ec); + else + e_policy_conformant_part_add(ips->ec); +} + +static void +_e_input_panel_surface_cb_floating_drag_enabled_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t enabled) +{ + E_Input_Panel_Surface *ips = wl_resource_get_user_data(resource); + + if (!ips) + { + WTI_WARNING(resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "No Input Panel Surface For Surface"); + return; + } + + g_floating_info->moving_req = !!enabled; } static const struct wl_input_panel_surface_interface _e_input_panel_surface_implementation = { _e_input_panel_surface_cb_toplevel_set, _e_input_panel_surface_cb_overlay_panel_set, _e_input_panel_surface_cb_ready_set, - _e_input_panel_surface_cb_floating_panel_set + _e_input_panel_surface_cb_floating_panel_set, + _e_input_panel_surface_cb_floating_drag_enabled_set }; static void @@ -237,13 +279,149 @@ _e_input_panel_surface_resource_destroy(struct wl_resource *resource) free(ips); } +static void +_e_input_panel_init_floating_position(E_Client *ec) +{ + int zx, zy, zw, zh; + + if (!ec || !g_floating_info) return; + + e_zone_useful_geometry_get(ec->zone, &zx, &zy, &zw, &zh); + + switch (ec->e.state.rot.ang.curr) + { + case 90: + case 270: + g_floating_info->start_position.landscape_x = (zh - ec->client.h) / 2; + g_floating_info->start_position.landscape_y = (zw - ec->client.w) / 2; + g_floating_info->init_landscape_position = EINA_TRUE; + break; + case 0: + case 180: + default: + g_floating_info->start_position.portrait_x = (zw - ec->client.w) / 2; + g_floating_info->start_position.portrait_y = (zh - ec->client.h) / 2; + g_floating_info->init_portrait_position = EINA_TRUE; + break; + } +} + +static void +_e_input_panel_stay_within_screen(E_Client *ec, int x, int y, int *new_x, int *new_y) +{ + int zx, zy, zw, zh; + + if (!ec || !g_floating_info) return; + + e_zone_useful_geometry_get(ec->zone, &zx, &zy, &zw, &zh); + + switch (ec->e.state.rot.ang.curr) + { + case 90: + case 270: + if (x < 0) + *new_x = 0; + else if (x > zh - ec->client.h) + *new_x = zh - ec->client.h; + else + *new_x = x; + + if (y < 0) + *new_y = 0; + else if (y > zw - ec->client.w) + *new_y = zw - ec->client.w; + else + *new_y = y; + break; + case 0: + case 180: + default: + if (x < 0) + *new_x = 0; + else if (x > zw - ec->client.w) + *new_x = zw - ec->client.w; + else + *new_x = x; + + if (y < 0) + *new_y = 0; + else if (y > zh - ec->client.h) + *new_y = zh - ec->client.h; + else + *new_y = y; + break; + } +} + +static void +_e_input_panel_convert_floating_position(E_Client *ec, int x, int y, int *new_x, int *new_y, E_Input_Panel_Coordinate_Type cur_type) +{ + int zx, zy, zw, zh; + int cur_angle; + + if (!ec || !g_floating_info) return; + + cur_angle = ec->e.state.rot.ang.curr; + if ((!g_floating_info->init_portrait_position && (cur_angle == 0 || cur_angle == 180)) || + (!g_floating_info->init_landscape_position && (cur_angle == 90 || cur_angle == 270))) + _e_input_panel_init_floating_position(ec); + + e_zone_useful_geometry_get(ec->zone, &zx, &zy, &zw, &zh); + + switch (cur_angle) + { + case 90: + if (cur_type == E_INPUT_PANEL_COORDINATE_TYPE_ABSOLUTE) + { + *new_x = zh - y - ec->client.h; + *new_y = x; + } + else if (cur_type == E_INPUT_PANEL_COORDINATE_TYPE_LOGICAL) + { + *new_x = y; + *new_y = zh - x - ec->client.h; + } + break; + case 180: + if (cur_type == E_INPUT_PANEL_COORDINATE_TYPE_ABSOLUTE) + { + *new_x = zh - y - ec->client.h; + *new_y = zw - x - ec->client.w; + } + else if (cur_type == E_INPUT_PANEL_COORDINATE_TYPE_LOGICAL) + { + *new_x = zw - x - ec->client.w; + *new_y = zh - y - ec->client.h; + } + break; + case 270: + if (cur_type == E_INPUT_PANEL_COORDINATE_TYPE_ABSOLUTE) + { + *new_x = y; + *new_y = zw - x - ec->client.w; + } + else if (cur_type == E_INPUT_PANEL_COORDINATE_TYPE_LOGICAL) + { + *new_x = zw - y - ec->client.w; + *new_y = x; + } + break; + case 0: + default: + *new_x = x; + *new_y = y; + break; + } +} + static void _e_input_panel_position_set(E_Client *ec, int w, int h) { int nx, ny; int zx, zy, zw, zh; + Eina_Bool is_portrait; - if (!ec) return; + if (!ec || !g_floating_info) return; e_zone_useful_geometry_get(ec->zone, &zx, &zy, &zw, &zh); @@ -253,24 +431,41 @@ _e_input_panel_position_set(E_Client *ec, int w, int h) case 90: nx = zx + zw - w; ny = zy + (zh - h) / 2; + is_portrait = EINA_FALSE; break; case 180: nx = zx + (zw - w) / 2; ny = zy; + is_portrait = EINA_TRUE; break; case 270: nx = zx; ny = zy + (zh - h) / 2; + is_portrait = EINA_FALSE; break; case 0: default: nx = zx + (zw - w) / 2; ny = zy + zh - h; + is_portrait = EINA_TRUE; break; } - if (!ec->vkbd.floating) - e_client_util_move_without_frame(ec, nx, ny); + if (ec->vkbd.floating) + { + int sx, sy; + if ((is_portrait && !g_floating_info->init_portrait_position) || (!is_portrait && !g_floating_info->init_landscape_position)) + _e_input_panel_init_floating_position(ec); + + if (is_portrait) + _e_input_panel_stay_within_screen(ec, g_floating_info->start_position.portrait_x, g_floating_info->start_position.portrait_y, &sx, &sy); + else + _e_input_panel_stay_within_screen(ec, g_floating_info->start_position.landscape_x, g_floating_info->start_position.landscape_y, &sx, &sy); + + _e_input_panel_convert_floating_position(ec, sx, sy, &nx, &ny, E_INPUT_PANEL_COORDINATE_TYPE_LOGICAL); + } + + e_client_util_move_without_frame(ec, nx, ny); } static void @@ -463,6 +658,74 @@ _e_ips_cb_evas_resize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *e _e_input_panel_position_set(ec, w, h); } +static void +_e_ips_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + E_Client *ec; + + ec = data; + if (e_object_is_del(E_OBJECT(ec)) || !ec->vkbd.floating || !g_floating_info) + return; + + g_floating_info->moving_req = EINA_FALSE; +} + +static void +_e_ips_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + E_Client *ec; + Evas_Event_Mouse_Move *ev = event_info; + + ec = data; + if (e_object_is_del(E_OBJECT(ec)) || !ec->vkbd.floating || !g_floating_info) + return; + + g_floating_info->before_canvas_x = ev->cur.canvas.x; + g_floating_info->before_canvas_y = ev->cur.canvas.y; +} + +static void +_e_ips_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info) +{ + E_Client *ec; + Evas_Event_Mouse_Move *ev = event_info; + Evas_Coord x, y, w, h; + int b_x = 0, b_y = 0, n_x = 0, n_y = 0; + int d_x, d_y; + + ec = data; + if (e_object_is_del(E_OBJECT(ec)) || !ec->vkbd.floating || !g_floating_info) + return; + + if (!g_floating_info->moving_req) + return; + + evas_object_geometry_get(obj, &x, &y, &w, &h); + + d_x = x + (ev->cur.canvas.x - g_floating_info->before_canvas_x); + d_y = y + (ev->cur.canvas.y - g_floating_info->before_canvas_y); + + _e_input_panel_convert_floating_position(ec, d_x, d_y, &b_x, &b_y, E_INPUT_PANEL_COORDINATE_TYPE_ABSOLUTE); + _e_input_panel_stay_within_screen(ec, b_x, b_y, &n_x, &n_y); + + g_floating_info->before_canvas_x = ev->cur.canvas.x; + g_floating_info->before_canvas_y = ev->cur.canvas.y; + + if (ec->e.state.rot.ang.curr == 90 || ec->e.state.rot.ang.curr == 270) + { + g_floating_info->start_position.landscape_x = n_x; + g_floating_info->start_position.landscape_y = n_y; + } + else + { + g_floating_info->start_position.portrait_x = n_x; + g_floating_info->start_position.portrait_y = n_y; + } + + _e_input_panel_convert_floating_position(ec, n_x, n_y, &d_x, &d_y, E_INPUT_PANEL_COORDINATE_TYPE_LOGICAL); + evas_object_move(obj, d_x, d_y); +} + static void _e_input_panel_cb_surface_get(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *surface_resource) { @@ -538,6 +801,9 @@ _e_input_panel_cb_surface_get(struct wl_client *client, struct wl_resource *reso evas_object_raise(ec->frame); evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_RESIZE, _e_ips_cb_evas_resize, ec); + evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_MOUSE_UP, _e_ips_cb_mouse_up, ec); + evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_MOUSE_DOWN, _e_ips_cb_mouse_down, ec); + evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_MOUSE_MOVE, _e_ips_cb_mouse_move, ec); cdata->surface = surface_resource; cdata->shell.configure_send = NULL; @@ -774,6 +1040,7 @@ e_input_panel_init(void) } g_input_panel->idle_enter = ecore_idle_enterer_add(_e_input_panel_idle_enter, NULL); + g_floating_info = E_NEW(E_Input_Panel_Floating_Info, 1); return EINA_TRUE; } @@ -797,6 +1064,9 @@ e_input_panel_shutdown(void) E_FREE_FUNC(g_input_panel->idle_enter, ecore_idle_enterer_del); } + + if (g_floating_info) + E_FREE(g_floating_info); } static void @@ -943,21 +1213,22 @@ e_input_panel_show_need_rerun_set(Eina_Bool need_rerun) void e_input_panel_floating_position_set(E_Client *ec, int x, int y) { - if (!ec) return; + if (!ec || !g_floating_info) return; switch (ec->e.state.rot.ang.curr) { - case 0: - case 180: - g_floating_position.portrait_x = x; - g_floating_position.portrait_y = y; - break; case 90: case 270: - g_floating_position.landscape_x = x; - g_floating_position.landscape_y = y; + g_floating_info->start_position.landscape_x = x; + g_floating_info->start_position.landscape_y = y; + g_floating_info->init_landscape_position = EINA_TRUE; break; + case 0: + case 180: default: + g_floating_info->start_position.portrait_x = x; + g_floating_info->start_position.portrait_y = y; + g_floating_info->init_portrait_position = EINA_TRUE; break; } -} \ No newline at end of file +}