From: JengHyun Kang Date: Fri, 18 Aug 2017 00:29:07 +0000 (+0900) Subject: [ACR-1004][efl-util] Add new api guide for global gesture X-Git-Tag: GitHub/PR#40/tizen-studio~57^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F63%2F144763%2F8;p=sdk%2Fonline-doc.git [ACR-1004][efl-util] Add new api guide for global gesture PS2: Reviewed PS5: New image and related text reviewed PS7: Fixed typo in an image and reviewed the query answers Change-Id: I1a1be1c9a55bd3c534f8c4abf48fa4f8523913fa --- diff --git a/org.tizen.guides/html/images/efl_global_gesture_edge_drag.png b/org.tizen.guides/html/images/efl_global_gesture_edge_drag.png new file mode 100644 index 0000000..36989d8 Binary files /dev/null and b/org.tizen.guides/html/images/efl_global_gesture_edge_drag.png differ diff --git a/org.tizen.guides/html/images/efl_global_gesture_edge_swipe.png b/org.tizen.guides/html/images/efl_global_gesture_edge_swipe.png new file mode 100644 index 0000000..67e8fc6 Binary files /dev/null and b/org.tizen.guides/html/images/efl_global_gesture_edge_swipe.png differ diff --git a/org.tizen.guides/html/images/efl_global_gesture_event_propagate.png b/org.tizen.guides/html/images/efl_global_gesture_event_propagate.png new file mode 100644 index 0000000..0b31dfb Binary files /dev/null and b/org.tizen.guides/html/images/efl_global_gesture_event_propagate.png differ diff --git a/org.tizen.guides/html/images/efl_global_gesture_life_cycle.png b/org.tizen.guides/html/images/efl_global_gesture_life_cycle.png new file mode 100644 index 0000000..07bad1a Binary files /dev/null and b/org.tizen.guides/html/images/efl_global_gesture_life_cycle.png differ diff --git a/org.tizen.guides/html/images/efl_global_gesture_palm_cover.png b/org.tizen.guides/html/images/efl_global_gesture_palm_cover.png new file mode 100644 index 0000000..601f19e Binary files /dev/null and b/org.tizen.guides/html/images/efl_global_gesture_palm_cover.png differ diff --git a/org.tizen.guides/html/images/efl_global_gesture_palm_swipe.png b/org.tizen.guides/html/images/efl_global_gesture_palm_swipe.png new file mode 100644 index 0000000..df4d570 Binary files /dev/null and b/org.tizen.guides/html/images/efl_global_gesture_palm_swipe.png differ diff --git a/org.tizen.guides/html/images/efl_global_gesture_pan.png b/org.tizen.guides/html/images/efl_global_gesture_pan.png new file mode 100644 index 0000000..0a48c5d Binary files /dev/null and b/org.tizen.guides/html/images/efl_global_gesture_pan.png differ diff --git a/org.tizen.guides/html/images/efl_global_gesture_pinch.png b/org.tizen.guides/html/images/efl_global_gesture_pinch.png new file mode 100644 index 0000000..c80e6b6 Binary files /dev/null and b/org.tizen.guides/html/images/efl_global_gesture_pinch.png differ diff --git a/org.tizen.guides/html/images/efl_global_gesture_tap.png b/org.tizen.guides/html/images/efl_global_gesture_tap.png new file mode 100644 index 0000000..0de91fc Binary files /dev/null and b/org.tizen.guides/html/images/efl_global_gesture_tap.png differ diff --git a/org.tizen.guides/html/native/ui/efl/efl_util_n.htm b/org.tizen.guides/html/native/ui/efl/efl_util_n.htm index bb62a2d..65f4607 100644 --- a/org.tizen.guides/html/native/ui/efl/efl_util_n.htm +++ b/org.tizen.guides/html/native/ui/efl/efl_util_n.htm @@ -28,11 +28,20 @@

Content

Related Info

+

You can generate input events using the EFL UTIL INPUT API (for mobile and wearable applications). You can generate key input events that emulate various hardware key presses and touch input events that emulate screen touches.

