언어 설정

Menu
Sites
Language
How to absorb the touch event for zoomming gesture?

I'm implmenting the functionality of Zoom In and Zoom out on GLView.

And my app also response to the mouse move event. So currently my app response both zooming and moving event, that leads to unexpected behavior.

I hope the  call backs for zooming can absorb the event. That is, if the system detected zooming gesture and send event for zooming to my app, it should not send mouse move event to my app anymore.

Below are codes for app_create() where the zooming and moving callbacks registered.

static bool app_create(void *data) {
    /* Hook to take necessary actions before main event loop starts
  * Initialize UI resources and application's data
  * If this function returns true, the main loop of application starts
  * If this function returns false, the application is terminated. */

 Evas_Object *gl;
 Ecore_Animator *ani;
 appdata_s *ad = data;

 if (!data)
  return false;

 /* Create the window */
 ad->win = add_win(ad->name);

 if (!ad->win)
  return false;

 create_indicator(ad);
 evas_object_smart_callback_add(ad->win, "delete,request", win_delete_request_cb, NULL);
 eext_object_event_callback_add(ad->win, EEXT_CALLBACK_BACK, win_back_cb, ad);

 /* Create and initialize GLView */
 gl = elm_glview_add(ad->conform);
 ELEMENTARY_GLVIEW_GLOBAL_USE(gl);
 evas_object_size_hint_align_set(gl, EVAS_HINT_FILL, EVAS_HINT_FILL);
 evas_object_size_hint_weight_set(gl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);

 /* Request a surface with alpha and a depth buffer */
 elm_glview_mode_set(gl, ELM_GLVIEW_DEPTH);

 /* The resize policy tells GLView what to do with the surface when it
  * resizes. ELM_GLVIEW_RESIZE_POLICY_RECREATE will tell it to
  * destroy the current surface and recreate it to the new size.
  */
 elm_glview_resize_policy_set(gl, ELM_GLVIEW_RESIZE_POLICY_RECREATE);

 /* The render policy sets how GLView should render GL code.
  * ELM_GLVIEW_RENDER_POLICY_ON_DEMAND will have the GL callback
  * called only when the object is visible.
  * ELM_GLVIEW_RENDER_POLICY_ALWAYS would cause the callback to be
  * called even if the object were hidden.
  */
 elm_glview_render_policy_set(gl, ELM_GLVIEW_RENDER_POLICY_ON_DEMAND);

 /* The initialize callback function gets registered here */
 elm_glview_init_func_set(gl, init_gl);

 /* The delete callback function gets registered here */
 elm_glview_del_func_set(gl, del_gl);

 /* The render callback function gets registered here */
 elm_glview_render_func_set(gl, draw_gl);

 Evas_Object *ges = elm_gesture_layer_add(gl);
 elm_gesture_layer_attach(ges, gl);

 elm_gesture_layer_cb_set(ges, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_START,
   zoom_start_cb, ad);
 elm_gesture_layer_cb_set(ges, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_MOVE,
   zoom_move_cb, ad);
 elm_gesture_layer_cb_set(ges, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_END,
   zoom_end_cb, ad);
 elm_gesture_layer_cb_set(ges, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_ABORT,
   zoom_abort_cb, ad);
 elm_box_pack_end(gl, ad->rect);
 evas_object_show(ad->rect);

 /* Add the GLView to the conformant and show it */
 elm_object_content_set(ad->conform, gl);
 evas_object_show(gl);

 elm_object_focus_set(gl, EINA_TRUE);


 /* This adds an animator so that the app will regularly
  * trigger updates of the GLView using elm_glview_changed_set().
  *
  * NOTE: If you delete GL, this animator will keep running trying to access
  * GL so this animator needs to be deleted with ecore_animator_del().
  */
 ani = ecore_animator_add(anim, gl);
 evas_object_data_set(gl, "ani", ani);
 evas_object_data_set(gl, "ad", ad);
 evas_object_event_callback_add(gl, EVAS_CALLBACK_DEL, del_anim, gl);

 evas_object_event_callback_add(gl, EVAS_CALLBACK_MOUSE_DOWN, mouse_down_cb, ad);
 evas_object_event_callback_add(gl, EVAS_CALLBACK_MOUSE_UP, mouse_up_cb, ad);
 evas_object_event_callback_add(gl, EVAS_CALLBACK_MOUSE_MOVE, mouse_move_cb, ad);

 evas_object_show(ad->win);

 /* Return true: the main loop will now start running */
 return true;
}

