How can I add touch to a watch face (EFL)

208 Views Asked by At

I am trying to add touch events to my watch face that I am developing with the EFL libraries. But the touch layer is either not working or, when it is, it is fully covering my watch face, although it should be transparent.

My code that creates the watch window is:

Evas_Object *win = NULL;
int ret = EINA_FALSE;

/*
 * Get watch window object
 */
ret = watch_app_get_elm_win(&win);
if (ret != APP_ERROR_NONE) {
    dlog_print(DLOG_ERROR, LOG_TAG, "failed to get watch window. err = %d", ret);
    return NULL;
}
evas_object_resize(win, width, height);

/* <Variant A or B here> */

evas_object_show(win);

Then I try to create a transparent gesture layer and touch callbacks (like described on https://docs.tizen.org/application/native/guides/ui/efl/touch-gesture). I have tried two variants.

Variant A - I use the same window that I created for the watch (win). No errors, but it doesn't work, no touch events:

/* Variant A */
/* Gesture layer transparent object */
Evas_Object *r;
/* Gesture layer object */
Evas_Object *g;

win = elm_win_util_standard_add("gesture_layer", "Gesture Layer");
elm_win_autodel_set(win, EINA_TRUE);

/* Gesture layer transparent object */  
r = evas_object_rectangle_add(evas_object_evas_get(win));
evas_object_move(r, 0, 0);
evas_object_color_set(r, 0, 0, 255, 128);
elm_win_resize_object_add(win, r);

/* Gesture layer object */
g = elm_gesture_layer_add(win);
elm_gesture_layer_attach(g, r);
evas_object_show(r);

/* Set callbacks */
elm_gesture_layer_cb_set(g, ELM_GESTURE_N_TAPS, ELM_GESTURE_STATE_START, n_finger_tap_start, NULL);

Variant B - I use a separate object winTouch for the touch layer. It works, but the layer appears fully opaque and the watch face cannot be seen:

/* Variant B */    
Evas_Object *winTouch;

/* Gesture layer transparent object */
Evas_Object *r;
/* Gesture layer object */
Evas_Object *g;

winTouch = elm_win_util_standard_add("gesture_layer", "Gesture Layer");
elm_win_autodel_set(winTouch, EINA_TRUE);

/* Gesture layer transparent object */
r = evas_object_rectangle_add(evas_object_evas_get(winTouch));
evas_object_move(r, 0, 0);
evas_object_color_set(r, 0, 0, 255, 0);
elm_win_resize_object_add(winTouch, r);

/* Gesture layer object */
g = elm_gesture_layer_add(winTouch);
elm_gesture_layer_attach(g, r);
evas_object_show(r);
evas_object_show(winTouch); // <--- Without this line, Variant B behaves like Variant A

/* Set callbacks */
elm_gesture_layer_cb_set(g, ELM_GESTURE_N_TAPS, ELM_GESTURE_STATE_START, n_finger_tap_start, NULL);
// and other callbacks

What am I doing wrong?

My project is based on the SDK sample "Chronograph Watch". There are actually 4 different Evas_Object's:

  1. evas_object_resize(win, width, height);
  2. evas_object_resize(bg, width, height);
  3. evas_object_resize(chronograph_layout, DIAM_SCREEN, DIAM_SCREEN);
  4. evas_object_resize(parts, size_w, size_h);

Where should I add the gesture layer? When I add it on 1, Variant A does nothing, Variant B works but covers the watch face. If I do it on one of the others, both Variants work but cover the watch face. I don't understand why, since I am specifying a transparent color.

EDIT: One new thought: could it be that the touch gesture layer does only work on apps, not on watch faces?

2

There are 2 best solutions below

3
On BEST ANSWER

The widget tree of chronographwatch App is

Win -> Bg -> Layout -> Images

This sample app's top view is Layout(main.edc), So you should attach gesture layer on that.

Evas_Object *gesture;
gesture = elm_gesture_layer_add(chronograph_layout);
elm_gesture_layer_attach(gesture, chronograph_layout);

elm_gesture_layer_cb_set(gesture, ELM_GESTURE_N_TAPS,
  ELM_GESTURE_STATE_START, n_finger_tap_start, NULL);
elm_gesture_layer_cb_set(gesture, ELM_GESTURE_N_TAPS,
  ELM_GESTURE_STATE_END, n_finger_tap_end, NULL);

I can get an event properly.

  • If you want to use system defined gestures such as flick, zoom, rotate, long tap you need to use gesture layer. but if you just want to get touch event on the object. just use EVAS_CALLBACK_MOUSE_XXX.

Hope you got a solution.

3
On

You don't need to create a new window for gesture layer.

you got a window from API. then did you create a new window using elm_win_add API?

My below sample code works well. window was transprent.

Plz see you code carefully and if you don't find the wrong things.

why don't you share your full code. i will look around.

static Evas_Event_Flags
n_finger_tap_start(void *data , void *event_info)
{
    printf("tap start\n");
   return EVAS_EVENT_FLAG_ON_HOLD;
}

void
test_gesture_layer(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
      void *event_info EINA_UNUSED)
{
   Evas_Coord w, h;
   Evas_Object *win;

   w = 480;
   h = 800;

   win = elm_win_add(NULL, "gesture-layer", ELM_WIN_BASIC);
   elm_win_title_set(win, "Gesture Layer");
   elm_win_autodel_set(win, EINA_TRUE);
   evas_object_resize(win, w, h);

   Evas_Object *r, *g;

   r = evas_object_rectangle_add(evas_object_evas_get(win));
   evas_object_move(r, 0, 0);
   evas_object_color_set(r, 0, 0, 0, 0);
   elm_win_resize_object_add(win, r);

   g = elm_gesture_layer_add(win);
   elm_gesture_layer_attach(g, r);
   evas_object_show(r);

   elm_gesture_layer_cb_set(g, ELM_GESTURE_N_TAPS,
       ELM_GESTURE_STATE_START, n_finger_tap_start, NULL);

   evas_object_show(win);
}