+
  • Handling global gestures +

    You can handle global gestures using the EFL UTIL GESTURE API (for mobile and wearable applications). You can grab and deactivate global gestures, and select and deactivate them in a window.

  • Window Layers and Notification Levels

    @@ -75,6 +86,68 @@

    Figure: Notification levels

    Notification levels

    +

    Global Gestures

    + +

    Normal touch events are delivered to the active, visible window. Global gestures intercept these touch events and generate gesture events instead of propagating the touch events. Gestures can be recognized and delivered in 2 ways:

    + + +

    Figure: Global gesture event propagation methods

    +

    Global gesture event propagation methods

    + +

    After gesture recognition, the server sends no further touch events until all fingers are released. The server renews the gesture recognition state only after all fingers are released.

    + +

    Figure: Global gesture life cycle

    +

    Global gesture life cycle

    + +

    Global gesture events are generated based on user touch behavior. Gestures have various states:

    + +

    Continuous gestures generate events in the begin, update, and end states, while non-continuous gestures generate events in the done state.

    +

    You can implement the following gesture types:

    +

    Prerequisites

    @@ -316,6 +389,504 @@ touch_event_generator() } +

    Grabbing Gestures

    + +

    To receive global gesture events, you must grab the gestures that you want. You can grab gestures in the background (without a window). Each gesture can only be grabbed by 1 client at a time. For example, if a client grabs a 2-finger double tap gesture, other clients cannot grab the same gesture but can grab a 2-finger triple tap gesture. You can grab edge swipe, edge drag, tap, and palm cover gestures.

    +

    To grab gestures:

    + +
      +
    1. Create callbacks for gesture events: +
      +/* EFL_UTIL_EVENT_GESTURE_EDGE_SWIPE */
      +Eina Bool
      +_edge_swipe_cb(void *data, int type, void *event)
      +{
      +    efl_util_event_gesture_edge_swipe_s *ev;
      +
      +    ev = (efl_util_event_gesture_edge_swipe_s *)event;
      +
      +    printf("[Edge_Swipe] mode: %d, fingers: %d, start_point: (%d, %d), edge: %d\n",
      +           ev->mode, ev->fingers, ev->sx, ev->sy, ev->edge);
      +
      +    return ECORE_CALLBACK_PASS_ON;
      +}
      +
      +/* EFL_UTIL_EVENT_GESTURE_EDGE_DRAG */
      +Eina Bool
      +_edge_drag_cb(void *data, int type, void *event)
      +{
      +    efl_util_event_gesture_edge_drag_s *ev;
      +
      +    ev = (efl_util_event_gesture_edge_drag_s *)event;
      +
      +    printf("[Edge_Drag] mode: %d, fingers: %d, center_point: (%d, %d), edge: %d\n",
      +           ev->mode, ev->fingers, ev->cx, ev->cy, ev->edge);
      +
      +    return ECORE_CALLBACK_PASS_ON;
      +}
      +
      +/* EFL_UTIL_EVENT_GESTURE_TAP */
      +Eina Bool
      +_tap_cb(void *data, int type, void *event)
      +{
      +    efl_util_event_gesture_tap_s *ev;
      +
      +    ev = (efl_util_event_gesture_tap_s *)event;
      +
      +    printf("[Tap] mode: %d, fingers: %d, repeats: %d\n",
      +           ev->mode, ev->fingers, ev->repeats);
      +
      +    return ECORE_CALLBACK_PASS_ON;
      +}
      +
      +/* EFL_UTIL_EVENT_GESTURE_PALM_COVER */
      +Eina Bool
      +_palm_cover_cb(void *data, int type, void *event)
      +{
      +    efl_util_event_gesture_palm_cover_s *ev;
      +
      +    ev = (efl_util_event_gesture_palm_cover_s *)event;
      +
      +    printf("[Palm_Cover] mode: %d, duration: %d, center_point: (%d, %d), size: %d, pressure: %lf\n",
      +           ev->mode, ev->duration, ev->cx, ev->cy, ev->size, ev->pressure);
      +
      +    return ECORE_CALLBACK_PASS_ON;
      +}
      +
    2. +
    3. Create the efl_util_gesture_h structure and initialize the structure members with the efl_util_gesture_initialize() function: +
      +void
      +grab_gesture()
      +{
      +    int ret = EFL_UTIL_ERROR_NONE;
      +    efl_util_gesture_h h_gesture = NULL;
      +    efl_util_gesture_data d_edge_swipe = NULL;
      +    efl_util_gesture_data d_edge_drag = NULL;
      +    efl_util_gesture_data d_tap = NULL;
      +    efl_util_gesture_data d_palm_cover = NULL;
      +
      +    /* Create a gesture handle */
      +    h_gesture = efl_util_gesture_initialize();
      +
      +    if (!h_gesture) {
      +        ret = get_last_result();
      +        /* Failed to initialize the gesture system */
      +
      +        return;
      +    }
      +
    4. +
    5. Define the gesture data to grab using the efl_util_gesture_xxx_new() and efl_util_gesture_xxx_size_set() functions. +

      Setting a size is optional. If a size is not set, the gesture is grabbed within a full-size edge.

      +
      +    /* Define a top edge 1-finger swipe gesture */
      +    d_edge_swipe = efl_util_gesture_edge_swipe_new(h_gesture, 1, EFL_UTIL_GESTURE_EDGE_TOP);
      +    if (!d_edge_swipe) {
      +        ret = get_last_result();
      +        /* Failed to create edge swipe data */
      +
      +        return;
      +    }
      +    /* Set the size */
      +    ret = efl_util_gesture_edge_swipe_size_set(d_edge_swipe, EFL_UTIL_GESTURE_EDGE_SIZE_PARTIAL, 0, 100);
      +    if (ret != EFL_UTIL_ERROR_NONE) {
      +        /* Failed to set size for edge swipe */
      +
      +        return;
      +    }
      +
      +    /* Define a left edge 1-finger drag gesture */
      +    d_edge_drag = efl_util_gesture_edge_drag_new(h_gesture, 1, EFL_UTIL_GESTURE_EDGE_LEFT);
      +    if (!d_edge_drag) {
      +        ret = get_last_result();
      +        /* Failed to create edge drag data */
      +
      +        return;
      +    }
      +    /* Set the size */
      +    ret = efl_util_gesture_edge_drag_size_set(d_edge_drag, EFL_UTIL_GESTURE_EDGE_SIZE_PARTIAL, 0, 100);
      +    if (ret != EFL_UTIL_ERROR_NONE) {
      +        /* Failed to set size for edge drag */
      +
      +        return;
      +    }
      +
      +    /* Define a 2-finger double tap gesture */
      +    d_tap = efl_util_gesture_tap_new(h_gesture, 2, 2);
      +    if (!d_tap) {
      +        ret = get_last_result();
      +        /* Failed to create tap data */
      +
      +        return;
      +    }
      +
      +    /* Define a palm cover gesture */
      +    d_palm_cover = efl_util_gesture_palm_cover_new(h_gesture);
      +    if (!d_palm_cover) {
      +        ret = get_last_result();
      +        /* Failed to create palm cover data */
      +
      +        return;
      +    }
      +
    6. +
    7. To grab a gesture, use the efl_util_gesture_grab() function: +
      +    /* Select the gesture you want to grab */
      +    ret = efl_util_gesture_grab(h_gesture, d_edge_swipe);
      +    /*
      +        You can grab multiple gestures:
      +        ret = efl_util_gesture_grab(h_gesture, d_edge_drag);
      +        ret = efl_util_gesture_grab(h_gesture, d_tap);
      +        ret = efl_util_gesture_grab(h_gesture, d_palm_cover);
      +    */
      +    if (ret != EFL_UTIL_ERROR_NONE) {
      +        /* Failed to grab a gesture */
      +
      +        return;
      +    }
      +
    8. +
    9. Define the gesture event handlers: +
      +    /* Add handlers for the gestures that you want to receive */
      +    ecore_event_handler_add(EFL_UTIL_EVENT_GESTURE_EDGE_SWIPE, _edge_swipe_cb, NULL);
      +    /*
      +       You can handle multiple gestures:
      +       ecore_event_handler_add(EFL_UTIL_EVENT_GESTURE_EDGE_DRAG, _edge_drag_cb, NULL);
      +       ecore_event_handler_add(EFL_UTIL_EVENT_GESTURE_TAP, _tap_cb, NULL);
      +       ecore_event_handler_add(EFL_UTIL_EVENT_GESTURE_PALM_COVER, _palm_cover_cb, NULL);
      +    */
      +
    10. +
    11. Run the main loop: +
      +    /* Run Ecore main loop */
      +    ecore_main_loop_begin();
      +
      +
    12. +
    13. When no longer needed, free the resources and deinitialize the efl_util_gesture_h structure: + +
      +    /* Ungrab the gesture */
      +    ret = efl_util_gesture_ungrab(h_gesture, d_edge_swipe);
      +    /*
      +       Ungrab other gestures if necessary:
      +       ret = efl_util_gesture_ungrab(h_gesture, d_edge_drag);
      +       ret = efl_util_gesture_ungrab(h_gesture, d_tap);
      +       ret = efl_util_gesture_ungrab(h_gesture, d_palm_cover);
      +     */
      +
      +    if (ret != EFL_UTIL_ERROR_NONE) {
      +        /* Failed to ungrab the gesture */
      +
      +        return;
      +    }
      +
      +    /* Free the gesture data */
      +    ret = efl_util_gesture_edge_swipe_free(h_gesture, d_edge_swipe);
      +    /*
      +       Free the data for all gestures:
      +       ret = efl_util_gesture_edge_drag_free(h_gesture, d_edge_drag);
      +       ret = efl_util_gesture_tap_free(h_gesture, d_tap);
      +       ret = efl_util_gesture_palm_cover_free(h_gesture, d_palm_cover);
      +     */
      +    if (ret != EFL_UTIL_ERROR_NONE) {
      +        /* Failed to free gesture data */
      +
      +        return;
      +    }
      +
      +    ret = efl_util_gesture_deinitialize(h_gesture);
      +    if (ret != EFL_UTIL_ERROR_NONE) {
      +        /* Failed to deinitialize the gesture system */
      +
      +        return;
      +    }
      +}
      +
    14. +
    + +

    Selecting Gestures

    + +

    Unlike grabbing, selecting a gesture requires a window. By selecting a gesture, you can detect gesture events when the selected window is active. Selecting has a higher priority than grabbing. Only the palm cover gesture can be selected.

    +

    To select a gesture:

    + +
      +
    1. Create the required callbacks: +
        +
      1. Create a callback for the gesture event: +
        +/* EFL_UTIL_EVENT_GESTURE_PALM_COVER */
        +Eina Bool
        +_palm_cover_cb(void *data, int type, void *event)
        +{
        +    efl_util_event_gesture_palm_cover_s *ev;
        +
        +    ev = (efl_util_event_gesture_palm_cover_s *)event;
        +
        +    printf("[Palm_Cover] mode: %d, duration: %d, center_point: (%d, %d), size: %d, pressure: %lf\n",
        +           ev->mode, ev->duration, ev->cx, ev->cy, ev->size, ev->pressure);
        +
        +    return ECORE_CALLBACK_PASS_ON;
        +}
      2. +
      3. Create the window destruction callback: +
        +/* Window destruction callback */
        +void
        +_window_delete_cb(void *data, Evas_Object *obj, void *event)
        +{
        +    elm_exit();
        +}
        +
      4. +
    2. +
    3. Create the efl_util_gesture_h structure and initialize the structure members with the efl_util_gesture_initialize() function: +
      +void
      +select_gesture()
      +{
      +    int ret = EFL_UTIL_ERROR_NONE;
      +    Evas_Object *window = NULL;
      +    efl_util_gesture_h h_gesture = NULL;
      +    efl_util_gesture_data d_palm_cover = NULL;
      +
      +    /* Create a gesture handle */
      +    h_gesture = efl_util_gesture_initialize();
      +
      +    if (!h_gesture) {
      +        ret = get_last_result();
      +        /* Failed to initialize the gesture system */
      +
      +        return;
      +    }
      +
    4. +
    5. Define the gesture data to select: +
      +    /* Define the palm cover gesture */
      +    d_palm_cover = efl_util_gesture_palm_cover_new(h_gesture);
      +    if (!d_palm_cover) {
      +        ret = get_last_result();
      +        /* Failed to create palm cover gesture data */
      +
      +        return;
      +    }
      +
    6. +
    7. Create and show a window in which you want to select a gesture. +

      This example uses the efl_win_add() function, but you can create the window in many ways.

      +
      +    window = elm_win_add(NULL, "Gesture Select Window", ELM_WIN_BASIC);
      +    if (window) {
      +        elm_win_title_set(window, "Gesture Select Window");
      +        elm_win_borderless_set(window, EINA_TRUE);
      +        evas_object_smart_callback_add(window, "delete,request", _window_delete_cb, NULL);
      +        elm_win_indicator_mode_set(window, ELM_WIN_INDICATOR_SHOW);
      +    }
      +
    8. +
    9. To select the gesture, use the efl_util_gesture_select() function: +
      +    ret = efl_util_gesture_select(h_gesture, window, d_palm_cover);
      +    if (ret != EFL_UTIL_ERROR_NONE) {
      +        /* Failed to select the gesture */
      +
      +        return;
      +    }
      +
    10. +
    11. Define the gesture event handler: +
      +    /* Add a palm cover event handler */
      +    ecore_event_handler_add(EFL_UTIL_EVENT_GESTURE_PALM_COVER, _palm_cover_cb, NULL);
      +
    12. +
    13. Run the main loop: +
      +    /* Run Elm */
      +    elm_run();
      +
    14. +
    15. When no longer needed, free the resources and deinitialize the efl_util_gesture_h structure: +
      +    /* Deselect the palm cover gesture */
      +    ret = efl_util_gesture_deselect(h_gesture, d_palm_cover);
      +    if (ret != EFL_UTIL_ERROR_NONE) {
      +        /* Failed to deselect the palm cover gesture */
      +
      +        return;
      +    }
      +
      +    /* Free the gesture data */
      +    ret = efl_util_gesture_palm_cover_free(h_gesture, d_palm_cover);
      +    if (ret != EFL_UTIL_ERROR_NONE) {
      +        /* Failed to free gesture data */
      +
      +        return;
      +    }
      +
      +    /* Delete the window */
      +    evas_object_del(window);
      +
      +    ret = efl_util_gesture_deinitialize(h_gesture);
      +    if (ret != EFL_UTIL_ERROR_NONE) {
      +        /* Failed to deinitialize the gesture system*/
      +
      +        return;
      +    }
      +}
      +
    16. +
    + +

    Deactivating Gestures

    + +

    Gestures are activated by default.

    +

    To deactivate and re-activate gestures:

    + +
    1. Create the efl_util_gesture_h structure and initialize the structure members with the efl_util_gesture_initialize() function: +
      +void
      +activate_gesture()
      +{
      +    int ret = EFL_UTIL_ERROR_NONE;
      +    efl_util_gesture_h h_gesture = NULL;
      +    efl_util_gesture_data d_palm_cover = NULL;
      +    unsigned int type = 0;
      +    Eina_Bool active = EINA_FALSE;
      +
      +    /* Create a gesture handle */
      +    h_gesture = efl_util_gesture_initialize();
      +
      +    if (!h_gesture) {
      +        ret = get_last_result();
      +        /* Failed to initialize the gesture system */
      +
      +        return;
      +    }
      +
    2. +
    3. To deactivate a gesture type, use the efl_util_gesture_activate_set() function: +
      +    /* Select the gesture types to deactivate */
      +    type = EFL_UTIL_GESTURE_TYPE_EDGE_SWIPE;
      +    /*
      +       You can select multiple gesture types using bitwise operation, for example:
      +       type = EFL_UTIL_GESTURE_TYPE_TAP | EFL_UTIL_GESTURE_TYPE_PAN;
      +    */
      +    /* Deactivate the gesture (active is EINA_FALSE) */
      +    ret = efl_util_gesture_activate_set(h_gesture, type, active);
      +    if (ret != EFL_UTIL_ERROR_NONE) {
      +        /* Failed to set activation status */
      +
      +        return;
      +    }
      +
    4. +
    5. Run the main loop: +
      +    /* Run Elm */
      +    elm_run();
      +
    6. +
    7. When no longer needed, re-activate the gestures and deinitialize the efl_util_gesture_h structure: +
      +    /* Re-activate any deactivated gestures */
      +    active = EINA_TRUE;
      +    ret = efl_util_gesture_activate_set(h_gesture, type, active);
      +    if (ret != EFL_UTIL_ERROR_NONE) {
      +        /* Failed to activate gesture */
      +
      +        return;
      +    }
      +
      +    ret = efl_util_gesture_deinitialize(h_gesture);
      +    if (ret != EFL_UTIL_ERROR_NONE) {
      +        /* Failed to deinitialize the gesture system */
      +
      +        return;
      +    }
      +}
      +
    8. +
    + +

    Deactivating Gestures in a Window

    +

    Gestures are activated by default.

    +

    To deactivate and re-activate gestures in a window:

    + +
      +
    1. Create the window destruction callback: +
      +/* Window destruction callback */
      +void
      +_window_delete_cb(void *data, Evas_Object *obj, void *event)
      +{
      +    elm_exit();
      +}
      +
    2. +
    3. Create the efl_util_gesture_h structure and initialize the structure members with the efl_util_gesture_initialize() function: +
      +void
      +activate_gesture()
      +{
      +    int ret = EFL_UTIL_ERROR_NONE;
      +    efl_util_gesture_h h_gesture = NULL;
      +    efl_util_gesture_data d_palm_cover = NULL;
      +    Evas_Object *window = NULL;
      +    unsigned int type = 0;
      +    Eina_Bool active = EINA_FALSE;
      +
      +    /* Create a gesture handle */
      +    h_gesture = efl_util_gesture_initialize();
      +
      +    if (!h_gesture) {
      +        ret = get_last_result();
      +        /* Failed to initialize the gesture system */
      +
      +        return;
      +    }
      +
    4. +
    5. Create and show a window in which you want to deactivate a gesture. +

      This example uses the efl_win_add() function, but you can create the window in many ways.

      +
      +    window = elm_win_add(NULL, "Gesture Select Window", ELM_WIN_BASIC);
      +    if (window) {
      +        elm_win_title_set(window, "Gesture Select Window");
      +        elm_win_borderless_set(window, EINA_TRUE);
      +        evas_object_smart_callback_add(window, "delete,request", _window_delete_cb, NULL);
      +        elm_win_indicator_mode_set(window, ELM_WIN_INDICATOR_SHOW);
      +    }
      +
    6. +
    7. To deactivate a gesture type, use the efl_util_gesture_activate_set_on_window() function: +
      +    /* Select the gesture types to deactivate */
      +    type = EFL_UTIL_GESTURE_TYPE_EDGE_SWIPE;
      +    /*
      +       You can select multiple gesture types using bitwise operation, for example:
      +       type = EFL_UTIL_GESTURE_TYPE_TAP | EFL_UTIL_GESTURE_TYPE_PAN;
      +    */
      +    /* Deactivate the gesture (active is EINA_FALSE) */
      +    ret = efl_util_gesture_activate_set_on_window(h_gesture, window, type, active);
      +    if (ret != EFL_UTIL_ERROR_NONE) {
      +        /* Failed to set activation status */
      +
      +        return;
      +    }
      +
    8. +
    9. Run the main loop: +
      +    /* Run Elm */
      +    elm_run();
      +
    10. +
    11. When no longer needed, re-activate the gestures, delete the window, and deinitialize the efl_util_gesture_h structure: +
      +    /* Re-activate any deactivated gestures */
      +    active = EINA_TRUE;
      +    ret = efl_util_gesture_activate_set_on_window(h_gesture, window, type, active);
      +    if (ret != EFL_UTIL_ERROR_NONE) {
      +        /* Failed to activate gesture */
      +
      +        return;
      +    }
      +
      +    /* Delete the window */
      +    evas_object_del(window);
      +
      +    ret = efl_util_gesture_deinitialize(h_gesture);
      +    if (ret != EFL_UTIL_ERROR_NONE) {
      +        /* Failed to deinitialize the gesture system*/
      +
      +        return;
      +    }
      +}
      +
    12. +