Below is the picture to show that my app get zooming and moving event alternately.

Edited by: Jean Yang on 13 9월, 2015

Responses

15 댓글
Alex Dem

Hi,
In my opinion you could try to:
1) searate logic and unregister all other callbacks inside 'zoom_start_cb' for ELM_GESTURE_ZOOM and register again on ELM_GESTURE_STATE_END/ELM_GESTURE_STATE_ABORT
2) you could use some internal variable wich mean that gesture (ELM_GESTURE_ZOOM ) is in progress and other operations are not allowed.
Alexey.

Jean Yang

Hi Alex,

   Surely, both methods you mentioned can work, the 1) method unregistered the mouse event when it recieved the zoom gesture and register them again when zoom gesture end or abort. the 2) method use variable to mark the gesture handling in progress.

   But both of these two methods seems intricacy. Let's imaging if we have many gestures registered at the same time.

   Is there any method to ignore some event at certain level?

   I tried evas_object_pass_events_set() to ignore gl event  in zoom_start_cb.

static Evas_Event_Flags zoom_start_cb(void *data , void *event_info)
{
    Elm_Gesture_Zoom_Info *p = (Elm_Gesture_Zoom_Info *)event_info;
    dlog_print(DLOG_ERROR, "sample:zoom_start_cb", "Zoom info (x,y,radius,zoom,momentum) = (%d, %d, %d, %lf, %lf)", p->x, p->y, p->radius, p->zoom, p->momentum);

    appdata_s *ad = data;
    evas_object_pass_events_set(ad->gl, EINA_TRUE);

    return EVAS_EVENT_FLAG_NONE;
}

    And evas_object_pass_events_set() to normally process gl event  in zoom_end_cb and zoom_abort_cb.

static Evas_Event_Flags zoom_end_cb(void *data , void *event_info)
{
    Elm_Gesture_Zoom_Info *p = (Elm_Gesture_Zoom_Info *)event_info;
    dlog_print(DLOG_ERROR, "sample:zoom_end_cb", "Zoom info (x,y,radius,zoom,momentum) = (%d, %d, %d, %lf, %lf)", p->x, p->y, p->radius, p->zoom, p->momentum);

    appdata_s *ad = data;
    evas_object_pass_events_set(ad->gl, EINA_FALSE);

    return EVAS_EVENT_FLAG_NONE;
}

static Evas_Event_Flags zoom_abort_cb(void *data , void *event_info)
{
    Elm_Gesture_Zoom_Info *p = (Elm_Gesture_Zoom_Info *)event_info;
    dlog_print(DLOG_ERROR, "sample:zoom_abort_cb", "Zoom info (x,y,radius,zoom,momentum) = (%d, %d, %d, %lf, %lf)", p->x, p->y, p->radius, p->zoom, p->momentum);

    appdata_s *ad = data;
    evas_object_pass_events_set(ad->gl, EINA_FALSE);

    return EVAS_EVENT_FLAG_NONE;
}

   But the result is zoom move event also cannot be recieved.

  

  It seems as the gesture layer is attached to glview, if glview ignored its events, the gesture layer will not recieved the events also. The event chain breaks at the glview and will not passed to the attached gesture layer.

Alex Dem

Hi,
From my previous experience better to control gestures by himself.
But maybe someone could provide some useful api
Alexey.

Merrillin

Great code. Nice

Shakespeare

Anyway, I can not clear all these codes. Can you explain it for me?

Craig Rush

 You can prevent the zoom behavior from handling the related gesture (such as a touch gesture) using a custom zoom.filter to ignore touchstart.