Mobile native Wearable native

Tracking Multi-point Touch Events

This tutorial demonstrates how you can use the Evas_Object to paint on a canvas and track touch events.

Initializing Multi-point Touch

This sample is a fully functional application able to track multiple simultaneous clicks. For every click, a black rectangle spot is drawn on the screen. This way it is easy to test the multi-point touch operation with the application.

Initialization is implemented in the multitouch.c file.

The appdata structure includes Evas_Object pointers, a list, and a Boolean flag.

typedef struct appdata 
{
   Evas_Object *win;
   Evas_Object *conform;
   Evas_Object *nf;
   Evas_Object *button;
   Evas_Object *box;
   Evas_Object *rect;
   Evas_Object *label;

   // List of mouse spots
   Eina_List *spots;

   // Flag for checking the mouse down event
   Eina_Bool down; 
} 
appdata_s;

The main() function initializes event callbacks and calls the ui_app_main() function to start the EFL application.

int
main(int argc, char *argv[])
{
   appdata_s *ad = {0,};
   int ret = 0;

   ui_app_lifecycle_callback_s event_callback = {0,};
   app_event_handler_h handlers[5] = {NULL,};

   event_callback.create = app_create;
   event_callback.terminate = app_terminate;
   event_callback.pause = app_pause;
   event_callback.resume = app_resume;
   event_callback.app_control = app_control;

   ui_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY, ui_app_low_battery, &ad);
   ui_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY, ui_app_low_memory, &ad);
   ui_app_add_event_handler(&handlers[APP_EVENT_DEVICE_ORIENTATION_CHANGED], APP_EVENT_DEVICE_ORIENTATION_CHANGED, ui_app_orient_changed, &ad);
   ui_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED, ui_app_lang_changed, &ad);
   ui_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED], APP_EVENT_REGION_FORMAT_CHANGED, ui_app_region_changed, &ad);
   ui_app_remove_event_handler(handlers[APP_EVENT_LOW_MEMORY]);

   ret = ui_app_main(argc, argv, &event_callback, &ad);

   return ret;
}

The following figure illustrates the Multi-point Touch.

Figure: Multi-point Touch screens

Multi-point Touch screens

Handling the Canvas

The create_base_gui() function creates base GUI elements including Naviframe and the Naviframe button. Naviframe includes each view screen as an item, which in turn includes the title and a button which clears spots when clicked.

static void
create_base_gui(appdata_s *ad)
{
   Elm_Object_Item *nf_it;

   // Naviframe
   ad->nf = elm_naviframe_add(ad->conform);
   elm_object_content_set(ad->conform, ad->nf);
   evas_object_show(ad->nf);

   // Button
   ad->button = elm_button_add(ad->nf);
   elm_object_text_set(ad->button, "Clear");
   evas_object_smart_callback_add(ad->button, "clicked", button_clicked_cb, ad);

   // Create main view
   ad->box = create_main_view(ad);
   nf_it = elm_naviframe_item_push(ad->nf, "Multi-point Touch",
                                   NULL, NULL, ad->box, NULL);
   elm_object_item_part_content_set(nf_it, "title_right_btn", ad->button);
} 

The create_main_view() function creates the main view including the label and an event rectangle.

The label displays information on mouse event status and coordinates (x, y positions). The event rectangle is received completely through mouse (touch) events. To show 2 elements in a Naviframe content area, a container combining those elements is necessary. A box container functions in that role. The label and rectangle pack end the box and the box is embedded into the Naviframe content area.

static Evas_Object *
create_main_view(appdata_s *ad)
{
   Evas_Object *box;

   // Box
   box = elm_box_add(ad->nf);
   evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
   evas_object_show(box);

   // Label
   ad->label = elm_label_add(box);
   elm_object_text_set(ad->label, "None");
   evas_object_size_hint_weight_set(ad->label, EVAS_HINT_EXPAND, 0);
   evas_object_size_hint_align_set(ad->label, EVAS_HINT_FILL, EVAS_HINT_FILL);
   evas_object_repeat_events_set(ad->label, EINA_TRUE);
   elm_box_pack_end(box, ad->label);
   evas_object_show(ad->label);

   // Event Rect
   ad->rect = evas_object_rectangle_add(evas_object_evas_get(box));
   evas_object_size_hint_weight_set(ad->rect, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
   evas_object_size_hint_align_set(ad->rect, EVAS_HINT_FILL, EVAS_HINT_FILL);
   evas_object_color_set(ad->rect, 204, 204, 204, 255);
   evas_object_repeat_events_set(ad->rect, EINA_TRUE);
   elm_box_pack_end(box, ad->rect);
   evas_object_show(ad->rect);

   return box;
}

The create_spot() function creates a rectangle, resizes the rectangle according to received size input, and moves the rectangle according to received coordinates (x, y positions) input.

Evas_Object *
create_spot(Evas_Object *parent, Evas_Coord x, Evas_Coord y, int size)
{
   Evas_Object *spot;
   spot = evas_object_rectangle_add(evas_object_evas_get(parent));
   evas_object_resize(spot, size, size);
   // Adjust x, y positions to be center of object
   evas_object_move(spot, x - (size/2), y - (size/2));
   evas_object_show(spot);

   return spot;
}

The rectangle object is stored in Eina_List (ad->spots) for managing other functions. The button_clicked_cb() function removes all evas_objects into the ad->spots list, meaning all spot rectangles are cleared.

static void
button_clicked_cb(void *data, Evas *evas, Evas_Object *object, void *event_info)
{
   appdata_s *ad = data;
   Evas_Object *spot;

   EINA_LIST_FREE(ad->spots, spot)
   {
      evas_object_del(spot);
      spot = NULL;
   }
   elm_object_text_set(ad->label, "Clear");
}

Managing Touch Events

On the bottom of the create_main_view() function, event callbacks are added to the event rectangle. An event callback is added using the evas_object_event_callback_add() function.

The event types for a touch event contain the "MOUSE" keyword due to backward compatibility with Tizen 2.3. Before the multi-point touch concept was introduced, there was no difference between a single touch event and a mouse event. As a result, the single touch event used the EVAS_CALLBACK_MOUSE_DOWN/UP/MOVE event types.

The following touch event types are supported:

  • EVAS_CALLBACK_MOUSE_DOWN: This event is called when the given object receives the mouse down event.
  • EVAS_CALLBACK_MOUSE_UP: This event is called when the given object receives the mouse up event.
  • EVAS_CALLBACK_MOUSE_MOVE: This event is called when the given object receives the mouse move event.
  • EVAS_CALLBACK_MULTI_DOWN: This event is called when the given object has already received the mouse down event and receives the multi-mouse down event.
  • EVAS_CALLBACK_MULTI_UP: This event is called when the given object receives the multi-mouse up event.
  • EVAS_CALLBACK_MULTI_MOVE: This event is called when the given object receives the multi-mouse move event.

If the given object receives a mouse event, a callback function is called, and event information, such as coordinates (x, y positions) is passed. The mousemove_cb() function sets the mouse status, positions text in the label, and draws a spot rectangle. To distinguish down and up positions, set different colors for the down and up rectangles.

static void
mousemove_cb(void *data, Evas *evas, Evas_Object *obj, void *event_info)
{
   appdata_s *ad = data;
   Evas_Object *spot;
   char buf[1024];
   Evas_Event_Mouse_Move *ev = event_info;
   Evas_Coord x = ev->cur.canvas.x;
   Evas_Coord y = ev->cur.canvas.y;
   int size = (int) 5 * elm_config_scale_get();

   if (!ad->down)
      return;

   snprintf(buf, sizeof(buf), "Mouse Move, %d, %d", x, y);
   elm_object_text_set(ad->label, buf);

   // Draw spot on event position
   spot = create_spot(ad->rect, x, y, size);
   evas_object_color_set(spot, 0, 0, 0, 255);
   ad->spots= eina_list_append(ad->spots, spot);
}

static void
create_event_object(appdata_s *ad)
{
   Evas_Object *box;
   box = elm_box_add(ad->nf);
   evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
   evas_object_show(box);

   evas_object_event_callback_add(box, EVAS_CALLBACK_MOUSE_MOVE, mousemove_cb, ad);
}
Go to top